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 6f0d2e8db079242a81d3e81a1c5dcb2d04f1e9c2..8ea561fe86e2061e93f6e19274d8383bb12f219b 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -1431,6 +1431,14 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| void DoBufferSubData( |
| GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); |
| + // A workaround to adjust read buffer and draw buffers to GL_NONE |
| + // if the specified read buffer or draw buffers have no image attached. |
|
Zhenyao Mo
2016/11/14 19:42:24
have missing images.
yunchao
2016/11/15 16:21:59
Done.
|
| + // Return false if read buffer has no image or all of the draw buffers |
| + // have no image. Then we can generate INVALID_OPERATION or return directly |
| + // in the callers accordingly. |
| + bool AdjustColorBufferAttachmentsIfNecessary( |
| + bool read, bool draw); |
| + |
| // Wrapper for glCheckFramebufferStatus |
| GLenum DoCheckFramebufferStatus(GLenum target); |
| @@ -7213,6 +7221,13 @@ error::Error GLES2DecoderImpl::HandleDeleteProgram( |
| error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { |
| const char* func_name = "glClear"; |
| DCHECK(!ShouldDeferDraws()); |
| + if (mask & GL_COLOR_BUFFER_BIT && |
|
Zhenyao Mo
2016/11/14 19:42:24
(mask & GL_COLOR_BUFFER_BIT) != 0
yunchao
2016/11/15 16:21:59
Done.
|
| + workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) |
| + return error::kNoError; |
| + } |
| if (CheckBoundDrawFramebufferValid(func_name)) { |
| ApplyDirtyState(); |
| if (workarounds().gl_clear_broken) { |
| @@ -7532,6 +7547,39 @@ void GLES2DecoderImpl::RestoreClearState() { |
| state_.scissor_height); |
| } |
| +bool GLES2DecoderImpl::AdjustColorBufferAttachmentsIfNecessary( |
| + bool read, bool draw) { |
| + DCHECK(workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty); |
| + if (read) { |
| + const Framebuffer* framebuffer = |
| + GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER); |
| + if (framebuffer && |
| + framebuffer->ReadBufferHasNoImage() && |
| + framebuffer->ColorBuffersHaveImage()) { |
| + glReadBuffer(GL_NONE); |
| + return false; |
| + } |
| + } else { |
| + GLsizei num = 0; |
| + GLenum buf[8]; |
| + for (int i = 0; i < 8; ++i) |
| + buf[i] = GL_NONE; |
| + const Framebuffer* framebuffer = |
| + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER); |
| + if (framebuffer && |
| + framebuffer->DrawBuffersHaveNoImage(num, buf) && |
| + framebuffer->ColorBuffersHaveImage()) { |
| + glDrawBuffersARB(8, buf); |
| + } |
| + if (num == 0) { |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { |
| Framebuffer* framebuffer = |
| GetFramebufferInfoForTarget(target); |
| @@ -7542,6 +7590,21 @@ GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { |
| if (completeness != GL_FRAMEBUFFER_COMPLETE) { |
| return completeness; |
| } |
| + |
| + bool has_image = true; |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (target == GL_READ_FRAMEBUFFER) { |
| + has_image = AdjustColorBufferAttachmentsIfNecessary(true, false); |
| + } else { |
| + has_image = AdjustColorBufferAttachmentsIfNecessary(false, true); |
| + } |
| + if (!has_image) { |
| + return GL_FRAMEBUFFER_COMPLETE; |
| + } |
| + } |
| + |
| return framebuffer->GetStatus(texture_manager(), target); |
| } |
| @@ -7832,6 +7895,19 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( |
| const char* func_name = "glBlitFramebufferCHROMIUM"; |
| DCHECK(!ShouldDeferReads() && !ShouldDeferDraws()); |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + (mask & GL_COLOR_BUFFER_BIT) != 0 && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) { |
| + return; |
| + } |
| + if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "no valid color image"); |
| + return; |
| + } |
| + } |
| if (!CheckBoundFramebufferValid(func_name)) { |
| return; |
| } |
| @@ -9806,6 +9882,13 @@ error::Error GLES2DecoderImpl::DoDrawArrays( |
| LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); |
| return error::kNoError; |
| } |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) { |
| + return error::kNoError; |
| + } |
| + } |
| if (!CheckBoundDrawFramebufferValid(function_name)) { |
|
Zhenyao Mo
2016/11/14 19:42:24
All this same code is right above CheckBoundDrawFr
yunchao
2016/11/15 16:21:59
Done.
It is a little different in Clear and Clea
|
| return error::kNoError; |
| } |
| @@ -9970,6 +10053,13 @@ error::Error GLES2DecoderImpl::DoDrawElements(const char* function_name, |
| return error::kNoError; |
| } |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) { |
| + return error::kNoError; |
| + } |
| + } |
| if (!CheckBoundDrawFramebufferValid(function_name)) { |
| return error::kNoError; |
| } |
| @@ -11195,6 +11285,16 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size, |
| return error::kNoError; |
| } |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "no valid color image"); |
| + return error::kNoError; |
| + } |
| + } |
| + |
| if (!CheckBoundReadFramebufferValid( |
| func_name, GL_INVALID_FRAMEBUFFER_OPERATION)) { |
| return error::kNoError; |
| @@ -13828,6 +13928,16 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| return; |
| } |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "no valid color image"); |
| + return; |
| + } |
| + } |
| + |
| if (!CheckBoundReadFramebufferValid(func_name, |
| GL_INVALID_FRAMEBUFFER_OPERATION)) { |
| return; |
| @@ -14075,6 +14185,15 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| return; |
| } |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "no valid color image"); |
| + return; |
| + } |
| + } |
| if (!CheckBoundReadFramebufferValid(func_name, |
| GL_INVALID_FRAMEBUFFER_OPERATION)) { |
| return; |
| @@ -14191,6 +14310,15 @@ void GLES2DecoderImpl::DoCopyTexSubImage3D( |
| return; |
| } |
| + if (workarounds().adjust_framebuffer_complete_status && |
| + SupportsDrawBuffers() && |
| + framebuffer_state_.clear_state_dirty) { |
| + if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "no valid color image"); |
| + return; |
| + } |
| + } |
| if (!CheckBoundReadFramebufferValid(func_name, |
| GL_INVALID_FRAMEBUFFER_OPERATION)) { |
| return; |