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 #include "SkPreConfig.h"
13 #include "SkUserConfig.h"
14 #include "SkPostConfig.h"
15 #include <stddef.h>
16 #include <stdint.h>
17 // IWYU pragma: end_exports
18
19 /** \file SkTypes.h
20 */
21
22 /** See SkGraphics::GetVersion() to retrieve these at runtime
23 */
24 #define SKIA_VERSION_MAJOR 1
25 #define SKIA_VERSION_MINOR 0
26 #define SKIA_VERSION_PATCH 0
27
28
29 /** Called internally if we hit an unrecoverable error.
30 The platform implementation must not return, but should either throw
31 an exception or otherwise exit.
32 */
33 SK_API extern void sk_abort_no_print(void);
34
35 #ifndef SkDebugf
36 SK_API void SkDebugf(const char format[], ...);
37 #endif
38
39 // SkASSERT, SkASSERTF and SkASSERT_RELEASE can be used as stand alone assertion expressions, e.g.
40 // uint32_t foo(int x) {
41 // SkASSERT(x > 4);
42 // return x - 4;
43 // }
44 // and are also written to be compatible with constexpr functions:
45 // constexpr uint32_t foo(int x) {
46 // return SkASSERT(x > 4),
47 // x - 4;
48 // }
49 #define SkASSERT_RELEASE(cond) \
50 static_cast<void>( (cond) ? (void)0 : []{ SK_ABORT("assert(" #cond ")"); }() )
51
52 #ifdef SK_DEBUG
53 #define SkASSERT(cond) SkASSERT_RELEASE(cond)
54 #define SkASSERTF(cond, fmt, ...) static_cast<void>( (cond) ? (void)0 : [&]{ \
55 SkDebugf(fmt"\n", __VA_ARGS__); \
56 SK_ABORT("assert(" #cond ")"); \
57 }() )
58 #define SkDEBUGFAIL(message) SK_ABORT(message)
59 #define SkDEBUGFAILF(fmt, ...) SkASSERTF(false, fmt, ##__VA_ARGS__)
60 #define SkDEBUGCODE(...) __VA_ARGS__
61 #define SkDEBUGF(...) SkDebugf(__VA_ARGS__)
62 #define SkAssertResult(cond) SkASSERT(cond)
63 #else
64 #define SkASSERT(cond) static_cast<void>(0)
65 #define SkASSERTF(cond, fmt, ...) static_cast<void>(0)
66 #define SkDEBUGFAIL(message)
67 #define SkDEBUGFAILF(fmt, ...)
68 #define SkDEBUGCODE(...)
69 #define SkDEBUGF(...)
70
71 // unlike SkASSERT, this macro executes its condition in the non-debug build.
72 // The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
73 #define SkAssertResult(cond) if (cond) {} do {} while(false)
74 #endif
75
76 ////////////////////////////////////////////////////////////////////////////////
77
78 /** Fast type for unsigned 8 bits. Use for parameter passing and local
79 variables, not for storage
80 */
81 typedef unsigned U8CPU;
82
83 /** Fast type for unsigned 16 bits. Use for parameter passing and local
84 variables, not for storage
85 */
86 typedef unsigned U16CPU;
87
88 /** @return false or true based on the condition
89 */
SkToBool(const T & x)90 template <typename T> static constexpr bool SkToBool(const T& x) { return 0 != x; }
91
92 static constexpr int16_t SK_MaxS16 = INT16_MAX;
93 static constexpr int16_t SK_MinS16 = -SK_MaxS16;
94
95 static constexpr int32_t SK_MaxS32 = INT32_MAX;
96 static constexpr int32_t SK_MinS32 = -SK_MaxS32;
97 static constexpr int32_t SK_NaN32 = INT32_MIN;
98
99 static constexpr int64_t SK_MaxS64 = INT64_MAX;
100 static constexpr int64_t SK_MinS64 = -SK_MaxS64;
101
SkLeftShift(int32_t value,int32_t shift)102 static inline constexpr int32_t SkLeftShift(int32_t value, int32_t shift) {
103 return (int32_t) ((uint32_t) value << shift);
104 }
105
SkLeftShift(int64_t value,int32_t shift)106 static inline constexpr int64_t SkLeftShift(int64_t value, int32_t shift) {
107 return (int64_t) ((uint64_t) value << shift);
108 }
109
110 ////////////////////////////////////////////////////////////////////////////////
111
112 /** @return the number of entries in an array (not a pointer)
113 */
114 template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
115 #define SK_ARRAY_COUNT(array) (sizeof(SkArrayCountHelper(array)))
116
117 ////////////////////////////////////////////////////////////////////////////////
118
SkAlign2(T x)119 template <typename T> static constexpr T SkAlign2(T x) { return (x + 1) >> 1 << 1; }
SkAlign4(T x)120 template <typename T> static constexpr T SkAlign4(T x) { return (x + 3) >> 2 << 2; }
SkAlign8(T x)121 template <typename T> static constexpr T SkAlign8(T x) { return (x + 7) >> 3 << 3; }
122
SkIsAlign2(T x)123 template <typename T> static constexpr bool SkIsAlign2(T x) { return 0 == (x & 1); }
SkIsAlign4(T x)124 template <typename T> static constexpr bool SkIsAlign4(T x) { return 0 == (x & 3); }
SkIsAlign8(T x)125 template <typename T> static constexpr bool SkIsAlign8(T x) { return 0 == (x & 7); }
126
SkAlignPtr(T x)127 template <typename T> static constexpr T SkAlignPtr(T x) {
128 return sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x);
129 }
SkIsAlignPtr(T x)130 template <typename T> static constexpr bool SkIsAlignPtr(T x) {
131 return sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x);
132 }
133
134 typedef uint32_t SkFourByteTag;
SkSetFourByteTag(char a,char b,char c,char d)135 static inline constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d) {
136 return (((uint8_t)a << 24) | ((uint8_t)b << 16) | ((uint8_t)c << 8) | (uint8_t)d);
137 }
138
139 ////////////////////////////////////////////////////////////////////////////////
140
141 /** 32 bit integer to hold a unicode value
142 */
143 typedef int32_t SkUnichar;
144
145 /** 16 bit unsigned integer to hold a glyph index
146 */
147 typedef uint16_t SkGlyphID;
148
149 /** 32 bit value to hold a millisecond duration
150 Note that SK_MSecMax is about 25 days.
151 */
152 typedef uint32_t SkMSec;
153
154 /** Maximum representable milliseconds; 24d 20h 31m 23.647s.
155 */
156 static constexpr SkMSec SK_MSecMax = INT32_MAX;
157
158 /** The generation IDs in Skia reserve 0 has an invalid marker.
159 */
160 static constexpr uint32_t SK_InvalidGenID = 0;
161
162 /** The unique IDs in Skia reserve 0 has an invalid marker.
163 */
164 static constexpr uint32_t SK_InvalidUniqueID = 0;
165
SkAbs32(int32_t value)166 static inline int32_t SkAbs32(int32_t value) {
167 SkASSERT(value != SK_NaN32); // The most negative int32_t can't be negated.
168 if (value < 0) {
169 value = -value;
170 }
171 return value;
172 }
173
SkTAbs(T value)174 template <typename T> static inline T SkTAbs(T value) {
175 if (value < 0) {
176 value = -value;
177 }
178 return value;
179 }
180
SkMax32(int32_t a,int32_t b)181 static inline int32_t SkMax32(int32_t a, int32_t b) {
182 if (a < b)
183 a = b;
184 return a;
185 }
186
SkMin32(int32_t a,int32_t b)187 static inline int32_t SkMin32(int32_t a, int32_t b) {
188 if (a > b)
189 a = b;
190 return a;
191 }
192
SkTMin(const T & a,const T & b)193 template <typename T> constexpr const T& SkTMin(const T& a, const T& b) {
194 return (a < b) ? a : b;
195 }
196
SkTMax(const T & a,const T & b)197 template <typename T> constexpr const T& SkTMax(const T& a, const T& b) {
198 return (b < a) ? a : b;
199 }
200
SkTClamp(const T & x,const T & lo,const T & hi)201 template <typename T> constexpr const T& SkTClamp(const T& x, const T& lo, const T& hi) {
202 return (x < lo) ? lo : SkTMin(x, hi);
203 }
204
205 /** @return value pinned (clamped) between min and max, inclusively.
206 */
SkTPin(const T & value,const T & min,const T & max)207 template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
208 return SkTMax(SkTMin(value, max), min);
209 }
210
211 ////////////////////////////////////////////////////////////////////////////////
212
213 /** Indicates whether an allocation should count against a cache budget.
214 */
215 enum class SkBudgeted : bool {
216 kNo = false,
217 kYes = true
218 };
219
220 /** Indicates whether a backing store needs to be an exact match or can be
221 larger than is strictly necessary
222 */
223 enum class SkBackingFit {
224 kApprox,
225 kExact
226 };
227
228 #endif
229