Commit 327411e8 by Corentin Wallez Committed by Commit Bot

WebGL_compatibility: disallow client-side arrays

BUG=angleproject:1523 Change-Id: Icd207b2d94c1375c6f3189af42d55eac52b99603 Reviewed-on: https://chromium-review.googlesource.com/418398 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent a2c74985
...@@ -42,6 +42,8 @@ bool ValidateDrawAttribs(ValidationContext *context, ...@@ -42,6 +42,8 @@ bool ValidateDrawAttribs(ValidationContext *context,
const gl::State &state = context->getGLState(); const gl::State &state = context->getGLState();
const gl::Program *program = state.getProgram(); const gl::Program *program = state.getProgram();
bool webglCompatibility = context->getExtensions().webglCompatibility;
const VertexArray *vao = state.getVertexArray(); const VertexArray *vao = state.getVertexArray();
const auto &vertexAttribs = vao->getVertexAttributes(); const auto &vertexAttribs = vao->getVertexAttributes();
size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
...@@ -96,6 +98,15 @@ bool ValidateDrawAttribs(ValidationContext *context, ...@@ -96,6 +98,15 @@ bool ValidateDrawAttribs(ValidationContext *context,
} }
} }
} }
else if (webglCompatibility)
{
// [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
// If a vertex attribute is enabled as an array via enableVertexAttribArray but no
// buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then
// calls to drawArrays or drawElements will generate an INVALID_OPERATION error.
context->handleError(
Error(GL_INVALID_OPERATION, "An enabled vertex array has no buffer."));
}
else if (attrib.pointer == NULL) else if (attrib.pointer == NULL)
{ {
// This is an application error that would normally result in a crash, // This is an application error that would normally result in a crash,
...@@ -3306,11 +3317,6 @@ bool ValidateDrawElements(ValidationContext *context, ...@@ -3306,11 +3317,6 @@ bool ValidateDrawElements(ValidationContext *context,
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
if (!indices && !elementArrayBuffer)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
if (elementArrayBuffer) if (elementArrayBuffer)
{ {
...@@ -3335,10 +3341,21 @@ bool ValidateDrawElements(ValidationContext *context, ...@@ -3335,10 +3341,21 @@ bool ValidateDrawElements(ValidationContext *context,
return false; return false;
} }
} }
else if (context->getExtensions().webglCompatibility && count > 0)
{
// [WebGL 1.0] Section 6.2 No Client Side Arrays
// If drawElements is called with a count greater than zero, and no WebGLBuffer is bound
// to the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
context->handleError(
Error(GL_INVALID_OPERATION, "There is no element array buffer bound and count > 0."));
return false;
}
else if (!indices) else if (!indices)
{ {
// Catch this programming error here // This is an application error that would normally result in a crash,
context->handleError(Error(GL_INVALID_OPERATION)); // but we catch it and return an error
context->handleError(
Error(GL_INVALID_OPERATION, "No element array buffer and no pointer."));
return false; return false;
} }
......
...@@ -140,6 +140,78 @@ TEST_P(WebGLCompatibilityTest, ExtensionCompilerSpec) ...@@ -140,6 +140,78 @@ TEST_P(WebGLCompatibilityTest, ExtensionCompilerSpec)
glDeleteProgram(program); glDeleteProgram(program);
} }
// Test that client-side array buffers are forbidden in WebGL mode
TEST_P(WebGLCompatibilityTest, ForbidsClientSideArrayBuffer)
{
const std::string &vert =
"attribute vec3 a_pos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(a_pos, 1.0);\n"
"}\n";
const std::string &frag =
"precision highp float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, vert, frag);
GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
ASSERT_NE(-1, posLocation);
glUseProgram(program.get());
const auto &vertices = GetQuadVertices();
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices.data());
glEnableVertexAttribArray(posLocation);
ASSERT_GL_NO_ERROR();
glDrawArrays(GL_TRIANGLES, 0, 6);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
// Test that client-side element array buffers are forbidden in WebGL mode
TEST_P(WebGLCompatibilityTest, ForbidsClientSideElementBuffer)
{
const std::string &vert =
"attribute vec3 a_pos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(a_pos, 1.0);\n"
"}\n";
const std::string &frag =
"precision highp float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, vert, frag);
GLint posLocation = glGetAttribLocation(program.get(), "a_pos");
ASSERT_NE(-1, posLocation);
glUseProgram(program.get());
const auto &vertices = GetQuadVertices();
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posLocation);
const GLubyte indices[] = {0, 1, 2, 3, 4, 5};
ASSERT_GL_NO_ERROR();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest, ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment