OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2014 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkCachedData_priv.h" | |
9 #include "SkRefCnt.h" | |
10 #include "SkDiscardableMemory.h" | |
11 | |
12 SkCachedData::SkCachedData(void* data, size_t size) | |
13 : fData(data) | |
14 , fSize(size) | |
15 , fRefCnt(2) // 1 owner, not in cache | |
16 { | |
17 fStorage.fMalloc = data; | |
18 fStorageType = kMalloc_StorageType; | |
19 } | |
20 | |
21 SkCachedData::SkCachedData(size_t size, SkDiscardableMemory* dm) | |
22 : fData(dm->data()) | |
23 , fSize(size) | |
24 , fRefCnt(2) // 1 owner, not in cache | |
25 { | |
26 fStorage.fDM = dm; | |
27 fStorageType = kDiscardableMemory_StorageType; | |
28 } | |
29 | |
30 SkCachedData::~SkCachedData() { | |
31 switch (fStorageType) { | |
32 case kMalloc_StorageType: | |
33 sk_free(fStorage.fMalloc); | |
34 break; | |
35 case kDiscardableMemory_StorageType: | |
36 SkDELETE(fStorage.fDM); | |
37 break; | |
38 } | |
39 } | |
40 | |
41 void SkCachedData::internalRef(int refAmount) { | |
42 #ifdef SK_DEBUG | |
43 SkASSERT(2 == refAmount || 3 == refAmount); | |
44 if (3 == refAmount) { | |
45 // assert that we are not already attached (i.e. the low-bit is 0) | |
46 SkASSERT(0 == (fRefCnt & 1)); | |
47 } | |
48 #endif | |
49 | |
50 const int32_t new_count = sk_atomic_add(&fRefCnt, refAmount) + refAmount; | |
51 const int owners = new_count >> 1; | |
52 const int in_cache = new_count & 1; | |
53 | |
54 SkASSERT(owners >= 2); | |
55 | |
56 if (2 == owners) { | |
qiankun
2014/09/25 07:15:11
In some cases, owners may exceed 2 before SkCached
| |
57 sk_membar_acquire__after_atomic_dec(); | |
58 if (in_cache) { | |
59 this->lock(); | |
60 } | |
61 } | |
62 } | |
63 | |
64 void SkCachedData::internalUnref(int refAmount) { | |
65 #ifdef SK_DEBUG | |
66 SkASSERT(2 == refAmount || 3 == refAmount); | |
67 if (3 == refAmount) { | |
68 // assert that we are already attached (i.e. the low-bit is 1) | |
69 SkASSERT(1 == (fRefCnt & 1)); | |
70 } | |
71 #endif | |
72 | |
73 const int32_t new_count = sk_atomic_add(&fRefCnt, -refAmount) - refAmount; | |
74 const int owners = new_count >> 1; | |
75 const int in_cache = new_count & 1; | |
76 | |
77 switch (owners) { | |
78 case 0: | |
79 sk_membar_acquire__after_atomic_dec(); | |
80 SkDELETE(this); | |
81 break; | |
82 case 1: | |
83 sk_membar_acquire__after_atomic_dec(); | |
84 if (in_cache) { | |
85 this->unlock(); | |
86 } | |
87 break; | |
88 default: | |
89 break; | |
90 } | |
91 } | |
92 | |
93 void SkCachedData::lock() { | |
94 switch (fStorageType) { | |
95 case kMalloc_StorageType: | |
96 fData = fStorage.fMalloc; | |
97 break; | |
98 case kDiscardableMemory_StorageType: | |
99 if (fStorage.fDM->lock()) { | |
100 fData = fStorage.fDM->data(); | |
101 } else { | |
102 fData = NULL; // signal failure to lock, contents are gone | |
103 } | |
104 break; | |
105 } | |
106 } | |
107 | |
108 void SkCachedData::unlock() { | |
109 switch (fStorageType) { | |
110 case kMalloc_StorageType: | |
111 // nothing to do/check | |
112 break; | |
113 case kDiscardableMemory_StorageType: | |
114 if (fData) { // did the previous lock succeed? | |
115 fStorage.fDM->unlock(); | |
116 } | |
117 break; | |
118 } | |
119 fData = NULL; // signal that we're in an unlocked state | |
120 } | |
121 | |
OLD | NEW |