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