summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2020-09-11 17:27:19 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2020-10-06 15:34:47 +0000
commit2406f225a91c564490655a35f57659bd6bf7e8c1 (patch)
tree164ed9666ff43389ec7accbf476d4d63c9067333
parentcbcbe39f4d539f06f7b4e10c3996c57d578fece3 (diff)
downloadmutter-2406f225a91c564490655a35f57659bd6bf7e8c1.tar.gz
clutter/actor: Use graphene APIs
ClutterActor is a particularly heavy user of matrices, and switching to graphene_matrix_* APIs means we had to change the order of operations due to left-hand vs right-hand differences. When applying the actor transform, there are 2 main branches that can be followed: the default transforms, and when a custom transform is set. To facilitate review, here's the table that I've made to guide myself: +--------------- Case 1: Default Transforms --------------+ | CoglMatrix | graphene_matrix_t | +----------------------------+----------------------------+ | multiply (child transform) | translate (-pivot) | | translate (allocation)¹ | rotate_x (angle) | | translate (pivot)¹ | rotate_y (angle) | | translate (translation)¹ | rotate_z (angle) | | scale (sx, sy, sz) | scale (sx, sy, sz) | | rotate_z (angle) | translate (translation)¹ | | rotate_y (angle) | translate (pivot)¹ | | rotate_x (angle) | translate (allocation)¹ | | translate (-pivot) | multiply (child transform) | +----------------------------+----------------------------+ ¹ - these 3 translations are simplified as a single call to translate(allocation + pivot + translation) +---------------- Case 2: Custom Transform ---------------+ | CoglMatrix | graphene_matrix_t | +----------------------------+----------------------------+ | multiply (child transform) | translate (-pivot) | | translate (allocation)² | multiply (transform) | | translate (pivot)² | translate (pivot)² | | multiply (transform) | translate (allocation)² | | translate (-pivot) | multiply (child transform) | +----------------------------+----------------------------+ ² - likewise, these 2 translations are simplified as a single call to translate(allocation + pivot) https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
-rw-r--r--clutter/clutter/clutter-actor.c113
1 files changed, 55 insertions, 58 deletions
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 71bf95fe9..68290b986 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -1268,9 +1268,9 @@ _clutter_actor_transform_local_box_to_stage (ClutterActor *self,
if (!stage_priv->has_inverse_transform)
return FALSE;
cogl_framebuffer_get_modelview_matrix (fb, &modelview);
- cogl_matrix_multiply (&transform_to_stage,
- &stage_priv->inverse_transform,
- &modelview);
+ graphene_matrix_multiply (&modelview,
+ &stage_priv->inverse_transform,
+ &transform_to_stage);
vertices[0].x = box->x1;
vertices[0].y = box->y1;
@@ -2979,7 +2979,7 @@ _clutter_actor_get_relative_transformation_matrix (ClutterActor *self,
ClutterActor *ancestor,
graphene_matrix_t *matrix)
{
- cogl_matrix_init_identity (matrix);
+ graphene_matrix_init_identity (matrix);
_clutter_actor_apply_relative_transformation_matrix (self, ancestor, matrix);
}
@@ -3069,6 +3069,7 @@ clutter_actor_real_apply_transform (ClutterActor *self,
{
ClutterActorPrivate *priv = self->priv;
const ClutterTransformInfo *info;
+ graphene_point3d_t p;
float pivot_x = 0.f, pivot_y = 0.f;
info = _clutter_actor_get_transform_info_or_defaults (self);
@@ -3090,72 +3091,66 @@ clutter_actor_real_apply_transform (ClutterActor *self,
priv->allocation.x1 + pivot_x + info->translation.x,
priv->allocation.y1 + pivot_y + info->translation.y);
- /* we apply the :child-transform from the parent actor, if we have one */
- if (priv->parent != NULL)
+ /* roll back the pivot translation */
+ if (pivot_x != 0.f || pivot_y != 0.f || info->pivot_z != 0.f)
{
- const ClutterTransformInfo *parent_info;
-
- parent_info = _clutter_actor_get_transform_info_or_defaults (priv->parent);
- cogl_matrix_init_from_matrix (matrix, &(parent_info->child_transform));
+ graphene_point3d_init (&p, -pivot_x, -pivot_y, -info->pivot_z);
+ graphene_matrix_translate (matrix, &p);
}
- else
- cogl_matrix_init_identity (matrix);
/* if we have an overriding transformation, we use that, and get out */
if (info->transform_set)
{
+ graphene_matrix_multiply (matrix, &info->transform, matrix);
+
/* we still need to apply the :allocation's origin and :pivot-point
* translations, since :transform is relative to the actor's coordinate
* space, and to the pivot point
*/
- cogl_matrix_translate (matrix,
+ graphene_point3d_init (&p,
priv->allocation.x1 + pivot_x,
priv->allocation.y1 + pivot_y,
info->pivot_z);
- cogl_matrix_multiply (matrix, matrix, &info->transform);
- goto roll_back_pivot;
+ graphene_matrix_translate (matrix, &p);
+ goto roll_back;
}
+ if (info->rx_angle)
+ graphene_matrix_rotate (matrix, info->rx_angle, graphene_vec3_x_axis ());
+
+ if (info->ry_angle)
+ graphene_matrix_rotate (matrix, info->ry_angle, graphene_vec3_y_axis ());
+
+ if (info->rz_angle)
+ graphene_matrix_rotate (matrix, info->rz_angle, graphene_vec3_z_axis ());
+
+ if (info->scale_x != 1.0 || info->scale_y != 1.0 || info->scale_z != 1.0)
+ graphene_matrix_scale (matrix, info->scale_x, info->scale_y, info->scale_z);
+
/* basic translation: :allocation's origin and :z-position; instead
* of decomposing the pivot and translation info separate operations,
* we just compose everything into a single translation
*/
- cogl_matrix_translate (matrix,
+ graphene_point3d_init (&p,
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);
+ graphene_matrix_translate (matrix, &p);
- /* because the rotation involves translations, we must scale
- * before applying the rotations (if we apply the scale after
- * the rotations, the translations included in the rotation are
- * not scaled and so the entire object will move on the screen
- * as a result of rotating it).
- *
- * XXX:2.0 the comment has to be reworded once we remove the
- * per-transformation centers; we also may want to apply rotation
- * first and scaling after, to match the matrix decomposition
- * 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 (matrix, info->scale_x, info->scale_y, info->scale_z);
-
- if (info->rz_angle)
- cogl_matrix_rotate (matrix, info->rz_angle, 0, 0, 1.0);
-
- if (info->ry_angle)
- cogl_matrix_rotate (matrix, info->ry_angle, 0, 1.0, 0);
-
- if (info->rx_angle)
- cogl_matrix_rotate (matrix, info->rx_angle, 1.0, 0, 0);
+roll_back:
+ /* we apply the :child-transform from the parent actor, if we have one */
+ if (priv->parent != NULL)
+ {
+ const ClutterTransformInfo *parent_info;
-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 (matrix, -pivot_x, -pivot_y, -info->pivot_z);
+ parent_info = _clutter_actor_get_transform_info_or_defaults (priv->parent);
+ graphene_matrix_multiply (matrix, &parent_info->child_transform, matrix);
+ }
}
/* Applies the transforms associated with this actor to the given
* matrix. */
+
static void
ensure_valid_actor_transform (ClutterActor *actor)
{
@@ -3164,6 +3159,8 @@ ensure_valid_actor_transform (ClutterActor *actor)
if (priv->transform_valid)
return;
+ graphene_matrix_init_identity (&priv->transform);
+
CLUTTER_ACTOR_GET_CLASS (actor)->apply_transform (actor, &priv->transform);
priv->has_inverse_transform =
cogl_graphene_matrix_get_inverse (&priv->transform,
@@ -3179,7 +3176,7 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self,
ClutterActorPrivate *priv = self->priv;
ensure_valid_actor_transform (self);
- cogl_matrix_multiply (matrix, matrix, &priv->transform);
+ graphene_matrix_multiply (&priv->transform, matrix, matrix);
}
/*
@@ -3205,7 +3202,7 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self,
*
* This function doesn't initialize the given @matrix, it simply
* multiplies the requested transformation matrix with the existing contents of
- * @matrix. You can use cogl_matrix_init_identity() to initialize the @matrix
+ * @matrix. You can use graphene_matrix_init_identity() to initialize the @matrix
* before calling this function, or you can use
* clutter_actor_get_relative_transformation_matrix() instead.
*/
@@ -3843,7 +3840,7 @@ clutter_actor_paint (ClutterActor *self,
clutter_actor_get_transform (self, &transform);
- if (!cogl_matrix_is_identity (&transform))
+ if (!graphene_matrix_is_identity (&transform))
{
transform_node = clutter_transform_node_new (&transform);
clutter_paint_node_add_child (transform_node, root_node);
@@ -3862,7 +3859,7 @@ clutter_actor_paint (ClutterActor *self,
_clutter_actor_get_relative_transformation_matrix (self, NULL,
&expected_matrix);
- if (!cogl_matrix_equal (&transform, &expected_matrix))
+ if (!graphene_matrix_equal_fast (&transform, &expected_matrix))
{
GString *buf = g_string_sized_new (1024);
ClutterActor *parent;
@@ -4465,8 +4462,8 @@ get_default_transform_info (void)
if (G_UNLIKELY (g_once_init_enter (&initialized)))
{
- cogl_matrix_init_identity (&default_transform_info.transform);
- cogl_matrix_init_identity (&default_transform_info.child_transform);
+ graphene_matrix_init_identity (&default_transform_info.transform);
+ graphene_matrix_init_identity (&default_transform_info.child_transform);
g_once_init_leave (&initialized, TRUE);
}
@@ -14821,7 +14818,7 @@ clutter_actor_set_transform_internal (ClutterActor *self,
was_set = info->transform_set;
info->transform = *transform;
- info->transform_set = !cogl_matrix_is_identity (&info->transform);
+ info->transform_set = !graphene_matrix_is_identity (&info->transform);
transform_changed (self);
@@ -14859,9 +14856,9 @@ clutter_actor_set_transform (ClutterActor *self,
info = _clutter_actor_get_transform_info_or_defaults (self);
if (transform != NULL)
- cogl_matrix_init_from_matrix (&new_transform, transform);
+ graphene_matrix_init_from_matrix (&new_transform, transform);
else
- cogl_matrix_init_identity (&new_transform);
+ graphene_matrix_init_identity (&new_transform);
_clutter_actor_create_transition (self, obj_props[PROP_TRANSFORM],
&info->transform,
@@ -14884,7 +14881,7 @@ clutter_actor_get_transform (ClutterActor *self,
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (transform != NULL);
- cogl_matrix_init_identity (transform);
+ graphene_matrix_init_identity (transform);
_clutter_actor_apply_modelview_transform (self, transform);
}
@@ -19427,10 +19424,10 @@ clutter_actor_set_child_transform_internal (ClutterActor *self,
GObject *obj;
gboolean was_set = info->child_transform_set;
- cogl_matrix_init_from_matrix (&info->child_transform, transform);
+ graphene_matrix_init_from_matrix (&info->child_transform, transform);
/* if it's the identity matrix, we need to toggle the boolean flag */
- info->child_transform_set = !cogl_matrix_is_identity (transform);
+ info->child_transform_set = !graphene_matrix_is_identity (transform);
/* we need to reset the transform_valid flag on each child */
clutter_actor_iter_init (&iter, self);
@@ -19473,9 +19470,9 @@ clutter_actor_set_child_transform (ClutterActor *self,
info = _clutter_actor_get_transform_info_or_defaults (self);
if (transform != NULL)
- cogl_matrix_init_from_matrix (&new_transform, transform);
+ graphene_matrix_init_from_matrix (&new_transform, transform);
else
- cogl_matrix_init_identity (&new_transform);
+ graphene_matrix_init_identity (&new_transform);
_clutter_actor_create_transition (self, obj_props[PROP_CHILD_TRANSFORM],
&info->child_transform,
@@ -19505,9 +19502,9 @@ clutter_actor_get_child_transform (ClutterActor *self,
info = _clutter_actor_get_transform_info_or_defaults (self);
if (info->child_transform_set)
- cogl_matrix_init_from_matrix (transform, &info->child_transform);
+ graphene_matrix_init_from_matrix (transform, &info->child_transform);
else
- cogl_matrix_init_identity (transform);
+ graphene_matrix_init_identity (transform);
}
static void