blob: ce2a050f1e0b4ffc8a55c910894873d23f603a39 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
8#ifndef SkTypes_DEFINED
9#define SkTypes_DEFINED
10
Mike Klein81d35a72020-02-05 10:17:57 -060011/** \file SkTypes.h
12*/
13
14// Pre-SkUserConfig.h setup.
15
16// Allows embedders that want to disable macros that take arguments to just
17// define that symbol to be one of these
18#define SK_NOTHING_ARG1(arg1)
19#define SK_NOTHING_ARG2(arg1, arg2)
20#define SK_NOTHING_ARG3(arg1, arg2, arg3)
21
22#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN) && \
23 !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC)
24
25 #ifdef __APPLE__
26 #include "TargetConditionals.h"
27 #endif
28
29 #if defined(_WIN32) || defined(__SYMBIAN32__)
30 #define SK_BUILD_FOR_WIN
31 #elif defined(ANDROID) || defined(__ANDROID__)
32 #define SK_BUILD_FOR_ANDROID
33 #elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || \
34 defined(__OpenBSD__) || defined(__sun) || defined(__NetBSD__) || \
35 defined(__DragonFly__) || defined(__Fuchsia__) || \
36 defined(__GLIBC__) || defined(__GNU__) || defined(__unix__)
37 #define SK_BUILD_FOR_UNIX
38 #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
39 #define SK_BUILD_FOR_IOS
40 #else
41 #define SK_BUILD_FOR_MAC
42 #endif
43
44#endif
45
46#if defined(SK_BUILD_FOR_WIN) && !defined(__clang__)
47 #if !defined(SK_RESTRICT)
48 #define SK_RESTRICT __restrict
49 #endif
50 #if !defined(SK_WARN_UNUSED_RESULT)
51 #define SK_WARN_UNUSED_RESULT
52 #endif
53#endif
54
55#if !defined(SK_RESTRICT)
56 #define SK_RESTRICT __restrict__
57#endif
58
59#if !defined(SK_WARN_UNUSED_RESULT)
60 #define SK_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
61#endif
62
63#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
64 #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
65 #define SK_CPU_BENDIAN
66 #elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
67 #define SK_CPU_LENDIAN
68 #elif defined(__sparc) || defined(__sparc__) || \
69 defined(_POWER) || defined(__powerpc__) || \
70 defined(__ppc__) || defined(__hppa) || \
71 defined(__PPC__) || defined(__PPC64__) || \
72 defined(_MIPSEB) || defined(__ARMEB__) || \
73 defined(__s390__) || \
74 (defined(__sh__) && defined(__BIG_ENDIAN__)) || \
75 (defined(__ia64) && defined(__BIG_ENDIAN__))
76 #define SK_CPU_BENDIAN
77 #else
78 #define SK_CPU_LENDIAN
79 #endif
80#endif
81
82#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
83 #define SK_CPU_X86 1
84#endif
85
86/**
87 * SK_CPU_SSE_LEVEL
88 *
89 * If defined, SK_CPU_SSE_LEVEL should be set to the highest supported level.
90 * On non-intel CPU this should be undefined.
91 */
92#define SK_CPU_SSE_LEVEL_SSE1 10
93#define SK_CPU_SSE_LEVEL_SSE2 20
94#define SK_CPU_SSE_LEVEL_SSE3 30
95#define SK_CPU_SSE_LEVEL_SSSE3 31
96#define SK_CPU_SSE_LEVEL_SSE41 41
97#define SK_CPU_SSE_LEVEL_SSE42 42
98#define SK_CPU_SSE_LEVEL_AVX 51
99#define SK_CPU_SSE_LEVEL_AVX2 52
100#define SK_CPU_SSE_LEVEL_AVX512 60
101
102// When targetting iOS and using gyp to generate the build files, it is not
103// possible to select files to build depending on the architecture (i.e. it
104// is not possible to use hand optimized assembly implementation). In that
105// configuration SK_BUILD_NO_OPTS is defined. Remove optimisation then.
106#ifdef SK_BUILD_NO_OPTS
107 #define SK_CPU_SSE_LEVEL 0
108#endif
109
110// Are we in GCC/Clang?
111#ifndef SK_CPU_SSE_LEVEL
112 // These checks must be done in descending order to ensure we set the highest
113 // available SSE level.
114 #if defined(__AVX512F__)
115 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX512
116 #elif defined(__AVX2__)
117 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2
118 #elif defined(__AVX__)
119 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX
120 #elif defined(__SSE4_2__)
121 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE42
122 #elif defined(__SSE4_1__)
123 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE41
124 #elif defined(__SSSE3__)
125 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3
126 #elif defined(__SSE3__)
127 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3
128 #elif defined(__SSE2__)
129 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
130 #endif
131#endif
132
133// Are we in VisualStudio?
134#ifndef SK_CPU_SSE_LEVEL
135 // These checks must be done in descending order to ensure we set the highest
136 // available SSE level. 64-bit intel guarantees at least SSE2 support.
137 #if defined(__AVX2__)
138 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2
139 #elif defined(__AVX__)
140 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX
141 #elif defined(_M_X64) || defined(_M_AMD64)
142 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
143 #elif defined(_M_IX86_FP)
144 #if _M_IX86_FP >= 2
145 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
146 #elif _M_IX86_FP == 1
147 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1
148 #endif
149 #endif
150#endif
151
152// ARM defines
153#if defined(__arm__) && (!defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR)
154 #define SK_CPU_ARM32
155#elif defined(__aarch64__) && !defined(SK_BUILD_NO_OPTS)
156 #define SK_CPU_ARM64
157#endif
158
159// All 64-bit ARM chips have NEON. Many 32-bit ARM chips do too.
160#if !defined(SK_ARM_HAS_NEON) && !defined(SK_BUILD_NO_OPTS) && defined(__ARM_NEON)
161 #define SK_ARM_HAS_NEON
162#endif
163
164// Really this __APPLE__ check shouldn't be necessary, but it seems that Apple's Clang defines
165// __ARM_FEATURE_CRC32 for -arch arm64, even though their chips don't support those instructions!
166#if defined(__ARM_FEATURE_CRC32) && !defined(__APPLE__)
167 #define SK_ARM_HAS_CRC32
168#endif
169
170
171// DLL/.so exports.
172#if !defined(SKIA_IMPLEMENTATION)
173 #define SKIA_IMPLEMENTATION 0
174#endif
175#if !defined(SK_API)
176 #if defined(SKIA_DLL)
177 #if defined(_MSC_VER)
178 #if SKIA_IMPLEMENTATION
179 #define SK_API __declspec(dllexport)
180 #else
181 #define SK_API __declspec(dllimport)
182 #endif
183 #else
184 #define SK_API __attribute__((visibility("default")))
185 #endif
186 #else
187 #define SK_API
188 #endif
189#endif
190
191// SK_SPI is functionally identical to SK_API, but used within src to clarify that it's less stable
192#if !defined(SK_SPI)
193 #define SK_SPI SK_API
194#endif
195
bungemanf20488b2015-07-29 11:49:40 -0700196// IWYU pragma: begin_exports
Mike Kleindbbefa82019-04-23 11:11:35 -0500197#if defined (SK_USER_CONFIG_HEADER)
198 #include SK_USER_CONFIG_HEADER
199#else
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500200 #include "include/config/SkUserConfig.h"
Mike Kleindbbefa82019-04-23 11:11:35 -0500201#endif
bungemanf20488b2015-07-29 11:49:40 -0700202#include <stddef.h>
bungeman@google.comfab44db2013-10-11 18:50:45 +0000203#include <stdint.h>
bungemanf20488b2015-07-29 11:49:40 -0700204// IWYU pragma: end_exports
205
Mike Klein81d35a72020-02-05 10:17:57 -0600206// Post SkUserConfig.h checks and such.
207#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
208 #ifdef NDEBUG
209 #define SK_RELEASE
210 #else
211 #define SK_DEBUG
212 #endif
213#endif
214
215#if defined(SK_DEBUG) && defined(SK_RELEASE)
216# error "cannot define both SK_DEBUG and SK_RELEASE"
217#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
218# error "must define either SK_DEBUG or SK_RELEASE"
219#endif
220
221#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
222# error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
223#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
224# error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
225#endif
226
227#if defined(SK_CPU_BENDIAN) && !defined(I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN)
228 #error "The Skia team is not endian-savvy enough to support big-endian CPUs."
229 #error "If you still want to use Skia,"
230 #error "please define I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN."
231#endif
232
233#if !defined(SK_ATTRIBUTE)
234# if defined(__clang__) || defined(__GNUC__)
235# define SK_ATTRIBUTE(attr) __attribute__((attr))
236# else
237# define SK_ATTRIBUTE(attr)
238# endif
239#endif
240
241#if !defined(SK_SUPPORT_GPU)
242# define SK_SUPPORT_GPU 1
243#endif
244
245/**
246 * If GPU is enabled but no GPU backends are enabled then enable GL by default.
247 * Traditionally clients have relied on Skia always building with the GL backend
248 * and opting in to additional backends. TODO: Require explicit opt in for GL.
249 */
250#if SK_SUPPORT_GPU
Brian Salomon1171d312020-03-19 08:47:44 -0400251# if !defined(SK_GL) && !defined(SK_VULKAN) && !defined(SK_METAL)
Mike Klein81d35a72020-02-05 10:17:57 -0600252# define SK_GL
253# endif
254#endif
255
256#if !defined(SK_SUPPORT_ATLAS_TEXT)
257# define SK_SUPPORT_ATLAS_TEXT 0
258#elif SK_SUPPORT_ATLAS_TEXT && !SK_SUPPORT_GPU
259# error "SK_SUPPORT_ATLAS_TEXT requires SK_SUPPORT_GPU"
260#endif
261
262#if !defined(SkUNREACHABLE)
263# if defined(_MSC_VER) && !defined(__clang__)
264# define SkUNREACHABLE __assume(false)
265# else
266# define SkUNREACHABLE __builtin_unreachable()
267# endif
268#endif
269
270#if defined(SK_BUILD_FOR_GOOGLE3)
271 void SkDebugfForDumpStackTrace(const char* data, void* unused);
272 void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg);
273# define SK_DUMP_GOOGLE3_STACK() DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr)
274#else
275# define SK_DUMP_GOOGLE3_STACK()
276#endif
277
278#ifdef SK_BUILD_FOR_WIN
279 // Lets visual studio follow error back to source
280 #define SK_DUMP_LINE_FORMAT(message) \
281 SkDebugf("%s(%d): fatal error: \"%s\"\n", __FILE__, __LINE__, message)
282#else
283 #define SK_DUMP_LINE_FORMAT(message) \
284 SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message)
285#endif
286
287#ifndef SK_ABORT
288# define SK_ABORT(message) \
289 do { \
290 SK_DUMP_LINE_FORMAT(message); \
291 SK_DUMP_GOOGLE3_STACK(); \
292 sk_abort_no_print(); \
293 SkUNREACHABLE; \
294 } while (false)
295#endif
296
Mike Reeda04c91e2020-02-10 16:51:10 +0000297// If SK_R32_SHIFT is set, we'll use that to choose RGBA or BGRA.
298// If not, we'll default to RGBA everywhere except BGRA on Windows.
299#if defined(SK_R32_SHIFT)
300 static_assert(SK_R32_SHIFT == 0 || SK_R32_SHIFT == 16, "");
301#elif defined(SK_BUILD_FOR_WIN)
302 #define SK_R32_SHIFT 16
303#else
304 #define SK_R32_SHIFT 0
305#endif
306
307#if defined(SK_B32_SHIFT)
308 static_assert(SK_B32_SHIFT == (16-SK_R32_SHIFT), "");
309#else
310 #define SK_B32_SHIFT (16-SK_R32_SHIFT)
311#endif
312
Mike Klein81d35a72020-02-05 10:17:57 -0600313#define SK_G32_SHIFT 8
314#define SK_A32_SHIFT 24
315
Mike Reeda04c91e2020-02-10 16:51:10 +0000316
Mike Klein81d35a72020-02-05 10:17:57 -0600317/**
318 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
319 * relationship between the byte order and shift values depends on machine endianness. If the shift
320 * order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
321 * endian machine and the A channel on a big endian machine. Thus, given those shifts values,
322 * SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
323 * SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
324 */
325#ifdef SK_CPU_BENDIAN
326# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
327 (SK_ ## C3 ## 32_SHIFT == 0 && \
328 SK_ ## C2 ## 32_SHIFT == 8 && \
329 SK_ ## C1 ## 32_SHIFT == 16 && \
330 SK_ ## C0 ## 32_SHIFT == 24)
331#else
332# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
333 (SK_ ## C0 ## 32_SHIFT == 0 && \
334 SK_ ## C1 ## 32_SHIFT == 8 && \
335 SK_ ## C2 ## 32_SHIFT == 16 && \
336 SK_ ## C3 ## 32_SHIFT == 24)
337#endif
338
339#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN
340 #ifdef free
341 #undef free
342 #endif
343 #include <crtdbg.h>
344 #undef free
345#endif
346
347#if !defined(SK_UNUSED)
348# if !defined(__clang__) && defined(_MSC_VER)
349# define SK_UNUSED __pragma(warning(suppress:4189))
350# else
351# define SK_UNUSED SK_ATTRIBUTE(unused)
352# endif
353#endif
354
355/**
356 * If your judgment is better than the compiler's (i.e. you've profiled it),
357 * you can use SK_ALWAYS_INLINE to force inlining. E.g.
358 * inline void someMethod() { ... } // may not be inlined
359 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined
360 */
361#if !defined(SK_ALWAYS_INLINE)
362# if defined(SK_BUILD_FOR_WIN)
363# define SK_ALWAYS_INLINE __forceinline
364# else
365# define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
366# endif
367#endif
368
369/**
370 * If your judgment is better than the compiler's (i.e. you've profiled it),
371 * you can use SK_NEVER_INLINE to prevent inlining.
372 */
373#if !defined(SK_NEVER_INLINE)
374# if defined(SK_BUILD_FOR_WIN)
375# define SK_NEVER_INLINE __declspec(noinline)
376# else
377# define SK_NEVER_INLINE SK_ATTRIBUTE(noinline)
378# endif
379#endif
380
381#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
382 #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0)
383#elif defined(__GNUC__)
384 #define SK_PREFETCH(ptr) __builtin_prefetch(ptr)
385#else
386 #define SK_PREFETCH(ptr)
387#endif
388
389#ifndef SK_PRINTF_LIKE
390# if defined(__clang__) || defined(__GNUC__)
391# define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
392# else
393# define SK_PRINTF_LIKE(A, B)
394# endif
395#endif
396
397#ifndef SK_SIZE_T_SPECIFIER
398# if defined(_MSC_VER) && !defined(__clang__)
399# define SK_SIZE_T_SPECIFIER "%Iu"
400# else
401# define SK_SIZE_T_SPECIFIER "%zu"
402# endif
403#endif
404
405#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
406 #define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 0
407#endif
408
409#if !defined(SK_GAMMA_EXPONENT)
410 #define SK_GAMMA_EXPONENT (0.0f) // SRGB
411#endif
412
413#ifndef GR_TEST_UTILS
414# define GR_TEST_UTILS 0
415#endif
416
417#if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN)
418# define SK_HISTOGRAMS_ENABLED 1
419#else
420# define SK_HISTOGRAMS_ENABLED 0
421#endif
422
423#ifndef SK_HISTOGRAM_BOOLEAN
424# define SK_HISTOGRAM_BOOLEAN(name, value)
425#endif
426
427#ifndef SK_HISTOGRAM_ENUMERATION
428# define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value)
429#endif
430
431#ifndef SK_DISABLE_LEGACY_SHADERCONTEXT
432#define SK_ENABLE_LEGACY_SHADERCONTEXT
433#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000434
Chinmay Gardef832c0a2020-03-18 14:37:23 -0700435#ifdef SK_ENABLE_API_AVAILABLE
436#define SK_API_AVAILABLE API_AVAILABLE
437#else
438#define SK_API_AVAILABLE(...)
439#endif
440
reed@android.com8a1c16f2008-12-17 15:59:43 +0000441/** Called internally if we hit an unrecoverable error.
442 The platform implementation must not return, but should either throw
443 an exception or otherwise exit.
444*/
djsollenf2b340f2016-01-29 08:51:04 -0800445SK_API extern void sk_abort_no_print(void);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000446
reed@android.com8a1c16f2008-12-17 15:59:43 +0000447#ifndef SkDebugf
georgec4ade572014-08-01 12:02:07 -0700448 SK_API void SkDebugf(const char format[], ...);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000449#endif
450
Mike Klein37bbfe32017-09-28 09:47:45 -0400451// SkASSERT, SkASSERTF and SkASSERT_RELEASE can be used as stand alone assertion expressions, e.g.
452// uint32_t foo(int x) {
453// SkASSERT(x > 4);
454// return x - 4;
455// }
456// and are also written to be compatible with constexpr functions:
457// constexpr uint32_t foo(int x) {
458// return SkASSERT(x > 4),
459// x - 4;
460// }
caryclarkd6562002016-07-27 12:02:07 -0700461#define SkASSERT_RELEASE(cond) \
Mike Klein37bbfe32017-09-28 09:47:45 -0400462 static_cast<void>( (cond) ? (void)0 : []{ SK_ABORT("assert(" #cond ")"); }() )
djsollenf2b340f2016-01-29 08:51:04 -0800463
reed@android.com8a1c16f2008-12-17 15:59:43 +0000464#ifdef SK_DEBUG
Mike Klein37bbfe32017-09-28 09:47:45 -0400465 #define SkASSERT(cond) SkASSERT_RELEASE(cond)
466 #define SkASSERTF(cond, fmt, ...) static_cast<void>( (cond) ? (void)0 : [&]{ \
467 SkDebugf(fmt"\n", __VA_ARGS__); \
468 SK_ABORT("assert(" #cond ")"); \
469 }() )
bungeman1f790aa2016-07-20 09:49:10 -0700470 #define SkDEBUGFAIL(message) SK_ABORT(message)
herb966e3d32015-09-18 07:00:48 -0700471 #define SkDEBUGFAILF(fmt, ...) SkASSERTF(false, fmt, ##__VA_ARGS__)
csmartdaltonceeaa782016-08-10 10:07:57 -0700472 #define SkDEBUGCODE(...) __VA_ARGS__
Hal Canary2b0e6cd2018-07-09 12:43:39 -0400473 #define SkDEBUGF(...) SkDebugf(__VA_ARGS__)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000474 #define SkAssertResult(cond) SkASSERT(cond)
475#else
Mike Klein37bbfe32017-09-28 09:47:45 -0400476 #define SkASSERT(cond) static_cast<void>(0)
477 #define SkASSERTF(cond, fmt, ...) static_cast<void>(0)
tomhudson@google.com0c00f212011-12-28 14:59:50 +0000478 #define SkDEBUGFAIL(message)
hsterne6f8ff02016-08-15 15:26:31 -0700479 #define SkDEBUGFAILF(fmt, ...)
csmartdaltonceeaa782016-08-10 10:07:57 -0700480 #define SkDEBUGCODE(...)
Hal Canary2b0e6cd2018-07-09 12:43:39 -0400481 #define SkDEBUGF(...)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000482
Hal Canaryc36f7e72018-06-18 15:50:09 -0400483 // unlike SkASSERT, this macro executes its condition in the non-debug build.
bsalomon1b4c01c2016-05-09 12:35:17 -0700484 // The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
485 #define SkAssertResult(cond) if (cond) {} do {} while(false)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000486#endif
487
Hal Canarybc718c12018-06-12 14:16:11 -0400488////////////////////////////////////////////////////////////////////////////////
489
Hal Canaryc36f7e72018-06-18 15:50:09 -0400490/** Fast type for unsigned 8 bits. Use for parameter passing and local
491 variables, not for storage
492*/
reed@google.com37a31332011-01-25 14:55:42 +0000493typedef unsigned U8CPU;
494
Hal Canaryc36f7e72018-06-18 15:50:09 -0400495/** Fast type for unsigned 16 bits. Use for parameter passing and local
496 variables, not for storage
497*/
reed@google.com37a31332011-01-25 14:55:42 +0000498typedef unsigned U16CPU;
499
Hal Canaryc36f7e72018-06-18 15:50:09 -0400500/** @return false or true based on the condition
reed@android.com8a1c16f2008-12-17 15:59:43 +0000501*/
Hal Canaryc36f7e72018-06-18 15:50:09 -0400502template <typename T> static constexpr bool SkToBool(const T& x) { return 0 != x; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000503
Hal Canaryc36f7e72018-06-18 15:50:09 -0400504static constexpr int16_t SK_MaxS16 = INT16_MAX;
505static constexpr int16_t SK_MinS16 = -SK_MaxS16;
506
507static constexpr int32_t SK_MaxS32 = INT32_MAX;
508static constexpr int32_t SK_MinS32 = -SK_MaxS32;
509static constexpr int32_t SK_NaN32 = INT32_MIN;
510
Ben Wagnerb0897652018-06-15 15:37:57 +0000511static constexpr int64_t SK_MaxS64 = INT64_MAX;
Mike Reed3d5a6b52018-01-31 15:55:47 -0500512static constexpr int64_t SK_MinS64 = -SK_MaxS64;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000513
Mike Kleind9187c02018-09-07 17:32:47 +0000514static inline constexpr int32_t SkLeftShift(int32_t value, int32_t shift) {
515 return (int32_t) ((uint32_t) value << shift);
516}
517
518static inline constexpr int64_t SkLeftShift(int64_t value, int32_t shift) {
519 return (int64_t) ((uint64_t) value << shift);
520}
521
Hal Canaryc36f7e72018-06-18 15:50:09 -0400522////////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000523
Hal Canaryc36f7e72018-06-18 15:50:09 -0400524/** @return the number of entries in an array (not a pointer)
525*/
mtkleinfc00a7c2015-05-07 10:58:44 -0700526template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
caryclark95b96d62015-08-19 10:12:59 -0700527#define SK_ARRAY_COUNT(array) (sizeof(SkArrayCountHelper(array)))
reed@android.com8a1c16f2008-12-17 15:59:43 +0000528
Mike Kleind9187c02018-09-07 17:32:47 +0000529////////////////////////////////////////////////////////////////////////////////
530
531template <typename T> static constexpr T SkAlign2(T x) { return (x + 1) >> 1 << 1; }
532template <typename T> static constexpr T SkAlign4(T x) { return (x + 3) >> 2 << 2; }
533template <typename T> static constexpr T SkAlign8(T x) { return (x + 7) >> 3 << 3; }
534
535template <typename T> static constexpr bool SkIsAlign2(T x) { return 0 == (x & 1); }
536template <typename T> static constexpr bool SkIsAlign4(T x) { return 0 == (x & 3); }
537template <typename T> static constexpr bool SkIsAlign8(T x) { return 0 == (x & 7); }
538
539template <typename T> static constexpr T SkAlignPtr(T x) {
540 return sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x);
541}
542template <typename T> static constexpr bool SkIsAlignPtr(T x) {
543 return sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x);
544}
545
reed@android.com8a1c16f2008-12-17 15:59:43 +0000546typedef uint32_t SkFourByteTag;
Hal Canarybb9ee9b2018-06-12 16:47:47 -0400547static inline constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d) {
Hal Canarybc718c12018-06-12 14:16:11 -0400548 return (((uint8_t)a << 24) | ((uint8_t)b << 16) | ((uint8_t)c << 8) | (uint8_t)d);
549}
550
551////////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000552
553/** 32 bit integer to hold a unicode value
554*/
555typedef int32_t SkUnichar;
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700556
halcanaryd0e95a52016-07-25 07:18:12 -0700557/** 16 bit unsigned integer to hold a glyph index
558*/
559typedef uint16_t SkGlyphID;
560
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700561/** 32 bit value to hold a millisecond duration
Hal Canaryc36f7e72018-06-18 15:50:09 -0400562 Note that SK_MSecMax is about 25 days.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000563*/
Hal Canaryc36f7e72018-06-18 15:50:09 -0400564typedef uint32_t SkMSec;
565
566/** Maximum representable milliseconds; 24d 20h 31m 23.647s.
567*/
568static constexpr SkMSec SK_MSecMax = INT32_MAX;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000569
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000570/** The generation IDs in Skia reserve 0 has an invalid marker.
Hal Canaryc36f7e72018-06-18 15:50:09 -0400571*/
572static constexpr uint32_t SK_InvalidGenID = 0;
573
bsalomon1c63bf62014-07-22 13:09:46 -0700574/** The unique IDs in Skia reserve 0 has an invalid marker.
Hal Canaryc36f7e72018-06-18 15:50:09 -0400575*/
576static constexpr uint32_t SK_InvalidUniqueID = 0;
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000577
Mike Kleind9187c02018-09-07 17:32:47 +0000578static inline int32_t SkAbs32(int32_t value) {
579 SkASSERT(value != SK_NaN32); // The most negative int32_t can't be negated.
580 if (value < 0) {
581 value = -value;
582 }
583 return value;
584}
585
586template <typename T> static inline T SkTAbs(T value) {
587 if (value < 0) {
588 value = -value;
589 }
590 return value;
591}
592
Mike Kleind9187c02018-09-07 17:32:47 +0000593/** @return value pinned (clamped) between min and max, inclusively.
Brian Osmand0b3d9c2020-02-11 09:34:07 -0500594
595 NOTE: Unlike std::clamp, SkTPin has well-defined behavior if 'value' is a
596 floating point NaN. In that case, 'max' is returned.
Mike Kleind9187c02018-09-07 17:32:47 +0000597*/
598template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
Brian Osman788b9162020-02-07 10:36:46 -0500599 return value < min ? min : (value < max ? value : max);
Mike Kleind9187c02018-09-07 17:32:47 +0000600}
601
Hal Canaryc36f7e72018-06-18 15:50:09 -0400602////////////////////////////////////////////////////////////////////////////////
bsalomon5ec26ae2016-02-25 08:33:02 -0800603
Hal Canaryc36f7e72018-06-18 15:50:09 -0400604/** Indicates whether an allocation should count against a cache budget.
605*/
bsalomon5ec26ae2016-02-25 08:33:02 -0800606enum class SkBudgeted : bool {
607 kNo = false,
608 kYes = true
609};
610
Hal Canaryc36f7e72018-06-18 15:50:09 -0400611/** Indicates whether a backing store needs to be an exact match or can be
612 larger than is strictly necessary
613*/
robertphillips76948d42016-05-04 12:47:41 -0700614enum class SkBackingFit {
615 kApprox,
616 kExact
617};
618
reed@android.com8a1c16f2008-12-17 15:59:43 +0000619#endif