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 #ifndef SkPostConfig_DEFINED 9 #define SkPostConfig_DEFINED 10 11 #if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE) 12 # define SK_BUILD_FOR_WIN 13 #endif 14 15 #if defined(SK_DEBUG) && defined(SK_RELEASE) 16 # error "cannot define both SK_DEBUG and SK_RELEASE" 17 #elif !defined(SK_DEBUG) && !defined(SK_RELEASE) 18 # error "must define either SK_DEBUG or SK_RELEASE" 19 #endif 20 21 #if defined(SK_SUPPORT_UNITTEST) && !defined(SK_DEBUG) 22 # error "can't have unittests without debug" 23 #endif 24 25 #if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT) 26 # error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT" 27 #elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT) 28 # define SK_SCALAR_IS_FLOAT 29 #endif 30 31 /** 32 * Matrix calculations may be float or double. 33 * The default is double, as that is faster given our impl uses doubles 34 * for intermediate calculations. 35 */ 36 #if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT) 37 # error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT" 38 #elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT) 39 # define SK_MSCALAR_IS_DOUBLE 40 #endif 41 42 #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) 43 # error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN" 44 #elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN) 45 # error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN" 46 #endif 47 48 /** 49 * Ensure the port has defined all of SK_X32_SHIFT, or none of them. 50 */ 51 #ifdef SK_A32_SHIFT 52 # if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT) 53 # error "all or none of the 32bit SHIFT amounts must be defined" 54 # endif 55 #else 56 # if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT) 57 # error "all or none of the 32bit SHIFT amounts must be defined" 58 # endif 59 #endif 60 61 #if !defined(SK_HAS_COMPILER_FEATURE) 62 # if defined(__has_feature) 63 # define SK_HAS_COMPILER_FEATURE(x) __has_feature(x) 64 # else 65 # define SK_HAS_COMPILER_FEATURE(x) 0 66 # endif 67 #endif 68 69 #if !defined(SK_ATTRIBUTE) 70 # if defined(__clang__) || defined(__GNUC__) 71 # define SK_ATTRIBUTE(attr) __attribute__((attr)) 72 # else 73 # define SK_ATTRIBUTE(attr) 74 # endif 75 #endif 76 77 #if !defined(SK_SUPPORT_GPU) 78 # define SK_SUPPORT_GPU 1 79 #endif 80 81 /** 82 * The clang static analyzer likes to know that when the program is not 83 * expected to continue (crash, assertion failure, etc). It will notice that 84 * some combination of parameters lead to a function call that does not return. 85 * It can then make appropriate assumptions about the parameters in code 86 * executed only if the non-returning function was *not* called. 87 */ 88 #if !defined(SkNO_RETURN_HINT) 89 # if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn) 90 static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn)); 91 static inline void SkNO_RETURN_HINT() {} 92 # else 93 # define SkNO_RETURN_HINT() do {} while (false) 94 # endif 95 #endif 96 97 #if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB) 98 # error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB" 99 #elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB) 100 # define SK_HAS_ZLIB 101 #endif 102 103 /////////////////////////////////////////////////////////////////////////////// 104 105 #ifndef SkNEW 106 # define SkNEW(type_name) (new type_name) 107 # define SkNEW_ARGS(type_name, args) (new type_name args) 108 # define SkNEW_ARRAY(type_name, count) (new type_name[(count)]) 109 # define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name) 110 # define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args) 111 # define SkDELETE(obj) (delete (obj)) 112 # define SkDELETE_ARRAY(array) (delete[] (array)) 113 #endif 114 115 #ifndef SK_CRASH 116 # if 1 // set to 0 for infinite loop, which can help connecting gdb 117 # define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false) 118 # else 119 # define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true) 120 # endif 121 #endif 122 123 /////////////////////////////////////////////////////////////////////////////// 124 125 /** 126 * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects 127 * are still held on exit. 128 * Defaults to 1 in DEBUG and 0 in RELEASE. 129 * FIXME: currently always 0, since it fails if multiple threads run at once 130 * (see skbug.com/1219 ). 131 */ 132 #ifndef SK_ENABLE_INST_COUNT 133 # ifdef SK_DEBUG 134 # define SK_ENABLE_INST_COUNT 0 135 # else 136 # define SK_ENABLE_INST_COUNT 0 137 # endif 138 #endif 139 140 /////////////////////////////////////////////////////////////////////////////// 141 142 #if defined(SK_SOFTWARE_FLOAT) && defined(SK_SCALAR_IS_FLOAT) 143 // if this is defined, we convert floats to 2s compliment ints for compares. 144 # ifndef SK_SCALAR_SLOW_COMPARES 145 # define SK_SCALAR_SLOW_COMPARES 146 # endif 147 # ifndef SK_USE_FLOATBITS 148 # define SK_USE_FLOATBITS 149 # endif 150 #endif 151 152 #ifdef SK_BUILD_FOR_WIN 153 # ifndef WIN32_LEAN_AND_MEAN 154 # define WIN32_LEAN_AND_MEAN 155 # define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 156 # endif 157 # ifndef NOMINMAX 158 # define NOMINMAX 159 # define NOMINMAX_WAS_LOCALLY_DEFINED 160 # endif 161 # 162 # include <windows.h> 163 # 164 # ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 165 # undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 166 # undef WIN32_LEAN_AND_MEAN 167 # endif 168 # ifdef NOMINMAX_WAS_LOCALLY_DEFINED 169 # undef NOMINMAX_WAS_LOCALLY_DEFINED 170 # undef NOMINMAX 171 # endif 172 # 173 # ifndef SK_DEBUGBREAK 174 # define SK_DEBUGBREAK(p) do { if (!(p)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false) 175 # endif 176 # 177 # ifndef SK_A32_SHIFT 178 # define SK_A32_SHIFT 24 179 # define SK_R32_SHIFT 16 180 # define SK_G32_SHIFT 8 181 # define SK_B32_SHIFT 0 182 # endif 183 # 184 #else 185 # ifdef SK_DEBUG 186 # include <stdio.h> 187 # ifndef SK_DEBUGBREAK 188 # define SK_DEBUGBREAK(cond) do { if (cond) break; \ 189 SkDebugf("%s:%d: failed assertion \"%s\"\n", \ 190 __FILE__, __LINE__, #cond); SK_CRASH(); } while (false) 191 # endif 192 # endif 193 #endif 194 195 /** 196 * We check to see if the SHIFT value has already been defined. 197 * if not, we define it ourself to some default values. We default to OpenGL 198 * order (in memory: r,g,b,a) 199 */ 200 #ifndef SK_A32_SHIFT 201 # ifdef SK_CPU_BENDIAN 202 # define SK_R32_SHIFT 24 203 # define SK_G32_SHIFT 16 204 # define SK_B32_SHIFT 8 205 # define SK_A32_SHIFT 0 206 # else 207 # define SK_R32_SHIFT 0 208 # define SK_G32_SHIFT 8 209 # define SK_B32_SHIFT 16 210 # define SK_A32_SHIFT 24 211 # endif 212 #endif 213 214 /** 215 * SkColor has well defined shift values, but SkPMColor is configurable. This 216 * macro is a convenience that returns true if the shift values are equal while 217 * ignoring the machine's endianness. 218 */ 219 #define SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER \ 220 (SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 0) 221 222 /** 223 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The 224 * relationship between the byte order and shift values depends on machine endianness. If the shift 225 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little 226 * endian machine and the A channel on a big endian machine. Thus, given those shifts values, 227 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and 228 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine. 229 */ 230 #ifdef SK_CPU_BENDIAN 231 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 232 (SK_ ## C3 ## 32_SHIFT == 0 && \ 233 SK_ ## C2 ## 32_SHIFT == 8 && \ 234 SK_ ## C1 ## 32_SHIFT == 16 && \ 235 SK_ ## C0 ## 32_SHIFT == 24) 236 #else 237 # define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \ 238 (SK_ ## C0 ## 32_SHIFT == 0 && \ 239 SK_ ## C1 ## 32_SHIFT == 8 && \ 240 SK_ ## C2 ## 32_SHIFT == 16 && \ 241 SK_ ## C3 ## 32_SHIFT == 24) 242 #endif 243 244 ////////////////////////////////////////////////////////////////////// 245 246 #if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) 247 # ifndef SkLONGLONG 248 # ifdef SK_BUILD_FOR_WIN32 249 # define SkLONGLONG __int64 250 # else 251 # define SkLONGLONG long long 252 # endif 253 # endif 254 #endif 255 256 ////////////////////////////////////////////////////////////////////////////////////////////// 257 #ifndef SK_BUILD_FOR_WINCE 258 # include <string.h> 259 # include <stdlib.h> 260 #else 261 # define _CMNINTRIN_DECLARE_ONLY 262 # include "cmnintrin.h" 263 #endif 264 265 #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 266 # ifdef free 267 # undef free 268 # endif 269 # include <crtdbg.h> 270 # undef free 271 # 272 # ifdef SK_DEBUGx 273 # if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus) 274 void * operator new( 275 size_t cb, 276 int nBlockUse, 277 const char * szFileName, 278 int nLine, 279 int foo 280 ); 281 void * operator new[]( 282 size_t cb, 283 int nBlockUse, 284 const char * szFileName, 285 int nLine, 286 int foo 287 ); 288 void operator delete( 289 void *pUserData, 290 int, const char*, int, int 291 ); 292 void operator delete( 293 void *pUserData 294 ); 295 void operator delete[]( void * p ); 296 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0) 297 # else 298 # define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) 299 # endif 300 # define new DEBUG_CLIENTBLOCK 301 # else 302 # define DEBUG_CLIENTBLOCK 303 # endif 304 #endif 305 306 ////////////////////////////////////////////////////////////////////// 307 308 #ifndef SK_OVERRIDE 309 # if defined(_MSC_VER) 310 # define SK_OVERRIDE override 311 # elif defined(__clang__) 312 // Using __attribute__((override)) on clang does not appear to always work. 313 // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no 314 // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing 315 // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma). 316 # pragma clang diagnostic ignored "-Wc++11-extensions" 317 # 318 # if __has_feature(cxx_override_control) 319 # define SK_OVERRIDE override 320 # elif defined(__has_extension) && __has_extension(cxx_override_control) 321 # define SK_OVERRIDE override 322 # endif 323 # endif 324 # ifndef SK_OVERRIDE 325 # define SK_OVERRIDE 326 # endif 327 #endif 328 329 ////////////////////////////////////////////////////////////////////// 330 331 #if !defined(SK_UNUSED) 332 # define SK_UNUSED SK_ATTRIBUTE(unused) 333 #endif 334 335 #if !defined(SK_ATTR_DEPRECATED) 336 // FIXME: we ignore msg for now... 337 # define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated) 338 #endif 339 340 /** 341 * If your judgment is better than the compiler's (i.e. you've profiled it), 342 * you can use SK_ALWAYS_INLINE to force inlining. E.g. 343 * inline void someMethod() { ... } // may not be inlined 344 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined 345 */ 346 #if !defined(SK_ALWAYS_INLINE) 347 # if defined(SK_BUILD_FOR_WIN) 348 # define SK_ALWAYS_INLINE __forceinline 349 # else 350 # define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline 351 # endif 352 #endif 353 354 ////////////////////////////////////////////////////////////////////// 355 356 #if defined(__clang__) || defined(__GNUC__) 357 # define SK_PREFETCH(ptr) __builtin_prefetch(ptr) 358 # define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) 359 #else 360 # define SK_PREFETCH(ptr) 361 # define SK_WRITE_PREFETCH(ptr) 362 #endif 363 364 ////////////////////////////////////////////////////////////////////// 365 366 #ifndef SK_PRINTF_LIKE 367 # if defined(__clang__) || defined(__GNUC__) 368 # define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 369 # else 370 # define SK_PRINTF_LIKE(A, B) 371 # endif 372 #endif 373 374 ////////////////////////////////////////////////////////////////////// 375 376 #ifndef SK_SIZE_T_SPECIFIER 377 # if defined(_MSC_VER) 378 # define SK_SIZE_T_SPECIFIER "%Iu" 379 # else 380 # define SK_SIZE_T_SPECIFIER "%zu" 381 # endif 382 #endif 383 384 ////////////////////////////////////////////////////////////////////// 385 386 #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 387 # define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1 388 #endif 389 390 #endif // SkPostConfig_DEFINED 391