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)); 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 #ifndef SK_ABORT 135 # define SK_ABORT(message) \ 136 do { \ 137 SkNO_RETURN_HINT(); \ 138 SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message); \ 139 SK_DUMP_GOOGLE3_STACK(); \ 140 sk_abort_no_print(); \ 141 } while (false) 142 #endif 143 144 /** 145 * We check to see if the SHIFT value has already been defined. 146 * if not, we define it ourself to some default values. We default to OpenGL 147 * order (in memory: r,g,b,a) 148 */ 149 #ifndef SK_A32_SHIFT 150 # ifdef SK_CPU_BENDIAN 151 # define SK_R32_SHIFT 24 152 # define SK_G32_SHIFT 16 153 # define SK_B32_SHIFT 8 154 # define SK_A32_SHIFT 0 155 # else 156 # define SK_R32_SHIFT 0 157 # define SK_G32_SHIFT 8 158 # define SK_B32_SHIFT 16 159 # define SK_A32_SHIFT 24 160 # endif 161 #endif 162 163 /** 164 * SkColor has well defined shift values, but SkPMColor is configurable. This 165 * macro is a convenience that returns true if the shift values are equal while 166 * ignoring the machine's endianness. 167 */ 168 #define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \ 169 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0) 170 171 /** 172 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The 173 * relationship between the byte order and shift values depends on machine endianness. If the shift 174 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little 175 * endian machine and the A channel on a big endian machine. Thus, given those shifts values, 176 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and 177 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine. 178 */ 179 #ifdef SK_CPU_BENDIAN 180 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 181 (SK_ ## C3 ## 32_SHIFT == 0 && \ 182 SK_ ## C2 ## 32_SHIFT == 8 && \ 183 SK_ ## C1 ## 32_SHIFT == 16 && \ 184 SK_ ## C0 ## 32_SHIFT == 24) 185 #else 186 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 187 (SK_ ## C0 ## 32_SHIFT == 0 && \ 188 SK_ ## C1 ## 32_SHIFT == 8 && \ 189 SK_ ## C2 ## 32_SHIFT == 16 && \ 190 SK_ ## C3 ## 32_SHIFT == 24) 191 #endif 192 193 ////////////////////////////////////////////////////////////////////////////////////////////// 194 195 #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 196 # ifdef free 197 # undef free 198 # endif 199 # include <crtdbg.h> 200 # undef free 201 # 202 # ifdef SK_DEBUGx 203 # if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus) 204 void * operator new( 205 size_t cb, 206 int nBlockUse, 207 const char * szFileName, 208 int nLine, 209 int foo 210 ); 211 void * operator new[]( 212 size_t cb, 213 int nBlockUse, 214 const char * szFileName, 215 int nLine, 216 int foo 217 ); 218 void operator delete( 219 void *pUserData, 220 int, const char*, int, int 221 ); 222 void operator delete( 223 void *pUserData 224 ); 225 void operator delete[]( void * p ); 226 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0) 227 # else 228 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) 229 # endif 230 # define new DEBUG_CLIENTBLOCK 231 # else 232 # define DEBUG_CLIENTBLOCK 233 # endif 234 #endif 235 236 ////////////////////////////////////////////////////////////////////// 237 238 #if !defined(SK_UNUSED) 239 # if defined(_MSC_VER) 240 # define SK_UNUSED __pragma(warning(suppress:4189)) 241 # else 242 # define SK_UNUSED SK_ATTRIBUTE(unused) 243 # endif 244 #endif 245 246 #if !defined(SK_ATTR_DEPRECATED) 247 // FIXME: we ignore msg for now... 248 # define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated) 249 #endif 250 251 #if !defined(SK_ATTR_EXTERNALLY_DEPRECATED) 252 # if !defined(SK_INTERNAL) 253 # define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg) 254 # else 255 # define SK_ATTR_EXTERNALLY_DEPRECATED(msg) 256 # endif 257 #endif 258 259 /** 260 * If your judgment is better than the compiler's (i.e. you've profiled it), 261 * you can use SK_ALWAYS_INLINE to force inlining. E.g. 262 * inline void someMethod() { ... } // may not be inlined 263 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined 264 */ 265 #if !defined(SK_ALWAYS_INLINE) 266 # if defined(SK_BUILD_FOR_WIN) 267 # define SK_ALWAYS_INLINE __forceinline 268 # else 269 # define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline 270 # endif 271 #endif 272 273 /** 274 * If your judgment is better than the compiler's (i.e. you've profiled it), 275 * you can use SK_NEVER_INLINE to prevent inlining. 276 */ 277 #if !defined(SK_NEVER_INLINE) 278 # if defined(SK_BUILD_FOR_WIN) 279 # define SK_NEVER_INLINE __declspec(noinline) 280 # else 281 # define SK_NEVER_INLINE SK_ATTRIBUTE(noinline) 282 # endif 283 #endif 284 285 ////////////////////////////////////////////////////////////////////// 286 287 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 288 #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0) 289 #define SK_WRITE_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0) 290 #elif defined(__GNUC__) 291 #define SK_PREFETCH(ptr) __builtin_prefetch(ptr) 292 #define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) 293 #else 294 #define SK_PREFETCH(ptr) 295 #define SK_WRITE_PREFETCH(ptr) 296 #endif 297 298 ////////////////////////////////////////////////////////////////////// 299 300 #ifndef SK_PRINTF_LIKE 301 # if defined(__clang__) || defined(__GNUC__) 302 # define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 303 # else 304 # define SK_PRINTF_LIKE(A, B) 305 # endif 306 #endif 307 308 ////////////////////////////////////////////////////////////////////// 309 310 #ifndef SK_SIZE_T_SPECIFIER 311 # if defined(_MSC_VER) 312 # define SK_SIZE_T_SPECIFIER "%Iu" 313 # else 314 # define SK_SIZE_T_SPECIFIER "%zu" 315 # endif 316 #endif 317 318 ////////////////////////////////////////////////////////////////////// 319 320 #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 321 # define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1 322 #endif 323 324 ////////////////////////////////////////////////////////////////////// 325 326 #ifndef SK_EGL 327 # if defined(SK_BUILD_FOR_ANDROID) 328 # define SK_EGL 1 329 # else 330 # define SK_EGL 0 331 # endif 332 #endif 333 334 ////////////////////////////////////////////////////////////////////// 335 336 #if !defined(SK_GAMMA_EXPONENT) 337 #define SK_GAMMA_EXPONENT (0.0f) // SRGB 338 #endif 339 340 ////////////////////////////////////////////////////////////////////// 341 342 #ifndef GR_TEST_UTILS 343 # define GR_TEST_UTILS 1 344 #endif 345 346 ////////////////////////////////////////////////////////////////////// 347 348 #if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN) 349 # define SK_HISTOGRAMS_ENABLED 1 350 #else 351 # define SK_HISTOGRAMS_ENABLED 0 352 #endif 353 354 #ifndef SK_HISTOGRAM_BOOLEAN 355 # define SK_HISTOGRAM_BOOLEAN(name, value) 356 #endif 357 358 #ifndef SK_HISTOGRAM_ENUMERATION 359 # define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value) 360 #endif 361 362 #endif // SkPostConfig_DEFINED 363