--- 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);
}
}
}