From 6ea0f8facc0c88a56aacb0a70372a2644c687340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 20 Mar 2020 23:51:05 +0100 Subject: [PATCH] clutter/clone: Build scale factor for transformation during allocation For ClutterClones we need to apply a scale to the texture of the clone to ensure the painted texture of the source actor actually fits the allocation of the clone. We're doing this using the transformation matrix instead of using the scale_x/scale_y properties of ClutterActor to allow users to scale ClutterClones using that API independently. Now it's quite a bad idea to get the allocation boxes for calculating that scale using clutter_actor_get_allocation_box(), since that method will internally do an immediate relayout of the stage in case the actor isn't allocated. Another side effect of that approach is that it makes it impossible to invalidate the transform (which will be needed when we start caching those matrices) properly. So since we eventually allocate both the source actor and the clone ourselves anyway, we can simply use the allocation box inside clutter_clone_allocate() (which is definitely updated and valid at that point) to calculate the scale factor. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1181 --- clutter/clutter/clutter-clone.c | 42 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/clutter/clutter/clutter-clone.c b/clutter/clutter/clutter-clone.c index 6b534e69b..fe34359d8 100644 --- a/clutter/clutter/clutter-clone.c +++ b/clutter/clutter/clutter-clone.c @@ -52,6 +52,8 @@ struct _ClutterClonePrivate { ClutterActor *clone_source; + float x_scale, y_scale; + gulong source_destroy_id; }; @@ -122,8 +124,6 @@ static void clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix) { ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; - ClutterActorBox box, source_box; - gfloat x_scale, y_scale; /* First chain up and apply all the standard ClutterActor * transformations... */ @@ -134,21 +134,7 @@ clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix) if (priv->clone_source == NULL) return; - /* get our allocated size */ - clutter_actor_get_allocation_box (self, &box); - - /* and get the allocated size of the source */ - clutter_actor_get_allocation_box (priv->clone_source, &source_box); - - /* We need to scale what the clone-source actor paints to fill our own - * allocation... - */ - x_scale = clutter_actor_box_get_width (&box) - / clutter_actor_box_get_width (&source_box); - y_scale = clutter_actor_box_get_height (&box) - / clutter_actor_box_get_height (&source_box); - - cogl_matrix_scale (matrix, x_scale, y_scale, 1.f); + cogl_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f); } static void @@ -244,6 +230,8 @@ clutter_clone_allocate (ClutterActor *self, { ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; ClutterActorClass *parent_class; + ClutterActorBox source_box; + float x_scale, y_scale; /* chain up */ parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class); @@ -259,6 +247,23 @@ clutter_clone_allocate (ClutterActor *self, !clutter_actor_has_allocation (priv->clone_source)) clutter_actor_allocate_preferred_size (priv->clone_source); + clutter_actor_get_allocation_box (priv->clone_source, &source_box); + + /* We need to scale what the clone-source actor paints to fill our own + * allocation... + */ + x_scale = clutter_actor_box_get_width (box) + / clutter_actor_box_get_width (&source_box); + y_scale = clutter_actor_box_get_height (box) + / clutter_actor_box_get_height (&source_box); + + if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) || + !G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON)) + { + priv->x_scale = x_scale; + priv->y_scale = y_scale; + } + #if 0 /* XXX - this is wrong: ClutterClone cannot clone unparented * actors, as it will break all invariants @@ -364,6 +369,9 @@ static void clutter_clone_init (ClutterClone *self) { self->priv = clutter_clone_get_instance_private (self); + + self->priv->x_scale = 1.f; + self->priv->y_scale = 1.f; } /**