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

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: Remove mutateAll entry point 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
« no previous file with comments | « src/gpu/GrLayerCache.h ('k') | src/gpu/effects/GrTextureStripAtlas.h » ('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 "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) {}
mtklein 2014/07/17 20:23:29 Dead code now?
robertphillips 2014/07/18 15:00:36 Done.
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 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
84 for (; !iter.done(); ++iter) {
85 GrCachedLayer* layer = &(*iter);
86 this->unlock(layer);
87 SkDELETE(layer);
88 }
131 89
132 // The atlas only lets go of its texture when the atlas is deleted. 90 // The atlas only lets go of its texture when the atlas is deleted.
133 fAtlas.free(); 91 fAtlas.free();
134 } 92 }
135 93
136 void GrLayerCache::initAtlas() { 94 void GrLayerCache::initAtlas() {
137 static const int kAtlasTextureWidth = 1024; 95 static const int kAtlasTextureWidth = 1024;
138 static const int kAtlasTextureHeight = 1024; 96 static const int kAtlasTextureHeight = 1024;
139 97
140 SkASSERT(NULL == fAtlas.get()); 98 SkASSERT(NULL == fAtlas.get());
141 99
142 // The layer cache only gets 1 plot 100 // The layer cache only gets 1 plot
143 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight) ; 101 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight) ;
144 fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfi g, 102 fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfi g,
145 kRenderTarget_GrTextureFlagBit, 103 kRenderTarget_GrTextureFlagBit,
146 textureSize, kNumPlotsX, kNumPlotsY, false ))); 104 textureSize, kNumPlotsX, kNumPlotsY, false )));
147 } 105 }
148 106
149 void GrLayerCache::freeAll() { 107 void GrLayerCache::freeAll() {
150 SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 108
151 for (int i = 0; i < fLayerHash.count(); ++i) { 109 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
152 this->unlock(layerArray[i]); 110 for (; !iter.done(); ++iter) {
111 GrCachedLayer* layer = &(*iter);
112 this->unlock(layer);
113 SkDELETE(layer);
153 } 114 }
154 115 fLayerHash.rewind();
155 fLayerHash.deleteAll();
156 116
157 // The atlas only lets go of its texture when the atlas is deleted. 117 // The atlas only lets go of its texture when the atlas is deleted.
158 fAtlas.free(); 118 fAtlas.free();
159 // GrLayerCache always assumes an atlas exists so recreate it. The atlas 119 // GrLayerCache always assumes an atlas exists so recreate it. The atlas
160 // lazily allocates a replacement texture so reallocating a new 120 // lazily allocates a replacement texture so reallocating a new
161 // atlas here won't disrupt a GrContext::contextDestroyed or freeGpuResource s. 121 // atlas here won't disrupt a GrContext::contextDestroyed or freeGpuResource s.
162 // TODO: Make GrLayerCache lazily allocate the atlas manager? 122 // TODO: Make GrLayerCache lazily allocate the atlas manager?
163 this->initAtlas(); 123 this->initAtlas();
164 } 124 }
165 125
166 GrCachedLayer* GrLayerCache::createLayer(const SkPicture* picture, int layerID) { 126 GrCachedLayer* GrLayerCache::createLayer(const SkPicture* picture, int layerID) {
167 SkASSERT(picture->uniqueID() != SK_InvalidGenID); 127 SkASSERT(picture->uniqueID() != SK_InvalidGenID && layerID >= 0);
168 128
169 GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (picture->uniqueID(), layer ID)); 129 GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (picture->uniqueID(), layer ID));
170 fLayerHash.insert(PictureLayerKey(picture->uniqueID(), layerID), layer); 130 fLayerHash.add(layer);
171 return layer; 131 return layer;
172 } 132 }
173 133
174 GrCachedLayer* GrLayerCache::findLayer(const SkPicture* picture, int layerID) { 134 GrCachedLayer* GrLayerCache::findLayer(const SkPicture* picture, int layerID) {
175 SkASSERT(picture->uniqueID() != SK_InvalidGenID); 135 SkASSERT(picture->uniqueID() != SK_InvalidGenID && layerID >= 0);
176 return fLayerHash.find(PictureLayerKey(picture->uniqueID(), layerID)); 136 return fLayerHash.find(GrCachedLayer::Key(picture->uniqueID(), layerID));
177 } 137 }
178 138
179 GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int lay erID) { 139 GrCachedLayer* GrLayerCache::findLayerOrCreate(const SkPicture* picture, int lay erID) {
180 SkASSERT(picture->uniqueID() != SK_InvalidGenID); 140 SkASSERT(picture->uniqueID() != SK_InvalidGenID && layerID >= 0);
181 GrCachedLayer* layer = fLayerHash.find(PictureLayerKey(picture->uniqueID(), layerID)); 141 GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(picture->uniqueID( ), layerID));
182 if (NULL == layer) { 142 if (NULL == layer) {
183 layer = this->createLayer(picture, layerID); 143 layer = this->createLayer(picture, layerID);
184 } 144 }
185 145
186 return layer; 146 return layer;
187 } 147 }
188 148
189 bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc) { 149 bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc) {
190 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 150 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
191 151
192 if (NULL != layer->texture()) { 152 if (NULL != layer->texture()) {
193 // This layer is already locked 153 // This layer is already locked
194 #ifdef SK_DEBUG 154 #ifdef SK_DEBUG
195 if (layer->isAtlased()) { 155 if (layer->isAtlased()) {
196 // It claims to be atlased 156 // It claims to be atlased
197 SkASSERT(layer->rect().width() == desc.fWidth); 157 SkASSERT(layer->rect().width() == desc.fWidth);
198 SkASSERT(layer->rect().height() == desc.fHeight); 158 SkASSERT(layer->rect().height() == desc.fHeight);
199 } 159 }
200 #endif 160 #endif
201 return true; 161 return true;
202 } 162 }
203 163
204 #if USE_ATLAS 164 #if USE_ATLAS
205 { 165 {
206 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID( ))); 166 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
207 if (NULL == pictInfo) { 167 if (NULL == pictInfo) {
208 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID())); 168 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID()));
209 fPictureHash.insert(PictureKey(layer->pictureID()), pictInfo); 169 fPictureHash.add(pictInfo);
210 } 170 }
211 171
212 SkIPoint16 loc; 172 SkIPoint16 loc;
213 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage, 173 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage,
214 desc.fWidth, desc.fHeight, 174 desc.fWidth, desc.fHeight,
215 NULL, &loc); 175 NULL, &loc);
216 // addToAtlas can allocate the backing texture 176 // addToAtlas can allocate the backing texture
217 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture())); 177 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
218 if (NULL != plot) { 178 if (NULL != plot) {
219 GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY, 179 GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
(...skipping 16 matching lines...) Expand all
236 void GrLayerCache::unlock(GrCachedLayer* layer) { 196 void GrLayerCache::unlock(GrCachedLayer* layer) {
237 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 197 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
238 198
239 if (NULL == layer || NULL == layer->texture()) { 199 if (NULL == layer || NULL == layer->texture()) {
240 return; 200 return;
241 } 201 }
242 202
243 if (layer->isAtlased()) { 203 if (layer->isAtlased()) {
244 SkASSERT(layer->texture() == fAtlas->getTexture()); 204 SkASSERT(layer->texture() == fAtlas->getTexture());
245 205
246 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID( ))); 206 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
247 SkASSERT(NULL != pictInfo); 207 SkASSERT(NULL != pictInfo);
248 pictInfo->fPlotUsage.isEmpty(); // just to silence compiler warnings for the time being 208 pictInfo->fPlotUsage.isEmpty(); // just to silence compiler warnings for the time being
249 209
250 // TODO: purging from atlas goes here 210 // TODO: purging from atlas goes here
251 } else { 211 } else {
252 fContext->unlockScratchTexture(layer->texture()); 212 fContext->unlockScratchTexture(layer->texture());
253 layer->setTexture(NULL, GrIRect16::MakeEmpty()); 213 layer->setTexture(NULL, GrIRect16::MakeEmpty());
254 } 214 }
255 } 215 }
256 216
257 #ifdef SK_DEBUG 217 #ifdef SK_DEBUG
258 void GrLayerCache::validate() const { 218 void GrLayerCache::validate() const {
259 const SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 219 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas h);
260 for (int i = 0; i < fLayerHash.count(); ++i) { 220 for (; !iter.done(); ++iter) {
261 layerArray[i]->validate(fAtlas->getTexture()); 221 (*iter).validate(fAtlas->getTexture());
262 } 222 }
263 } 223 }
264 224
265 class GrAutoValidateCache : ::SkNoncopyable { 225 class GrAutoValidateCache : ::SkNoncopyable {
266 public: 226 public:
267 explicit GrAutoValidateCache(GrLayerCache* cache) 227 explicit GrAutoValidateCache(GrLayerCache* cache)
268 : fCache(cache) { 228 : fCache(cache) {
269 fCache->validate(); 229 fCache->validate();
270 } 230 }
271 ~GrAutoValidateCache() { 231 ~GrAutoValidateCache() {
272 fCache->validate(); 232 fCache->validate();
273 } 233 }
274 private: 234 private:
275 GrLayerCache* fCache; 235 GrLayerCache* fCache;
276 }; 236 };
277 #endif 237 #endif
278 238
279 void GrLayerCache::purge(const SkPicture* picture) { 239 void GrLayerCache::purge(const SkPicture* picture) {
280 SkDEBUGCODE(GrAutoValidateCache avc(this);) 240 SkDEBUGCODE(GrAutoValidateCache avc(this);)
281 241
282 // This is somewhat of an abuse of GrTHashTable. We need to find all the 242 // 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; 243 SkTDArray<GrCachedLayer*> toBeRemoved;
288 244
289 const SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 245 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
290 for (int i = 0; i < fLayerHash.count(); ++i) { 246 for (; !iter.done(); ++iter) {
291 if (picture->uniqueID() == layerArray[i]->pictureID()) { 247 if (picture->uniqueID() == (*iter).pictureID()) {
292 *toBeRemoved.append() = layerArray[i]; 248 *toBeRemoved.append() = &(*iter);
293 } 249 }
294 } 250 }
295 251
296 for (int i = 0; i < toBeRemoved.count(); ++i) { 252 for (int i = 0; i < toBeRemoved.count(); ++i) {
297 this->unlock(toBeRemoved[i]); 253 this->unlock(toBeRemoved[i]);
298 254 fLayerHash.remove(GrCachedLayer::GetKey(*toBeRemoved[i]));
299 PictureLayerKey key(picture->uniqueID(), toBeRemoved[i]->layerID());
300 fLayerHash.remove(key, toBeRemoved[i]);
301 SkDELETE(toBeRemoved[i]); 255 SkDELETE(toBeRemoved[i]);
302 } 256 }
303 257
304 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(picture->uniqueID())) ; 258 GrPictureInfo* pictInfo = fPictureHash.find(picture->uniqueID());
305 if (NULL != pictInfo) { 259 if (NULL != pictInfo) {
306 fPictureHash.remove(PictureKey(picture->uniqueID()), pictInfo); 260 fPictureHash.remove(picture->uniqueID());
307 SkDELETE(pictInfo); 261 SkDELETE(pictInfo);
308 } 262 }
309 } 263 }
OLDNEW
« no previous file with comments | « src/gpu/GrLayerCache.h ('k') | src/gpu/effects/GrTextureStripAtlas.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698