Clip FramebufferD3D::readPixels to framebuffer.
In GL, ReadPixels() is allowed to modify memory that corresponds to
pixels outside the framebuffer.
In WebGL it must not do that, so clip the read area to the framebuffer.
Enable corresponding test.
BUG=angleproject:1815
Change-Id: Ie99401a2102c352ffb1193a57aa66a5b96c184aa
Reviewed-on: https://chromium-review.googlesource.com/540556
Commit-Queue: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index 4d3b064..e1f9bc5 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -236,22 +236,34 @@
}
gl::Error FramebufferD3D::readPixels(const gl::Context *context,
- const gl::Rectangle &area,
+ const gl::Rectangle &origArea,
GLenum format,
GLenum type,
void *pixels) const
{
+ // Clip read area to framebuffer.
+ const gl::Extents fbSize = getState().getReadAttachment()->getSize();
+ const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
+ gl::Rectangle area;
+ if (!ClipRectangle(origArea, fbRect, &area))
+ {
+ // nothing to read
+ return gl::NoError();
+ }
+
const gl::PixelPackState &packState = context->getGLState().getPackState();
const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
GLuint outputPitch = 0;
- ANGLE_TRY_RESULT(
- sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength),
- outputPitch);
+ ANGLE_TRY_RESULT(sizedFormatInfo.computeRowPitch(type, origArea.width, packState.alignment,
+ packState.rowLength),
+ outputPitch);
GLuint outputSkipBytes = 0;
ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false),
outputSkipBytes);
+ outputSkipBytes +=
+ (area.x - origArea.x) * sizedFormatInfo.pixelBytes + (area.y - origArea.y) * outputPitch;
return readPixelsImpl(context, area, format, type, outputPitch, packState,
reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);