[mutter] clutter/actor: Cache transformations applied using apply_transform vfunc
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter/actor: Cache transformations applied using apply_transform vfunc
- Date: Tue, 30 Jun 2020 18:17:26 +0000 (UTC)
commit 64304b0b68d22325cbd6196612793323937c6f32
Author: Jonas Dreßler <verdre v0yd nl>
Date: Thu Mar 12 12:13:53 2020 +0100
clutter/actor: Cache transformations applied using apply_transform vfunc
If we want to invalidate the stage-views list reliably on changes to the
actors transformation matrices, we also need to get notified about
changes to the custom transformations applied using the
apply_transform() vfunc.
So provide a new API that allows invalidating the transformation matrix
for actors implementing custom transformations, too. This in turn allows
us to cache the matrix applied using the apply_transform() vfunc by
moving responsibility of keeping track of the caching from
clutter_actor_real_apply_transform() to
_clutter_actor_apply_modelview_transform().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1343
clutter/clutter/clutter-actor.c | 60 ++++++++++++++++++++++++++---------------
clutter/clutter/clutter-actor.h | 8 +++++-
clutter/clutter/clutter-clone.c | 1 +
clutter/clutter/clutter-stage.c | 2 ++
4 files changed, 48 insertions(+), 23 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 86ffe2f1f0..052c84a166 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -3034,14 +3034,9 @@ clutter_actor_real_apply_transform (ClutterActor *self,
ClutterMatrix *matrix)
{
ClutterActorPrivate *priv = self->priv;
- CoglMatrix *transform = &priv->transform;
const ClutterTransformInfo *info;
float pivot_x = 0.f, pivot_y = 0.f;
- /* we already have a cached transformation */
- if (priv->transform_valid)
- goto multiply_and_return;
-
info = _clutter_actor_get_transform_info_or_defaults (self);
/* compute the pivot point given the allocated size */
@@ -3067,10 +3062,10 @@ clutter_actor_real_apply_transform (ClutterActor *self,
const ClutterTransformInfo *parent_info;
parent_info = _clutter_actor_get_transform_info_or_defaults (priv->parent);
- clutter_matrix_init_from_matrix (transform, &(parent_info->child_transform));
+ clutter_matrix_init_from_matrix (matrix, &(parent_info->child_transform));
}
else
- clutter_matrix_init_identity (transform);
+ clutter_matrix_init_identity (matrix);
/* if we have an overriding transformation, we use that, and get out */
if (info->transform_set)
@@ -3079,11 +3074,11 @@ clutter_actor_real_apply_transform (ClutterActor *self,
* translations, since :transform is relative to the actor's coordinate
* space, and to the pivot point
*/
- cogl_matrix_translate (transform,
+ cogl_matrix_translate (matrix,
priv->allocation.x1 + pivot_x,
priv->allocation.y1 + pivot_y,
info->pivot_z);
- cogl_matrix_multiply (transform, transform, &info->transform);
+ cogl_matrix_multiply (matrix, matrix, &info->transform);
goto roll_back_pivot;
}
@@ -3091,7 +3086,7 @@ clutter_actor_real_apply_transform (ClutterActor *self,
* of decomposing the pivot and translation info separate operations,
* we just compose everything into a single translation
*/
- cogl_matrix_translate (transform,
+ cogl_matrix_translate (matrix,
priv->allocation.x1 + pivot_x + info->translation.x,
priv->allocation.y1 + pivot_y + info->translation.y,
info->z_position + info->pivot_z + info->translation.z);
@@ -3108,27 +3103,21 @@ clutter_actor_real_apply_transform (ClutterActor *self,
* code we use when interpolating transformations
*/
if (info->scale_x != 1.0 || info->scale_y != 1.0 || info->scale_z != 1.0)
- cogl_matrix_scale (transform, info->scale_x, info->scale_y, info->scale_z);
+ cogl_matrix_scale (matrix, info->scale_x, info->scale_y, info->scale_z);
if (info->rz_angle)
- cogl_matrix_rotate (transform, info->rz_angle, 0, 0, 1.0);
+ cogl_matrix_rotate (matrix, info->rz_angle, 0, 0, 1.0);
if (info->ry_angle)
- cogl_matrix_rotate (transform, info->ry_angle, 0, 1.0, 0);
+ cogl_matrix_rotate (matrix, info->ry_angle, 0, 1.0, 0);
if (info->rx_angle)
- cogl_matrix_rotate (transform, info->rx_angle, 1.0, 0, 0);
+ cogl_matrix_rotate (matrix, info->rx_angle, 1.0, 0, 0);
roll_back_pivot:
/* roll back the pivot translation */
if (pivot_x != 0.f || pivot_y != 0.f || info->pivot_z != 0.f)
- cogl_matrix_translate (transform, -pivot_x, -pivot_y, -info->pivot_z);
-
- /* we have a valid modelview */
- priv->transform_valid = TRUE;
-
-multiply_and_return:
- cogl_matrix_multiply (matrix, matrix, &priv->transform);
+ cogl_matrix_translate (matrix, -pivot_x, -pivot_y, -info->pivot_z);
}
/* Applies the transforms associated with this actor to the given
@@ -3137,7 +3126,17 @@ void
_clutter_actor_apply_modelview_transform (ClutterActor *self,
ClutterMatrix *matrix)
{
- CLUTTER_ACTOR_GET_CLASS (self)->apply_transform (self, matrix);
+ ClutterActorPrivate *priv = self->priv;
+
+ if (priv->transform_valid)
+ goto out;
+
+ CLUTTER_ACTOR_GET_CLASS (self)->apply_transform (self, &priv->transform);
+
+ priv->transform_valid = TRUE;
+
+out:
+ cogl_matrix_multiply (matrix, matrix, &priv->transform);
}
/*
@@ -19739,3 +19738,20 @@ clutter_actor_queue_immediate_relayout (ClutterActor *self)
if (stage)
clutter_stage_set_actor_needs_immediate_relayout (stage);
}
+
+/**
+ * clutter_actor_invalidate_transform:
+ * @self: A #ClutterActor
+ *
+ * Invalidate the cached transformation matrix of @self.
+ * This is needed for implementations overriding the apply_transform()
+ * vfunc and has to be called if the matrix returned by apply_transform()
+ * would change.
+ */
+void
+clutter_actor_invalidate_transform (ClutterActor *self)
+{
+ g_return_if_fail (CLUTTER_IS_ACTOR (self));
+
+ self->priv->transform_valid = FALSE;
+}
diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h
index 67d327b5b4..128acac1a3 100644
--- a/clutter/clutter/clutter-actor.h
+++ b/clutter/clutter/clutter-actor.h
@@ -178,7 +178,10 @@ struct _ClutterActor
* implementation.
* @apply_transform: virtual function, used when applying the transformations
* to an actor before painting it or when transforming coordinates or
- * the allocation; it must chain up to the parent's implementation
+ * the allocation; if the transformation calculated by this function may
+ * have changed, the cached transformation must be invalidated by calling
+ * clutter_actor_invalidate_transform(); it must chain up to the parent's
+ * implementation
* @parent_set: signal class handler for the #ClutterActor::parent-set
* @destroy: signal class handler for #ClutterActor::destroy. It must
* chain up to the parent's implementation
@@ -918,6 +921,9 @@ void clutter_actor_pick_box (ClutterActor *self,
CLUTTER_EXPORT
GList * clutter_actor_peek_stage_views (ClutterActor *self);
+CLUTTER_EXPORT
+void clutter_actor_invalidate_transform (ClutterActor *self);
+
G_END_DECLS
#endif /* __CLUTTER_ACTOR_H__ */
diff --git a/clutter/clutter/clutter-clone.c b/clutter/clutter/clutter-clone.c
index fe34359d8e..f130a3c98e 100644
--- a/clutter/clutter/clutter-clone.c
+++ b/clutter/clutter/clutter-clone.c
@@ -262,6 +262,7 @@ clutter_clone_allocate (ClutterActor *self,
{
priv->x_scale = x_scale;
priv->y_scale = y_scale;
+ clutter_actor_invalidate_transform (CLUTTER_ACTOR (self));
}
#if 0
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 8d3fc8b800..df3a4c3c33 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -2905,6 +2905,8 @@ clutter_stage_update_view_perspective (ClutterStage *stage)
z_2d,
priv->viewport[2],
priv->viewport[3]);
+
+ clutter_actor_invalidate_transform (CLUTTER_ACTOR (stage));
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]