clutter/actor: Extend caching in apply_relative_transformation_matrix

Apart from a few edge cases we can avoid walking the tree and transform
to the ancestor coordinate space by multiplying the actor stage-relative
matrix with the inverse of the ancestor's stage-relative matrix.

Since the stage-relative matrices are cached, this reduces the number of
matrix multiplications we do in many situations considerably.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3259>
This commit is contained in:
Robert Mader 2023-09-09 04:57:25 +02:00 committed by Marge Bot
parent 47d4613ce7
commit dfd58ca8f1

View File

@ -3045,6 +3045,10 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
graphene_matrix_t *matrix) graphene_matrix_t *matrix)
{ {
ClutterActorPrivate *priv = self->priv;
graphene_matrix_t parent_modelview;
graphene_matrix_t inverse_parent_modelview;
/* Note we terminate before ever calling stage->apply_transform() /* Note we terminate before ever calling stage->apply_transform()
* since that would conceptually be relative to the underlying * since that would conceptually be relative to the underlying
* window OpenGL coordinates so we'd need a special @ancestor * window OpenGL coordinates so we'd need a special @ancestor
@ -3052,32 +3056,42 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
if (self == ancestor) if (self == ancestor)
return; return;
if (ancestor == NULL) if (!priv->absolute_modelview_valid)
{ {
ClutterActorPrivate *priv = self->priv; graphene_matrix_init_identity (&priv->absolute_modelview);
if (!priv->absolute_modelview_valid) if (priv->parent != NULL)
{ {
graphene_matrix_init_identity (&priv->absolute_modelview); _clutter_actor_apply_relative_transformation_matrix (priv->parent,
NULL,
if (priv->parent != NULL) &priv->absolute_modelview);
{
_clutter_actor_apply_relative_transformation_matrix (priv->parent,
NULL,
&priv->absolute_modelview);
}
_clutter_actor_apply_modelview_transform (self, &priv->absolute_modelview);
priv->absolute_modelview_valid = TRUE;
} }
_clutter_actor_apply_modelview_transform (self, &priv->absolute_modelview);
priv->absolute_modelview_valid = TRUE;
}
if (ancestor == NULL)
{
graphene_matrix_multiply (&priv->absolute_modelview, matrix, matrix); graphene_matrix_multiply (&priv->absolute_modelview, matrix, matrix);
return; return;
} }
if (self->priv->parent != NULL) graphene_matrix_init_identity (&parent_modelview);
_clutter_actor_apply_relative_transformation_matrix (self->priv->parent, _clutter_actor_apply_relative_transformation_matrix (ancestor,
NULL,
&parent_modelview);
if (graphene_matrix_inverse (&parent_modelview,
&inverse_parent_modelview))
{
graphene_matrix_multiply (&inverse_parent_modelview, matrix, matrix);
graphene_matrix_multiply (&priv->absolute_modelview, matrix, matrix);
return;
}
if (priv->parent != NULL)
_clutter_actor_apply_relative_transformation_matrix (priv->parent,
ancestor, ancestor,
matrix); matrix);