From 0717eb9f6b0acae8a7914f71ceeb1b5789d831f6 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 14 Sep 2010 00:18:02 +0100 Subject: [PATCH] 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. --- cogl/cogl-material-arbfp.c | 7 +++++++ cogl/cogl-material.c | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/cogl/cogl-material-arbfp.c b/cogl/cogl-material-arbfp.c index 3f2ed8062..dc66befe7 100644 --- a/cogl/cogl-material-arbfp.c +++ b/cogl/cogl-material-arbfp.c @@ -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. */ diff --git a/cogl/cogl-material.c b/cogl/cogl-material.c index 557bcb217..477238f07 100644 --- a/cogl/cogl-material.c +++ b/cogl/cogl-material.c @@ -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;