1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #ifndef BLEND2D_BLRUNTIME_P_H |
8 | #define BLEND2D_BLRUNTIME_P_H |
9 | |
10 | #include "./blapi-internal_p.h" |
11 | #include "./blruntime.h" |
12 | |
13 | //! \cond INTERNAL |
14 | //! \addtogroup blend2d_internal |
15 | //! \{ |
16 | |
17 | // ============================================================================ |
18 | // [BLRuntime - FixedFuncArray] |
19 | // ============================================================================ |
20 | |
21 | //! Fixed array used by handlers, initial content should be zero initialized |
22 | //! by the linker as it's used only in a statically allocated `BLRuntimeContext`. |
23 | template<typename Func, size_t N> |
24 | struct BLFixedFuncArray { |
25 | size_t size; |
26 | Func data[N]; |
27 | |
28 | BL_INLINE void reset() noexcept { size = 0; } |
29 | |
30 | BL_INLINE void add(Func func) noexcept { |
31 | BL_ASSERT(size < N); |
32 | data[size++] = func; |
33 | } |
34 | |
35 | template<typename... Args> |
36 | BL_INLINE void call(Args&&... args) noexcept { |
37 | for (size_t i = 0; i < size; i++) |
38 | data[i](std::forward<Args>(args)...); |
39 | } |
40 | |
41 | template<typename... Args> |
42 | BL_INLINE void callInReverseOrder(Args&&... args) noexcept { |
43 | size_t i = size; |
44 | while (i) |
45 | data[--i](std::forward<Args>(args)...); |
46 | } |
47 | }; |
48 | |
49 | // ============================================================================ |
50 | // [BLRuntime - Context] |
51 | // ============================================================================ |
52 | |
53 | //! Blend2D runtime context. |
54 | //! |
55 | //! A singleton that is created at Blend2D startup and that can be used to query |
56 | //! various information about the library and its runtime. |
57 | struct BLRuntimeContext { |
58 | //! Shutdown handler. |
59 | typedef void (BL_CDECL* ShutdownFunc)(BLRuntimeContext* rt) BL_NOEXCEPT; |
60 | //! Cleanup handler. |
61 | typedef void (BL_CDECL* CleanupFunc)(BLRuntimeContext* rt, uint32_t cleanupFlags) BL_NOEXCEPT; |
62 | //! MemoryInfo handler. |
63 | typedef void (BL_CDECL* MemoryInfoFunc)(BLRuntimeContext* rt, BLRuntimeMemoryInfo* memoryInfo) BL_NOEXCEPT; |
64 | |
65 | //! Counts how many times `blRuntimeInit()` has been called. |
66 | //! |
67 | //! Returns the current initialization count, which is incremented every |
68 | //! time a `blRuntimeInit()` is called and decremented every time a |
69 | //! `blRuntimeShutdown()` is called. |
70 | //! |
71 | //! When this counter is incremented from 0 to 1 the library is initialized, |
72 | //! when it's decremented to zero it will free all resources and it will no |
73 | //! longer be safe to use. |
74 | volatile size_t refCount; |
75 | |
76 | //! System information. |
77 | BLRuntimeSystemInfo systemInfo; |
78 | |
79 | // NOTE: There is only a limited number of handlers that can be added to the |
80 | // context. The reason we do it this way is that for builds of Blend2D that |
81 | // have conditionally disabled some features it's easier to have only `RtInit()` |
82 | // handlers and let them register cleanup/shutdown handlers when needed. |
83 | |
84 | //! Shutdown handlers (always traversed from last to first). |
85 | BLFixedFuncArray<ShutdownFunc, 8> shutdownHandlers; |
86 | //! Cleanup handlers (always executed from first to last). |
87 | BLFixedFuncArray<CleanupFunc, 8> cleanupHandlers; |
88 | //! MemoryInfo handlers (always traversed from first to last). |
89 | BLFixedFuncArray<MemoryInfoFunc, 8> memoryInfoHandlers; |
90 | }; |
91 | |
92 | //! Instance of a global runtime context. |
93 | BL_HIDDEN extern BLRuntimeContext blRuntimeContext; |
94 | |
95 | // ============================================================================ |
96 | // [BLRuntime - Cpu Features] |
97 | // ============================================================================ |
98 | |
99 | // NOTE: Must be in anonymous namespace. When the compilation unit uses certain |
100 | // optimizations we constexpr the check and return `true` without checking CPU |
101 | // features as the compilation unit uses them anyway [at that point]. |
102 | BL_DIAGNOSTIC_PUSH(BL_DIAGNOSTIC_NO_UNUSED_PARAMETERS) |
103 | |
104 | namespace { |
105 | |
106 | #ifdef BL_TARGET_OPT_SSE2 |
107 | constexpr bool blRuntimeHasSSE2(BLRuntimeContext* rt) noexcept { return true; } |
108 | #else |
109 | inline bool blRuntimeHasSSE2(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_SSE2) != 0; } |
110 | #endif |
111 | |
112 | #ifdef BL_TARGET_OPT_SSE3 |
113 | constexpr bool blRuntimeHasSSE3(BLRuntimeContext* rt) noexcept { return true; } |
114 | #else |
115 | inline bool blRuntimeHasSSE3(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_SSE3) != 0; } |
116 | #endif |
117 | |
118 | #ifdef BL_TARGET_OPT_SSSE3 |
119 | constexpr bool blRuntimeHasSSSE3(BLRuntimeContext* rt) noexcept { return true; } |
120 | #else |
121 | inline bool blRuntimeHasSSSE3(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_SSSE3) != 0; } |
122 | #endif |
123 | |
124 | #ifdef BL_TARGET_OPT_SSE4_1 |
125 | constexpr bool blRuntimeHasSSE4_1(BLRuntimeContext* rt) noexcept { return true; } |
126 | #else |
127 | inline bool blRuntimeHasSSE4_1(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_SSE4_1) != 0; } |
128 | #endif |
129 | |
130 | #ifdef BL_TARGET_OPT_SSE4_2 |
131 | constexpr bool blRuntimeHasSSE4_2(BLRuntimeContext* rt) noexcept { return true; } |
132 | #else |
133 | inline bool blRuntimeHasSSE4_2(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_SSE4_2) != 0; } |
134 | #endif |
135 | |
136 | #ifdef BL_TARGET_OPT_AVX |
137 | constexpr bool blRuntimeHasAVX(BLRuntimeContext* rt) noexcept { return true; } |
138 | #else |
139 | inline bool blRuntimeHasAVX(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_AVX) != 0; } |
140 | #endif |
141 | |
142 | #ifdef BL_TARGET_OPT_AVX2 |
143 | constexpr bool blRuntimeHasAVX2(BLRuntimeContext* rt) noexcept { return true; } |
144 | #else |
145 | inline bool blRuntimeHasAVX2(BLRuntimeContext* rt) noexcept { return (rt->systemInfo.cpuFeatures & BL_RUNTIME_CPU_FEATURE_X86_AVX2) != 0; } |
146 | #endif |
147 | |
148 | } // {anonymous} |
149 | |
150 | BL_DIAGNOSTIC_POP |
151 | |
152 | // ============================================================================ |
153 | // [BLRuntime - Impl] |
154 | // ============================================================================ |
155 | |
156 | BL_HIDDEN void BL_CDECL blRuntimeDummyDestroyImplFunc(void* impl, void* destroyData) noexcept; |
157 | |
158 | // ============================================================================ |
159 | // [BLRuntime - Utilities] |
160 | // ============================================================================ |
161 | |
162 | BL_HIDDEN BL_NORETURN void blRuntimeFailure(const char* fmt, ...) noexcept; |
163 | |
164 | // ============================================================================ |
165 | // [BLRuntime - Runtime Init] |
166 | // ============================================================================ |
167 | |
168 | BL_HIDDEN void blThreadingRtInit(BLRuntimeContext* rt) noexcept; |
169 | BL_HIDDEN void blThreadPoolRtInit(BLRuntimeContext* rt) noexcept; |
170 | BL_HIDDEN void blZeroAllocatorRtInit(BLRuntimeContext* rt) noexcept; |
171 | BL_HIDDEN void blMatrix2DRtInit(BLRuntimeContext* rt) noexcept; |
172 | BL_HIDDEN void blArrayRtInit(BLRuntimeContext* rt) noexcept; |
173 | BL_HIDDEN void blStringRtInit(BLRuntimeContext* rt) noexcept; |
174 | BL_HIDDEN void blPathRtInit(BLRuntimeContext* rt) noexcept; |
175 | BL_HIDDEN void blRegionRtInit(BLRuntimeContext* rt) noexcept; |
176 | BL_HIDDEN void blImageRtInit(BLRuntimeContext* rt) noexcept; |
177 | BL_HIDDEN void blImageScalerRtInit(BLRuntimeContext* rt) noexcept; |
178 | BL_HIDDEN void blPatternRtInit(BLRuntimeContext* rt) noexcept; |
179 | BL_HIDDEN void blGradientRtInit(BLRuntimeContext* rt) noexcept; |
180 | BL_HIDDEN void blFontRtInit(BLRuntimeContext* rt) noexcept; |
181 | BL_HIDDEN void blContextRtInit(BLRuntimeContext* rt) noexcept; |
182 | |
183 | #if !defined(BL_BUILD_NO_FIXED_PIPE) |
184 | BL_HIDDEN void blFixedPipeRtInit(BLRuntimeContext* rt) noexcept; |
185 | #endif |
186 | |
187 | #if !defined(BL_BUILD_NO_JIT) |
188 | BL_HIDDEN void blPipeGenRtInit(BLRuntimeContext* rt) noexcept; |
189 | #endif |
190 | |
191 | //! \} |
192 | //! \endcond |
193 | |
194 | #endif // BLEND2D_BLRUNTIME_P_H |
195 | |