Fix bug in aggressive layer cache purging
A picture may possess many layers that get placed in one plot of the atlas. In this case we can only remove the plot from the plotUsage tracking structure when all the layers belonging to the picture in that plot have been removed. Review URL: https://codereview.chromium.org/654463004
This commit is contained in:
parent
a3a706fcd4
commit
225a627ccb
@ -100,6 +100,7 @@ GrLayerCache::~GrLayerCache() {
|
||||
|
||||
void GrLayerCache::initAtlas() {
|
||||
SkASSERT(NULL == fAtlas.get());
|
||||
GR_STATIC_ASSERT(kNumPlotsX*kNumPlotsX == GrPictureInfo::kNumPlots);
|
||||
|
||||
SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight);
|
||||
fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfig,
|
||||
@ -201,6 +202,9 @@ bool GrLayerCache::tryToAtlas(GrCachedLayer* layer,
|
||||
// addToAtlas can allocate the backing texture
|
||||
SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
|
||||
if (plot) {
|
||||
#if !GR_CACHE_HOISTED_LAYERS
|
||||
pictInfo->incPlotUsage(plot->id());
|
||||
#endif
|
||||
// The layer was successfully added to the atlas
|
||||
GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
|
||||
SkToS16(desc.fWidth),
|
||||
@ -264,8 +268,12 @@ void GrLayerCache::unlock(GrCachedLayer* layer) {
|
||||
// render target pingponging from that due to the re-use of cached layers
|
||||
GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID());
|
||||
SkASSERT(pictInfo);
|
||||
|
||||
GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot());
|
||||
|
||||
pictInfo->decPlotUsage(plotID);
|
||||
|
||||
if (0 == pictInfo->plotUsage(plotID)) {
|
||||
GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot());
|
||||
}
|
||||
|
||||
layer->setPlot(NULL);
|
||||
layer->setTexture(NULL, GrIRect16::MakeEmpty());
|
||||
@ -301,6 +309,9 @@ void GrLayerCache::validate() const {
|
||||
SkASSERT(pictInfo->fPictureID == layer->pictureID());
|
||||
|
||||
SkASSERT(pictInfo->fPlotUsage.contains(layer->plot()));
|
||||
#if !GR_CACHE_HOISTED_LAYERS
|
||||
SkASSERT(pictInfo->plotUsage(layer->plot()->id()) > 0);
|
||||
#endif
|
||||
|
||||
if (layer->locked()) {
|
||||
plotLocks[layer->plot()->id()]++;
|
||||
@ -400,6 +411,9 @@ void GrLayerCache::purgePlot(GrPlot* plot) {
|
||||
|
||||
GrPictureInfo* pictInfo = fPictureHash.find(pictureIDToRemove);
|
||||
if (pictInfo) {
|
||||
#if !GR_CACHE_HOISTED_LAYERS
|
||||
SkASSERT(0 == pictInfo->plotUsage(plot->id()));
|
||||
#endif
|
||||
GrAtlas::RemovePlot(&pictInfo->fPlotUsage, plot);
|
||||
|
||||
if (pictInfo->fPlotUsage.isEmpty()) {
|
||||
|
@ -30,16 +30,44 @@ struct GrPictureDeletedMessage {
|
||||
// plot may be used to store layers from multiple pictures.
|
||||
struct GrPictureInfo {
|
||||
public:
|
||||
static const int kNumPlots = 4;
|
||||
|
||||
// for SkTDynamicHash - just use the pictureID as the hash key
|
||||
static const uint32_t& GetKey(const GrPictureInfo& pictInfo) { return pictInfo.fPictureID; }
|
||||
static uint32_t Hash(const uint32_t& key) { return SkChecksum::Mix(key); }
|
||||
|
||||
// GrPictureInfo proper
|
||||
GrPictureInfo(uint32_t pictureID) : fPictureID(pictureID) { }
|
||||
GrPictureInfo(uint32_t pictureID) : fPictureID(pictureID) {
|
||||
#if !GR_CACHE_HOISTED_LAYERS
|
||||
memset(fPlotUses, 0, sizeof(fPlotUses));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GR_CACHE_HOISTED_LAYERS
|
||||
void incPlotUsage(int plotID) {
|
||||
SkASSERT(plotID < kNumPlots);
|
||||
fPlotUses[plotID]++;
|
||||
}
|
||||
|
||||
void decPlotUsage(int plotID) {
|
||||
SkASSERT(plotID < kNumPlots);
|
||||
SkASSERT(fPlotUses[plotID] > 0);
|
||||
fPlotUses[plotID]--;
|
||||
}
|
||||
|
||||
int plotUsage(int plotID) const {
|
||||
SkASSERT(plotID < kNumPlots);
|
||||
return fPlotUses[plotID];
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint32_t fPictureID;
|
||||
|
||||
GrAtlas::ClientPlotUsage fPlotUsage;
|
||||
|
||||
#if !GR_CACHE_HOISTED_LAYERS
|
||||
private:
|
||||
int fPlotUses[kNumPlots];
|
||||
#endif
|
||||
};
|
||||
|
||||
// GrCachedLayer encapsulates the caching information for a single saveLayer.
|
||||
|
Loading…
Reference in New Issue
Block a user