diff options
author | robertphillips <robertphillips@google.com> | 2014-09-30 11:33:02 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-30 11:33:02 -0700 |
commit | b5a97154f893a5fd3495e16872d370124e93c6ca (patch) | |
tree | e139e1d58496b906d9c50652641cf3afa65cd081 /src | |
parent | 5bc760a6a6a61ff462a204e0c051ad6147760223 (diff) |
Allow previously-hoisted layers to be reused in the same draw
In the Sierpinkski test case there are only a few layers appear in the "to be drawn" lists but they those layers get reused a lot of times with different transforms. This CL adds an additional category to allow such layers to be placed in the GrReplacements object without needing to be rendered.
This is split out of (Fix sub-picture layer rendering bugs - https://codereview.chromium.org/597293002/)
BUG=skia:2315
R=bsalomon@google.com
Author: robertphillips@google.com
Review URL: https://codereview.chromium.org/616023002
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrLayerHoister.cpp | 26 | ||||
-rw-r--r-- | src/gpu/GrLayerHoister.h | 11 | ||||
-rw-r--r-- | src/gpu/GrPictureUtils.cpp | 4 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 8 |
4 files changed, 33 insertions, 16 deletions
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp index f2e6560a18..8143bdc375 100644 --- a/src/gpu/GrLayerHoister.cpp +++ b/src/gpu/GrLayerHoister.cpp @@ -18,6 +18,7 @@ bool GrLayerHoister::FindLayersToHoist(const SkPicture* topLevelPicture, const SkRect& query, SkTDArray<HoistedLayer>* atlased, SkTDArray<HoistedLayer>* nonAtlased, + SkTDArray<HoistedLayer>* recycled, GrLayerCache* layerCache) { bool anyHoisted = false; @@ -101,20 +102,22 @@ bool GrLayerHoister::FindLayersToHoist(const SkPicture* topLevelPicture, continue; } - if (needsRendering) { - HoistedLayer* hl; + HoistedLayer* hl; + if (needsRendering) { if (layer->isAtlased()) { hl = atlased->append(); } else { hl = nonAtlased->append(); } - - hl->fLayer = layer; - hl->fPicture = pict; - hl->fOffset = info.fOffset; - hl->fCTM = info.fOriginXform; + } else { + hl = recycled->append(); } + + hl->fLayer = layer; + hl->fPicture = pict; + hl->fOffset = info.fOffset; + hl->fCTM = info.fOriginXform; } } @@ -160,6 +163,7 @@ static void convert_layers_to_replacements(const SkTDArray<GrLayerHoister::Hoist void GrLayerHoister::DrawLayers(const SkTDArray<HoistedLayer>& atlased, const SkTDArray<HoistedLayer>& nonAtlased, + const SkTDArray<HoistedLayer>& recycled, GrReplacements* replacements) { // Render the atlased layers that require it if (atlased.count() > 0) { @@ -253,6 +257,7 @@ void GrLayerHoister::DrawLayers(const SkTDArray<HoistedLayer>& atlased, convert_layers_to_replacements(atlased, replacements); convert_layers_to_replacements(nonAtlased, replacements); + convert_layers_to_replacements(recycled, replacements); } static void unlock_layer_in_cache(GrLayerCache* layerCache, @@ -270,7 +275,8 @@ static void unlock_layer_in_cache(GrLayerCache* layerCache, void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, const SkTDArray<HoistedLayer>& atlased, - const SkTDArray<HoistedLayer>& nonAtlased) { + const SkTDArray<HoistedLayer>& nonAtlased, + const SkTDArray<HoistedLayer>& recycled) { for (int i = 0; i < atlased.count(); ++i) { unlock_layer_in_cache(layerCache, atlased[i].fPicture, atlased[i].fLayer); @@ -280,6 +286,10 @@ void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, unlock_layer_in_cache(layerCache, nonAtlased[i].fPicture, nonAtlased[i].fLayer); } + for (int i = 0; i < recycled.count(); ++i) { + unlock_layer_in_cache(layerCache, recycled[i].fPicture, recycled[i].fLayer); + } + #if DISABLE_CACHING // This code completely clears out the atlas. It is required when // caching is disabled so the atlas doesn't fill up and force more diff --git a/src/gpu/GrLayerHoister.h b/src/gpu/GrLayerHoister.h index 6aff2ea32a..58b3f4870b 100644 --- a/src/gpu/GrLayerHoister.h +++ b/src/gpu/GrLayerHoister.h @@ -36,6 +36,7 @@ public: @param query The rectangle that is about to be drawn. @param atlased Out parameter storing the layers that should be hoisted to the atlas @param nonAtlased Out parameter storing the layers that should be hoisted stand alone + @param recycled Out parameter storing layers that need hoisting but not rendering @param layerCache The source of new layers Return true if any layers are suitable for hoisting; false otherwise */ @@ -43,25 +44,31 @@ public: const SkRect& query, SkTDArray<HoistedLayer>* altased, SkTDArray<HoistedLayer>* nonAtlased, + SkTDArray<HoistedLayer>* recycled, GrLayerCache* layerCache); /** Draw the specified layers into either the atlas or free floating textures. @param atlased The layers to be drawn into the atlas @param nonAtlased The layers to be drawn into their own textures - @oaram replacements The replacement structure to fill in with the rendered layer info + @param recycled Layers that don't need rendering but do need to go into the + replacements object + @param replacements The replacement structure to fill in with the rendered layer info */ static void DrawLayers(const SkTDArray<HoistedLayer>& atlased, const SkTDArray<HoistedLayer>& nonAtlased, + const SkTDArray<HoistedLayer>& recycled, GrReplacements* replacements); /** Unlock unneeded layers in the layer cache. @param layerCache holder of the locked layers @param atlased Unneeded layers in the atlas @param nonAtlased Unneeded layers in their own textures + @param recycled Unneeded layers that did not require rendering */ static void UnlockLayers(GrLayerCache* layerCache, const SkTDArray<HoistedLayer>& atlased, - const SkTDArray<HoistedLayer>& nonAtlased); + const SkTDArray<HoistedLayer>& nonAtlased, + const SkTDArray<HoistedLayer>& recycled); }; #endif diff --git a/src/gpu/GrPictureUtils.cpp b/src/gpu/GrPictureUtils.cpp index a4f32e7e02..6aeda2032d 100644 --- a/src/gpu/GrPictureUtils.cpp +++ b/src/gpu/GrPictureUtils.cpp @@ -127,8 +127,8 @@ private: dst.fPicture->ref(); dst.fSize = SkISize::Make(newClip.width(), newClip.height()); dst.fOffset = SkIPoint::Make(newClip.fLeft, newClip.fTop); - dst.fOriginXform = *fCTM; - dst.fOriginXform.postConcat(src.fOriginXform); + dst.fOriginXform = src.fOriginXform; + dst.fOriginXform.postConcat(*fCTM); if (src.fPaint) { dst.fPaint = SkNEW_ARGS(SkPaint, (*src.fPaint)); } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 30b3668d6b..455a8abe01 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1850,23 +1850,23 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture return true; } - SkTDArray<GrLayerHoister::HoistedLayer> atlased, nonAtlased; + SkTDArray<GrLayerHoister::HoistedLayer> atlased, nonAtlased, recycled; if (!GrLayerHoister::FindLayersToHoist(mainPicture, clipBounds, &atlased, &nonAtlased, - fContext->getLayerCache())) { + &recycled, fContext->getLayerCache())) { return false; } GrReplacements replacements; - GrLayerHoister::DrawLayers(atlased, nonAtlased, &replacements); + GrLayerHoister::DrawLayers(atlased, nonAtlased, recycled, &replacements); // Render the entire picture using new layers const SkMatrix initialMatrix = mainCanvas->getTotalMatrix(); GrRecordReplaceDraw(mainPicture, mainCanvas, &replacements, initialMatrix, NULL); - GrLayerHoister::UnlockLayers(fContext->getLayerCache(), atlased, nonAtlased); + GrLayerHoister::UnlockLayers(fContext->getLayerCache(), atlased, nonAtlased, recycled); return true; } |