[clutter/wip/apocalypses/apocalypse-3: 12/35] actor: Make paint_node() and ::paint mutually exclusive



commit b02c18bc9e1ea4a5ed5981059901234c7374a8f1
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Mon Mar 5 18:32:16 2012 +0000

    actor: Make paint_node() and ::paint mutually exclusive
    
    The ::paint signal is the old way to paint an actor; the paint_node()
    virtual function is the new way. It's still not possible to traverse the
    whole scene graph and build a render tree of PaintNode instances, but
    with this change we simultaneously cut out the ::paint signal emission
    from the critical path for actors that are using the new PaintNode-based
    API, and we retain backward compatibility in the interim period between
    1.10 and 2.0.

 clutter/clutter-actor.c |   96 +++++++++++++++++++++++++++-------------------
 1 files changed, 56 insertions(+), 40 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index aaad7f0..c4df67a 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -3178,15 +3178,44 @@ add_or_remove_flatten_effect (ClutterActor *self)
 }
 
 static void
+clutter_actor_real_paint (ClutterActor *actor)
+{
+  ClutterActorPrivate *priv = actor->priv;
+  ClutterActor *iter;
+
+  for (iter = priv->first_child;
+       iter != NULL;
+       iter = iter->priv->next_sibling)
+    {
+      CLUTTER_NOTE (PAINT, "Painting %s, child of %s, at { %.2f, %.2f - %.2f x %.2f }",
+                    _clutter_actor_get_debug_name (iter),
+                    _clutter_actor_get_debug_name (actor),
+                    iter->priv->allocation.x1,
+                    iter->priv->allocation.y1,
+                    iter->priv->allocation.x2 - iter->priv->allocation.x1,
+                    iter->priv->allocation.y2 - iter->priv->allocation.y1);
+
+      clutter_actor_paint (iter);
+    }
+}
+
+static gboolean
 clutter_actor_paint_node (ClutterActor     *actor,
                           ClutterPaintNode *root)
 {
   ClutterActorPrivate *priv = actor->priv;
 
-  if (priv->bg_color_set)
+  if (priv->bg_color_set &&
+      !clutter_color_equal (&priv->bg_color, CLUTTER_COLOR_Transparent))
     {
       ClutterPaintNode *node;
       ClutterColor bg_color;
+      ClutterActorBox box;
+
+      box.x1 = 0.f;
+      box.y1 = 0.f;
+      box.x2 = clutter_actor_box_get_width (&priv->allocation);
+      box.y2 = clutter_actor_box_get_height (&priv->allocation);
 
       bg_color = priv->bg_color;
       bg_color.alpha = clutter_actor_get_paint_opacity_internal (actor)
@@ -3195,7 +3224,7 @@ clutter_actor_paint_node (ClutterActor     *actor,
 
       node = clutter_color_node_new (&bg_color);
       clutter_paint_node_set_name (node, "backgroundColor");
-      clutter_paint_node_add_rectangle (node, &priv->allocation);
+      clutter_paint_node_add_rectangle (node, &box);
       clutter_paint_node_add_child (root, node);
       clutter_paint_node_unref (node);
     }
@@ -3207,31 +3236,21 @@ clutter_actor_paint_node (ClutterActor     *actor,
     CLUTTER_ACTOR_GET_CLASS (actor)->paint_node (actor, root);
 
   if (clutter_paint_node_get_n_children (root) == 0)
-    return;
+    return FALSE;
 
-  _clutter_paint_node_paint (root);
-}
+#ifdef CLUTTER_ENABLE_DEBUG
+  if (CLUTTER_HAS_DEBUG (PAINT))
+    {
+      /* dump the tree only if we have one */
+      _clutter_paint_node_dump_tree (root);
+    }
+#endif /* CLUTTER_ENABLE_DEBUG */
 
-static void
-clutter_actor_real_paint (ClutterActor *actor)
-{
-  ClutterActorPrivate *priv = actor->priv;
-  ClutterActor *iter;
+  _clutter_paint_node_paint (root);
 
-  for (iter = priv->first_child;
-       iter != NULL;
-       iter = iter->priv->next_sibling)
-    {
-      CLUTTER_NOTE (PAINT, "Painting %s, child of %s, at { %.2f, %.2f - %.2f x %.2f }",
-                    _clutter_actor_get_debug_name (iter),
-                    _clutter_actor_get_debug_name (actor),
-                    iter->priv->allocation.x1,
-                    iter->priv->allocation.y1,
-                    iter->priv->allocation.x2 - iter->priv->allocation.x1,
-                    iter->priv->allocation.y2 - iter->priv->allocation.y1);
+  CLUTTER_ACTOR_GET_CLASS (actor)->paint (actor);
 
-      clutter_actor_paint (iter);
-    }
+  return TRUE;
 }
 
 /**
@@ -3510,6 +3529,7 @@ clutter_actor_continue_paint (ClutterActor *self)
       if (_clutter_context_get_pick_mode () == CLUTTER_PICK_NONE)
         {
           ClutterPaintNode *dummy;
+          gboolean emit_paint;
 
           /* XXX - this will go away in 2.0, when we can get rid of this
            * stuff and switch to a pure retained render tree of PaintNodes
@@ -3517,24 +3537,17 @@ clutter_actor_continue_paint (ClutterActor *self)
            */
           dummy = _clutter_dummy_node_new ();
           clutter_paint_node_set_name (dummy, "Root");
-          clutter_actor_paint_node (self, dummy);
+          emit_paint = !clutter_actor_paint_node (self, dummy);
+          clutter_paint_node_unref (dummy);
 
-          if (clutter_paint_node_get_n_children (dummy) != 0)
+          if (emit_paint || CLUTTER_ACTOR_IS_TOPLEVEL (self))
+            g_signal_emit (self, actor_signals[PAINT], 0);
+          else
             {
-#ifdef CLUTTER_ENABLE_DEBUG
-              if (CLUTTER_HAS_DEBUG (PAINT))
-                {
-                  /* dump the tree only if we have one */
-                  _clutter_paint_node_dump_tree (dummy);
-                }
-#endif /* CLUTTER_ENABLE_DEBUG */
-
-              _clutter_paint_node_paint (dummy);
+              CLUTTER_NOTE (PAINT, "The actor '%s' painted using PaintNodes, "
+                                   "skipping the emission of the paint signal.",
+                                   _clutter_actor_get_debug_name (self));
             }
-
-          clutter_paint_node_unref (dummy);
-
-          g_signal_emit (self, actor_signals[PAINT], 0);
         }
       else
         {
@@ -17586,11 +17599,14 @@ clutter_actor_get_content_box (ClutterActor    *self,
   if (!clutter_actor_has_allocation (self))
     return;
 
+  box->x1 = 0.f;
+  box->y1 = 0.f;
+  box->x2 = priv->allocation.x2 - priv->allocation.x1;
+  box->y2 = priv->allocation.y2 - priv->allocation.y1;
+
   if (priv->content == NULL)
     return;
 
-  *box = priv->allocation;
-
   /* no need to do any more work */
   if (priv->content_gravity == CLUTTER_CONTENT_GRAVITY_RESIZE_FILL)
     return;



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