mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 19:40:43 -05: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
7379a5fc04
commit
fac7338fdd
@ -151,149 +151,6 @@ _cogl_pipeline_backend_arbfp_get_max_texture_units (void)
|
|||||||
return _cogl_get_max_texture_image_units ();
|
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 *
|
static CoglPipelineBackendARBfpPrivate *
|
||||||
get_arbfp_priv (CoglPipeline *pipeline)
|
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
|
* arbfp-authority to maximize the chance that other pipelines can
|
||||||
* share it.
|
* share it.
|
||||||
*/
|
*/
|
||||||
authority = find_arbfp_authority (pipeline, user_program);
|
authority = _cogl_pipeline_find_codegen_authority (pipeline, user_program);
|
||||||
authority_priv = get_arbfp_priv (authority);
|
authority_priv = get_arbfp_priv (authority);
|
||||||
if (!authority_priv)
|
if (!authority_priv)
|
||||||
{
|
{
|
||||||
|
@ -956,5 +956,9 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
|
|||||||
int
|
int
|
||||||
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
|
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
|
||||||
|
|
||||||
|
CoglPipeline *
|
||||||
|
_cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
|
||||||
|
CoglHandle user_program);
|
||||||
|
|
||||||
#endif /* __COGL_PIPELINE_PRIVATE_H */
|
#endif /* __COGL_PIPELINE_PRIVATE_H */
|
||||||
|
|
||||||
|
@ -5595,3 +5595,145 @@ _cogl_debug_dump_pipelines_dot_file (const char *filename)
|
|||||||
g_string_free (graph, TRUE);
|
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