Bug 953221 - Split out DRAW_BUFFER/READ_BUFFER state setup. r=bjacob
authorDan Glastonbury <dglastonbury@mozilla.com>
Fri, 24 Jan 2014 14:02:07 +1000
changeset 181622 59c788a177d22b527f495d04dba5883add3815a4
parent 181621 235034a27f3c15519868bb44aadf3c0d675d1c36
child 181623 ef07214e11ff91bc9d406e0049621a4ce22db25d
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs953221
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 953221 - Split out DRAW_BUFFER/READ_BUFFER state setup. r=bjacob
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLFramebuffer.cpp
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -201,28 +201,16 @@ WebGLContext::BindFramebuffer(GLenum tar
     // silently ignore a deleted frame buffer
     if (wfb && wfb->IsDeleted())
         return;
 
     MakeContextCurrent();
 
     if (!wfb) {
         gl->fBindFramebuffer(target, 0);
-
-        // Restore draw/read buffers when switching back to default
-        // render target.
-        GLint drawBuffer = LOCAL_GL_COLOR_ATTACHMENT0;
-        gl->fGetIntegerv(LOCAL_GL_DRAW_BUFFER, &drawBuffer);
-        if (drawBuffer == LOCAL_GL_NONE)
-            gl->fDrawBuffer(LOCAL_GL_COLOR_ATTACHMENT0);
-
-        GLint readBuffer = LOCAL_GL_COLOR_ATTACHMENT0;
-        gl->fGetIntegerv(LOCAL_GL_READ_BUFFER, &readBuffer);
-        if (readBuffer == LOCAL_GL_NONE)
-            gl->fReadBuffer(LOCAL_GL_COLOR_ATTACHMENT0);
     } else {
         GLuint framebuffername = wfb->GLName();
         gl->fBindFramebuffer(target, framebuffername);
         wfb->SetHasEverBeenBound(true);
     }
 
     mBoundFramebuffer = wfb;
 }
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -714,37 +714,62 @@ void WebGLFramebuffer::EnsureColorAttach
 
     mColorAttachments.SetLength(colorAttachmentId + 1);
 
     for (size_t i = colorAttachmentId; i >= currentAttachmentCount; i--) {
         mColorAttachments[i].mAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0 + i;
     }
 }
 
+static void
+FinalizeDrawAndReadBuffers(GLContext* aGL, bool aColorBufferDefined)
+{
+    MOZ_ASSERT(aGL, "Expected a valid GLContext ptr.");
+    // GLES don't support DrawBuffer()/ReadBuffer.
+    // According to http://www.opengl.org/wiki/Framebuffer_Object
+    //
+    // Each draw buffers must either specify color attachment points that have images
+    // attached or must be GL_NONE​. (GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER​ when false).
+    //
+    // If the read buffer is set, then it must specify an attachment point that has an
+    // image attached. (GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER​ when false).
+    //
+    // Note that this test is not performed if OpenGL 4.2 or ARB_ES2_compatibility is
+    // available.
+    if (aGL->IsGLES2() ||
+        aGL->IsSupported(GLFeature::ES2_compatibility) ||
+        aGL->IsAtLeast(ContextProfile::OpenGL, 420))
+    {
+        return;
+    }
+
+    // TODO(djg): Assert that fDrawBuffer/fReadBuffer is not NULL.
+    GLenum colorBufferSource = aColorBufferDefined ? LOCAL_GL_COLOR_ATTACHMENT0 : LOCAL_GL_NONE;
+    aGL->fDrawBuffer(colorBufferSource);
+    aGL->fReadBuffer(colorBufferSource);
+}
+
 void
 WebGLFramebuffer::FinalizeAttachments() const
 {
     for (size_t i = 0; i < ColorAttachmentCount(); i++) {
         if (ColorAttachment(i).IsDefined())
             ColorAttachment(i).FinalizeAttachment(LOCAL_GL_COLOR_ATTACHMENT0 + i);
     }
 
-    GLenum colorBufferSource =
-        ColorAttachment(0).IsDefined() ? LOCAL_GL_COLOR_ATTACHMENT0 : LOCAL_GL_NONE;
-    mContext->gl->fDrawBuffer(colorBufferSource);
-    mContext->gl->fReadBuffer(colorBufferSource);
-
     if (DepthAttachment().IsDefined())
         DepthAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_ATTACHMENT);
 
     if (StencilAttachment().IsDefined())
         StencilAttachment().FinalizeAttachment(LOCAL_GL_STENCIL_ATTACHMENT);
 
     if (DepthStencilAttachment().IsDefined())
         DepthStencilAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
+
+    FinalizeDrawAndReadBuffers(mContext->gl, ColorAttachment(0).IsDefined());
 }
 
 inline void
 ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::Attachment& aField)
 {
     aField.mTexturePtr = nullptr;
     aField.mRenderbufferPtr = nullptr;
 }