From 25abdf09b76fb594f8e64295a93aad241bcc3941 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 16 Aug 2010 17:02:15 +0100 Subject: [PATCH] effect: Allow any effect to override the paint volume An Effect implementation might override the paint volume of the actor to which it is applied to. The get_paint_volume() virtual function should be added to the Effect class vtable so that any effect can get the current paint volume and update it. The clutter_actor_get_paint_volume() function becomes context aware, and does the right thing if called from within a ClutterEffect pre_paint() or post_paint() implementation, by allowing all effects in the chain up to the caller to modify the paint volume. --- clutter/clutter-actor.c | 54 +++++++++++++++++++++++++++++++++++++-- clutter/clutter-effect.c | 17 ++++++++++++ clutter/clutter-effect.h | 9 +++++-- clutter/clutter-private.h | 6 +++-- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index e811d4f7b..8a0ae33e8 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -493,6 +493,8 @@ struct _ClutterActorPrivate ClutterMetaGroup *actions; ClutterMetaGroup *constraints; ClutterMetaGroup *effects; + + ClutterActorMeta *current_effect; }; enum @@ -2338,14 +2340,20 @@ _clutter_actor_effects_pre_paint (ClutterActor *self) const GList *effects, *l; gboolean was_pre_painted = FALSE; + priv->current_effect = NULL; + effects = _clutter_meta_group_peek_metas (priv->effects); for (l = effects; l != NULL; l = l->next) { ClutterEffect *effect = l->data; + priv->current_effect = l->data; + was_pre_painted |= _clutter_effect_pre_paint (effect); } + priv->current_effect = NULL; + return was_pre_painted; } @@ -2355,14 +2363,20 @@ _clutter_actor_effects_post_paint (ClutterActor *self) ClutterActorPrivate *priv = self->priv; const GList *effects, *l; + priv->current_effect = NULL; + /* we walk the list backwards, to unwind the post-paint order */ effects = _clutter_meta_group_peek_metas (priv->effects); for (l = g_list_last ((GList *) effects); l != NULL; l = l->prev) { ClutterEffect *effect = l->data; + priv->current_effect = l->data; + _clutter_effect_post_paint (effect); } + + priv->current_effect = NULL; } /* Recursively applies the transforms associated with this actor and @@ -3259,11 +3273,13 @@ clutter_actor_real_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume) { ClutterActorPrivate *priv = self->priv; + gfloat width, height; /* the default origin is set to { 0, 0, 0 } */ + clutter_actor_box_get_size (&priv->allocation, &width, &height); + clutter_paint_volume_set_width (volume, width); + clutter_paint_volume_set_height (volume, height); - clutter_paint_volume_set_width (volume, priv->allocation.x2 - priv->allocation.x1); - clutter_paint_volume_set_height (volume, priv->allocation.y2 - priv->allocation.y1); clutter_paint_volume_set_depth (volume, priv->z); } @@ -11682,6 +11698,7 @@ _clutter_paint_volume_get_box (ClutterPaintVolume *pv, ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self) { + ClutterActorPrivate *priv; ClutterPaintVolume *pv; g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); @@ -11689,6 +11706,39 @@ clutter_actor_get_paint_volume (ClutterActor *self) pv = _clutter_paint_volume_new (self); CLUTTER_ACTOR_GET_CLASS (self)->get_paint_volume (self, pv); + priv = self->priv; + + /* since effects can modify the paint volume, we allow them to actually + * do this by making get_paint_volume() "context sensitive" + */ + if (priv->effects != NULL) + { + if (priv->current_effect != NULL) + { + const GList *effects, *l; + + /* if we are being called from within the paint sequence of + * an actor, get the paint volume up to the current effect + */ + effects = _clutter_meta_group_peek_metas (priv->effects); + for (l = effects; + l != NULL || (l != NULL && l->data != priv->current_effect); + l = l->next) + { + _clutter_effect_get_paint_volume (l->data, pv); + } + } + else + { + const GList *effects, *l; + + /* otherwise, get the cumulative volume */ + effects = _clutter_meta_group_peek_metas (priv->effects); + for (l = effects; l != NULL; l = l->next) + _clutter_effect_get_paint_volume (l->data, pv); + } + } + return pv; } diff --git a/clutter/clutter-effect.c b/clutter/clutter-effect.c index c89f33251..f920a75f1 100644 --- a/clutter/clutter-effect.c +++ b/clutter/clutter-effect.c @@ -191,11 +191,18 @@ clutter_effect_real_post_paint (ClutterEffect *effect) { } +static void +clutter_effect_real_get_paint_volume (ClutterEffect *effect, + ClutterPaintVolume *volume) +{ +} + static void clutter_effect_class_init (ClutterEffectClass *klass) { klass->pre_paint = clutter_effect_real_pre_paint; klass->post_paint = clutter_effect_real_post_paint; + klass->get_paint_volume = clutter_effect_real_get_paint_volume; } static void @@ -218,3 +225,13 @@ _clutter_effect_post_paint (ClutterEffect *effect) CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect); } + +void +_clutter_effect_get_paint_volume (ClutterEffect *effect, + ClutterPaintVolume *volume) +{ + g_return_if_fail (CLUTTER_IS_EFFECT (effect)); + g_return_if_fail (volume != NULL); + + CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume); +} diff --git a/clutter/clutter-effect.h b/clutter/clutter-effect.h index 5b04be808..6db925569 100644 --- a/clutter/clutter-effect.h +++ b/clutter/clutter-effect.h @@ -72,16 +72,21 @@ struct _ClutterEffectClass ClutterActorMetaClass parent_class; /*< public >*/ - gboolean (* pre_paint) (ClutterEffect *effect); - void (* post_paint) (ClutterEffect *effect); + gboolean (* pre_paint) (ClutterEffect *effect); + void (* post_paint) (ClutterEffect *effect); + + void (* get_paint_volume) (ClutterEffect *effect, + ClutterPaintVolume *volume); /*< private >*/ + void (* _clutter_effect0) (void); void (* _clutter_effect1) (void); void (* _clutter_effect2) (void); void (* _clutter_effect3) (void); void (* _clutter_effect4) (void); void (* _clutter_effect5) (void); void (* _clutter_effect6) (void); + void (* _clutter_effect7) (void); }; GType clutter_effect_get_type (void) G_GNUC_CONST; diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 3e8c9bef7..e5df30567 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -384,8 +384,10 @@ void _clutter_run_repaint_functions (void); gint32 _clutter_backend_get_units_serial (ClutterBackend *backend); -gboolean _clutter_effect_pre_paint (ClutterEffect *effect); -void _clutter_effect_post_paint (ClutterEffect *effect); +gboolean _clutter_effect_pre_paint (ClutterEffect *effect); +void _clutter_effect_post_paint (ClutterEffect *effect); +void _clutter_effect_get_paint_volume (ClutterEffect *effect, + ClutterPaintVolume *volume); void _clutter_constraint_update_allocation (ClutterConstraint *constraint, ClutterActor *actor,