diff options
author | robertphillips <robertphillips@google.com> | 2014-08-21 13:07:35 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-21 13:07:35 -0700 |
commit | 64bf76722ef06eabf51b55afda9f4ff431e41460 (patch) | |
tree | 58da52d1632ccceb83f6f2d8fd9644bfcb053206 /src | |
parent | c92e550d3656abaf83b134b158756b940d58a907 (diff) |
Split up monolithic EXPERIMENTAL_drawPicture method
This is prep for the new multi-picture API.
This is split out of (Add new API to allow layer hoisting/atlasing across picture piles - https://codereview.chromium.org/474623002/)
R=bsalomon@google.com
Author: robertphillips@google.com
Review URL: https://codereview.chromium.org/489103002
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 136 |
1 files changed, 85 insertions, 51 deletions
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index f2bd025a0f..693e16c0e3 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1876,49 +1876,20 @@ static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); } -bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* picture, - const SkMatrix* matrix, const SkPaint* paint) { - // todo: should handle these natively - if (matrix || paint) { - return false; - } - - fContext->getLayerCache()->processDeletedPictures(); - - SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); - - const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); - if (NULL == data) { - return false; - } - - const GrAccelData *gpuData = static_cast<const GrAccelData*>(data); - - if (0 == gpuData->numSaveLayers()) { - return false; - } - - SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); - for (int i = 0; i < gpuData->numSaveLayers(); ++i) { - pullForward[i] = false; - } - - SkRect clipBounds; - if (!mainCanvas->getClipBounds(&clipBounds)) { - return true; - } - SkIRect query; - clipBounds.roundOut(&query); - - SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getActiveOps(query)); - - // This code pre-renders the entire layer since it will be cached and potentially +// Return true if any layers are suitable for hoisting +bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData, + const SkPicture::OperationList* ops, + const SkIRect& query, + bool* pullForward) { + bool anyHoisted = false; + + // Layer hoisting pre-renders the entire layer since it will be cached and potentially // reused with different clips (e.g., in different tiles). Because of this the // clip will not be limiting the size of the pre-rendered layer. kSaveLayerMaxSize // is used to limit which clips are pre-rendered. static const int kSaveLayerMaxSize = 256; - if (NULL != ops.get()) { + if (NULL != ops) { // In this case the picture has been generated with a BBH so we use // the BBH to limit the pre-rendering to just the layers needed to cover // the region being drawn @@ -1928,7 +1899,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture // For now we're saving all the layers in the GrAccelData so they // can be nested. Additionally, the nested layers appear before // their parent in the list. - for (int j = 0 ; j < gpuData->numSaveLayers(); ++j) { + for (int j = 0; j < gpuData->numSaveLayers(); ++j) { const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j); if (pullForward[j]) { @@ -1949,6 +1920,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture } pullForward[j] = true; + anyHoisted = true; } } } else { @@ -1976,9 +1948,53 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture } pullForward[j] = true; + anyHoisted = true; } } + return anyHoisted; +} + +bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* picture, + const SkMatrix* matrix, const SkPaint* paint) { + // todo: should handle these natively + if (matrix || paint) { + return false; + } + + fContext->getLayerCache()->processDeletedPictures(); + + SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); + + const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); + if (NULL == data) { + return false; + } + + const GrAccelData *gpuData = static_cast<const GrAccelData*>(data); + + if (0 == gpuData->numSaveLayers()) { + return false; + } + + SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); + for (int i = 0; i < gpuData->numSaveLayers(); ++i) { + pullForward[i] = false; + } + + SkRect clipBounds; + if (!mainCanvas->getClipBounds(&clipBounds)) { + return true; + } + SkIRect query; + clipBounds.roundOut(&query); + + SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getActiveOps(query)); + + if (!FindLayersToHoist(gpuData, ops.get(), query, pullForward.get())) { + return false; + } + SkPictureReplacementPlayback::PlaybackReplacements replacements; SkTDArray<GrCachedLayer*> atlased, nonAtlased; @@ -2037,13 +2053,28 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture } } + this->drawLayers(picture, atlased, nonAtlased); + + // Render the entire picture using new layers + SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); + + playback.draw(mainCanvas, NULL); + + this->unlockLayers(picture); + + return true; +} + +void SkGpuDevice::drawLayers(const SkPicture* picture, + const SkTDArray<GrCachedLayer*>& atlased, + const SkTDArray<GrCachedLayer*>& nonAtlased) { // Render the atlased layers that require it if (atlased.count() > 0) { // All the atlased layers are rendered into the same GrTexture SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( - atlased[0]->texture()->asRenderTarget(), - SkSurface::kStandard_TextRenderMode, - SkSurface::kDontClear_RenderTargetFlag)); + atlased[0]->texture()->asRenderTarget(), + SkSurface::kStandard_TextRenderMode, + SkSurface::kDontClear_RenderTargetFlag)); SkCanvas* atlasCanvas = surface->getCanvas(); @@ -2091,9 +2122,9 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture // Each non-atlased layer has its own GrTexture SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( - layer->texture()->asRenderTarget(), - SkSurface::kStandard_TextRenderMode, - SkSurface::kDontClear_RenderTargetFlag)); + layer->texture()->asRenderTarget(), + SkSurface::kStandard_TextRenderMode, + SkSurface::kDontClear_RenderTargetFlag)); SkCanvas* layerCanvas = surface->getCanvas(); @@ -2117,17 +2148,22 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture layerCanvas->flush(); } +} - // Render the entire picture using new layers - SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); +void SkGpuDevice::unlockLayers(const SkPicture* picture) { + SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); - playback.draw(mainCanvas, NULL); + const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); + SkASSERT(NULL != data); + + const GrAccelData *gpuData = static_cast<const GrAccelData*>(data); + SkASSERT(0 != gpuData->numSaveLayers()); // unlock the layers for (int i = 0; i < gpuData->numSaveLayers(); ++i) { const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); - GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture->uniqueID(), + GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture->uniqueID(), info.fSaveLayerOpID, info.fRestoreOpID, info.fCTM); @@ -2142,8 +2178,6 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture fContext->getLayerCache()->purgeAll(); #endif - - return true; } SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |