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(context, format, type) : ValidES3ReadFormatType(context, 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; }
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(); ASSERT(framebuffer); 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); } if (!framebuffer->getReadColorbuffer()) { return gl::error(GL_INVALID_OPERATION, false); } GLenum currentInternalFormat, currentFormat, currentType; int clientVersion = context->getClientVersion(); context->getCurrentReadFormatType(¤tInternalFormat, ¤tFormat, ¤tType); bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) : ValidES3ReadFormatType(context, 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; }