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 */ 40 extern 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 */ 45 extern void sk_throw(void); 46 47 enum { 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 */ 56 extern 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 */ 59 extern 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 */ 63 extern void* sk_realloc_throw(void* buffer, size_t size); 64 /** Free memory returned by sk_malloc(). It is safe to pass null. 65 */ 66 extern void sk_free(void*); 67 68 // bzero is safer than memset, but we can't rely on it, so... sk_bzero() 69 static inline void sk_bzero(void* buffer, size_t size) { 70 memset(buffer, 0, size); 71 } 72 73 /////////////////////////////////////////////////////////////////////// 74 75 #define SK_INIT_TO_AVOID_WARNING = 0 76 77 #ifndef SkDebugf 78 void SkDebugf(const char format[], ...); 79 #endif 80 81 #ifdef SK_DEBUG 82 #define SkASSERT(cond) SK_DEBUGBREAK(cond) 83 #define SkDEBUGCODE(code) code 84 #define SkDECLAREPARAM(type, var) , type var 85 #define SkPARAM(var) , var 86 // #define SkDEBUGF(args ) SkDebugf##args 87 #define SkDEBUGF(args ) SkDebugf args 88 #define SkAssertResult(cond) SkASSERT(cond) 89 #else 90 #define SkASSERT(cond) 91 #define SkDEBUGCODE(code) 92 #define SkDEBUGF(args) 93 #define SkDECLAREPARAM(type, var) 94 #define SkPARAM(var) 95 96 // unlike SkASSERT, this guy executes its condition in the non-debug build 97 #define SkAssertResult(cond) cond 98 #endif 99 100 /////////////////////////////////////////////////////////////////////// 101 102 /** Fast type for signed 8 bits. Use for parameter passing and local variables, not for storage 103 */ 104 typedef int S8CPU; 105 /** Fast type for unsigned 8 bits. Use for parameter passing and local variables, not for storage 106 */ 107 typedef int S16CPU; 108 /** Fast type for signed 16 bits. Use for parameter passing and local variables, not for storage 109 */ 110 typedef unsigned U8CPU; 111 /** Fast type for unsigned 16 bits. Use for parameter passing and local variables, not for storage 112 */ 113 typedef unsigned U16CPU; 114 115 /** Meant to be faster than bool (doesn't promise to be 0 or 1, just 0 or non-zero 116 */ 117 typedef int SkBool; 118 /** Meant to be a small version of bool, for storage purposes. Will be 0 or 1 119 */ 120 typedef uint8_t SkBool8; 121 122 #ifdef SK_DEBUG 123 int8_t SkToS8(long); 124 uint8_t SkToU8(size_t); 125 int16_t SkToS16(long); 126 uint16_t SkToU16(size_t); 127 int32_t SkToS32(long); 128 uint32_t SkToU32(size_t); 129 #else 130 #define SkToS8(x) ((int8_t)(x)) 131 #define SkToU8(x) ((uint8_t)(x)) 132 #define SkToS16(x) ((int16_t)(x)) 133 #define SkToU16(x) ((uint16_t)(x)) 134 #define SkToS32(x) ((int32_t)(x)) 135 #define SkToU32(x) ((uint32_t)(x)) 136 #endif 137 138 /** Returns 0 or 1 based on the condition 139 */ 140 #define SkToBool(cond) ((cond) != 0) 141 142 #define SK_MaxS16 32767 143 #define SK_MinS16 -32767 144 #define SK_MaxU16 0xFFFF 145 #define SK_MinU16 0 146 #define SK_MaxS32 0x7FFFFFFF 147 #define SK_MinS32 0x80000001 148 #define SK_MaxU32 0xFFFFFFFF 149 #define SK_MinU32 0 150 #define SK_NaN32 0x80000000 151 152 /** Returns true if the value can be represented with signed 16bits 153 */ 154 static inline bool SkIsS16(long x) { 155 return (int16_t)x == x; 156 } 157 158 /** Returns true if the value can be represented with unsigned 16bits 159 */ 160 static inline bool SkIsU16(long x) { 161 return (uint16_t)x == x; 162 } 163 164 ////////////////////////////////////////////////////////////////////////////// 165 #ifndef SK_OFFSETOF 166 #define SK_OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1) 167 #endif 168 169 /** Returns the number of entries in an array (not a pointer) 170 */ 171 #define SK_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) 172 173 /** Returns x rounded up to a multiple of 2 174 */ 175 #define SkAlign2(x) (((x) + 1) >> 1 << 1) 176 /** Returns x rounded up to a multiple of 4 177 */ 178 #define SkAlign4(x) (((x) + 3) >> 2 << 2) 179 180 typedef uint32_t SkFourByteTag; 181 #define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 182 183 /** 32 bit integer to hold a unicode value 184 */ 185 typedef int32_t SkUnichar; 186 /** 32 bit value to hold a millisecond count 187 */ 188 typedef uint32_t SkMSec; 189 /** 1 second measured in milliseconds 190 */ 191 #define SK_MSec1 1000 192 /** maximum representable milliseconds 193 */ 194 #define SK_MSecMax 0x7FFFFFFF 195 /** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0 196 */ 197 #define SkMSec_LT(a, b) ((int32_t)(a) - (int32_t)(b) < 0) 198 /** Returns a <= b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0 199 */ 200 #define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0) 201 202 /**************************************************************************** 203 The rest of these only build with C++ 204 */ 205 #ifdef __cplusplus 206 207 /** Faster than SkToBool for integral conditions. Returns 0 or 1 208 */ 209 static inline int Sk32ToBool(uint32_t n) { 210 return (n | (0-n)) >> 31; 211 } 212 213 template <typename T> inline void SkTSwap(T& a, T& b) { 214 T c(a); 215 a = b; 216 b = c; 217 } 218 219 static inline int32_t SkAbs32(int32_t value) { 220 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR 221 if (value < 0) 222 value = -value; 223 return value; 224 #else 225 int32_t mask = value >> 31; 226 return (value ^ mask) - mask; 227 #endif 228 } 229 230 static inline int32_t SkMax32(int32_t a, int32_t b) { 231 if (a < b) 232 a = b; 233 return a; 234 } 235 236 static inline int32_t SkMin32(int32_t a, int32_t b) { 237 if (a > b) 238 a = b; 239 return a; 240 } 241 242 static inline int32_t SkSign32(int32_t a) { 243 return (a >> 31) | ((unsigned) -a >> 31); 244 } 245 246 static inline int32_t SkFastMin32(int32_t value, int32_t max) { 247 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR 248 if (value > max) 249 value = max; 250 return value; 251 #else 252 int diff = max - value; 253 // clear diff if it is negative (clear if value > max) 254 diff &= (diff >> 31); 255 return value + diff; 256 #endif 257 } 258 259 /** Returns signed 32 bit value pinned between min and max, inclusively 260 */ 261 static inline int32_t SkPin32(int32_t value, int32_t min, int32_t max) { 262 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR 263 if (value < min) 264 value = min; 265 if (value > max) 266 value = max; 267 #else 268 if (value < min) 269 value = min; 270 else if (value > max) 271 value = max; 272 #endif 273 return value; 274 } 275 276 static inline uint32_t SkSetClearShift(uint32_t bits, bool cond, 277 unsigned shift) { 278 SkASSERT((int)cond == 0 || (int)cond == 1); 279 return (bits & ~(1 << shift)) | ((int)cond << shift); 280 } 281 282 static inline uint32_t SkSetClearMask(uint32_t bits, bool cond, 283 uint32_t mask) { 284 return cond ? bits | mask : bits & ~mask; 285 } 286 287 ////////////////////////////////////////////////////////////////////////////// 288 289 /** \class SkNoncopyable 290 291 SkNoncopyable is the base class for objects that may do not want to 292 be copied. It hides its copy-constructor and its assignment-operator. 293 */ 294 class SkNoncopyable { 295 public: 296 SkNoncopyable() {} 297 298 private: 299 SkNoncopyable(const SkNoncopyable&); 300 SkNoncopyable& operator=(const SkNoncopyable&); 301 }; 302 303 class SkAutoFree : SkNoncopyable { 304 public: 305 SkAutoFree() : fPtr(NULL) {} 306 explicit SkAutoFree(void* ptr) : fPtr(ptr) {} 307 ~SkAutoFree() { sk_free(fPtr); } 308 309 /** Return the currently allocate buffer, or null 310 */ 311 void* get() const { return fPtr; } 312 313 /** Assign a new ptr allocated with sk_malloc (or null), and return the 314 previous ptr. Note it is the caller's responsibility to sk_free the 315 returned ptr. 316 */ 317 void* set(void* ptr) { 318 void* prev = fPtr; 319 fPtr = ptr; 320 return prev; 321 } 322 323 /** Transfer ownership of the current ptr to the caller, setting the 324 internal reference to null. Note the caller is reponsible for calling 325 sk_free on the returned address. 326 */ 327 void* detach() { return this->set(NULL); } 328 329 /** Free the current buffer, and set the internal reference to NULL. Same 330 as calling sk_free(detach()) 331 */ 332 void free() { 333 sk_free(fPtr); 334 fPtr = NULL; 335 } 336 337 private: 338 void* fPtr; 339 // illegal 340 SkAutoFree(const SkAutoFree&); 341 SkAutoFree& operator=(const SkAutoFree&); 342 }; 343 344 class SkAutoMalloc : public SkAutoFree { 345 public: 346 explicit SkAutoMalloc(size_t size) 347 : SkAutoFree(sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP)) {} 348 349 SkAutoMalloc(size_t size, unsigned flags) 350 : SkAutoFree(sk_malloc_flags(size, flags)) {} 351 SkAutoMalloc() {} 352 353 void* alloc(size_t size, 354 unsigned flags = (SK_MALLOC_THROW | SK_MALLOC_TEMP)) { 355 sk_free(set(sk_malloc_flags(size, flags))); 356 return get(); 357 } 358 }; 359 360 template <size_t kSize> class SkAutoSMalloc : SkNoncopyable { 361 public: 362 explicit SkAutoSMalloc(size_t size) 363 { 364 if (size <= kSize) 365 fPtr = fStorage; 366 else 367 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); 368 } 369 ~SkAutoSMalloc() 370 { 371 if (fPtr != (void*)fStorage) 372 sk_free(fPtr); 373 } 374 void* get() const { return fPtr; } 375 private: 376 void* fPtr; 377 uint32_t fStorage[(kSize + 3) >> 2]; 378 // illegal 379 SkAutoSMalloc(const SkAutoSMalloc&); 380 SkAutoSMalloc& operator=(const SkAutoSMalloc&); 381 }; 382 383 #endif /* C++ */ 384 385 #endif 386 387