Bug 1396704 - Support GLBlitHelper without VAOs. - r=daoshengmu draft
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 05 Sep 2017 17:34:22 -0700
changeset 659399 0ef47a952dfe955b3ba604365dd529b4a5ac0ed8
parent 659233 973e8b890a62aee4b3170558ac3b608928162ef6
child 729984 a793078b42d5ce5e57625d9435ed3a9412119d8d
push id78123
push userbmo:jgilbert@mozilla.com
push dateWed, 06 Sep 2017 00:36:00 +0000
reviewersdaoshengmu
bugs1396704
milestone57.0a1
Bug 1396704 - Support GLBlitHelper without VAOs. - r=daoshengmu MozReview-Commit-ID: HB5p6Kt0zTb
gfx/gl/GLBlitHelper.cpp
gfx/gl/GLBlitHelper.h
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -180,37 +180,16 @@ public:
     ~ScopedBindArrayBuffer()
     {
         mGL.fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mOldVBO);
     }
 };
 
 // --
 
-class ScopedBindVAO final
-{
-    GLContext& mGL;
-    const GLuint mOldVAO;
-
-public:
-    ScopedBindVAO(GLContext* const gl, const GLuint vao)
-        : mGL(*gl)
-        , mOldVAO(mGL.GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING))
-    {
-        mGL.fBindVertexArray(vao);
-    }
-
-    ~ScopedBindVAO()
-    {
-        mGL.fBindVertexArray(mOldVAO);
-    }
-};
-
-// --
-
 class ScopedShader final
 {
     GLContext& mGL;
     const GLuint mName;
 
 public:
     ScopedShader(GLContext* const gl, const GLenum shaderType)
         : mGL(*gl)
@@ -362,56 +341,96 @@ DrawBlitProg::Draw(const BaseArgs& args,
         gl->fUniform2f(mLoc_uDivisors, argsYUV->divisors.width, argsYUV->divisors.height);
         const auto& colorMatrix = gfxUtils::YuvToRgbMatrix4x4ColumnMajor(argsYUV->colorSpace);
         gl->fUniformMatrix4fv(mLoc_uColorMatrix, 1, false, colorMatrix);
     }
 
     // --
 
     const ScopedDrawBlitState drawState(gl, args.destSize);
-    const ScopedBindVAO bindVAO(gl, mParent.mQuadVAO);
+
+    GLuint oldVAO;
+    GLint vaa0Enabled;
+    GLint vaa0Size;
+    GLenum vaa0Type;
+    GLint vaa0Normalized;
+    GLsizei vaa0Stride;
+    GLvoid* vaa0Pointer;
+    if (mParent.mQuadVAO) {
+        oldVAO = gl->GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING);
+        gl->fBindVertexArray(mParent.mQuadVAO);
+    } else {
+        gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vaa0Enabled);
+        gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &vaa0Size);
+        gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint*)&vaa0Type);
+        gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vaa0Normalized);
+        gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, (GLint*)&vaa0Stride);
+        gl->fGetVertexAttribPointerv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &vaa0Pointer);
+
+        gl->fEnableVertexAttribArray(0);
+        const ScopedBindArrayBuffer bindVBO(gl, mParent.mQuadVBO);
+        gl->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0);
+    }
+
     gl->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+
+    if (mParent.mQuadVAO) {
+        gl->fBindVertexArray(oldVAO);
+    } else {
+        if (vaa0Enabled) {
+            gl->fEnableVertexAttribArray(0);
+        } else {
+            gl->fDisableVertexAttribArray(0);
+        }
+        gl->fVertexAttribPointer(0, vaa0Size, vaa0Type, bool(vaa0Normalized), vaa0Stride,
+                                 vaa0Pointer);
+    }
 }
 
 // --
 
 GLBlitHelper::GLBlitHelper(GLContext* const gl)
     : mGL(gl)
     , mQuadVAO(0)
+    , mQuadVBO(0)
     , mDrawBlitProg_VertShader(mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER))
     , mYuvUploads{0}
     , mYuvUploads_YSize(0, 0)
     , mYuvUploads_UVSize(0, 0)
 {
     if (!mGL->IsSupported(GLFeature::vertex_array_object)) {
         gfxCriticalError() << "GLBlitHelper requires vertex_array_object.";
         return;
     }
 
-    GLuint vbo = 0;
-    mGL->fGenBuffers(1, &vbo);
+    mGL->fGenBuffers(1, &mQuadVBO);
     {
-        const ScopedBindArrayBuffer bindVBO(mGL, vbo);
+        const ScopedBindArrayBuffer bindVBO(mGL, mQuadVBO);
 
         const float quadData[] = {
             0, 0,
             1, 0,
             0, 1,
             1, 1
         };
         const HeapCopyOfStackArray<float> heapQuadData(quadData);
         mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER, heapQuadData.ByteLength(),
                          heapQuadData.Data(), LOCAL_GL_STATIC_DRAW);
 
-        mGL->fGenVertexArrays(1, &mQuadVAO);
-        const ScopedBindVAO bindVAO(mGL, mQuadVAO);
-        mGL->fEnableVertexAttribArray(0);
-        mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0);
+        if (mGL->IsSupported(GLFeature::vertex_array_object)) {
+            const auto prev = mGL->GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING);
+
+            mGL->fGenVertexArrays(1, &mQuadVAO);
+            mGL->fBindVertexArray(mQuadVAO);
+            mGL->fEnableVertexAttribArray(0);
+            mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0);
+
+            mGL->fBindVertexArray(prev);
+        }
     }
-    mGL->fDeleteBuffers(1, &vbo);
 
     // --
 
     if (!mGL->IsGLES()) {
         const auto glslVersion = mGL->ShadingLanguageVersion();
         if (glslVersion >= 130) {
             mDrawBlitProg_VersionLine = nsPrintfCString("#version %u\n", glslVersion);
         }
@@ -466,17 +485,21 @@ GLBlitHelper::~GLBlitHelper()
         delete ptr;
     }
     mDrawBlitProgs.clear();
 
     if (!mGL->MakeCurrent())
         return;
 
     mGL->fDeleteShader(mDrawBlitProg_VertShader);
-    mGL->fDeleteVertexArrays(1, &mQuadVAO);
+    mGL->fDeleteBuffers(1, &mQuadVBO);
+
+    if (mQuadVAO) {
+        mGL->fDeleteVertexArrays(1, &mQuadVAO);
+    }
 }
 
 // --
 
 const DrawBlitProg*
 GLBlitHelper::GetDrawBlitProg(const DrawBlitProg::Key& key) const
 {
     const auto& res = mDrawBlitProgs.insert({key, nullptr});
--- a/gfx/gl/GLBlitHelper.h
+++ b/gfx/gl/GLBlitHelper.h
@@ -103,16 +103,17 @@ class GLBlitHelper final
     friend class BindAnglePlanes;
     friend class DrawBlitProg;
     friend class GLContext;
 
     GLContext* const mGL;
     mutable std::map<DrawBlitProg::Key, const DrawBlitProg*> mDrawBlitProgs;
 
     GLuint mQuadVAO;
+    GLuint mQuadVBO;
     nsCString mDrawBlitProg_VersionLine;
     const GLuint mDrawBlitProg_VertShader;
 
     GLuint mYuvUploads[3];
     gfx::IntSize mYuvUploads_YSize;
     gfx::IntSize mYuvUploads_UVSize;
 
 #ifdef XP_WIN