Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index b0891db4337b4cd396917e38dba49436311fdee5..ab8d0f68ab94609c07a11711e668b38d272f6d98 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -7990,6 +7990,70 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( |
| } |
| } |
| + gfx::Size read_size = GetBoundReadFramebufferSize(); |
| + gfx::Rect rect(0, 0, read_size.width(), read_size.height()); |
| + GLuint src_x = srcX1 > srcX0 ? srcX0 : srcX1; |
|
Zhenyao Mo
2016/10/13 00:35:56
From your code, it seems you include the lower bou
yunchao
2016/10/13 01:50:47
(Just a quick reply about this, I think the spec i
Zhenyao Mo
2016/10/13 22:51:23
Yes, your interpretation sounds reasonable. The sp
|
| + GLuint src_y = srcY1 > srcY0 ? srcY0 : srcY1; |
| + GLuint src_width = srcX1 > srcX0 ? srcX1 - srcX0 : srcX0 - srcX1; |
|
Zhenyao Mo
2016/10/13 00:35:56
These math needs to be safe (using base::CheckedNu
yunchao
2016/10/14 13:49:05
Done.
|
| + GLuint src_height = srcY1 > srcY0 ? srcY1 - srcY0 : srcY0 - srcY1; |
| + gfx::Rect src_region(src_x, src_y, src_width, src_height); |
| + if (!rect.Contains(src_region) && (src_width != 0) && (src_height != 0)) { |
| + // If pixels lying outside the read framebuffer, adjust src region |
| + // and dst region to appropriate in-bounds regions respectively. |
| + rect.Intersect(gfx::Rect(src_x, src_y, src_width, src_height)); |
| + GLuint src_real_width = rect.width(); |
| + GLuint src_real_height = rect.height(); |
| + GLuint xoffset = rect.x() - src_x; |
|
Zhenyao Mo
2016/10/13 00:35:56
This could also cause overflow since src_x can be
yunchao
2016/10/14 13:49:05
Done.
|
| + GLuint yoffset = rect.y() - src_y; |
| + // if X/Y is reversed, use the top/right out-of-bounds region for mapping to |
| + // dst region, instead of left/bottom out-of-bounds region for mapping. |
| + if (((srcX1 > srcX0) && (dstX1 < dstX0)) || |
| + ((srcX1 < srcX0) && (dstX1 > dstX0))) { |
| + xoffset = src_x + src_width - rect.x() - rect.width(); |
| + } |
| + if (((srcY1 > srcY0) && (dstY1 < dstY0)) || |
| + ((srcY1 < srcY0) && (dstY1 > dstY0))) { |
| + yoffset = src_y + src_height - rect.y() - rect.height(); |
| + } |
| + |
| + GLuint dst_x = dstX1 > dstX0 ? dstX0 : dstX1; |
| + GLuint dst_y = dstY1 > dstY0 ? dstY0 : dstY1; |
| + GLuint dst_width = dstX1 > dstX0 ? dstX1 - dstX0 : dstX0 - dstX1; |
| + GLuint dst_height = dstY1 > dstY0 ? dstY1 - dstY0 : dstY0 - dstY1; |
| + GLfloat dst_mapping_width = |
| + static_cast<GLfloat>(src_real_width) * dst_width / src_width; |
| + GLfloat dst_mapping_height = |
| + static_cast<GLfloat>(src_real_height) * dst_height / src_height; |
| + GLfloat dst_mapping_xoffset = |
| + static_cast<GLfloat>(xoffset) * dst_width / src_width; |
| + GLfloat dst_mapping_yoffset = |
| + static_cast<GLfloat>(yoffset) * dst_height / src_height; |
| + |
| + GLuint dst_mapping_x0 = (filter == GL_LINEAR) ? |
|
yunchao
2016/10/12 15:26:14
Please see the discuss at https://github.com/Khron
Zhenyao Mo
2016/10/13 00:35:56
I think no matter what the filter is, we should on
yunchao
2016/10/13 01:50:47
According to the GLES3 spec, for NEAREST filter, "
Corentin Wallez
2016/10/13 14:35:53
I understand the spec differently, see my comment
Zhenyao Mo
2016/10/13 22:51:23
cwallez: I fail to understand you here. I think wh
Zhenyao Mo
2016/10/13 22:51:23
yunchao: I think the spec you quoted is for both L
Zhenyao Mo
2016/10/13 23:16:15
Thinking more about this: for the scaled valid low
yunchao
2016/10/14 02:52:50
I agree with you, Zhenyao. I am just waiting for t
yunchao
2016/10/14 02:52:50
Yes, the most part of this patch should be OK, I h
yunchao
2016/10/14 02:52:50
That's true.
|
| + std::floor(dst_x + dst_mapping_xoffset) : |
| + std::round(dst_x + dst_mapping_xoffset); |
| + GLuint dst_mapping_y0 = (filter == GL_LINEAR) ? |
| + std::floor(dst_y + dst_mapping_yoffset) : |
| + std::round(dst_y + dst_mapping_yoffset); |
| + |
| + GLuint dst_mapping_x1 = (filter == GL_LINEAR) ? |
| + std::ceil(dst_x + dst_mapping_xoffset + dst_mapping_width) : |
| + std::round(dst_x + dst_mapping_xoffset + dst_mapping_width); |
| + GLuint dst_mapping_y1 = (filter == GL_LINEAR) ? |
| + std::ceil(dst_y + dst_mapping_yoffset + dst_mapping_height) : |
| + std::round(dst_y + dst_mapping_yoffset + dst_mapping_height); |
| + |
| + srcX0 = srcX0 < srcX1 ? rect.x() : rect.x() + rect.width(); |
| + srcY0 = srcY0 < srcY1 ? rect.y() : rect.y() + rect.height(); |
| + srcX1 = srcX0 < srcX1 ? rect.x() + rect.width() : rect.x(); |
| + srcY1 = srcY0 < srcY1 ? rect.y() + rect.height() : rect.y(); |
| + |
| + dstX0 = dstX0 < dstX1 ? dst_mapping_x0 : dst_mapping_x1; |
| + dstY0 = dstY0 < dstY1 ? dst_mapping_y0 : dst_mapping_y1; |
| + dstX1 = dstX0 < dstX1 ? dst_mapping_x1 : dst_mapping_x0; |
| + dstY1 = dstY0 < dstY1 ? dst_mapping_y1 : dst_mapping_y0; |
| + } |
| + |
| bool enable_srgb = |
| (read_buffer_has_srgb || draw_buffers_has_srgb) && |
| ((mask & GL_COLOR_BUFFER_BIT) != 0); |