Home | History | Annotate | Download | only in core
      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