blob: bbf64318e65e499431f98bbb38941540a9ac30ab [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__
Kevin Lubick7f5b19b2021-11-23 09:08:05 -050026 #include <TargetConditionals.h>
Mike Klein81d35a72020-02-05 10:17:57 -060027 #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
Mike Klein51d35ed2020-04-24 08:16:22 -0500100#define SK_CPU_SSE_LEVEL_SKX 60
Mike Klein81d35a72020-02-05 10:17:57 -0600101
Mike Klein81d35a72020-02-05 10:17:57 -0600102// Are we in GCC/Clang?
103#ifndef SK_CPU_SSE_LEVEL
104 // These checks must be done in descending order to ensure we set the highest
105 // available SSE level.
Mike Klein51d35ed2020-04-24 08:16:22 -0500106 #if defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512CD__) && \
107 defined(__AVX512BW__) && defined(__AVX512VL__)
108 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SKX
Mike Klein81d35a72020-02-05 10:17:57 -0600109 #elif defined(__AVX2__)
110 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2
111 #elif defined(__AVX__)
112 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX
113 #elif defined(__SSE4_2__)
114 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE42
115 #elif defined(__SSE4_1__)
116 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE41
117 #elif defined(__SSSE3__)
118 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3
119 #elif defined(__SSE3__)
120 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3
121 #elif defined(__SSE2__)
122 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
123 #endif
124#endif
125
126// Are we in VisualStudio?
127#ifndef SK_CPU_SSE_LEVEL
128 // These checks must be done in descending order to ensure we set the highest
129 // available SSE level. 64-bit intel guarantees at least SSE2 support.
Mike Klein51d35ed2020-04-24 08:16:22 -0500130 #if defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512CD__) && \
131 defined(__AVX512BW__) && defined(__AVX512VL__)
132 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SKX
133 #elif defined(__AVX2__)
Mike Klein81d35a72020-02-05 10:17:57 -0600134 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2
135 #elif defined(__AVX__)
136 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX
137 #elif defined(_M_X64) || defined(_M_AMD64)
138 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
139 #elif defined(_M_IX86_FP)
140 #if _M_IX86_FP >= 2
141 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
142 #elif _M_IX86_FP == 1
143 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1
144 #endif
145 #endif
146#endif
147
148// ARM defines
149#if defined(__arm__) && (!defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR)
150 #define SK_CPU_ARM32
Mike Klein09a26912020-12-07 12:03:11 -0600151#elif defined(__aarch64__)
Mike Klein81d35a72020-02-05 10:17:57 -0600152 #define SK_CPU_ARM64
153#endif
154
155// All 64-bit ARM chips have NEON. Many 32-bit ARM chips do too.
Mike Klein09a26912020-12-07 12:03:11 -0600156#if !defined(SK_ARM_HAS_NEON) && defined(__ARM_NEON)
Mike Klein81d35a72020-02-05 10:17:57 -0600157 #define SK_ARM_HAS_NEON
158#endif
159
Mike Klein62a0f152020-08-25 16:40:25 -0500160#if defined(__ARM_FEATURE_CRC32)
Mike Klein81d35a72020-02-05 10:17:57 -0600161 #define SK_ARM_HAS_CRC32
162#endif
163
164
165// DLL/.so exports.
166#if !defined(SKIA_IMPLEMENTATION)
167 #define SKIA_IMPLEMENTATION 0
168#endif
169#if !defined(SK_API)
170 #if defined(SKIA_DLL)
171 #if defined(_MSC_VER)
172 #if SKIA_IMPLEMENTATION
173 #define SK_API __declspec(dllexport)
174 #else
175 #define SK_API __declspec(dllimport)
176 #endif
177 #else
178 #define SK_API __attribute__((visibility("default")))
179 #endif
180 #else
181 #define SK_API
182 #endif
183#endif
184
185// SK_SPI is functionally identical to SK_API, but used within src to clarify that it's less stable
186#if !defined(SK_SPI)
187 #define SK_SPI SK_API
188#endif
189
bungemanf20488b2015-07-29 11:49:40 -0700190// IWYU pragma: begin_exports
Mike Kleindbbefa82019-04-23 11:11:35 -0500191#if defined (SK_USER_CONFIG_HEADER)
192 #include SK_USER_CONFIG_HEADER
193#else
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500194 #include "include/config/SkUserConfig.h"
Mike Kleindbbefa82019-04-23 11:11:35 -0500195#endif
bungemanf20488b2015-07-29 11:49:40 -0700196#include <stddef.h>
bungeman@google.comfab44db2013-10-11 18:50:45 +0000197#include <stdint.h>
bungemanf20488b2015-07-29 11:49:40 -0700198// IWYU pragma: end_exports
199
Mike Klein81d35a72020-02-05 10:17:57 -0600200// Post SkUserConfig.h checks and such.
201#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
202 #ifdef NDEBUG
203 #define SK_RELEASE
204 #else
205 #define SK_DEBUG
206 #endif
207#endif
208
209#if defined(SK_DEBUG) && defined(SK_RELEASE)
210# error "cannot define both SK_DEBUG and SK_RELEASE"
211#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
212# error "must define either SK_DEBUG or SK_RELEASE"
213#endif
214
215#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
216# error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
217#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
218# error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
219#endif
220
221#if defined(SK_CPU_BENDIAN) && !defined(I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN)
222 #error "The Skia team is not endian-savvy enough to support big-endian CPUs."
223 #error "If you still want to use Skia,"
224 #error "please define I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN."
225#endif
226
227#if !defined(SK_ATTRIBUTE)
228# if defined(__clang__) || defined(__GNUC__)
229# define SK_ATTRIBUTE(attr) __attribute__((attr))
230# else
231# define SK_ATTRIBUTE(attr)
232# endif
233#endif
234
235#if !defined(SK_SUPPORT_GPU)
236# define SK_SUPPORT_GPU 1
237#endif
238
Greg Daniela21aacf2021-10-25 16:47:46 -0400239#if SK_SUPPORT_GPU || SK_GRAPHITE_ENABLED
Brian Osman946a4cb2021-07-12 17:02:21 -0400240# if !defined(SK_ENABLE_SKSL)
241# define SK_ENABLE_SKSL
242# endif
243#else
Brian Salomonf4ba4ec2020-03-19 15:54:28 -0400244# undef SK_GL
245# undef SK_VULKAN
246# undef SK_METAL
247# undef SK_DAWN
248# undef SK_DIRECT3D
Mike Klein81d35a72020-02-05 10:17:57 -0600249#endif
250
Mike Klein81d35a72020-02-05 10:17:57 -0600251#if !defined(SkUNREACHABLE)
252# if defined(_MSC_VER) && !defined(__clang__)
Ben Wagner07953612020-06-17 11:24:53 -0400253# include <intrin.h>
254# define FAST_FAIL_INVALID_ARG 5
255// See https://developercommunity.visualstudio.com/content/problem/1128631/code-flow-doesnt-see-noreturn-with-extern-c.html
256// for why this is wrapped. Hopefully removable after msvc++ 19.27 is no longer supported.
257[[noreturn]] static inline void sk_fast_fail() { __fastfail(FAST_FAIL_INVALID_ARG); }
258# define SkUNREACHABLE sk_fast_fail()
Mike Klein81d35a72020-02-05 10:17:57 -0600259# else
Ben Wagner07953612020-06-17 11:24:53 -0400260# define SkUNREACHABLE __builtin_trap()
Mike Klein81d35a72020-02-05 10:17:57 -0600261# endif
262#endif
263
264#if defined(SK_BUILD_FOR_GOOGLE3)
265 void SkDebugfForDumpStackTrace(const char* data, void* unused);
266 void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg);
267# define SK_DUMP_GOOGLE3_STACK() DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr)
268#else
269# define SK_DUMP_GOOGLE3_STACK()
270#endif
271
Mike Klein81d35a72020-02-05 10:17:57 -0600272#ifndef SK_ABORT
John Stiles616da102020-06-12 14:07:41 -0400273# ifdef SK_BUILD_FOR_WIN
274 // This style lets Visual Studio follow errors back to the source file.
275# define SK_DUMP_LINE_FORMAT "%s(%d)"
276# else
277# define SK_DUMP_LINE_FORMAT "%s:%d"
278# endif
279# define SK_ABORT(message, ...) \
Mike Klein81d35a72020-02-05 10:17:57 -0600280 do { \
John Stiles616da102020-06-12 14:07:41 -0400281 SkDebugf(SK_DUMP_LINE_FORMAT ": fatal error: \"" message "\"\n", \
282 __FILE__, __LINE__, ##__VA_ARGS__); \
283 SK_DUMP_GOOGLE3_STACK(); \
284 sk_abort_no_print(); \
Mike Klein81d35a72020-02-05 10:17:57 -0600285 } while (false)
286#endif
287
Mike Reeda04c91e2020-02-10 16:51:10 +0000288// If SK_R32_SHIFT is set, we'll use that to choose RGBA or BGRA.
289// If not, we'll default to RGBA everywhere except BGRA on Windows.
290#if defined(SK_R32_SHIFT)
291 static_assert(SK_R32_SHIFT == 0 || SK_R32_SHIFT == 16, "");
292#elif defined(SK_BUILD_FOR_WIN)
293 #define SK_R32_SHIFT 16
294#else
295 #define SK_R32_SHIFT 0
296#endif
297
298#if defined(SK_B32_SHIFT)
299 static_assert(SK_B32_SHIFT == (16-SK_R32_SHIFT), "");
300#else
301 #define SK_B32_SHIFT (16-SK_R32_SHIFT)
302#endif
303
Mike Klein81d35a72020-02-05 10:17:57 -0600304#define SK_G32_SHIFT 8
305#define SK_A32_SHIFT 24
306
Mike Reeda04c91e2020-02-10 16:51:10 +0000307
Mike Klein81d35a72020-02-05 10:17:57 -0600308/**
John Stiles9f987c32020-05-27 14:12:26 -0400309 * SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time.
Mike Klein81d35a72020-02-05 10:17:57 -0600310 */
311#ifdef SK_CPU_BENDIAN
312# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
313 (SK_ ## C3 ## 32_SHIFT == 0 && \
314 SK_ ## C2 ## 32_SHIFT == 8 && \
315 SK_ ## C1 ## 32_SHIFT == 16 && \
316 SK_ ## C0 ## 32_SHIFT == 24)
317#else
318# define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
319 (SK_ ## C0 ## 32_SHIFT == 0 && \
320 SK_ ## C1 ## 32_SHIFT == 8 && \
321 SK_ ## C2 ## 32_SHIFT == 16 && \
322 SK_ ## C3 ## 32_SHIFT == 24)
323#endif
324
325#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN
326 #ifdef free
327 #undef free
328 #endif
329 #include <crtdbg.h>
330 #undef free
331#endif
332
333#if !defined(SK_UNUSED)
334# if !defined(__clang__) && defined(_MSC_VER)
335# define SK_UNUSED __pragma(warning(suppress:4189))
336# else
337# define SK_UNUSED SK_ATTRIBUTE(unused)
338# endif
339#endif
340
Greg Daniel4fc3a012021-05-04 15:10:03 -0400341#if !defined(SK_MAYBE_UNUSED)
342# if defined(__clang__) || defined(__GNUC__)
343# define SK_MAYBE_UNUSED [[maybe_unused]]
344# else
345# define SK_MAYBE_UNUSED
346# endif
347#endif
348
Mike Klein81d35a72020-02-05 10:17:57 -0600349/**
350 * If your judgment is better than the compiler's (i.e. you've profiled it),
351 * you can use SK_ALWAYS_INLINE to force inlining. E.g.
352 * inline void someMethod() { ... } // may not be inlined
353 * SK_ALWAYS_INLINE void someMethod() { ... } // should always be inlined
354 */
355#if !defined(SK_ALWAYS_INLINE)
356# if defined(SK_BUILD_FOR_WIN)
357# define SK_ALWAYS_INLINE __forceinline
358# else
359# define SK_ALWAYS_INLINE SK_ATTRIBUTE(always_inline) inline
360# endif
361#endif
362
363/**
364 * If your judgment is better than the compiler's (i.e. you've profiled it),
365 * you can use SK_NEVER_INLINE to prevent inlining.
366 */
367#if !defined(SK_NEVER_INLINE)
368# if defined(SK_BUILD_FOR_WIN)
369# define SK_NEVER_INLINE __declspec(noinline)
370# else
371# define SK_NEVER_INLINE SK_ATTRIBUTE(noinline)
372# endif
373#endif
374
375#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
376 #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0)
377#elif defined(__GNUC__)
378 #define SK_PREFETCH(ptr) __builtin_prefetch(ptr)
379#else
380 #define SK_PREFETCH(ptr)
381#endif
382
383#ifndef SK_PRINTF_LIKE
384# if defined(__clang__) || defined(__GNUC__)
385# define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
386# else
387# define SK_PRINTF_LIKE(A, B)
388# endif
389#endif
390
Mike Klein81d35a72020-02-05 10:17:57 -0600391#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
392 #define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 0
393#endif
394
395#if !defined(SK_GAMMA_EXPONENT)
396 #define SK_GAMMA_EXPONENT (0.0f) // SRGB
397#endif
398
399#ifndef GR_TEST_UTILS
400# define GR_TEST_UTILS 0
401#endif
402
Robert Phillips7cef6782021-07-01 13:21:37 -0400403#ifndef SK_GPU_V1
404# define SK_GPU_V1 1
Robert Phillips7b931f82021-06-09 14:04:05 -0400405#endif
406
Greg Daniel65476e02020-10-27 09:20:20 -0400407#if defined(SK_HISTOGRAM_ENUMERATION) || \
408 defined(SK_HISTOGRAM_BOOLEAN) || \
Greg Daniel771c7502020-10-29 10:24:54 -0400409 defined(SK_HISTOGRAM_EXACT_LINEAR) || \
410 defined(SK_HISTOGRAM_MEMORY_KB)
Mike Klein81d35a72020-02-05 10:17:57 -0600411# define SK_HISTOGRAMS_ENABLED 1
412#else
413# define SK_HISTOGRAMS_ENABLED 0
414#endif
415
416#ifndef SK_HISTOGRAM_BOOLEAN
Greg Daniel65476e02020-10-27 09:20:20 -0400417# define SK_HISTOGRAM_BOOLEAN(name, sample)
Mike Klein81d35a72020-02-05 10:17:57 -0600418#endif
419
420#ifndef SK_HISTOGRAM_ENUMERATION
Greg Daniel65476e02020-10-27 09:20:20 -0400421# define SK_HISTOGRAM_ENUMERATION(name, sample, enum_size)
422#endif
423
424#ifndef SK_HISTOGRAM_EXACT_LINEAR
Greg Daniel771c7502020-10-29 10:24:54 -0400425# define SK_HISTOGRAM_EXACT_LINEAR(name, sample, value_max)
Mike Klein81d35a72020-02-05 10:17:57 -0600426#endif
427
Greg Daniel771c7502020-10-29 10:24:54 -0400428#ifndef SK_HISTOGRAM_MEMORY_KB
429# define SK_HISTOGRAM_MEMORY_KB(name, sample)
430#endif
431
432#define SK_HISTOGRAM_PERCENTAGE(name, percent_as_int) \
433 SK_HISTOGRAM_EXACT_LINEAR(name, percent_as_int, 101)
434
Mike Klein81d35a72020-02-05 10:17:57 -0600435#ifndef SK_DISABLE_LEGACY_SHADERCONTEXT
436#define SK_ENABLE_LEGACY_SHADERCONTEXT
437#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000438
Chinmay Gardef832c0a2020-03-18 14:37:23 -0700439#ifdef SK_ENABLE_API_AVAILABLE
440#define SK_API_AVAILABLE API_AVAILABLE
441#else
442#define SK_API_AVAILABLE(...)
443#endif
444
Kevin Lubick493f89e2020-09-14 08:37:35 -0400445#if defined(SK_BUILD_FOR_LIBFUZZER) || defined(SK_BUILD_FOR_AFL_FUZZ)
446 #define SK_BUILD_FOR_FUZZER
447#endif
448
reed@android.com8a1c16f2008-12-17 15:59:43 +0000449/** Called internally if we hit an unrecoverable error.
450 The platform implementation must not return, but should either throw
451 an exception or otherwise exit.
452*/
Ben Wagner1e67f7f2020-07-28 10:26:57 -0400453[[noreturn]] SK_API extern void sk_abort_no_print(void);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000454
reed@android.com8a1c16f2008-12-17 15:59:43 +0000455#ifndef SkDebugf
John Stiles55f0d7a2021-07-14 19:36:50 -0400456 SK_API void SkDebugf(const char format[], ...) SK_PRINTF_LIKE(1, 2);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000457#endif
458
Mike Klein37bbfe32017-09-28 09:47:45 -0400459// SkASSERT, SkASSERTF and SkASSERT_RELEASE can be used as stand alone assertion expressions, e.g.
460// uint32_t foo(int x) {
461// SkASSERT(x > 4);
462// return x - 4;
463// }
464// and are also written to be compatible with constexpr functions:
465// constexpr uint32_t foo(int x) {
466// return SkASSERT(x > 4),
467// x - 4;
468// }
caryclarkd6562002016-07-27 12:02:07 -0700469#define SkASSERT_RELEASE(cond) \
John Stiles616da102020-06-12 14:07:41 -0400470 static_cast<void>( (cond) ? (void)0 : []{ SK_ABORT("assert(%s)", #cond); }() )
djsollenf2b340f2016-01-29 08:51:04 -0800471
reed@android.com8a1c16f2008-12-17 15:59:43 +0000472#ifdef SK_DEBUG
Mike Klein37bbfe32017-09-28 09:47:45 -0400473 #define SkASSERT(cond) SkASSERT_RELEASE(cond)
474 #define SkASSERTF(cond, fmt, ...) static_cast<void>( (cond) ? (void)0 : [&]{ \
Ethan Nicholasbb9fbe02020-12-01 10:44:47 -0500475 SkDebugf(fmt"\n", ##__VA_ARGS__); \
John Stiles616da102020-06-12 14:07:41 -0400476 SK_ABORT("assert(%s)", #cond); \
Mike Klein37bbfe32017-09-28 09:47:45 -0400477 }() )
John Stiles616da102020-06-12 14:07:41 -0400478 #define SkDEBUGFAIL(message) SK_ABORT("%s", message)
479 #define SkDEBUGFAILF(fmt, ...) SK_ABORT(fmt, ##__VA_ARGS__)
csmartdaltonceeaa782016-08-10 10:07:57 -0700480 #define SkDEBUGCODE(...) __VA_ARGS__
Hal Canary2b0e6cd2018-07-09 12:43:39 -0400481 #define SkDEBUGF(...) SkDebugf(__VA_ARGS__)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000482 #define SkAssertResult(cond) SkASSERT(cond)
483#else
Mike Klein37bbfe32017-09-28 09:47:45 -0400484 #define SkASSERT(cond) static_cast<void>(0)
485 #define SkASSERTF(cond, fmt, ...) static_cast<void>(0)
tomhudson@google.com0c00f212011-12-28 14:59:50 +0000486 #define SkDEBUGFAIL(message)
hsterne6f8ff02016-08-15 15:26:31 -0700487 #define SkDEBUGFAILF(fmt, ...)
csmartdaltonceeaa782016-08-10 10:07:57 -0700488 #define SkDEBUGCODE(...)
Hal Canary2b0e6cd2018-07-09 12:43:39 -0400489 #define SkDEBUGF(...)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000490
Hal Canaryc36f7e72018-06-18 15:50:09 -0400491 // unlike SkASSERT, this macro executes its condition in the non-debug build.
bsalomon1b4c01c2016-05-09 12:35:17 -0700492 // The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
493 #define SkAssertResult(cond) if (cond) {} do {} while(false)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000494#endif
495
Hal Canarybc718c12018-06-12 14:16:11 -0400496////////////////////////////////////////////////////////////////////////////////
497
Hal Canaryc36f7e72018-06-18 15:50:09 -0400498/** Fast type for unsigned 8 bits. Use for parameter passing and local
499 variables, not for storage
500*/
reed@google.com37a31332011-01-25 14:55:42 +0000501typedef unsigned U8CPU;
502
Hal Canaryc36f7e72018-06-18 15:50:09 -0400503/** Fast type for unsigned 16 bits. Use for parameter passing and local
504 variables, not for storage
505*/
reed@google.com37a31332011-01-25 14:55:42 +0000506typedef unsigned U16CPU;
507
Hal Canaryc36f7e72018-06-18 15:50:09 -0400508/** @return false or true based on the condition
reed@android.com8a1c16f2008-12-17 15:59:43 +0000509*/
John Stilesfe0de302020-08-14 10:52:06 -0400510template <typename T> static constexpr bool SkToBool(const T& x) {
511 return 0 != x; // NOLINT(modernize-use-nullptr)
512}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000513
Hal Canaryc36f7e72018-06-18 15:50:09 -0400514static constexpr int16_t SK_MaxS16 = INT16_MAX;
515static constexpr int16_t SK_MinS16 = -SK_MaxS16;
516
517static constexpr int32_t SK_MaxS32 = INT32_MAX;
518static constexpr int32_t SK_MinS32 = -SK_MaxS32;
519static constexpr int32_t SK_NaN32 = INT32_MIN;
520
Ben Wagnerb0897652018-06-15 15:37:57 +0000521static constexpr int64_t SK_MaxS64 = INT64_MAX;
Mike Reed3d5a6b52018-01-31 15:55:47 -0500522static constexpr int64_t SK_MinS64 = -SK_MaxS64;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000523
Mike Kleind9187c02018-09-07 17:32:47 +0000524static inline constexpr int32_t SkLeftShift(int32_t value, int32_t shift) {
525 return (int32_t) ((uint32_t) value << shift);
526}
527
528static inline constexpr int64_t SkLeftShift(int64_t value, int32_t shift) {
529 return (int64_t) ((uint64_t) value << shift);
530}
531
Hal Canaryc36f7e72018-06-18 15:50:09 -0400532////////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000533
Hal Canaryc36f7e72018-06-18 15:50:09 -0400534/** @return the number of entries in an array (not a pointer)
535*/
mtkleinfc00a7c2015-05-07 10:58:44 -0700536template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
caryclark95b96d62015-08-19 10:12:59 -0700537#define SK_ARRAY_COUNT(array) (sizeof(SkArrayCountHelper(array)))
reed@android.com8a1c16f2008-12-17 15:59:43 +0000538
Mike Kleind9187c02018-09-07 17:32:47 +0000539////////////////////////////////////////////////////////////////////////////////
540
541template <typename T> static constexpr T SkAlign2(T x) { return (x + 1) >> 1 << 1; }
542template <typename T> static constexpr T SkAlign4(T x) { return (x + 3) >> 2 << 2; }
543template <typename T> static constexpr T SkAlign8(T x) { return (x + 7) >> 3 << 3; }
544
545template <typename T> static constexpr bool SkIsAlign2(T x) { return 0 == (x & 1); }
546template <typename T> static constexpr bool SkIsAlign4(T x) { return 0 == (x & 3); }
547template <typename T> static constexpr bool SkIsAlign8(T x) { return 0 == (x & 7); }
548
549template <typename T> static constexpr T SkAlignPtr(T x) {
550 return sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x);
551}
552template <typename T> static constexpr bool SkIsAlignPtr(T x) {
553 return sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x);
554}
555
Kevin Lubickafa657d2021-11-01 11:45:19 -0400556/**
557 * align up to a power of 2
558 */
559static inline constexpr size_t SkAlignTo(size_t x, size_t alignment) {
560 // The same as alignment && SkIsPow2(value), w/o a dependency cycle.
561 SkASSERT(alignment && (alignment & (alignment - 1)) == 0);
562 return (x + alignment - 1) & ~(alignment - 1);
563}
564
reed@android.com8a1c16f2008-12-17 15:59:43 +0000565typedef uint32_t SkFourByteTag;
Hal Canarybb9ee9b2018-06-12 16:47:47 -0400566static inline constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d) {
Mike Klein89c909e2020-06-01 15:50:19 -0500567 return (((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | (uint32_t)d);
Hal Canarybc718c12018-06-12 14:16:11 -0400568}
569
570////////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000571
572/** 32 bit integer to hold a unicode value
573*/
574typedef int32_t SkUnichar;
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700575
halcanaryd0e95a52016-07-25 07:18:12 -0700576/** 16 bit unsigned integer to hold a glyph index
577*/
578typedef uint16_t SkGlyphID;
579
benjaminwagnerec4d4d72016-03-25 12:59:53 -0700580/** 32 bit value to hold a millisecond duration
Hal Canaryc36f7e72018-06-18 15:50:09 -0400581 Note that SK_MSecMax is about 25 days.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000582*/
Hal Canaryc36f7e72018-06-18 15:50:09 -0400583typedef uint32_t SkMSec;
584
585/** Maximum representable milliseconds; 24d 20h 31m 23.647s.
586*/
587static constexpr SkMSec SK_MSecMax = INT32_MAX;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000588
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000589/** The generation IDs in Skia reserve 0 has an invalid marker.
Hal Canaryc36f7e72018-06-18 15:50:09 -0400590*/
591static constexpr uint32_t SK_InvalidGenID = 0;
592
bsalomon1c63bf62014-07-22 13:09:46 -0700593/** The unique IDs in Skia reserve 0 has an invalid marker.
Hal Canaryc36f7e72018-06-18 15:50:09 -0400594*/
595static constexpr uint32_t SK_InvalidUniqueID = 0;
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000596
Mike Kleind9187c02018-09-07 17:32:47 +0000597static inline int32_t SkAbs32(int32_t value) {
598 SkASSERT(value != SK_NaN32); // The most negative int32_t can't be negated.
599 if (value < 0) {
600 value = -value;
601 }
602 return value;
603}
604
605template <typename T> static inline T SkTAbs(T value) {
606 if (value < 0) {
607 value = -value;
608 }
609 return value;
610}
611
Hal Canaryc36f7e72018-06-18 15:50:09 -0400612////////////////////////////////////////////////////////////////////////////////
bsalomon5ec26ae2016-02-25 08:33:02 -0800613
Hal Canaryc36f7e72018-06-18 15:50:09 -0400614/** Indicates whether an allocation should count against a cache budget.
615*/
bsalomon5ec26ae2016-02-25 08:33:02 -0800616enum class SkBudgeted : bool {
617 kNo = false,
618 kYes = true
619};
620
Hal Canaryc36f7e72018-06-18 15:50:09 -0400621/** Indicates whether a backing store needs to be an exact match or can be
622 larger than is strictly necessary
623*/
robertphillips76948d42016-05-04 12:47:41 -0700624enum class SkBackingFit {
625 kApprox,
626 kExact
627};
628
reed@android.com8a1c16f2008-12-17 15:59:43 +0000629#endif