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,
const gl::State &state = context->getGLState();
const gl::Program *program = state.getProgram();
bool webglCompatibility = context->getExtensions().webglCompatibility;
const VertexArray *vao = state.getVertexArray();
const auto &vertexAttribs = vao->getVertexAttributes();
size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
......@@ -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)
{
// This is an application error that would normally result in a crash,
......@@ -3306,11 +3317,6 @@ bool ValidateDrawElements(ValidationContext *context,
const gl::VertexArray *vao = state.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
if (!indices && !elementArrayBuffer)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
if (elementArrayBuffer)
{
......@@ -3335,10 +3341,21 @@ bool ValidateDrawElements(ValidationContext *context,
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)
{
// Catch this programming error here
context->handleError(Error(GL_INVALID_OPERATION));
// This is an application error that would normally result in a crash,
// but we catch it and return an error
context->handleError(
Error(GL_INVALID_OPERATION, "No element array buffer and no pointer."));
return false;
}
......
......@@ -140,6 +140,78 @@ TEST_P(WebGLCompatibilityTest, ExtensionCompilerSpec)
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
// tests should be run against.
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