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