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

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

Issue 678403002: Discard atlas after every MultiPictureDraw::draw (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix rebase error Created 6 years, 1 month 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/GrLayerHoister.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"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } 74 }
75 75
76 private: 76 private:
77 const GrTexture* fBackingTexture; 77 const GrTexture* fBackingTexture;
78 const GrCachedLayer* fLayer; 78 const GrCachedLayer* fLayer;
79 }; 79 };
80 #endif 80 #endif
81 81
82 GrLayerCache::GrLayerCache(GrContext* context) 82 GrLayerCache::GrLayerCache(GrContext* context)
83 : fContext(context) { 83 : fContext(context) {
84 this->initAtlas();
85 memset(fPlotLocks, 0, sizeof(fPlotLocks)); 84 memset(fPlotLocks, 0, sizeof(fPlotLocks));
86 } 85 }
87 86
88 GrLayerCache::~GrLayerCache() { 87 GrLayerCache::~GrLayerCache() {
89 88
90 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); 89 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
91 for (; !iter.done(); ++iter) { 90 for (; !iter.done(); ++iter) {
92 GrCachedLayer* layer = &(*iter); 91 GrCachedLayer* layer = &(*iter);
93 SkASSERT(0 == layer->uses()); 92 SkASSERT(0 == layer->uses());
94 this->unlock(layer); 93 this->unlock(layer);
(...skipping 18 matching lines...) Expand all
113 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); 112 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
114 for (; !iter.done(); ++iter) { 113 for (; !iter.done(); ++iter) {
115 GrCachedLayer* layer = &(*iter); 114 GrCachedLayer* layer = &(*iter);
116 this->unlock(layer); 115 this->unlock(layer);
117 SkDELETE(layer); 116 SkDELETE(layer);
118 } 117 }
119 fLayerHash.rewind(); 118 fLayerHash.rewind();
120 119
121 // The atlas only lets go of its texture when the atlas is deleted. 120 // The atlas only lets go of its texture when the atlas is deleted.
122 fAtlas.free(); 121 fAtlas.free();
123 // GrLayerCache always assumes an atlas exists so recreate it. The atlas
124 // lazily allocates a replacement texture so reallocating a new
125 // atlas here won't disrupt a GrContext::abandonContext or freeGpuResources.
126 // TODO: Make GrLayerCache lazily allocate the atlas manager?
127 this->initAtlas();
128 } 122 }
129 123
130 GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID, 124 GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
131 int start, int stop, 125 int start, int stop,
132 const SkIRect& bounds, 126 const SkIRect& bounds,
133 const SkMatrix& ctm, 127 const SkMatrix& ctm,
134 const SkPaint* paint) { 128 const SkPaint* paint) {
135 SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0); 129 SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
136 130
137 GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, bo unds, ctm, paint)); 131 GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, bo unds, ctm, paint));
(...skipping 19 matching lines...) Expand all
157 if (NULL == layer) { 151 if (NULL == layer) {
158 layer = this->createLayer(pictureID, start, stop, bounds, ctm, paint); 152 layer = this->createLayer(pictureID, start, stop, bounds, ctm, paint);
159 } 153 }
160 154
161 return layer; 155 return layer;
162 } 156 }
163 157
164 bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, 158 bool GrLayerCache::tryToAtlas(GrCachedLayer* layer,
165 const GrSurfaceDesc& desc, 159 const GrSurfaceDesc& desc,
166 bool* needsRendering) { 160 bool* needsRendering) {
167 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 161 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : NULL, la yer);)
168 162
169 SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight)); 163 SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight));
170 164
171 if (layer->locked()) { 165 if (layer->locked()) {
172 // This layer is already locked 166 // This layer is already locked
167 SkASSERT(fAtlas);
173 SkASSERT(layer->isAtlased()); 168 SkASSERT(layer->isAtlased());
174 SkASSERT(layer->rect().width() == desc.fWidth); 169 SkASSERT(layer->rect().width() == desc.fWidth);
175 SkASSERT(layer->rect().height() == desc.fHeight); 170 SkASSERT(layer->rect().height() == desc.fHeight);
176 *needsRendering = false; 171 *needsRendering = false;
177 return true; 172 return true;
178 } 173 }
179 174
180 if (layer->isAtlased()) { 175 if (layer->isAtlased()) {
176 SkASSERT(fAtlas);
181 // Hooray it is still in the atlas - make sure it stays there 177 // Hooray it is still in the atlas - make sure it stays there
182 layer->setLocked(true); 178 layer->setLocked(true);
183 this->incPlotLock(layer->plot()->id()); 179 this->incPlotLock(layer->plot()->id());
184 *needsRendering = false; 180 *needsRendering = false;
185 return true; 181 return true;
186 } else { 182 } else {
183 if (!fAtlas) {
184 this->initAtlas();
185 if (!fAtlas) {
186 return false;
187 }
188 }
187 // Not in the atlas - will it fit? 189 // Not in the atlas - will it fit?
188 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); 190 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
189 if (NULL == pictInfo) { 191 if (NULL == pictInfo) {
190 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID())); 192 pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID()));
191 fPictureHash.add(pictInfo); 193 fPictureHash.add(pictInfo);
192 } 194 }
193 195
194 SkIPoint16 loc; 196 SkIPoint16 loc;
195 for (int i = 0; i < 2; ++i) { // extra pass in case we fail to add but a re able to purge 197 for (int i = 0; i < 2; ++i) { // extra pass in case we fail to add but a re able to purge
196 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage, 198 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 return false; 238 return false;
237 } 239 }
238 240
239 layer->setTexture(tex, GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc. fHeight))); 241 layer->setTexture(tex, GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc. fHeight)));
240 layer->setLocked(true); 242 layer->setLocked(true);
241 *needsRendering = true; 243 *needsRendering = true;
242 return true; 244 return true;
243 } 245 }
244 246
245 void GrLayerCache::unlock(GrCachedLayer* layer) { 247 void GrLayerCache::unlock(GrCachedLayer* layer) {
246 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas->getTexture(), layer);) 248 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : NULL, la yer);)
247 249
248 if (NULL == layer || !layer->locked()) { 250 if (NULL == layer || !layer->locked()) {
249 // invalid or not locked 251 // invalid or not locked
250 return; 252 return;
251 } 253 }
252 254
253 if (layer->isAtlased()) { 255 if (layer->isAtlased()) {
254 const int plotID = layer->plot()->id(); 256 const int plotID = layer->plot()->id();
255 257
256 this->decPlotLock(plotID); 258 this->decPlotLock(plotID);
257 // At this point we could aggressively clear out un-locked plots but 259 // At this point we could aggressively clear out un-locked plots but
258 // by delaying we may be able to reuse some of the atlased layers later. 260 // by delaying we may be able to reuse some of the atlased layers later.
259 #if DISABLE_CACHING 261 #if !GR_CACHE_HOISTED_LAYERS
260 // This testing code aggressively removes the atlased layers. This 262 // This testing code aggressively removes the atlased layers. This
261 // can be used to separate the performance contribution of less 263 // can be used to separate the performance contribution of less
262 // render target pingponging from that due to the re-use of cached layer s 264 // render target pingponging from that due to the re-use of cached layer s
263 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); 265 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
264 SkASSERT(pictInfo); 266 SkASSERT(pictInfo);
265 267
266 GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot()); 268 GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot());
267 269
268 layer->setPlot(NULL); 270 layer->setPlot(NULL);
269 layer->setTexture(NULL, GrIRect16::MakeEmpty()); 271 layer->setTexture(NULL, GrIRect16::MakeEmpty());
270 #endif 272 #endif
271 273
272 } else { 274 } else {
273 layer->setTexture(NULL, GrIRect16::MakeEmpty()); 275 layer->setTexture(NULL, GrIRect16::MakeEmpty());
274 } 276 }
275 277
276 layer->setLocked(false); 278 layer->setLocked(false);
277 } 279 }
278 280
279 #ifdef SK_DEBUG 281 #ifdef SK_DEBUG
280 void GrLayerCache::validate() const { 282 void GrLayerCache::validate() const {
281 int plotLocks[kNumPlotsX * kNumPlotsY]; 283 int plotLocks[kNumPlotsX * kNumPlotsY];
282 memset(plotLocks, 0, sizeof(plotLocks)); 284 memset(plotLocks, 0, sizeof(plotLocks));
283 285
284 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas h); 286 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas h);
285 for (; !iter.done(); ++iter) { 287 for (; !iter.done(); ++iter) {
286 const GrCachedLayer* layer = &(*iter); 288 const GrCachedLayer* layer = &(*iter);
287 289
288 layer->validate(fAtlas->getTexture()); 290 layer->validate(fAtlas.get() ? fAtlas->getTexture() : NULL);
289 291
290 const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); 292 const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
291 if (!pictInfo) { 293 if (!pictInfo) {
292 // If there is no picture info for this picture then all of its 294 // If there is no picture info for this picture then all of its
293 // layers should be non-atlased. 295 // layers should be non-atlased.
294 SkASSERT(!layer->isAtlased()); 296 SkASSERT(!layer->isAtlased());
295 } 297 }
296 298
297 if (layer->plot()) { 299 if (layer->plot()) {
298 SkASSERT(pictInfo); 300 SkASSERT(pictInfo);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 350
349 GrPictureInfo* pictInfo = fPictureHash.find(pictureID); 351 GrPictureInfo* pictInfo = fPictureHash.find(pictureID);
350 if (pictInfo) { 352 if (pictInfo) {
351 fPictureHash.remove(pictureID); 353 fPictureHash.remove(pictureID);
352 SkDELETE(pictInfo); 354 SkDELETE(pictInfo);
353 } 355 }
354 } 356 }
355 357
356 bool GrLayerCache::purgePlot() { 358 bool GrLayerCache::purgePlot() {
357 SkDEBUGCODE(GrAutoValidateCache avc(this);) 359 SkDEBUGCODE(GrAutoValidateCache avc(this);)
360 SkASSERT(fAtlas);
358 361
359 GrAtlas::PlotIter iter; 362 GrAtlas::PlotIter iter;
360 GrPlot* plot; 363 GrPlot* plot;
361 for (plot = fAtlas->iterInit(&iter, GrAtlas::kLRUFirst_IterOrder); 364 for (plot = fAtlas->iterInit(&iter, GrAtlas::kLRUFirst_IterOrder);
362 plot; 365 plot;
363 plot = iter.prev()) { 366 plot = iter.prev()) {
364 if (fPlotLocks[plot->id()] > 0) { 367 if (fPlotLocks[plot->id()] > 0) {
365 continue; 368 continue;
366 } 369 }
367 370
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 if (pictInfo->fPlotUsage.isEmpty()) { 405 if (pictInfo->fPlotUsage.isEmpty()) {
403 fPictureHash.remove(pictInfo->fPictureID); 406 fPictureHash.remove(pictInfo->fPictureID);
404 SkDELETE(pictInfo); 407 SkDELETE(pictInfo);
405 } 408 }
406 } 409 }
407 } 410 }
408 411
409 plot->resetRects(); 412 plot->resetRects();
410 } 413 }
411 414
415 #if !GR_CACHE_HOISTED_LAYERS
412 void GrLayerCache::purgeAll() { 416 void GrLayerCache::purgeAll() {
417 if (!fAtlas) {
418 return;
419 }
420
413 GrAtlas::PlotIter iter; 421 GrAtlas::PlotIter iter;
414 GrPlot* plot; 422 GrPlot* plot;
415 for (plot = fAtlas->iterInit(&iter, GrAtlas::kLRUFirst_IterOrder); 423 for (plot = fAtlas->iterInit(&iter, GrAtlas::kLRUFirst_IterOrder);
416 plot; 424 plot;
417 plot = iter.prev()) { 425 plot = iter.prev()) {
418 SkASSERT(0 == fPlotLocks[plot->id()]); 426 SkASSERT(0 == fPlotLocks[plot->id()]);
419 427
420 this->purgePlot(plot); 428 this->purgePlot(plot);
421 } 429 }
430
431 fContext->discardRenderTarget(fAtlas->getTexture()->asRenderTarget());
422 } 432 }
433 #endif
423 434
424 class GrPictureDeletionListener : public SkPicture::DeletionListener { 435 class GrPictureDeletionListener : public SkPicture::DeletionListener {
425 virtual void onDeletion(uint32_t pictureID) SK_OVERRIDE{ 436 virtual void onDeletion(uint32_t pictureID) SK_OVERRIDE{
426 const GrPictureDeletedMessage message = { pictureID }; 437 const GrPictureDeletedMessage message = { pictureID };
427 SkMessageBus<GrPictureDeletedMessage>::Post(message); 438 SkMessageBus<GrPictureDeletedMessage>::Post(message);
428 } 439 }
429 }; 440 };
430 441
431 void GrLayerCache::trackPicture(const SkPicture* picture) { 442 void GrLayerCache::trackPicture(const SkPicture* picture) {
432 if (NULL == fDeletionListener) { 443 if (NULL == fDeletionListener) {
433 fDeletionListener.reset(SkNEW(GrPictureDeletionListener)); 444 fDeletionListener.reset(SkNEW(GrPictureDeletionListener));
434 } 445 }
435 446
436 picture->addDeletionListener(fDeletionListener); 447 picture->addDeletionListener(fDeletionListener);
437 } 448 }
438 449
439 void GrLayerCache::processDeletedPictures() { 450 void GrLayerCache::processDeletedPictures() {
440 SkTDArray<GrPictureDeletedMessage> deletedPictures; 451 SkTDArray<GrPictureDeletedMessage> deletedPictures;
441 fPictDeletionInbox.poll(&deletedPictures); 452 fPictDeletionInbox.poll(&deletedPictures);
442 453
443 for (int i = 0; i < deletedPictures.count(); i++) { 454 for (int i = 0; i < deletedPictures.count(); i++) {
444 this->purge(deletedPictures[i].pictureID); 455 this->purge(deletedPictures[i].pictureID);
445 } 456 }
446 } 457 }
447 458
448 #ifdef SK_DEVELOPER 459 #ifdef SK_DEVELOPER
449 void GrLayerCache::writeLayersToDisk(const SkString& dirName) { 460 void GrLayerCache::writeLayersToDisk(const SkString& dirName) {
450 461
451 GrTexture* atlasTexture = fAtlas->getTexture(); 462 if (fAtlas) {
452 if (NULL != atlasTexture) { 463 GrTexture* atlasTexture = fAtlas->getTexture();
453 SkString fileName(dirName); 464 if (NULL != atlasTexture) {
454 fileName.append("\\atlas.png"); 465 SkString fileName(dirName);
466 fileName.append("\\atlas.png");
455 467
456 atlasTexture->surfacePriv().savePixels(fileName.c_str()); 468 atlasTexture->surfacePriv().savePixels(fileName.c_str());
469 }
457 } 470 }
458 471
459 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); 472 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
460 for (; !iter.done(); ++iter) { 473 for (; !iter.done(); ++iter) {
461 GrCachedLayer* layer = &(*iter); 474 GrCachedLayer* layer = &(*iter);
462 475
463 if (layer->isAtlased() || !layer->texture()) { 476 if (layer->isAtlased() || !layer->texture()) {
464 continue; 477 continue;
465 } 478 }
466 479
467 SkString fileName(dirName); 480 SkString fileName(dirName);
468 fileName.appendf("\\%d-%d.png", layer->fKey.pictureID(), layer->fKey.sta rt()); 481 fileName.appendf("\\%d-%d.png", layer->fKey.pictureID(), layer->fKey.sta rt());
469 482
470 layer->texture()->surfacePriv().savePixels(fileName.c_str()); 483 layer->texture()->surfacePriv().savePixels(fileName.c_str());
471 } 484 }
472 } 485 }
473 #endif 486 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrLayerCache.h ('k') | src/gpu/GrLayerHoister.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698