blob: d50f2eb715eb07b75b26cb4ea6ee526e0753b65f [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkTypes_DEFINED
11#define SkTypes_DEFINED
12
13#include "SkPreConfig.h"
14#include "SkUserConfig.h"
15#include "SkPostConfig.h"
16
17#ifndef SK_IGNORE_STDINT_DOT_H
18 #include <stdint.h>
19#endif
20
21#include <stdio.h>
22
23/** \file SkTypes.h
24*/
25
reed@android.com9aa8b322010-04-13 13:22:54 +000026/** See SkGraphics::GetVersion() to retrieve these at runtime
27 */
28#define SKIA_VERSION_MAJOR 1
29#define SKIA_VERSION_MINOR 0
30#define SKIA_VERSION_PATCH 0
31
reed@android.com8a1c16f2008-12-17 15:59:43 +000032/*
33 memory wrappers to be implemented by the porting layer (platform)
34*/
35
36/** Called internally if we run out of memory. The platform implementation must
37 not return, but should either throw an exception or otherwise exit.
38*/
39extern void sk_out_of_memory(void);
40/** Called internally if we hit an unrecoverable error.
41 The platform implementation must not return, but should either throw
42 an exception or otherwise exit.
43*/
44extern void sk_throw(void);
45
46enum {
47 SK_MALLOC_TEMP = 0x01, //!< hint to sk_malloc that the requested memory will be freed in the scope of the stack frame
48 SK_MALLOC_THROW = 0x02 //!< instructs sk_malloc to call sk_throw if the memory cannot be allocated.
49};
50/** Return a block of memory (at least 4-byte aligned) of at least the
51 specified size. If the requested memory cannot be returned, either
52 return null (if SK_MALLOC_TEMP bit is clear) or call sk_throw()
53 (if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free().
54*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000055SK_API extern void* sk_malloc_flags(size_t size, unsigned flags);
reed@android.com8a1c16f2008-12-17 15:59:43 +000056/** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag
57*/
58extern void* sk_malloc_throw(size_t size);
59/** Same as standard realloc(), but this one never returns null on failure. It will throw
60 an exception if it fails.
61*/
62extern void* sk_realloc_throw(void* buffer, size_t size);
63/** Free memory returned by sk_malloc(). It is safe to pass null.
64*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000065SK_API extern void sk_free(void*);
reed@android.com8a1c16f2008-12-17 15:59:43 +000066
reed@android.com4516f472009-06-29 16:25:36 +000067// bzero is safer than memset, but we can't rely on it, so... sk_bzero()
68static inline void sk_bzero(void* buffer, size_t size) {
69 memset(buffer, 0, size);
70}
71
reed@android.com8a1c16f2008-12-17 15:59:43 +000072///////////////////////////////////////////////////////////////////////
73
74#define SK_INIT_TO_AVOID_WARNING = 0
75
76#ifndef SkDebugf
77 void SkDebugf(const char format[], ...);
78#endif
79
80#ifdef SK_DEBUG
81 #define SkASSERT(cond) SK_DEBUGBREAK(cond)
82 #define SkDEBUGCODE(code) code
83 #define SkDECLAREPARAM(type, var) , type var
84 #define SkPARAM(var) , var
85// #define SkDEBUGF(args ) SkDebugf##args
86 #define SkDEBUGF(args ) SkDebugf args
87 #define SkAssertResult(cond) SkASSERT(cond)
88#else
89 #define SkASSERT(cond)
90 #define SkDEBUGCODE(code)
91 #define SkDEBUGF(args)
92 #define SkDECLAREPARAM(type, var)
93 #define SkPARAM(var)
94
95 // unlike SkASSERT, this guy executes its condition in the non-debug build
96 #define SkAssertResult(cond) cond
97#endif
98
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000099namespace {
100
101template <bool>
102struct SkCompileAssert {
103};
104
105} // namespace
106
107#define SK_COMPILE_ASSERT(expr, msg) \
108 typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
109
reed@android.com8a1c16f2008-12-17 15:59:43 +0000110///////////////////////////////////////////////////////////////////////
111
reed@google.com37a31332011-01-25 14:55:42 +0000112/**
113 * Fast type for signed 8 bits. Use for parameter passing and local variables,
114 * not for storage.
115 */
116typedef int S8CPU;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117
reed@google.com37a31332011-01-25 14:55:42 +0000118/**
119 * Fast type for unsigned 8 bits. Use for parameter passing and local
120 * variables, not for storage
121 */
122typedef unsigned U8CPU;
123
124/**
125 * Fast type for signed 16 bits. Use for parameter passing and local variables,
126 * not for storage
127 */
128typedef int S16CPU;
129
130/**
131 * Fast type for unsigned 16 bits. Use for parameter passing and local
132 * variables, not for storage
133 */
134typedef unsigned U16CPU;
135
136/**
137 * Meant to be faster than bool (doesn't promise to be 0 or 1,
138 * just 0 or non-zero
139 */
140typedef int SkBool;
141
142/**
143 * Meant to be a small version of bool, for storage purposes. Will be 0 or 1
144 */
145typedef uint8_t SkBool8;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146
147#ifdef SK_DEBUG
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +0000148 SK_API int8_t SkToS8(long);
149 SK_API uint8_t SkToU8(size_t);
150 SK_API int16_t SkToS16(long);
151 SK_API uint16_t SkToU16(size_t);
152 SK_API int32_t SkToS32(long);
153 SK_API uint32_t SkToU32(size_t);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000154#else
155 #define SkToS8(x) ((int8_t)(x))
156 #define SkToU8(x) ((uint8_t)(x))
157 #define SkToS16(x) ((int16_t)(x))
158 #define SkToU16(x) ((uint16_t)(x))
159 #define SkToS32(x) ((int32_t)(x))
160 #define SkToU32(x) ((uint32_t)(x))
161#endif
162
163/** Returns 0 or 1 based on the condition
164*/
165#define SkToBool(cond) ((cond) != 0)
166
167#define SK_MaxS16 32767
168#define SK_MinS16 -32767
169#define SK_MaxU16 0xFFFF
170#define SK_MinU16 0
171#define SK_MaxS32 0x7FFFFFFF
172#define SK_MinS32 0x80000001
173#define SK_MaxU32 0xFFFFFFFF
174#define SK_MinU32 0
175#define SK_NaN32 0x80000000
176
reed@android.comd4577752009-11-21 02:48:11 +0000177/** Returns true if the value can be represented with signed 16bits
178 */
reed@android.com90209ca2009-11-21 19:58:04 +0000179static inline bool SkIsS16(long x) {
reed@android.comd4577752009-11-21 02:48:11 +0000180 return (int16_t)x == x;
181}
182
183/** Returns true if the value can be represented with unsigned 16bits
184 */
reed@android.com90209ca2009-11-21 19:58:04 +0000185static inline bool SkIsU16(long x) {
reed@android.comd4577752009-11-21 02:48:11 +0000186 return (uint16_t)x == x;
187}
188
189//////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000190#ifndef SK_OFFSETOF
191 #define SK_OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1)
192#endif
193
194/** Returns the number of entries in an array (not a pointer)
195*/
196#define SK_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
197
198/** Returns x rounded up to a multiple of 2
199*/
200#define SkAlign2(x) (((x) + 1) >> 1 << 1)
201/** Returns x rounded up to a multiple of 4
202*/
203#define SkAlign4(x) (((x) + 3) >> 2 << 2)
204
205typedef uint32_t SkFourByteTag;
206#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
207
208/** 32 bit integer to hold a unicode value
209*/
210typedef int32_t SkUnichar;
211/** 32 bit value to hold a millisecond count
212*/
213typedef uint32_t SkMSec;
214/** 1 second measured in milliseconds
215*/
216#define SK_MSec1 1000
217/** maximum representable milliseconds
218*/
219#define SK_MSecMax 0x7FFFFFFF
220/** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
221*/
222#define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0)
223/** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0
224*/
225#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
226
reed@android.com8a1c16f2008-12-17 15:59:43 +0000227/****************************************************************************
228 The rest of these only build with C++
229*/
230#ifdef __cplusplus
231
232/** Faster than SkToBool for integral conditions. Returns 0 or 1
233*/
reed@android.comd4577752009-11-21 02:48:11 +0000234static inline int Sk32ToBool(uint32_t n) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235 return (n | (0-n)) >> 31;
236}
237
reed@android.comd4577752009-11-21 02:48:11 +0000238template <typename T> inline void SkTSwap(T& a, T& b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000239 T c(a);
240 a = b;
241 b = c;
242}
243
reed@android.comd4577752009-11-21 02:48:11 +0000244static inline int32_t SkAbs32(int32_t value) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000245#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
246 if (value < 0)
247 value = -value;
248 return value;
249#else
250 int32_t mask = value >> 31;
251 return (value ^ mask) - mask;
252#endif
253}
254
reed@android.comd4577752009-11-21 02:48:11 +0000255static inline int32_t SkMax32(int32_t a, int32_t b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000256 if (a < b)
257 a = b;
258 return a;
259}
260
reed@android.comd4577752009-11-21 02:48:11 +0000261static inline int32_t SkMin32(int32_t a, int32_t b) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000262 if (a > b)
263 a = b;
264 return a;
265}
266
reed@android.comd4577752009-11-21 02:48:11 +0000267static inline int32_t SkSign32(int32_t a) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000268 return (a >> 31) | ((unsigned) -a >> 31);
269}
270
reed@android.comd4577752009-11-21 02:48:11 +0000271static inline int32_t SkFastMin32(int32_t value, int32_t max) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000272#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
273 if (value > max)
274 value = max;
275 return value;
276#else
277 int diff = max - value;
278 // clear diff if it is negative (clear if value > max)
279 diff &= (diff >> 31);
280 return value + diff;
281#endif
282}
283
284/** Returns signed 32 bit value pinned between min and max, inclusively
285*/
reed@android.comd4577752009-11-21 02:48:11 +0000286static inline int32_t SkPin32(int32_t value, int32_t min, int32_t max) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000287#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
288 if (value < min)
289 value = min;
290 if (value > max)
291 value = max;
292#else
293 if (value < min)
294 value = min;
295 else if (value > max)
296 value = max;
297#endif
298 return value;
299}
300
reed@android.comd4577752009-11-21 02:48:11 +0000301static inline uint32_t SkSetClearShift(uint32_t bits, bool cond,
302 unsigned shift) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000303 SkASSERT((int)cond == 0 || (int)cond == 1);
304 return (bits & ~(1 << shift)) | ((int)cond << shift);
305}
306
reed@android.comd4577752009-11-21 02:48:11 +0000307static inline uint32_t SkSetClearMask(uint32_t bits, bool cond,
308 uint32_t mask) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000309 return cond ? bits | mask : bits & ~mask;
310}
311
reed@google.com1fcd51e2011-01-05 15:50:27 +0000312///////////////////////////////////////////////////////////////////////////////
313
vandebo@chromium.org325cb9a2011-03-30 18:36:29 +0000314/** Use to combine multiple bits in a bitmask in a type safe way.
315 */
316template <typename T>
317T SkTBitOr(T a, T b) {
318 return (T)(a | b);
319}
320
reed@google.com1fcd51e2011-01-05 15:50:27 +0000321/**
322 * Use to cast a pointer to a different type, and maintaining strict-aliasing
323 */
324template <typename Dst> Dst SkTCast(const void* ptr) {
325 union {
326 const void* src;
327 Dst dst;
328 } data;
329 data.src = ptr;
330 return data.dst;
331}
332
reed@android.com8a1c16f2008-12-17 15:59:43 +0000333//////////////////////////////////////////////////////////////////////////////
334
335/** \class SkNoncopyable
336
337SkNoncopyable is the base class for objects that may do not want to
338be copied. It hides its copy-constructor and its assignment-operator.
339*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +0000340class SK_API SkNoncopyable {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000341public:
342 SkNoncopyable() {}
reed@google.com1fcd51e2011-01-05 15:50:27 +0000343
reed@android.com8a1c16f2008-12-17 15:59:43 +0000344private:
345 SkNoncopyable(const SkNoncopyable&);
346 SkNoncopyable& operator=(const SkNoncopyable&);
347};
348
349class SkAutoFree : SkNoncopyable {
350public:
351 SkAutoFree() : fPtr(NULL) {}
352 explicit SkAutoFree(void* ptr) : fPtr(ptr) {}
353 ~SkAutoFree() { sk_free(fPtr); }
reed@google.com1fcd51e2011-01-05 15:50:27 +0000354
reed@android.com8a1c16f2008-12-17 15:59:43 +0000355 /** Return the currently allocate buffer, or null
356 */
357 void* get() const { return fPtr; }
358
359 /** Assign a new ptr allocated with sk_malloc (or null), and return the
360 previous ptr. Note it is the caller's responsibility to sk_free the
361 returned ptr.
362 */
363 void* set(void* ptr) {
364 void* prev = fPtr;
365 fPtr = ptr;
366 return prev;
367 }
reed@google.com1fcd51e2011-01-05 15:50:27 +0000368
reed@android.com8a1c16f2008-12-17 15:59:43 +0000369 /** Transfer ownership of the current ptr to the caller, setting the
370 internal reference to null. Note the caller is reponsible for calling
371 sk_free on the returned address.
372 */
373 void* detach() { return this->set(NULL); }
374
375 /** Free the current buffer, and set the internal reference to NULL. Same
376 as calling sk_free(detach())
377 */
378 void free() {
379 sk_free(fPtr);
380 fPtr = NULL;
381 }
382
383private:
384 void* fPtr;
385 // illegal
386 SkAutoFree(const SkAutoFree&);
387 SkAutoFree& operator=(const SkAutoFree&);
388};
389
390class SkAutoMalloc : public SkAutoFree {
391public:
392 explicit SkAutoMalloc(size_t size)
393 : SkAutoFree(sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP)) {}
394
395 SkAutoMalloc(size_t size, unsigned flags)
396 : SkAutoFree(sk_malloc_flags(size, flags)) {}
397 SkAutoMalloc() {}
398
399 void* alloc(size_t size,
400 unsigned flags = (SK_MALLOC_THROW | SK_MALLOC_TEMP)) {
401 sk_free(set(sk_malloc_flags(size, flags)));
402 return get();
403 }
404};
405
reed@google.com63a60602011-03-10 13:07:35 +0000406/**
407 * Manage an allocated block of memory. If the requested size is <= kSize, then
408 * the allocation will come from the stack rather than the heap. This object
409 * is the sole manager of the lifetime of the block, so the caller must not
410 * call sk_free() or delete on the block.
411 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000412template <size_t kSize> class SkAutoSMalloc : SkNoncopyable {
413public:
reed@google.com63a60602011-03-10 13:07:35 +0000414 /**
415 * Creates initially empty storage. get() returns a ptr, but it is to
416 * a zero-byte allocation. Must call realloc(size) to return an allocated
417 * block.
418 */
419 SkAutoSMalloc() {
420 fPtr = fStorage;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000421 }
reed@google.com63a60602011-03-10 13:07:35 +0000422
423 /**
424 * Allocate a block of the specified size. If size <= kSize, then the
425 * allocation will come from the stack, otherwise it will be dynamically
426 * allocated.
427 */
428 explicit SkAutoSMalloc(size_t size) {
429 fPtr = fStorage;
430 this->realloc(size);
431 }
432
433 /**
434 * Free the allocated block (if any). If the block was small enought to
435 * have been allocated on the stack (size <= kSize) then this does nothing.
436 */
437 ~SkAutoSMalloc() {
438 if (fPtr != (void*)fStorage) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000439 sk_free(fPtr);
reed@google.com63a60602011-03-10 13:07:35 +0000440 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000441 }
reed@google.com63a60602011-03-10 13:07:35 +0000442
443 /**
444 * Return the allocated block. May return non-null even if the block is
445 * of zero size. Since this may be on the stack or dynamically allocated,
446 * the caller must not call sk_free() on it, but must rely on SkAutoSMalloc
447 * to manage it.
448 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000449 void* get() const { return fPtr; }
reed@google.com63a60602011-03-10 13:07:35 +0000450
451 /**
452 * Return a new block of the requested size, freeing (as necessary) any
453 * previously allocated block. As with the constructor, if size <= kSize
454 * then the return block may be allocated locally, rather than from the
455 * heap.
456 */
457 void* realloc(size_t size) {
458 if (fPtr != (void*)fStorage) {
459 sk_free(fPtr);
460 }
461
462 if (size <= kSize) {
463 fPtr = fStorage;
464 } else {
465 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP);
466 }
467 return fPtr;
468 }
469
reed@android.com8a1c16f2008-12-17 15:59:43 +0000470private:
471 void* fPtr;
472 uint32_t fStorage[(kSize + 3) >> 2];
473 // illegal
474 SkAutoSMalloc(const SkAutoSMalloc&);
475 SkAutoSMalloc& operator=(const SkAutoSMalloc&);
476};
477
478#endif /* C++ */
479
480#endif
481