diff options
author | robertphillips <robertphillips@google.com> | 2014-09-18 12:03:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-18 12:03:15 -0700 |
commit | 1c4c528c2a5693c88ceb94888c747559c6a32091 (patch) | |
tree | 8c495bbd520afc5db964e7e76db7339ce71a4651 /src/gpu | |
parent | 0d276f71d2cf30f4a282cd4f470084c6b42c6af2 (diff) |
Refactor layer hoisting code
This CL consolidates the layer hoisting functionality in GrLayerHoister in preparation for retiring SkDpuDevice::EXPERIMENTAL_drawPicture in favor of SkMultiPictureDraw::draw.
R=bsalomon@google.com
Author: robertphillips@google.com
Review URL: https://codereview.chromium.org/580173002
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrLayerHoister.cpp | 88 | ||||
-rw-r--r-- | src/gpu/GrLayerHoister.h | 24 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 82 |
3 files changed, 105 insertions, 89 deletions
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp index a29d91ac9d..aa9576b675 100644 --- a/src/gpu/GrLayerHoister.cpp +++ b/src/gpu/GrLayerHoister.cpp @@ -9,12 +9,16 @@ #include "GrLayerHoister.h" #include "SkCanvas.h" #include "SkRecordDraw.h" +#include "GrRecordReplaceDraw.h" +#include "SkGrPixelRef.h" #include "SkSurface.h" // Return true if any layers are suitable for hoisting bool GrLayerHoister::FindLayersToHoist(const GrAccelData *gpuData, const SkRect& query, - bool pullForward[]) { + SkTDArray<GrCachedLayer*>* atlased, + SkTDArray<GrCachedLayer*>* nonAtlased, + GrLayerCache* layerCache) { bool anyHoisted = false; // Layer hoisting pre-renders the entire layer since it will be cached and potentially @@ -23,6 +27,8 @@ bool GrLayerHoister::FindLayersToHoist(const GrAccelData *gpuData, // is used to limit which clips are pre-rendered. static const int kSaveLayerMaxSize = 256; + SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); + // Pre-render all the layers that intersect the query rect for (int i = 0; i < gpuData->numSaveLayers(); ++i) { pullForward[i] = false; @@ -51,12 +57,87 @@ bool GrLayerHoister::FindLayersToHoist(const GrAccelData *gpuData, anyHoisted = true; } + if (!anyHoisted) { + return false; + } + + atlased->setReserve(atlased->reserved() + gpuData->numSaveLayers()); + + // Generate the layer and/or ensure it is locked + for (int i = 0; i < gpuData->numSaveLayers(); ++i) { + if (pullForward[i]) { + const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); + + GrCachedLayer* layer = layerCache->findLayerOrCreate(info.fPictureID, + info.fSaveLayerOpID, + info.fRestoreOpID, + info.fOffset, + info.fOriginXform, + info.fPaint); + + GrTextureDesc desc; + desc.fFlags = kRenderTarget_GrTextureFlagBit; + desc.fWidth = info.fSize.fWidth; + desc.fHeight = info.fSize.fHeight; + desc.fConfig = kSkia8888_GrPixelConfig; + // TODO: need to deal with sample count + + bool needsRendering = layerCache->lock(layer, desc, + info.fHasNestedLayers || info.fIsNested); + if (NULL == layer->texture()) { + continue; + } + + if (needsRendering) { + if (layer->isAtlased()) { + *atlased->append() = layer; + } else { + *nonAtlased->append() = layer; + } + } + } + } + return anyHoisted; } +static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) { + SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); + result->setInfo(info); + result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); +} + +static void convert_layers_to_replacements(const SkTDArray<GrCachedLayer*>& layers, + GrReplacements* replacements) { + // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? + for (int i = 0; i < layers.count(); ++i) { + GrReplacements::ReplacementInfo* layerInfo = replacements->push(); + layerInfo->fStart = layers[i]->start(); + layerInfo->fStop = layers[i]->stop(); + layerInfo->fPos = layers[i]->offset();; + + SkBitmap bm; + wrap_texture(layers[i]->texture(), + !layers[i]->isAtlased() ? layers[i]->rect().width() + : layers[i]->texture()->width(), + !layers[i]->isAtlased() ? layers[i]->rect().height() + : layers[i]->texture()->height(), + &bm); + layerInfo->fImage = SkImage::NewTexture(bm); + + layerInfo->fPaint = layers[i]->paint() ? SkNEW_ARGS(SkPaint, (*layers[i]->paint())) : NULL; + + layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i]->rect().fLeft, + layers[i]->rect().fTop, + layers[i]->rect().width(), + layers[i]->rect().height()); + } +} + void GrLayerHoister::DrawLayers(const SkPicture* picture, const SkTDArray<GrCachedLayer*>& atlased, - const SkTDArray<GrCachedLayer*>& nonAtlased) { + const SkTDArray<GrCachedLayer*>& nonAtlased, + GrReplacements* replacements) { // Render the atlased layers that require it if (atlased.count() > 0) { // All the atlased layers are rendered into the same GrTexture @@ -146,6 +227,9 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture, layerCanvas->flush(); } + + convert_layers_to_replacements(atlased, replacements); + convert_layers_to_replacements(nonAtlased, replacements); } void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, const SkPicture* picture) { diff --git a/src/gpu/GrLayerHoister.h b/src/gpu/GrLayerHoister.h index 4116aef84d..a3b97e328a 100644 --- a/src/gpu/GrLayerHoister.h +++ b/src/gpu/GrLayerHoister.h @@ -13,6 +13,7 @@ class GrAccelData; struct GrCachedLayer; +class GrReplacements; struct SkRect; // This class collects the layer hoisting functionality in one place. @@ -23,25 +24,30 @@ struct SkRect; class GrLayerHoister { public: /** Find the layers in 'gpuData' that need hoisting. - @param gpuData Acceleration structure containing layer information for a picture - @param query The rectangle that is about to be drawn. - @param pullForward A gpuData->numSaveLayers -sized Boolean array indicating - which layers are to be hoisted + @param gpuData Acceleration structure containing layer information for a picture + @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 layerCache The source of new layers Return true if any layers are suitable for hoisting; false otherwise */ static bool FindLayersToHoist(const GrAccelData *gpuData, const SkRect& query, - bool pullForward[]); + SkTDArray<GrCachedLayer*>* altased, + SkTDArray<GrCachedLayer*>* nonAtlased, + GrLayerCache* layerCache); /** Draw the specified layers of 'picture' into either the atlas or free floating textures. - @param picture The picture containing the layers - @param atlased The layers to be drawn into the atlas - @param nonAtlased The layers to be drawn into their own textures + @param picture The picture containing the layers + @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 */ static void DrawLayers(const SkPicture* picture, const SkTDArray<GrCachedLayer*>& atlased, - const SkTDArray<GrCachedLayer*>& nonAtlased); + const SkTDArray<GrCachedLayer*>& nonAtlased, + GrReplacements* replacements); /** Unlock all the layers associated with picture in the layer cache. @param layerCache holder of the locked layers diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 25ab12243d..02dca83ee0 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1836,39 +1836,6 @@ void SkGpuDevice::EXPERIMENTAL_optimize(const SkPicture* picture) { fContext->getLayerCache()->trackPicture(picture); } -static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) { - SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); - result->setInfo(info); - result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); -} - -static void convert_layers_to_replacements(const SkTDArray<GrCachedLayer*>& layers, - GrReplacements* replacements) { - // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer? - for (int i = 0; i < layers.count(); ++i) { - GrReplacements::ReplacementInfo* layerInfo = replacements->push(); - layerInfo->fStart = layers[i]->start(); - layerInfo->fStop = layers[i]->stop(); - layerInfo->fPos = layers[i]->offset();; - - SkBitmap bm; - wrap_texture(layers[i]->texture(), - !layers[i]->isAtlased() ? layers[i]->rect().width() - : layers[i]->texture()->width(), - !layers[i]->isAtlased() ? layers[i]->rect().height() - : layers[i]->texture()->height(), - &bm); - layerInfo->fImage = SkImage::NewTexture(bm); - - layerInfo->fPaint = layers[i]->paint() ? SkNEW_ARGS(SkPaint, (*layers[i]->paint())) : NULL; - - layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i]->rect().fLeft, - layers[i]->rect().fTop, - layers[i]->rect().width(), - layers[i]->rect().height()); - } -} - bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { // todo: should handle these natively @@ -1886,66 +1853,25 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture } const GrAccelData *gpuData = static_cast<const GrAccelData*>(data); - if (0 == gpuData->numSaveLayers()) { return false; } - SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); - SkRect clipBounds; if (!mainCanvas->getClipBounds(&clipBounds)) { return true; } - if (!GrLayerHoister::FindLayersToHoist(gpuData, clipBounds, pullForward.get())) { - return false; - } - SkTDArray<GrCachedLayer*> atlased, nonAtlased; - atlased.setReserve(gpuData->numSaveLayers()); - - // Generate the layer and/or ensure it is locked - for (int i = 0; i < gpuData->numSaveLayers(); ++i) { - if (pullForward[i]) { - const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); - - GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(), - info.fSaveLayerOpID, - info.fRestoreOpID, - info.fOffset, - info.fOriginXform, - info.fPaint); - - GrTextureDesc desc; - desc.fFlags = kRenderTarget_GrTextureFlagBit; - desc.fWidth = info.fSize.fWidth; - desc.fHeight = info.fSize.fHeight; - desc.fConfig = kSkia8888_GrPixelConfig; - // TODO: need to deal with sample count - - bool needsRendering = fContext->getLayerCache()->lock(layer, desc, - info.fHasNestedLayers || info.fIsNested); - if (NULL == layer->texture()) { - continue; - } - if (needsRendering) { - if (layer->isAtlased()) { - *atlased.append() = layer; - } else { - *nonAtlased.append() = layer; - } - } - } + if (!GrLayerHoister::FindLayersToHoist(gpuData, clipBounds, &atlased, &nonAtlased, + fContext->getLayerCache())) { + return false; } - GrLayerHoister::DrawLayers(picture, atlased, nonAtlased); - GrReplacements replacements; - convert_layers_to_replacements(atlased, &replacements); - convert_layers_to_replacements(nonAtlased, &replacements); + GrLayerHoister::DrawLayers(picture, atlased, nonAtlased, &replacements); // Render the entire picture using new layers GrRecordReplaceDraw(*picture->fRecord, mainCanvas, picture->fBBH.get(), &replacements, NULL); |