--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -689,16 +689,36 @@ WebGLContext::DrawElements_check(const c
GenerateWarning("%s: bound element array buffer previously used with a type other than "
"%s, this will affect performance.",
funcName, WebGLContext::EnumName(type));
}
return true;
}
+static void
+HandleDrawElementsErrors(WebGLContext* webgl, const char* funcName,
+ gl::GLContext::LocalErrorScope& errorScope)
+{
+ const auto err = errorScope.GetError();
+ if (err == LOCAL_GL_INVALID_OPERATION) {
+ webgl->ErrorInvalidOperation("%s: Driver rejected indexed draw call, possibly"
+ " due to out-of-bounds indices.", funcName);
+ return;
+ }
+
+ MOZ_ASSERT(!err);
+ if (err) {
+ webgl->ErrorImplementationBug("%s: Unexpected driver error during indexed draw"
+ " call. Please file a bug.",
+ funcName);
+ return;
+ }
+}
+
void
WebGLContext::DrawElements(GLenum mode, GLsizei vertCount, GLenum type,
WebGLintptr byteOffset)
{
const char funcName[] = "drawElements";
if (IsContextLost())
return;
@@ -715,18 +735,30 @@ WebGLContext::DrawElements(GLenum mode,
const ScopedDrawHelper scopedHelper(this, funcName, 0, mMaxFetchedVertices, instanceCount,
&error);
if (error)
return;
{
ScopedDrawCallWrapper wrapper(*this);
- gl->fDrawElements(mode, vertCount, type,
- reinterpret_cast<GLvoid*>(byteOffset));
+ {
+ UniquePtr<gl::GLContext::LocalErrorScope> errorScope;
+
+ if (gl->IsANGLE()) {
+ errorScope.reset(new gl::GLContext::LocalErrorScope(*gl));
+ }
+
+ gl->fDrawElements(mode, vertCount, type,
+ reinterpret_cast<GLvoid*>(byteOffset));
+
+ if (errorScope) {
+ HandleDrawElementsErrors(this, funcName, *errorScope);
+ }
+ }
}
Draw_cleanup(funcName);
}
void
WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type,
WebGLintptr byteOffset, GLsizei instanceCount)
@@ -750,19 +782,30 @@ WebGLContext::DrawElementsInstanced(GLen
const ScopedDrawHelper scopedHelper(this, funcName, 0, mMaxFetchedVertices, instanceCount,
&error);
if (error)
return;
{
ScopedDrawCallWrapper wrapper(*this);
- gl->fDrawElementsInstanced(mode, vertCount, type,
- reinterpret_cast<GLvoid*>(byteOffset),
- instanceCount);
+ {
+ UniquePtr<gl::GLContext::LocalErrorScope> errorScope;
+
+ if (gl->IsANGLE()) {
+ errorScope.reset(new gl::GLContext::LocalErrorScope(*gl));
+ }
+
+ gl->fDrawElementsInstanced(mode, vertCount, type,
+ reinterpret_cast<GLvoid*>(byteOffset),
+ instanceCount);
+ if (errorScope) {
+ HandleDrawElementsErrors(this, funcName, *errorScope);
+ }
+ }
}
Draw_cleanup(funcName);
}
////////////////////////////////////////
void