SkTypes.h revision 8a1c16ff38322f0210116fa7293eb8817c7e477e
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef SkTypes_DEFINED 18#define SkTypes_DEFINED 19 20#include "SkPreConfig.h" 21#include "SkUserConfig.h" 22#include "SkPostConfig.h" 23 24#ifndef SK_IGNORE_STDINT_DOT_H 25 #include <stdint.h> 26#endif 27 28#include <stdio.h> 29 30/** \file SkTypes.h 31*/ 32 33/* 34 memory wrappers to be implemented by the porting layer (platform) 35*/ 36 37/** Called internally if we run out of memory. The platform implementation must 38 not return, but should either throw an exception or otherwise exit. 39*/ 40extern void sk_out_of_memory(void); 41/** Called internally if we hit an unrecoverable error. 42 The platform implementation must not return, but should either throw 43 an exception or otherwise exit. 44*/ 45extern void sk_throw(void); 46 47enum { 48 SK_MALLOC_TEMP = 0x01, //!< hint to sk_malloc that the requested memory will be freed in the scope of the stack frame 49 SK_MALLOC_THROW = 0x02 //!< instructs sk_malloc to call sk_throw if the memory cannot be allocated. 50}; 51/** Return a block of memory (at least 4-byte aligned) of at least the 52 specified size. If the requested memory cannot be returned, either 53 return null (if SK_MALLOC_TEMP bit is clear) or call sk_throw() 54 (if SK_MALLOC_TEMP bit is set). To free the memory, call sk_free(). 55*/ 56extern void* sk_malloc_flags(size_t size, unsigned flags); 57/** Same as sk_malloc(), but hard coded to pass SK_MALLOC_THROW as the flag 58*/ 59extern void* sk_malloc_throw(size_t size); 60/** Same as standard realloc(), but this one never returns null on failure. It will throw 61 an exception if it fails. 62*/ 63extern void* sk_realloc_throw(void* buffer, size_t size); 64/** Free memory returned by sk_malloc(). It is safe to pass null. 65*/ 66extern void sk_free(void*); 67 68/////////////////////////////////////////////////////////////////////// 69 70#define SK_INIT_TO_AVOID_WARNING = 0 71 72#ifndef SkDebugf 73 void SkDebugf(const char format[], ...); 74#endif 75 76#ifdef SK_DEBUG 77 #define SkASSERT(cond) SK_DEBUGBREAK(cond) 78 #define SkDEBUGCODE(code) code 79 #define SkDECLAREPARAM(type, var) , type var 80 #define SkPARAM(var) , var 81// #define SkDEBUGF(args ) SkDebugf##args 82 #define SkDEBUGF(args ) SkDebugf args 83 #define SkAssertResult(cond) SkASSERT(cond) 84#else 85 #define SkASSERT(cond) 86 #define SkDEBUGCODE(code) 87 #define SkDEBUGF(args) 88 #define SkDECLAREPARAM(type, var) 89 #define SkPARAM(var) 90 91 // unlike SkASSERT, this guy executes its condition in the non-debug build 92 #define SkAssertResult(cond) cond 93#endif 94 95/////////////////////////////////////////////////////////////////////// 96 97/** Fast type for signed 8 bits. Use for parameter passing and local variables, not for storage 98*/ 99typedef int S8CPU; 100/** Fast type for unsigned 8 bits. Use for parameter passing and local variables, not for storage 101*/ 102typedef int S16CPU; 103/** Fast type for signed 16 bits. Use for parameter passing and local variables, not for storage 104*/ 105typedef unsigned U8CPU; 106/** Fast type for unsigned 16 bits. Use for parameter passing and local variables, not for storage 107*/ 108typedef unsigned U16CPU; 109 110/** Meant to be faster than bool (doesn't promise to be 0 or 1, just 0 or non-zero 111*/ 112typedef int SkBool; 113/** Meant to be a small version of bool, for storage purposes. Will be 0 or 1 114*/ 115typedef uint8_t SkBool8; 116 117#ifdef SK_DEBUG 118 int8_t SkToS8(long); 119 uint8_t SkToU8(size_t); 120 int16_t SkToS16(long); 121 uint16_t SkToU16(size_t); 122 int32_t SkToS32(long); 123 uint32_t SkToU32(size_t); 124#else 125 #define SkToS8(x) ((int8_t)(x)) 126 #define SkToU8(x) ((uint8_t)(x)) 127 #define SkToS16(x) ((int16_t)(x)) 128 #define SkToU16(x) ((uint16_t)(x)) 129 #define SkToS32(x) ((int32_t)(x)) 130 #define SkToU32(x) ((uint32_t)(x)) 131#endif 132 133/** Returns 0 or 1 based on the condition 134*/ 135#define SkToBool(cond) ((cond) != 0) 136 137#define SK_MaxS16 32767 138#define SK_MinS16 -32767 139#define SK_MaxU16 0xFFFF 140#define SK_MinU16 0 141#define SK_MaxS32 0x7FFFFFFF 142#define SK_MinS32 0x80000001 143#define SK_MaxU32 0xFFFFFFFF 144#define SK_MinU32 0 145#define SK_NaN32 0x80000000 146 147#ifndef SK_OFFSETOF 148 #define SK_OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) 149#endif 150 151/** Returns the number of entries in an array (not a pointer) 152*/ 153#define SK_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) 154 155/** Returns x rounded up to a multiple of 2 156*/ 157#define SkAlign2(x) (((x) + 1) >> 1 << 1) 158/** Returns x rounded up to a multiple of 4 159*/ 160#define SkAlign4(x) (((x) + 3) >> 2 << 2) 161 162typedef uint32_t SkFourByteTag; 163#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 164 165/** 32 bit integer to hold a unicode value 166*/ 167typedef int32_t SkUnichar; 168/** 32 bit value to hold a millisecond count 169*/ 170typedef uint32_t SkMSec; 171/** 1 second measured in milliseconds 172*/ 173#define SK_MSec1 1000 174/** maximum representable milliseconds 175*/ 176#define SK_MSecMax 0x7FFFFFFF 177/** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0 178*/ 179#define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0) 180/** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0 181*/ 182#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0) 183 184 185/**************************************************************************** 186 The rest of these only build with C++ 187*/ 188#ifdef __cplusplus 189 190/** Faster than SkToBool for integral conditions. Returns 0 or 1 191*/ 192inline int Sk32ToBool(uint32_t n) 193{ 194 return (n | (0-n)) >> 31; 195} 196 197template <typename T> inline void SkTSwap(T& a, T& b) 198{ 199 T c(a); 200 a = b; 201 b = c; 202} 203 204inline int32_t SkAbs32(int32_t value) 205{ 206#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 207 if (value < 0) 208 value = -value; 209 return value; 210#else 211 int32_t mask = value >> 31; 212 return (value ^ mask) - mask; 213#endif 214} 215 216inline int32_t SkMax32(int32_t a, int32_t b) 217{ 218 if (a < b) 219 a = b; 220 return a; 221} 222 223inline int32_t SkMin32(int32_t a, int32_t b) 224{ 225 if (a > b) 226 a = b; 227 return a; 228} 229 230inline int32_t SkSign32(int32_t a) 231{ 232 return (a >> 31) | ((unsigned) -a >> 31); 233} 234 235inline int32_t SkFastMin32(int32_t value, int32_t max) 236{ 237#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 238 if (value > max) 239 value = max; 240 return value; 241#else 242 int diff = max - value; 243 // clear diff if it is negative (clear if value > max) 244 diff &= (diff >> 31); 245 return value + diff; 246#endif 247} 248 249/** Returns signed 32 bit value pinned between min and max, inclusively 250*/ 251inline int32_t SkPin32(int32_t value, int32_t min, int32_t max) 252{ 253#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 254 if (value < min) 255 value = min; 256 if (value > max) 257 value = max; 258#else 259 if (value < min) 260 value = min; 261 else if (value > max) 262 value = max; 263#endif 264 return value; 265} 266 267inline uint32_t SkSetClearShift(uint32_t bits, bool cond, unsigned shift) 268{ 269 SkASSERT((int)cond == 0 || (int)cond == 1); 270 return (bits & ~(1 << shift)) | ((int)cond << shift); 271} 272 273inline uint32_t SkSetClearMask(uint32_t bits, bool cond, uint32_t mask) 274{ 275 return cond ? bits | mask : bits & ~mask; 276} 277 278////////////////////////////////////////////////////////////////////////////// 279 280/** \class SkNoncopyable 281 282SkNoncopyable is the base class for objects that may do not want to 283be copied. It hides its copy-constructor and its assignment-operator. 284*/ 285class SkNoncopyable { 286public: 287 SkNoncopyable() {} 288 289private: 290 SkNoncopyable(const SkNoncopyable&); 291 SkNoncopyable& operator=(const SkNoncopyable&); 292}; 293 294class SkAutoFree : SkNoncopyable { 295public: 296 SkAutoFree() : fPtr(NULL) {} 297 explicit SkAutoFree(void* ptr) : fPtr(ptr) {} 298 ~SkAutoFree() { sk_free(fPtr); } 299 300 /** Return the currently allocate buffer, or null 301 */ 302 void* get() const { return fPtr; } 303 304 /** Assign a new ptr allocated with sk_malloc (or null), and return the 305 previous ptr. Note it is the caller's responsibility to sk_free the 306 returned ptr. 307 */ 308 void* set(void* ptr) { 309 void* prev = fPtr; 310 fPtr = ptr; 311 return prev; 312 } 313 314 /** Transfer ownership of the current ptr to the caller, setting the 315 internal reference to null. Note the caller is reponsible for calling 316 sk_free on the returned address. 317 */ 318 void* detach() { return this->set(NULL); } 319 320 /** Free the current buffer, and set the internal reference to NULL. Same 321 as calling sk_free(detach()) 322 */ 323 void free() { 324 sk_free(fPtr); 325 fPtr = NULL; 326 } 327 328private: 329 void* fPtr; 330 // illegal 331 SkAutoFree(const SkAutoFree&); 332 SkAutoFree& operator=(const SkAutoFree&); 333}; 334 335class SkAutoMalloc : public SkAutoFree { 336public: 337 explicit SkAutoMalloc(size_t size) 338 : SkAutoFree(sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP)) {} 339 340 SkAutoMalloc(size_t size, unsigned flags) 341 : SkAutoFree(sk_malloc_flags(size, flags)) {} 342 SkAutoMalloc() {} 343 344 void* alloc(size_t size, 345 unsigned flags = (SK_MALLOC_THROW | SK_MALLOC_TEMP)) { 346 sk_free(set(sk_malloc_flags(size, flags))); 347 return get(); 348 } 349}; 350 351template <size_t kSize> class SkAutoSMalloc : SkNoncopyable { 352public: 353 explicit SkAutoSMalloc(size_t size) 354 { 355 if (size <= kSize) 356 fPtr = fStorage; 357 else 358 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); 359 } 360 ~SkAutoSMalloc() 361 { 362 if (fPtr != (void*)fStorage) 363 sk_free(fPtr); 364 } 365 void* get() const { return fPtr; } 366private: 367 void* fPtr; 368 uint32_t fStorage[(kSize + 3) >> 2]; 369 // illegal 370 SkAutoSMalloc(const SkAutoSMalloc&); 371 SkAutoSMalloc& operator=(const SkAutoSMalloc&); 372}; 373 374#endif /* C++ */ 375 376#endif 377 378