SkPostConfig.h revision 3c12840b234e614faf569e80f311a77ce65d9fe0
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#if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT) 26# error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT" 27#elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT) 28# define SK_SCALAR_IS_FLOAT 29#endif 30 31/** 32 * Matrix calculations may be float or double. 33 * The default is double, as that is faster given our impl uses doubles 34 * for intermediate calculations. 35 */ 36#if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT) 37# error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT" 38#elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT) 39# define SK_MSCALAR_IS_DOUBLE 40#endif 41 42#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) 43# error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN" 44#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN) 45# error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN" 46#endif 47 48/** 49 * Ensure the port has defined all of SK_X32_SHIFT, or none of them. 50 */ 51#ifdef SK_A32_SHIFT 52# if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT) 53# error "all or none of the 32bit SHIFT amounts must be defined" 54# endif 55#else 56# if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT) 57# error "all or none of the 32bit SHIFT amounts must be defined" 58# endif 59#endif 60 61#if !defined(SK_HAS_COMPILER_FEATURE) 62# if defined(__has_feature) 63# define SK_HAS_COMPILER_FEATURE(x) __has_feature(x) 64# else 65# define SK_HAS_COMPILER_FEATURE(x) 0 66# endif 67#endif 68 69#if !defined(SK_ATTRIBUTE) 70# if defined(__clang__) || defined(__GNUC__) 71# define SK_ATTRIBUTE(attr) __attribute__((attr)) 72# else 73# define SK_ATTRIBUTE(attr) 74# endif 75#endif 76 77#if !defined(SK_SUPPORT_GPU) 78# define SK_SUPPORT_GPU 1 79#endif 80 81/** 82 * The clang static analyzer likes to know that when the program is not 83 * expected to continue (crash, assertion failure, etc). It will notice that 84 * some combination of parameters lead to a function call that does not return. 85 * It can then make appropriate assumptions about the parameters in code 86 * executed only if the non-returning function was *not* called. 87 */ 88#if !defined(SkNO_RETURN_HINT) 89# if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn) 90 static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); 91 static inline void SkNO_RETURN_HINT() {} 92# else 93# define SkNO_RETURN_HINT() do {} while (false) 94# endif 95#endif 96 97#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB) 98# error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB" 99#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB) 100# define SK_HAS_ZLIB 101#endif 102 103/////////////////////////////////////////////////////////////////////////////// 104 105#ifndef SkNEW 106# define SkNEW(type_name) (new type_name) 107# define SkNEW_ARGS(type_name, args) (new type_name args) 108# define SkNEW_ARRAY(type_name, count) (new type_name[(count)]) 109# define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name) 110# define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args) 111# define SkDELETE(obj) (delete (obj)) 112# define SkDELETE_ARRAY(array) (delete[] (array)) 113#endif 114 115#ifndef SK_CRASH 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 123/////////////////////////////////////////////////////////////////////////////// 124 125/** 126 * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects 127 * are still held on exit. 128 * Defaults to 1 in DEBUG and 0 in RELEASE. 129 * FIXME: currently always 0, since it fails if multiple threads run at once 130 * (see skbug.com/1219 ). 131 */ 132#ifndef SK_ENABLE_INST_COUNT 133# ifdef SK_DEBUG 134# define SK_ENABLE_INST_COUNT 0 135# else 136# define SK_ENABLE_INST_COUNT 0 137# endif 138#endif 139 140/////////////////////////////////////////////////////////////////////////////// 141 142#ifdef SK_BUILD_FOR_WIN 143# ifndef WIN32_LEAN_AND_MEAN 144# define WIN32_LEAN_AND_MEAN 145# define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 146# endif 147# ifndef NOMINMAX 148# define NOMINMAX 149# define NOMINMAX_WAS_LOCALLY_DEFINED 150# endif 151# 152# include <windows.h> 153# 154# ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 155# undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 156# undef WIN32_LEAN_AND_MEAN 157# endif 158# ifdef NOMINMAX_WAS_LOCALLY_DEFINED 159# undef NOMINMAX_WAS_LOCALLY_DEFINED 160# undef NOMINMAX 161# endif 162# 163# ifndef SK_DEBUGBREAK 164# define SK_DEBUGBREAK(p) do { if (!(p)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false) 165# endif 166# 167# ifndef SK_A32_SHIFT 168# define SK_A32_SHIFT 24 169# define SK_R32_SHIFT 16 170# define SK_G32_SHIFT 8 171# define SK_B32_SHIFT 0 172# endif 173# 174#else 175# ifdef SK_DEBUG 176# include <stdio.h> 177# ifndef SK_DEBUGBREAK 178# define SK_DEBUGBREAK(cond) do { if (cond) break; \ 179 SkDebugf("%s:%d: failed assertion \"%s\"\n", \ 180 __FILE__, __LINE__, #cond); SK_CRASH(); } while (false) 181# endif 182# endif 183#endif 184 185/** 186 * We check to see if the SHIFT value has already been defined. 187 * if not, we define it ourself to some default values. We default to OpenGL 188 * order (in memory: r,g,b,a) 189 */ 190#ifndef SK_A32_SHIFT 191# ifdef SK_CPU_BENDIAN 192# define SK_R32_SHIFT 24 193# define SK_G32_SHIFT 16 194# define SK_B32_SHIFT 8 195# define SK_A32_SHIFT 0 196# else 197# define SK_R32_SHIFT 0 198# define SK_G32_SHIFT 8 199# define SK_B32_SHIFT 16 200# define SK_A32_SHIFT 24 201# endif 202#endif 203 204/** 205 * SkColor has well defined shift values, but SkPMColor is configurable. This 206 * macro is a convenience that returns true if the shift values are equal while 207 * ignoring the machine's endianness. 208 */ 209#define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \ 210 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0) 211 212/** 213 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The 214 * relationship between the byte order and shift values depends on machine endianness. If the shift 215 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little 216 * endian machine and the A channel on a big endian machine. Thus, given those shifts values, 217 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and 218 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine. 219 */ 220#ifdef SK_CPU_BENDIAN 221# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 222 (SK_ ## C3 ## 32_SHIFT == 0 && \ 223 SK_ ## C2 ## 32_SHIFT == 8 && \ 224 SK_ ## C1 ## 32_SHIFT == 16 && \ 225 SK_ ## C0 ## 32_SHIFT == 24) 226#else 227# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 228 (SK_ ## C0 ## 32_SHIFT == 0 && \ 229 SK_ ## C1 ## 32_SHIFT == 8 && \ 230 SK_ ## C2 ## 32_SHIFT == 16 && \ 231 SK_ ## C3 ## 32_SHIFT == 24) 232#endif 233 234////////////////////////////////////////////////////////////////////// 235 236#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) 237# ifndef SkLONGLONG 238# ifdef SK_BUILD_FOR_WIN32 239# define SkLONGLONG __int64 240# else 241# define SkLONGLONG long long 242# endif 243# endif 244#endif 245 246////////////////////////////////////////////////////////////////////////////////////////////// 247#ifndef SK_BUILD_FOR_WINCE 248# include <string.h> 249# include <stdlib.h> 250#else 251# define _CMNINTRIN_DECLARE_ONLY 252# include "cmnintrin.h" 253#endif 254 255#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 256# ifdef free 257# undef free 258# endif 259# include <crtdbg.h> 260# undef free 261# 262# ifdef SK_DEBUGx 263# if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus) 264 void * operator new( 265 size_t cb, 266 int nBlockUse, 267 const char * szFileName, 268 int nLine, 269 int foo 270 ); 271 void * operator new[]( 272 size_t cb, 273 int nBlockUse, 274 const char * szFileName, 275 int nLine, 276 int foo 277 ); 278 void operator delete( 279 void *pUserData, 280 int, const char*, int, int 281 ); 282 void operator delete( 283 void *pUserData 284 ); 285 void operator delete[]( void * p ); 286# define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0) 287# else 288# define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) 289# endif 290# define new DEBUG_CLIENTBLOCK 291# else 292# define DEBUG_CLIENTBLOCK 293# endif 294#endif 295 296////////////////////////////////////////////////////////////////////// 297 298#ifndef SK_OVERRIDE 299# if defined(_MSC_VER) 300# define SK_OVERRIDE override 301# elif defined(__clang__) 302 // Using __attribute__((override)) on clang does not appear to always work. 303 // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no 304 // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing 305 // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma). 306# pragma clang diagnostic ignored "-Wc++11-extensions" 307# 308# if __has_feature(cxx_override_control) 309# define SK_OVERRIDE override 310# elif defined(__has_extension) && __has_extension(cxx_override_control) 311# define SK_OVERRIDE override 312# endif 313# endif 314# ifndef SK_OVERRIDE 315# define SK_OVERRIDE 316# endif 317#endif 318 319////////////////////////////////////////////////////////////////////// 320 321#if !defined(SK_UNUSED) 322# define SK_UNUSED SK_ATTRIBUTE(unused) 323#endif 324 325#if !defined(SK_ATTR_DEPRECATED) 326 // FIXME: we ignore msg for now... 327# define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated) 328#endif 329 330/** 331 * If your judgment is better than the compiler's (i.e. you've profiled it), 332 * you can use SK_ALWAYS_INLINE to force inlining. E.g. 333 * inline void someMethod() { ... } // may not be inlined 334 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined 335 */ 336#if !defined(SK_ALWAYS_INLINE) 337# if defined(SK_BUILD_FOR_WIN) 338# define SK_ALWAYS_INLINE __forceinline 339# else 340# define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline 341# endif 342#endif 343 344////////////////////////////////////////////////////////////////////// 345 346#if defined(__clang__) || defined(__GNUC__) 347# define SK_PREFETCH(ptr) __builtin_prefetch(ptr) 348# define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) 349#else 350# define SK_PREFETCH(ptr) 351# define SK_WRITE_PREFETCH(ptr) 352#endif 353 354////////////////////////////////////////////////////////////////////// 355 356#ifndef SK_PRINTF_LIKE 357# if defined(__clang__) || defined(__GNUC__) 358# define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 359# else 360# define SK_PRINTF_LIKE(A, B) 361# endif 362#endif 363 364////////////////////////////////////////////////////////////////////// 365 366#ifndef SK_SIZE_T_SPECIFIER 367# if defined(_MSC_VER) 368# define SK_SIZE_T_SPECIFIER "%Iu" 369# else 370# define SK_SIZE_T_SPECIFIER "%zu" 371# endif 372#endif 373 374////////////////////////////////////////////////////////////////////// 375 376#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 377# define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1 378#endif 379 380#endif // SkPostConfig_DEFINED 381