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

Side by Side Diff: src/gpu/GrLayerCache.cpp

Issue 402693003: Replace GrTHash with SkTDynamicHash (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix initializer order Created 6 years, 5 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 "GrAtlas.h" 8 #include "GrAtlas.h"
9 #include "GrGpu.h" 9 #include "GrGpu.h"
10 #include "GrLayerCache.h" 10 #include "GrLayerCache.h"
11 11
12 /**
13 * PictureLayerKey just wraps a saveLayer's id in a picture for GrTHashTable.
14 */
15 class GrLayerCache::PictureLayerKey {
16 public:
17 PictureLayerKey(uint32_t pictureID, int layerID)
18 : fPictureID(pictureID)
19 , fLayerID(layerID) {
20 }
21
22 uint32_t pictureID() const { return fPictureID; }
23 int layerID() const { return fLayerID; }
24
25 uint32_t getHash() const { return (fPictureID << 16) | fLayerID; }
26
27 static bool LessThan(const GrCachedLayer& layer, const PictureLayerKey& key) {
28 if (layer.pictureID() == key.pictureID()) {
29 return layer.layerID() < key.layerID();
30 }
31
32 return layer.pictureID() < key.pictureID();
33 }
34
35 static bool Equals(const GrCachedLayer& layer, const PictureLayerKey& key) {
36 return layer.pictureID() == key.pictureID() && layer.layerID() == key.la yerID();
37 }
38
39 private:
40 uint32_t fPictureID;
41 int fLayerID;
42 };
43
44 /**
45 * PictureKey just wraps a picture's unique ID for GrTHashTable. It is used to
46 * look up a picture's GrPictureInfo (i.e., its GrPlot usage).
47 */
48 class GrLayerCache::PictureKey {
49 public:
50 PictureKey(uint32_t pictureID) : fPictureID(pictureID) { }
51
52 uint32_t pictureID() const { return fPictureID; }
53
54 uint32_t getHash() const { return fPictureID; }
55
56 static bool LessThan(const GrPictureInfo& pictInfo, const PictureKey& key) {
57 return pictInfo.fPictureID < key.pictureID();
58 }
59
60 static bool Equals(const GrPictureInfo& pictInfo, const PictureKey& key) {
61 return pictInfo.fPictureID == key.pictureID();
62
63 }
64
65 private:
66 uint32_t fPictureID;
67 };
68
69 #ifdef SK_DEBUG 12 #ifdef SK_DEBUG
70 void GrCachedLayer::validate(const GrTexture* backingTexture) const { 13 void GrCachedLayer::validate(const GrTexture* backingTexture) const {
71 SkASSERT(SK_InvalidGenID != fPictureID); 14 SkASSERT(SK_InvalidGenID != fKey.getPictureID());
72 SkASSERT(-1 != fLayerID); 15 SkASSERT(-1 != fKey.getLayerID());
16
73 17
74 if (NULL != fTexture) { 18 if (NULL != fTexture) {
75 // If the layer is in some texture then it must occupy some rectangle 19 // If the layer is in some texture then it must occupy some rectangle
76 SkASSERT(!fRect.isEmpty()); 20 SkASSERT(!fRect.isEmpty());
77 if (!this->isAtlased()) { 21 if (!this->isAtlased()) {
78 // If it isn't atlased then the rectangle should start at the origin 22 // If it isn't atlased then the rectangle should start at the origin
79 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop); 23 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop);
80 } 24 }
81 } else { 25 } else {
82 SkASSERT(fRect.isEmpty()); 26 SkASSERT(fRect.isEmpty());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 const GrTexture* fBackingTexture; 58 const GrTexture* fBackingTexture;
115 const GrCachedLayer* fLayer; 59 const GrCachedLayer* fLayer;
116 }; 60 };
117 #endif 61 #endif
118 62
119 GrLayerCache::GrLayerCache(GrContext* context) 63 GrLayerCache::GrLayerCache(GrContext* context)
120 : fContext(context) { 64 : fContext(context) {
121 this->initAtlas(); 65 this->initAtlas();
122 } 66 }
123 67
124 GrLayerCache::~GrLayerCache() { 68 class UnlockAndDeleteFunctor {
125 SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 69 public:
126 for (int i = 0; i < fLayerHash.count(); ++i) { 70 UnlockAndDeleteFunctor(GrLayerCache* cache) : fCache(cache) {}
127 this->unlock(layerArray[i]); 71
72 void operator()(GrCachedLayer& layer) {
73 fCache->unlock(&layer);
74 SkDELETE(&layer);
128 } 75 }
129 76
130 fLayerHash.deleteAll(); 77 private:
78 GrLayerCache* fCache;
79 };
80
81 GrLayerCache::~GrLayerCache() {
82
83 fLayerHash.mutateAll(UnlockAndDeleteFunctor(this));
mtklein 2014/07/17 19:36:20 Now that I'm remembering, maybe adding mutateAll m
robertphillips 2014/07/17 20:02:46 Yeah it's not a fantastic clarity win. I think it
131 84
132 // The atlas only lets go of its texture when the atlas is deleted. 85 // The atlas only lets go of its texture when the atlas is deleted.
133 fAtlas.free(); 86 fAtlas.free();
134 } 87 }
135 88
136 void GrLayerCache::initAtlas() { 89 void GrLayerCache::initAtlas() {
137 static const int kAtlasTextureWidth = 1024; 90 static const int kAtlasTextureWidth = 1024;
138 static const int kAtlasTextureHeight = 1024; 91 static const int kAtlasTextureHeight = 1024;
139 92
140 SkASSERT(NULL == fAtlas.get()); 93 SkASSERT(NULL == fAtlas.get());
141 94
142 // The layer cache only gets 1 plot 95 // The layer cache only gets 1 plot
143 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight) ; 96 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight) ;
144 fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfi g, 97 fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfi g,
145 kRenderTarget_GrTextureFlagBit, 98 kRenderTarget_GrTextureFlagBit,
146 textureSize, kNumPlotsX, kNumPlotsY, false ))); 99 textureSize, kNumPlotsX, kNumPlotsY, false )));
147 } 100 }
148 101
149 void GrLayerCache::freeAll() { 102 void GrLayerCache::freeAll() {
150 SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray();
151 for (int i = 0; i < fLayerHash.count(); ++i) {
152 this->unlock(layerArray[i]);
153 }
154 103
155 fLayerHash.deleteAll(); 104 fLayerHash.mutateAll(UnlockAndDeleteFunctor(this));
105 fLayerHash.rewind();
156 106
157 // The atlas only lets go of its texture when the atlas is deleted. 107 // The atlas only lets go of its texture when the atlas is deleted.
158 fAtlas.free(); 108 fAtlas.free();
159 // GrLayerCache always assumes an atlas exists so recreate it. The atlas 109 // GrLayerCache always assumes an atlas exists so recreate it. The atlas
160 // lazily allocates a replacement texture so reallocating a new 110 // lazily allocates a replacement texture so reallocating a new
161 // atlas here won't disrupt a GrContext::contextDestroyed or freeGpuResource s. 111 // atlas here won't disrupt a GrContext::contextDestroyed or freeGpuResource s.
162 // TODO: Make GrLayerCache lazily allocate the atlas manager? 112 // TODO: Make GrLayerCache lazily allocate the atlas manager?
163 this->initAtlas(); 113 this->initAtlas();
164 } 114 }
165 115
166 GrCachedLayer* GrLayerCache::createLayer(const SkPicture* picture, int layerID) { 116 GrCachedLayer* GrLayerCache::createLayer(const SkPicture* picture, int layerID) {
167 SkASSERT(picture->uniqueID() != SK_InvalidGenID); 117 SkASSERT(picture->uniqueID() != SK_InvalidGenID && layerID >= 0);
168 118
169 GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (picture->uniqueID(), layer ID)); 119 GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (picture->uniqueID(), layer ID));
170 fLayerHash.insert(PictureLayerKey(picture->uniqueID(), layerID), layer); 120 fLayerHash.add(layer);
171 return layer; 121 return layer;
172 } 122 }
173 123
174 GrCachedLayer* GrLayerCache::findLayer(const SkPicture* picture, int layerID) { 124 GrCachedLayer* GrLayerCache::findLayer(const SkPicture* picture, int layerID) {
175 SkASSERT(picture->uniqueID() != SK_InvalidGenID); 125 SkASSERT(picture->uniqueID() != SK_InvalidGenID && layerID >= 0);
176 return fLayerHash.find(PictureLayerKey(picture->uniqueID(), layerID)); 126 return fLayerHash.find(GrCachedLayer::Key(picture->uniqueID(), layerID));
177 } 127 }
178 128
179 GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int lay erID) { 129 GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int lay erID) {
180 SkASSERT(picture->uniqueID() != SK_InvalidGenID); 130 SkASSERT(picture->uniqueID() != SK_InvalidGenID && layerID >= 0);
181 GrCachedLayer* layer = fLayerHash.find(PictureLayerKey(picture->uniqueID(), layerID)); 131 GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(picture->uniqueID( ), layerID));
182 if (NULL == layer) { 132 if (NULL == layer) {
183 layer = this->createLayer(picture, layerID); 133 layer = this->createLayer(picture, layerID);
184 } 134 }
185 135
186 return layer; 136 return layer;
187 } 137 }
188 138
189 bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc) { 139 bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc) {
190 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 140 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
191 141
192 if (NULL != layer->texture()) { 142 if (NULL != layer->texture()) {
193 // This layer is already locked 143 // This layer is already locked
194 #ifdef SK_DEBUG 144 #ifdef SK_DEBUG
195 if (layer->isAtlased()) { 145 if (layer->isAtlased()) {
196 // It claims to be atlased 146 // It claims to be atlased
197 SkASSERT(layer->rect().width() == desc.fWidth); 147 SkASSERT(layer->rect().width() == desc.fWidth);
198 SkASSERT(layer->rect().height() == desc.fHeight); 148 SkASSERT(layer->rect().height() == desc.fHeight);
199 } 149 }
200 #endif 150 #endif
201 return true; 151 return true;
202 } 152 }
203 153
204 #if USE_ATLAS 154 #if USE_ATLAS
205 { 155 {
206 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID( ))); 156 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
207 if (NULL == pictInfo) { 157 if (NULL == pictInfo) {
208 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID())); 158 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID()));
209 fPictureHash.insert(PictureKey(layer->pictureID()), pictInfo); 159 fPictureHash.add(pictInfo);
210 } 160 }
211 161
212 SkIPoint16 loc; 162 SkIPoint16 loc;
213 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage, 163 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage,
214 desc.fWidth, desc.fHeight, 164 desc.fWidth, desc.fHeight,
215 NULL, &loc); 165 NULL, &loc);
216 // addToAtlas can allocate the backing texture 166 // addToAtlas can allocate the backing texture
217 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture())); 167 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
218 if (NULL != plot) { 168 if (NULL != plot) {
219 GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY, 169 GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
(...skipping 16 matching lines...) Expand all
236 void GrLayerCache::unlock(GrCachedLayer* layer) { 186 void GrLayerCache::unlock(GrCachedLayer* layer) {
237 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 187 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
238 188
239 if (NULL == layer || NULL == layer->texture()) { 189 if (NULL == layer || NULL == layer->texture()) {
240 return; 190 return;
241 } 191 }
242 192
243 if (layer->isAtlased()) { 193 if (layer->isAtlased()) {
244 SkASSERT(layer->texture() == fAtlas->getTexture()); 194 SkASSERT(layer->texture() == fAtlas->getTexture());
245 195
246 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID( ))); 196 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
247 SkASSERT(NULL != pictInfo); 197 SkASSERT(NULL != pictInfo);
248 pictInfo->fPlotUsage.isEmpty(); // just to silence compiler warnings for the time being 198 pictInfo->fPlotUsage.isEmpty(); // just to silence compiler warnings for the time being
249 199
250 // TODO: purging from atlas goes here 200 // TODO: purging from atlas goes here
251 } else { 201 } else {
252 fContext->unlockScratchTexture(layer->texture()); 202 fContext->unlockScratchTexture(layer->texture());
253 layer->setTexture(NULL, GrIRect16::MakeEmpty()); 203 layer->setTexture(NULL, GrIRect16::MakeEmpty());
254 } 204 }
255 } 205 }
256 206
257 #ifdef SK_DEBUG 207 #ifdef SK_DEBUG
258 void GrLayerCache::validate() const { 208 void GrLayerCache::validate() const {
259 const SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 209 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas h);
260 for (int i = 0; i < fLayerHash.count(); ++i) { 210 for (; !iter.done(); ++iter) {
261 layerArray[i]->validate(fAtlas->getTexture()); 211 (*iter).validate(fAtlas->getTexture());
262 } 212 }
263 } 213 }
264 214
265 class GrAutoValidateCache : ::SkNoncopyable { 215 class GrAutoValidateCache : ::SkNoncopyable {
266 public: 216 public:
267 explicit GrAutoValidateCache(GrLayerCache* cache) 217 explicit GrAutoValidateCache(GrLayerCache* cache)
268 : fCache(cache) { 218 : fCache(cache) {
269 fCache->validate(); 219 fCache->validate();
270 } 220 }
271 ~GrAutoValidateCache() { 221 ~GrAutoValidateCache() {
272 fCache->validate(); 222 fCache->validate();
273 } 223 }
274 private: 224 private:
275 GrLayerCache* fCache; 225 GrLayerCache* fCache;
276 }; 226 };
277 #endif 227 #endif
278 228
279 void GrLayerCache::purge(const SkPicture* picture) { 229 void GrLayerCache::purge(const SkPicture* picture) {
280 SkDEBUGCODE(GrAutoValidateCache avc(this);) 230 SkDEBUGCODE(GrAutoValidateCache avc(this);)
281 231
282 // This is somewhat of an abuse of GrTHashTable. We need to find all the 232 // We need to find all the layers associated with 'picture' and remove them.
283 // layers associated with 'picture' but the usual hash calls only look for
284 // exact key matches. This code peeks into the hash table's innards to
285 // find all the 'picture'-related layers.
286 // TODO: use a different data structure for the layer hash?
287 SkTDArray<GrCachedLayer*> toBeRemoved; 233 SkTDArray<GrCachedLayer*> toBeRemoved;
288 234
289 const SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 235 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
290 for (int i = 0; i < fLayerHash.count(); ++i) { 236 for (; !iter.done(); ++iter) {
291 if (picture->uniqueID() == layerArray[i]->pictureID()) { 237 if (picture->uniqueID() == (*iter).pictureID()) {
292 *toBeRemoved.append() = layerArray[i]; 238 *toBeRemoved.append() = &(*iter);
293 } 239 }
294 } 240 }
295 241
296 for (int i = 0; i < toBeRemoved.count(); ++i) { 242 for (int i = 0; i < toBeRemoved.count(); ++i) {
297 this->unlock(toBeRemoved[i]); 243 this->unlock(toBeRemoved[i]);
298 244 fLayerHash.remove(GrCachedLayer::GetKey(*toBeRemoved[i]));
299 PictureLayerKey key(picture->uniqueID(), toBeRemoved[i]->layerID());
300 fLayerHash.remove(key, toBeRemoved[i]);
301 SkDELETE(toBeRemoved[i]); 245 SkDELETE(toBeRemoved[i]);
302 } 246 }
303 247
304 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(picture->uniqueID())) ; 248 GrPictureInfo* pictInfo = fPictureHash.find(picture->uniqueID());
305 if (NULL != pictInfo) { 249 if (NULL != pictInfo) {
306 fPictureHash.remove(PictureKey(picture->uniqueID()), pictInfo); 250 fPictureHash.remove(picture->uniqueID());
307 SkDELETE(pictInfo); 251 SkDELETE(pictInfo);
308 } 252 }
309 } 253 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698