Commit 739bd8ba by Frank Henigman Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent e145def0
...@@ -236,22 +236,34 @@ GLenum FramebufferD3D::getImplementationColorReadType(const gl::Context *context ...@@ -236,22 +236,34 @@ GLenum FramebufferD3D::getImplementationColorReadType(const gl::Context *context
} }
gl::Error FramebufferD3D::readPixels(const gl::Context *context, gl::Error FramebufferD3D::readPixels(const gl::Context *context,
const gl::Rectangle &area, const gl::Rectangle &origArea,
GLenum format, GLenum format,
GLenum type, GLenum type,
void *pixels) const 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::PixelPackState &packState = context->getGLState().getPackState();
const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type); const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
GLuint outputPitch = 0; GLuint outputPitch = 0;
ANGLE_TRY_RESULT( ANGLE_TRY_RESULT(sizedFormatInfo.computeRowPitch(type, origArea.width, packState.alignment,
sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength), packState.rowLength),
outputPitch); outputPitch);
GLuint outputSkipBytes = 0; GLuint outputSkipBytes = 0;
ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false), ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false),
outputSkipBytes); outputSkipBytes);
outputSkipBytes +=
(area.x - origArea.x) * sizedFormatInfo.pixelBytes + (area.y - origArea.y) * outputPitch;
return readPixelsImpl(context, area, format, type, outputPitch, packState, return readPixelsImpl(context, area, format, type, outputPitch, packState,
reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes); reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);
......
...@@ -256,7 +256,10 @@ class WebGLReadOutsideFramebufferTest : public ANGLETest ...@@ -256,7 +256,10 @@ class WebGLReadOutsideFramebufferTest : public ANGLETest
// the corresponding source pixel is outside the framebuffer. // the corresponding source pixel is outside the framebuffer.
TEST_P(WebGLReadOutsideFramebufferTest, ReadPixels) TEST_P(WebGLReadOutsideFramebufferTest, ReadPixels)
{ {
// Main(&WebGLReadOutsideFramebufferTest::TestReadPixels, false); if (IsD3DSM3() || IsD3D11())
{
Main(&WebGLReadOutsideFramebufferTest::TestReadPixels, false);
}
} }
// Check that copyTexSubImage2D does not set a destination pixel when // Check that copyTexSubImage2D does not set a destination pixel when
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment