Use glInvalidateFramebuffer() when it is supported.
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 2 Apr 2014 16:19:33 +0000 (16:19 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 2 Apr 2014 16:19:33 +0000 (16:19 +0000)
BUG=skia:1541
R=egdaniel@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/218763006

git-svn-id: http://skia.googlecode.com/svn/trunk@14026 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGLCaps.h
src/gpu/gl/GrGpuGL.cpp

index c4b7c2f..0e836b1 100644 (file)
@@ -23,6 +23,7 @@ void GrGLCaps::reset() {
     fStencilVerifiedColorConfigs.reset();
     fMSFBOType = kNone_MSFBOType;
     fFBFetchType = kNone_FBFetchType;
+    fInvalidateFBType = kNone_InvalidateFBType;
     fMaxFragmentUniformVectors = 0;
     fMaxVertexAttributes = 0;
     fMaxFragmentTextureUnits = 0;
@@ -64,6 +65,7 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
     fMaxFixedFunctionTextureCoords = caps.fMaxFixedFunctionTextureCoords;
     fMSFBOType = caps.fMSFBOType;
     fFBFetchType = caps.fFBFetchType;
+    fInvalidateFBType = caps.fInvalidateFBType;
     fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
     fBGRAFormatSupport = caps.fBGRAFormatSupport;
     fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
@@ -222,7 +224,15 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
         fUseNonVBOVertexAndIndexDynamicData = true;
     }
 
-    fDiscardRenderTargetSupport = ctxInfo.hasExtension("GL_EXT_discard_framebuffer");
+    if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) ||
+        (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) || 
+        ctxInfo.hasExtension("GL_ARB_invalidate_subdata")) {
+        fDiscardRenderTargetSupport = true;
+        fInvalidateFBType = kInvalidate_InvalidateFBType;
+    } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) {
+        fDiscardRenderTargetSupport = true;
+        fInvalidateFBType = kDiscard_InvalidateFBType;
+    }
 
     if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) {
         fFullClearIsFree = true;
@@ -632,11 +642,21 @@ SkString GrGLCaps::dump() const {
     GR_STATIC_ASSERT(2 == kNV_FBFetchType);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFBFetchTypeStr) == kLast_FBFetchType + 1);
 
+    static const char* kInvalidateFBTypeStr[] = {
+        "None",
+        "Discard",
+        "Invalidate",
+    };
+    GR_STATIC_ASSERT(0 == kNone_InvalidateFBType);
+    GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType);
+    GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType);
+    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1);
 
     r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
     r.appendf("Fixed Function Support: %s\n", (fFixedFunctionSupport ? "YES" : "NO"));
     r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
     r.appendf("FB Fetch Type: %s\n", kFBFetchTypeStr[fFBFetchType]);
+    r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
     r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
     r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits);
     if (fFixedFunctionSupport) {
index 21176d1..4cde2bd 100644 (file)
@@ -75,7 +75,15 @@ public:
         /** GL_NV_shader_framebuffer_fetch */
         kNV_FBFetchType,
 
-        kLast_FBFetchType = kNV_FBFetchType,
+        kLast_FBFetchType = kNV_FBFetchType
+    };
+
+    enum InvalidateFBType {
+        kNone_InvalidateFBType,
+        kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
+        kInvalidate_InvalidateFBType,     //<! glInvalidateFramebuffer()
+
+        kLast_InvalidateFBType = kInvalidate_InvalidateFBType
     };
 
     /**
@@ -159,6 +167,8 @@ public:
 
     FBFetchType fbFetchType() const { return fFBFetchType; }
 
+    InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
+
     /**
      * Returs a string containeng the caps info.
      */
@@ -307,9 +317,9 @@ private:
     int fMaxFragmentTextureUnits;
     int fMaxFixedFunctionTextureCoords;
 
-    MSFBOType fMSFBOType;
-
-    FBFetchType fFBFetchType;
+    MSFBOType           fMSFBOType;
+    FBFetchType         fFBFetchType;
+    InvalidateFBType    fInvalidateFBType;
 
     bool fRGBA8RenderbufferSupport : 1;
     bool fBGRAFormatSupport : 1;
index 93adb50..b210433 100644 (file)
@@ -1296,6 +1296,9 @@ void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) {
 }
 
 void GrGpuGL::discard(GrRenderTarget* renderTarget) {
+    if (!this->caps()->discardRenderTargetSupport()) {
+        return;
+    }
     if (NULL == renderTarget) {
         renderTarget = this->drawState()->getRenderTarget();
         if (NULL == renderTarget) {
@@ -1308,8 +1311,31 @@ void GrGpuGL::discard(GrRenderTarget* renderTarget) {
         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));
+    switch (this->glCaps().invalidateFBType()) {
+        case GrGLCaps::kNone_FBFetchType:
+            GrCrash("Should never get here.");
+            break;
+        case GrGLCaps::kInvalidate_InvalidateFBType:
+            if (0 == glRT->renderFBOID()) {
+                //  When rendering to the default framebuffer the legal values for attachments
+                //  are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the various FBO attachment
+                //  types.
+                static const GrGLenum attachments[] = { GR_GL_COLOR };
+                GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
+                        attachments));
+            } else {
+                static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 };
+                GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
+                        attachments));
+            }
+            break;
+        case GrGLCaps::kDiscard_InvalidateFBType: {
+            static const GrGLenum attachments[] = { GR_GL_COLOR };
+            GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
+                    attachments));
+            break;
+        }
+    }
     renderTarget->flagAsResolved();
 }