mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 12:32:05 +00:00
Move find_arbfp_authority to cogl-pipeline.c
The code for finding the arbfp authority for a pipeline should be the same as finding the GLSL authority. So that the code can be shared the function has been moved to cogl-pipeline.c and renamed to _cogl_pipeline_find_codegen_authority.
This commit is contained in:
parent
e57a132f94
commit
9bbb088a2a
@ -151,149 +151,6 @@ _cogl_pipeline_backend_arbfp_get_max_texture_units (void)
|
||||
return _cogl_get_max_texture_image_units ();
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int i;
|
||||
CoglPipelineLayer **layers;
|
||||
} AddLayersToArrayState;
|
||||
|
||||
static gboolean
|
||||
add_layer_to_array_cb (CoglPipelineLayer *layer,
|
||||
void *user_data)
|
||||
{
|
||||
AddLayersToArrayState *state = user_data;
|
||||
state->layers[state->i++] = layer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
layers_arbfp_would_differ (CoglPipelineLayer **pipeline0_layers,
|
||||
CoglPipelineLayer **pipeline1_layers,
|
||||
int n_layers)
|
||||
{
|
||||
int i;
|
||||
/* The layer state that affects arbfp codegen... */
|
||||
unsigned long arbfp_codegen_modifiers =
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE |
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT;
|
||||
|
||||
for (i = 0; i < n_layers; i++)
|
||||
{
|
||||
CoglPipelineLayer *layer0 = pipeline0_layers[i];
|
||||
CoglPipelineLayer *layer1 = pipeline1_layers[i];
|
||||
unsigned long layer_differences;
|
||||
|
||||
if (layer0 == layer1)
|
||||
continue;
|
||||
|
||||
layer_differences =
|
||||
_cogl_pipeline_layer_compare_differences (layer0, layer1);
|
||||
|
||||
if (layer_differences & arbfp_codegen_modifiers)
|
||||
{
|
||||
/* When it comes to texture differences the only thing that
|
||||
* affects the arbfp is the target enum... */
|
||||
if (layer_differences == COGL_PIPELINE_LAYER_STATE_TEXTURE)
|
||||
{
|
||||
CoglHandle tex0 = _cogl_pipeline_layer_get_texture (layer0);
|
||||
CoglHandle tex1 = _cogl_pipeline_layer_get_texture (layer1);
|
||||
GLenum gl_target0;
|
||||
GLenum gl_target1;
|
||||
|
||||
cogl_texture_get_gl_texture (tex0, NULL, &gl_target0);
|
||||
cogl_texture_get_gl_texture (tex1, NULL, &gl_target1);
|
||||
if (gl_target0 == gl_target1)
|
||||
continue;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This tries to find the oldest ancestor whos state would generate
|
||||
* the same arbfp program as the current pipeline. This is a simple
|
||||
* mechanism for reducing the number of arbfp programs we have to
|
||||
* generate.
|
||||
*/
|
||||
static CoglPipeline *
|
||||
find_arbfp_authority (CoglPipeline *pipeline, CoglHandle user_program)
|
||||
{
|
||||
CoglPipeline *authority0;
|
||||
CoglPipeline *authority1;
|
||||
int n_layers;
|
||||
CoglPipelineLayer **authority0_layers;
|
||||
CoglPipelineLayer **authority1_layers;
|
||||
|
||||
/* XXX: we'll need to update this when we add fog support to the
|
||||
* arbfp codegen */
|
||||
|
||||
if (user_program != COGL_INVALID_HANDLE)
|
||||
return pipeline;
|
||||
|
||||
/* Find the first pipeline that modifies state that affects the
|
||||
* arbfp codegen... */
|
||||
authority0 = _cogl_pipeline_get_authority (pipeline,
|
||||
COGL_PIPELINE_STATE_LAYERS);
|
||||
|
||||
/* Find the next ancestor after that, that also modifies state
|
||||
* affecting arbfp codegen... */
|
||||
if (_cogl_pipeline_get_parent (authority0))
|
||||
{
|
||||
authority1 =
|
||||
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0),
|
||||
COGL_PIPELINE_STATE_LAYERS);
|
||||
}
|
||||
else
|
||||
return authority0;
|
||||
|
||||
n_layers = authority0->n_layers;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
AddLayersToArrayState state;
|
||||
|
||||
if (authority0->n_layers != authority1->n_layers)
|
||||
return authority0;
|
||||
|
||||
authority0_layers =
|
||||
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
|
||||
state.i = 0;
|
||||
state.layers = authority0_layers;
|
||||
_cogl_pipeline_foreach_layer_internal (authority0,
|
||||
add_layer_to_array_cb,
|
||||
&state);
|
||||
|
||||
authority1_layers =
|
||||
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
|
||||
state.i = 0;
|
||||
state.layers = authority1_layers;
|
||||
_cogl_pipeline_foreach_layer_internal (authority1,
|
||||
add_layer_to_array_cb,
|
||||
&state);
|
||||
|
||||
if (layers_arbfp_would_differ (authority0_layers, authority1_layers,
|
||||
n_layers))
|
||||
return authority0;
|
||||
|
||||
/* Find the next ancestor after that, that also modifies state
|
||||
* affecting arbfp codegen... */
|
||||
|
||||
if (!_cogl_pipeline_get_parent (authority1))
|
||||
break;
|
||||
|
||||
authority0 = authority1;
|
||||
authority1 =
|
||||
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1),
|
||||
COGL_PIPELINE_STATE_LAYERS);
|
||||
if (authority1 == authority0)
|
||||
break;
|
||||
}
|
||||
|
||||
return authority1;
|
||||
}
|
||||
|
||||
static CoglPipelineBackendARBfpPrivate *
|
||||
get_arbfp_priv (CoglPipeline *pipeline)
|
||||
{
|
||||
@ -374,7 +231,7 @@ _cogl_pipeline_backend_arbfp_start (CoglPipeline *pipeline,
|
||||
* arbfp-authority to maximize the chance that other pipelines can
|
||||
* share it.
|
||||
*/
|
||||
authority = find_arbfp_authority (pipeline, user_program);
|
||||
authority = _cogl_pipeline_find_codegen_authority (pipeline, user_program);
|
||||
authority_priv = get_arbfp_priv (authority);
|
||||
if (!authority_priv)
|
||||
{
|
||||
|
@ -956,5 +956,9 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
|
||||
int
|
||||
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
|
||||
|
||||
CoglPipeline *
|
||||
_cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
|
||||
CoglHandle user_program);
|
||||
|
||||
#endif /* __COGL_PIPELINE_PRIVATE_H */
|
||||
|
||||
|
@ -5595,3 +5595,145 @@ _cogl_debug_dump_pipelines_dot_file (const char *filename)
|
||||
g_string_free (graph, TRUE);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int i;
|
||||
CoglPipelineLayer **layers;
|
||||
} AddLayersToArrayState;
|
||||
|
||||
static gboolean
|
||||
add_layer_to_array_cb (CoglPipelineLayer *layer,
|
||||
void *user_data)
|
||||
{
|
||||
AddLayersToArrayState *state = user_data;
|
||||
state->layers[state->i++] = layer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
layers_codegen_would_differ (CoglPipelineLayer **pipeline0_layers,
|
||||
CoglPipelineLayer **pipeline1_layers,
|
||||
int n_layers)
|
||||
{
|
||||
int i;
|
||||
/* The layer state that affects codegen... */
|
||||
unsigned long codegen_modifiers =
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE |
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT;
|
||||
|
||||
for (i = 0; i < n_layers; i++)
|
||||
{
|
||||
CoglPipelineLayer *layer0 = pipeline0_layers[i];
|
||||
CoglPipelineLayer *layer1 = pipeline1_layers[i];
|
||||
unsigned long layer_differences;
|
||||
|
||||
if (layer0 == layer1)
|
||||
continue;
|
||||
|
||||
layer_differences =
|
||||
_cogl_pipeline_layer_compare_differences (layer0, layer1);
|
||||
|
||||
if (layer_differences & codegen_modifiers)
|
||||
{
|
||||
/* When it comes to texture differences the only thing that
|
||||
* affects the codegen is the target enum... */
|
||||
if (layer_differences == COGL_PIPELINE_LAYER_STATE_TEXTURE)
|
||||
{
|
||||
CoglHandle tex0 = _cogl_pipeline_layer_get_texture (layer0);
|
||||
CoglHandle tex1 = _cogl_pipeline_layer_get_texture (layer1);
|
||||
GLenum gl_target0;
|
||||
GLenum gl_target1;
|
||||
|
||||
cogl_texture_get_gl_texture (tex0, NULL, &gl_target0);
|
||||
cogl_texture_get_gl_texture (tex1, NULL, &gl_target1);
|
||||
if (gl_target0 == gl_target1)
|
||||
continue;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This tries to find the oldest ancestor whos state would generate
|
||||
* the same shader program as the current pipeline. This is a simple
|
||||
* mechanism for reducing the number of programs we have to generate.
|
||||
*/
|
||||
CoglPipeline *
|
||||
_cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
|
||||
CoglHandle user_program)
|
||||
{
|
||||
CoglPipeline *authority0;
|
||||
CoglPipeline *authority1;
|
||||
int n_layers;
|
||||
CoglPipelineLayer **authority0_layers;
|
||||
CoglPipelineLayer **authority1_layers;
|
||||
|
||||
/* XXX: we'll need to update this when we add fog support to the
|
||||
* codegen */
|
||||
|
||||
if (user_program != COGL_INVALID_HANDLE)
|
||||
return pipeline;
|
||||
|
||||
/* Find the first pipeline that modifies state that affects the
|
||||
* codegen... */
|
||||
authority0 = _cogl_pipeline_get_authority (pipeline,
|
||||
COGL_PIPELINE_STATE_LAYERS);
|
||||
|
||||
/* Find the next ancestor after that, that also modifies state
|
||||
* affecting codegen... */
|
||||
if (_cogl_pipeline_get_parent (authority0))
|
||||
{
|
||||
authority1 =
|
||||
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0),
|
||||
COGL_PIPELINE_STATE_LAYERS);
|
||||
}
|
||||
else
|
||||
return authority0;
|
||||
|
||||
n_layers = authority0->n_layers;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
AddLayersToArrayState state;
|
||||
|
||||
if (authority0->n_layers != authority1->n_layers)
|
||||
return authority0;
|
||||
|
||||
authority0_layers =
|
||||
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
|
||||
state.i = 0;
|
||||
state.layers = authority0_layers;
|
||||
_cogl_pipeline_foreach_layer_internal (authority0,
|
||||
add_layer_to_array_cb,
|
||||
&state);
|
||||
|
||||
authority1_layers =
|
||||
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
|
||||
state.i = 0;
|
||||
state.layers = authority1_layers;
|
||||
_cogl_pipeline_foreach_layer_internal (authority1,
|
||||
add_layer_to_array_cb,
|
||||
&state);
|
||||
|
||||
if (layers_codegen_would_differ (authority0_layers, authority1_layers,
|
||||
n_layers))
|
||||
return authority0;
|
||||
|
||||
/* Find the next ancestor after that, that also modifies state
|
||||
* affecting codegen... */
|
||||
|
||||
if (!_cogl_pipeline_get_parent (authority1))
|
||||
break;
|
||||
|
||||
authority0 = authority1;
|
||||
authority1 =
|
||||
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1),
|
||||
COGL_PIPELINE_STATE_LAYERS);
|
||||
if (authority1 == authority0)
|
||||
break;
|
||||
}
|
||||
|
||||
return authority1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user