Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkTypes.h
Go to the documentation of this file.
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 
51 static inline void* sk_careful_memcpy(void* dst, const void* src, size_t len) {
52  // When we pass >0 len we had better already be passing valid pointers.
53  // So we just need to skip calling memcpy when len == 0.
54  if (len) {
55  memcpy(dst,src,len);
56  }
57  return dst;
58 }
59 
65 #define SKIA_VERSION_MAJOR 1
66 #define SKIA_VERSION_MINOR 0
67 #define SKIA_VERSION_PATCH 0
68 
69 /*
70  memory wrappers to be implemented by the porting layer (platform)
71 */
72 
76 SK_API extern void sk_out_of_memory(void);
81 SK_API extern void sk_abort_no_print(void);
82 
83 enum {
84  SK_MALLOC_TEMP = 0x01,
86 };
92 SK_API extern void* sk_malloc_flags(size_t size, unsigned flags);
95 SK_API extern void* sk_malloc_throw(size_t size);
99 SK_API extern void* sk_realloc_throw(void* buffer, size_t size);
102 SK_API extern void sk_free(void*);
103 
106 SK_API extern void* sk_calloc(size_t size);
107 
110 SK_API extern void* sk_calloc_throw(size_t size);
111 
112 // bzero is safer than memset, but we can't rely on it, so... sk_bzero()
113 static inline void sk_bzero(void* buffer, size_t size) {
114  // Please c.f. sk_careful_memcpy. It's undefined behavior to call memset(null, 0, 0).
115  if (size) {
116  memset(buffer, 0, size);
117  }
118 }
119 
121 
122 #ifdef override_GLOBAL_NEW
123 #include <new>
124 
125 inline void* operator new(size_t size) {
126  return sk_malloc_throw(size);
127 }
128 
129 inline void operator delete(void* p) {
130  sk_free(p);
131 }
132 #endif
133 
135 
136 #define SK_INIT_TO_AVOID_WARNING = 0
137 
138 #ifndef SkDebugf
139  SK_API void SkDebugf(const char format[], ...);
140 #endif
141 
142 #define SkREQUIRE_SEMICOLON_AFTER(code) do { code } while (false)
143 
144 #define SkASSERT_RELEASE(cond) \
145  SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT(#cond); } )
146 
147 #ifdef SK_DEBUG
148  #define SkASSERT(cond) \
149  SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT("assert(" #cond ")"); })
150  #define SkASSERTF(cond, fmt, ...) \
151  SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { \
152  SkDebugf(fmt"\n", __VA_ARGS__); \
153  SK_ABORT("assert(" #cond ")"); \
154  })
155  #define SkDEBUGFAIL(message) SK_ABORT(message)
156  #define SkDEBUGFAILF(fmt, ...) SkASSERTF(false, fmt, ##__VA_ARGS__)
157  #define SkDEBUGCODE(...) __VA_ARGS__
158  #define SkDECLAREPARAM(type, var) , type var
159  #define SkPARAM(var) , var
160  #define SkDEBUGF(args ) SkDebugf args
161  #define SkAssertResult(cond) SkASSERT(cond)
162 #else
163  #define SkASSERT(cond)
164  #define SkASSERTF(cond, fmt, ...)
165  #define SkDEBUGFAIL(message)
166  #define SkDEBUGFAILF(fmt, ...)
167  #define SkDEBUGCODE(...)
168  #define SkDEBUGF(args)
169  #define SkDECLAREPARAM(type, var)
170  #define SkPARAM(var)
171 
172  // unlike SkASSERT, this guy executes its condition in the non-debug build.
173  // The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
174  #define SkAssertResult(cond) if (cond) {} do {} while(false)
175 #endif
176 
177 // Legacy macro names for SK_ABORT
178 #define SkFAIL(message) SK_ABORT(message)
179 #define sk_throw() SK_ABORT("sk_throw")
180 
181 #ifdef SK_IGNORE_TO_STRING
182  #define SK_TO_STRING_NONVIRT()
183  #define SK_TO_STRING_VIRT()
184  #define SK_TO_STRING_PUREVIRT()
185  #define SK_TO_STRING_OVERRIDE()
186 #else
187  class SkString;
188  // the 'toString' helper functions convert Sk* objects to human-readable
189  // form in developer mode
190  #define SK_TO_STRING_NONVIRT() void toString(SkString* str) const;
191  #define SK_TO_STRING_VIRT() virtual void toString(SkString* str) const;
192  #define SK_TO_STRING_PUREVIRT() virtual void toString(SkString* str) const = 0;
193  #define SK_TO_STRING_OVERRIDE() void toString(SkString* str) const override;
194 #endif
195 
196 /*
197  * Usage: SK_MACRO_CONCAT(a, b) to construct the symbol ab
198  *
199  * SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
200  *
201  */
202 #define SK_MACRO_CONCAT(X, Y) SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
203 #define SK_MACRO_CONCAT_IMPL_PRIV(X, Y) X ## Y
204 
205 /*
206  * Usage: SK_MACRO_APPEND_LINE(foo) to make foo123, where 123 is the current
207  * line number. Easy way to construct
208  * unique names for local functions or
209  * variables.
210  */
211 #define SK_MACRO_APPEND_LINE(name) SK_MACRO_CONCAT(name, __LINE__)
212 
236 #define SK_REQUIRE_LOCAL_VAR(classname) \
237  static_assert(false, "missing name for " #classname)
238 
240 
245 typedef int S8CPU;
246 
251 typedef unsigned U8CPU;
252 
257 typedef int S16CPU;
258 
263 typedef unsigned U16CPU;
264 
268 typedef uint8_t SkBool8;
269 
270 #include "../private/SkTFitsIn.h"
271 template <typename D, typename S> D SkTo(S s) {
272  SkASSERT(SkTFitsIn<D>(s));
273  return static_cast<D>(s);
274 }
275 #define SkToS8(x) SkTo<int8_t>(x)
276 #define SkToU8(x) SkTo<uint8_t>(x)
277 #define SkToS16(x) SkTo<int16_t>(x)
278 #define SkToU16(x) SkTo<uint16_t>(x)
279 #define SkToS32(x) SkTo<int32_t>(x)
280 #define SkToU32(x) SkTo<uint32_t>(x)
281 #define SkToInt(x) SkTo<int>(x)
282 #define SkToUInt(x) SkTo<unsigned>(x)
283 #define SkToSizeT(x) SkTo<size_t>(x)
284 
287 #define SkToBool(cond) ((cond) != 0)
288 
289 #define SK_MaxS16 32767
290 #define SK_MinS16 -32767
291 #define SK_MaxU16 0xFFFF
292 #define SK_MinU16 0
293 #define SK_MaxS32 0x7FFFFFFF
294 #define SK_MinS32 -SK_MaxS32
295 #define SK_MaxU32 0xFFFFFFFF
296 #define SK_MinU32 0
297 #define SK_NaN32 ((int) (1U << 31))
298 
301 static inline bool SkIsS16(long x) {
302  return (int16_t)x == x;
303 }
304 
307 static inline bool SkIsU16(long x) {
308  return (uint16_t)x == x;
309 }
310 
311 static inline int32_t SkLeftShift(int32_t value, int32_t shift) {
312  return (int32_t) ((uint32_t) value << shift);
313 }
314 
315 static inline int64_t SkLeftShift(int64_t value, int32_t shift) {
316  return (int64_t) ((uint64_t) value << shift);
317 }
318 
320 
322 template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
323 #define SK_ARRAY_COUNT(array) (sizeof(SkArrayCountHelper(array)))
324 
325 // Can be used to bracket data types that must be dense, e.g. hash keys.
326 #if defined(__clang__) // This should work on GCC too, but GCC diagnostic pop didn't seem to work!
327  #define SK_BEGIN_REQUIRE_DENSE _Pragma("GCC diagnostic push") \
328  _Pragma("GCC diagnostic error \"-Wpadded\"")
329  #define SK_END_REQUIRE_DENSE _Pragma("GCC diagnostic pop")
330 #else
331  #define SK_BEGIN_REQUIRE_DENSE
332  #define SK_END_REQUIRE_DENSE
333 #endif
334 
335 #define SkAlign2(x) (((x) + 1) >> 1 << 1)
336 #define SkIsAlign2(x) (0 == ((x) & 1))
337 
338 #define SkAlign4(x) (((x) + 3) >> 2 << 2)
339 #define SkIsAlign4(x) (0 == ((x) & 3))
340 
341 #define SkAlign8(x) (((x) + 7) >> 3 << 3)
342 #define SkIsAlign8(x) (0 == ((x) & 7))
343 
344 #define SkAlign16(x) (((x) + 15) >> 4 << 4)
345 #define SkIsAlign16(x) (0 == ((x) & 15))
346 
347 #define SkAlignPtr(x) (sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x))
348 #define SkIsAlignPtr(x) (sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x))
349 
350 typedef uint32_t SkFourByteTag;
351 #define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
352 
355 typedef int32_t SkUnichar;
356 
359 typedef uint16_t SkGlyphID;
360 
364 typedef uint32_t SkMSec;
367 #define SK_MSec1 1000
368 
370 #define SK_MSecMax 0x7FFFFFFF
371 
373 #define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0)
374 
376 #define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
377 
380 #define SK_InvalidGenID 0
381 
383 #define SK_InvalidUniqueID 0
384 
385 /****************************************************************************
386  The rest of these only build with C++
387 */
388 #ifdef __cplusplus
389 
392 static inline constexpr int Sk32ToBool(uint32_t n) {
393  return (n | (0-n)) >> 31;
394 }
395 
398 template <typename T> inline void SkTSwap(T& a, T& b) {
399  T c(a);
400  a = b;
401  b = c;
402 }
403 
404 static inline int32_t SkAbs32(int32_t value) {
405  SkASSERT(value != SK_NaN32); // The most negative int32_t can't be negated.
406  if (value < 0) {
407  value = -value;
408  }
409  return value;
410 }
411 
412 template <typename T> inline T SkTAbs(T value) {
413  if (value < 0) {
414  value = -value;
415  }
416  return value;
417 }
418 
419 static inline int32_t SkMax32(int32_t a, int32_t b) {
420  if (a < b)
421  a = b;
422  return a;
423 }
424 
425 static inline int32_t SkMin32(int32_t a, int32_t b) {
426  if (a > b)
427  a = b;
428  return a;
429 }
430 
431 template <typename T> constexpr const T& SkTMin(const T& a, const T& b) {
432  return (a < b) ? a : b;
433 }
434 
435 template <typename T> constexpr const T& SkTMax(const T& a, const T& b) {
436  return (b < a) ? a : b;
437 }
438 
439 static inline int32_t SkSign32(int32_t a) {
440  return (a >> 31) | ((unsigned) -a >> 31);
441 }
442 
443 static inline int32_t SkFastMin32(int32_t value, int32_t max) {
444  if (value > max) {
445  value = max;
446  }
447  return value;
448 }
449 
451 template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
452  return SkTMax(SkTMin(value, max), min);
453 }
454 
455 
457 
461 enum class SkBudgeted : bool {
462  kNo = false,
463  kYes = true
464 };
465 
470 enum class SkBackingFit {
471  kApprox,
472  kExact
473 };
474 
476 
479 template <typename T>
480 T SkTBitOr(T a, T b) {
481  return (T)(a | b);
482 }
483 
487 template <typename Dst> Dst SkTCast(const void* ptr) {
488  union {
489  const void* src;
490  Dst dst;
491  } data;
492  data.src = ptr;
493  return data.dst;
494 }
495 
497 
503 class SK_API SkNoncopyable {
504 public:
505  SkNoncopyable() {}
506 
507 private:
508  SkNoncopyable(const SkNoncopyable&);
509  SkNoncopyable& operator=(const SkNoncopyable&);
510 };
511 
512 class SkAutoFree : SkNoncopyable {
513 public:
514  SkAutoFree() : fPtr(NULL) {}
515  explicit SkAutoFree(void* ptr) : fPtr(ptr) {}
516  ~SkAutoFree() { sk_free(fPtr); }
517 
520  void* get() const { return fPtr; }
521 
526  void* set(void* ptr) {
527  void* prev = fPtr;
528  fPtr = ptr;
529  return prev;
530  }
531 
536  void* release() { return this->set(NULL); }
537 
541  void reset() {
542  sk_free(fPtr);
543  fPtr = NULL;
544  }
545 
546 private:
547  void* fPtr;
548  // illegal
549  SkAutoFree(const SkAutoFree&);
550  SkAutoFree& operator=(const SkAutoFree&);
551 };
552 #define SkAutoFree(...) SK_REQUIRE_LOCAL_VAR(SkAutoFree)
553 
559 class SkAutoMalloc : SkNoncopyable {
560 public:
561  explicit SkAutoMalloc(size_t size = 0) {
562  fPtr = size ? sk_malloc_throw(size) : NULL;
563  fSize = size;
564  }
565 
566  ~SkAutoMalloc() {
567  sk_free(fPtr);
568  }
569 
574  enum OnShrink {
580  kAlloc_OnShrink,
581 
587  kReuse_OnShrink
588  };
589 
593  void* reset(size_t size = 0, OnShrink shrink = kAlloc_OnShrink, bool* didChangeAlloc = NULL) {
594  if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) {
595  if (didChangeAlloc) {
596  *didChangeAlloc = false;
597  }
598  return fPtr;
599  }
600 
601  sk_free(fPtr);
602  fPtr = size ? sk_malloc_throw(size) : NULL;
603  fSize = size;
604  if (didChangeAlloc) {
605  *didChangeAlloc = true;
606  }
607 
608  return fPtr;
609  }
610 
614  void* get() { return fPtr; }
615  const void* get() const { return fPtr; }
616 
621  void* release() {
622  void* ptr = fPtr;
623  fPtr = NULL;
624  fSize = 0;
625  return ptr;
626  }
627 
628 private:
629  void* fPtr;
630  size_t fSize; // can be larger than the requested size (see kReuse)
631 };
632 #define SkAutoMalloc(...) SK_REQUIRE_LOCAL_VAR(SkAutoMalloc)
633 
640 template <size_t kSizeRequested> class SkAutoSMalloc : SkNoncopyable {
641 public:
646  SkAutoSMalloc() {
647  fPtr = fStorage;
648  fSize = kSize;
649  }
650 
655  explicit SkAutoSMalloc(size_t size) {
656  fPtr = fStorage;
657  fSize = kSize;
658  this->reset(size);
659  }
660 
665  ~SkAutoSMalloc() {
666  if (fPtr != (void*)fStorage) {
667  sk_free(fPtr);
668  }
669  }
670 
676  void* get() const { return fPtr; }
677 
683  void* reset(size_t size,
684  SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink,
685  bool* didChangeAlloc = NULL) {
686  size = (size < kSize) ? kSize : size;
687  bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink || size > fSize);
688  if (didChangeAlloc) {
689  *didChangeAlloc = alloc;
690  }
691  if (alloc) {
692  if (fPtr != (void*)fStorage) {
693  sk_free(fPtr);
694  }
695 
696  if (size == kSize) {
697  SkASSERT(fPtr != fStorage); // otherwise we lied when setting didChangeAlloc.
698  fPtr = fStorage;
699  } else {
701  }
702 
703  fSize = size;
704  }
705  SkASSERT(fSize >= size && fSize >= kSize);
706  SkASSERT((fPtr == fStorage) || fSize > kSize);
707  return fPtr;
708  }
709 
710 private:
711  // Align up to 32 bits.
712  static const size_t kSizeAlign4 = SkAlign4(kSizeRequested);
713 #if defined(GOOGLE3)
714  // Stack frame size is limited for GOOGLE3. 4k is less than the actual max, but some functions
715  // have multiple large stack allocations.
716  static const size_t kMaxBytes = 4 * 1024;
717  static const size_t kSize = kSizeRequested > kMaxBytes ? kMaxBytes : kSizeAlign4;
718 #else
719  static const size_t kSize = kSizeAlign4;
720 #endif
721 
722  void* fPtr;
723  size_t fSize; // can be larger than the requested size (see kReuse)
724  uint32_t fStorage[kSize >> 2];
725 };
726 // Can't guard the constructor because it's a template class.
727 
728 #endif /* C++ */
729 
730 #endif
SK_API void * sk_malloc_throw(size_t size)
Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag.
uint16_t SkGlyphID
16 bit unsigned integer to hold a glyph index
Definition: SkTypes.h:359
SK_API void sk_out_of_memory(void)
Called internally if we run out of memory.
char(& SkArrayCountHelper(T(&array)[N]))[N]
Returns the number of entries in an array (not a pointer)
SK_API void * sk_calloc_throw(size_t size)
Same as sk_calloc, but throws an exception instead of returning NULL on failure.
SK_API void * sk_malloc_flags(size_t size, unsigned flags)
Return a block of memory (at least 4-byte aligned) of at least the specified size.
uint8_t SkBool8
Meant to be a small version of bool, for storage purposes.
Definition: SkTypes.h:268
unsigned U16CPU
Fast type for unsigned 16 bits.
Definition: SkTypes.h:263
instructs sk_malloc to call sk_throw if the memory cannot be allocated.
Definition: SkTypes.h:85
SK_API void sk_free(void *)
Free memory returned by sk_malloc().
uint32_t SkMSec
32 bit value to hold a millisecond duration Note that SK_MSecMax is about 25 days.
Definition: SkTypes.h:364
hint to sk_malloc that the requested memory will be freed in the scope of the stack frame ...
Definition: SkTypes.h:84
static bool SkIsS16(long x)
Returns true if the value can be represented with signed 16bits.
Definition: SkTypes.h:301
static bool SkIsU16(long x)
Returns true if the value can be represented with unsigned 16bits.
Definition: SkTypes.h:307
int S8CPU
Fast type for signed 8 bits.
Definition: SkTypes.h:245
int32_t SkUnichar
32 bit integer to hold a unicode value
Definition: SkTypes.h:355
SK_API void sk_abort_no_print(void)
Called internally if we hit an unrecoverable error.
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
sk_careful_memcpy() is just like memcpy(), but guards against undefined behavior. ...
Definition: SkTypes.h:51
SK_API void * sk_realloc_throw(void *buffer, size_t size)
Same as standard realloc(), but this one never returns null on failure.
SK_API void * sk_calloc(size_t size)
Much like calloc: returns a pointer to at least size zero bytes, or NULL on failure.
unsigned U8CPU
Fast type for unsigned 8 bits.
Definition: SkTypes.h:251
Light weight class for managing strings.
Definition: SkString.h:121
int S16CPU
Fast type for signed 16 bits.
Definition: SkTypes.h:257