material: make layer/material_pre_changes mutually exclusive

This makes it so we only notify backends of either a single material
change or a single layer change. Previously all material STATE_LAYERS
changes would be followed by a more detailed layer change.

For backends that perform code generation for fragment processing they
typically need to understand the details of how layers get changed to
determine if they need to repeat codegen. It doesn't help them to report
a material STATE_LAYERS change for all layer changes since it's so
broad, they really need to wait for the layer change to be notified.

What does help though is to report a STATE_LAYERS change for a change in
material->n_layers because they typically do need to repeat codegen in
that case.
This commit is contained in:
Robert Bragg 2010-09-14 00:18:02 +01:00
parent 16e9794318
commit 3adeef6604
2 changed files with 28 additions and 1 deletions

View File

@ -1200,6 +1200,13 @@ _cogl_material_backend_arbfp_layer_pre_change_notify (
CoglMaterialLayer *layer,
CoglMaterialLayerState change)
{
CoglMaterialBackendARBfpPrivate *priv = get_arbfp_authority_priv (owner);
if (!priv)
return;
dirty_fragment_state (owner, priv);
/* TODO: we could be saving snippets of texture combine code along
* with each layer and then when a layer changes we would just free
* the snippet. */

View File

@ -1131,7 +1131,27 @@ _cogl_material_pre_change_notify (CoglMaterial *material,
{
const CoglMaterialBackend *backend =
_cogl_material_backends[material->backend];
backend->material_pre_change_notify (material, change, new_color);
/* To simplify things for the backends we are careful about how
* we report STATE_LAYERS changes.
*
* All STATE_LAYERS changes with the exception of ->n_layers
* will also result in layer_pre_change_notifications. For
* backends that perform code generation for fragment processing
* they typically need to understand the details of how layers
* get changed to determine if they need to repeat codegen. It
* doesn't help them to report a material STATE_LAYERS change
* for all layer changes since it's so broad, they really need
* to wait for the layer change to be notified. What does help
* though is to report a STATE_LAYERS change for a change in
* ->n_layers because they typically do need to repeat codegen
* in that case.
*
* This just ensures backends only get a single material or
* layer pre-change notification for any particular change.
*/
if (!from_layer_change)
backend->material_pre_change_notify (material, change, new_color);
}
/* There may be an arbitrary tree of descendants of this material;