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