diff options
author | robertphillips <robertphillips@google.com> | 2014-10-28 07:21:44 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-28 07:21:44 -0700 |
commit | fd61ed0d7929cf85e0b936f48c72035af4c0a4b3 (patch) | |
tree | c91a06c5372a7846a01fe12a21e7597a790f88a3 /src/core/SkMultiPictureDraw.cpp | |
parent | ed53742e92c94d5ce20b982833725cf20546aaca (diff) |
Alter layer hoisting to only hoist layers for one canvas at a time
This CL alters layer hoisting to defer creation of the free floating layers until they are actually needed (rather than creating _all_ the hoisted layers at the start).
It also fixes a pre vs. post Concat bug with how matrices were being accumulated.
BUG=skia:2315
Review URL: https://codereview.chromium.org/657383004
Diffstat (limited to 'src/core/SkMultiPictureDraw.cpp')
-rw-r--r-- | src/core/SkMultiPictureDraw.cpp | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/core/SkMultiPictureDraw.cpp b/src/core/SkMultiPictureDraw.cpp index 19b26ca607..5fe3c0ea52 100644 --- a/src/core/SkMultiPictureDraw.cpp +++ b/src/core/SkMultiPictureDraw.cpp @@ -63,7 +63,10 @@ void SkMultiPictureDraw::draw() { #ifndef SK_IGNORE_GPU_LAYER_HOISTING GrContext* context = NULL; - SkTDArray<GrHoistedLayer> atlased, nonAtlased, recycled; + // Start by collecting all the layers that are going to be atlased and render + // them (if necessary). Hoisting the free floating layers is deferred until + // drawing the canvas that requires them. + SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled; for (int i = 0; i < fDrawData.count(); ++i) { if (fDrawData[i].canvas->getGrContext() && @@ -80,28 +83,57 @@ void SkMultiPictureDraw::draw() { continue; } - GrLayerHoister::FindLayersToHoist(context, fDrawData[i].picture, - clipBounds, &atlased, &nonAtlased, &recycled); + // TODO: sorting the cacheable layers from smallest to largest + // would improve the packing and reduce the number of swaps + // TODO: another optimization would be to make a first pass to + // lock any required layer that is already in the atlas + GrLayerHoister::FindLayersToAtlas(context, fDrawData[i].picture, + clipBounds, + &atlasedNeedRendering, &atlasedRecycled); } } - GrReplacements replacements; - if (NULL != context) { - GrLayerHoister::DrawLayers(atlased, nonAtlased, recycled, &replacements); + GrLayerHoister::DrawLayersToAtlas(context, atlasedNeedRendering); } + + SkTDArray<GrHoistedLayer> needRendering, recycled; #endif for (int i = 0; i < fDrawData.count(); ++i) { #ifndef SK_IGNORE_GPU_LAYER_HOISTING if (fDrawData[i].canvas->getGrContext() && !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { - // Render the entire picture using new layers + + SkRect clipBounds; + if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { + continue; + } + + // Find the layers required by this canvas. It will return atlased + // layers in the 'recycled' list since they have already been drawn. + GrLayerHoister::FindLayersToHoist(context, fDrawData[i].picture, + clipBounds, &needRendering, &recycled); + + GrLayerHoister::DrawLayers(context, needRendering); + + GrReplacements replacements; + + GrLayerHoister::ConvertLayersToReplacements(needRendering, &replacements); + GrLayerHoister::ConvertLayersToReplacements(recycled, &replacements); + const SkMatrix initialMatrix = fDrawData[i].canvas->getTotalMatrix(); + // Render the entire picture using new layers GrRecordReplaceDraw(fDrawData[i].picture, fDrawData[i].canvas, &replacements, initialMatrix, NULL); - } else + + GrLayerHoister::UnlockLayers(context, needRendering); + GrLayerHoister::UnlockLayers(context, recycled); + + needRendering.rewind(); + recycled.rewind(); + } else #endif { fDrawData[i].canvas->drawPicture(fDrawData[i].picture, @@ -112,7 +144,8 @@ void SkMultiPictureDraw::draw() { #ifndef SK_IGNORE_GPU_LAYER_HOISTING if (NULL != context) { - GrLayerHoister::UnlockLayers(context, atlased, nonAtlased, recycled); + GrLayerHoister::UnlockLayers(context, atlasedNeedRendering); + GrLayerHoister::UnlockLayers(context, atlasedRecycled); } #endif |