2 * Copyright 2006 The Android Open Source Project
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SkPostConfig_DEFINED
9 #define SkPostConfig_DEFINED
11 #if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
12 # define SK_BUILD_FOR_WIN
15 #if defined(SK_DEBUG) && defined(SK_RELEASE)
16 # error "cannot define both SK_DEBUG and SK_RELEASE"
17 #elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
18 # error "must define either SK_DEBUG or SK_RELEASE"
21 #if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG)
22 # error "can't have unittests without debug"
26 * Matrix calculations may be float or double.
27 * The default is double, as that is faster given our impl uses doubles
28 * for intermediate calculations.
30 #if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT)
31 # error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT"
32 #elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT)
33 # define SK_MSCALAR_IS_DOUBLE
36 #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
37 # error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
38 #elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
39 # error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
43 * Ensure the port has defined all of SK_X32_SHIFT, or none of them.
46 # if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
47 # error "all or none of the 32bit SHIFT amounts must be defined"
50 # if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
51 # error "all or none of the 32bit SHIFT amounts must be defined"
55 #if !defined(SK_HAS_COMPILER_FEATURE)
56 # if defined(__has_feature)
57 # define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
59 # define SK_HAS_COMPILER_FEATURE(x) 0
63 #if !defined(SK_ATTRIBUTE)
64 # if defined(__clang__) || defined(__GNUC__)
65 # define SK_ATTRIBUTE(attr) __attribute__((attr))
67 # define SK_ATTRIBUTE(attr)
71 #if !defined(SK_SUPPORT_GPU)
72 # define SK_SUPPORT_GPU 1
76 * The clang static analyzer likes to know that when the program is not
77 * expected to continue (crash, assertion failure, etc). It will notice that
78 * some combination of parameters lead to a function call that does not return.
79 * It can then make appropriate assumptions about the parameters in code
80 * executed only if the non-returning function was *not* called.
82 #if !defined(SkNO_RETURN_HINT)
83 # if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
84 static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
85 static inline void SkNO_RETURN_HINT() {}
87 # define SkNO_RETURN_HINT() do {} while (false)
91 #if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
92 # error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
93 #elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
97 ///////////////////////////////////////////////////////////////////////////////
100 # define SkNEW(type_name) (new type_name)
101 # define SkNEW_ARGS(type_name, args) (new type_name args)
102 # define SkNEW_ARRAY(type_name, count) (new type_name[(count)])
103 # define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name)
104 # define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args)
105 # define SkDELETE(obj) (delete (obj))
106 # define SkDELETE_ARRAY(array) (delete[] (array))
110 # ifdef SK_BUILD_FOR_WIN
111 # define SK_CRASH() __debugbreak()
113 # if 1 // set to 0 for infinite loop, which can help connecting gdb
114 # define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
116 # define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
121 ///////////////////////////////////////////////////////////////////////////////
124 * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects
125 * are still held on exit.
126 * Defaults to 1 in DEBUG and 0 in RELEASE.
128 #ifndef SK_ENABLE_INST_COUNT
129 // Only enabled for static builds, because instance counting relies on static
130 // variables in functions defined in header files.
131 # if defined(SK_DEBUG) && !defined(SKIA_DLL)
132 # define SK_ENABLE_INST_COUNT 1
134 # define SK_ENABLE_INST_COUNT 0
138 ///////////////////////////////////////////////////////////////////////////////
140 #ifdef SK_BUILD_FOR_WIN
141 # ifndef WIN32_LEAN_AND_MEAN
142 # define WIN32_LEAN_AND_MEAN
143 # define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
147 # define NOMINMAX_WAS_LOCALLY_DEFINED
150 # include <windows.h>
152 # ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
153 # undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
154 # undef WIN32_LEAN_AND_MEAN
156 # ifdef NOMINMAX_WAS_LOCALLY_DEFINED
157 # undef NOMINMAX_WAS_LOCALLY_DEFINED
161 # ifndef SK_A32_SHIFT
162 # define SK_A32_SHIFT 24
163 # define SK_R32_SHIFT 16
164 # define SK_G32_SHIFT 8
165 # define SK_B32_SHIFT 0
170 #ifndef SK_ALWAYSBREAK
172 # define SK_ALWAYSBREAK(cond) do { \
174 SkNO_RETURN_HINT(); \
175 SkDebugf("%s:%d: failed assertion \"%s\"\n", __FILE__, __LINE__, #cond); \
179 # define SK_ALWAYSBREAK(cond) do { if (cond) break; SK_CRASH(); } while (false)
184 * We check to see if the SHIFT value has already been defined.
185 * if not, we define it ourself to some default values. We default to OpenGL
186 * order (in memory: r,g,b,a)
189 # ifdef SK_CPU_BENDIAN
190 # define SK_R32_SHIFT 24
191 # define SK_G32_SHIFT 16
192 # define SK_B32_SHIFT 8
193 # define SK_A32_SHIFT 0
195 # define SK_R32_SHIFT 0
196 # define SK_G32_SHIFT 8
197 # define SK_B32_SHIFT 16
198 # define SK_A32_SHIFT 24
203 * SkColor has well defined shift values, but SkPMColor is configurable. This
204 * macro is a convenience that returns true if the shift values are equal while
205 * ignoring the machine's endianness.
207 #define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \
208 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0)
211 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
212 * relationship between the byte order and shift values depends on machine endianness. If the shift
213 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
214 * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
215 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
216 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
218 #ifdef SK_CPU_BENDIAN
219 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
220 (SK_ ## C3 ## 32_SHIFT == 0 && \
221 SK_ ## C2 ## 32_SHIFT == 8 && \
222 SK_ ## C1 ## 32_SHIFT == 16 && \
223 SK_ ## C0 ## 32_SHIFT == 24)
225 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
226 (SK_ ## C0 ## 32_SHIFT == 0 && \
227 SK_ ## C1 ## 32_SHIFT == 8 && \
228 SK_ ## C2 ## 32_SHIFT == 16 && \
229 SK_ ## C3 ## 32_SHIFT == 24)
232 //////////////////////////////////////////////////////////////////////
234 // TODO: rebaseline as needed so we can remove this flag entirely.
235 // - all platforms have int64_t now
236 // - we have slightly different fixed math results because of this check
237 // since we don't define this for linux/android
238 #if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
240 # define SkLONGLONG int64_t
244 //////////////////////////////////////////////////////////////////////////////////////////////
245 #ifndef SK_BUILD_FOR_WINCE
249 # define _CMNINTRIN_DECLARE_ONLY
250 # include "cmnintrin.h"
253 #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
261 # if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
265 const char * szFileName,
269 void * operator new[](
272 const char * szFileName,
276 void operator delete(
278 int, const char*, int, int
280 void operator delete(
283 void operator delete[]( void * p );
284 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
286 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
288 # define new DEBUG_CLIENTBLOCK
290 # define DEBUG_CLIENTBLOCK
294 //////////////////////////////////////////////////////////////////////
297 # if defined(_MSC_VER)
298 # define SK_OVERRIDE override
299 # elif defined(__clang__)
300 // Using __attribute__((override)) on clang does not appear to always work.
301 // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no
302 // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing
303 // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma).
304 # pragma clang diagnostic ignored "-Wc++11-extensions"
306 # if __has_feature(cxx_override_control)
307 # define SK_OVERRIDE override
308 # elif defined(__has_extension) && __has_extension(cxx_override_control)
309 # define SK_OVERRIDE override
317 //////////////////////////////////////////////////////////////////////
319 #if !defined(SK_UNUSED)
320 # define SK_UNUSED SK_ATTRIBUTE(unused)
323 #if !defined(SK_ATTR_DEPRECATED)
324 // FIXME: we ignore msg for now...
325 # define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated)
328 #if !defined(SK_ATTR_EXTERNALLY_DEPRECATED)
329 # if !defined(SK_INTERNAL)
330 # define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg)
332 # define SK_ATTR_EXTERNALLY_DEPRECATED(msg)
337 * If your judgment is better than the compiler's (i.e. you've profiled it),
338 * you can use SK_ALWAYS_INLINE to force inlining. E.g.
339 * inline void someMethod() { ... } // may not be inlined
340 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined
342 #if !defined(SK_ALWAYS_INLINE)
343 # if defined(SK_BUILD_FOR_WIN)
344 # define SK_ALWAYS_INLINE __forceinline
346 # define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
350 //////////////////////////////////////////////////////////////////////
352 #if defined(__clang__) || defined(__GNUC__)
353 # define SK_PREFETCH(ptr) __builtin_prefetch(ptr)
354 # define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1)
356 # define SK_PREFETCH(ptr)
357 # define SK_WRITE_PREFETCH(ptr)
360 //////////////////////////////////////////////////////////////////////
362 #ifndef SK_PRINTF_LIKE
363 # if defined(__clang__) || defined(__GNUC__)
364 # define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
366 # define SK_PRINTF_LIKE(A, B)
370 //////////////////////////////////////////////////////////////////////
372 #ifndef SK_SIZE_T_SPECIFIER
373 # if defined(_MSC_VER)
374 # define SK_SIZE_T_SPECIFIER "%Iu"
376 # define SK_SIZE_T_SPECIFIER "%zu"
380 //////////////////////////////////////////////////////////////////////
382 #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
383 # define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
386 //////////////////////////////////////////////////////////////////////
388 #ifndef SK_ATOMICS_PLATFORM_H
389 # if defined(_MSC_VER)
390 # define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h"
392 # define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h"
396 #ifndef SK_MUTEX_PLATFORM_H
397 # if defined(SK_BUILD_FOR_WIN)
398 # define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h"
400 # define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h"
404 #ifndef SK_BARRIERS_PLATFORM_H
405 # if SK_HAS_COMPILER_FEATURE(thread_sanitizer)
406 # define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_tsan.h"
407 # elif defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
408 # define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h"
410 # define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h"
414 //////////////////////////////////////////////////////////////////////
417 # if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_NACL)
424 //////////////////////////////////////////////////////////////////////
426 #if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB)
427 # error "cannot define both SK_GAMMA_EXPONENT and SK_GAMMA_SRGB"
428 #elif defined(SK_GAMMA_SRGB)
429 # define SK_GAMMA_EXPONENT (0.0f)
430 #elif !defined(SK_GAMMA_EXPONENT)
431 # define SK_GAMMA_EXPONENT (2.2f)
434 #endif // SkPostConfig_DEFINED