Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: src/core/SkCachedData.cpp

Issue 592843003: Add SkCachedData and use it for SkMipMap (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkCachedData.h ('k') | src/core/SkMipMap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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.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(1)
16 , fStorageType(kMalloc_StorageType)
17 , fInCache(false)
18 , fIsLocked(true)
19 {
20 fStorage.fMalloc = data;
21 }
22
23 SkCachedData::SkCachedData(size_t size, SkDiscardableMemory* dm)
24 : fData(dm->data())
25 , fSize(size)
26 , fRefCnt(1)
27 , fStorageType(kDiscardableMemory_StorageType)
28 , fInCache(false)
29 , fIsLocked(true)
30 {
31 fStorage.fDM = dm;
32 }
33
34 SkCachedData::~SkCachedData() {
35 switch (fStorageType) {
36 case kMalloc_StorageType:
37 sk_free(fStorage.fMalloc);
38 break;
39 case kDiscardableMemory_StorageType:
40 SkDELETE(fStorage.fDM);
41 break;
42 }
43 }
44
45 class SkCachedData::AutoMutexWritable {
46 public:
47 AutoMutexWritable(const SkCachedData* cd) : fCD(const_cast<SkCachedData*>(cd )) {
48 fCD->fMutex.acquire();
49 fCD->validate();
50 }
51 ~AutoMutexWritable() {
52 fCD->validate();
53 fCD->fMutex.release();
54 }
55
56 SkCachedData* get() { return fCD; }
57 SkCachedData* operator->() { return fCD; }
58
59 private:
60 SkCachedData* fCD;
61 };
62
63 void SkCachedData::internalRef(bool fromCache) const {
64 AutoMutexWritable(this)->inMutexRef(fromCache);
65 }
66
67 void SkCachedData::internalUnref(bool fromCache) const {
68 if (AutoMutexWritable(this)->inMutexUnref(fromCache)) {
69 // can't delete inside doInternalUnref, since it is locking a mutex (whi ch we own)
70 SkDELETE(this);
71 }
72 }
73
74 //////////////////////////////////////////////////////////////////////////////// ///////////////////
75
76 void SkCachedData::inMutexRef(bool fromCache) {
77 if ((1 == fRefCnt) && fInCache) {
78 this->inMutexLock();
79 }
80
81 fRefCnt += 1;
82 if (fromCache) {
83 SkASSERT(!fInCache);
84 fInCache = true;
85 }
86 }
87
88 bool SkCachedData::inMutexUnref(bool fromCache) {
89 switch (--fRefCnt) {
90 case 0:
91 // we're going to be deleted, so we need to be unlocked (for Discard ableMemory)
92 if (fIsLocked) {
93 this->inMutexUnlock();
94 }
95 break;
96 case 1:
97 if (fInCache && !fromCache) {
98 // If we're down to 1 owner, and that owner is the cache, this i t is safe
99 // to unlock (and mutate fData) even if the cache is in a differ ent thread,
100 // as the cache is NOT allowed to inspect or use fData.
101 this->inMutexUnlock();
102 }
103 break;
104 default:
105 break;
106 }
107
108 if (fromCache) {
109 SkASSERT(fInCache);
110 fInCache = false;
111 }
112
113 // return true when we need to be deleted
114 return 0 == fRefCnt;
115 }
116
117 void SkCachedData::inMutexLock() {
118 fMutex.assertHeld();
119
120 SkASSERT(!fIsLocked);
121 fIsLocked = true;
122
123 switch (fStorageType) {
124 case kMalloc_StorageType:
125 this->setData(fStorage.fMalloc);
126 break;
127 case kDiscardableMemory_StorageType:
128 if (fStorage.fDM->lock()) {
129 this->setData(fStorage.fDM->data());
130 } else {
131 this->setData(NULL); // signal failure to lock, contents are g one
132 }
133 break;
134 }
135 }
136
137 void SkCachedData::inMutexUnlock() {
138 fMutex.assertHeld();
139
140 SkASSERT(fIsLocked);
141 fIsLocked = false;
142
143 switch (fStorageType) {
144 case kMalloc_StorageType:
145 // nothing to do/check
146 break;
147 case kDiscardableMemory_StorageType:
148 if (fData) { // did the previous lock succeed?
149 fStorage.fDM->unlock();
150 }
151 break;
152 }
153 this->setData(NULL); // signal that we're in an unlocked state
154 }
155
156 //////////////////////////////////////////////////////////////////////////////// ///////////////////
157
158 #ifdef SK_DEBUG
159 void SkCachedData::validate() const {
160 if (fIsLocked) {
161 SkASSERT((fInCache && fRefCnt > 1) || !fInCache);
162 switch (fStorageType) {
163 case kMalloc_StorageType:
164 SkASSERT(fData == fStorage.fMalloc);
165 break;
166 case kDiscardableMemory_StorageType:
167 // fData can be null or the actual value, depending if DM's lock succeeded
168 break;
169 }
170 } else {
171 SkASSERT((fInCache && 1 == fRefCnt) || (0 == fRefCnt));
172 SkASSERT(NULL == fData);
173 }
174 }
175 #endif
OLDNEW
« no previous file with comments | « src/core/SkCachedData.h ('k') | src/core/SkMipMap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698