Bug 1425369 - Treat Draw* as Draw*Instanced(1). - r=daoshengmu
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 14 Dec 2017 14:10:30 -0800
changeset 450873 1884f463bb819b163bc96d1caec272a0e5ff9e78
parent 450872 6ad8731124c39ee7d3e63dffb0e6008096bbcd07
child 450874 0b8cec51ffc2c3112c01901bba0cb96ab995729e
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaoshengmu
bugs1425369
milestone59.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 1425369 - Treat Draw* as Draw*Instanced(1). - r=daoshengmu MozReview-Commit-ID: KZKNQtCSG4V
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextDraw.cpp
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1287,23 +1287,32 @@ protected:
                    GLsizei rawHeight, GLsizei rawDepth, GLint border,
                    const TexImageSource& src, const Maybe<GLsizei>& expectedImageSize);
 
 // -----------------------------------------------------------------------------
 // Vertices Feature (WebGLContextVertices.cpp)
     GLenum mPrimRestartTypeBytes;
 
 public:
-    void DrawArrays(GLenum mode, GLint first, GLsizei count);
-    void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
-                             GLsizei primcount);
+    void DrawArrays(GLenum mode, GLint first, GLsizei count) {
+        DrawArraysInstanced(mode, first, count, 1, "drawArrays");
+    }
+
     void DrawElements(GLenum mode, GLsizei count, GLenum type,
-                      WebGLintptr byteOffset, const char* funcName = nullptr);
-    void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
-                               WebGLintptr byteOffset, GLsizei primcount);
+                      WebGLintptr byteOffset, const char* funcName = "drawElements")
+    {
+        DrawElementsInstanced(mode, count, type, byteOffset, 1, funcName);
+    }
+
+    void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount,
+                             GLsizei instanceCount,
+                             const char* funcName = "drawArraysInstanced");
+    void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type,
+                               WebGLintptr byteOffset, GLsizei instanceCount,
+                               const char* funcName = "drawElementsInstanced");
 
     void EnableVertexAttribArray(GLuint index);
     void DisableVertexAttribArray(GLuint index);
 
     JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
                               ErrorResult& rv);
 
     void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -464,16 +464,23 @@ public:
     void Advance() const {
         if (!mWithTF)
             return;
 
         mTFO->mActive_VertPosition += mUsedVerts;
     }
 };
 
+static bool
+HasInstancedDrawing(const WebGLContext& webgl)
+{
+    return webgl.IsWebGL2() ||
+           webgl.IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays);
+}
+
 ////////////////////////////////////////
 
 bool
 WebGLContext::DrawArrays_check(const char* const funcName, const GLint first,
                                const GLsizei vertCount, const GLsizei instanceCount,
                                Maybe<uint32_t>* const out_lastVert)
 {
     if (!ValidateNonNegative(funcName, "first", first) ||
@@ -502,63 +509,20 @@ WebGLContext::DrawArrays_check(const cha
             return false;
         }
         *out_lastVert = Some(lastVert_checked.value());
     }
     return true;
 }
 
 void
-WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei vertCount)
-{
-    AUTO_PROFILER_LABEL("WebGLContext::DrawArrays", GRAPHICS);
-    const char funcName[] = "drawArrays";
-    if (IsContextLost())
-        return;
-
-    MakeContextCurrent();
-
-    bool error = false;
-    ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
-    if (error)
-        return;
-
-    const GLsizei instanceCount = 1;
-    Maybe<uint32_t> lastVert;
-    if (!DrawArrays_check(funcName, first, vertCount, instanceCount, &lastVert))
-        return;
-
-    const ScopedDrawHelper scopedHelper(this, funcName, mode, lastVert, instanceCount,
-                                        &error);
-    if (error)
-        return;
-
-    const ScopedDrawWithTransformFeedback scopedTF(this, funcName, mode, vertCount,
-                                                   instanceCount, &error);
-    if (error)
-        return;
-
-    {
-        ScopedDrawCallWrapper wrapper(*this);
-        if (vertCount) {
-            AUTO_PROFILER_LABEL("glDrawArrays", GRAPHICS);
-            gl->fDrawArrays(mode, first, vertCount);
-        }
-    }
-
-    Draw_cleanup(funcName);
-    scopedTF.Advance();
-}
-
-void
 WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
-                                  GLsizei instanceCount)
+                                  GLsizei instanceCount, const char* const funcName)
 {
     AUTO_PROFILER_LABEL("WebGLContext::DrawArraysInstanced", GRAPHICS);
-    const char funcName[] = "drawArraysInstanced";
     if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     bool error = false;
     ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
     if (error)
@@ -577,17 +541,22 @@ WebGLContext::DrawArraysInstanced(GLenum
                                                    instanceCount, &error);
     if (error)
         return;
 
     {
         ScopedDrawCallWrapper wrapper(*this);
         if (vertCount && instanceCount) {
             AUTO_PROFILER_LABEL("glDrawArraysInstanced", GRAPHICS);
-            gl->fDrawArraysInstanced(mode, first, vertCount, instanceCount);
+            if (HasInstancedDrawing(*this)) {
+                gl->fDrawArraysInstanced(mode, first, vertCount, instanceCount);
+            } else {
+                MOZ_ASSERT(instanceCount == 1);
+                gl->fDrawArrays(mode, first, vertCount);
+            }
         }
     }
 
     Draw_cleanup(funcName);
     scopedTF.Advance();
 }
 
 ////////////////////////////////////////
@@ -697,76 +666,21 @@ HandleDrawElementsErrors(WebGLContext* w
         webgl->ErrorImplementationBug("%s: Unexpected driver error during indexed draw"
                                       " call. Please file a bug.",
                                       funcName);
         return;
     }
 }
 
 void
-WebGLContext::DrawElements(GLenum mode, GLsizei indexCount, GLenum type,
-                           WebGLintptr byteOffset, const char* funcName)
-{
-    AUTO_PROFILER_LABEL("WebGLContext::DrawElements", GRAPHICS);
-    if (!funcName) {
-        funcName = "drawElements";
-    }
-    if (IsContextLost())
-        return;
-
-    MakeContextCurrent();
-
-    bool error = false;
-    ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
-    if (error)
-        return;
-
-    const GLsizei instanceCount = 1;
-    Maybe<uint32_t> lastVert;
-    if (!DrawElements_check(funcName, indexCount, type, byteOffset, instanceCount,
-                            &lastVert))
-    {
-        return;
-    }
-
-    const ScopedDrawHelper scopedHelper(this, funcName, mode, lastVert, instanceCount,
-                                        &error);
-    if (error)
-        return;
-
-    {
-        ScopedDrawCallWrapper wrapper(*this);
-        {
-            UniquePtr<gl::GLContext::LocalErrorScope> errorScope;
-
-            if (gl->IsANGLE()) {
-                errorScope.reset(new gl::GLContext::LocalErrorScope(*gl));
-            }
-
-            if (indexCount) {
-                AUTO_PROFILER_LABEL("glDrawElements", GRAPHICS);
-                gl->fDrawElements(mode, indexCount, type,
-                                  reinterpret_cast<GLvoid*>(byteOffset));
-            }
-
-            if (errorScope) {
-                HandleDrawElementsErrors(this, funcName, *errorScope);
-            }
-        }
-    }
-
-    Draw_cleanup(funcName);
-}
-
-void
 WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei indexCount, GLenum type,
-                                    WebGLintptr byteOffset, GLsizei instanceCount)
+                                    WebGLintptr byteOffset, GLsizei instanceCount,
+                                    const char* const funcName)
 {
     AUTO_PROFILER_LABEL("WebGLContext::DrawElementsInstanced", GRAPHICS);
-    const char funcName[] = "drawElementsInstanced";
     if (IsContextLost())
         return;
 
     MakeContextCurrent();
 
     bool error = false;
     ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
     if (error)
@@ -790,19 +704,25 @@ WebGLContext::DrawElementsInstanced(GLen
             UniquePtr<gl::GLContext::LocalErrorScope> errorScope;
 
             if (gl->IsANGLE()) {
                 errorScope.reset(new gl::GLContext::LocalErrorScope(*gl));
             }
 
             if (indexCount && instanceCount) {
                 AUTO_PROFILER_LABEL("glDrawElementsInstanced", GRAPHICS);
-                gl->fDrawElementsInstanced(mode, indexCount, type,
-                                           reinterpret_cast<GLvoid*>(byteOffset),
-                                           instanceCount);
+                if (HasInstancedDrawing(*this)) {
+                    gl->fDrawElementsInstanced(mode, indexCount, type,
+                                               reinterpret_cast<GLvoid*>(byteOffset),
+                                               instanceCount);
+                } else {
+                    MOZ_ASSERT(instanceCount == 1);
+                    gl->fDrawElements(mode, indexCount, type,
+                                      reinterpret_cast<GLvoid*>(byteOffset));
+                }
             }
 
             if (errorScope) {
                 HandleDrawElementsErrors(this, funcName, *errorScope);
             }
         }
     }