Apparently clutter_paint_volume_union() has problems building the union
of two paint volumes in eye coordinates, that's probably because of the
negative coordinates that come into play there.
Circumvent that by making even more use of Graphene and letting it take
care of computing the union. We do that by creating two graphene_box_t's
from the axis-aligned paint volumes and intersecting those boxes, then
setting our vertices to the new min and max points of the resulting box.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1507
Add a helper function to determine if a seat has a (physical)
touchscreen associated with it.
Currently src/backends/meta-backend.c has a private version of this
(check_has_physical_touchscreen) and further patches in this patch-set
need the same functionality. So add a generic helper for this to
avoid code duplication.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
_cogl_util_get_eye_planes_for_screen_poly() is quite a complicated beast. Ever
since Clutter became a compositor toolkit, and specially after we switched to
graphene_frustum_t on paint volumes, we can brutally simplify this function.
The new code assumes camera is at (0, 0, 0) at world coordinates (i.e. before
applying the projection). We also consider that the redraw clip are at stage
coordinates. That means that converting the clip rectangle to world rectangle
is simply a matter of projecting the corresponding vertices using the "view"
matrix. Furthermore, we only need to project the top-left, and bottom-right
vertices, since top-right and bottom-left can be derived from those two.
The frustum setup still uses triplets of vertices to setup the planes, except
now the first vertex is always the camera (hardcoded to 0, 0, 0), and the other
two vertices are the projected clip rectangle vertices.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
The redraw clip region may contain multiple clip rectangles. We currently
only use the extents of this region, but having multiple frusta for each
rectangle is a better alternative, and will allow us to remove the extra
projection we currently do.
Make the clip frustum an array, with multiple frusta.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
The clip planes / frustum are contextual to painting. In the past, for
the lack of a better place, it was added to ClutterStage, but now we
have an appropriate home for such data: ClutterPaintContext.
Move the frustum to the paint context.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
While refactoring the clipping planes / frustum code, it became more and
more evident that we do not need to update them while picking. Picking
nowadays goes through a completely different code path, that does not
rely on paint volume culling.
While it might be interesting to eventually also cull out based on paint
volumes, it certainly won't go through the painting code anymore.
Remove setting up the view when picking, and rename functions appropriatedly.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Culling paint volumes don't give this level of detail anymore, and in
fact knowing whether it was partially or fully in was only being used
in a debug path. For the purposes of culling, it doesn't matter if a
given actor is partially or completely inside the frustum; either way,
it must be painted.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Instead of 4 planes, use a graphene_frustum_t to store the clipping
planes.
The cautious reviewer might noticed that we are now setting up 6
planes: the 4 planes we were doing before, plus 2 extra planes in
the Z axis. These extra planes simulate an "infinite" Z far, and
an "on-camera" Z near.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
ClutterStage defines the 8 vertices of a frustum:
4 ----------------------------- 5
| \ / |
| \ / |
| 0 --------------------- 1 |
| | | |
| | | |
| 3 --------------------- 2 |
| / \ |
| / \ |
7 ----------------------------- 6
Then, it uses triplets of vertices to create each clipping plane.
It only sets up 4 planes (it doesn't clip based on depth), defined
by the following vertices:
* 0 - 4 - 5
* 1 - 5 - 6
* 2 - 6 - 7
* 0 - 7 - 4
The first 3 triplets are selected using the for-loop. However, the
last triplet is different, and is done out of the loop. It could
have been made simpler by using the "3 - 7 - 4" triplet.
Simplify the current code by using the suggested triplet, calculated
inside the for-loop.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Instead of our own implementation that upscales, then downscales back,
use graphene_matrix_inverse() directly. This is possible after switching
to a z-near value that doesn't have problems with float precision.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Picking is specially sensitive for float precision, and tests can
easily fail when something changes, even if ever so slightly. A
simple way to workaround this is by adjusting the projected points
using the same procedure described at 67cc60cbda.
Round projected points for picking to 256ths.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
A first step towards abandoning the CoglObject type system: convert
CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects.
CoglFramebuffer is turned into an abstract GObject, while the two others
are currently final. The "winsys" and "platform" are still sprinkled
'void *' in the the non-abstract type instances however.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1496
The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high
resolution X server timestamps", meaning they should have the same scope
as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at
the same time.
This was not done correctly when mutter had determined the X server used
the monotonic clock, where it'd just forward the monotonic clock,
confusing any client using _NET_WM_FRAME_DRAWN and friends.
Fix this by 1) splitting the timestamp conversiot into an X11 case and a
display server case, where the display server case simply clamps the
monotonic clock, as it is assumed Xwayland is always usign the monotonic
clock, and 2) if we're a X11 compositing manager, if the X server is
using the monotonic clock, apply the same semantics as the display
server case and always just clamp, or if not, calculate the offset every
10 seconds, and offset the monotonic clock timestamp with the calculated
X server timestamp offset.
This fixes an issue that would occur if mutter (or rather GNOME Shell)
would have been started before a X11 timestamp overflow, after the
overflow happened. In this case, GTK3 clients would get unclamped
timestamps, and get very confused, resulting in frames queued several
weeks into the future.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1494
Keeping track of the projected position is costly, and adds quite some complexity
to ClutterOffscreenEffect.pre_paint(). As far as research goes, there's not a
single consumer of this function that uses the position for anything - only size
is used.
Remove clutter_offscreen_effect_get_target_rect(), and drop the annoying position
field from ClutterOffscreenEffect as well. This allows us to stop projecting the
position on pre-paint, and simplify things.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1474
ClutterPipelineNode will be used by GNOME Shell in the future.
Fortunately for us, CoglPipeline is already usable from GJS,
so we don't need to skip the constructor for the pipeline node.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1474
Move unreffing the framebuffer to ClutterOffscreenEffect.pre_paint().
This will allow us to properly chain up ClutterOffscreenEffect.paint()
and not reimplement exactly what ClutterEffect does by default.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1474
In this case, since we are building the entire matrix by ourselves,
reverse the order of operations (translate + scale → scale + translate)
and build it using graphene-specific APIs.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
This is another instance of graphene reversing the order of operations (see
the commit notes of how ClutterActor was ported.) The tl;dr; here is that,
in the CoglMatrix past, we used to do:
(actor transforms) → scale
and now, it's the other way round:
scale → (actor transforms)
due to changing from right-handed multiplications (CoglMatrix) to left-handed
ones (graphene_matrix_t).
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
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