From 662d12aeff9c7404b915e44777b50f0995252fd8 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Mon, 19 Sep 2011 12:36:52 +0100 Subject: [PATCH] actor: add oob-transform opt to catch out-of-band transforms Out-of-band transforms are considered to be all actor transforms done directly with the Cogl API instead of via ClutterActor::apply_transform. By running with CLUTTER_DEBUG=oob-transform then Clutter will explicitly try to detect when un-expected transforms have been applied to the modelview matrix stack. Out-of-band transforms can lead to awkward bugs in Clutter applications because Clutter itself doesn't know about them and this can disrupt Clutter's input handling and calculations of actor paint-volumes which can lead to visual artifacts. Reviewed-by: Emmanuele Bassi --- clutter/clutter-actor.c | 23 +++++++++++++++++++++++ clutter/clutter-debug.h | 3 ++- clutter/clutter-main.c | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 9c051c161..91cf1733e 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -2864,6 +2864,29 @@ clutter_actor_paint (ClutterActor *self) cogl_get_modelview_matrix (&matrix); _clutter_actor_apply_modelview_transform (self, &matrix); cogl_set_modelview_matrix (&matrix); + + /* Catch when out-of-band transforms have been made by actors not as part + * of an apply_transform vfunc... */ + if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_OOB_TRANSFORMS)) + { + CoglMatrix expected_matrix; + _clutter_actor_get_relative_transformation_matrix (self, NULL, + &expected_matrix); + if (!cogl_matrix_equal (&matrix, &expected_matrix)) + { + ClutterActor *parent = self; + GString *parents = g_string_new (""); + while ((parent = clutter_actor_get_parent (parent))) + g_string_append_printf (parents, "->%s", G_OBJECT_TYPE_NAME (parent)); + g_warning ("Unexpected transform found when painting actor " + "\"%s\". This will be caused by one of the actor's " + "ancestors (%s) using the Cogl API directly to transform " + "children instead of using ::apply_transform().", + _clutter_actor_get_debug_name (self), + parents->str); + g_string_free (parents, TRUE); + } + } } if (priv->has_clip) diff --git a/clutter/clutter-debug.h b/clutter/clutter-debug.h index 9ee1e4447..75263fd0c 100644 --- a/clutter/clutter-debug.h +++ b/clutter/clutter-debug.h @@ -26,7 +26,8 @@ typedef enum { CLUTTER_DEBUG_LAYOUT = 1 << 15, CLUTTER_DEBUG_PICK = 1 << 16, CLUTTER_DEBUG_EVENTLOOP = 1 << 17, - CLUTTER_DEBUG_CLIPPING = 1 << 18 + CLUTTER_DEBUG_CLIPPING = 1 << 18, + CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 19 } ClutterDebugFlag; typedef enum { diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 55320c676..7a2cdcd6a 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -167,7 +167,8 @@ static const GDebugKey clutter_debug_keys[] = { { "multistage", CLUTTER_DEBUG_MULTISTAGE }, { "animation", CLUTTER_DEBUG_ANIMATION }, { "layout", CLUTTER_DEBUG_LAYOUT }, - { "clipping", CLUTTER_DEBUG_CLIPPING } + { "clipping", CLUTTER_DEBUG_CLIPPING }, + { "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS } }; #endif /* CLUTTER_ENABLE_DEBUG */