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

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

Issue 825263005: notify resource caches when pixelref genID goes stale (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapCache.h" 8 #include "SkBitmapCache.h"
9 #include "SkResourceCache.h" 9 #include "SkResourceCache.h"
10 #include "SkMipMap.h" 10 #include "SkMipMap.h"
(...skipping 15 matching lines...) Expand all
26 } 26 }
27 SkIPoint origin = bm.pixelRefOrigin(); 27 SkIPoint origin = bm.pixelRefOrigin();
28 return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height()); 28 return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
29 } 29 }
30 30
31 namespace { 31 namespace {
32 static unsigned gBitmapKeyNamespaceLabel; 32 static unsigned gBitmapKeyNamespaceLabel;
33 33
34 struct BitmapKey : public SkResourceCache::Key { 34 struct BitmapKey : public SkResourceCache::Key {
35 public: 35 public:
36 BitmapKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& b ounds) 36 BitmapKey(uint32_t genID, SkScalar sx, SkScalar sy, const SkIRect& bounds)
37 : fGenID(genID) 37 : fGenID(genID)
38 , fScaleX(scaleX) 38 , fScaleX(sx)
39 , fScaleY(scaleY) 39 , fScaleY(sy)
40 , fBounds(bounds) 40 , fBounds(bounds)
41 { 41 {
42 this->init(&gBitmapKeyNamespaceLabel, 42 this->init(&gBitmapKeyNamespaceLabel,
43 sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(f Bounds)); 43 sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(f Bounds));
44 } 44 }
45 45
46 uint32_t fGenID; 46 uint32_t fGenID;
47 SkScalar fScaleX; 47 SkScalar fScaleX;
48 SkScalar fScaleY; 48 SkScalar fScaleY;
49 SkIRect fBounds; 49 SkIRect fBounds;
50 }; 50 };
51 51
52 //////////////////////////////////////////////////////////////////////////////// //////////
53
54 struct BitmapRec : public SkResourceCache::Rec { 52 struct BitmapRec : public SkResourceCache::Rec {
55 BitmapRec(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& b ounds, 53 BitmapRec(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& b ounds,
56 const SkBitmap& result) 54 const SkBitmap& result)
57 : fKey(genID, scaleX, scaleY, bounds) 55 : fKey(genID, scaleX, scaleY, bounds)
58 , fBitmap(result) 56 , fBitmap(result)
59 {} 57 {}
60 58
61 BitmapKey fKey;
62 SkBitmap fBitmap;
63
64 virtual const Key& getKey() const SK_OVERRIDE { return fKey; } 59 virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
65 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap .getSize(); } 60 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap .getSize(); }
66 61
67 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextBitmap ) { 62 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextBitmap ) {
68 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec); 63 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec);
69 SkBitmap* result = (SkBitmap*)contextBitmap; 64 SkBitmap* result = (SkBitmap*)contextBitmap;
70 65
71 *result = rec.fBitmap; 66 *result = rec.fBitmap;
72 result->lockPixels(); 67 result->lockPixels();
73 return SkToBool(result->getPixels()); 68 return SkToBool(result->getPixels());
74 } 69 }
70
71 // Given a genID, return true if this rec does NOT match that genID
72 // Caller will purge the rec if we return false (when our genID matches)
73 static bool NotGenID(const SkResourceCache::Rec& baseRec, void* contextGenID ) {
74 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec);
75 uintptr_t genID = (uintptr_t)contextGenID;
76 return rec.fKey.fGenID != genID;
77 }
78
79 private:
80 BitmapKey fKey;
81 SkBitmap fBitmap;
75 }; 82 };
76 } // namespace 83 } // namespace
77 84
78 #define CHECK_LOCAL(localCache, localName, globalName, ...) \ 85 #define CHECK_LOCAL(localCache, localName, globalName, ...) \
79 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global Name(__VA_ARGS__)) 86 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global Name(__VA_ARGS__))
80 87
81 bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc aleY, SkBitmap* result, 88 bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc aleY, SkBitmap* result,
82 SkResourceCache* localCache) { 89 SkResourceCache* localCache) {
83 if (0 == invScaleX || 0 == invScaleY) { 90 if (0 == invScaleX || 0 == invScaleY) {
84 // degenerate, and the key we use for mipmaps 91 // degenerate, and the key we use for mipmaps
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 || result.width() != subset.width() 125 || result.width() != subset.width()
119 || result.height() != subset.height()) { 126 || result.height() != subset.height()) {
120 return false; 127 return false;
121 } else { 128 } else {
122 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, s ubset, result)); 129 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, s ubset, result));
123 130
124 CHECK_LOCAL(localCache, add, Add, rec); 131 CHECK_LOCAL(localCache, add, Add, rec);
125 return true; 132 return true;
126 } 133 }
127 } 134 }
135
136 void SkBitmapCache::NotifyGenIDStale(uint32_t genID) {
137 SkResourceCache::PurgeVisitor(&gBitmapKeyNamespaceLabel, BitmapRec::NotGenID ,
138 (void*)((uintptr_t)genID));
139 }
140
128 //////////////////////////////////////////////////////////////////////////////// ////////// 141 //////////////////////////////////////////////////////////////////////////////// //////////
142 //////////////////////////////////////////////////////////////////////////////// //////////
143
144 namespace {
145 static unsigned gMipMapKeyNamespaceLabel;
146
147 struct MipMapKey : public SkResourceCache::Key {
148 public:
149 MipMapKey(uint32_t genID, const SkIRect& bounds) : fGenID(genID), fBounds(bo unds) {
150 this->init(&gMipMapKeyNamespaceLabel, sizeof(fGenID) + sizeof(fBounds));
151 }
152
153 uint32_t fGenID;
154 SkIRect fBounds;
155 };
129 156
130 struct MipMapRec : public SkResourceCache::Rec { 157 struct MipMapRec : public SkResourceCache::Rec {
131 MipMapRec(const SkBitmap& src, const SkMipMap* result) 158 MipMapRec(const SkBitmap& src, const SkMipMap* result)
132 : fKey(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)) 159 : fKey(src.getGenerationID(), get_bounds_from_bitmap(src))
133 , fMipMap(result) 160 , fMipMap(result)
134 { 161 {
135 fMipMap->attachToCacheAndRef(); 162 fMipMap->attachToCacheAndRef();
136 } 163 }
137 164
138 virtual ~MipMapRec() { 165 virtual ~MipMapRec() {
139 fMipMap->detachFromCacheAndUnref(); 166 fMipMap->detachFromCacheAndUnref();
140 } 167 }
141 168
142 virtual const Key& getKey() const SK_OVERRIDE { return fKey; } 169 virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
143 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap ->size(); } 170 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap ->size(); }
144 171
145 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) { 172 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) {
146 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec); 173 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);
147 const SkMipMap* mm = SkRef(rec.fMipMap); 174 const SkMipMap* mm = SkRef(rec.fMipMap);
148 // the call to ref() above triggers a "lock" in the case of discardable memory, 175 // the call to ref() above triggers a "lock" in the case of discardable memory,
149 // which means we can now check for null (in case the lock failed). 176 // which means we can now check for null (in case the lock failed).
150 if (NULL == mm->data()) { 177 if (NULL == mm->data()) {
151 mm->unref(); // balance our call to ref() 178 mm->unref(); // balance our call to ref()
152 return false; 179 return false;
153 } 180 }
154 // the call must call unref() when they are done. 181 // the call must call unref() when they are done.
155 *(const SkMipMap**)contextMip = mm; 182 *(const SkMipMap**)contextMip = mm;
156 return true; 183 return true;
157 } 184 }
158 185
186 // Given a genID, return true if this rec does NOT match that genID
187 // Caller will purge the rec if we return false (when our genID matches)
188 static bool NotGenID(const SkResourceCache::Rec& baseRec, void* contextGenID ) {
189 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);
190 uintptr_t genID = (uintptr_t)contextGenID;
191 return rec.fKey.fGenID != genID;
192 }
193
159 private: 194 private:
160 BitmapKey fKey; 195 MipMapKey fKey;
161 const SkMipMap* fMipMap; 196 const SkMipMap* fMipMap;
162 }; 197 };
198 }
163 199
164 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) { 200 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) {
165 BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)); 201 BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src));
166 const SkMipMap* result; 202 const SkMipMap* result;
167 203
168 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Visitor, &result)) { 204 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Visitor, &result)) {
169 result = NULL; 205 result = NULL;
170 } 206 }
171 return result; 207 return result;
172 } 208 }
173 209
174 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache) { 210 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache) {
175 return localCache ? localCache->GetDiscardableFactory() 211 return localCache ? localCache->GetDiscardableFactory()
176 : SkResourceCache::GetDiscardableFactory(); 212 : SkResourceCache::GetDiscardableFactory();
177 } 213 }
178 214
179 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l ocalCache) { 215 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l ocalCache) {
180 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache)); 216 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache));
181 if (mipmap) { 217 if (mipmap) {
182 MipMapRec* rec = SkNEW_ARGS(MipMapRec, (src, mipmap)); 218 MipMapRec* rec = SkNEW_ARGS(MipMapRec, (src, mipmap));
183 CHECK_LOCAL(localCache, add, Add, rec); 219 CHECK_LOCAL(localCache, add, Add, rec);
184 } 220 }
185 return mipmap; 221 return mipmap;
186 } 222 }
187 223
224 void SkMipMapCache::NotifyGenIDStale(uint32_t genID) {
225 SkResourceCache::PurgeVisitor(&gMipMapKeyNamespaceLabel, MipMapRec::NotGenID ,
226 (void*)((uintptr_t)genID));
227 }
OLDNEW
« no previous file with comments | « src/core/SkBitmapCache.h ('k') | src/core/SkPixelRef.cpp » ('j') | src/core/SkPixelRef.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698