The most common case for Clutter is 2D axis-aligned actors, which
maintain these properties even after projecting to eye coordinates.
In those cases, we can use a simpler hit test by checking against
boxes.
Not only this is simpler, but this maintains an important aspect
of picking that is a requirement for Clutter: watertightness. Even
though the triangles checks do work on x86_64, they do not guarantee
watertightness. This breaks tests on ARM.
Use graphene_box_t to hit-test axis-aligned 2D actors.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1599>
This commit introduces a few important changes in order to
acommodate graphene_ray_t. Most of them are positive changes,
so don't panic :)
The first very visible change is that neither the actor box
nor the clip rectangles are projected before being pushed.
This required changing the parameters of the related functions
at both ClutterPickContext, and ClutterPickStack, to receive
boxes instead of vertices. These rectangles are projected on
demand now, so in the best case (first actor picked) only
one projection happens; and in the worst case, it projects
as much as it does now.
The second important change is that there are no more checks
for axis-alignment anymore. That's because picking now happens
in 3D space, using triangles.
Talking about triangles in 3D space, this is what is used now
for picking. We break down each actor rectangle in 2 triangles,
and check if the projected pick point is inside any one of them,
of if the ray intersects any one of them. The same check happens
for the clip rectangles.
Checking the projected pick point is both an optimization for the
2D case, and a workaround to graphene_ray_t problems with float
precision, which is specially visible on edges such as the top
bar.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1509
ClutterPickStack is a new boxed type that stores the vertices
and clip rectangles. It is meant to be a byproduct of picking,
and takes over most of what ClutterStage currently does.
It introduces a 'seal' system, inspired by MetaKmsUpdate. After
the pick operation is done, and the rectangles are collected,
the pick stack is sealed, and is not allowed to be externally
modified anymore. Internally, it still can invalidate pick
records when an actor is destroyed.
For now, it handles both the clip rectangles, and the matrix
stack, separatedly. Future commits will rearrange this.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1509