Line data Source code
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 194585 : template <typename D, typename S> D SkTo(S s) {
212 194585 : SkASSERT(SkTFitsIn<D>(s));
213 194585 : 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 0 : static inline bool SkIsS16(long x) {
242 0 : 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 29286 : static inline int32_t SkLeftShift(int32_t value, int32_t shift) {
252 29286 : return (int32_t) ((uint32_t) value << shift);
253 : }
254 :
255 5852 : static inline int64_t SkLeftShift(int64_t value, int32_t shift) {
256 5852 : 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 3823 : template <typename T> static inline void SkTSwap(T& a, T& b) {
339 3963 : T c(std::move(a));
340 3823 : a = std::move(b);
341 3823 : b = std::move(c);
342 3823 : }
343 :
344 8506 : static inline int32_t SkAbs32(int32_t value) {
345 8506 : SkASSERT(value != SK_NaN32); // The most negative int32_t can't be negated.
346 8506 : if (value < 0) {
347 2439 : value = -value;
348 : }
349 8506 : return value;
350 : }
351 :
352 0 : template <typename T> static inline T SkTAbs(T value) {
353 0 : if (value < 0) {
354 0 : value = -value;
355 : }
356 0 : return value;
357 : }
358 :
359 2953 : static inline int32_t SkMax32(int32_t a, int32_t b) {
360 2953 : if (a < b)
361 833 : a = b;
362 2953 : return a;
363 : }
364 :
365 27812 : static inline int32_t SkMin32(int32_t a, int32_t b) {
366 27812 : if (a > b)
367 6735 : a = b;
368 27812 : return a;
369 : }
370 :
371 26375 : template <typename T> constexpr const T& SkTMin(const T& a, const T& b) {
372 26375 : return (a < b) ? a : b;
373 : }
374 :
375 22241 : template <typename T> constexpr const T& SkTMax(const T& a, const T& b) {
376 22241 : 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 0 : static inline int32_t SkFastMin32(int32_t value, int32_t max) {
384 0 : if (value > max) {
385 0 : value = max;
386 : }
387 0 : return value;
388 : }
389 :
390 : /** Returns value pinned between min and max, inclusively. */
391 7085 : template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
392 7085 : 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 2340 : template <typename Dst> Dst SkTCast(const void* ptr) {
428 : union {
429 : const void* src;
430 : Dst dst;
431 : } data;
432 2340 : data.src = ptr;
433 2340 : 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 11902 : SkNoncopyable() {}
446 :
447 : private:
448 : SkNoncopyable(const SkNoncopyable&);
449 : SkNoncopyable& operator=(const SkNoncopyable&);
450 : };
451 :
452 : #endif /* C++ */
453 :
454 : #endif
|