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 7a0243a18d839a4f260dec14eee529a14ddd6c34..57709adf8ec8213158ac9ce747470c7507f8cc7b 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -1349,6 +1349,11 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| GLint level, |
| GLint layer); |
| + // Check that whether the currently bound draw framebuffer has image |
|
Zhenyao Mo
2016/09/09 16:29:57
nit: remove that
yunchao
2016/09/09 16:47:33
Done.
|
| + // that is identical to the read framebuffer's image for blitFramebuffer, |
| + // and only check the designated image type by parameter mask. |
| + bool FormsFramebufferBlitingFeedbackLoop(GLbitfield mask); |
| + |
| // Check if a framebuffer meets our requirements. |
| // Generates |gl_error| if the framebuffer is incomplete. |
| bool CheckFramebufferValid( |
| @@ -4332,6 +4337,60 @@ bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop( |
| return attachment->FormsFeedbackLoop(texture, level, layer); |
| } |
| +bool GLES2DecoderImpl::FormsFramebufferBlitingFeedbackLoop(GLbitfield mask) { |
| + 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 the same image. |
| + if (!read_framebuffer && !draw_framebuffer) |
| + return true; |
| + if (!read_framebuffer || !draw_framebuffer) |
| + return false; |
| + if ((mask & GL_COLOR_BUFFER_BIT) != 0) { |
| + const Framebuffer::Attachment* read_buffer = |
| + read_framebuffer->GetReadBufferAttachment(); |
| + |
| + for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { |
|
Zhenyao Mo
2016/09/09 16:29:57
If you go through attachments of the draw_framebuf
yunchao
2016/09/09 16:47:33
That's true. But we still need to iterate to cover
Zhenyao Mo
2016/09/09 17:39:32
We should always optimize against most common use
|
| + 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)) { |
| + return true; |
| + } |
| + } |
| + } |
| + 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 && |
|
Zhenyao Mo
2016/09/09 16:29:57
nit: wrong indent
yunchao
2016/09/09 16:47:33
Done.
|
| + depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { |
| + return true; |
| + } |
| + } |
| + 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)) { |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| gfx::Size GLES2DecoderImpl::GetBoundReadFramebufferSize() { |
| Framebuffer* framebuffer = |
| GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); |
| @@ -7599,6 +7658,12 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( |
| return; |
| } |
| + if (FormsFramebufferBlitingFeedbackLoop(mask)) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "source buffer and destination buffers are identical"); |
| + return; |
| + } |
| + |
| GLenum src_format = GetBoundReadFramebufferInternalFormat(); |
| GLenum src_type = GetBoundReadFramebufferTextureType(); |