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() = default; 446 447 SkNoncopyable(SkNoncopyable&&) = default; 448 SkNoncopyable& operator =(SkNoncopyable&&) = default; 449 450 SkNoncopyable(const SkNoncopyable&) = delete; 451 SkNoncopyable& operator=(const SkNoncopyable&) = delete; 452 }; 453 454 #endif /* C++ */ 455 456 #endif 457