mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 05:12:15 +00:00
pipeline: generalize _cogl_pipeline_equal
_cogl_pipeline_equal now accepts a mask of pipeline differences and layer differences to constrain what state will be compared. In addition a set of flags are passed that can tweak the comparison semantics for some state groups. For example when comparing layer textures we sometimes only need to compare the texture target and can ignore the data itself. In updating the code this patch also changes it so all required pipeline authorities are resolved in one step up-front instead of resolving the authority for each state group in turn and repeatedly having to traverse the pipeline's ancestry. This adds two new functions _cogl_pipeline_resolve_authorities and _cogl_pipeline_layer_resolve_authorities to handle resolving a set of authorities.
This commit is contained in:
parent
8e899985c6
commit
2c9cd76baa
@ -406,13 +406,12 @@ compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
|
||||
{
|
||||
/* batch rectangles using compatible pipelines */
|
||||
|
||||
/* XXX: _cogl_pipeline_equal may give false negatives since it avoids
|
||||
* deep comparisons as an optimization. It aims to compare enough so
|
||||
* that we that we are able to batch the 90% common cases, but may not
|
||||
* look at less common differences. */
|
||||
if (_cogl_pipeline_equal (entry0->pipeline,
|
||||
entry1->pipeline,
|
||||
TRUE))
|
||||
(COGL_PIPELINE_STATE_ALL &
|
||||
~COGL_PIPELINE_STATE_COLOR),
|
||||
COGL_PIPELINE_LAYER_STATE_ALL,
|
||||
0))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -71,30 +71,55 @@ typedef struct _CoglPipelineLayer CoglPipelineLayer;
|
||||
#define COGL_PIPELINE_BACKEND_DEFAULT 0
|
||||
#define COGL_PIPELINE_BACKEND_UNDEFINED 3
|
||||
|
||||
/* XXX: should I rename these as
|
||||
* COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ?
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT = 1L<<0,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE = 1L<<1,
|
||||
COGL_PIPELINE_LAYER_STATE_FILTERS = 1L<<2,
|
||||
COGL_PIPELINE_LAYER_STATE_WRAP_MODES = 1L<<3,
|
||||
/* sparse state */
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE = 1L<<4,
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT = 1L<<5,
|
||||
COGL_PIPELINE_LAYER_STATE_USER_MATRIX = 1L<<6,
|
||||
/* note: layers don't currently have any non-sparse state */
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS = 1L<<7,
|
||||
COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT,
|
||||
COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT
|
||||
} CoglPipelineLayerStateIndex;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_FILTERS =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_WRAP_MODES =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_USER_MATRIX =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
|
||||
|
||||
/* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_ALL =
|
||||
(1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1,
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_ALL_SPARSE =
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT |
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE |
|
||||
COGL_PIPELINE_LAYER_STATE_FILTERS |
|
||||
COGL_PIPELINE_LAYER_STATE_WRAP_MODES |
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE |
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT |
|
||||
COGL_PIPELINE_LAYER_STATE_USER_MATRIX |
|
||||
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS,
|
||||
(1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1,
|
||||
|
||||
COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE =
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE |
|
||||
@ -259,37 +284,68 @@ struct _CoglPipelineLayer
|
||||
|
||||
};
|
||||
|
||||
/* XXX: should I rename these as
|
||||
* COGL_PIPELINE_STATE_INDEX_XYZ... ?
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* sparse state */
|
||||
COGL_PIPELINE_STATE_COLOR_INDEX,
|
||||
COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX,
|
||||
COGL_PIPELINE_STATE_LAYERS_INDEX,
|
||||
COGL_PIPELINE_STATE_LIGHTING_INDEX,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX,
|
||||
COGL_PIPELINE_STATE_BLEND_INDEX,
|
||||
COGL_PIPELINE_STATE_USER_SHADER_INDEX,
|
||||
COGL_PIPELINE_STATE_DEPTH_INDEX,
|
||||
COGL_PIPELINE_STATE_FOG_INDEX,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
|
||||
/* non-sparse */
|
||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
||||
|
||||
COGL_PIPELINE_STATE_COUNT,
|
||||
COGL_PIPELINE_STATE_SPARSE_COUNT = COGL_PIPELINE_STATE_COUNT - 1,
|
||||
} CoglPipelineStateIndex;
|
||||
|
||||
/* Used in pipeline->differences masks and for notifying pipeline
|
||||
* state changes... */
|
||||
typedef enum _CoglPipelineState
|
||||
{
|
||||
COGL_PIPELINE_STATE_COLOR = 1L<<0,
|
||||
COGL_PIPELINE_STATE_BLEND_ENABLE = 1L<<1,
|
||||
COGL_PIPELINE_STATE_LAYERS = 1L<<2,
|
||||
COGL_PIPELINE_STATE_COLOR =
|
||||
1L<<COGL_PIPELINE_STATE_COLOR_INDEX,
|
||||
COGL_PIPELINE_STATE_BLEND_ENABLE =
|
||||
1L<<COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX,
|
||||
COGL_PIPELINE_STATE_LAYERS =
|
||||
1L<<COGL_PIPELINE_STATE_LAYERS_INDEX,
|
||||
|
||||
COGL_PIPELINE_STATE_LIGHTING = 1L<<3,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC = 1L<<4,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE = 1L<<5,
|
||||
COGL_PIPELINE_STATE_BLEND = 1L<<6,
|
||||
COGL_PIPELINE_STATE_USER_SHADER = 1L<<7,
|
||||
COGL_PIPELINE_STATE_DEPTH = 1L<<8,
|
||||
COGL_PIPELINE_STATE_FOG = 1L<<9,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE = 1L<<10,
|
||||
COGL_PIPELINE_STATE_LIGHTING =
|
||||
1L<<COGL_PIPELINE_STATE_LIGHTING_INDEX,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC =
|
||||
1L<<COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE =
|
||||
1L<<COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX,
|
||||
COGL_PIPELINE_STATE_BLEND =
|
||||
1L<<COGL_PIPELINE_STATE_BLEND_INDEX,
|
||||
COGL_PIPELINE_STATE_USER_SHADER =
|
||||
1L<<COGL_PIPELINE_STATE_USER_SHADER_INDEX,
|
||||
COGL_PIPELINE_STATE_DEPTH =
|
||||
1L<<COGL_PIPELINE_STATE_DEPTH_INDEX,
|
||||
COGL_PIPELINE_STATE_FOG =
|
||||
1L<<COGL_PIPELINE_STATE_FOG_INDEX,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE =
|
||||
1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
|
||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE = 1L<<11,
|
||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE =
|
||||
1L<<COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
||||
|
||||
COGL_PIPELINE_STATE_ALL =
|
||||
((1L<<COGL_PIPELINE_STATE_COUNT) - 1),
|
||||
|
||||
COGL_PIPELINE_STATE_ALL_SPARSE =
|
||||
COGL_PIPELINE_STATE_COLOR |
|
||||
COGL_PIPELINE_STATE_BLEND_ENABLE |
|
||||
COGL_PIPELINE_STATE_LAYERS |
|
||||
COGL_PIPELINE_STATE_LIGHTING |
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC |
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE |
|
||||
COGL_PIPELINE_STATE_BLEND |
|
||||
COGL_PIPELINE_STATE_USER_SHADER |
|
||||
COGL_PIPELINE_STATE_DEPTH |
|
||||
COGL_PIPELINE_STATE_FOG |
|
||||
COGL_PIPELINE_STATE_POINT_SIZE,
|
||||
(COGL_PIPELINE_STATE_ALL
|
||||
& ~COGL_PIPELINE_STATE_REAL_BLEND_ENABLE),
|
||||
|
||||
COGL_PIPELINE_STATE_AFFECTS_BLENDING =
|
||||
COGL_PIPELINE_STATE_COLOR |
|
||||
@ -834,10 +890,23 @@ unsigned long
|
||||
_cogl_pipeline_compare_differences (CoglPipeline *pipeline0,
|
||||
CoglPipeline *pipeline1);
|
||||
|
||||
/* Sometimes when evaluating pipelines, either during comparisons or
|
||||
* if calculating a hash value we need to tweak the evaluation
|
||||
* semantics */
|
||||
typedef enum _CoglPipelineEvalFlags
|
||||
{
|
||||
/* When evaluating a pipeline-layer with associated textures then
|
||||
* evaluate the texture target, but don't consider the texture data
|
||||
* itself. */
|
||||
COGL_PIPELINE_EVAL_FLAG_IGNORE_TEXTURE_DATA = 1L<<0
|
||||
} CoglPipelineEvalFlags;
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
CoglPipeline *pipeline1,
|
||||
gboolean skip_gl_color);
|
||||
unsigned long differences,
|
||||
unsigned long layer_differences,
|
||||
CoglPipelineEvalFlags flags);
|
||||
|
||||
CoglPipeline *
|
||||
_cogl_pipeline_journal_ref (CoglPipeline *pipeline);
|
||||
|
@ -2708,7 +2708,8 @@ _cogl_pipeline_apply_overrides (CoglPipeline *pipeline,
|
||||
|
||||
static gboolean
|
||||
_cogl_pipeline_layer_texture_equal (CoglPipelineLayer *authority0,
|
||||
CoglPipelineLayer *authority1)
|
||||
CoglPipelineLayer *authority1,
|
||||
CoglPipelineEvalFlags flags)
|
||||
{
|
||||
GLuint gl_handle0, gl_handle1;
|
||||
GLenum gl_target0, gl_target1;
|
||||
@ -2716,8 +2717,10 @@ _cogl_pipeline_layer_texture_equal (CoglPipelineLayer *authority0,
|
||||
cogl_texture_get_gl_texture (authority0->texture, &gl_handle0, &gl_target0);
|
||||
cogl_texture_get_gl_texture (authority1->texture, &gl_handle1, &gl_target1);
|
||||
|
||||
return (gl_handle0 == gl_handle1 &&
|
||||
gl_target0 == gl_target1);
|
||||
if (flags & COGL_PIPELINE_EVAL_FLAG_IGNORE_TEXTURE_DATA)
|
||||
return (gl_target0 == gl_target1);
|
||||
else
|
||||
return (gl_handle0 == gl_handle1 && gl_target0 == gl_target1);
|
||||
}
|
||||
|
||||
/* Determine the mask of differences between two layers.
|
||||
@ -2915,24 +2918,58 @@ typedef gboolean
|
||||
CoglPipelineLayer *authority1);
|
||||
|
||||
static gboolean
|
||||
layer_state_equal (CoglPipelineLayerState state,
|
||||
CoglPipelineLayer *layer0,
|
||||
CoglPipelineLayer *layer1,
|
||||
layer_state_equal (CoglPipelineLayerStateIndex state_index,
|
||||
CoglPipelineLayer **authorities0,
|
||||
CoglPipelineLayer **authorities1,
|
||||
CoglPipelineLayerStateComparitor comparitor)
|
||||
{
|
||||
CoglPipelineLayer *authority0 =
|
||||
_cogl_pipeline_layer_get_authority (layer0, state);
|
||||
CoglPipelineLayer *authority1 =
|
||||
_cogl_pipeline_layer_get_authority (layer1, state);
|
||||
return comparitor (authorities0[state_index], authorities1[state_index]);
|
||||
}
|
||||
|
||||
return comparitor (authority0, authority1);
|
||||
static void
|
||||
_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer,
|
||||
unsigned long differences,
|
||||
CoglPipelineLayer **authorities)
|
||||
{
|
||||
unsigned long remaining = differences;
|
||||
CoglPipelineLayer *authority = layer;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned long found = authority->differences & remaining;
|
||||
int i;
|
||||
|
||||
if (found == 0)
|
||||
continue;
|
||||
|
||||
for (i = 0; True; i++)
|
||||
{
|
||||
unsigned long state = (1L<<i);
|
||||
|
||||
if (state & found)
|
||||
authorities[i] = authority;
|
||||
else if (state > found)
|
||||
break;
|
||||
}
|
||||
|
||||
remaining &= ~found;
|
||||
if (remaining == 0)
|
||||
return;
|
||||
}
|
||||
while ((authority = _cogl_pipeline_layer_get_parent (authority)));
|
||||
|
||||
g_assert (remaining == 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
|
||||
CoglPipelineLayer *layer1)
|
||||
CoglPipelineLayer *layer1,
|
||||
unsigned long differences_mask,
|
||||
CoglPipelineEvalFlags flags)
|
||||
{
|
||||
unsigned long layers_difference;
|
||||
CoglPipelineLayer *authorities0[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT];
|
||||
CoglPipelineLayer *authorities1[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT];
|
||||
|
||||
if (layer0 == layer1)
|
||||
return TRUE;
|
||||
@ -2940,45 +2977,59 @@ _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
|
||||
layers_difference =
|
||||
_cogl_pipeline_layer_compare_differences (layer0, layer1);
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_TEXTURE,
|
||||
layer0, layer1,
|
||||
_cogl_pipeline_layer_texture_equal))
|
||||
return FALSE;
|
||||
/* Only compare the sparse state groups requested by the caller... */
|
||||
layers_difference &= differences_mask;
|
||||
|
||||
_cogl_pipeline_layer_resolve_authorities (layer0,
|
||||
layers_difference,
|
||||
authorities0);
|
||||
_cogl_pipeline_layer_resolve_authorities (layer1,
|
||||
layers_difference,
|
||||
authorities1);
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE)
|
||||
{
|
||||
CoglPipelineLayerStateIndex state_index =
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_INDEX;
|
||||
if (!_cogl_pipeline_layer_texture_equal (authorities0[state_index],
|
||||
authorities1[state_index],
|
||||
flags))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE,
|
||||
layer0, layer1,
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
||||
authorities0, authorities1,
|
||||
_cogl_pipeline_layer_combine_state_equal))
|
||||
return FALSE;
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT,
|
||||
layer0, layer1,
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
|
||||
authorities0, authorities1,
|
||||
_cogl_pipeline_layer_combine_constant_equal))
|
||||
return FALSE;
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_FILTERS &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_FILTERS,
|
||||
layer0, layer1,
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
|
||||
authorities0, authorities1,
|
||||
_cogl_pipeline_layer_filters_equal))
|
||||
return FALSE;
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_WRAP_MODES &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_WRAP_MODES,
|
||||
layer0, layer1,
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
|
||||
authorities0, authorities1,
|
||||
_cogl_pipeline_layer_wrap_modes_equal))
|
||||
return FALSE;
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_USER_MATRIX,
|
||||
layer0, layer1,
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
|
||||
authorities0, authorities1,
|
||||
_cogl_pipeline_layer_user_matrix_equal))
|
||||
return FALSE;
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS &&
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS,
|
||||
layer0, layer1,
|
||||
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
|
||||
authorities0, authorities1,
|
||||
_cogl_pipeline_layer_point_sprite_coords_equal))
|
||||
return FALSE;
|
||||
|
||||
@ -3065,9 +3116,15 @@ _cogl_pipeline_blend_state_equal (CoglPipeline *authority0,
|
||||
blend_state1->blend_dst_factor_rgb)
|
||||
return FALSE;
|
||||
#ifndef HAVE_COGL_GLES
|
||||
if (!cogl_color_equal (&blend_state0->blend_constant,
|
||||
&blend_state1->blend_constant))
|
||||
return FALSE;
|
||||
if (blend_state0->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
|
||||
blend_state0->blend_src_factor_rgb == GL_CONSTANT_COLOR ||
|
||||
blend_state0->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
|
||||
blend_state0->blend_dst_factor_rgb == GL_CONSTANT_COLOR)
|
||||
{
|
||||
if (!cogl_color_equal (&blend_state0->blend_constant,
|
||||
&blend_state1->blend_constant))
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
@ -3121,7 +3178,9 @@ _cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
||||
|
||||
static gboolean
|
||||
_cogl_pipeline_layers_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1)
|
||||
CoglPipeline *authority1,
|
||||
unsigned long differences,
|
||||
CoglPipelineEvalFlags flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -3134,7 +3193,9 @@ _cogl_pipeline_layers_equal (CoglPipeline *authority0,
|
||||
for (i = 0; i < authority0->n_layers; i++)
|
||||
{
|
||||
if (!_cogl_pipeline_layer_equal (authority0->layers_cache[i],
|
||||
authority1->layers_cache[i]))
|
||||
authority1->layers_cache[i],
|
||||
differences,
|
||||
flags))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -3229,21 +3290,55 @@ _cogl_pipeline_compare_differences (CoglPipeline *pipeline0,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
simple_property_equal (CoglPipeline *pipeline0,
|
||||
CoglPipeline *pipeline1,
|
||||
simple_property_equal (CoglPipeline **authorities0,
|
||||
CoglPipeline **authorities1,
|
||||
unsigned long pipelines_difference,
|
||||
CoglPipelineState state,
|
||||
CoglPipelineStateIndex state_index,
|
||||
CoglPipelineStateComparitor comparitor)
|
||||
{
|
||||
if (pipelines_difference & state)
|
||||
if (pipelines_difference & (1L<<state_index))
|
||||
{
|
||||
if (!comparitor (_cogl_pipeline_get_authority (pipeline0, state),
|
||||
_cogl_pipeline_get_authority (pipeline1, state)))
|
||||
if (!comparitor (authorities0[state_index], authorities1[state_index]))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_pipeline_resolve_authorities (CoglPipeline *pipeline,
|
||||
unsigned long differences,
|
||||
CoglPipeline **authorities)
|
||||
{
|
||||
unsigned long remaining = differences;
|
||||
CoglPipeline *authority = pipeline;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned long found = authority->differences & remaining;
|
||||
int i;
|
||||
|
||||
if (found == 0)
|
||||
continue;
|
||||
|
||||
for (i = 0; True; i++)
|
||||
{
|
||||
unsigned long state = (1L<<i);
|
||||
|
||||
if (state & found)
|
||||
authorities[i] = authority;
|
||||
else if (state > found)
|
||||
break;
|
||||
}
|
||||
|
||||
remaining &= ~found;
|
||||
if (remaining == 0)
|
||||
return;
|
||||
}
|
||||
while ((authority = _cogl_pipeline_get_parent (authority)));
|
||||
|
||||
g_assert (remaining == 0);
|
||||
}
|
||||
|
||||
/* Comparison of two arbitrary pipelines is done by:
|
||||
* 1) walking up the parents of each pipeline until a common
|
||||
* ancestor is found, and at each step ORing together the
|
||||
@ -3252,30 +3347,29 @@ simple_property_equal (CoglPipeline *pipeline0,
|
||||
* 2) using the final difference mask to determine which state
|
||||
* groups to compare.
|
||||
*
|
||||
* This is used by the Cogl journal to compare pipelines so that it
|
||||
* can split up geometry that needs different OpenGL state.
|
||||
* This is used, for example, by the Cogl journal to compare pipelines so that
|
||||
* it can split up geometry that needs different OpenGL state.
|
||||
*
|
||||
* It is acceptable to have false negatives - although they will result
|
||||
* in redundant OpenGL calls that try and update the state.
|
||||
*
|
||||
* When comparing texture layers, _cogl_pipeline_equal will actually
|
||||
* compare the underlying GL texture handle that the Cogl texture uses
|
||||
* so that atlas textures and sub textures will be considered equal if
|
||||
* they point to the same texture. This is useful for comparing
|
||||
* pipelines in the journal but it means that _cogl_pipeline_equal
|
||||
* doesn't strictly compare whether the pipelines are the same. If we
|
||||
* needed those semantics we could perhaps add another function or
|
||||
* some flags to control the behaviour.
|
||||
*
|
||||
* False positives aren't allowed.
|
||||
* XXX: When comparing texture layers, _cogl_pipeline_equal will actually
|
||||
* compare the underlying GL texture handle that the Cogl texture uses so that
|
||||
* atlas textures and sub textures will be considered equal if they point to
|
||||
* the same texture. This is useful for comparing pipelines in the journal but
|
||||
* it means that _cogl_pipeline_equal doesn't strictly compare whether the
|
||||
* pipelines are the same. If we needed those semantics we could perhaps add
|
||||
* another function or some flags to control the behaviour.
|
||||
*/
|
||||
gboolean
|
||||
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
CoglPipeline *pipeline1,
|
||||
gboolean skip_gl_color)
|
||||
unsigned long differences,
|
||||
unsigned long layer_differences,
|
||||
CoglPipelineEvalFlags flags)
|
||||
{
|
||||
unsigned long pipelines_difference;
|
||||
unsigned long pipelines_difference;
|
||||
CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
||||
CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
||||
gboolean ret;
|
||||
|
||||
COGL_STATIC_TIMER (pipeline_equal_timer,
|
||||
"Mainloop", /* parent */
|
||||
"_cogl_pipeline_equal",
|
||||
@ -3294,7 +3388,8 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
|
||||
/* First check non-sparse properties */
|
||||
|
||||
if (pipeline0->real_blend_enable != pipeline1->real_blend_enable)
|
||||
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE &&
|
||||
pipeline0->real_blend_enable != pipeline1->real_blend_enable)
|
||||
goto done;
|
||||
|
||||
/* Then check sparse properties */
|
||||
@ -3302,34 +3397,43 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
pipelines_difference =
|
||||
_cogl_pipeline_compare_differences (pipeline0, pipeline1);
|
||||
|
||||
if (pipelines_difference & COGL_PIPELINE_STATE_COLOR &&
|
||||
!skip_gl_color)
|
||||
/* Only compare the sparse state groups requested by the caller... */
|
||||
pipelines_difference &= differences;
|
||||
|
||||
_cogl_pipeline_resolve_authorities (pipeline0,
|
||||
pipelines_difference,
|
||||
authorities0);
|
||||
_cogl_pipeline_resolve_authorities (pipeline1,
|
||||
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)
|
||||
{
|
||||
CoglPipelineState state = COGL_PIPELINE_STATE_COLOR;
|
||||
CoglPipeline *authority0 =
|
||||
_cogl_pipeline_get_authority (pipeline0, state);
|
||||
CoglPipeline *authority1 =
|
||||
_cogl_pipeline_get_authority (pipeline1, state);
|
||||
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 (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_LIGHTING,
|
||||
COGL_PIPELINE_STATE_LIGHTING_INDEX,
|
||||
_cogl_pipeline_lighting_state_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX,
|
||||
_cogl_pipeline_alpha_func_state_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE,
|
||||
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX,
|
||||
_cogl_pipeline_alpha_func_reference_state_equal))
|
||||
goto done;
|
||||
|
||||
@ -3338,11 +3442,8 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
if (pipeline0->real_blend_enable &&
|
||||
pipelines_difference & COGL_PIPELINE_STATE_BLEND)
|
||||
{
|
||||
CoglPipelineState state = COGL_PIPELINE_STATE_BLEND;
|
||||
CoglPipeline *authority0 =
|
||||
_cogl_pipeline_get_authority (pipeline0, state);
|
||||
CoglPipeline *authority1 =
|
||||
_cogl_pipeline_get_authority (pipeline1, state);
|
||||
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;
|
||||
@ -3351,42 +3452,46 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
/* 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 (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_BLEND,
|
||||
COGL_PIPELINE_STATE_BLEND_INDEX,
|
||||
_cogl_pipeline_blend_enable_equal))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_DEPTH,
|
||||
COGL_PIPELINE_STATE_DEPTH_INDEX,
|
||||
_cogl_pipeline_depth_state_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_FOG,
|
||||
COGL_PIPELINE_STATE_FOG_INDEX,
|
||||
_cogl_pipeline_fog_state_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
_cogl_pipeline_point_size_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_USER_SHADER,
|
||||
COGL_PIPELINE_STATE_USER_SHADER_INDEX,
|
||||
_cogl_pipeline_user_shader_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (pipeline0, pipeline1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_LAYERS,
|
||||
_cogl_pipeline_layers_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;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
done:
|
||||
|
Loading…
Reference in New Issue
Block a user