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

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

Issue 397873004: Make GrLayerCache use multiple plots in its atlas (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Try to pacify clang 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') | no next file » | 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"
(...skipping 23 matching lines...) Expand all
34 34
35 static bool Equals(const GrCachedLayer& layer, const PictureLayerKey& key) { 35 static bool Equals(const GrCachedLayer& layer, const PictureLayerKey& key) {
36 return layer.pictureID() == key.pictureID() && layer.layerID() == key.la yerID(); 36 return layer.pictureID() == key.pictureID() && layer.layerID() == key.la yerID();
37 } 37 }
38 38
39 private: 39 private:
40 uint32_t fPictureID; 40 uint32_t fPictureID;
41 int fLayerID; 41 int fLayerID;
42 }; 42 };
43 43
44 /**
45 * PictureKey just wraps a picture's unique ID for GrTHashTable. It is used to
jvanverth1 2014/07/16 21:04:16 I don't think we're supposed to use GrTHashTable a
robertphillips 2014/07/17 11:57:45 Why don't I do that as a separate CL and just elim
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
44 #ifdef SK_DEBUG 69 #ifdef SK_DEBUG
45 void GrCachedLayer::validate(GrTexture* backingTexture) const { 70 void GrCachedLayer::validate(const GrTexture* backingTexture) const {
46 SkASSERT(SK_InvalidGenID != fPictureID); 71 SkASSERT(SK_InvalidGenID != fPictureID);
47 SkASSERT(-1 != fLayerID); 72 SkASSERT(-1 != fLayerID);
48 73
49 if (NULL != fTexture) { 74 if (NULL != fTexture) {
50 // If the layer is in some texture then it must occupy some rectangle 75 // If the layer is in some texture then it must occupy some rectangle
51 SkASSERT(!fRect.isEmpty()); 76 SkASSERT(!fRect.isEmpty());
52 if (!this->isAtlased()) { 77 if (!this->isAtlased()) {
53 // If it isn't atlased then the rectangle should start at the origin 78 // If it isn't atlased then the rectangle should start at the origin
54 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop); 79 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop);
55 } 80 }
56 } else { 81 } else {
57 SkASSERT(fRect.isEmpty()); 82 SkASSERT(fRect.isEmpty());
83 SkASSERT(NULL == fPlot);
84 }
85
86 if (NULL != fPlot) {
87 // If a layer has a plot (i.e., is atlased) then it must point to
88 // the backing texture. Additionally, its rect should be non-empty.
89 SkASSERT(NULL != fTexture && backingTexture == fTexture);
90 SkASSERT(!fRect.isEmpty());
58 } 91 }
59 } 92 }
60 93
61 class GrAutoValidateLayer : ::SkNoncopyable { 94 class GrAutoValidateLayer : ::SkNoncopyable {
62 public: 95 public:
63 GrAutoValidateLayer(GrTexture* backingTexture, const GrCachedLayer* layer) 96 GrAutoValidateLayer(GrTexture* backingTexture, const GrCachedLayer* layer)
64 : fBackingTexture(backingTexture) 97 : fBackingTexture(backingTexture)
65 , fLayer(layer) { 98 , fLayer(layer) {
66 if (NULL != fLayer) { 99 if (NULL != fLayer) {
67 fLayer->validate(backingTexture); 100 fLayer->validate(backingTexture);
68 } 101 }
69 } 102 }
70 ~GrAutoValidateLayer() { 103 ~GrAutoValidateLayer() {
71 if (NULL != fLayer) { 104 if (NULL != fLayer) {
72 fLayer->validate(fBackingTexture); 105 fLayer->validate(fBackingTexture);
73 } 106 }
74 } 107 }
108 void setBackingTexture(GrTexture* backingTexture) {
109 SkASSERT(NULL == fBackingTexture || fBackingTexture == backingTexture);
110 fBackingTexture = backingTexture;
111 }
75 112
76 private: 113 private:
77 GrTexture* fBackingTexture; 114 const GrTexture* fBackingTexture;
78 const GrCachedLayer* fLayer; 115 const GrCachedLayer* fLayer;
79 }; 116 };
80 #endif 117 #endif
81 118
82 GrLayerCache::GrLayerCache(GrContext* context) 119 GrLayerCache::GrLayerCache(GrContext* context)
83 : fContext(context) { 120 : fContext(context) {
84 this->initAtlas(); 121 this->initAtlas();
85 } 122 }
86 123
87 GrLayerCache::~GrLayerCache() { 124 GrLayerCache::~GrLayerCache() {
(...skipping 11 matching lines...) Expand all
99 void GrLayerCache::initAtlas() { 136 void GrLayerCache::initAtlas() {
100 static const int kAtlasTextureWidth = 1024; 137 static const int kAtlasTextureWidth = 1024;
101 static const int kAtlasTextureHeight = 1024; 138 static const int kAtlasTextureHeight = 1024;
102 139
103 SkASSERT(NULL == fAtlas.get()); 140 SkASSERT(NULL == fAtlas.get());
104 141
105 // The layer cache only gets 1 plot 142 // The layer cache only gets 1 plot
106 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight) ; 143 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight) ;
107 fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfi g, 144 fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfi g,
108 kRenderTarget_GrTextureFlagBit, 145 kRenderTarget_GrTextureFlagBit,
109 textureSize, 1, 1, false))); 146 textureSize, kNumPlotsX, kNumPlotsY, false )));
110 } 147 }
111 148
112 void GrLayerCache::freeAll() { 149 void GrLayerCache::freeAll() {
113 SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 150 SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray();
114 for (int i = 0; i < fLayerHash.count(); ++i) { 151 for (int i = 0; i < fLayerHash.count(); ++i) {
115 this->unlock(layerArray[i]); 152 this->unlock(layerArray[i]);
116 } 153 }
117 154
118 fLayerHash.deleteAll(); 155 fLayerHash.deleteAll();
119 156
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 if (layer->isAtlased()) { 195 if (layer->isAtlased()) {
159 // It claims to be atlased 196 // It claims to be atlased
160 SkASSERT(layer->rect().width() == desc.fWidth); 197 SkASSERT(layer->rect().width() == desc.fWidth);
161 SkASSERT(layer->rect().height() == desc.fHeight); 198 SkASSERT(layer->rect().height() == desc.fHeight);
162 } 199 }
163 #endif 200 #endif
164 return true; 201 return true;
165 } 202 }
166 203
167 #if USE_ATLAS 204 #if USE_ATLAS
168 SkIPoint16 loc; 205 {
169 GrPlot* plot = fAtlas->addToAtlas(&fPlotUsage, desc.fWidth, desc.fHeight, NU LL, &loc); 206 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID( )));
170 if (NULL != plot) { 207 if (NULL == pictInfo) {
171 GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY, 208 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID()));
172 SkToS16(desc.fWidth), SkToS16(des c.fHeight)); 209 fPictureHash.insert(PictureKey(layer->pictureID()), pictInfo);
173 layer->setTexture(fAtlas->getTexture(), bounds); 210 }
174 layer->setAtlased(true); 211
175 return false; 212 SkIPoint16 loc;
213 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage,
214 desc.fWidth, desc.fHeight,
215 NULL, &loc);
216 // addToAtlas can allocate the backing texture
217 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
218 if (NULL != plot) {
219 GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
220 SkToS16(desc.fWidth), SkToS16 (desc.fHeight));
221 layer->setTexture(fAtlas->getTexture(), bounds);
222 layer->setPlot(plot);
223 return false;
224 }
176 } 225 }
177 #endif 226 #endif
178 227
179 // The texture wouldn't fit in the cache - give it it's own texture. 228 // The texture wouldn't fit in the cache - give it it's own texture.
180 // This path always uses a new scratch texture and (thus) doesn't cache anyt hing. 229 // This path always uses a new scratch texture and (thus) doesn't cache anyt hing.
181 // This can yield a lot of re-rendering 230 // This can yield a lot of re-rendering
182 layer->setTexture(fContext->lockAndRefScratchTexture(desc, GrContext::kAppro x_ScratchTexMatch), 231 layer->setTexture(fContext->lockAndRefScratchTexture(desc, GrContext::kAppro x_ScratchTexMatch),
183 GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc.fHeig ht))); 232 GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc.fHeig ht)));
184 return false; 233 return false;
185 } 234 }
186 235
187 void GrLayerCache::unlock(GrCachedLayer* layer) { 236 void GrLayerCache::unlock(GrCachedLayer* layer) {
188 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 237 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);)
189 238
190 if (NULL == layer || NULL == layer->texture()) { 239 if (NULL == layer || NULL == layer->texture()) {
191 return; 240 return;
192 } 241 }
193 242
194 if (layer->isAtlased()) { 243 if (layer->isAtlased()) {
195 // The atlas doesn't currently use a scratch texture (and we would have 244 SkASSERT(layer->texture() == fAtlas->getTexture());
196 // to free up space differently anyways) 245
197 // TODO: unlock atlas space when a recycling rectanizer is available 246 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID( )));
247 SkASSERT(NULL != pictInfo);
248 pictInfo->fPlotUsage.isEmpty(); // just to silence compiler warnings for the time being
249
250 // TODO: purging from atlas goes here
198 } else { 251 } else {
199 fContext->unlockScratchTexture(layer->texture()); 252 fContext->unlockScratchTexture(layer->texture());
200 layer->setTexture(NULL, GrIRect16::MakeEmpty()); 253 layer->setTexture(NULL, GrIRect16::MakeEmpty());
201 } 254 }
202 } 255 }
203 256
204 #ifdef SK_DEBUG 257 #ifdef SK_DEBUG
205 void GrLayerCache::validate() const { 258 void GrLayerCache::validate() const {
206 const SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray(); 259 const SkTDArray<GrCachedLayer*>& layerArray = fLayerHash.getArray();
207 for (int i = 0; i < fLayerHash.count(); ++i) { 260 for (int i = 0; i < fLayerHash.count(); ++i) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 293 }
241 } 294 }
242 295
243 for (int i = 0; i < toBeRemoved.count(); ++i) { 296 for (int i = 0; i < toBeRemoved.count(); ++i) {
244 this->unlock(toBeRemoved[i]); 297 this->unlock(toBeRemoved[i]);
245 298
246 PictureLayerKey key(picture->uniqueID(), toBeRemoved[i]->layerID()); 299 PictureLayerKey key(picture->uniqueID(), toBeRemoved[i]->layerID());
247 fLayerHash.remove(key, toBeRemoved[i]); 300 fLayerHash.remove(key, toBeRemoved[i]);
248 SkDELETE(toBeRemoved[i]); 301 SkDELETE(toBeRemoved[i]);
249 } 302 }
303
304 GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(picture->uniqueID())) ;
305 if (NULL != pictInfo) {
306 fPictureHash.remove(PictureKey(picture->uniqueID()), pictInfo);
307 SkDELETE(pictInfo);
308 }
250 } 309 }
OLDNEW
« no previous file with comments | « src/gpu/GrLayerCache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698