SkPostConfig.h revision 6fcbfcead5dc1b61fa5b4c139a1a3714e8c58091
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 * SkColor has well defined shift values, but SkPMColor is configurable. This
211 * macro is a convenience that returns true if the shift values are equal while
212 * ignoring the machine's endianness.
213 */
214#define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \
215    (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0)
216
217/**
218 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
219 * relationship between the byte order and shift values depends on machine endianness. If the shift
220 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
221 * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
222 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
223 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
224 */
225#ifdef SK_CPU_BENDIAN
226    #define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
227        (SK_ ## C3 ## 32_SHIFT == 0  &&             \
228         SK_ ## C2 ## 32_SHIFT == 8  &&             \
229         SK_ ## C1 ## 32_SHIFT == 16 &&             \
230         SK_ ## C0 ## 32_SHIFT == 24)
231#else
232    #define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
233        (SK_ ## C0 ## 32_SHIFT == 0  &&             \
234         SK_ ## C1 ## 32_SHIFT == 8  &&             \
235         SK_ ## C2 ## 32_SHIFT == 16 &&             \
236         SK_ ## C3 ## 32_SHIFT == 24)
237#endif
238
239//  stdlib macros
240
241#if 0
242#if !defined(strlen) && defined(SK_DEBUG)
243    extern size_t sk_strlen(const char*);
244    #define strlen(s)   sk_strlen(s)
245#endif
246#ifndef sk_strcpy
247    #define sk_strcpy(dst, src)     strcpy(dst, src)
248#endif
249#ifndef sk_strchr
250    #define sk_strchr(s, c)         strchr(s, c)
251#endif
252#ifndef sk_strrchr
253    #define sk_strrchr(s, c)        strrchr(s, c)
254#endif
255#ifndef sk_strcmp
256    #define sk_strcmp(s, t)         strcmp(s, t)
257#endif
258#ifndef sk_strncmp
259    #define sk_strncmp(s, t, n)     strncmp(s, t, n)
260#endif
261#ifndef sk_memcpy
262    #define sk_memcpy(dst, src, n)  memcpy(dst, src, n)
263#endif
264#ifndef memmove
265    #define memmove(dst, src, n)    memmove(dst, src, n)
266#endif
267#ifndef sk_memset
268    #define sk_memset(dst, val, n)  memset(dst, val, n)
269#endif
270#ifndef sk_memcmp
271    #define sk_memcmp(s, t, n)      memcmp(s, t, n)
272#endif
273
274#define sk_strequal(s, t)           (!sk_strcmp(s, t))
275#define sk_strnequal(s, t, n)       (!sk_strncmp(s, t, n))
276#endif
277
278//////////////////////////////////////////////////////////////////////
279
280#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
281    #ifndef SkLONGLONG
282        #ifdef SK_BUILD_FOR_WIN32
283            #define SkLONGLONG  __int64
284        #else
285            #define SkLONGLONG  long long
286        #endif
287    #endif
288#endif
289
290//////////////////////////////////////////////////////////////////////////////////////////////
291#ifndef SK_BUILD_FOR_WINCE
292#include <string.h>
293#include <stdlib.h>
294#else
295#define _CMNINTRIN_DECLARE_ONLY
296#include "cmnintrin.h"
297#endif
298
299#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
300//#define _CRTDBG_MAP_ALLOC
301#ifdef free
302#undef free
303#endif
304#include <crtdbg.h>
305#undef free
306
307#ifdef SK_DEBUGx
308#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
309    void * operator new(
310        size_t cb,
311        int nBlockUse,
312        const char * szFileName,
313        int nLine,
314        int foo
315        );
316    void * operator new[](
317        size_t cb,
318        int nBlockUse,
319        const char * szFileName,
320        int nLine,
321        int foo
322        );
323    void operator delete(
324        void *pUserData,
325        int, const char*, int, int
326        );
327    void operator delete(
328        void *pUserData
329        );
330    void operator delete[]( void * p );
331    #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
332#else
333    #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
334#endif
335    #define new DEBUG_CLIENTBLOCK
336#else
337#define DEBUG_CLIENTBLOCK
338#endif // _DEBUG
339
340
341#endif
342
343#endif
344
345//////////////////////////////////////////////////////////////////////
346
347#ifndef SK_OVERRIDE
348    #if defined(_MSC_VER)
349        #define SK_OVERRIDE override
350    #elif defined(__clang__)
351        // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no
352        // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing
353        // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma).
354        #pragma clang diagnostic ignored "-Wc++11-extensions"
355
356        #if __has_feature(cxx_override_control)
357            // Some documentation suggests we should be using __attribute__((override)),
358            // but it doesn't work.
359            #define SK_OVERRIDE override
360        #elif defined(__has_extension)
361            #if __has_extension(cxx_override_control)
362                #define SK_OVERRIDE override
363            #endif
364        #endif
365    #endif
366    #ifndef SK_OVERRIDE
367        #define SK_OVERRIDE
368    #endif
369#endif
370
371//////////////////////////////////////////////////////////////////////
372
373#if !defined(SK_UNUSED)
374    #define SK_UNUSED SK_ATTRIBUTE(unused)
375#endif
376
377//////////////////////////////////////////////////////////////////////
378
379#ifndef SK_PRINTF_LIKE
380#if defined(__clang__) || defined(__GNUC__)
381#define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
382#else
383#define SK_PRINTF_LIKE(A, B)
384#endif
385#endif
386
387//////////////////////////////////////////////////////////////////////
388
389#ifndef SK_SIZE_T_SPECIFIER
390#if defined(_MSC_VER)
391#define SK_SIZE_T_SPECIFIER "%Iu"
392#else
393#define SK_SIZE_T_SPECIFIER "%zu"
394#endif
395#endif
396
397//////////////////////////////////////////////////////////////////////
398
399#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
400#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
401#endif
402