• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 // IWYU pragma: private, include "SkTypes.h"
9 
10 #ifndef SkPostConfig_DEFINED
11 #define SkPostConfig_DEFINED
12 
13 #if !defined(SK_DEBUG) && !defined(SK_RELEASE)
14     #ifdef NDEBUG
15         #define SK_RELEASE
16     #else
17         #define SK_DEBUG
18     #endif
19 #endif
20 
21 #if defined(SK_DEBUG) && defined(SK_RELEASE)
22 #  error "cannot define both SK_DEBUG and SK_RELEASE"
23 #elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
24 #  error "must define either SK_DEBUG or SK_RELEASE"
25 #endif
26 
27 #if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG)
28 #  error "can't have unittests without debug"
29 #endif
30 
31 /**
32  * Matrix calculations may be float or double.
33  * The default is float, as that's what Chromium's using.
34  */
35 #if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT)
36 #  error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT"
37 #elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT)
38 #  define SK_MSCALAR_IS_FLOAT
39 #endif
40 
41 #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
42 #  error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
43 #elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
44 #  error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
45 #endif
46 
47 /**
48  * Ensure the port has defined all of SK_X32_SHIFT, or none of them.
49  */
50 #ifdef SK_A32_SHIFT
51 #  if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
52 #    error "all or none of the 32bit SHIFT amounts must be defined"
53 #  endif
54 #else
55 #  if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
56 #    error "all or none of the 32bit SHIFT amounts must be defined"
57 #  endif
58 #endif
59 
60 #if !defined(SK_HAS_COMPILER_FEATURE)
61 #  if defined(__has_feature)
62 #    define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
63 #  else
64 #    define SK_HAS_COMPILER_FEATURE(x) 0
65 #  endif
66 #endif
67 
68 #if !defined(SK_ATTRIBUTE)
69 #  if defined(__clang__) || defined(__GNUC__)
70 #    define SK_ATTRIBUTE(attr) __attribute__((attr))
71 #  else
72 #    define SK_ATTRIBUTE(attr)
73 #  endif
74 #endif
75 
76 #if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
77     #define SK_VECTORCALL __vectorcall
78 #elif defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_NEON)
79     #define SK_VECTORCALL __attribute__((pcs("aapcs-vfp")))
80 #else
81     #define SK_VECTORCALL
82 #endif
83 
84 #if !defined(SK_SUPPORT_GPU)
85 #  define SK_SUPPORT_GPU 1
86 #endif
87 
88 #if !defined(SK_SUPPORT_ATLAS_TEXT)
89 #  define SK_SUPPORT_ATLAS_TEXT 0
90 #elif SK_SUPPORT_ATLAS_TEXT && !SK_SUPPORT_GPU
91 #  error "SK_SUPPORT_ATLAS_TEXT requires SK_SUPPORT_GPU"
92 #endif
93 
94 /**
95  * The clang static analyzer likes to know that when the program is not
96  * expected to continue (crash, assertion failure, etc). It will notice that
97  * some combination of parameters lead to a function call that does not return.
98  * It can then make appropriate assumptions about the parameters in code
99  * executed only if the non-returning function was *not* called.
100  */
101 #if !defined(SkNO_RETURN_HINT)
102 #  if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
103      static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
SkNO_RETURN_HINT()104      static inline void SkNO_RETURN_HINT() {}
105 #  else
106 #    define SkNO_RETURN_HINT() do {} while (false)
107 #  endif
108 #endif
109 
110 ///////////////////////////////////////////////////////////////////////////////
111 
112 // TODO(mdempsky): Move elsewhere as appropriate.
113 #include <new>
114 
115 
116 ///////////////////////////////////////////////////////////////////////////////
117 
118 #ifdef SK_BUILD_FOR_WIN
119 #  ifndef SK_A32_SHIFT
120 #    define SK_A32_SHIFT 24
121 #    define SK_R32_SHIFT 16
122 #    define SK_G32_SHIFT 8
123 #    define SK_B32_SHIFT 0
124 #  endif
125 #
126 #endif
127 
128 #if defined(SK_BUILD_FOR_GOOGLE3)
129     void SkDebugfForDumpStackTrace(const char* data, void* unused);
130     void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg);
131 #  define SK_DUMP_GOOGLE3_STACK() DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr)
132 #else
133 #  define SK_DUMP_GOOGLE3_STACK()
134 #endif
135 
136 #ifdef SK_BUILD_FOR_WIN
137 // permits visual studio to follow error back to source
138 #define SK_DUMP_LINE_FORMAT(message) \
139     SkDebugf("%s(%d): fatal error: \"%s\"\n", __FILE__, __LINE__, message)
140 #else
141 #define SK_DUMP_LINE_FORMAT(message) \
142     SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message)
143 #endif
144 
145 #ifndef SK_ABORT
146 #  define SK_ABORT(message) \
147     do { \
148        SkNO_RETURN_HINT(); \
149        SK_DUMP_LINE_FORMAT(message); \
150        SK_DUMP_GOOGLE3_STACK(); \
151        sk_abort_no_print(); \
152     } while (false)
153 #endif
154 
155 /**
156  *  We check to see if the SHIFT value has already been defined.
157  *  if not, we define it ourself to some default values. We default to OpenGL
158  *  order (in memory: r,g,b,a)
159  */
160 #ifndef SK_A32_SHIFT
161 #  ifdef SK_CPU_BENDIAN
162 #    define SK_R32_SHIFT    24
163 #    define SK_G32_SHIFT    16
164 #    define SK_B32_SHIFT    8
165 #    define SK_A32_SHIFT    0
166 #  else
167 #    define SK_R32_SHIFT    0
168 #    define SK_G32_SHIFT    8
169 #    define SK_B32_SHIFT    16
170 #    define SK_A32_SHIFT    24
171 #  endif
172 #endif
173 
174 /**
175  * SkColor has well defined shift values, but SkPMColor is configurable. This
176  * macro is a convenience that returns true if the shift values are equal while
177  * ignoring the machine's endianness.
178  */
179 #define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \
180     (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0)
181 
182 /**
183  * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
184  * relationship between the byte order and shift values depends on machine endianness. If the shift
185  * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
186  * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
187  * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
188  * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
189  */
190 #ifdef SK_CPU_BENDIAN
191 #  define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
192         (SK_ ## C3 ## 32_SHIFT == 0  &&             \
193          SK_ ## C2 ## 32_SHIFT == 8  &&             \
194          SK_ ## C1 ## 32_SHIFT == 16 &&             \
195          SK_ ## C0 ## 32_SHIFT == 24)
196 #else
197 #  define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
198         (SK_ ## C0 ## 32_SHIFT == 0  &&             \
199          SK_ ## C1 ## 32_SHIFT == 8  &&             \
200          SK_ ## C2 ## 32_SHIFT == 16 &&             \
201          SK_ ## C3 ## 32_SHIFT == 24)
202 #endif
203 
204 //////////////////////////////////////////////////////////////////////////////////////////////
205 
206 #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN
207 #  ifdef free
208 #    undef free
209 #  endif
210 #  include <crtdbg.h>
211 #  undef free
212 #
213 #  ifdef SK_DEBUGx
214 #    if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
215        void * operator new(
216            size_t cb,
217            int nBlockUse,
218            const char * szFileName,
219            int nLine,
220            int foo
221            );
222        void * operator new[](
223            size_t cb,
224            int nBlockUse,
225            const char * szFileName,
226            int nLine,
227            int foo
228            );
229        void operator delete(
230            void *pUserData,
231            int, const char*, int, int
232            );
233        void operator delete(
234            void *pUserData
235            );
236        void operator delete[]( void * p );
237 #      define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
238 #    else
239 #      define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
240 #    endif
241 #    define new DEBUG_CLIENTBLOCK
242 #  else
243 #    define DEBUG_CLIENTBLOCK
244 #  endif
245 #endif
246 
247 //////////////////////////////////////////////////////////////////////
248 
249 #if !defined(SK_UNUSED)
250 #  if !defined(__clang__) && defined(_MSC_VER)
251 #    define SK_UNUSED __pragma(warning(suppress:4189))
252 #  else
253 #    define SK_UNUSED SK_ATTRIBUTE(unused)
254 #  endif
255 #endif
256 
257 #if !defined(SK_ATTR_DEPRECATED)
258    // FIXME: we ignore msg for now...
259 #  define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated)
260 #endif
261 
262 /**
263  * If your judgment is better than the compiler's (i.e. you've profiled it),
264  * you can use SK_ALWAYS_INLINE to force inlining. E.g.
265  *     inline void someMethod() { ... }             // may not be inlined
266  *     SK_ALWAYS_INLINE void someMethod() { ... }   // should always be inlined
267  */
268 #if !defined(SK_ALWAYS_INLINE)
269 #  if defined(SK_BUILD_FOR_WIN)
270 #    define SK_ALWAYS_INLINE __forceinline
271 #  else
272 #    define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
273 #  endif
274 #endif
275 
276 /**
277  * If your judgment is better than the compiler's (i.e. you've profiled it),
278  * you can use SK_NEVER_INLINE to prevent inlining.
279  */
280 #if !defined(SK_NEVER_INLINE)
281 #  if defined(SK_BUILD_FOR_WIN)
282 #    define SK_NEVER_INLINE __declspec(noinline)
283 #  else
284 #    define SK_NEVER_INLINE SK_ATTRIBUTE(noinline)
285 #  endif
286 #endif
287 
288 //////////////////////////////////////////////////////////////////////
289 
290 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
291     #define SK_PREFETCH(ptr)       _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0)
292     #define SK_WRITE_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0)
293 #elif defined(__GNUC__)
294     #define SK_PREFETCH(ptr)       __builtin_prefetch(ptr)
295     #define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1)
296 #else
297     #define SK_PREFETCH(ptr)
298     #define SK_WRITE_PREFETCH(ptr)
299 #endif
300 
301 //////////////////////////////////////////////////////////////////////
302 
303 #ifndef SK_PRINTF_LIKE
304 #  if defined(__clang__) || defined(__GNUC__)
305 #    define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
306 #  else
307 #    define SK_PRINTF_LIKE(A, B)
308 #  endif
309 #endif
310 
311 //////////////////////////////////////////////////////////////////////
312 
313 #ifndef SK_SIZE_T_SPECIFIER
314 #  if defined(_MSC_VER) && !defined(__clang__)
315 #    define SK_SIZE_T_SPECIFIER "%Iu"
316 #  else
317 #    define SK_SIZE_T_SPECIFIER "%zu"
318 #  endif
319 #endif
320 
321 //////////////////////////////////////////////////////////////////////
322 
323 #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
324 #  define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
325 #endif
326 
327 //////////////////////////////////////////////////////////////////////
328 
329 #ifndef SK_EGL
330 #  if defined(SK_BUILD_FOR_ANDROID)
331 #    define SK_EGL 1
332 #  else
333 #    define SK_EGL 0
334 #  endif
335 #endif
336 
337 //////////////////////////////////////////////////////////////////////
338 
339 #if !defined(SK_GAMMA_EXPONENT)
340     #define SK_GAMMA_EXPONENT (0.0f)  // SRGB
341 #endif
342 
343 //////////////////////////////////////////////////////////////////////
344 
345 #ifndef GR_TEST_UTILS
346 #  define GR_TEST_UTILS 0
347 #endif
348 
349 //////////////////////////////////////////////////////////////////////
350 
351 #if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN)
352 #  define SK_HISTOGRAMS_ENABLED 1
353 #else
354 #  define SK_HISTOGRAMS_ENABLED 0
355 #endif
356 
357 #ifndef SK_HISTOGRAM_BOOLEAN
358 #  define SK_HISTOGRAM_BOOLEAN(name, value)
359 #endif
360 
361 #ifndef SK_HISTOGRAM_ENUMERATION
362 #  define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value)
363 #endif
364 
365 #endif // SkPostConfig_DEFINED
366