SkPostConfig.h revision af159a580b29488c717c8ae7ee442dbe006a20ba
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/** 72 * Used to align stack allocated variables/buffers. 73 * Different compilers have different ways to accomplish this. 74 */ 75#if defined(_MSC_VER) 76# define SK_ALIGN(x) __declspec(align(x)) 77#else 78# define SK_ALIGN(x) __attribute__((aligned(x))) 79#endif 80 81#if !defined(SK_SUPPORT_GPU) 82# define SK_SUPPORT_GPU 1 83#endif 84 85/** 86 * The clang static analyzer likes to know that when the program is not 87 * expected to continue (crash, assertion failure, etc). It will notice that 88 * some combination of parameters lead to a function call that does not return. 89 * It can then make appropriate assumptions about the parameters in code 90 * executed only if the non-returning function was *not* called. 91 */ 92#if !defined(SkNO_RETURN_HINT) 93# if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn) 94 static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); 95 static inline void SkNO_RETURN_HINT() {} 96# else 97# define SkNO_RETURN_HINT() do {} while (false) 98# endif 99#endif 100 101#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB) 102# error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB" 103#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB) 104# define SK_HAS_ZLIB 105#endif 106 107/////////////////////////////////////////////////////////////////////////////// 108 109#ifndef SkNEW 110# define SkNEW(type_name) (new type_name) 111# define SkNEW_ARGS(type_name, args) (new type_name args) 112# define SkNEW_ARRAY(type_name, count) (new type_name[(count)]) 113# define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name) 114# define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args) 115# define SkDELETE(obj) (delete (obj)) 116# define SkDELETE_ARRAY(array) (delete[] (array)) 117#endif 118 119#ifndef SK_CRASH 120# if 1 // set to 0 for infinite loop, which can help connecting gdb 121# define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false) 122# else 123# define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true) 124# endif 125#endif 126 127/////////////////////////////////////////////////////////////////////////////// 128 129/** 130 * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects 131 * are still held on exit. 132 * Defaults to 1 in DEBUG and 0 in RELEASE. 133 */ 134#ifndef SK_ENABLE_INST_COUNT 135# ifdef SK_DEBUG 136// Only enabled for static builds, because instance counting relies on static 137// variables in functions defined in header files. 138# define SK_ENABLE_INST_COUNT !defined(SKIA_DLL) 139# else 140# define SK_ENABLE_INST_COUNT 0 141# endif 142#endif 143 144/////////////////////////////////////////////////////////////////////////////// 145 146#ifdef SK_BUILD_FOR_WIN 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# ifdef NOMINMAX_WAS_LOCALLY_DEFINED 163# undef NOMINMAX_WAS_LOCALLY_DEFINED 164# undef NOMINMAX 165# endif 166# 167# ifndef SK_ALWAYSBREAK 168# define SK_ALWAYSBREAK(p) do { if (!(p)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false) 169# endif 170# 171# ifndef SK_A32_SHIFT 172# define SK_A32_SHIFT 24 173# define SK_R32_SHIFT 16 174# define SK_G32_SHIFT 8 175# define SK_B32_SHIFT 0 176# endif 177# 178#else 179# ifndef SK_ALWAYSBREAK 180# ifdef SK_DEBUG 181# include <stdio.h> 182# define SK_ALWAYSBREAK(cond) do { if (cond) break; \ 183 SkDebugf("%s:%d: failed assertion \"%s\"\n", \ 184 __FILE__, __LINE__, #cond); SK_CRASH(); } while (false) 185# else 186# define SK_ALWAYSBREAK(cond) do { if (cond) break; SK_CRASH(); } while (false) 187# endif 188# endif 189#endif 190 191/** 192 * We check to see if the SHIFT value has already been defined. 193 * if not, we define it ourself to some default values. We default to OpenGL 194 * order (in memory: r,g,b,a) 195 */ 196#ifndef SK_A32_SHIFT 197# ifdef SK_CPU_BENDIAN 198# define SK_R32_SHIFT 24 199# define SK_G32_SHIFT 16 200# define SK_B32_SHIFT 8 201# define SK_A32_SHIFT 0 202# else 203# define SK_R32_SHIFT 0 204# define SK_G32_SHIFT 8 205# define SK_B32_SHIFT 16 206# define SK_A32_SHIFT 24 207# endif 208#endif 209 210/** 211 * SkColor has well defined shift values, but SkPMColor is configurable. This 212 * macro is a convenience that returns true if the shift values are equal while 213 * ignoring the machine's endianness. 214 */ 215#define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \ 216 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0) 217 218/** 219 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The 220 * relationship between the byte order and shift values depends on machine endianness. If the shift 221 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little 222 * endian machine and the A channel on a big endian machine. Thus, given those shifts values, 223 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and 224 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine. 225 */ 226#ifdef SK_CPU_BENDIAN 227# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 228 (SK_ ## C3 ## 32_SHIFT == 0 && \ 229 SK_ ## C2 ## 32_SHIFT == 8 && \ 230 SK_ ## C1 ## 32_SHIFT == 16 && \ 231 SK_ ## C0 ## 32_SHIFT == 24) 232#else 233# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 234 (SK_ ## C0 ## 32_SHIFT == 0 && \ 235 SK_ ## C1 ## 32_SHIFT == 8 && \ 236 SK_ ## C2 ## 32_SHIFT == 16 && \ 237 SK_ ## C3 ## 32_SHIFT == 24) 238#endif 239 240////////////////////////////////////////////////////////////////////// 241 242// TODO: rebaseline as needed so we can remove this flag entirely. 243// - all platforms have int64_t now 244// - we have slightly different fixed math results because of this check 245// since we don't define this for linux/android 246#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) 247# ifndef SkLONGLONG 248# define SkLONGLONG int64_t 249# endif 250#endif 251 252////////////////////////////////////////////////////////////////////////////////////////////// 253#ifndef SK_BUILD_FOR_WINCE 254# include <string.h> 255# include <stdlib.h> 256#else 257# define _CMNINTRIN_DECLARE_ONLY 258# include "cmnintrin.h" 259#endif 260 261#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 262# ifdef free 263# undef free 264# endif 265# include <crtdbg.h> 266# undef free 267# 268# ifdef SK_DEBUGx 269# if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus) 270 void * operator new( 271 size_t cb, 272 int nBlockUse, 273 const char * szFileName, 274 int nLine, 275 int foo 276 ); 277 void * operator new[]( 278 size_t cb, 279 int nBlockUse, 280 const char * szFileName, 281 int nLine, 282 int foo 283 ); 284 void operator delete( 285 void *pUserData, 286 int, const char*, int, int 287 ); 288 void operator delete( 289 void *pUserData 290 ); 291 void operator delete[]( void * p ); 292# define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0) 293# else 294# define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) 295# endif 296# define new DEBUG_CLIENTBLOCK 297# else 298# define DEBUG_CLIENTBLOCK 299# endif 300#endif 301 302////////////////////////////////////////////////////////////////////// 303 304#ifndef SK_OVERRIDE 305# if defined(_MSC_VER) 306# define SK_OVERRIDE override 307# elif defined(__clang__) 308 // Using __attribute__((override)) on clang does not appear to always work. 309 // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no 310 // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing 311 // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma). 312# pragma clang diagnostic ignored "-Wc++11-extensions" 313# 314# if __has_feature(cxx_override_control) 315# define SK_OVERRIDE override 316# elif defined(__has_extension) && __has_extension(cxx_override_control) 317# define SK_OVERRIDE override 318# endif 319# endif 320# ifndef SK_OVERRIDE 321# define SK_OVERRIDE 322# endif 323#endif 324 325////////////////////////////////////////////////////////////////////// 326 327#if !defined(SK_UNUSED) 328# define SK_UNUSED SK_ATTRIBUTE(unused) 329#endif 330 331#if !defined(SK_ATTR_DEPRECATED) 332 // FIXME: we ignore msg for now... 333# define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated) 334#endif 335 336#if !defined(SK_ATTR_EXTERNALLY_DEPRECATED) 337# if !defined(SK_INTERNAL) 338# define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg) 339# else 340# define SK_ATTR_EXTERNALLY_DEPRECATED(msg) 341# endif 342#endif 343 344/** 345 * If your judgment is better than the compiler's (i.e. you've profiled it), 346 * you can use SK_ALWAYS_INLINE to force inlining. E.g. 347 * inline void someMethod() { ... } // may not be inlined 348 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined 349 */ 350#if !defined(SK_ALWAYS_INLINE) 351# if defined(SK_BUILD_FOR_WIN) 352# define SK_ALWAYS_INLINE __forceinline 353# else 354# define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline 355# endif 356#endif 357 358////////////////////////////////////////////////////////////////////// 359 360#if defined(__clang__) || defined(__GNUC__) 361# define SK_PREFETCH(ptr) __builtin_prefetch(ptr) 362# define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) 363#else 364# define SK_PREFETCH(ptr) 365# define SK_WRITE_PREFETCH(ptr) 366#endif 367 368////////////////////////////////////////////////////////////////////// 369 370#ifndef SK_PRINTF_LIKE 371# if defined(__clang__) || defined(__GNUC__) 372# define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 373# else 374# define SK_PRINTF_LIKE(A, B) 375# endif 376#endif 377 378////////////////////////////////////////////////////////////////////// 379 380#ifndef SK_SIZE_T_SPECIFIER 381# if defined(_MSC_VER) 382# define SK_SIZE_T_SPECIFIER "%Iu" 383# else 384# define SK_SIZE_T_SPECIFIER "%zu" 385# endif 386#endif 387 388////////////////////////////////////////////////////////////////////// 389 390#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 391# define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1 392#endif 393 394////////////////////////////////////////////////////////////////////// 395 396#ifndef SK_ATOMICS_PLATFORM_H 397# if defined(_MSC_VER) 398# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h" 399# elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) 400# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_android.h" 401# else 402# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h" 403# endif 404#endif 405 406#ifndef SK_MUTEX_PLATFORM_H 407# if defined(SK_BUILD_FOR_WIN) 408# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h" 409# else 410# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h" 411# endif 412#endif 413 414 415////////////////////////////////////////////////////////////////////// 416 417#if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB) 418# error "cannot define both SK_GAMMA_EXPONENT and SK_GAMMA_SRGB" 419#elif defined(SK_GAMMA_SRGB) 420# define SK_GAMMA_EXPONENT (0.0f) 421#elif !defined(SK_GAMMA_EXPONENT) 422# define SK_GAMMA_EXPONENT (2.2f) 423#endif 424 425#endif // SkPostConfig_DEFINED 426