Fix clearing out-of-range default FB drawbuffer
The default framebuffer is initialized with just one drawbuffer slot
so the number of drawbuffers needs to be validated before checking if
a buffer is attached.
BUG=angleproject:2831
TEST=angle_end2end_tests
Change-Id: I960c39357853d1cd4575b06a992cff33223ab3df
Reviewed-on: https://chromium-review.googlesource.com/c/1264518
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index fa0edf9..3567e29 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -3547,49 +3547,67 @@
void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
+ Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
+ const FramebufferAttachment *attachment = nullptr;
+ if (buffer == GL_DEPTH)
+ {
+ attachment = framebufferObject->getDepthbuffer();
+ }
+ if (buffer == GL_COLOR &&
+ static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorBuffers())
+ {
+ attachment = framebufferObject->getColorbuffer(drawbuffer);
+ }
// It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
// that the backend doesn't need to take this case into account.
- if (buffer == GL_DEPTH && !getGLState().getDrawFramebuffer()->getDepthbuffer())
- {
- return;
- }
- if (buffer == GL_COLOR && !getGLState().getDrawFramebuffer()->getColorbuffer(drawbuffer))
+ if (!attachment)
{
return;
}
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
- ANGLE_CONTEXT_TRY(
- mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values));
}
void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
+ Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
+ const FramebufferAttachment *attachment = nullptr;
+ if (buffer == GL_COLOR &&
+ static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorBuffers())
+ {
+ attachment = framebufferObject->getColorbuffer(drawbuffer);
+ }
// It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
// that the backend doesn't need to take this case into account.
- if (buffer == GL_COLOR && !getGLState().getDrawFramebuffer()->getColorbuffer(drawbuffer))
+ if (!attachment)
{
return;
}
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
- ANGLE_CONTEXT_TRY(
- mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values));
}
void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
+ Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
+ const FramebufferAttachment *attachment = nullptr;
+ if (buffer == GL_STENCIL)
+ {
+ attachment = framebufferObject->getStencilbuffer();
+ }
+ if (buffer == GL_COLOR &&
+ static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorBuffers())
+ {
+ attachment = framebufferObject->getColorbuffer(drawbuffer);
+ }
// It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
// that the backend doesn't need to take this case into account.
- if (buffer == GL_STENCIL && !getGLState().getDrawFramebuffer()->getStencilbuffer())
- {
- return;
- }
- if (buffer == GL_COLOR && !getGLState().getDrawFramebuffer()->getColorbuffer(drawbuffer))
+ if (!attachment)
{
return;
}
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
- ANGLE_CONTEXT_TRY(
- mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values));
}
void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)