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 b1039c98a9deef97378f9c15553905196c95305a..b480cee2e6dc7b031d67e987727dd1d95e739926 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -7601,6 +7601,48 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( |
| return; |
| } |
| + // Check whether read framebuffer and draw framebuffer have identical image |
| + enum FeedbackLoopState { |
| + FeedbackLoopTrue, |
| + FeedbackLoopFalse, |
| + FeedbackLoopUnknown |
| + }; |
| + |
| + FeedbackLoopState is_feedback_loop = FeedbackLoopUnknown; |
| + Framebuffer* read_framebuffer = |
| + framebuffer_state_.bound_read_framebuffer.get(); |
| + Framebuffer* draw_framebuffer = |
| + framebuffer_state_.bound_draw_framebuffer.get(); |
| + // If both read framebuffer and draw framebuffer are default framebuffer, |
| + // They always have identical image. Otherwise, if one of read framebuffer |
| + // and draw framebuffe is default framebuffer, but the other is fbo, they |
| + // always have no identical image. |
| + if (!read_framebuffer && !draw_framebuffer) { |
| + is_feedback_loop = FeedbackLoopTrue; |
| + } else if (!read_framebuffer || !draw_framebuffer) { |
| + is_feedback_loop = FeedbackLoopFalse; |
| + } |
| + if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { |
| + const Framebuffer::Attachment* depth_buffer_read = |
| + read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); |
| + const Framebuffer::Attachment* depth_buffer_draw = |
| + draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); |
| + if (depth_buffer_draw && |
| + depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { |
| + is_feedback_loop = FeedbackLoopTrue; |
| + } |
| + } |
| + if ((mask & GL_STENCIL_BUFFER_BIT) != 0) { |
| + const Framebuffer::Attachment* stencil_buffer_read = |
| + read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); |
| + const Framebuffer::Attachment* stencil_buffer_draw = |
| + draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); |
| + if (stencil_buffer_draw && |
| + stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { |
| + is_feedback_loop = FeedbackLoopTrue; |
| + } |
| + } |
| + |
| GLenum src_format = GetBoundReadFramebufferInternalFormat(); |
| GLenum src_type = GetBoundReadFramebufferTextureType(); |
| @@ -7617,6 +7659,9 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( |
| GLenum src_sized_format = |
| GLES2Util::ConvertToSizedFormat(src_format, src_type); |
| + const Framebuffer::Attachment* read_buffer = |
| + is_feedback_loop == FeedbackLoopUnknown ? |
| + read_framebuffer->GetReadBufferAttachment() : nullptr; |
| for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { |
| GLenum dst_format = GetBoundColorDrawBufferInternalFormat( |
| static_cast<GLint>(ii)); |
| @@ -7639,8 +7684,29 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( |
| "incompatible src/dst color formats"); |
| return; |
| } |
| + // Check whether draw buffers have identical color image with read buffer |
| + if (is_feedback_loop == FeedbackLoopUnknown) { |
| + GLenum drawbuffer = static_cast<GLenum>(GL_DRAW_BUFFER0 + ii); |
| + if (draw_framebuffer->GetDrawBuffer(drawbuffer) == GL_NONE) { |
| + continue; |
| + } |
| + GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + ii); |
| + const Framebuffer::Attachment* draw_buffer = |
| + draw_framebuffer->GetAttachment(attachment); |
| + if (!draw_buffer) { |
| + continue; |
| + } |
| + if (draw_buffer->IsSameAttachment(read_buffer)) { |
| + is_feedback_loop = FeedbackLoopTrue; |
|
Zhenyao Mo
2016/09/12 05:37:08
nit: break
yunchao
2016/09/12 06:01:51
Done.
|
| + } |
| + } |
| } |
| } |
| + if (is_feedback_loop == FeedbackLoopTrue) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "source buffer and destination buffers are identical"); |
| + return; |
| + } |
| if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { |
| if (filter != GL_NEAREST) { |