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 // IWYU pragma: private, include "SkTypes.h" 9 10 #ifndef SkPostConfig_DEFINED 11 #define SkPostConfig_DEFINED 12 13 #if defined(SK_BUILD_FOR_WIN32) 14 # define SK_BUILD_FOR_WIN 15 #endif 16 17 #if !defined(SK_DEBUG) && !defined(SK_RELEASE) 18 #ifdef NDEBUG 19 #define SK_RELEASE 20 #else 21 #define SK_DEBUG 22 #endif 23 #endif 24 25 #if defined(SK_DEBUG) && defined(SK_RELEASE) 26 # error "cannot define both SK_DEBUG and SK_RELEASE" 27 #elif !defined(SK_DEBUG) && !defined(SK_RELEASE) 28 # error "must define either SK_DEBUG or SK_RELEASE" 29 #endif 30 31 #if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG) 32 # error "can't have unittests without debug" 33 #endif 34 35 /** 36 * Matrix calculations may be float or double. 37 * The default is float, as that's what Chromium's using. 38 */ 39 #if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT) 40 # error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT" 41 #elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT) 42 # define SK_MSCALAR_IS_FLOAT 43 #endif 44 45 #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) 46 # error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN" 47 #elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN) 48 # error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN" 49 #endif 50 51 /** 52 * Ensure the port has defined all of SK_X32_SHIFT, or none of them. 53 */ 54 #ifdef SK_A32_SHIFT 55 # if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT) 56 # error "all or none of the 32bit SHIFT amounts must be defined" 57 # endif 58 #else 59 # if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT) 60 # error "all or none of the 32bit SHIFT amounts must be defined" 61 # endif 62 #endif 63 64 #if !defined(SK_HAS_COMPILER_FEATURE) 65 # if defined(__has_feature) 66 # define SK_HAS_COMPILER_FEATURE(x) __has_feature(x) 67 # else 68 # define SK_HAS_COMPILER_FEATURE(x) 0 69 # endif 70 #endif 71 72 #if !defined(SK_ATTRIBUTE) 73 # if defined(__clang__) || defined(__GNUC__) 74 # define SK_ATTRIBUTE(attr) __attribute__((attr)) 75 # else 76 # define SK_ATTRIBUTE(attr) 77 # endif 78 #endif 79 80 #if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 81 #define SK_VECTORCALL __vectorcall 82 #elif defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_NEON) 83 #define SK_VECTORCALL __attribute__((pcs("aapcs-vfp"))) 84 #else 85 #define SK_VECTORCALL 86 #endif 87 88 #if !defined(SK_SUPPORT_GPU) 89 # define SK_SUPPORT_GPU 1 90 #endif 91 92 /** 93 * The clang static analyzer likes to know that when the program is not 94 * expected to continue (crash, assertion failure, etc). It will notice that 95 * some combination of parameters lead to a function call that does not return. 96 * It can then make appropriate assumptions about the parameters in code 97 * executed only if the non-returning function was *not* called. 98 */ 99 #if !defined(SkNO_RETURN_HINT) 100 # if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn) 101 static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); SkNO_RETURN_HINT()102 static inline void SkNO_RETURN_HINT() {} 103 # else 104 # define SkNO_RETURN_HINT() do {} while (false) 105 # endif 106 #endif 107 108 /////////////////////////////////////////////////////////////////////////////// 109 110 // TODO(mdempsky): Move elsewhere as appropriate. 111 #include <new> 112 113 114 /////////////////////////////////////////////////////////////////////////////// 115 116 #ifdef SK_BUILD_FOR_WIN 117 # ifndef SK_A32_SHIFT 118 # define SK_A32_SHIFT 24 119 # define SK_R32_SHIFT 16 120 # define SK_G32_SHIFT 8 121 # define SK_B32_SHIFT 0 122 # endif 123 # 124 #endif 125 126 #if defined(GOOGLE3) 127 void SkDebugfForDumpStackTrace(const char* data, void* unused); 128 void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg); 129 # define SK_DUMP_GOOGLE3_STACK() DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr) 130 #else 131 # define SK_DUMP_GOOGLE3_STACK() 132 #endif 133 134 #ifdef SK_BUILD_FOR_WIN 135 // permits visual studio to follow error back to source 136 #define SK_DUMP_LINE_FORMAT(message) \ 137 SkDebugf("%s(%d): fatal error: \"%s\"\n", __FILE__, __LINE__, message) 138 #else 139 #define SK_DUMP_LINE_FORMAT(message) \ 140 SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message) 141 #endif 142 143 #ifndef SK_ABORT 144 # define SK_ABORT(message) \ 145 do { \ 146 SkNO_RETURN_HINT(); \ 147 SK_DUMP_LINE_FORMAT(message); \ 148 SK_DUMP_GOOGLE3_STACK(); \ 149 sk_abort_no_print(); \ 150 } while (false) 151 #endif 152 153 /** 154 * We check to see if the SHIFT value has already been defined. 155 * if not, we define it ourself to some default values. We default to OpenGL 156 * order (in memory: r,g,b,a) 157 */ 158 #ifndef SK_A32_SHIFT 159 # ifdef SK_CPU_BENDIAN 160 # define SK_R32_SHIFT 24 161 # define SK_G32_SHIFT 16 162 # define SK_B32_SHIFT 8 163 # define SK_A32_SHIFT 0 164 # else 165 # define SK_R32_SHIFT 0 166 # define SK_G32_SHIFT 8 167 # define SK_B32_SHIFT 16 168 # define SK_A32_SHIFT 24 169 # endif 170 #endif 171 172 /** 173 * SkColor has well defined shift values, but SkPMColor is configurable. This 174 * macro is a convenience that returns true if the shift values are equal while 175 * ignoring the machine's endianness. 176 */ 177 #define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \ 178 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0) 179 180 /** 181 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The 182 * relationship between the byte order and shift values depends on machine endianness. If the shift 183 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little 184 * endian machine and the A channel on a big endian machine. Thus, given those shifts values, 185 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and 186 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine. 187 */ 188 #ifdef SK_CPU_BENDIAN 189 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 190 (SK_ ## C3 ## 32_SHIFT == 0 && \ 191 SK_ ## C2 ## 32_SHIFT == 8 && \ 192 SK_ ## C1 ## 32_SHIFT == 16 && \ 193 SK_ ## C0 ## 32_SHIFT == 24) 194 #else 195 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 196 (SK_ ## C0 ## 32_SHIFT == 0 && \ 197 SK_ ## C1 ## 32_SHIFT == 8 && \ 198 SK_ ## C2 ## 32_SHIFT == 16 && \ 199 SK_ ## C3 ## 32_SHIFT == 24) 200 #endif 201 202 ////////////////////////////////////////////////////////////////////////////////////////////// 203 204 #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 205 # ifdef free 206 # undef free 207 # endif 208 # include <crtdbg.h> 209 # undef free 210 # 211 # ifdef SK_DEBUGx 212 # if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus) 213 void * operator new( 214 size_t cb, 215 int nBlockUse, 216 const char * szFileName, 217 int nLine, 218 int foo 219 ); 220 void * operator new[]( 221 size_t cb, 222 int nBlockUse, 223 const char * szFileName, 224 int nLine, 225 int foo 226 ); 227 void operator delete( 228 void *pUserData, 229 int, const char*, int, int 230 ); 231 void operator delete( 232 void *pUserData 233 ); 234 void operator delete[]( void * p ); 235 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0) 236 # else 237 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) 238 # endif 239 # define new DEBUG_CLIENTBLOCK 240 # else 241 # define DEBUG_CLIENTBLOCK 242 # endif 243 #endif 244 245 ////////////////////////////////////////////////////////////////////// 246 247 #if !defined(SK_UNUSED) 248 # if defined(_MSC_VER) 249 # define SK_UNUSED __pragma(warning(suppress:4189)) 250 # else 251 # define SK_UNUSED SK_ATTRIBUTE(unused) 252 # endif 253 #endif 254 255 #if !defined(SK_ATTR_DEPRECATED) 256 // FIXME: we ignore msg for now... 257 # define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated) 258 #endif 259 260 /** 261 * If your judgment is better than the compiler's (i.e. you've profiled it), 262 * you can use SK_ALWAYS_INLINE to force inlining. E.g. 263 * inline void someMethod() { ... } // may not be inlined 264 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined 265 */ 266 #if !defined(SK_ALWAYS_INLINE) 267 # if defined(SK_BUILD_FOR_WIN) 268 # define SK_ALWAYS_INLINE __forceinline 269 # else 270 # define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline 271 # endif 272 #endif 273 274 /** 275 * If your judgment is better than the compiler's (i.e. you've profiled it), 276 * you can use SK_NEVER_INLINE to prevent inlining. 277 */ 278 #if !defined(SK_NEVER_INLINE) 279 # if defined(SK_BUILD_FOR_WIN) 280 # define SK_NEVER_INLINE __declspec(noinline) 281 # else 282 # define SK_NEVER_INLINE SK_ATTRIBUTE(noinline) 283 # endif 284 #endif 285 286 ////////////////////////////////////////////////////////////////////// 287 288 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 289 #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0) 290 #define SK_WRITE_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0) 291 #elif defined(__GNUC__) 292 #define SK_PREFETCH(ptr) __builtin_prefetch(ptr) 293 #define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) 294 #else 295 #define SK_PREFETCH(ptr) 296 #define SK_WRITE_PREFETCH(ptr) 297 #endif 298 299 ////////////////////////////////////////////////////////////////////// 300 301 #ifndef SK_PRINTF_LIKE 302 # if defined(__clang__) || defined(__GNUC__) 303 # define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 304 # else 305 # define SK_PRINTF_LIKE(A, B) 306 # endif 307 #endif 308 309 ////////////////////////////////////////////////////////////////////// 310 311 #ifndef SK_SIZE_T_SPECIFIER 312 # if defined(_MSC_VER) 313 # define SK_SIZE_T_SPECIFIER "%Iu" 314 # else 315 # define SK_SIZE_T_SPECIFIER "%zu" 316 # endif 317 #endif 318 319 ////////////////////////////////////////////////////////////////////// 320 321 #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 322 # define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1 323 #endif 324 325 ////////////////////////////////////////////////////////////////////// 326 327 #ifndef SK_EGL 328 # if defined(SK_BUILD_FOR_ANDROID) 329 # define SK_EGL 1 330 # else 331 # define SK_EGL 0 332 # endif 333 #endif 334 335 ////////////////////////////////////////////////////////////////////// 336 337 #if !defined(SK_GAMMA_EXPONENT) 338 #define SK_GAMMA_EXPONENT (0.0f) // SRGB 339 #endif 340 341 ////////////////////////////////////////////////////////////////////// 342 343 #ifndef GR_TEST_UTILS 344 # define GR_TEST_UTILS 0 345 #endif 346 347 ////////////////////////////////////////////////////////////////////// 348 349 #if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN) 350 # define SK_HISTOGRAMS_ENABLED 1 351 #else 352 # define SK_HISTOGRAMS_ENABLED 0 353 #endif 354 355 #ifndef SK_HISTOGRAM_BOOLEAN 356 # define SK_HISTOGRAM_BOOLEAN(name, value) 357 #endif 358 359 #ifndef SK_HISTOGRAM_ENUMERATION 360 # define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value) 361 #endif 362 363 #endif // SkPostConfig_DEFINED 364