From 1bba0f5d99b64917b5d1f589a6a7740fcd1b129b Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Mon, 20 Feb 2012 00:09:37 +0000 Subject: [PATCH] pipeline: make _equal() cost scale by n bits in differences 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. Reviewed-by: Neil Roberts --- cogl/cogl-pipeline-private.h | 5 +- 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 e0c74a281..b88e4017f 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 4cc67295d..13a76bb0c 100644 --- a/cogl/cogl-pipeline.c +++ b/cogl/cogl-pipeline.c @@ -2092,21 +2092,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<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 (!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; - - 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: