[clutter/clutter-1.16] actor: Improve conditions for skipping implicit transitions



commit 9424e995fa4c7ef60555a641561c5f6e44aa2276
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Apr 24 15:17:07 2013 -0400

    actor: Improve conditions for skipping implicit transitions
    
    The "should this implicit transition be skipped" check should live into
    its own function, where we can actually explain what it does and which
    conditions should be respected.
    
    Instead of just blindly skipping actors that are unmapped, or haven't
    been painted yet, we should add a couple of escape hatches.
    
    First of all, we don't want :allocation to be implicitly animated until
    we have been painted (thus allocated) once; this avoids actors "flying
    in" into their allocation.
    
    We also want to allow implicit transitions on the opacity even if we
    haven't been painted yet; the internal optimization that we employ in
    clutter_actor_paint() and skips painting fully transparent actors is
    exactly that: an internal optimization. Caller code should not be aware
    of this change, and it should not influence code outside of ClutterActor
    itself.
    
    The rest of the conditions are the same: if the easing state's duration
    is zero, or if the actor is both unmapped and not in a cloned branch of
    the scene graph, then implicit transitions are pointless, as they won't
    be painted.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=698766

 clutter/clutter-actor.c |   59 +++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 49 insertions(+), 10 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 0963615..cee624a 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -18706,6 +18706,52 @@ clutter_actor_add_transition_internal (ClutterActor *self,
   clutter_timeline_start (timeline);
 }
 
+static gboolean
+should_skip_transition (ClutterActor *self,
+                        GParamSpec   *pspec)
+{
+  ClutterActorPrivate *priv = self->priv;
+  const ClutterAnimationInfo *info;
+
+  /* this function is called from _clutter_actor_create_transition() which
+   * calls _clutter_actor_get_animation_info() first, so we're guaranteed
+   * to have the correct ClutterAnimationInfo pointer
+   */
+  info = _clutter_actor_get_animation_info_or_defaults (self);
+
+  /* if the easing state has a non-zero duration we always want an
+   * implicit transition to occur
+   */
+  if (info->cur_state->easing_duration == 0)
+    return TRUE;
+
+  /* we do want :opacity transitions to work even if they start from an
+   * unpainted actor, because of the opacity optimization that lives in
+   * clutter_actor_paint()
+   */
+  if (pspec == obj_props[PROP_OPACITY] && !priv->was_painted)
+    return FALSE;
+
+  /* on the other hand, if the actor hasn't been allocated yet, we want to
+   * skip all transitions on the :allocation, to avoid actors "flying in"
+   * into their new position and size
+   */
+  if (pspec == obj_props[PROP_ALLOCATION] && priv->needs_allocation)
+    return TRUE;
+
+  /* if the actor is not mapped and is not part of a branch of the scene
+   * graph that is being cloned, then we always skip implicit transitions
+   * on the account of the fact that the actor is not going to be visible
+   * when those transitions happen
+   */
+  if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
+      priv->in_cloned_branch == 0 &&
+      !clutter_actor_has_mapped_clones (self))
+    return TRUE;
+
+  return FALSE;
+}
+
 /*< private >*
  * _clutter_actor_create_transition:
  * @actor: a #ClutterActor
@@ -18783,17 +18829,9 @@ _clutter_actor_create_transition (ClutterActor *actor,
       goto out;
     }
 
-  if (info->cur_state->easing_duration == 0 ||
-      !actor->priv->was_painted ||
-      (!CLUTTER_ACTOR_IS_MAPPED (actor) &&
-       actor->priv->in_cloned_branch == 0 &&
-       !clutter_actor_has_mapped_clones (actor)))
+  if (should_skip_transition (actor, pspec))
     {
-      /* don't bother creating the transition if one is not necessary
-       * because the actor doesn't want one, or if the actor is not
-       * visible: we just set the final value directly on the actor.
-       *
-       * we also don't go through the Animatable interface because we
+      /* we don't go through the Animatable interface because we
        * already know we got here through an animatable property.
        */
       CLUTTER_NOTE (ANIMATION, "Easing duration=0 was_painted=%s, immediate set for '%s::%s'",
@@ -18808,6 +18846,7 @@ _clutter_actor_create_transition (ClutterActor *actor,
                                              pspec->param_id,
                                              &final,
                                              pspec);
+
       g_value_unset (&initial);
       g_value_unset (&final);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]