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 SkTypes_DEFINED
      9 #define SkTypes_DEFINED
     10 
     11 // IWYU pragma: begin_exports
     12 
     13 // In at least two known scenarios when using GCC with libc++:
     14 //  * GCC 4.8 targeting ARMv7 with NEON
     15 //  * GCC 4.9 targeting ARMv8 64 bit
     16 // we need to typedef float float32_t (or include <arm_neon.h> which does that)
     17 // before #including <memory>. This makes no sense.  I'm not very interested in
     18 // understanding why... these are old, bizarre platform configuration that we
     19 // should just let die.
     20 // See https://llvm.org/bugs/show_bug.cgi?id=25608 .
     21 #include <ciso646>  // Include something innocuous to define _LIBCPP_VERISON if it's libc++.
     22 #if defined(__GNUC__) && __GNUC__ == 4 \
     23  && ((defined(__arm__) && (defined(__ARM_NEON__) || defined(__ARM_NEON))) || defined(__aarch64__)) \
     24  && defined(_LIBCPP_VERSION)
     25     typedef float float32_t;
     26     #include <memory>
     27 #endif
     28 
     29 #include "SkPreConfig.h"
     30 #include "SkUserConfig.h"
     31 #include "SkPostConfig.h"
     32 #include <stddef.h>
     33 #include <stdint.h>
     34 // IWYU pragma: end_exports
     35 
     36 #include <string.h>
     37 // TODO(herb): remove after chromuim skia/ext/SkMemory_new_handler.cpp
     38 // has been updated to point to private/SkMalloc.h
     39 #include "../private/SkMalloc.h"
     40 
     41 // enable to test new device-base clipping
     42 //#define SK_USE_DEVICE_CLIPPING
     43 
     44 /** \file SkTypes.h
     45 */
     46 
     47 /** See SkGraphics::GetVersion() to retrieve these at runtime
     48  */
     49 #define SKIA_VERSION_MAJOR  1
     50 #define SKIA_VERSION_MINOR  0
     51 #define SKIA_VERSION_PATCH  0
     52 
     53 
     54 /** Called internally if we hit an unrecoverable error.
     55     The platform implementation must not return, but should either throw
     56     an exception or otherwise exit.
     57 */
     58 SK_API extern void sk_abort_no_print(void);
     59 
     60 ///////////////////////////////////////////////////////////////////////////////
     61 
     62 #ifdef override_GLOBAL_NEW
     63 #include <new>
     64 
     65 inline void* operator new(size_t size) {
     66     return sk_malloc_throw(size);
     67 }
     68 
     69 inline void operator delete(void* p) {
     70     sk_free(p);
     71 }
     72 #endif
     73 
     74 ///////////////////////////////////////////////////////////////////////////////
     75 
     76 #define SK_INIT_TO_AVOID_WARNING    = 0
     77 
     78 #ifndef SkDebugf
     79     SK_API void SkDebugf(const char format[], ...);
     80 #endif
     81 
     82 #define SkREQUIRE_SEMICOLON_AFTER(code) do { code } while (false)
     83 
     84 #define SkASSERT_RELEASE(cond) \
     85     SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT(#cond); } )
     86 
     87 #ifdef SK_DEBUG
     88     #define SkASSERT(cond) \
     89         SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT("assert(" #cond ")"); })
     90     #define SkASSERTF(cond, fmt, ...) \
     91         SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { \
     92                                       SkDebugf(fmt"\n", __VA_ARGS__); \
     93                                       SK_ABORT("assert(" #cond ")"); \
     94                                   })
     95     #define SkDEBUGFAIL(message)        SK_ABORT(message)
     96     #define SkDEBUGFAILF(fmt, ...)      SkASSERTF(false, fmt, ##__VA_ARGS__)
     97     #define SkDEBUGCODE(...)            __VA_ARGS__
     98     #define SkDECLAREPARAM(type, var)   , type var
     99     #define SkPARAM(var)                , var
    100     #define SkDEBUGF(args       )       SkDebugf args
    101     #define SkAssertResult(cond)        SkASSERT(cond)
    102 #else
    103     #define SkASSERT(cond)
    104     #define SkASSERTF(cond, fmt, ...)
    105     #define SkDEBUGFAIL(message)
    106     #define SkDEBUGFAILF(fmt, ...)
    107     #define SkDEBUGCODE(...)
    108     #define SkDEBUGF(args)
    109     #define SkDECLAREPARAM(type, var)
    110     #define SkPARAM(var)
    111 
    112     // unlike SkASSERT, this guy executes its condition in the non-debug build.
    113     // The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
    114     #define SkAssertResult(cond)         if (cond) {} do {} while(false)
    115 #endif
    116 
    117 // Legacy macro names for SK_ABORT
    118 #define SkFAIL(message)                 SK_ABORT(message)
    119 #define sk_throw()                      SK_ABORT("sk_throw")
    120 
    121 #ifdef SK_IGNORE_TO_STRING
    122     #define SK_TO_STRING_NONVIRT()
    123     #define SK_TO_STRING_VIRT()
    124     #define SK_TO_STRING_PUREVIRT()
    125     #define SK_TO_STRING_OVERRIDE()
    126 #else
    127     class SkString;
    128     // the 'toString' helper functions convert Sk* objects to human-readable
    129     // form in developer mode
    130     #define SK_TO_STRING_NONVIRT() void toString(SkString* str) const;
    131     #define SK_TO_STRING_VIRT() virtual void toString(SkString* str) const;
    132     #define SK_TO_STRING_PUREVIRT() virtual void toString(SkString* str) const = 0;
    133     #define SK_TO_STRING_OVERRIDE() void toString(SkString* str) const override;
    134 #endif
    135 
    136 /*
    137  *  Usage:  SK_MACRO_CONCAT(a, b)   to construct the symbol ab
    138  *
    139  *  SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
    140  *
    141  */
    142 #define SK_MACRO_CONCAT(X, Y)           SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
    143 #define SK_MACRO_CONCAT_IMPL_PRIV(X, Y)  X ## Y
    144 
    145 /*
    146  *  Usage: SK_MACRO_APPEND_LINE(foo)    to make foo123, where 123 is the current
    147  *                                      line number. Easy way to construct
    148  *                                      unique names for local functions or
    149  *                                      variables.
    150  */
    151 #define SK_MACRO_APPEND_LINE(name)  SK_MACRO_CONCAT(name, __LINE__)
    152 
    153 /**
    154  * For some classes, it's almost always an error to instantiate one without a name, e.g.
    155  *   {
    156  *       SkAutoMutexAcquire(&mutex);
    157  *       <some code>
    158  *   }
    159  * In this case, the writer meant to hold mutex while the rest of the code in the block runs,
    160  * but instead the mutex is acquired and then immediately released.  The correct usage is
    161  *   {
    162  *       SkAutoMutexAcquire lock(&mutex);
    163  *       <some code>
    164  *   }
    165  *
    166  * To prevent callers from instantiating your class without a name, use SK_REQUIRE_LOCAL_VAR
    167  * like this:
    168  *   class classname {
    169  *       <your class>
    170  *   };
    171  *   #define classname(...) SK_REQUIRE_LOCAL_VAR(classname)
    172  *
    173  * This won't work with templates, and you must inline the class' constructors and destructors.
    174  * Take a look at SkAutoFree and SkAutoMalloc in this file for examples.
    175  */
    176 #define SK_REQUIRE_LOCAL_VAR(classname) \
    177     static_assert(false, "missing name for " #classname)
    178 
    179 ///////////////////////////////////////////////////////////////////////
    180 
    181 /**
    182  *  Fast type for signed 8 bits. Use for parameter passing and local variables,
    183  *  not for storage.
    184  */
    185 typedef int S8CPU;
    186 
    187 /**
    188  *  Fast type for unsigned 8 bits. Use for parameter passing and local
    189  *  variables, not for storage
    190  */
    191 typedef unsigned U8CPU;
    192 
    193 /**
    194  *  Fast type for signed 16 bits. Use for parameter passing and local variables,
    195  *  not for storage
    196  */
    197 typedef int S16CPU;
    198 
    199 /**
    200  *  Fast type for unsigned 16 bits. Use for parameter passing and local
    201  *  variables, not for storage
    202  */
    203 typedef unsigned U16CPU;
    204 
    205 /**
    206  *  Meant to be a small version of bool, for storage purposes. Will be 0 or 1
    207  */
    208 typedef uint8_t SkBool8;
    209 
    210 #include "../private/SkTFitsIn.h"
    211 template <typename D, typename S> D SkTo(S s) {
    212     SkASSERT(SkTFitsIn<D>(s));
    213     return static_cast<D>(s);
    214 }
    215 #define SkToS8(x)    SkTo<int8_t>(x)
    216 #define SkToU8(x)    SkTo<uint8_t>(x)
    217 #define SkToS16(x)   SkTo<int16_t>(x)
    218 #define SkToU16(x)   SkTo<uint16_t>(x)
    219 #define SkToS32(x)   SkTo<int32_t>(x)
    220 #define SkToU32(x)   SkTo<uint32_t>(x)
    221 #define SkToInt(x)   SkTo<int>(x)
    222 #define SkToUInt(x)  SkTo<unsigned>(x)
    223 #define SkToSizeT(x) SkTo<size_t>(x)
    224 
    225 /** Returns 0 or 1 based on the condition
    226 */
    227 #define SkToBool(cond)  ((cond) != 0)
    228 
    229 #define SK_MaxS16   32767
    230 #define SK_MinS16   -32767
    231 #define SK_MaxU16   0xFFFF
    232 #define SK_MinU16   0
    233 #define SK_MaxS32   0x7FFFFFFF
    234 #define SK_MinS32   -SK_MaxS32
    235 #define SK_MaxU32   0xFFFFFFFF
    236 #define SK_MinU32   0
    237 #define SK_NaN32    ((int) (1U << 31))
    238 
    239 /** Returns true if the value can be represented with signed 16bits
    240  */
    241 static inline bool SkIsS16(long x) {
    242     return (int16_t)x == x;
    243 }
    244 
    245 /** Returns true if the value can be represented with unsigned 16bits
    246  */
    247 static inline bool SkIsU16(long x) {
    248     return (uint16_t)x == x;
    249 }
    250 
    251 static inline int32_t SkLeftShift(int32_t value, int32_t shift) {
    252     return (int32_t) ((uint32_t) value << shift);
    253 }
    254 
    255 static inline int64_t SkLeftShift(int64_t value, int32_t shift) {
    256     return (int64_t) ((uint64_t) value << shift);
    257 }
    258 
    259 //////////////////////////////////////////////////////////////////////////////
    260 
    261 /** Returns the number of entries in an array (not a pointer) */
    262 template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
    263 #define SK_ARRAY_COUNT(array) (sizeof(SkArrayCountHelper(array)))
    264 
    265 // Can be used to bracket data types that must be dense, e.g. hash keys.
    266 #if defined(__clang__)  // This should work on GCC too, but GCC diagnostic pop didn't seem to work!
    267     #define SK_BEGIN_REQUIRE_DENSE _Pragma("GCC diagnostic push") \
    268                                    _Pragma("GCC diagnostic error \"-Wpadded\"")
    269     #define SK_END_REQUIRE_DENSE   _Pragma("GCC diagnostic pop")
    270 #else
    271     #define SK_BEGIN_REQUIRE_DENSE
    272     #define SK_END_REQUIRE_DENSE
    273 #endif
    274 
    275 #define SkAlign2(x)     (((x) + 1) >> 1 << 1)
    276 #define SkIsAlign2(x)   (0 == ((x) & 1))
    277 
    278 #define SkAlign4(x)     (((x) + 3) >> 2 << 2)
    279 #define SkIsAlign4(x)   (0 == ((x) & 3))
    280 
    281 #define SkAlign8(x)     (((x) + 7) >> 3 << 3)
    282 #define SkIsAlign8(x)   (0 == ((x) & 7))
    283 
    284 #define SkAlign16(x)     (((x) + 15) >> 4 << 4)
    285 #define SkIsAlign16(x)   (0 == ((x) & 15))
    286 
    287 #define SkAlignPtr(x)   (sizeof(void*) == 8 ?   SkAlign8(x) :   SkAlign4(x))
    288 #define SkIsAlignPtr(x) (sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x))
    289 
    290 typedef uint32_t SkFourByteTag;
    291 #define SkSetFourByteTag(a, b, c, d)    (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
    292 
    293 /** 32 bit integer to hold a unicode value
    294 */
    295 typedef int32_t SkUnichar;
    296 
    297 /** 16 bit unsigned integer to hold a glyph index
    298 */
    299 typedef uint16_t SkGlyphID;
    300 
    301 /** 32 bit value to hold a millisecond duration
    302  *  Note that SK_MSecMax is about 25 days.
    303  */
    304 typedef uint32_t SkMSec;
    305 /** 1 second measured in milliseconds
    306 */
    307 #define SK_MSec1 1000
    308 /** maximum representable milliseconds; 24d 20h 31m 23.647s.
    309 */
    310 #define SK_MSecMax 0x7FFFFFFF
    311 /** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
    312 */
    313 #define SkMSec_LT(a, b)     ((int32_t)(a) - (int32_t)(b) < 0)
    314 /** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
    315 */
    316 #define SkMSec_LE(a, b)     ((int32_t)(a) - (int32_t)(b) <= 0)
    317 
    318 /** The generation IDs in Skia reserve 0 has an invalid marker.
    319  */
    320 #define SK_InvalidGenID     0
    321 /** The unique IDs in Skia reserve 0 has an invalid marker.
    322  */
    323 #define SK_InvalidUniqueID  0
    324 
    325 /****************************************************************************
    326     The rest of these only build with C++
    327 */
    328 #ifdef __cplusplus
    329 
    330 /** Faster than SkToBool for integral conditions. Returns 0 or 1
    331 */
    332 static inline constexpr int Sk32ToBool(uint32_t n) {
    333     return (n | (0-n)) >> 31;
    334 }
    335 
    336 /** Generic swap function. Classes with efficient swaps should specialize this function to take
    337     their fast path. This function is used by SkTSort. */
    338 template <typename T> static inline void SkTSwap(T& a, T& b) {
    339     T c(std::move(a));
    340     a = std::move(b);
    341     b = std::move(c);
    342 }
    343 
    344 static inline int32_t SkAbs32(int32_t value) {
    345     SkASSERT(value != SK_NaN32);  // The most negative int32_t can't be negated.
    346     if (value < 0) {
    347         value = -value;
    348     }
    349     return value;
    350 }
    351 
    352 template <typename T> static inline T SkTAbs(T value) {
    353     if (value < 0) {
    354         value = -value;
    355     }
    356     return value;
    357 }
    358 
    359 static inline int32_t SkMax32(int32_t a, int32_t b) {
    360     if (a < b)
    361         a = b;
    362     return a;
    363 }
    364 
    365 static inline int32_t SkMin32(int32_t a, int32_t b) {
    366     if (a > b)
    367         a = b;
    368     return a;
    369 }
    370 
    371 template <typename T> constexpr const T& SkTMin(const T& a, const T& b) {
    372     return (a < b) ? a : b;
    373 }
    374 
    375 template <typename T> constexpr const T& SkTMax(const T& a, const T& b) {
    376     return (b < a) ? a : b;
    377 }
    378 
    379 static inline int32_t SkSign32(int32_t a) {
    380     return (a >> 31) | ((unsigned) -a >> 31);
    381 }
    382 
    383 static inline int32_t SkFastMin32(int32_t value, int32_t max) {
    384     if (value > max) {
    385         value = max;
    386     }
    387     return value;
    388 }
    389 
    390 /** Returns value pinned between min and max, inclusively. */
    391 template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
    392     return SkTMax(SkTMin(value, max), min);
    393 }
    394 
    395 
    396 ///////////////////////////////////////////////////////////////////////////////
    397 
    398 /**
    399  *  Indicates whether an allocation should count against a cache budget.
    400  */
    401 enum class SkBudgeted : bool {
    402     kNo  = false,
    403     kYes = true
    404 };
    405 
    406 /**
    407  * Indicates whether a backing store needs to be an exact match or can be larger
    408  * than is strictly necessary
    409  */
    410 enum class SkBackingFit {
    411     kApprox,
    412     kExact
    413 };
    414 
    415 ///////////////////////////////////////////////////////////////////////////////
    416 
    417 /** Use to combine multiple bits in a bitmask in a type safe way.
    418  */
    419 template <typename T>
    420 T SkTBitOr(T a, T b) {
    421     return (T)(a | b);
    422 }
    423 
    424 /**
    425  *  Use to cast a pointer to a different type, and maintaining strict-aliasing
    426  */
    427 template <typename Dst> Dst SkTCast(const void* ptr) {
    428     union {
    429         const void* src;
    430         Dst dst;
    431     } data;
    432     data.src = ptr;
    433     return data.dst;
    434 }
    435 
    436 //////////////////////////////////////////////////////////////////////////////
    437 
    438 /** \class SkNoncopyable
    439 
    440 SkNoncopyable is the base class for objects that do not want to
    441 be copied. It hides its copy-constructor and its assignment-operator.
    442 */
    443 class SK_API SkNoncopyable {
    444 public:
    445     SkNoncopyable() {}
    446 
    447 private:
    448     SkNoncopyable(const SkNoncopyable&);
    449     SkNoncopyable& operator=(const SkNoncopyable&);
    450 };
    451 
    452 #endif /* C++ */
    453 
    454 #endif
    455