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