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