Index: gpu/command_buffer/service/context_state.cc |
diff --git a/gpu/command_buffer/service/context_state.cc b/gpu/command_buffer/service/context_state.cc |
index e8912cfe1625b769dc0047b935c2f098aed31da3..88358ef80f9ba7bcd34bba26b3758251cee36391 100644 |
--- a/gpu/command_buffer/service/context_state.cc |
+++ b/gpu/command_buffer/service/context_state.cc |
@@ -26,6 +26,26 @@ void EnableDisable(GLenum pname, bool enable) { |
} |
} |
+GLuint Get2dServiceId(const TextureUnit& unit) { |
+ return unit.bound_texture_2d.get() |
+ ? unit.bound_texture_2d->service_id() : 0; |
+} |
+ |
+GLuint GetCubeServiceId(const TextureUnit& unit) { |
+ return unit.bound_texture_cube_map.get() |
+ ? unit.bound_texture_cube_map->service_id() : 0; |
+} |
+ |
+GLuint GetOesServiceId(const TextureUnit& unit) { |
+ return unit.bound_texture_external_oes.get() |
+ ? unit.bound_texture_external_oes->service_id() : 0; |
+} |
+ |
+GLuint GetArbServiceId(const TextureUnit& unit) { |
+ return unit.bound_texture_rectangle_arb.get() |
+ ? unit.bound_texture_rectangle_arb->service_id() : 0; |
+} |
+ |
} // anonymous namespace. |
TextureUnit::TextureUnit() |
@@ -47,31 +67,48 @@ ContextState::ContextState(FeatureInfo* feature_info, Logger* logger) |
ContextState::~ContextState() { |
} |
-void ContextState::RestoreTextureUnitBindings(GLuint unit) const { |
+void ContextState::RestoreTextureUnitBindings( |
+ GLuint unit, const ContextState* prev_state) const { |
DCHECK_LT(unit, texture_units.size()); |
const TextureUnit& texture_unit = texture_units[unit]; |
- glActiveTexture(GL_TEXTURE0 + unit); |
- GLuint service_id = texture_unit.bound_texture_2d.get() |
- ? texture_unit.bound_texture_2d->service_id() |
- : 0; |
- glBindTexture(GL_TEXTURE_2D, service_id); |
- service_id = texture_unit.bound_texture_cube_map.get() |
- ? texture_unit.bound_texture_cube_map->service_id() |
- : 0; |
- glBindTexture(GL_TEXTURE_CUBE_MAP, service_id); |
- |
- if (feature_info_->feature_flags().oes_egl_image_external) { |
- service_id = texture_unit.bound_texture_external_oes.get() |
- ? texture_unit.bound_texture_external_oes->service_id() |
- : 0; |
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id); |
+ GLuint service_id_2d = Get2dServiceId(texture_unit); |
+ GLuint service_id_cube = GetCubeServiceId(texture_unit); |
+ GLuint service_id_oes = GetOesServiceId(texture_unit); |
+ GLuint service_id_arb = GetArbServiceId(texture_unit); |
+ |
+ bool bind_texture_2d = true; |
+ bool bind_texture_cube = true; |
+ bool bind_texture_oes = feature_info_->feature_flags().oes_egl_image_external; |
+ bool bind_texture_arb = feature_info_->feature_flags().arb_texture_rectangle; |
+ |
+ if (prev_state) { |
+ const TextureUnit& prev_unit = prev_state->texture_units[unit]; |
+ bind_texture_2d = service_id_2d != Get2dServiceId(prev_unit); |
+ bind_texture_cube = service_id_cube != GetCubeServiceId(prev_unit); |
+ bind_texture_oes = |
+ bind_texture_oes && service_id_oes != GetOesServiceId(prev_unit); |
+ bind_texture_arb = |
+ bind_texture_arb && service_id_arb != GetArbServiceId(prev_unit); |
+ } |
+ |
+ // Early-out if nothing has changed from the previous state. |
+ if (!bind_texture_2d && !bind_texture_cube |
+ && !bind_texture_oes && !bind_texture_arb) { |
+ return; |
} |
- if (feature_info_->feature_flags().arb_texture_rectangle) { |
- service_id = texture_unit.bound_texture_rectangle_arb.get() |
- ? texture_unit.bound_texture_rectangle_arb->service_id() |
- : 0; |
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id); |
+ glActiveTexture(GL_TEXTURE0 + unit); |
+ if (bind_texture_2d) { |
+ glBindTexture(GL_TEXTURE_2D, service_id_2d); |
+ } |
+ if (bind_texture_cube) { |
+ glBindTexture(GL_TEXTURE_CUBE_MAP, service_id_cube); |
+ } |
+ if (bind_texture_oes) { |
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id_oes); |
+ } |
+ if (bind_texture_arb) { |
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id_arb); |
} |
} |
@@ -101,10 +138,11 @@ void ContextState::RestoreActiveTexture() const { |
glActiveTexture(GL_TEXTURE0 + active_texture_unit); |
} |
-void ContextState::RestoreAllTextureUnitBindings() const { |
+void ContextState::RestoreAllTextureUnitBindings( |
+ const ContextState* prev_state) const { |
// Restore Texture state. |
for (size_t ii = 0; ii < texture_units.size(); ++ii) { |
- RestoreTextureUnitBindings(ii); |
+ RestoreTextureUnitBindings(ii, prev_state); |
} |
RestoreActiveTexture(); |
} |
@@ -139,8 +177,8 @@ void ContextState::RestoreGlobalState() const { |
InitState(); |
} |
-void ContextState::RestoreState() const { |
- RestoreAllTextureUnitBindings(); |
+void ContextState::RestoreState(const ContextState* prev_state) const { |
+ RestoreAllTextureUnitBindings(prev_state); |
// Restore Attrib State |
// TODO: This if should not be needed. RestoreState is getting called |