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 3c69e1a137f44081a7c8c9be19fc156942e8f2f5..682690eaac922edebbc36b30ed599c5aef9aae04 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -621,7 +621,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| void RestoreTextureUnitBindings(unsigned unit) const override { |
| state_.RestoreTextureUnitBindings(unit, NULL); |
| } |
| - void RestoreFramebufferBindings() const override; |
| + void MarkFramebufferBindingsChanged() override; |
| void RestoreRenderbufferBindings() override; |
| void RestoreTextureState(unsigned service_id) const override; |
| @@ -668,9 +668,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| base::TimeDelta GetTotalProcessingCommandsTime() override; |
| void AddProcessingCommandsTime(base::TimeDelta) override; |
| - // Restores the current state to the user's settings. |
| - void RestoreCurrentFramebufferBindings(); |
| - |
| // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. |
| void ApplyDirtyState(); |
| @@ -752,9 +749,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| bool GenSamplersHelper(GLsizei n, const GLuint* client_ids); |
| void DeleteSamplersHelper(GLsizei n, const GLuint* client_ids); |
| - // Workarounds |
| - void OnFboChanged() const; |
| - void OnUseFramebuffer() const; |
| + void ApplyFramebufferBindings(GLenum target); |
| + void OnUseFramebuffer(); |
| error::ContextLostReason GetContextLostReasonFromResetStatus( |
| GLenum reset_status) const; |
| @@ -1758,10 +1754,10 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| switch (target) { |
| case GL_FRAMEBUFFER: |
| case GL_DRAW_FRAMEBUFFER_EXT: |
| - framebuffer = framebuffer_state_.bound_draw_framebuffer.get(); |
| + framebuffer = framebuffer_state_.bound_draw_framebuffer(); |
| break; |
| case GL_READ_FRAMEBUFFER_EXT: |
| - framebuffer = framebuffer_state_.bound_read_framebuffer.get(); |
| + framebuffer = framebuffer_state_.bound_read_framebuffer(); |
| break; |
| default: |
| NOTREACHED(); |
| @@ -1848,13 +1844,13 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| bool ShouldDeferDraws() { |
| return !offscreen_target_frame_buffer_.get() && |
| - framebuffer_state_.bound_draw_framebuffer.get() == NULL && |
| + !framebuffer_state_.bound_draw_framebuffer() && |
| surface_->DeferDraws(); |
| } |
| bool ShouldDeferReads() { |
| return !offscreen_target_frame_buffer_.get() && |
| - framebuffer_state_.bound_read_framebuffer.get() == NULL && |
| + !framebuffer_state_.bound_read_framebuffer() && |
| surface_->DeferDraws(); |
| } |
| @@ -1867,7 +1863,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| if (ShouldDeferDraws()) |
| return error::kDeferCommandUntilLater; |
| if (!offscreen_target_frame_buffer_.get() && |
| - !framebuffer_state_.bound_draw_framebuffer.get() && |
| + !framebuffer_state_.bound_draw_framebuffer() && |
| !surface_->SetBackbufferAllocation(true)) |
| return error::kLostContext; |
| return error::kNoError; |
| @@ -1877,7 +1873,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| if (ShouldDeferReads()) |
| return error::kDeferCommandUntilLater; |
| if (!offscreen_target_frame_buffer_.get() && |
| - !framebuffer_state_.bound_read_framebuffer.get() && |
| + !framebuffer_state_.bound_read_framebuffer() && |
| !surface_->SetBackbufferAllocation(true)) |
| return error::kLostContext; |
| return error::kNoError; |
| @@ -2214,30 +2210,30 @@ ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, |
| ScopedGLErrorSuppressor suppressor( |
| "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState()); |
| glBindFramebufferEXT(GL_FRAMEBUFFER, id); |
| - decoder->OnFboChanged(); |
| + decoder->framebuffer_state_.MarkBindingDirty(GL_FRAMEBUFFER); |
| } |
| ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { |
| - ScopedGLErrorSuppressor suppressor( |
| - "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState()); |
| - decoder_->RestoreCurrentFramebufferBindings(); |
| } |
| ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( |
| GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) |
| : decoder_(decoder) { |
| - resolve_and_bind_ = ( |
| - decoder_->offscreen_target_frame_buffer_.get() && |
| - decoder_->IsOffscreenBufferMultisampled() && |
| - (!decoder_->framebuffer_state_.bound_read_framebuffer.get() || |
| - enforce_internal_framebuffer)); |
| - if (!resolve_and_bind_) |
| + resolve_and_bind_ = |
| + (decoder_->offscreen_target_frame_buffer_.get() && |
| + decoder_->IsOffscreenBufferMultisampled() && |
| + (!decoder_->framebuffer_state_.bound_read_framebuffer() || |
| + enforce_internal_framebuffer)); |
| + if (!resolve_and_bind_) { |
| + decoder_->ApplyFramebufferBindings(GL_READ_FRAMEBUFFER_EXT); |
| return; |
| + } |
| ScopedGLErrorSuppressor suppressor( |
| "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState()); |
| glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, |
| decoder_->offscreen_target_frame_buffer_->id()); |
| + decoder->framebuffer_state_.MarkBindingDirty(GL_READ_FRAMEBUFFER_EXT); |
| GLuint targetid; |
| if (internal) { |
| if (!decoder_->offscreen_resolved_frame_buffer_.get()) { |
| @@ -2266,6 +2262,7 @@ ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( |
| targetid = decoder_->offscreen_saved_frame_buffer_->id(); |
| } |
| glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid); |
| + // Binding will be marked dirty below. |
| const int width = decoder_->offscreen_size_.width(); |
| const int height = decoder_->offscreen_size_.height(); |
| decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); |
| @@ -2280,6 +2277,7 @@ ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( |
| GL_COLOR_BUFFER_BIT, |
| GL_NEAREST); |
| glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); |
| + decoder->framebuffer_state_.MarkBindingDirty(GL_FRAMEBUFFER); |
| } |
| ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { |
| @@ -2288,7 +2286,6 @@ ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { |
| ScopedGLErrorSuppressor suppressor( |
| "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState()); |
| - decoder_->RestoreCurrentFramebufferBindings(); |
| if (decoder_->state_.enable_flags.scissor_test) { |
| decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); |
| } |
| @@ -3529,32 +3526,22 @@ void GLES2DecoderImpl::DeleteBuffersHelper( |
| void GLES2DecoderImpl::DeleteFramebuffersHelper( |
| GLsizei n, const GLuint* client_ids) { |
| - bool supports_separate_framebuffer_binds = |
| - features().chromium_framebuffer_multisample; |
| - |
| + GLenum target = features().chromium_framebuffer_multisample |
| + ? GL_DRAW_FRAMEBUFFER_EXT |
| + : GL_FRAMEBUFFER; |
| for (GLsizei ii = 0; ii < n; ++ii) { |
| Framebuffer* framebuffer = |
| GetFramebuffer(client_ids[ii]); |
| if (framebuffer && !framebuffer->IsDeleted()) { |
| - if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { |
| - GLenum target = supports_separate_framebuffer_binds ? |
| - GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; |
| - |
| + if (framebuffer == framebuffer_state_.bound_draw_framebuffer()) { |
| // Unbind attachments on FBO before deletion. |
| - if (workarounds().unbind_attachments_on_bound_render_fbo_delete) |
| + if (workarounds().unbind_attachments_on_bound_render_fbo_delete) { |
| framebuffer->DoUnbindGLAttachmentsForWorkaround(target); |
| - |
| - glBindFramebufferEXT(target, GetBackbufferServiceId()); |
| - framebuffer_state_.bound_draw_framebuffer = NULL; |
| - framebuffer_state_.clear_state_dirty = true; |
| - } |
| - if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) { |
| - framebuffer_state_.bound_read_framebuffer = NULL; |
| - GLenum target = supports_separate_framebuffer_binds ? |
| - GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; |
| - glBindFramebufferEXT(target, GetBackbufferServiceId()); |
| + } |
| + framebuffer_state_.set_bound_draw_framebuffer(nullptr); |
| } |
| - OnFboChanged(); |
| + if (framebuffer == framebuffer_state_.bound_read_framebuffer()) |
| + framebuffer_state_.set_bound_read_framebuffer(nullptr); |
| RemoveFramebuffer(client_ids[ii]); |
| } |
| } |
| @@ -3573,21 +3560,21 @@ void GLES2DecoderImpl::DeleteRenderbuffersHelper( |
| } |
| // Unbind from current framebuffers. |
| if (supports_separate_framebuffer_binds) { |
| - if (framebuffer_state_.bound_read_framebuffer.get()) { |
| - framebuffer_state_.bound_read_framebuffer |
| - ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer); |
| + if (framebuffer_state_.bound_read_framebuffer()) { |
| + framebuffer_state_.bound_read_framebuffer()->UnbindRenderbuffer( |
| + GL_READ_FRAMEBUFFER_EXT, renderbuffer); |
| } |
| - if (framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.bound_draw_framebuffer |
| - ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); |
| + if (framebuffer_state_.bound_draw_framebuffer()) { |
| + framebuffer_state_.bound_draw_framebuffer()->UnbindRenderbuffer( |
| + GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); |
| } |
| } else { |
| - if (framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.bound_draw_framebuffer |
| - ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer); |
| + if (framebuffer_state_.bound_draw_framebuffer()) { |
| + framebuffer_state_.bound_draw_framebuffer()->UnbindRenderbuffer( |
| + GL_FRAMEBUFFER, renderbuffer); |
| } |
| } |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| RemoveRenderbuffer(client_ids[ii]); |
| } |
| } |
| @@ -3602,25 +3589,25 @@ void GLES2DecoderImpl::DeleteTexturesHelper( |
| if (texture_ref) { |
| Texture* texture = texture_ref->texture(); |
| if (texture->IsAttachedToFramebuffer()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| } |
| // Unbind texture_ref from texture_ref units. |
| state_.UnbindTexture(texture_ref); |
| // Unbind from current framebuffers. |
| if (supports_separate_framebuffer_binds) { |
| - if (framebuffer_state_.bound_read_framebuffer.get()) { |
| - framebuffer_state_.bound_read_framebuffer |
| - ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref); |
| + if (framebuffer_state_.bound_read_framebuffer()) { |
| + framebuffer_state_.bound_read_framebuffer()->UnbindTexture( |
| + GL_READ_FRAMEBUFFER_EXT, texture_ref); |
| } |
| - if (framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.bound_draw_framebuffer |
| - ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref); |
| + if (framebuffer_state_.bound_draw_framebuffer()) { |
| + framebuffer_state_.bound_draw_framebuffer()->UnbindTexture( |
| + GL_DRAW_FRAMEBUFFER_EXT, texture_ref); |
| } |
| } else { |
| - if (framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.bound_draw_framebuffer |
| - ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); |
| + if (framebuffer_state_.bound_draw_framebuffer()) { |
| + framebuffer_state_.bound_draw_framebuffer()->UnbindTexture( |
| + GL_FRAMEBUFFER, texture_ref); |
| } |
| } |
| #if defined(OS_MACOSX) |
| @@ -3676,9 +3663,9 @@ bool GLES2DecoderImpl::MakeCurrent() { |
| // Rebind the FBO if it was unbound by the context. |
| if (workarounds().unbind_fbo_on_context_switch) |
| - RestoreFramebufferBindings(); |
| + MarkFramebufferBindingsChanged(); |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| // Rebind textures if the service ids may have changed. |
| RestoreAllExternalTextureBindingsIfNeeded(); |
| @@ -3692,40 +3679,6 @@ void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { |
| query_manager_->ProcessPendingTransferQueries(); |
| } |
| -static void RebindCurrentFramebuffer( |
| - GLenum target, |
| - Framebuffer* framebuffer, |
| - GLuint back_buffer_service_id) { |
| - GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0; |
| - |
| - if (framebuffer_id == 0) { |
| - framebuffer_id = back_buffer_service_id; |
| - } |
| - |
| - glBindFramebufferEXT(target, framebuffer_id); |
| -} |
| - |
| -void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { |
| - framebuffer_state_.clear_state_dirty = true; |
| - |
| - if (!features().chromium_framebuffer_multisample) { |
| - RebindCurrentFramebuffer( |
| - GL_FRAMEBUFFER, |
| - framebuffer_state_.bound_draw_framebuffer.get(), |
| - GetBackbufferServiceId()); |
| - } else { |
| - RebindCurrentFramebuffer( |
| - GL_READ_FRAMEBUFFER_EXT, |
| - framebuffer_state_.bound_read_framebuffer.get(), |
| - GetBackbufferServiceId()); |
| - RebindCurrentFramebuffer( |
| - GL_DRAW_FRAMEBUFFER_EXT, |
| - framebuffer_state_.bound_draw_framebuffer.get(), |
| - GetBackbufferServiceId()); |
| - } |
| - OnFboChanged(); |
| -} |
| - |
| bool GLES2DecoderImpl::CheckFramebufferValid( |
| Framebuffer* framebuffer, |
| GLenum target, |
| @@ -3808,6 +3761,7 @@ bool GLES2DecoderImpl::CheckBoundDrawFramebufferValid( |
| bool clear_uncleared_images, const char* func_name) { |
| GLenum target = features().chromium_framebuffer_multisample ? |
| GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER; |
| + ApplyFramebufferBindings(target); |
| Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); |
| bool valid = CheckFramebufferValid( |
| framebuffer, target, clear_uncleared_images, func_name); |
| @@ -3819,6 +3773,7 @@ bool GLES2DecoderImpl::CheckBoundDrawFramebufferValid( |
| bool GLES2DecoderImpl::CheckBoundReadFramebufferValid(const char* func_name) { |
| GLenum target = features().chromium_framebuffer_multisample ? |
| GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER; |
| + ApplyFramebufferBindings(target); |
| Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); |
| bool valid = CheckFramebufferValid(framebuffer, target, true, func_name); |
| return valid; |
| @@ -3839,9 +3794,9 @@ GLint GLES2DecoderImpl::GetColorEncodingFromInternalFormat( |
| bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop( |
| TextureRef* texture, GLint level) { |
| - Framebuffer* framebuffer = features().chromium_framebuffer_multisample ? |
| - framebuffer_state_.bound_read_framebuffer.get() : |
| - framebuffer_state_.bound_draw_framebuffer.get(); |
| + Framebuffer* framebuffer = features().chromium_framebuffer_multisample |
| + ? framebuffer_state_.bound_read_framebuffer() |
| + : framebuffer_state_.bound_draw_framebuffer(); |
| if (!framebuffer) |
| return false; |
| const Framebuffer::Attachment* attachment = framebuffer->GetAttachment( |
| @@ -4062,8 +4017,8 @@ void GLES2DecoderImpl::Destroy(bool have_context) { |
| state_.bound_pixel_unpack_buffer = NULL; |
| state_.bound_transform_feedback_buffer = NULL; |
| state_.bound_uniform_buffer = NULL; |
| - framebuffer_state_.bound_read_framebuffer = NULL; |
| - framebuffer_state_.bound_draw_framebuffer = NULL; |
| + framebuffer_state_.set_bound_read_framebuffer(nullptr); |
| + framebuffer_state_.set_bound_draw_framebuffer(nullptr); |
| state_.bound_renderbuffer = NULL; |
| if (offscreen_saved_color_texture_info_.get()) { |
| @@ -4208,7 +4163,15 @@ void GLES2DecoderImpl::SetSurface( |
| DCHECK(context_->IsCurrent(NULL)); |
| DCHECK(surface_.get()); |
| surface_ = surface; |
| - RestoreCurrentFramebufferBindings(); |
| + MarkFramebufferBindingsChanged(); |
| + // Applying the framebuffer bindings would be possible to be done lazily. |
| + // For ease of testing, commit the bindings now. |
| + if (!features().chromium_framebuffer_multisample) { |
| + ApplyFramebufferBindings(GL_FRAMEBUFFER); |
| + } else { |
| + ApplyFramebufferBindings(GL_DRAW_FRAMEBUFFER_EXT); |
| + ApplyFramebufferBindings(GL_READ_FRAMEBUFFER_EXT); |
| + } |
| } |
| void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) { |
| @@ -4733,7 +4696,7 @@ bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() { |
| } |
| void GLES2DecoderImpl::ApplyDirtyState() { |
| - if (framebuffer_state_.clear_state_dirty) { |
| + if (framebuffer_state_.is_draw_framebuffer_clear_state_dirty()) { |
| bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(); |
| state_.SetDeviceColorMask(state_.color_mask_red, |
| state_.color_mask_green, |
| @@ -4753,7 +4716,7 @@ void GLES2DecoderImpl::ApplyDirtyState() { |
| GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth); |
| state_.SetDeviceCapabilityState( |
| GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil); |
| - framebuffer_state_.clear_state_dirty = false; |
| + framebuffer_state_.set_draw_framebuffer_clear_state_dirty(false); |
| } |
| } |
| @@ -4766,28 +4729,13 @@ GLuint GLES2DecoderImpl::GetBackbufferServiceId() const { |
| void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) { |
| TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState", |
| "context", logger_.GetLogPrefix()); |
| - // Restore the Framebuffer first because of bugs in Intel drivers. |
| - // Intel drivers incorrectly clip the viewport settings to |
| - // the size of the current framebuffer object. |
| - RestoreFramebufferBindings(); |
| + MarkFramebufferBindingsChanged(); |
|
vmiura
2016/04/28 22:28:20
Based on the previous comment here, we have to ens
|
| state_.RestoreState(prev_state); |
| } |
| -void GLES2DecoderImpl::RestoreFramebufferBindings() const { |
| - GLuint service_id = |
| - framebuffer_state_.bound_draw_framebuffer.get() |
| - ? framebuffer_state_.bound_draw_framebuffer->service_id() |
| - : GetBackbufferServiceId(); |
| - if (!features().chromium_framebuffer_multisample) { |
| - glBindFramebufferEXT(GL_FRAMEBUFFER, service_id); |
| - } else { |
| - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); |
| - service_id = framebuffer_state_.bound_read_framebuffer.get() |
| - ? framebuffer_state_.bound_read_framebuffer->service_id() |
| - : GetBackbufferServiceId(); |
| - glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id); |
| - } |
| - OnFboChanged(); |
| +void GLES2DecoderImpl::MarkFramebufferBindingsChanged() { |
| + framebuffer_state_.MarkBindingDirty(GL_DRAW_FRAMEBUFFER_EXT); |
| + framebuffer_state_.MarkBindingDirty(GL_READ_FRAMEBUFFER_EXT); |
| } |
| void GLES2DecoderImpl::RestoreRenderbufferBindings() { |
| @@ -4844,15 +4792,24 @@ uint32_t GLES2DecoderImpl::GetAndClearBackbufferClearBitsForTest() { |
| return clear_bits; |
| } |
| -void GLES2DecoderImpl::OnFboChanged() const { |
| +void GLES2DecoderImpl::ApplyFramebufferBindings(GLenum target) { |
| + if (!framebuffer_state_.IsBindingDirty(target)) |
| + return; |
| + Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); |
| + GLuint service_id = |
| + framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); |
| + |
| + glBindFramebufferEXT(target, service_id); |
| + |
| + framebuffer_state_.MarkBindingClean(target); |
| + |
| if (workarounds().restore_scissor_on_fbo_change) |
| state_.fbo_binding_for_scissor_workaround_dirty = true; |
| } |
| // Called after the FBO is checked for completeness. |
| -void GLES2DecoderImpl::OnUseFramebuffer() const { |
| +void GLES2DecoderImpl::OnUseFramebuffer() { |
| if (state_.fbo_binding_for_scissor_workaround_dirty) { |
| - state_.fbo_binding_for_scissor_workaround_dirty = false; |
| // The driver forgets the correct scissor when modifying the FBO binding. |
| glScissor(state_.scissor_x, |
| state_.scissor_y, |
| @@ -4867,7 +4824,6 @@ void GLES2DecoderImpl::OnUseFramebuffer() const { |
| void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { |
| Framebuffer* framebuffer = NULL; |
| - GLuint service_id = 0; |
| if (client_id != 0) { |
| framebuffer = GetFramebuffer(client_id); |
| if (!framebuffer) { |
| @@ -4879,35 +4835,20 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { |
| } |
| // It's a new id so make a framebuffer framebuffer for it. |
| + GLuint service_id = 0; |
| glGenFramebuffersEXT(1, &service_id); |
| CreateFramebuffer(client_id, service_id); |
| framebuffer = GetFramebuffer(client_id); |
| - } else { |
| - service_id = framebuffer->service_id(); |
| } |
| framebuffer->MarkAsValid(); |
| } |
| LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer"); |
| - if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { |
| - framebuffer_state_.bound_draw_framebuffer = framebuffer; |
| - } |
| - |
| - // vmiura: This looks like dup code |
| - if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { |
| - framebuffer_state_.bound_read_framebuffer = framebuffer; |
| - } |
| - |
| - framebuffer_state_.clear_state_dirty = true; |
| - |
| - // If we are rendering to the backbuffer get the FBO id for any simulated |
| - // backbuffer. |
| - if (framebuffer == NULL) { |
| - service_id = GetBackbufferServiceId(); |
| - } |
| - |
| - glBindFramebufferEXT(target, service_id); |
| - OnFboChanged(); |
| + framebuffer_state_.SetBoundFramebuffer(target, framebuffer); |
| + // Currently we apply the framebuffer binding directly. In the future, |
| + // this may not be neccessary. Current test expectations prevent more |
| + // lazy application. |
| + ApplyFramebufferBindings(target); |
| } |
| void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { |
| @@ -6286,11 +6227,8 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer( |
| GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer"); |
| if (error == GL_NO_ERROR) { |
| framebuffer->AttachRenderbuffer(attachment, renderbuffer); |
| + framebuffer_state_.NotifyFramebufferChanged(framebuffer); |
| } |
| - if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| - } |
| - OnFboChanged(); |
| } |
| void GLES2DecoderImpl::DoDisable(GLenum cap) { |
| @@ -6414,7 +6352,7 @@ void GLES2DecoderImpl::ClearUnclearedAttachments( |
| } |
| void GLES2DecoderImpl::RestoreClearState() { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.set_draw_framebuffer_clear_state_dirty(true); |
| glClearColor( |
| state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue, |
| state_.color_clear_alpha); |
| @@ -6495,6 +6433,7 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon( |
| if (texture_ref) |
| DoCopyTexImageIfNeeded(texture_ref->texture(), textarget); |
| + ApplyFramebufferBindings(target); |
| std::vector<GLenum> attachments; |
| if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { |
| attachments.push_back(GL_DEPTH_ATTACHMENT); |
| @@ -6521,12 +6460,8 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon( |
| if (error == GL_NO_ERROR) { |
| framebuffer->AttachTexture(attachment, texture_ref, textarget, level, |
| samples); |
| + framebuffer_state_.NotifyFramebufferChanged(framebuffer); |
| } |
| - if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| - } |
| - |
| - OnFboChanged(); |
| } |
| void GLES2DecoderImpl::DoFramebufferTextureLayer( |
| @@ -6552,6 +6487,7 @@ void GLES2DecoderImpl::DoFramebufferTextureLayer( |
| } |
| service_id = texture_ref->service_id(); |
| } |
| + ApplyFramebufferBindings(target); |
| LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTextureLayer"); |
| glFramebufferTextureLayer(target, attachment, service_id, level, layer); |
| GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTextureLayer"); |
| @@ -6559,9 +6495,7 @@ void GLES2DecoderImpl::DoFramebufferTextureLayer( |
| framebuffer->AttachTextureLayer(attachment, texture_ref, |
| texture_ref ? texture_ref->texture()->target() : 0, |
| level, layer); |
| - } |
| - if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyFramebufferChanged(framebuffer); |
| } |
| } |
| @@ -6629,7 +6563,7 @@ void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( |
| *params = attachment_object ? attachment_object->object_name() : 0; |
| return; |
| } |
| - |
| + ApplyFramebufferBindings(target); |
| glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); |
| // We didn't perform a full error check before gl call. |
| LOCAL_PEEK_GL_ERROR(kFunctionName); |
| @@ -10324,6 +10258,7 @@ bool GLES2DecoderImpl::ClearLevel(Texture* texture, |
| GLuint fb = 0; |
| glGenFramebuffersEXT(1, &fb); |
| glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); |
| + framebuffer_state_.MarkBindingDirty(GL_DRAW_FRAMEBUFFER_EXT); |
| glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, |
| target, texture->service_id(), level); |
| @@ -10336,6 +10271,7 @@ bool GLES2DecoderImpl::ClearLevel(Texture* texture, |
| // ANGLE promises a depth only attachment ok. |
| if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != |
| GL_FRAMEBUFFER_COMPLETE) { |
| + ApplyFramebufferBindings(GL_DRAW_FRAMEBUFFER_EXT); |
| return false; |
| } |
| glClearStencil(0); |
| @@ -10350,11 +10286,7 @@ bool GLES2DecoderImpl::ClearLevel(Texture* texture, |
| RestoreClearState(); |
| glDeleteFramebuffersEXT(1, &fb); |
| - Framebuffer* framebuffer = |
| - GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); |
| - GLuint fb_service_id = |
| - framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); |
| - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id); |
| + ApplyFramebufferBindings(GL_DRAW_FRAMEBUFFER_EXT); |
| return true; |
| } |
| @@ -11009,7 +10941,7 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D( |
| } |
| if (texture->IsAttachedToFramebuffer()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| } |
| std::unique_ptr<int8_t[]> zero; |
| @@ -11204,7 +11136,7 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage3D( |
| } |
| if (texture->IsAttachedToFramebuffer()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| } |
| std::unique_ptr<int8_t[]> zero; |
| @@ -11757,7 +11689,7 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| gfx::Size size = GetBoundReadFrameBufferSize(); |
| if (texture->IsAttachedToFramebuffer()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| } |
| // Clip to size to source dimensions |
| @@ -14362,7 +14294,7 @@ void GLES2DecoderImpl::TexStorageImpl( |
| } |
| Texture* texture = texture_ref->texture(); |
| if (texture->IsAttachedToFramebuffer()) { |
| - framebuffer_state_.clear_state_dirty = true; |
| + framebuffer_state_.NotifyBoundFramebuffersChanged(); |
| } |
| if (texture->IsImmutable()) { |
| LOCAL_SET_GL_ERROR( |