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