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#ifndef SkPostConfig_DEFINED
9#define SkPostConfig_DEFINED
10
11#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
12#  define SK_BUILD_FOR_WIN
13#endif
14
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"
19#endif
20
21#if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG)
22#  error "can't have unittests without debug"
23#endif
24
25/**
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.
29 */
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
34#endif
35
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"
40#endif
41
42/**
43 * Ensure the port has defined all of SK_X32_SHIFT, or none of them.
44 */
45#ifdef SK_A32_SHIFT
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"
48#  endif
49#else
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"
52#  endif
53#endif
54
55#if !defined(SK_HAS_COMPILER_FEATURE)
56#  if defined(__has_feature)
57#    define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
58#  else
59#    define SK_HAS_COMPILER_FEATURE(x) 0
60#  endif
61#endif
62
63#if !defined(SK_ATTRIBUTE)
64#  if defined(__clang__) || defined(__GNUC__)
65#    define SK_ATTRIBUTE(attr) __attribute__((attr))
66#  else
67#    define SK_ATTRIBUTE(attr)
68#  endif
69#endif
70
71// As usual, there are two ways to increase alignment... the MSVC way and the everyone-else way.
72#ifndef SK_STRUCT_ALIGN
73    #ifdef _MSC_VER
74        #define SK_STRUCT_ALIGN(N) __declspec(align(N))
75    #else
76        #define SK_STRUCT_ALIGN(N) __attribute__((aligned(N)))
77    #endif
78#endif
79
80#if !defined(SK_SUPPORT_GPU)
81#  define SK_SUPPORT_GPU 1
82#endif
83
84/**
85 * The clang static analyzer likes to know that when the program is not
86 * expected to continue (crash, assertion failure, etc). It will notice that
87 * some combination of parameters lead to a function call that does not return.
88 * It can then make appropriate assumptions about the parameters in code
89 * executed only if the non-returning function was *not* called.
90 */
91#if !defined(SkNO_RETURN_HINT)
92#  if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
93     static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
94     static inline void SkNO_RETURN_HINT() {}
95#  else
96#    define SkNO_RETURN_HINT() do {} while (false)
97#  endif
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) (new (buf) type_name args)
108#  define SkDELETE(obj)                              (delete (obj))
109#  define SkDELETE_ARRAY(array)                      (delete[] (array))
110#endif
111
112#ifndef SK_CRASH
113#  ifdef SK_BUILD_FOR_WIN
114#    define SK_CRASH() __debugbreak()
115#  else
116#    if 1   // set to 0 for infinite loop, which can help connecting gdb
117#      define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
118#    else
119#      define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
120#    endif
121#  endif
122#endif
123
124///////////////////////////////////////////////////////////////////////////////
125
126/**
127 * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects
128 * are still held on exit.
129 * Defaults to 1 in DEBUG and 0 in RELEASE.
130 */
131#ifndef SK_ENABLE_INST_COUNT
132// Only enabled for static builds, because instance counting relies on static
133// variables in functions defined in header files.
134#  if SK_DEVELOPER && !defined(SKIA_DLL)
135#    define SK_ENABLE_INST_COUNT 1
136#  else
137#    define SK_ENABLE_INST_COUNT 0
138#  endif
139#endif
140
141///////////////////////////////////////////////////////////////////////////////
142
143#ifdef SK_BUILD_FOR_WIN
144#  ifndef WIN32_LEAN_AND_MEAN
145#    define WIN32_LEAN_AND_MEAN
146#    define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
147#  endif
148#  ifndef NOMINMAX
149#    define NOMINMAX
150#    define NOMINMAX_WAS_LOCALLY_DEFINED
151#  endif
152#
153#  include <windows.h>
154#
155#  ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
156#    undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
157#    undef WIN32_LEAN_AND_MEAN
158#  endif
159#  ifdef NOMINMAX_WAS_LOCALLY_DEFINED
160#    undef NOMINMAX_WAS_LOCALLY_DEFINED
161#    undef NOMINMAX
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#endif
172
173#ifndef SK_ALWAYSBREAK
174#  ifdef SK_DEBUG
175#    define SK_ALWAYSBREAK(cond) do { \
176              if (cond) break; \
177              SkNO_RETURN_HINT(); \
178              SkDebugf("%s:%d: failed assertion \"%s\"\n", __FILE__, __LINE__, #cond); \
179              SK_CRASH(); \
180        } while (false)
181#  else
182#    define SK_ALWAYSBREAK(cond) do { if (cond) break; SK_CRASH(); } while (false)
183#  endif
184#endif
185
186/**
187 *  We check to see if the SHIFT value has already been defined.
188 *  if not, we define it ourself to some default values. We default to OpenGL
189 *  order (in memory: r,g,b,a)
190 */
191#ifndef SK_A32_SHIFT
192#  ifdef SK_CPU_BENDIAN
193#    define SK_R32_SHIFT    24
194#    define SK_G32_SHIFT    16
195#    define SK_B32_SHIFT    8
196#    define SK_A32_SHIFT    0
197#  else
198#    define SK_R32_SHIFT    0
199#    define SK_G32_SHIFT    8
200#    define SK_B32_SHIFT    16
201#    define SK_A32_SHIFT    24
202#  endif
203#endif
204
205/**
206 * SkColor has well defined shift values, but SkPMColor is configurable. This
207 * macro is a convenience that returns true if the shift values are equal while
208 * ignoring the machine's endianness.
209 */
210#define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \
211    (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0)
212
213/**
214 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
215 * relationship between the byte order and shift values depends on machine endianness. If the shift
216 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
217 * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
218 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
219 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
220 */
221#ifdef SK_CPU_BENDIAN
222#  define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
223        (SK_ ## C3 ## 32_SHIFT == 0  &&             \
224         SK_ ## C2 ## 32_SHIFT == 8  &&             \
225         SK_ ## C1 ## 32_SHIFT == 16 &&             \
226         SK_ ## C0 ## 32_SHIFT == 24)
227#else
228#  define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)     \
229        (SK_ ## C0 ## 32_SHIFT == 0  &&             \
230         SK_ ## C1 ## 32_SHIFT == 8  &&             \
231         SK_ ## C2 ## 32_SHIFT == 16 &&             \
232         SK_ ## C3 ## 32_SHIFT == 24)
233#endif
234
235//////////////////////////////////////////////////////////////////////////////////////////////
236#ifndef SK_BUILD_FOR_WINCE
237#  include <string.h>
238#  include <stdlib.h>
239#else
240#  define _CMNINTRIN_DECLARE_ONLY
241#  include "cmnintrin.h"
242#endif
243
244#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
245#  ifdef free
246#    undef free
247#  endif
248#  include <crtdbg.h>
249#  undef free
250#
251#  ifdef SK_DEBUGx
252#    if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
253       void * operator new(
254           size_t cb,
255           int nBlockUse,
256           const char * szFileName,
257           int nLine,
258           int foo
259           );
260       void * operator new[](
261           size_t cb,
262           int nBlockUse,
263           const char * szFileName,
264           int nLine,
265           int foo
266           );
267       void operator delete(
268           void *pUserData,
269           int, const char*, int, int
270           );
271       void operator delete(
272           void *pUserData
273           );
274       void operator delete[]( void * p );
275#      define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
276#    else
277#      define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
278#    endif
279#    define new DEBUG_CLIENTBLOCK
280#  else
281#    define DEBUG_CLIENTBLOCK
282#  endif
283#endif
284
285//////////////////////////////////////////////////////////////////////
286
287#if !defined(SK_UNUSED)
288#  define SK_UNUSED SK_ATTRIBUTE(unused)
289#endif
290
291#if !defined(SK_ATTR_DEPRECATED)
292   // FIXME: we ignore msg for now...
293#  define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated)
294#endif
295
296#if !defined(SK_ATTR_EXTERNALLY_DEPRECATED)
297#  if !defined(SK_INTERNAL)
298#    define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg)
299#  else
300#    define SK_ATTR_EXTERNALLY_DEPRECATED(msg)
301#  endif
302#endif
303
304/**
305 * If your judgment is better than the compiler's (i.e. you've profiled it),
306 * you can use SK_ALWAYS_INLINE to force inlining. E.g.
307 *     inline void someMethod() { ... }             // may not be inlined
308 *     SK_ALWAYS_INLINE void someMethod() { ... }   // should always be inlined
309 */
310#if !defined(SK_ALWAYS_INLINE)
311#  if defined(SK_BUILD_FOR_WIN)
312#    define SK_ALWAYS_INLINE __forceinline
313#  else
314#    define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
315#  endif
316#endif
317
318//////////////////////////////////////////////////////////////////////
319
320#if defined(__clang__) || defined(__GNUC__)
321#  define SK_PREFETCH(ptr) __builtin_prefetch(ptr)
322#  define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1)
323#else
324#  define SK_PREFETCH(ptr)
325#  define SK_WRITE_PREFETCH(ptr)
326#endif
327
328//////////////////////////////////////////////////////////////////////
329
330#ifndef SK_PRINTF_LIKE
331#  if defined(__clang__) || defined(__GNUC__)
332#    define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
333#  else
334#    define SK_PRINTF_LIKE(A, B)
335#  endif
336#endif
337
338//////////////////////////////////////////////////////////////////////
339
340#ifndef SK_SIZE_T_SPECIFIER
341#  if defined(_MSC_VER)
342#    define SK_SIZE_T_SPECIFIER "%Iu"
343#  else
344#    define SK_SIZE_T_SPECIFIER "%zu"
345#  endif
346#endif
347
348//////////////////////////////////////////////////////////////////////
349
350#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
351#  define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
352#endif
353
354//////////////////////////////////////////////////////////////////////
355
356#ifndef SK_EGL
357#  if defined(SK_BUILD_FOR_ANDROID)
358#    define SK_EGL 1
359#  else
360#    define SK_EGL 0
361#  endif
362#endif
363
364//////////////////////////////////////////////////////////////////////
365
366#if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB)
367#  error "cannot define both SK_GAMMA_EXPONENT and SK_GAMMA_SRGB"
368#elif defined(SK_GAMMA_SRGB)
369#  define SK_GAMMA_EXPONENT (0.0f)
370#elif !defined(SK_GAMMA_EXPONENT)
371#  define SK_GAMMA_EXPONENT (2.2f)
372#endif
373
374//////////////////////////////////////////////////////////////////////
375
376#ifndef GR_TEST_UTILS
377#  define GR_TEST_UTILS 1
378#endif
379
380#endif // SkPostConfig_DEFINED
381