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( |