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