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

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

Issue 950363002: Notify resource caches when pixelref genID goes stale (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update dox 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
« no previous file with comments | « src/core/SkBitmapCache.h ('k') | src/core/SkMaskCache.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "SkRect.h" 11 #include "SkRect.h"
12 12
13 /**
14 * Use this for bitmapcache and mipmapcache entries.
15 */
16 uint64_t SkMakeResourceCacheSharedIDForBitmap(uint32_t bitmapGenID) {
17 uint64_t sharedID = SkSetFourByteTag('b', 'm', 'a', 'p');
18 return (sharedID << 32) | bitmapGenID;
19 }
20
21 void SkNotifyBitmapGenIDIsStale(uint32_t bitmapGenID) {
22 SkResourceCache::PostPurgeSharedID(SkMakeResourceCacheSharedIDForBitmap(bitm apGenID));
23 }
24
25 //////////////////////////////////////////////////////////////////////////////// ///////////////////
26
13 SkBitmap::Allocator* SkBitmapCache::GetAllocator() { 27 SkBitmap::Allocator* SkBitmapCache::GetAllocator() {
14 return SkResourceCache::GetAllocator(); 28 return SkResourceCache::GetAllocator();
15 } 29 }
16 30
17 /** 31 /**
18 This function finds the bounds of the bitmap *within its pixelRef*. 32 This function finds the bounds of the bitmap *within its pixelRef*.
19 If the bitmap lacks a pixelRef, it will return an empty rect, since 33 If the bitmap lacks a pixelRef, it will return an empty rect, since
20 that doesn't make sense. This may be a useful enough function that 34 that doesn't make sense. This may be a useful enough function that
21 it should be somewhere else (in SkBitmap?). 35 it should be somewhere else (in SkBitmap?).
22 */ 36 */
23 static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) { 37 static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
24 if (!(bm.pixelRef())) { 38 if (!(bm.pixelRef())) {
25 return SkIRect::MakeEmpty(); 39 return SkIRect::MakeEmpty();
26 } 40 }
27 SkIPoint origin = bm.pixelRefOrigin(); 41 SkIPoint origin = bm.pixelRefOrigin();
28 return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height()); 42 return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
29 } 43 }
30 44
31 namespace { 45 namespace {
32 static unsigned gBitmapKeyNamespaceLabel; 46 static unsigned gBitmapKeyNamespaceLabel;
33 47
34 struct BitmapKey : public SkResourceCache::Key { 48 struct BitmapKey : public SkResourceCache::Key {
35 public: 49 public:
36 BitmapKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& b ounds) 50 BitmapKey(uint32_t genID, SkScalar sx, SkScalar sy, const SkIRect& bounds)
37 : fGenID(genID) 51 : fGenID(genID)
38 , fScaleX(scaleX) 52 , fScaleX(sx)
39 , fScaleY(scaleY) 53 , fScaleY(sy)
40 , fBounds(bounds) 54 , fBounds(bounds)
41 { 55 {
42 this->init(&gBitmapKeyNamespaceLabel, 56 this->init(&gBitmapKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitm ap(genID),
43 sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(f Bounds)); 57 sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(f Bounds));
44 } 58 }
45 59
46 uint32_t fGenID; 60 uint32_t fGenID;
47 SkScalar fScaleX; 61 SkScalar fScaleX;
48 SkScalar fScaleY; 62 SkScalar fScaleY;
49 SkIRect fBounds; 63 SkIRect fBounds;
50 }; 64 };
51 65
52 //////////////////////////////////////////////////////////////////////////////// //////////
53
54 struct BitmapRec : public SkResourceCache::Rec { 66 struct BitmapRec : public SkResourceCache::Rec {
55 BitmapRec(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& b ounds, 67 BitmapRec(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& b ounds,
56 const SkBitmap& result) 68 const SkBitmap& result)
57 : fKey(genID, scaleX, scaleY, bounds) 69 : fKey(genID, scaleX, scaleY, bounds)
58 , fBitmap(result) 70 , fBitmap(result)
59 {} 71 {}
60 72
61 BitmapKey fKey;
62 SkBitmap fBitmap;
63
64 const Key& getKey() const SK_OVERRIDE { return fKey; } 73 const Key& getKey() const SK_OVERRIDE { return fKey; }
65 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap.getSize (); } 74 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap.getSize (); }
66 75
67 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextBitmap ) { 76 static bool Finder(const SkResourceCache::Rec& baseRec, void* contextBitmap) {
68 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec); 77 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec);
69 SkBitmap* result = (SkBitmap*)contextBitmap; 78 SkBitmap* result = (SkBitmap*)contextBitmap;
70 79
71 *result = rec.fBitmap; 80 *result = rec.fBitmap;
72 result->lockPixels(); 81 result->lockPixels();
73 return SkToBool(result->getPixels()); 82 return SkToBool(result->getPixels());
74 } 83 }
84
85 private:
86 BitmapKey fKey;
87 SkBitmap fBitmap;
75 }; 88 };
76 } // namespace 89 } // namespace
77 90
78 #define CHECK_LOCAL(localCache, localName, globalName, ...) \ 91 #define CHECK_LOCAL(localCache, localName, globalName, ...) \
79 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global Name(__VA_ARGS__)) 92 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global Name(__VA_ARGS__))
80 93
81 bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc aleY, SkBitmap* result, 94 bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc aleY, SkBitmap* result,
82 SkResourceCache* localCache) { 95 SkResourceCache* localCache) {
83 if (0 == invScaleX || 0 == invScaleY) { 96 if (0 == invScaleX || 0 == invScaleY) {
84 // degenerate, and the key we use for mipmaps 97 // degenerate, and the key we use for mipmaps
85 return false; 98 return false;
86 } 99 }
87 BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_b itmap(src)); 100 BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_b itmap(src));
88 101
89 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Visitor, result); 102 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result);
90 } 103 }
91 104
92 void SkBitmapCache::Add(const SkBitmap& src, SkScalar invScaleX, SkScalar invSca leY, 105 void SkBitmapCache::Add(const SkBitmap& src, SkScalar invScaleX, SkScalar invSca leY,
93 const SkBitmap& result, SkResourceCache* localCache) { 106 const SkBitmap& result, SkResourceCache* localCache) {
94 if (0 == invScaleX || 0 == invScaleY) { 107 if (0 == invScaleX || 0 == invScaleY) {
95 // degenerate, and the key we use for mipmaps 108 // degenerate, and the key we use for mipmaps
96 return; 109 return;
97 } 110 }
98 SkASSERT(result.isImmutable()); 111 SkASSERT(result.isImmutable());
99 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (src.getGenerationID(), invScaleX, in vScaleY, 112 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (src.getGenerationID(), invScaleX, in vScaleY,
100 get_bounds_from_bitmap(src), result) ); 113 get_bounds_from_bitmap(src), result) );
101 CHECK_LOCAL(localCache, add, Add, rec); 114 CHECK_LOCAL(localCache, add, Add, rec);
102 } 115 }
103 116
104 bool SkBitmapCache::Find(uint32_t genID, const SkIRect& subset, SkBitmap* result , 117 bool SkBitmapCache::Find(uint32_t genID, const SkIRect& subset, SkBitmap* result ,
105 SkResourceCache* localCache) { 118 SkResourceCache* localCache) {
106 BitmapKey key(genID, SK_Scalar1, SK_Scalar1, subset); 119 BitmapKey key(genID, SK_Scalar1, SK_Scalar1, subset);
107 120
108 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Visitor, result); 121 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result);
109 } 122 }
110 123
111 bool SkBitmapCache::Add(uint32_t genID, const SkIRect& subset, const SkBitmap& r esult, 124 bool SkBitmapCache::Add(uint32_t genID, const SkIRect& subset, const SkBitmap& r esult,
112 SkResourceCache* localCache) { 125 SkResourceCache* localCache) {
113 SkASSERT(result.isImmutable()); 126 SkASSERT(result.isImmutable());
114 127
115 if (subset.isEmpty() 128 if (subset.isEmpty()
116 || subset.top() < 0 129 || subset.top() < 0
117 || subset.left() < 0 130 || subset.left() < 0
118 || result.width() != subset.width() 131 || result.width() != subset.width()
119 || result.height() != subset.height()) { 132 || result.height() != subset.height()) {
120 return false; 133 return false;
121 } else { 134 } else {
122 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, s ubset, result)); 135 BitmapRec* rec = SkNEW_ARGS(BitmapRec, (genID, SK_Scalar1, SK_Scalar1, s ubset, result));
123 136
124 CHECK_LOCAL(localCache, add, Add, rec); 137 CHECK_LOCAL(localCache, add, Add, rec);
125 return true; 138 return true;
126 } 139 }
127 } 140 }
141
128 //////////////////////////////////////////////////////////////////////////////// ////////// 142 //////////////////////////////////////////////////////////////////////////////// //////////
143 //////////////////////////////////////////////////////////////////////////////// //////////
144
145 namespace {
146 static unsigned gMipMapKeyNamespaceLabel;
147
148 struct MipMapKey : public SkResourceCache::Key {
149 public:
150 MipMapKey(uint32_t genID, const SkIRect& bounds) : fGenID(genID), fBounds(bo unds) {
151 this->init(&gMipMapKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitm ap(genID),
152 sizeof(fGenID) + sizeof(fBounds));
153 }
154
155 uint32_t fGenID;
156 SkIRect fBounds;
157 };
129 158
130 struct MipMapRec : public SkResourceCache::Rec { 159 struct MipMapRec : public SkResourceCache::Rec {
131 MipMapRec(const SkBitmap& src, const SkMipMap* result) 160 MipMapRec(const SkBitmap& src, const SkMipMap* result)
132 : fKey(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)) 161 : fKey(src.getGenerationID(), get_bounds_from_bitmap(src))
133 , fMipMap(result) 162 , fMipMap(result)
134 { 163 {
135 fMipMap->attachToCacheAndRef(); 164 fMipMap->attachToCacheAndRef();
136 } 165 }
137 166
138 virtual ~MipMapRec() { 167 virtual ~MipMapRec() {
139 fMipMap->detachFromCacheAndUnref(); 168 fMipMap->detachFromCacheAndUnref();
140 } 169 }
141 170
142 const Key& getKey() const SK_OVERRIDE { return fKey; } 171 const Key& getKey() const SK_OVERRIDE { return fKey; }
143 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap->size() ; } 172 size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap->size() ; }
144 173
145 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) { 174 static bool Finder(const SkResourceCache::Rec& baseRec, void* contextMip) {
146 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec); 175 const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);
147 const SkMipMap* mm = SkRef(rec.fMipMap); 176 const SkMipMap* mm = SkRef(rec.fMipMap);
148 // the call to ref() above triggers a "lock" in the case of discardable memory, 177 // 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). 178 // which means we can now check for null (in case the lock failed).
150 if (NULL == mm->data()) { 179 if (NULL == mm->data()) {
151 mm->unref(); // balance our call to ref() 180 mm->unref(); // balance our call to ref()
152 return false; 181 return false;
153 } 182 }
154 // the call must call unref() when they are done. 183 // the call must call unref() when they are done.
155 *(const SkMipMap**)contextMip = mm; 184 *(const SkMipMap**)contextMip = mm;
156 return true; 185 return true;
157 } 186 }
158 187
159 private: 188 private:
160 BitmapKey fKey; 189 MipMapKey fKey;
161 const SkMipMap* fMipMap; 190 const SkMipMap* fMipMap;
162 }; 191 };
192 }
163 193
164 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) { 194 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) {
165 BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)); 195 MipMapKey key(src.getGenerationID(), get_bounds_from_bitmap(src));
166 const SkMipMap* result; 196 const SkMipMap* result;
167 197
168 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Visitor, &result)) { 198 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Finder, &result)) {
169 result = NULL; 199 result = NULL;
170 } 200 }
171 return result; 201 return result;
172 } 202 }
173 203
174 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache) { 204 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache) {
175 return localCache ? localCache->GetDiscardableFactory() 205 return localCache ? localCache->GetDiscardableFactory()
176 : SkResourceCache::GetDiscardableFactory(); 206 : SkResourceCache::GetDiscardableFactory();
177 } 207 }
178 208
179 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l ocalCache) { 209 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l ocalCache) {
180 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache)); 210 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache));
181 if (mipmap) { 211 if (mipmap) {
182 MipMapRec* rec = SkNEW_ARGS(MipMapRec, (src, mipmap)); 212 MipMapRec* rec = SkNEW_ARGS(MipMapRec, (src, mipmap));
183 CHECK_LOCAL(localCache, add, Add, rec); 213 CHECK_LOCAL(localCache, add, Add, rec);
184 } 214 }
185 return mipmap; 215 return mipmap;
186 } 216 }
187
OLDNEW
« no previous file with comments | « src/core/SkBitmapCache.h ('k') | src/core/SkMaskCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698