1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkRegionPriv_DEFINED 11 #define SkRegionPriv_DEFINED 12 13 #include "SkRegion.h" 14 #include "SkThread.h" 15 16 #define assert_sentinel(value, isSentinel) \ 17 SkASSERT(((value) == SkRegion::kRunTypeSentinel) == isSentinel) 18 19 //SkDEBUGCODE(extern int32_t gRgnAllocCounter;) 20 21 struct SkRegion::RunHead { 22 int32_t fRefCnt; 23 int32_t fRunCount; 24 AllocRunHead25 static RunHead* Alloc(int count) 26 { 27 //SkDEBUGCODE(sk_atomic_inc(&gRgnAllocCounter);) 28 //SkDEBUGF(("************** gRgnAllocCounter::alloc %d\n", gRgnAllocCounter)); 29 30 SkASSERT(count >= SkRegion::kRectRegionRuns); 31 32 RunHead* head = (RunHead*)sk_malloc_throw(sizeof(RunHead) + count * sizeof(RunType)); 33 head->fRefCnt = 1; 34 head->fRunCount = count; 35 return head; 36 } 37 isComplexRunHead38 bool isComplex() const 39 { 40 return this != SkRegion_gEmptyRunHeadPtr && this != SkRegion_gRectRunHeadPtr; 41 } 42 writable_runsRunHead43 SkRegion::RunType* writable_runs() 44 { 45 SkASSERT(this->isComplex()); 46 SkASSERT(fRefCnt == 1); 47 return (SkRegion::RunType*)(this + 1); 48 } readonly_runsRunHead49 const SkRegion::RunType* readonly_runs() const 50 { 51 SkASSERT(this->isComplex()); 52 return (const SkRegion::RunType*)(this + 1); 53 } 54 ensureWritableRunHead55 RunHead* ensureWritable() 56 { 57 SkASSERT(this->isComplex()); 58 59 RunHead* writable = this; 60 if (fRefCnt > 1) 61 { 62 // We need to alloc & copy the current region before we call 63 // sk_atomic_dec because it could be freed in the meantime, 64 // otherwise. 65 writable = Alloc(fRunCount); 66 memcpy(writable->writable_runs(), this->readonly_runs(), 67 fRunCount * sizeof(RunType)); 68 69 // fRefCount might have changed since we last checked. 70 // If we own the last reference at this point, we need to 71 // free the memory. 72 if (sk_atomic_dec(&fRefCnt) == 1) 73 { 74 sk_free(this); 75 } 76 } 77 return writable; 78 } 79 }; 80 81 #endif 82