aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2015-12-16 05:08:27 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-16 05:08:27 -0800
commit7354a4b193aaaeae43fb9ede90e1158fa46c372b (patch)
treeeb9a59b67d46c38dc521e957946949ad7ee55bfb
parent5d16fea9e22221be5fbe2866bbcfe8d6f4c6aeac (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
-rw-r--r--src/core/SkCanvas.cpp36
-rw-r--r--src/gpu/gl/GrGLDefines.h1
-rw-r--r--src/gpu/gl/GrGLUtil.h6
3 files changed, 43 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();
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index f0b56ae989..8374e5cdaf 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -820,6 +820,7 @@
#define GR_GL_STENCIL 0x1802
#define GR_GL_NONE 0
+#define GR_GL_FRAMEBUFFER_DEFAULT 0x8218
#define GR_GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GR_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 70af3a36f4..8a3021cd57 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -81,6 +81,12 @@ enum GrGLDriver {
GR_GL_CALL(gl, GetFramebufferAttachmentParameteriv(t, a, pname, p)); \
} while (0)
+#define GR_GL_GetNamedFramebufferAttachmentParameteriv(gl, fb, a, pname, p) \
+ do { \
+ *(p) = GR_GL_INIT_ZERO; \
+ GR_GL_CALL(gl, GetNamedFramebufferAttachmentParameteriv(fb, a, pname, p)); \
+ } while (0)
+
#define GR_GL_GetRenderbufferParameteriv(gl, t, pname, p) \
do { \
*(p) = GR_GL_INIT_ZERO; \