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