Refactor ReadPixels validation.
Move ReadPixels error generation out of the implementation and into
the API level.
BUG=angle:571
Change-Id: I0b32294f359fedd13d1af2c95baf37a3e5ac1d5b
Reviewed-on: https://chromium-review.googlesource.com/188014
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index 5ed852c..98b353e 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -8,6 +8,8 @@
// validationES.h: Validation functions for generic OpenGL ES entry point parameters
#include "libGLESv2/validationES.h"
+#include "libGLESv2/validationES2.h"
+#include "libGLESv2/validationES3.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/Framebuffer.h"
@@ -771,4 +773,55 @@
}
}
+bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels)
+{
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ }
+
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+ {
+ 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;
+
+ bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(format, type) :
+ ValidES3ReadFormatType(currentInternalFormat, format, type);
+
+ if (!(currentFormat == format && currentType == type) && !validReadFormat)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
+ GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format :
+ GetSizedInternalFormat(format, type, clientVersion);
+
+ GLsizei outputPitch = GetRowPitch(sizedInternalFormat, type, clientVersion, width, context->getPackAlignment());
+ // sized query sanity check
+ if (bufSize)
+ {
+ int requiredSize = outputPitch * height;
+ if (requiredSize > *bufSize)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ }
+
+ return true;
+}
+
}