Bug 1425369 - Treat Draw* as Draw*Instanced(1). - r=daoshengmu a=gchang
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 14 Dec 2017 14:10:30 -0800
changeset 715231 5d7f843128a2877a38288424e568868c74cb2f54
parent 715230 5a9e5aee2aef31d650da88666ecf4c752518bca8
child 715490 d792006169bac787b918879a293ab1e607bafb43
push id94096
push userbmo:jgilbert@mozilla.com
push dateWed, 03 Jan 2018 05:51:31 +0000
reviewersdaoshengmu, gchang
bugs1425369
milestone58.0
Bug 1425369 - Treat Draw* as Draw*Instanced(1). - r=daoshengmu a=gchang 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);
             }
         }
     }