aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-09-30 11:33:02 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-30 11:33:02 -0700
commitb5a97154f893a5fd3495e16872d370124e93c6ca (patch)
treee139e1d58496b906d9c50652641cf3afa65cd081 /src
parent5bc760a6a6a61ff462a204e0c051ad6147760223 (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.cpp26
-rw-r--r--src/gpu/GrLayerHoister.h11
-rw-r--r--src/gpu/GrPictureUtils.cpp4
-rw-r--r--src/gpu/SkGpuDevice.cpp8
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;
}