aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-03-28 16:08:05 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-03-28 16:08:05 +0000
commit28361fad1054d59ed4e6a320c7a8b8782a1487c7 (patch)
tree77f1c92c7524c79802157e152429b14cf1e81d06 /src/gpu
parentba0c5ea90d0e6b2e8b20696e54fea13ead6dda93 (diff)
Add discard API to SkCanvas, plumb it to glDiscardFramebuffer()
BUG=skia:2349 R=robertphillips@google.com, reed@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/211683002 git-svn-id: http://skia.googlecode.com/svn/trunk@13976 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrContext.cpp8
-rw-r--r--src/gpu/GrDrawTarget.cpp37
-rw-r--r--src/gpu/GrDrawTarget.h6
-rw-r--r--src/gpu/GrDrawTargetCaps.h2
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp27
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h5
-rw-r--r--src/gpu/GrRenderTarget.cpp9
-rw-r--r--src/gpu/gl/GrGLCaps.cpp5
-rw-r--r--src/gpu/gl/GrGLCaps.h4
-rw-r--r--src/gpu/gl/GrGLDefines.h5
-rw-r--r--src/gpu/gl/GrGpuGL.cpp19
-rw-r--r--src/gpu/gl/GrGpuGL.h2
12 files changed, 99 insertions, 30 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 3a2bbe864c..c26327eecf 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1440,6 +1440,14 @@ void GrContext::resolveRenderTarget(GrRenderTarget* target) {
fGpu->resolveRenderTarget(target);
}
+void GrContext::discardRenderTarget(GrRenderTarget* target) {
+ SkASSERT(target);
+ ASSERT_OWNED_RESOURCE(target);
+ AutoRestoreEffects are;
+ AutoCheckFlush acf(this);
+ this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->discard(target);
+}
+
void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) {
if (NULL == src || NULL == dst) {
return;
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 8d3ded2d65..10698442b2 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -1019,6 +1019,7 @@ void GrDrawTargetCaps::reset() {
fBufferLockSupport = false;
fPathRenderingSupport = false;
fDstReadInShaderSupport = false;
+ fDiscardRenderTargetSupport = false;
fReuseScratchTextures = true;
fGpuTracingSupport = false;
@@ -1042,6 +1043,7 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
fBufferLockSupport = other.fBufferLockSupport;
fPathRenderingSupport = other.fPathRenderingSupport;
fDstReadInShaderSupport = other.fDstReadInShaderSupport;
+ fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport;
fReuseScratchTextures = other.fReuseScratchTextures;
fGpuTracingSupport = other.fGpuTracingSupport;
@@ -1057,23 +1059,24 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
SkString GrDrawTargetCaps::dump() const {
SkString r;
static const char* gNY[] = {"NO", "YES"};
- r.appendf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]);
- r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
- r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
- r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
- r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
- r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
- r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
- r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
- r.appendf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
- r.appendf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
- r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
- r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
- r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
- r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
- r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
- r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
- r.appendf("Max Sample Count : %d\n", fMaxSampleCount);
+ r.appendf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]);
+ r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
+ r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
+ r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
+ r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
+ r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
+ r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
+ r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
+ r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
+ r.appendf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
+ r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
+ r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
+ r.appendf("Discard Render Target Support: %s\n", gNY[fDiscardRenderTargetSupport]);
+ r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
+ r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
+ r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
+ r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
+ r.appendf("Max Sample Count : %d\n", fMaxSampleCount);
static const char* kConfigNames[] = {
"Unknown", // kUnknown_GrPixelConfig
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 5b26ff5d56..6b3d4637cc 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -438,6 +438,12 @@ public:
GrRenderTarget* renderTarget = NULL) = 0;
/**
+ * Discards the contents render target. NULL indicates that the current render target should
+ * be discarded.
+ **/
+ virtual void discard(GrRenderTarget* = NULL) = 0;
+
+ /**
* Called at start and end of gpu trace marking
* GR_CREATE_GPU_TRACE_MARKER(marker_str, target) will automatically call these at the start
* and end of a code block respectively
diff --git a/src/gpu/GrDrawTargetCaps.h b/src/gpu/GrDrawTargetCaps.h
index b33217a125..a77bce4430 100644
--- a/src/gpu/GrDrawTargetCaps.h
+++ b/src/gpu/GrDrawTargetCaps.h
@@ -40,6 +40,7 @@ public:
bool bufferLockSupport() const { return fBufferLockSupport; }
bool pathRenderingSupport() const { return fPathRenderingSupport; }
bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
+ bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
bool gpuTracingSupport() const { return fGpuTracingSupport; }
// Scratch textures not being reused means that those scratch textures
@@ -71,6 +72,7 @@ protected:
bool fBufferLockSupport : 1;
bool fPathRenderingSupport : 1;
bool fDstReadInShaderSupport : 1;
+ bool fDiscardRenderTargetSupport: 1;
bool fReuseScratchTextures : 1;
bool fGpuTracingSupport : 1;
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 178df7553a..8d34e6cf76 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -504,6 +504,7 @@ void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color,
rect = &r;
}
Clear* clr = this->recordClear();
+ GrColorIsPMAssert(color);
clr->fColor = color;
clr->fRect = *rect;
clr->fCanIgnoreRect = canIgnoreRect;
@@ -511,6 +512,20 @@ void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color,
renderTarget->ref();
}
+void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
+ if (!this->caps()->discardRenderTargetSupport()) {
+ return;
+ }
+ if (NULL == renderTarget) {
+ renderTarget = this->drawState()->getRenderTarget();
+ SkASSERT(NULL != renderTarget);
+ }
+ Clear* clr = this->recordClear();
+ clr->fColor = GrColor_ILLEGAL;
+ clr->fRenderTarget = renderTarget;
+ renderTarget->ref();
+}
+
void GrInOrderDrawBuffer::reset() {
SkASSERT(1 == fGeoPoolStateStack.count());
this->resetVertexSource();
@@ -630,10 +645,14 @@ void GrInOrderDrawBuffer::flush() {
++currClip;
break;
case kClear_Cmd:
- fDstGpu->clear(&fClears[currClear].fRect,
- fClears[currClear].fColor,
- fClears[currClear].fCanIgnoreRect,
- fClears[currClear].fRenderTarget);
+ if (GrColor_ILLEGAL == fClears[currClear].fColor) {
+ fDstGpu->discard(fClears[currClear].fRenderTarget);
+ } else {
+ fDstGpu->clear(&fClears[currClear].fRect,
+ fClears[currClear].fColor,
+ fClears[currClear].fCanIgnoreRect,
+ fClears[currClear].fRenderTarget);
+ }
++currClear;
break;
case kCopySurface_Cmd:
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 72d0f9656e..0e0c57db3f 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -72,7 +72,9 @@ public:
virtual void clear(const SkIRect* rect,
GrColor color,
bool canIgnoreRect,
- GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
+ GrRenderTarget* renderTarget) SK_OVERRIDE;
+
+ virtual void discard(GrRenderTarget*) SK_OVERRIDE;
virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
@@ -125,6 +127,7 @@ private:
GrDeviceCoordTexture fDstCopy;
};
+ // This is also used to record a discard by setting the color to GrColor_ILLEGAL
struct Clear : public ::SkNoncopyable {
Clear() : fRenderTarget(NULL) {}
~Clear() { SkSafeUnref(fRenderTarget); }
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index f18df2cfa6..729aa0d469 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -54,6 +54,15 @@ void GrRenderTarget::resolve() {
context->resolveRenderTarget(this);
}
+void GrRenderTarget::discard() {
+ // go through context so that all necessary flushing occurs
+ GrContext* context = this->getContext();
+ if (NULL == context) {
+ return;
+ }
+ context->discardRenderTarget(this);
+}
+
size_t GrRenderTarget::sizeInBytes() const {
size_t colorBits;
if (kUnknown_GrPixelConfig == fDesc.fConfig) {
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 47f3f0f0c8..bf7939ccee 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -45,7 +45,6 @@ void GrGLCaps::reset() {
fUseNonVBOVertexAndIndexDynamicData = false;
fIsCoreProfile = false;
fFixedFunctionSupport = false;
- fDiscardFBSupport = false;
fFullClearIsFree = false;
fDropsTileOnZeroDivide = false;
}
@@ -83,7 +82,6 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
fUseNonVBOVertexAndIndexDynamicData = caps.fUseNonVBOVertexAndIndexDynamicData;
fIsCoreProfile = caps.fIsCoreProfile;
fFixedFunctionSupport = caps.fFixedFunctionSupport;
- fDiscardFBSupport = caps.fDiscardFBSupport;
fFullClearIsFree = caps.fFullClearIsFree;
fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
@@ -224,7 +222,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
fUseNonVBOVertexAndIndexDynamicData = true;
}
- fDiscardFBSupport = ctxInfo.hasExtension("GL_EXT_discard_framebuffer");
+ fDiscardRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_discard_framebuffer");
if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
fFullClearIsFree = true;
@@ -664,7 +662,6 @@ SkString GrGLCaps::dump() const {
r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
r.appendf("Use non-VBO for dynamic data: %s\n",
(fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
- r.appendf("Discard FrameBuffer support: %s\n", (fDiscardFBSupport ? "YES" : "NO"));
r.appendf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO"));
r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO"));
return r;
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 0939f80c26..21176d16dd 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -245,9 +245,6 @@ public:
bool fixedFunctionSupport() const { return fFixedFunctionSupport; }
- /// Is there support for discarding the frame buffer
- bool discardFBSupport() const { return fDiscardFBSupport; }
-
bool fullClearIsFree() const { return fFullClearIsFree; }
bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
@@ -332,7 +329,6 @@ private:
bool fUseNonVBOVertexAndIndexDynamicData : 1;
bool fIsCoreProfile : 1;
bool fFixedFunctionSupport : 1;
- bool fDiscardFBSupport : 1;
bool fFullClearIsFree : 1;
bool fDropsTileOnZeroDivide : 1;
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 0dbd425f0d..a4dc2f782b 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -691,6 +691,11 @@
#define GR_GL_DEPTH_ATTACHMENT 0x8D00
#define GR_GL_STENCIL_ATTACHMENT 0x8D20
+// GL_EXT_discard_framebuffer
+#define GR_GL_COLOR 0x1800
+#define GR_GL_DEPTH 0x1801
+#define GR_GL_STENCIL 0x1802
+
#define GR_GL_NONE 0
#define GR_GL_FRAMEBUFFER_COMPLETE 0x8CD5
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index dc2ef7d84e..78bf8f91cf 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1295,6 +1295,25 @@ void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) {
GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
}
+void GrGpuGL::discard(GrRenderTarget* renderTarget) {
+ if (NULL == renderTarget) {
+ renderTarget = this->drawState()->getRenderTarget();
+ if (NULL == renderTarget) {
+ return;
+ }
+ }
+
+ GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
+ if (renderTarget != fHWBoundRenderTarget) {
+ fHWBoundRenderTarget = NULL;
+ GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID()));
+ }
+ GrGLenum attachments[] = { GR_GL_COLOR };
+ GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments), attachments));
+ renderTarget->flagAsResolved();
+}
+
+
void GrGpuGL::clearStencil() {
if (NULL == this->getDrawState().getRenderTarget()) {
return;
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 6a895750c5..e173aeff71 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -40,6 +40,8 @@ public:
GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
+ virtual void discard(GrRenderTarget*) SK_OVERRIDE;
+
// Used by GrGLProgram and GrGLTexGenProgramEffects to configure OpenGL state.
void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
void setProjectionMatrix(const SkMatrix& matrix,