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)
{
* 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)
{
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;
+}