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

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, 10 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 const Key& getKey() const SK_OVERRIDE { return fKey; } 59 const Key& getKey() const SK_OVERRIDE { return fKey; }
65 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap.getSize (); } 60 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 static SkResourceCache::PurgeVisitorResult PurgeGenID(const SkResourceCache: :Rec& baseRec,
72 void* contextGenID) {
73 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec);
74 uintptr_t genID = (uintptr_t)contextGenID;
75 if (rec.fKey.fGenID == genID) {
76 return SkResourceCache::kPurgeAndContinue_PurgeVisitorResult;
77 } else {
78 return SkResourceCache::kRetainAndContinue_PurgeVisitorResult;
79 }
80 }
81
82 private:
83 BitmapKey fKey;
84 SkBitmap fBitmap;
75 }; 85 };
76 } // namespace 86 } // namespace
77 87
78 #define CHECK_LOCAL(localCache, localName, globalName, ...) \ 88 #define CHECK_LOCAL(localCache, localName, globalName, ...) \
79 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global Name(__VA_ARGS__)) 89 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global Name(__VA_ARGS__))
80 90
81 bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc aleY, SkBitmap* result, 91 bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc aleY, SkBitmap* result,
82 SkResourceCache* localCache) { 92 SkResourceCache* localCache) {
83 if (0 == invScaleX || 0 == invScaleY) { 93 if (0 == invScaleX || 0 == invScaleY) {
84 // degenerate, and the key we use for mipmaps 94 // 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() 128 || result.width() != subset.width()
119 || result.height() != subset.height()) { 129 || result.height() != subset.height()) {
120 return false; 130 return false;
121 } else { 131 } else {
122 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, s ubset, result)); 132 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, s ubset, result));
123 133
124 CHECK_LOCAL(localCache, add, Add, rec); 134 CHECK_LOCAL(localCache, add, Add, rec);
125 return true; 135 return true;
126 } 136 }
127 } 137 }
138
139 void SkBitmapCache::NotifyGenIDStale(uint32_t genID) {
140 SkResourceCache::Purge(&gBitmapKeyNamespaceLabel, BitmapRec::PurgeGenID,
141 (void*)((uintptr_t)genID));
142 }
143
128 //////////////////////////////////////////////////////////////////////////////// ////////// 144 //////////////////////////////////////////////////////////////////////////////// //////////
145 //////////////////////////////////////////////////////////////////////////////// //////////
146
147 namespace {
148 static unsigned gMipMapKeyNamespaceLabel;
149
150 struct MipMapKey : public SkResourceCache::Key {
151 public:
152 MipMapKey(uint32_t genID, const SkIRect& bounds) : fGenID(genID), fBounds(bo unds) {
153 this->init(&gMipMapKeyNamespaceLabel, sizeof(fGenID) + sizeof(fBounds));
154 }
155
156 uint32_t fGenID;
157 SkIRect fBounds;
158 };
129 159
130 struct MipMapRec : public SkResourceCache::Rec { 160 struct MipMapRec : public SkResourceCache::Rec {
131 MipMapRec(const SkBitmap& src, const SkMipMap* result) 161 MipMapRec(const SkBitmap& src, const SkMipMap* result)
132 : fKey(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)) 162 : fKey(src.getGenerationID(), get_bounds_from_bitmap(src))
133 , fMipMap(result) 163 , fMipMap(result)
134 { 164 {
135 fMipMap->attachToCacheAndRef(); 165 fMipMap->attachToCacheAndRef();
136 } 166 }
137 167
138 virtual ~MipMapRec() { 168 virtual ~MipMapRec() {
139 fMipMap->detachFromCacheAndUnref(); 169 fMipMap->detachFromCacheAndUnref();
140 } 170 }
141 171
142 const Key& getKey() const SK_OVERRIDE { return fKey; } 172 const Key& getKey() const SK_OVERRIDE { return fKey; }
143 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap->size() ; } 173 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap->size() ; }
144 174
145 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) { 175 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) {
146 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec); 176 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);
147 const SkMipMap* mm = SkRef(rec.fMipMap); 177 const SkMipMap* mm = SkRef(rec.fMipMap);
148 // the call to ref() above triggers a "lock" in the case of discardable memory, 178 // 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). 179 // which means we can now check for null (in case the lock failed).
150 if (NULL == mm->data()) { 180 if (NULL == mm->data()) {
151 mm->unref(); // balance our call to ref() 181 mm->unref(); // balance our call to ref()
152 return false; 182 return false;
153 } 183 }
154 // the call must call unref() when they are done. 184 // the call must call unref() when they are done.
155 *(const SkMipMap**)contextMip = mm; 185 *(const SkMipMap**)contextMip = mm;
156 return true; 186 return true;
157 } 187 }
158 188
189 static SkResourceCache::PurgeVisitorResult PurgeGenID(const SkResourceCache: :Rec& baseRec,
190 void* contextGenID) {
191 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);
192 uintptr_t genID = (uintptr_t)contextGenID;
193 if (rec.fKey.fGenID == genID) {
194 return SkResourceCache::kPurgeAndContinue_PurgeVisitorResult;
195 } else {
196 return SkResourceCache::kRetainAndContinue_PurgeVisitorResult;
197 }
198 }
199
159 private: 200 private:
160 BitmapKey fKey; 201 MipMapKey fKey;
161 const SkMipMap* fMipMap; 202 const SkMipMap* fMipMap;
162 }; 203 };
204 }
163 205
164 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) { 206 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) {
165 BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)); 207 BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src));
166 const SkMipMap* result; 208 const SkMipMap* result = NULL; // if we never get called, we want to see a NULL.
167 209
168 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Visitor, &result)) { 210 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Visitor, &result)) {
169 result = NULL; 211 result = NULL;
170 } 212 }
171 return result; 213 return result;
172 } 214 }
173 215
174 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache) { 216 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache) {
175 return localCache ? localCache->GetDiscardableFactory() 217 return localCache ? localCache->GetDiscardableFactory()
176 : SkResourceCache::GetDiscardableFactory(); 218 : SkResourceCache::GetDiscardableFactory();
177 } 219 }
178 220
179 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l ocalCache) { 221 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l ocalCache) {
180 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache)); 222 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache));
181 if (mipmap) { 223 if (mipmap) {
182 MipMapRec* rec = SkNEW_ARGS(MipMapRec, (src, mipmap)); 224 MipMapRec* rec = SkNEW_ARGS(MipMapRec, (src, mipmap));
183 CHECK_LOCAL(localCache, add, Add, rec); 225 CHECK_LOCAL(localCache, add, Add, rec);
184 } 226 }
185 return mipmap; 227 return mipmap;
186 } 228 }
187 229
230 void SkMipMapCache::NotifyGenIDStale(uint32_t genID) {
231 SkResourceCache::Purge(&gMipMapKeyNamespaceLabel, MipMapRec::PurgeGenID,
232 (void*)((uintptr_t)genID));
233 }
OLDNEW
« no previous file with comments | « src/core/SkBitmapCache.h ('k') | src/core/SkPixelRef.cpp » ('j') | src/core/SkResourceCache.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698