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

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

Issue 1406013006: Update Layer Hoisting to store its atlas texture in the resource cache (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix Android bug Created 5 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 "GrLayerAtlas.h" 8 #include "GrLayerAtlas.h"
9 #include "GrContext.h" 9 #include "GrContext.h"
10 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
11 #include "GrGpu.h" 11 #include "GrGpu.h"
12 #include "GrLayerCache.h" 12 #include "GrLayerCache.h"
13 #include "GrSurfacePriv.h" 13 #include "GrSurfacePriv.h"
14 14
15 #ifdef SK_DEBUG 15 #ifdef SK_DEBUG
16 void GrCachedLayer::validate(const GrTexture* backingTexture) const { 16 void GrCachedLayer::validate(const GrTexture* backingTexture) const {
17 SkASSERT(SK_InvalidGenID != fKey.pictureID()); 17 SkASSERT(SK_InvalidGenID != fKey.pictureID());
18 18
19 if (fTexture) { 19 if (fTexture) {
20 // If the layer is in some texture then it must occupy some rectangle 20 // If the layer is in some texture then it must occupy some rectangle
21 SkASSERT(!fRect.isEmpty()); 21 SkASSERT(!fRect.isEmpty());
22 if (!this->isAtlased()) { 22 if (!this->isAtlased()) {
23 // If it isn't atlased then the rectangle should start at the origin 23 // If it isn't atlased then the rectangle should start at the origin
24 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop); 24 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop);
25 } 25 }
26 } else { 26 } else {
27 SkASSERT(fRect.isEmpty()); 27 SkASSERT(fRect.isEmpty());
28 SkASSERT(nullptr == fPlot); 28 SkASSERT(nullptr == fPlot);
29 SkASSERT(!fLocked); // layers without a texture cannot be locked 29 SkASSERT(!fLocked); // layers without a texture cannot be locked
30 SkASSERT(!fAtlased); // can't be atlased if it doesn't have a texture
30 } 31 }
31 32
32 if (fPlot) { 33 if (fPlot) {
34 SkASSERT(fAtlased);
33 // If a layer has a plot (i.e., is atlased) then it must point to 35 // If a layer has a plot (i.e., is atlased) then it must point to
34 // the backing texture. Additionally, its rect should be non-empty. 36 // the backing texture. Additionally, its rect should be non-empty.
35 SkASSERT(fTexture && backingTexture == fTexture); 37 SkASSERT(fTexture && backingTexture == fTexture);
36 SkASSERT(!fRect.isEmpty()); 38 SkASSERT(!fRect.isEmpty());
37 } 39 }
38 40
39 if (fLocked) { 41 if (fLocked) {
40 // If a layer is locked it must have a texture (though it need not be 42 // If a layer is locked it must have a texture (though it need not be
41 // the atlas-backing texture) and occupy some space. 43 // the atlas-backing texture) and occupy some space.
42 SkASSERT(fTexture); 44 SkASSERT(fTexture);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 void GrLayerCache::freeAll() { 114 void GrLayerCache::freeAll() {
113 115
114 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); 116 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
115 for (; !iter.done(); ++iter) { 117 for (; !iter.done(); ++iter) {
116 GrCachedLayer* layer = &(*iter); 118 GrCachedLayer* layer = &(*iter);
117 this->unlock(layer); 119 this->unlock(layer);
118 delete layer; 120 delete layer;
119 } 121 }
120 fLayerHash.rewind(); 122 fLayerHash.rewind();
121 123
122 // The atlas only lets go of its texture when the atlas is deleted. 124 if (fAtlas) {
123 fAtlas.free(); 125 fAtlas->resetPlots();
126 fAtlas->detachBackingTexture();
127 }
124 } 128 }
125 129
126 GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID, 130 GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
127 int start, int stop, 131 int start, int stop,
128 const SkIRect& srcIR, 132 const SkIRect& srcIR,
129 const SkIRect& dstIR, 133 const SkIRect& dstIR,
130 const SkMatrix& initialMat, 134 const SkMatrix& initialMat,
131 const int* key, 135 const int* key,
132 int keySize, 136 int keySize,
133 const SkPaint* paint) { 137 const SkPaint* paint) {
(...skipping 26 matching lines...) Expand all
160 srcIR, dstIR, initialMat, 164 srcIR, dstIR, initialMat,
161 key, keySize, paint); 165 key, keySize, paint);
162 } 166 }
163 167
164 return layer; 168 return layer;
165 } 169 }
166 170
167 bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, 171 bool GrLayerCache::tryToAtlas(GrCachedLayer* layer,
168 const GrSurfaceDesc& desc, 172 const GrSurfaceDesc& desc,
169 bool* needsRendering) { 173 bool* needsRendering) {
170 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : nullptr, layer);) 174 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTextureOrNull() : nu llptr, layer);)
171 175
172 SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight)); 176 SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight));
173 SkASSERT(0 == desc.fSampleCnt); 177 SkASSERT(0 == desc.fSampleCnt);
174 178
175 if (layer->locked()) { 179 if (layer->locked()) {
176 // This layer is already locked 180 // This layer is already locked
177 SkASSERT(fAtlas); 181 SkASSERT(fAtlas);
178 SkASSERT(layer->isAtlased()); 182 SkASSERT(layer->isAtlased());
179 SkASSERT(layer->rect().width() == desc.fWidth); 183 SkASSERT(layer->rect().width() == desc.fWidth);
180 SkASSERT(layer->rect().height() == desc.fHeight); 184 SkASSERT(layer->rect().height() == desc.fHeight);
(...skipping 29 matching lines...) Expand all
210 &loc); 214 &loc);
211 // addToAtlas can allocate the backing texture 215 // addToAtlas can allocate the backing texture
212 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture())); 216 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
213 if (plot) { 217 if (plot) {
214 #if !GR_CACHE_HOISTED_LAYERS 218 #if !GR_CACHE_HOISTED_LAYERS
215 pictInfo->incPlotUsage(plot->id()); 219 pictInfo->incPlotUsage(plot->id());
216 #endif 220 #endif
217 // The layer was successfully added to the atlas 221 // The layer was successfully added to the atlas
218 const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY, 222 const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY,
219 desc.fWidth, desc.fHeig ht); 223 desc.fWidth, desc.fHeig ht);
220 layer->setTexture(fAtlas->getTexture(), bounds); 224 layer->setTexture(fAtlas->getTexture(), bounds, true);
221 layer->setPlot(plot); 225 layer->setPlot(plot);
222 layer->setLocked(true); 226 layer->setLocked(true);
223 this->incPlotLock(layer->plot()->id()); 227 this->incPlotLock(layer->plot()->id());
224 *needsRendering = true; 228 *needsRendering = true;
225 return true; 229 return true;
226 } 230 }
227 231
228 // The layer was rejected by the atlas (even though we know it is 232 // The layer was rejected by the atlas (even though we know it is
229 // plausibly atlas-able). See if a plot can be purged and try again. 233 // plausibly atlas-able). See if a plot can be purged and try again.
230 if (!this->purgePlot()) { 234 if (!this->purgePlots(true)) {
231 break; // We weren't able to purge any plots 235 break; // We weren't able to purge any plots
232 } 236 }
233 } 237 }
234 238
235 if (pictInfo->fPlotUsage.isEmpty()) { 239 if (pictInfo->fPlotUsage.isEmpty()) {
236 fPictureHash.remove(pictInfo->fPictureID); 240 fPictureHash.remove(pictInfo->fPictureID);
237 delete pictInfo; 241 delete pictInfo;
238 } 242 }
239 } 243 }
240 244
(...skipping 12 matching lines...) Expand all
253 if (layer->fFilter) { 257 if (layer->fFilter) {
254 tex.reset(fContext->textureProvider()->createTexture(desc, true)); 258 tex.reset(fContext->textureProvider()->createTexture(desc, true));
255 } else { 259 } else {
256 tex.reset(fContext->textureProvider()->createApproxTexture(desc)); 260 tex.reset(fContext->textureProvider()->createApproxTexture(desc));
257 } 261 }
258 262
259 if (!tex) { 263 if (!tex) {
260 return false; 264 return false;
261 } 265 }
262 266
263 layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight)); 267 layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight), false);
264 layer->setLocked(true); 268 layer->setLocked(true);
265 *needsRendering = true; 269 *needsRendering = true;
266 return true; 270 return true;
267 } 271 }
268 272
269 void GrLayerCache::unlock(GrCachedLayer* layer) { 273 void GrLayerCache::unlock(GrCachedLayer* layer) {
270 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : nullptr, layer);) 274 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTextureOrNull() : nu llptr, layer);)
271 275
272 if (nullptr == layer || !layer->locked()) { 276 if (nullptr == layer || !layer->locked()) {
273 // invalid or not locked 277 // invalid or not locked
274 return; 278 return;
275 } 279 }
276 280
277 if (layer->isAtlased()) { 281 if (layer->isAtlased()) {
278 const int plotID = layer->plot()->id(); 282 const int plotID = layer->plot()->id();
279 283
280 this->decPlotLock(plotID); 284 this->decPlotLock(plotID);
(...skipping 11 matching lines...) Expand all
292 if (0 == pictInfo->plotUsage(plotID)) { 296 if (0 == pictInfo->plotUsage(plotID)) {
293 pictInfo->fPlotUsage.removePlot(layer->plot()); 297 pictInfo->fPlotUsage.removePlot(layer->plot());
294 298
295 if (pictInfo->fPlotUsage.isEmpty()) { 299 if (pictInfo->fPlotUsage.isEmpty()) {
296 fPictureHash.remove(pictInfo->fPictureID); 300 fPictureHash.remove(pictInfo->fPictureID);
297 delete pictInfo; 301 delete pictInfo;
298 } 302 }
299 } 303 }
300 304
301 layer->setPlot(nullptr); 305 layer->setPlot(nullptr);
302 layer->setTexture(nullptr, SkIRect::MakeEmpty()); 306 layer->setTexture(nullptr, SkIRect::MakeEmpty(), false);
303 #endif 307 #endif
304 308
305 } else { 309 } else {
306 layer->setTexture(nullptr, SkIRect::MakeEmpty()); 310 layer->setTexture(nullptr, SkIRect::MakeEmpty(), false);
307 } 311 }
308 312
309 layer->setLocked(false); 313 layer->setLocked(false);
310 } 314 }
311 315
312 #ifdef SK_DEBUG 316 #ifdef SK_DEBUG
313 void GrLayerCache::validate() const { 317 void GrLayerCache::validate() const {
314 int plotLocks[kNumPlotsX * kNumPlotsY]; 318 int plotLocks[kNumPlotsX * kNumPlotsY];
315 memset(plotLocks, 0, sizeof(plotLocks)); 319 memset(plotLocks, 0, sizeof(plotLocks));
316 320
317 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas h); 321 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas h);
318 for (; !iter.done(); ++iter) { 322 for (; !iter.done(); ++iter) {
319 const GrCachedLayer* layer = &(*iter); 323 const GrCachedLayer* layer = &(*iter);
320 324
321 layer->validate(fAtlas.get() ? fAtlas->getTexture() : nullptr); 325 layer->validate(fAtlas.get() ? fAtlas->getTextureOrNull() : nullptr);
322 326
323 const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); 327 const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
324 if (!pictInfo) { 328 if (!pictInfo) {
325 // If there is no picture info for this picture then all of its 329 // If there is no picture info for this picture then all of its
326 // layers should be non-atlased. 330 // layers should be non-atlased.
327 SkASSERT(!layer->isAtlased()); 331 SkASSERT(!layer->isAtlased());
328 } 332 }
329 333
330 if (layer->plot()) { 334 if (layer->plot()) {
331 SkASSERT(pictInfo); 335 SkASSERT(pictInfo);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 delete toBeRemoved[i]; 386 delete toBeRemoved[i];
383 } 387 }
384 388
385 GrPictureInfo* pictInfo = fPictureHash.find(pictureID); 389 GrPictureInfo* pictInfo = fPictureHash.find(pictureID);
386 if (pictInfo) { 390 if (pictInfo) {
387 fPictureHash.remove(pictureID); 391 fPictureHash.remove(pictureID);
388 delete pictInfo; 392 delete pictInfo;
389 } 393 }
390 } 394 }
391 395
392 bool GrLayerCache::purgePlot() { 396 bool GrLayerCache::purgePlots(bool justOne) {
393 SkDEBUGCODE(GrAutoValidateCache avc(this);) 397 SkDEBUGCODE(GrAutoValidateCache avc(this);)
394 SkASSERT(fAtlas); 398 SkASSERT(fAtlas);
395 399
400 bool anyPurged = false;
396 GrLayerAtlas::PlotIter iter; 401 GrLayerAtlas::PlotIter iter;
397 GrLayerAtlas::Plot* plot; 402 GrLayerAtlas::Plot* plot;
398 for (plot = fAtlas->iterInit(&iter, GrLayerAtlas::kLRUFirst_IterOrder); 403 for (plot = fAtlas->iterInit(&iter, GrLayerAtlas::kLRUFirst_IterOrder);
399 plot; 404 plot;
400 plot = iter.prev()) { 405 plot = iter.prev()) {
401 if (fPlotLocks[plot->id()] > 0) { 406 if (fPlotLocks[plot->id()] > 0) {
402 continue; 407 continue;
403 } 408 }
404 409
410 anyPurged = true;
405 this->purgePlot(plot); 411 this->purgePlot(plot);
406 return true; 412 if (justOne) {
413 break;
414 }
407 } 415 }
408 416
409 return false; 417 return anyPurged;
410 } 418 }
411 419
412 void GrLayerCache::purgePlot(GrLayerAtlas::Plot* plot) { 420 void GrLayerCache::purgePlot(GrLayerAtlas::Plot* plot) {
413 SkASSERT(0 == fPlotLocks[plot->id()]); 421 SkASSERT(0 == fPlotLocks[plot->id()]);
414 422
415 // We need to find all the layers in 'plot' and remove them. 423 // We need to find all the layers in 'plot' and remove them.
416 SkTDArray<GrCachedLayer*> toBeRemoved; 424 SkTDArray<GrCachedLayer*> toBeRemoved;
417 425
418 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); 426 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
419 for (; !iter.done(); ++iter) { 427 for (; !iter.done(); ++iter) {
(...skipping 28 matching lines...) Expand all
448 456
449 plot->reset(); 457 plot->reset();
450 } 458 }
451 459
452 #if !GR_CACHE_HOISTED_LAYERS 460 #if !GR_CACHE_HOISTED_LAYERS
453 void GrLayerCache::purgeAll() { 461 void GrLayerCache::purgeAll() {
454 if (!fAtlas) { 462 if (!fAtlas) {
455 return; 463 return;
456 } 464 }
457 465
458 GrLayerAtlas::PlotIter iter; 466 this->purgePlots(false); // clear them all out
459 GrLayerAtlas::Plot* plot;
460 for (plot = fAtlas->iterInit(&iter, GrLayerAtlas::kLRUFirst_IterOrder);
461 plot;
462 plot = iter.prev()) {
463 SkASSERT(0 == fPlotLocks[plot->id()]);
464
465 this->purgePlot(plot);
466 }
467 467
468 SkASSERT(0 == fPictureHash.count()); 468 SkASSERT(0 == fPictureHash.count());
469 469
470 SkAutoTUnref<GrDrawContext> drawContext( 470 if (fAtlas->getTextureOrNull()) {
471 fContext->drawContext(fAtlas->getTexture()->asRe nderTarget())); 471 SkAutoTUnref<GrDrawContext> drawContext(
472 fContext->drawContext(fAtlas->getTexture()-> asRenderTarget()));
472 473
473 if (drawContext) { 474 if (drawContext) {
474 drawContext->discard(); 475 drawContext->discard();
476 }
475 } 477 }
476 } 478 }
477 #endif 479 #endif
478 480
481 void GrLayerCache::begin() {
482 if (!fAtlas) {
483 return;
484 }
485
486 if (!fAtlas->reattachBackingTexture()) {
487 // We weren't able to re-attach. Clear out all the atlased layers.
488 this->purgePlots(false);
489 SkASSERT(0 == fPictureHash.count());
490 }
491 #ifdef SK_DEBUG
492 else {
493 // we've reattached - everything had better make sense
494 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash );
495 for (; !iter.done(); ++iter) {
496 GrCachedLayer* layer = &(*iter);
497
498 if (layer->isAtlased()) {
499 SkASSERT(fAtlas->getTexture() == layer->texture());
500 }
501 }
502 }
503 #endif
504 }
505
506 void GrLayerCache::end() {
507 if (!fAtlas) {
508 return;
509 }
510
511 // Adding this call will clear out all the layers in the atlas
512 //this->purgePlots(false);
513
514 fAtlas->detachBackingTexture();
515 }
516
479 void GrLayerCache::processDeletedPictures() { 517 void GrLayerCache::processDeletedPictures() {
480 SkTArray<SkPicture::DeletionMessage> deletedPictures; 518 SkTArray<SkPicture::DeletionMessage> deletedPictures;
481 fPictDeletionInbox.poll(&deletedPictures); 519 fPictDeletionInbox.poll(&deletedPictures);
482 520
483 for (int i = 0; i < deletedPictures.count(); i++) { 521 for (int i = 0; i < deletedPictures.count(); i++) {
484 this->purge(deletedPictures[i].fUniqueID); 522 this->purge(deletedPictures[i].fUniqueID);
485 } 523 }
486 } 524 }
487 525
488 #ifdef SK_DEVELOPER 526 #ifdef SK_DEVELOPER
489 void GrLayerCache::writeLayersToDisk(const SkString& dirName) { 527 void GrLayerCache::writeLayersToDisk(const SkString& dirName) {
490 528
491 if (fAtlas) { 529 if (fAtlas) {
492 GrTexture* atlasTexture = fAtlas->getTexture(); 530 GrTexture* atlasTexture = fAtlas->getTextureOrNull();
493 if (nullptr != atlasTexture) { 531 if (nullptr != atlasTexture) {
494 SkString fileName(dirName); 532 SkString fileName(dirName);
495 fileName.append("\\atlas.png"); 533 fileName.append("\\atlas.png");
496 534
497 atlasTexture->surfacePriv().savePixels(fileName.c_str()); 535 atlasTexture->surfacePriv().savePixels(fileName.c_str());
498 } 536 }
499 } 537 }
500 538
501 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); 539 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash);
502 for (; !iter.done(); ++iter) { 540 for (; !iter.done(); ++iter) {
503 GrCachedLayer* layer = &(*iter); 541 GrCachedLayer* layer = &(*iter);
504 542
505 if (layer->isAtlased() || !layer->texture()) { 543 if (layer->isAtlased() || !layer->texture()) {
506 continue; 544 continue;
507 } 545 }
508 546
509 SkString fileName(dirName); 547 SkString fileName(dirName);
510 fileName.appendf("\\%d", layer->fKey.pictureID()); 548 fileName.appendf("\\%d", layer->fKey.pictureID());
511 for (int i = 0; i < layer->fKey.keySize(); ++i) { 549 for (int i = 0; i < layer->fKey.keySize(); ++i) {
512 fileName.appendf("-%d", layer->fKey.key()[i]); 550 fileName.appendf("-%d", layer->fKey.key()[i]);
513 } 551 }
514 fileName.appendf(".png"); 552 fileName.appendf(".png");
515 553
516 layer->texture()->surfacePriv().savePixels(fileName.c_str()); 554 layer->texture()->surfacePriv().savePixels(fileName.c_str());
517 } 555 }
518 } 556 }
519 #endif 557 #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