OLD | NEW |
| (Empty) |
1 /* libs/corecg/SkRegionPriv.h | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #ifndef SkRegionPriv_DEFINED | |
19 #define SkRegionPriv_DEFINED | |
20 | |
21 #include "SkRegion.h" | |
22 #include "SkThread.h" | |
23 | |
24 #define assert_sentinel(value, isSentinel) \ | |
25 SkASSERT(((value) == SkRegion::kRunTypeSentinel) == isSentinel) | |
26 | |
27 //SkDEBUGCODE(extern int32_t gRgnAllocCounter;) | |
28 | |
29 struct SkRegion::RunHead { | |
30 int32_t fRefCnt; | |
31 int32_t fRunCount; | |
32 | |
33 static RunHead* Alloc(int count) | |
34 { | |
35 //SkDEBUGCODE(sk_atomic_inc(&gRgnAllocCounter);) | |
36 //SkDEBUGF(("************** gRgnAllocCounter::alloc %d\n", gRgnAllocCoun
ter)); | |
37 | |
38 SkASSERT(count >= SkRegion::kRectRegionRuns); | |
39 | |
40 RunHead* head = (RunHead*)sk_malloc_throw(sizeof(RunHead) + count * size
of(RunType)); | |
41 head->fRefCnt = 1; | |
42 head->fRunCount = count; | |
43 return head; | |
44 } | |
45 | |
46 bool isComplex() const | |
47 { | |
48 return this != SkRegion_gEmptyRunHeadPtr && this != SkRegion_gRectRunHea
dPtr; | |
49 } | |
50 | |
51 SkRegion::RunType* writable_runs() | |
52 { | |
53 SkASSERT(this->isComplex()); | |
54 SkASSERT(fRefCnt == 1); | |
55 return (SkRegion::RunType*)(this + 1); | |
56 } | |
57 const SkRegion::RunType* readonly_runs() const | |
58 { | |
59 SkASSERT(this->isComplex()); | |
60 return (const SkRegion::RunType*)(this + 1); | |
61 } | |
62 | |
63 RunHead* ensureWritable() | |
64 { | |
65 SkASSERT(this->isComplex()); | |
66 | |
67 RunHead* writable = this; | |
68 if (fRefCnt > 1) | |
69 { | |
70 // We need to alloc & copy the current region before we call | |
71 // sk_atomic_dec because it could be freed in the meantime, | |
72 // otherwise. | |
73 writable = Alloc(fRunCount); | |
74 memcpy(writable->writable_runs(), this->readonly_runs(), | |
75 fRunCount * sizeof(RunType)); | |
76 | |
77 // fRefCount might have changed since we last checked. | |
78 // If we own the last reference at this point, we need to | |
79 // free the memory. | |
80 if (sk_atomic_dec(&fRefCnt) == 1) | |
81 { | |
82 sk_free(this); | |
83 } | |
84 } | |
85 return writable; | |
86 } | |
87 }; | |
88 | |
89 #endif | |
OLD | NEW |