diff options
author | vmiura@chromium.org <vmiura@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-09 12:39:34 +0000 |
---|---|---|
committer | vmiura@chromium.org <vmiura@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-09 12:39:34 +0000 |
commit | 88ba52f7d3bffc205f98e9e44d4460d3a477afdb (patch) | |
tree | 8048a749900960f30a35aa53146c00241707a292 /gpu | |
parent | 2e34462ea26749c00b2f7d8c658a597a57bb86c2 (diff) | |
download | chromium_src-88ba52f7d3bffc205f98e9e44d4460d3a477afdb.zip chromium_src-88ba52f7d3bffc205f98e9e44d4460d3a477afdb.tar.gz chromium_src-88ba52f7d3bffc205f98e9e44d4460d3a477afdb.tar.bz2 |
Filter redundant state changes in gles2::ContextState::RestoreGlobalState().
Reduce GL calls in Virtual GL context restore, by checking for differences
from previous state.
BUG=244701, 353822
Review URL: https://codereview.chromium.org/228263007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262664 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 98 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_state.cc | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_state.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_state_impl_autogen.h | 242 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 6 |
5 files changed, 269 insertions, 91 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index e585d66..14ae1fb 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -7158,40 +7158,82 @@ bool %s::GetStateAs%s( file.Write("}\n") file.Write(""" -void ContextState::InitCapabilities() const { +void ContextState::InitCapabilities(const ContextState* prev_state) const { """) - for capability in _CAPABILITY_FLAGS: - file.Write(" EnableDisable(GL_%s, enable_flags.%s);\n" % - (capability['name'].upper(), capability['name'])) + def WriteCapabilities(test_prev): + for capability in _CAPABILITY_FLAGS: + capability_name = capability['name'] + if test_prev: + file.Write(" if (prev_state->enable_flags.%s != enable_flags.%s)\n" % + (capability_name, capability_name)) + file.Write(" EnableDisable(GL_%s, enable_flags.%s);\n" % + (capability_name.upper(), capability_name)) + + file.Write(" if (prev_state) {") + WriteCapabilities(True) + file.Write(" } else {") + WriteCapabilities(False) + file.Write(" }") + file.Write("""} -void ContextState::InitState() const { +void ContextState::InitState(const ContextState *prev_state) const { """) - # We need to sort the keys so the expectations match - for state_name in sorted(_STATES.keys()): - state = _STATES[state_name] - if state['type'] == 'FrontBack': - num_states = len(state['states']) - for ndx, group in enumerate(Grouper(num_states / 2, state['states'])): + def WriteStates(test_prev): + # We need to sort the keys so the expectations match + for state_name in sorted(_STATES.keys()): + state = _STATES[state_name] + if state['type'] == 'FrontBack': + num_states = len(state['states']) + for ndx, group in enumerate(Grouper(num_states / 2, state['states'])): + if test_prev: + file.Write(" if (") + args = [] + for place, item in enumerate(group): + item_name = item['name'] + args.append('%s' % item_name) + if test_prev: + if place > 0: + file.Write(' ||\n') + file.Write("(%s != prev_state->%s)" % (item_name, item_name)) + if test_prev: + file.Write(")\n") + file.Write( + " gl%s(%s, %s);\n" % + (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args))) + elif state['type'] == 'NamedParameter': + for item in state['states']: + if 'extension_flag' in item: + file.Write(" if (feature_info_->feature_flags().%s)\n " % + item['extension_flag']) + if test_prev: + file.Write(" if (prev_state->%s != %s)\n" % + (item['name'], item['name'])) + file.Write(" gl%s(%s, %s);\n" % + (state['func'], item['enum'], item['name'])) + else: + if test_prev: + file.Write(" if (") args = [] - for item in group: - args.append('%s' % item['name']) - file.Write( - " gl%s(%s, %s);\n" % - (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args))) - elif state['type'] == 'NamedParameter': - for item in state['states']: - if 'extension_flag' in item: - file.Write(" if (feature_info_->feature_flags().%s)\n " % - item['extension_flag']) - file.Write(" gl%s(%s, %s);\n" % - (state['func'], item['enum'], item['name'])) - else: - args = [] - for item in state['states']: - args.append('%s' % item['name']) - file.Write(" gl%s(%s);\n" % (state['func'], ", ".join(args))) + for place, item in enumerate(state['states']): + item_name = item['name'] + args.append('%s' % item_name) + if test_prev: + if place > 0: + file.Write(' ||\n') + file.Write("(%s != prev_state->%s)" % + (item_name, item_name)) + if test_prev: + file.Write(" )\n") + file.Write(" gl%s(%s);\n" % (state['func'], ", ".join(args))) + + file.Write(" if (prev_state) {") + WriteStates(True) + file.Write(" } else {") + WriteStates(False) + file.Write(" }") + file.Write("}\n") file.Write("""bool ContextState::GetEnabled(GLenum cap) const { diff --git a/gpu/command_buffer/service/context_state.cc b/gpu/command_buffer/service/context_state.cc index 6c929de..6c81655 100644 --- a/gpu/command_buffer/service/context_state.cc +++ b/gpu/command_buffer/service/context_state.cc @@ -213,9 +213,9 @@ void ContextState::RestoreAttribute(GLuint attrib_index) const { glVertexAttrib4fv(attrib_index, attrib_values[attrib_index].v); } -void ContextState::RestoreGlobalState() const { - InitCapabilities(); - InitState(); +void ContextState::RestoreGlobalState(const ContextState* prev_state) const { + InitCapabilities(prev_state); + InitState(prev_state); } void ContextState::RestoreState(const ContextState* prev_state) const { @@ -235,7 +235,7 @@ void ContextState::RestoreState(const ContextState* prev_state) const { RestoreBufferBindings(); RestoreRenderbufferBindings(); RestoreProgramBindings(); - RestoreGlobalState(); + RestoreGlobalState(prev_state); } ErrorState* ContextState::GetErrorState() { diff --git a/gpu/command_buffer/service/context_state.h b/gpu/command_buffer/service/context_state.h index 2c1f0e1..d68700f 100644 --- a/gpu/command_buffer/service/context_state.h +++ b/gpu/command_buffer/service/context_state.h @@ -102,15 +102,15 @@ struct GPU_EXPORT ContextState { void Initialize(); void RestoreState(const ContextState* prev_state) const; - void InitCapabilities() const; - void InitState() const; + void InitCapabilities(const ContextState* prev_state) const; + void InitState(const ContextState* prev_state) const; void RestoreActiveTexture() const; void RestoreAllTextureUnitBindings(const ContextState* prev_state) const; void RestoreActiveTextureUnitBinding(unsigned int target) const; void RestoreAttribute(GLuint index) const; void RestoreBufferBindings() const; - void RestoreGlobalState() const; + void RestoreGlobalState(const ContextState* prev_state) const; void RestoreProgramBindings() const; void RestoreRenderbufferBindings() const; void RestoreTextureUnitBindings( diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h index 9a42ae1..2e4d28a 100644 --- a/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/gpu/command_buffer/service/context_state_impl_autogen.h @@ -83,61 +83,197 @@ void ContextState::Initialize() { viewport_height = 1; } -void ContextState::InitCapabilities() const { - EnableDisable(GL_BLEND, enable_flags.blend); - EnableDisable(GL_CULL_FACE, enable_flags.cull_face); - EnableDisable(GL_DEPTH_TEST, enable_flags.depth_test); - EnableDisable(GL_DITHER, enable_flags.dither); - EnableDisable(GL_POLYGON_OFFSET_FILL, enable_flags.polygon_offset_fill); - EnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, - enable_flags.sample_alpha_to_coverage); - EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.sample_coverage); - EnableDisable(GL_SCISSOR_TEST, enable_flags.scissor_test); - EnableDisable(GL_STENCIL_TEST, enable_flags.stencil_test); +void ContextState::InitCapabilities(const ContextState* prev_state) const { + if (prev_state) { + if (prev_state->enable_flags.blend != enable_flags.blend) + EnableDisable(GL_BLEND, enable_flags.blend); + if (prev_state->enable_flags.cull_face != enable_flags.cull_face) + EnableDisable(GL_CULL_FACE, enable_flags.cull_face); + if (prev_state->enable_flags.depth_test != enable_flags.depth_test) + EnableDisable(GL_DEPTH_TEST, enable_flags.depth_test); + if (prev_state->enable_flags.dither != enable_flags.dither) + EnableDisable(GL_DITHER, enable_flags.dither); + if (prev_state->enable_flags.polygon_offset_fill != + enable_flags.polygon_offset_fill) + EnableDisable(GL_POLYGON_OFFSET_FILL, enable_flags.polygon_offset_fill); + if (prev_state->enable_flags.sample_alpha_to_coverage != + enable_flags.sample_alpha_to_coverage) + EnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, + enable_flags.sample_alpha_to_coverage); + if (prev_state->enable_flags.sample_coverage != + enable_flags.sample_coverage) + EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.sample_coverage); + if (prev_state->enable_flags.scissor_test != enable_flags.scissor_test) + EnableDisable(GL_SCISSOR_TEST, enable_flags.scissor_test); + if (prev_state->enable_flags.stencil_test != enable_flags.stencil_test) + EnableDisable(GL_STENCIL_TEST, enable_flags.stencil_test); + } else { + EnableDisable(GL_BLEND, enable_flags.blend); + EnableDisable(GL_CULL_FACE, enable_flags.cull_face); + EnableDisable(GL_DEPTH_TEST, enable_flags.depth_test); + EnableDisable(GL_DITHER, enable_flags.dither); + EnableDisable(GL_POLYGON_OFFSET_FILL, enable_flags.polygon_offset_fill); + EnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, + enable_flags.sample_alpha_to_coverage); + EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.sample_coverage); + EnableDisable(GL_SCISSOR_TEST, enable_flags.scissor_test); + EnableDisable(GL_STENCIL_TEST, enable_flags.stencil_test); + } } -void ContextState::InitState() const { - glBlendColor( - blend_color_red, blend_color_green, blend_color_blue, blend_color_alpha); - glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha); - glBlendFuncSeparate( - blend_source_rgb, blend_dest_rgb, blend_source_alpha, blend_dest_alpha); - glClearColor( - color_clear_red, color_clear_green, color_clear_blue, color_clear_alpha); - glClearDepth(depth_clear); - glClearStencil(stencil_clear); - glColorMask( - color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha); - glCullFace(cull_mode); - glDepthFunc(depth_func); - glDepthMask(depth_mask); - glDepthRange(z_near, z_far); - glFrontFace(front_face); - glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); - if (feature_info_->feature_flags().oes_standard_derivatives) - glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, - hint_fragment_shader_derivative); - glLineWidth(line_width); - glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); - glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); - glPolygonOffset(polygon_offset_factor, polygon_offset_units); - glSampleCoverage(sample_coverage_value, sample_coverage_invert); - glScissor(scissor_x, scissor_y, scissor_width, scissor_height); - glStencilFuncSeparate( - GL_FRONT, stencil_front_func, stencil_front_ref, stencil_front_mask); - glStencilFuncSeparate( - GL_BACK, stencil_back_func, stencil_back_ref, stencil_back_mask); - glStencilMaskSeparate(GL_FRONT, stencil_front_writemask); - glStencilMaskSeparate(GL_BACK, stencil_back_writemask); - glStencilOpSeparate(GL_FRONT, - stencil_front_fail_op, - stencil_front_z_fail_op, - stencil_front_z_pass_op); - glStencilOpSeparate(GL_BACK, - stencil_back_fail_op, - stencil_back_z_fail_op, - stencil_back_z_pass_op); - glViewport(viewport_x, viewport_y, viewport_width, viewport_height); +void ContextState::InitState(const ContextState* prev_state) const { + if (prev_state) { + if ((blend_color_red != prev_state->blend_color_red) || + (blend_color_green != prev_state->blend_color_green) || + (blend_color_blue != prev_state->blend_color_blue) || + (blend_color_alpha != prev_state->blend_color_alpha)) + glBlendColor(blend_color_red, + blend_color_green, + blend_color_blue, + blend_color_alpha); + if ((blend_equation_rgb != prev_state->blend_equation_rgb) || + (blend_equation_alpha != prev_state->blend_equation_alpha)) + glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha); + if ((blend_source_rgb != prev_state->blend_source_rgb) || + (blend_dest_rgb != prev_state->blend_dest_rgb) || + (blend_source_alpha != prev_state->blend_source_alpha) || + (blend_dest_alpha != prev_state->blend_dest_alpha)) + glBlendFuncSeparate(blend_source_rgb, + blend_dest_rgb, + blend_source_alpha, + blend_dest_alpha); + if ((color_clear_red != prev_state->color_clear_red) || + (color_clear_green != prev_state->color_clear_green) || + (color_clear_blue != prev_state->color_clear_blue) || + (color_clear_alpha != prev_state->color_clear_alpha)) + glClearColor(color_clear_red, + color_clear_green, + color_clear_blue, + color_clear_alpha); + if ((depth_clear != prev_state->depth_clear)) + glClearDepth(depth_clear); + if ((stencil_clear != prev_state->stencil_clear)) + glClearStencil(stencil_clear); + if ((color_mask_red != prev_state->color_mask_red) || + (color_mask_green != prev_state->color_mask_green) || + (color_mask_blue != prev_state->color_mask_blue) || + (color_mask_alpha != prev_state->color_mask_alpha)) + glColorMask( + color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha); + if ((cull_mode != prev_state->cull_mode)) + glCullFace(cull_mode); + if ((depth_func != prev_state->depth_func)) + glDepthFunc(depth_func); + if ((depth_mask != prev_state->depth_mask)) + glDepthMask(depth_mask); + if ((z_near != prev_state->z_near) || (z_far != prev_state->z_far)) + glDepthRange(z_near, z_far); + if ((front_face != prev_state->front_face)) + glFrontFace(front_face); + if (prev_state->hint_generate_mipmap != hint_generate_mipmap) + glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + if (feature_info_->feature_flags().oes_standard_derivatives) + if (prev_state->hint_fragment_shader_derivative != + hint_fragment_shader_derivative) + glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, + hint_fragment_shader_derivative); + if ((line_width != prev_state->line_width)) + glLineWidth(line_width); + if (prev_state->pack_alignment != pack_alignment) + glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); + if (prev_state->unpack_alignment != unpack_alignment) + glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); + if ((polygon_offset_factor != prev_state->polygon_offset_factor) || + (polygon_offset_units != prev_state->polygon_offset_units)) + glPolygonOffset(polygon_offset_factor, polygon_offset_units); + if ((sample_coverage_value != prev_state->sample_coverage_value) || + (sample_coverage_invert != prev_state->sample_coverage_invert)) + glSampleCoverage(sample_coverage_value, sample_coverage_invert); + if ((scissor_x != prev_state->scissor_x) || + (scissor_y != prev_state->scissor_y) || + (scissor_width != prev_state->scissor_width) || + (scissor_height != prev_state->scissor_height)) + glScissor(scissor_x, scissor_y, scissor_width, scissor_height); + if ((stencil_front_func != prev_state->stencil_front_func) || + (stencil_front_ref != prev_state->stencil_front_ref) || + (stencil_front_mask != prev_state->stencil_front_mask)) + glStencilFuncSeparate( + GL_FRONT, stencil_front_func, stencil_front_ref, stencil_front_mask); + if ((stencil_back_func != prev_state->stencil_back_func) || + (stencil_back_ref != prev_state->stencil_back_ref) || + (stencil_back_mask != prev_state->stencil_back_mask)) + glStencilFuncSeparate( + GL_BACK, stencil_back_func, stencil_back_ref, stencil_back_mask); + if ((stencil_front_writemask != prev_state->stencil_front_writemask)) + glStencilMaskSeparate(GL_FRONT, stencil_front_writemask); + if ((stencil_back_writemask != prev_state->stencil_back_writemask)) + glStencilMaskSeparate(GL_BACK, stencil_back_writemask); + if ((stencil_front_fail_op != prev_state->stencil_front_fail_op) || + (stencil_front_z_fail_op != prev_state->stencil_front_z_fail_op) || + (stencil_front_z_pass_op != prev_state->stencil_front_z_pass_op)) + glStencilOpSeparate(GL_FRONT, + stencil_front_fail_op, + stencil_front_z_fail_op, + stencil_front_z_pass_op); + if ((stencil_back_fail_op != prev_state->stencil_back_fail_op) || + (stencil_back_z_fail_op != prev_state->stencil_back_z_fail_op) || + (stencil_back_z_pass_op != prev_state->stencil_back_z_pass_op)) + glStencilOpSeparate(GL_BACK, + stencil_back_fail_op, + stencil_back_z_fail_op, + stencil_back_z_pass_op); + if ((viewport_x != prev_state->viewport_x) || + (viewport_y != prev_state->viewport_y) || + (viewport_width != prev_state->viewport_width) || + (viewport_height != prev_state->viewport_height)) + glViewport(viewport_x, viewport_y, viewport_width, viewport_height); + } else { + glBlendColor(blend_color_red, + blend_color_green, + blend_color_blue, + blend_color_alpha); + glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha); + glBlendFuncSeparate( + blend_source_rgb, blend_dest_rgb, blend_source_alpha, blend_dest_alpha); + glClearColor(color_clear_red, + color_clear_green, + color_clear_blue, + color_clear_alpha); + glClearDepth(depth_clear); + glClearStencil(stencil_clear); + glColorMask( + color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha); + glCullFace(cull_mode); + glDepthFunc(depth_func); + glDepthMask(depth_mask); + glDepthRange(z_near, z_far); + glFrontFace(front_face); + glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + if (feature_info_->feature_flags().oes_standard_derivatives) + glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, + hint_fragment_shader_derivative); + glLineWidth(line_width); + glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); + glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); + glPolygonOffset(polygon_offset_factor, polygon_offset_units); + glSampleCoverage(sample_coverage_value, sample_coverage_invert); + glScissor(scissor_x, scissor_y, scissor_width, scissor_height); + glStencilFuncSeparate( + GL_FRONT, stencil_front_func, stencil_front_ref, stencil_front_mask); + glStencilFuncSeparate( + GL_BACK, stencil_back_func, stencil_back_ref, stencil_back_mask); + glStencilMaskSeparate(GL_FRONT, stencil_front_writemask); + glStencilMaskSeparate(GL_BACK, stencil_back_writemask); + glStencilOpSeparate(GL_FRONT, + stencil_front_fail_op, + stencil_front_z_fail_op, + stencil_front_z_pass_op); + glStencilOpSeparate(GL_BACK, + stencil_back_fail_op, + stencil_back_z_fail_op, + stencil_back_z_pass_op); + glViewport(viewport_x, viewport_y, viewport_width, viewport_height); + } } bool ContextState::GetEnabled(GLenum cap) const { switch (cap) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 082a6a9..51c5d23 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -618,7 +618,7 @@ class GLES2DecoderImpl : public GLES2Decoder, state_.RestoreBufferBindings(); } virtual void RestoreGlobalState() const OVERRIDE { - state_.RestoreGlobalState(); + state_.RestoreGlobalState(NULL); } virtual void RestoreProgramBindings() const OVERRIDE { state_.RestoreProgramBindings(); @@ -2598,8 +2598,8 @@ bool GLES2DecoderImpl::Initialize( state_.scissor_height = state_.viewport_height; // Set all the default state because some GL drivers get it wrong. - state_.InitCapabilities(); - state_.InitState(); + state_.InitCapabilities(NULL); + state_.InitState(NULL); glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); DoBindBuffer(GL_ARRAY_BUFFER, 0); |