Move state query validation out of Context.
Generate all GL errors in the validation helper functions, instead of
within the state manipulation logic and internals of Context.
BUG=angle:571
Change-Id: I7a3f540e2ae0f5f8c7126e2593717cc3200dd7e5
Reviewed-on: https://chromium-review.googlesource.com/200551
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index 0fe7d22..a6ae90a 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -829,6 +829,7 @@
GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels)
{
gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ ASSERT(framebuffer);
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
@@ -840,16 +841,15 @@
return gl::error(GL_INVALID_OPERATION, false);
}
+ if (!framebuffer->getReadColorbuffer())
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
GLenum currentInternalFormat, currentFormat, currentType;
int clientVersion = context->getClientVersion();
- // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
- // and attempting to read back if that's the case is an error. The error will be registered
- // by getCurrentReadFormat.
- // Note: we need to explicitly check for framebuffer completeness here, before we call
- // getCurrentReadFormatType, because it generates a different (wrong) error for incomplete FBOs
- if (!context->getCurrentReadFormatType(¤tInternalFormat, ¤tFormat, ¤tType))
- return false;
+ context->getCurrentReadFormatType(¤tInternalFormat, ¤tFormat, ¤tType);
bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) :
ValidES3ReadFormatType(context, currentInternalFormat, format, type);
@@ -1038,4 +1038,64 @@
return true;
}
+bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
+{
+ if (!context->getQueryParameterInfo(pname, nativeType, numParams))
+ {
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
+ {
+ unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
+
+ if (colorAttachment >= context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_BINDING_2D:
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_TEXTURE_BINDING_3D:
+ case GL_TEXTURE_BINDING_2D_ARRAY:
+ if (context->getActiveSampler() >= context->getMaximumCombinedTextureImageUnits())
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ break;
+
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ {
+ Framebuffer *framebuffer = context->getReadFramebuffer();
+ ASSERT(framebuffer);
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
+ Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
+ if (!renderbuffer)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // pname is valid, but there are no parameters to return
+ if (numParams == 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
}