diff options
author | Robert Bragg <robert@linux.intel.com> | 2012-02-20 00:09:37 +0000 |
---|---|---|
committer | Robert Bragg <robert@linux.intel.com> | 2012-02-20 00:25:39 +0000 |
commit | 39de4f7201324baf976450eabd9cd8e9ed6de224 (patch) | |
tree | df294bdbb5b1cd256dc2a800f68ceb2f80bb3ef1 | |
parent | 4a20a08aa250a06225fb1aaaad859d030d21dec5 (diff) | |
download | cogl-wip/rib/master-next.tar.gz |
pipeline: make _equal() cost scale by n bits in differenceswip/rib/master-next
This improves the implementation of _cogl_pipeline_equal() to ensure
that the cost of the function scales by the number of bits set in the
pipelines_difference variable set after calling
_cogl_pipeline_compare_differences() instead of scaling by the number of
state groups cogl tracks.
As Cogl tracks more and more state groups we don't want
_cogl_pipeline_equal() to get slower.
-rw-r--r-- | cogl/cogl-pipeline-private.h | 5 | ||||
-rw-r--r-- | cogl/cogl-pipeline.c | 226 |
2 files changed, 102 insertions, 129 deletions
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h index e0c74a28..b88e4017 100644 --- a/cogl/cogl-pipeline-private.h +++ b/cogl/cogl-pipeline-private.h @@ -188,10 +188,11 @@ typedef enum /* non-sparse */ COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX, - COGL_PIPELINE_STATE_COUNT, - COGL_PIPELINE_STATE_SPARSE_COUNT = COGL_PIPELINE_STATE_COUNT - 1, + COGL_PIPELINE_STATE_COUNT } CoglPipelineStateIndex; +#define COGL_PIPELINE_STATE_SPARSE_COUNT (COGL_PIPELINE_STATE_COUNT - 1) + /* Used in pipeline->differences masks and for notifying pipeline * state changes. * diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c index 87a7fd33..7545855a 100644 --- a/cogl/cogl-pipeline.c +++ b/cogl/cogl-pipeline.c @@ -2090,21 +2090,6 @@ _cogl_pipeline_compare_differences (CoglPipeline *pipeline0, return pipelines_difference; } -static gboolean -simple_property_equal (CoglPipeline **authorities0, - CoglPipeline **authorities1, - unsigned long pipelines_difference, - CoglPipelineStateIndex state_index, - CoglPipelineStateComparitor comparitor) -{ - if (pipelines_difference & (1L<<state_index)) - { - if (!comparitor (authorities0[state_index], authorities1[state_index])) - return FALSE; - } - return TRUE; -} - static void _cogl_pipeline_resolve_authorities (CoglPipeline *pipeline, unsigned long differences, @@ -2174,6 +2159,7 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, unsigned long pipelines_difference; CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT]; CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT]; + int bit; gboolean ret; COGL_STATIC_TIMER (pipeline_equal_timer, @@ -2213,121 +2199,107 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, pipelines_difference, authorities1); - /* FIXME: we should resolve all the required authorities up front since - * that should reduce some repeat ancestor traversals. */ - - if (pipelines_difference & COGL_PIPELINE_STATE_COLOR) + COGL_FLAGS_FOREACH_START (&pipelines_difference, 1, bit) { - CoglPipeline *authority0 = authorities0[COGL_PIPELINE_STATE_COLOR_INDEX]; - CoglPipeline *authority1 = authorities1[COGL_PIPELINE_STATE_COLOR_INDEX]; - - if (!cogl_color_equal (&authority0->color, &authority1->color)) - goto done; - } - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_LIGHTING_INDEX, - _cogl_pipeline_lighting_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, - _cogl_pipeline_alpha_func_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, - _cogl_pipeline_alpha_func_reference_state_equal)) - goto done; - - /* We don't need to compare the detailed blending state if we know - * blending is disabled for both pipelines. */ - if (pipeline0->real_blend_enable && - pipelines_difference & COGL_PIPELINE_STATE_BLEND) - { - CoglPipeline *authority0 = authorities0[COGL_PIPELINE_STATE_BLEND_INDEX]; - CoglPipeline *authority1 = authorities1[COGL_PIPELINE_STATE_BLEND_INDEX]; - - if (!_cogl_pipeline_blend_state_equal (authority0, authority1)) - goto done; - } - - /* XXX: we don't need to compare the BLEND_ENABLE state because it's - * already reflected in ->real_blend_enable */ -#if 0 - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_BLEND_INDEX, - _cogl_pipeline_blend_enable_equal)) - return FALSE; -#endif - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_DEPTH_INDEX, - _cogl_pipeline_depth_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_FOG_INDEX, - _cogl_pipeline_fog_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_CULL_FACE_INDEX, - _cogl_pipeline_cull_face_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_POINT_SIZE_INDEX, - _cogl_pipeline_point_size_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_LOGIC_OPS_INDEX, - _cogl_pipeline_logic_ops_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_USER_SHADER_INDEX, - _cogl_pipeline_user_shader_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_UNIFORMS_INDEX, - _cogl_pipeline_uniforms_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX, - _cogl_pipeline_vertex_snippets_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX, - _cogl_pipeline_fragment_snippets_state_equal)) - goto done; + /* XXX: We considered having an array of callbacks for each state index + * that we'd call here but decided that this way the compiler is more + * likely going to be able to in-line the comparison functions and use + * the index to jump straight to the required code. */ + switch ((CoglPipelineStateIndex)bit) + { + case COGL_PIPELINE_STATE_COLOR_INDEX: + if (!cogl_color_equal (&authorities0[bit]->color, + &authorities1[bit]->color)) + goto done; + break; + case COGL_PIPELINE_STATE_LIGHTING_INDEX: + if (!_cogl_pipeline_lighting_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX: + if (!_cogl_pipeline_alpha_func_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX: + if (!_cogl_pipeline_alpha_func_reference_state_equal ( + authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_BLEND_INDEX: + /* We don't need to compare the detailed blending state if we know + * blending is disabled for both pipelines. */ + if (pipeline0->real_blend_enable) + { + if (!_cogl_pipeline_blend_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + } + break; + case COGL_PIPELINE_STATE_DEPTH_INDEX: + if (!_cogl_pipeline_depth_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_FOG_INDEX: + if (!_cogl_pipeline_fog_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_CULL_FACE_INDEX: + if (!_cogl_pipeline_cull_face_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_POINT_SIZE_INDEX: + if (!_cogl_pipeline_point_size_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_LOGIC_OPS_INDEX: + if (!_cogl_pipeline_logic_ops_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_USER_SHADER_INDEX: + if (!_cogl_pipeline_user_shader_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_UNIFORMS_INDEX: + if (!_cogl_pipeline_uniforms_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX: + if (!_cogl_pipeline_vertex_snippets_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX: + if (!_cogl_pipeline_fragment_snippets_state_equal (authorities0[bit], + authorities1[bit])) + goto done; + break; + case COGL_PIPELINE_STATE_LAYERS_INDEX: + { + if (!_cogl_pipeline_layers_equal (authorities0[bit], + authorities1[bit], + layer_differences, + flags)) + goto done; + break; + } - if (pipelines_difference & COGL_PIPELINE_STATE_LAYERS) - { - CoglPipelineStateIndex state_index = COGL_PIPELINE_STATE_LAYERS_INDEX; - if (!_cogl_pipeline_layers_equal (authorities0[state_index], - authorities1[state_index], - layer_differences, - flags)) - goto done; + case COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX: + case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX: + case COGL_PIPELINE_STATE_COUNT: + g_warn_if_reached (); + } } + COGL_FLAGS_FOREACH_END; ret = TRUE; done: |