summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2012-02-20 00:09:37 +0000
committerRobert Bragg <robert@linux.intel.com>2012-02-20 00:25:39 +0000
commit39de4f7201324baf976450eabd9cd8e9ed6de224 (patch)
treedf294bdbb5b1cd256dc2a800f68ceb2f80bb3ef1
parent4a20a08aa250a06225fb1aaaad859d030d21dec5 (diff)
downloadcogl-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.h5
-rw-r--r--cogl/cogl-pipeline.c226
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: