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 #  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));
     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