diff options
author | robertphillips <robertphillips@google.com> | 2015-12-16 05:08:27 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-16 05:08:27 -0800 |
commit | 7354a4b193aaaeae43fb9ede90e1158fa46c372b (patch) | |
tree | eb9a59b67d46c38dc521e957946949ad7ee55bfb /src/core | |
parent | 5d16fea9e22221be5fbe2866bbcfe8d6f4c6aeac (diff) |
Avoid pixel GPU readback in saveLayerWithPickup
When the default framebuffer is wrapped in a device for rendering we don't get a GrTexture. This CL adds a copy to a temporary texture in this instance so the rest of the Ganesh pipeline can continue on as usual.
Review URL: https://codereview.chromium.org/1531493002
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkCanvas.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 1d37e58419..814375687a 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -37,7 +37,9 @@ #include <new> #if SK_SUPPORT_GPU +#include "GrContext.h" #include "GrRenderTarget.h" +#include "SkGr.h" #endif /* @@ -1145,6 +1147,35 @@ int SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPai return this->saveLayer(bounds, paint, (SaveFlags)flags); } +static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, SkBaseDevice* dst) { + + SkBitmap srcBM; + +#if SK_SUPPORT_GPU + GrRenderTarget* srcRT = src->accessRenderTarget(); + if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) { + // When both the src & the dst are on the gpu but the src doesn't have a texture, + // we create a temporary texture for the draw. + // TODO: we should actually only copy the portion of the source needed to apply the image + // filter + GrContext* context = srcRT->getContext(); + SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(srcRT->desc(), true)); + + context->copySurface(tex, srcRT); + + GrWrapTextureInBitmap(tex, src->width(), src->height(), src->isOpaque(), &srcBM); + } else +#endif + { + srcBM = src->accessBitmap(false); + } + + SkCanvas c(dst); + + SkPaint p; + p.setImageFilter(filter); + c.drawBitmap(srcBM, 0, 0, &p); +} void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, SaveLayerStrategy strategy) { @@ -1210,6 +1241,11 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav } device->setOrigin(ir.fLeft, ir.fTop); + + if (0) { + draw_filter_into_device(fMCRec->fTopLayer->fDevice, nullptr, device); + } + DeviceCM* layer = new DeviceCM(device, paint, this, fConservativeRasterClip, forceSpriteOnRestore); device->unref(); |