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 /** 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 #if defined(SK_CPU_BENDIAN) && !defined(I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN) 44 #error "The Skia team is not endian-savvy enough to support big-endian CPUs." 45 #error "If you still want to use Skia," 46 #error "please define I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN." 47 #endif 48 49 /** 50 * Ensure the port has defined all of SK_X32_SHIFT, or none of them. 51 */ 52 #ifdef SK_A32_SHIFT 53 # if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT) 54 # error "all or none of the 32bit SHIFT amounts must be defined" 55 # endif 56 #else 57 # if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT) 58 # error "all or none of the 32bit SHIFT amounts must be defined" 59 # endif 60 #endif 61 62 #if !defined(SK_HAS_COMPILER_FEATURE) 63 # if defined(__has_feature) 64 # define SK_HAS_COMPILER_FEATURE(x) __has_feature(x) 65 # else 66 # define SK_HAS_COMPILER_FEATURE(x) 0 67 # endif 68 #endif 69 70 #if !defined(SK_ATTRIBUTE) 71 # if defined(__clang__) || defined(__GNUC__) 72 # define SK_ATTRIBUTE(attr) __attribute__((attr)) 73 # else 74 # define SK_ATTRIBUTE(attr) 75 # endif 76 #endif 77 78 #if !defined(SK_SUPPORT_GPU) 79 # define SK_SUPPORT_GPU 1 80 #endif 81 82 #if !defined(SK_SUPPORT_ATLAS_TEXT) 83 # define SK_SUPPORT_ATLAS_TEXT 0 84 #elif SK_SUPPORT_ATLAS_TEXT && !SK_SUPPORT_GPU 85 # error "SK_SUPPORT_ATLAS_TEXT requires SK_SUPPORT_GPU" 86 #endif 87 88 /** 89 * The clang static analyzer likes to know that when the program is not 90 * expected to continue (crash, assertion failure, etc). It will notice that 91 * some combination of parameters lead to a function call that does not return. 92 * It can then make appropriate assumptions about the parameters in code 93 * executed only if the non-returning function was *not* called. 94 */ 95 #if !defined(SkNO_RETURN_HINT) 96 # if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn) 97 static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); SkNO_RETURN_HINT()98 static inline void SkNO_RETURN_HINT() {} 99 # else 100 # define SkNO_RETURN_HINT() do {} while (false) 101 # endif 102 #endif 103 104 /////////////////////////////////////////////////////////////////////////////// 105 106 #ifdef SK_BUILD_FOR_WIN 107 # ifndef SK_A32_SHIFT 108 # define SK_A32_SHIFT 24 109 # define SK_R32_SHIFT 16 110 # define SK_G32_SHIFT 8 111 # define SK_B32_SHIFT 0 112 # endif 113 # 114 #endif 115 116 #if defined(SK_BUILD_FOR_GOOGLE3) 117 void SkDebugfForDumpStackTrace(const char* data, void* unused); 118 void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg); 119 # define SK_DUMP_GOOGLE3_STACK() DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr) 120 #else 121 # define SK_DUMP_GOOGLE3_STACK() 122 #endif 123 124 #ifdef SK_BUILD_FOR_WIN 125 // permits visual studio to follow error back to source 126 #define SK_DUMP_LINE_FORMAT(message) \ 127 SkDebugf("%s(%d): fatal error: \"%s\"\n", __FILE__, __LINE__, message) 128 #else 129 #define SK_DUMP_LINE_FORMAT(message) \ 130 SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message) 131 #endif 132 133 #ifndef SK_ABORT 134 # define SK_ABORT(message) \ 135 do { \ 136 SkNO_RETURN_HINT(); \ 137 SK_DUMP_LINE_FORMAT(message); \ 138 SK_DUMP_GOOGLE3_STACK(); \ 139 sk_abort_no_print(); \ 140 } while (false) 141 #endif 142 143 /** 144 * We check to see if the SHIFT value has already been defined. 145 * if not, we define it ourself to some default values. We default to OpenGL 146 * order (in memory: r,g,b,a) 147 */ 148 #ifndef SK_A32_SHIFT 149 # ifdef SK_CPU_BENDIAN 150 # define SK_R32_SHIFT 24 151 # define SK_G32_SHIFT 16 152 # define SK_B32_SHIFT 8 153 # define SK_A32_SHIFT 0 154 # else 155 # define SK_R32_SHIFT 0 156 # define SK_G32_SHIFT 8 157 # define SK_B32_SHIFT 16 158 # define SK_A32_SHIFT 24 159 # endif 160 #endif 161 162 /** 163 * SkColor has well defined shift values, but SkPMColor is configurable. This 164 * macro is a convenience that returns true if the shift values are equal while 165 * ignoring the machine's endianness. 166 */ 167 #define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \ 168 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0) 169 170 /** 171 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The 172 * relationship between the byte order and shift values depends on machine endianness. If the shift 173 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little 174 * endian machine and the A channel on a big endian machine. Thus, given those shifts values, 175 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and 176 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine. 177 */ 178 #ifdef SK_CPU_BENDIAN 179 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 180 (SK_ ## C3 ## 32_SHIFT == 0 && \ 181 SK_ ## C2 ## 32_SHIFT == 8 && \ 182 SK_ ## C1 ## 32_SHIFT == 16 && \ 183 SK_ ## C0 ## 32_SHIFT == 24) 184 #else 185 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 186 (SK_ ## C0 ## 32_SHIFT == 0 && \ 187 SK_ ## C1 ## 32_SHIFT == 8 && \ 188 SK_ ## C2 ## 32_SHIFT == 16 && \ 189 SK_ ## C3 ## 32_SHIFT == 24) 190 #endif 191 192 ////////////////////////////////////////////////////////////////////////////////////////////// 193 194 #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN 195 #ifdef free 196 #undef free 197 #endif 198 #include <crtdbg.h> 199 #undef free 200 #endif 201 202 ////////////////////////////////////////////////////////////////////// 203 204 #if !defined(SK_UNUSED) 205 # if !defined(__clang__) && defined(_MSC_VER) 206 # define SK_UNUSED __pragma(warning(suppress:4189)) 207 # else 208 # define SK_UNUSED SK_ATTRIBUTE(unused) 209 # endif 210 #endif 211 212 /** 213 * If your judgment is better than the compiler's (i.e. you've profiled it), 214 * you can use SK_ALWAYS_INLINE to force inlining. E.g. 215 * inline void someMethod() { ... } // may not be inlined 216 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined 217 */ 218 #if !defined(SK_ALWAYS_INLINE) 219 # if defined(SK_BUILD_FOR_WIN) 220 # define SK_ALWAYS_INLINE __forceinline 221 # else 222 # define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline 223 # endif 224 #endif 225 226 /** 227 * If your judgment is better than the compiler's (i.e. you've profiled it), 228 * you can use SK_NEVER_INLINE to prevent inlining. 229 */ 230 #if !defined(SK_NEVER_INLINE) 231 # if defined(SK_BUILD_FOR_WIN) 232 # define SK_NEVER_INLINE __declspec(noinline) 233 # else 234 # define SK_NEVER_INLINE SK_ATTRIBUTE(noinline) 235 # endif 236 #endif 237 238 ////////////////////////////////////////////////////////////////////// 239 240 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 241 #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0) 242 #define SK_WRITE_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0) 243 #elif defined(__GNUC__) 244 #define SK_PREFETCH(ptr) __builtin_prefetch(ptr) 245 #define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) 246 #else 247 #define SK_PREFETCH(ptr) 248 #define SK_WRITE_PREFETCH(ptr) 249 #endif 250 251 ////////////////////////////////////////////////////////////////////// 252 253 #ifndef SK_PRINTF_LIKE 254 # if defined(__clang__) || defined(__GNUC__) 255 # define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 256 # else 257 # define SK_PRINTF_LIKE(A, B) 258 # endif 259 #endif 260 261 ////////////////////////////////////////////////////////////////////// 262 263 #ifndef SK_SIZE_T_SPECIFIER 264 # if defined(_MSC_VER) && !defined(__clang__) 265 # define SK_SIZE_T_SPECIFIER "%Iu" 266 # else 267 # define SK_SIZE_T_SPECIFIER "%zu" 268 # endif 269 #endif 270 271 ////////////////////////////////////////////////////////////////////// 272 273 #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 274 # define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1 275 #endif 276 277 ////////////////////////////////////////////////////////////////////// 278 279 #if !defined(SK_GAMMA_EXPONENT) 280 #define SK_GAMMA_EXPONENT (0.0f) // SRGB 281 #endif 282 283 ////////////////////////////////////////////////////////////////////// 284 285 #ifndef GR_TEST_UTILS 286 # define GR_TEST_UTILS 0 287 #endif 288 289 ////////////////////////////////////////////////////////////////////// 290 291 #if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN) 292 # define SK_HISTOGRAMS_ENABLED 1 293 #else 294 # define SK_HISTOGRAMS_ENABLED 0 295 #endif 296 297 #ifndef SK_HISTOGRAM_BOOLEAN 298 # define SK_HISTOGRAM_BOOLEAN(name, value) 299 #endif 300 301 #ifndef SK_HISTOGRAM_ENUMERATION 302 # define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value) 303 #endif 304 305 #ifndef SK_DISABLE_LEGACY_SHADERCONTEXT 306 #define SK_ENABLE_LEGACY_SHADERCONTEXT 307 #endif 308 309 #endif // SkPostConfig_DEFINED 310