Bug 1016086 - Part 2: Save/restore attribute state in blit helper (r=Bas)
authorAndreas Gal <gal@mozilla.com>
Thu, 29 May 2014 10:19:48 -0400
changeset 185627 97a6db3c8b0ef895702cd025327241b11d99902b
parent 185626 5b455e3d326142b3eaf4feae108d7e183d300f88
child 185628 811e55feb157120088fb6444cb38463d89c1c8b6
push id26859
push userkwierso@gmail.com
push dateFri, 30 May 2014 00:35:41 +0000
treeherderautoland@9164a6ab85b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1016086
milestone32.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 1016086 - Part 2: Save/restore attribute state in blit helper (r=Bas)
gfx/gl/GLBlitTextureImageHelper.cpp
gfx/gl/ScopedGLHelpers.cpp
gfx/gl/ScopedGLHelpers.h
--- a/gfx/gl/GLBlitTextureImageHelper.cpp
+++ b/gfx/gl/GLBlitTextureImageHelper.cpp
@@ -141,36 +141,24 @@ GLBlitTextureImageHelper::BlitTextureIma
                 for (unsigned int i = 0; i < coords.Length(); ++i) {
                     coords[i].x = (coords[i].x * (dx1 - dx0)) + dx0;
                     coords[i].y = (coords[i].y * (dy1 - dy0)) + dy0;
                 }
             }
 
             ScopedBindTextureUnit autoTexUnit(mGL, LOCAL_GL_TEXTURE0);
             ScopedBindTexture autoTex(mGL, aSrc->GetTextureID());
-
-            mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-
-            mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.vertCoords().Elements());
-            mGL->fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.texCoords().Elements());
-
-            mGL->fEnableVertexAttribArray(0);
-            mGL->fEnableVertexAttribArray(1);
+            ScopedVertexAttribPointer autoAttrib0(mGL, 0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0, rects.vertCoords().Elements());
+            ScopedVertexAttribPointer autoAttrib1(mGL, 1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0, rects.texCoords().Elements());
 
             mGL->fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
 
-            mGL->fDisableVertexAttribArray(0);
-            mGL->fDisableVertexAttribArray(1);
-
         } while (aSrc->NextTile());
     } while (aDst->NextTile());
 
-    mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, nullptr);
-    mGL->fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, nullptr);
-
     // unbind the previous texture from the framebuffer
     SetBlitFramebufferForDestTexture(0);
 
     mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, savedFb);
 }
 
 void
 GLBlitTextureImageHelper::SetBlitFramebufferForDestTexture(GLuint aTexture)
--- a/gfx/gl/ScopedGLHelpers.cpp
+++ b/gfx/gl/ScopedGLHelpers.cpp
@@ -325,10 +325,81 @@ ScopedScissorRect::ScopedScissorRect(GLC
 void ScopedScissorRect::UnwrapImpl()
 {
   mGL->fScissor(mSavedScissorRect[0],
                 mSavedScissorRect[1],
                 mSavedScissorRect[2],
                 mSavedScissorRect[3]);
 }
 
+/* ScopedVertexAttribPointer **************************************************/
+
+ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
+                                                     GLuint index,
+                                                     GLint size,
+                                                     GLenum type,
+                                                     realGLboolean normalized,
+                                                     GLsizei stride,
+                                                     GLuint buffer,
+                                                     const GLvoid* pointer)
+    : ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
+{
+    WrapImpl(index);
+    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, buffer);
+    mGL->fVertexAttribPointer(index, size, type, normalized, stride, pointer);
+    mGL->fEnableVertexAttribArray(index);
+}
+
+ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
+                                                     GLuint index)
+    : ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
+{
+    WrapImpl(index);
+}
+
+void
+ScopedVertexAttribPointer::WrapImpl(GLuint index)
+{
+    mAttribIndex = index;
+
+    /*
+     * mGL->fGetVertexAttribiv takes:
+     *  VERTEX_ATTRIB_ARRAY_ENABLED
+     *  VERTEX_ATTRIB_ARRAY_SIZE,
+     *  VERTEX_ATTRIB_ARRAY_STRIDE,
+     *  VERTEX_ATTRIB_ARRAY_TYPE,
+     *  VERTEX_ATTRIB_ARRAY_NORMALIZED,
+     *  VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
+     *  CURRENT_VERTEX_ATTRIB
+     *
+     * CURRENT_VERTEX_ATTRIB is vertex shader state. \o/
+     * Others appear to be vertex array state,
+     * or alternatively in the internal vertex array state
+     * for a buffer object.
+    */
+
+    mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &mAttribEnabled);
+    mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &mAttribSize);
+    mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, &mAttribStride);
+    mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, &mAttribType);
+    mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &mAttribNormalized);
+    mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &mAttribBufferBinding);
+    mGL->fGetVertexAttribPointerv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &mAttribPointer);
+
+    // Note that uniform values are program state, so we don't need to rebind those.
+
+    mGL->GetUIntegerv(LOCAL_GL_ARRAY_BUFFER_BINDING, &mBoundBuffer);
+}
+
+void
+ScopedVertexAttribPointer::UnwrapImpl()
+{
+    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mAttribBufferBinding);
+    mGL->fVertexAttribPointer(mAttribIndex, mAttribSize, mAttribType, mAttribNormalized, mAttribStride, mAttribPointer);
+    if (mAttribEnabled)
+        mGL->fEnableVertexAttribArray(mAttribIndex);
+    else
+        mGL->fDisableVertexAttribArray(mAttribIndex);
+    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundBuffer);
+}
+
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/ScopedGLHelpers.h
+++ b/gfx/gl/ScopedGLHelpers.h
@@ -272,12 +272,38 @@ protected:
 public:
     ScopedScissorRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height);
     explicit ScopedScissorRect(GLContext* aGL);
 
 protected:
     void UnwrapImpl();
 };
 
+struct ScopedVertexAttribPointer
+    : public ScopedGLWrapper<ScopedVertexAttribPointer>
+{
+    friend struct ScopedGLWrapper<ScopedVertexAttribPointer>;
+
+protected:
+    GLuint mAttribIndex;
+    GLint mAttribEnabled;
+    GLint mAttribSize;
+    GLint mAttribStride;
+    GLint mAttribType;
+    GLint mAttribNormalized;
+    GLint mAttribBufferBinding;
+    void* mAttribPointer;
+    GLuint mBoundBuffer;
+
+public:
+    ScopedVertexAttribPointer(GLContext* aGL, GLuint index, GLint size, GLenum type, realGLboolean normalized,
+                              GLsizei stride, GLuint buffer, const GLvoid* pointer);
+    explicit ScopedVertexAttribPointer(GLContext* aGL, GLuint index);
+
+protected:
+    void WrapImpl(GLuint index);
+    void UnwrapImpl();
+};
+
 } /* namespace gl */
 } /* namespace mozilla */
 
 #endif /* SCOPEDGLHELPERS_H_ */