SkPostConfig.h revision f3f2d1619e34deb6a1a8cf623f432927e09d0d3c
1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SkPostConfig_DEFINED
11#define SkPostConfig_DEFINED
12
13#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
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#if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT)
28    #error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT"
29#elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
30    #define SK_SCALAR_IS_FLOAT
31#endif
32
33#if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT)
34    #error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT"
35#elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT)
36    // default is double, as that is faster given our impl uses doubles
37    // for intermediate calculations.
38    #define SK_MSCALAR_IS_DOUBLE
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// ensure the port has defined all of these, or none of them
48#ifdef SK_A32_SHIFT
49    #if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
50        #error "all or none of the 32bit SHIFT amounts must be defined"
51    #endif
52#else
53    #if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
54        #error "all or none of the 32bit SHIFT amounts must be defined"
55    #endif
56#endif
57
58#if !defined(SK_HAS_COMPILER_FEATURE)
59    #if defined(__has_feature)
60        #define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
61    #else
62        #define SK_HAS_COMPILER_FEATURE(x) 0
63    #endif
64#endif
65
66#if !defined(SK_SUPPORT_GPU)
67    #define SK_SUPPORT_GPU 1
68#endif
69
70/**
71 * The clang static analyzer likes to know that when the program is not
72 * expected to continue (crash, assertion failure, etc). It will notice that
73 * some combination of parameters lead to a function call that does not return.
74 * It can then make appropriate assumptions about the parameters in code
75 * executed only if the non-returning function was *not* called.
76 */
77#if !defined(SkNO_RETURN_HINT)
78    #if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
79        static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
80        static inline void SkNO_RETURN_HINT() {}
81    #else
82        #define SkNO_RETURN_HINT() do {} while (false)
83    #endif
84#endif
85
86#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
87    #error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
88#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
89    #define SK_HAS_ZLIB
90#endif
91
92///////////////////////////////////////////////////////////////////////////////
93
94#ifndef SkNEW
95    #define SkNEW(type_name)                (new type_name)
96    #define SkNEW_ARGS(type_name, args)     (new type_name args)
97    #define SkNEW_ARRAY(type_name, count)   (new type_name[(count)])
98    #define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name)
99    #define SkNEW_PLACEMENT_ARGS(buf, type_name, args) \
100                                            (new (buf) type_name args)
101    #define SkDELETE(obj)                   (delete (obj))
102    #define SkDELETE_ARRAY(array)           (delete[] (array))
103#endif
104
105#ifndef SK_CRASH
106#if 1   // set to 0 for infinite loop, which can help connecting gdb
107    #define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
108#else
109    #define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
110#endif
111#endif
112
113///////////////////////////////////////////////////////////////////////////////
114
115// SK_ENABLE_INST_COUNT defaults to 1 in DEBUG and 0 in RELEASE
116#ifndef SK_ENABLE_INST_COUNT
117    #ifdef SK_DEBUG
118        // FIXME: fails if multiple threads run at once (see skbug.com/1219 )
119        #define SK_ENABLE_INST_COUNT 0
120    #else
121        #define SK_ENABLE_INST_COUNT 0
122    #endif
123#endif
124
125///////////////////////////////////////////////////////////////////////////////
126
127#if defined(SK_SOFTWARE_FLOAT) && defined(SK_SCALAR_IS_FLOAT)
128    // if this is defined, we convert floats to 2scompliment ints for compares
129    #ifndef SK_SCALAR_SLOW_COMPARES
130        #define SK_SCALAR_SLOW_COMPARES
131    #endif
132    #ifndef SK_USE_FLOATBITS
133        #define SK_USE_FLOATBITS
134    #endif
135#endif
136
137#ifdef SK_BUILD_FOR_WIN
138    // we want lean_and_mean when we include windows.h
139    #ifndef WIN32_LEAN_AND_MEAN
140        #define WIN32_LEAN_AND_MEAN
141        #define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
142    #endif
143    #ifndef NOMINMAX
144        #define NOMINMAX
145        #define NOMINMAX_WAS_LOCALLY_DEFINED
146    #endif
147
148    #include <windows.h>
149
150    #ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
151        #undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
152        #undef WIN32_LEAN_AND_MEAN
153    #endif
154
155    #ifdef NOMINMAX_WAS_LOCALLY_DEFINED
156        #undef NOMINMAX_WAS_LOCALLY_DEFINED
157        #undef NOMINMAX
158    #endif
159
160    #ifndef SK_DEBUGBREAK
161        #define SK_DEBUGBREAK(cond)     do { if (!(cond)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false)
162    #endif
163
164    #ifndef SK_A32_SHIFT
165        #define SK_A32_SHIFT 24
166        #define SK_R32_SHIFT 16
167        #define SK_G32_SHIFT 8
168        #define SK_B32_SHIFT 0
169    #endif
170
171#else
172    #ifdef SK_DEBUG
173        #include <stdio.h>
174        #ifndef SK_DEBUGBREAK
175            #define SK_DEBUGBREAK(cond) do { if (cond) break; \
176                SkDebugf("%s:%d: failed assertion \"%s\"\n", \
177                __FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
178        #endif
179    #endif
180#endif
181
182/*
183 *  We check to see if the SHIFT value has already been defined.
184 *  if not, we define it ourself to some default values. We default to OpenGL
185 *  order (in memory: r,g,b,a)
186 */
187#ifndef SK_A32_SHIFT
188    #ifdef SK_CPU_BENDIAN
189        #define SK_R32_SHIFT    24
190        #define SK_G32_SHIFT    16
191        #define SK_B32_SHIFT    8
192        #define SK_A32_SHIFT    0
193    #else
194        #define SK_R32_SHIFT    0
195        #define SK_G32_SHIFT    8
196        #define SK_B32_SHIFT    16
197        #define SK_A32_SHIFT    24
198    #endif
199#endif
200
201/**
202 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
203 * relationship between the byte order and shift values depends on machine endianness. If the shift
204 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
205 * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
206 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
207 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
208 */
209#ifdef SK_CPU_BENDIAN
210    #define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
211        (SK_ ## C3 ## 32_SHIFT == 0  &&             \
212         SK_ ## C2 ## 32_SHIFT == 8  &&             \
213         SK_ ## C1 ## 32_SHIFT == 16 &&             \
214         SK_ ## C0 ## 32_SHIFT == 24)
215#else
216    #define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
217        (SK_ ## C0 ## 32_SHIFT == 0  &&             \
218         SK_ ## C1 ## 32_SHIFT == 8  &&             \
219         SK_ ## C2 ## 32_SHIFT == 16 &&             \
220         SK_ ## C3 ## 32_SHIFT == 24)
221#endif
222
223//  stdlib macros
224
225#if 0
226#if !defined(strlen) && defined(SK_DEBUG)
227    extern size_t sk_strlen(const char*);
228    #define strlen(s)   sk_strlen(s)
229#endif
230#ifndef sk_strcpy
231    #define sk_strcpy(dst, src)     strcpy(dst, src)
232#endif
233#ifndef sk_strchr
234    #define sk_strchr(s, c)         strchr(s, c)
235#endif
236#ifndef sk_strrchr
237    #define sk_strrchr(s, c)        strrchr(s, c)
238#endif
239#ifndef sk_strcmp
240    #define sk_strcmp(s, t)         strcmp(s, t)
241#endif
242#ifndef sk_strncmp
243    #define sk_strncmp(s, t, n)     strncmp(s, t, n)
244#endif
245#ifndef sk_memcpy
246    #define sk_memcpy(dst, src, n)  memcpy(dst, src, n)
247#endif
248#ifndef memmove
249    #define memmove(dst, src, n)    memmove(dst, src, n)
250#endif
251#ifndef sk_memset
252    #define sk_memset(dst, val, n)  memset(dst, val, n)
253#endif
254#ifndef sk_memcmp
255    #define sk_memcmp(s, t, n)      memcmp(s, t, n)
256#endif
257
258#define sk_strequal(s, t)           (!sk_strcmp(s, t))
259#define sk_strnequal(s, t, n)       (!sk_strncmp(s, t, n))
260#endif
261
262//////////////////////////////////////////////////////////////////////
263
264#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
265    #ifndef SkLONGLONG
266        #ifdef SK_BUILD_FOR_WIN32
267            #define SkLONGLONG  __int64
268        #else
269            #define SkLONGLONG  long long
270        #endif
271    #endif
272#endif
273
274//////////////////////////////////////////////////////////////////////////////////////////////
275#ifndef SK_BUILD_FOR_WINCE
276#include <string.h>
277#include <stdlib.h>
278#else
279#define _CMNINTRIN_DECLARE_ONLY
280#include "cmnintrin.h"
281#endif
282
283#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
284//#define _CRTDBG_MAP_ALLOC
285#ifdef free
286#undef free
287#endif
288#include <crtdbg.h>
289#undef free
290
291#ifdef SK_DEBUGx
292#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
293    void * operator new(
294        size_t cb,
295        int nBlockUse,
296        const char * szFileName,
297        int nLine,
298        int foo
299        );
300    void * operator new[](
301        size_t cb,
302        int nBlockUse,
303        const char * szFileName,
304        int nLine,
305        int foo
306        );
307    void operator delete(
308        void *pUserData,
309        int, const char*, int, int
310        );
311    void operator delete(
312        void *pUserData
313        );
314    void operator delete[]( void * p );
315    #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
316#else
317    #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
318#endif
319    #define new DEBUG_CLIENTBLOCK
320#else
321#define DEBUG_CLIENTBLOCK
322#endif // _DEBUG
323
324
325#endif
326
327#endif
328
329//////////////////////////////////////////////////////////////////////
330
331#ifndef SK_OVERRIDE
332    #if defined(_MSC_VER)
333        #define SK_OVERRIDE override
334    #elif defined(__clang__)
335        // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no
336        // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing
337        // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma).
338        #pragma clang diagnostic ignored "-Wc++11-extensions"
339
340        #if __has_feature(cxx_override_control)
341            // Some documentation suggests we should be using __attribute__((override)),
342            // but it doesn't work.
343            #define SK_OVERRIDE override
344        #elif defined(__has_extension)
345            #if __has_extension(cxx_override_control)
346                #define SK_OVERRIDE override
347            #endif
348        #endif
349    #else
350        // Linux GCC ignores "__attribute__((override))" and rejects "override".
351        #define SK_OVERRIDE
352    #endif
353#endif
354
355//////////////////////////////////////////////////////////////////////
356
357#ifndef SK_PRINTF_LIKE
358#if defined(__clang__) || defined(__GNUC__)
359#define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
360#else
361#define SK_PRINTF_LIKE(A, B)
362#endif
363#endif
364
365//////////////////////////////////////////////////////////////////////
366
367#ifndef SK_SIZE_T_SPECIFIER
368#if defined(_MSC_VER)
369#define SK_SIZE_T_SPECIFIER "%Iu"
370#else
371#define SK_SIZE_T_SPECIFIER "%zu"
372#endif
373#endif
374
375//////////////////////////////////////////////////////////////////////
376
377#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
378#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
379#endif
380