Bug 1396704 - Support GLBlitHelper without VAOs. - r=daoshengmu
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 05 Sep 2017 17:34:22 -0700
changeset 379134 34767394af0d91775da40b54e2f5a21083631c3f
parent 379133 4e6c69e3227cf6132792b3725531155d9c53adad
child 379135 67281ccb998f8cffc502b722529a40629d387005
push id32449
push userarchaeopteryx@coole-files.de
push dateWed, 06 Sep 2017 09:33:20 +0000
treeherdermozilla-central@c959327c6b75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaoshengmu
bugs1396704
milestone57.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 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