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

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

Powered by Google App Engine
This is Rietveld 408576698