Turns out GObject implicitly notifies all properties by default as soon
as a property setter is called, no matter if the property actually
changed or not. One can opt-out of this behavior by setting the
G_PARAM_EXPLICIT_NOTIFY flag.
So since almost all our properties get notified explicitely (well,
except ClutterActors deprecated show-on-set-parent property), set this
flag for all properties of ClutterActor and ClutterStage now. This
significantly reduces the number of notify:: signals emitted on
ClutterActors, because in gnome-shell javascript we usually set GObject
properties directly, not by going through the extra setter method.
More cleanups can be done in the future, since this flag is suitable for
almost every property in Clutter and even Mutter.
This fixes a crash where we'd hit a newly introduced assertion in
on_device_actor_reactive_changed() of ClutterStage because
notify::reactive got emitted multiple times.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1651>
Due to a few reasons currently the updating of input devices after stage
relayouts isn't working right now. Since we now have a list of pointer
devices in ClutterStage, we can simply use that list and can avoid
asking the input thread. Also we no longer need to check whether the
devices are pointer devices, since our list only consists of pointer
devices.
So switch to ClutterStages private list of pointer devices, which also
includes the core pointer (as opposed to the list returned by
clutter_seat_peek_devices()). This fixes picking after relayouts.
Note that this doesn't catch every possible change that might need a
repick, actors might also need a repick after transformation changes or
in case their custom clip has been changed.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1634>
As planned and prepared with the last commits, let ClutterStage take
care of tracking input devices and their respective actors. This means
we now can remove the old infrastructure for this from
ClutterInputDevice.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>
With the introduction of the input thread, we want to avoid modifying
ClutterInputDevices from the main thread, since they're owned and
updated by the thread.
There's one part of ClutterInputDevice that's still modified from the
main thread though, that is device-actors of pointer devices, and we're
going to move that state-tracking into ClutterStage instead.
So start that by adding the infrastructure to ClutterStage to keep track
of those things. It consists of two hashtables which associate devices
and touch sequences with actors, those hashtables get updated using
clutter_stage_update_device_entry() and
clutter_stage_remove_device_entry(), they can be queried by calling
clutter_stage_get_device_actor(), which will replace
clutter_input_device_get_actor().
clutter_stage_get_device_coords() is added and made available in
clutter-mutter.h because we need to get the coordinates when repicking
in meta_wayland_pointer_repick().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>
New entries indirectly added to `pending_queue_redraw` during the loop
would make our iterator invalid and cause `g_hash_table_iter_next` to
fail without having visited all elements. That was seen as assertion
failures but also likely resulted in incomplete paint clips.
Now we steal the iterator's entry before such corruption can happen,
free it manually, and reset the iterator to the beginning on every
iteration. This is actually safe and efficient because we're removing each
entry we visit. So no time is wasted in resuming from the (new) beginning
of the hash table.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1557
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1615>
Making this an event is overly convoluted, accounting that we
emit the event, then convert it to a ClutterStage signal, then
its only consumer (a11y) sets the active ATK state.
Take the event out of the equation, unify activation/deactivation
of the stage in MetaStage, and use it from the X11 backend too.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
The cached pick mode never actually cached anything, since it is
always, unconditionally reset when painting. Furthermore, next
commits will cull out actors during pick, which makes the pick
stack uncacheable.
Remove the cached pick mode.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1520>
The first comment isn't really needed anymore since
the is_full_stage_redraw_queued() underneath is quite self-explaining.
Also rephrase the second comment a bit, including that
_clutter_paint_volume_get_stage_paint_box() does the aligning to the
pixel grid.
Finally, the last comment also looks out of date since we do that
rounding inside _clutter_paint_volume_get_stage_paint_box(), so remove
it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
We currently pass actors a reference to their associated
ClutterStageQueueRedrawEntry when queueing a redraw. This "splitting" of
the ownership of the entry has introduced quite a few bugs in the past
and is hard to follow.
So give up the "splitting" of the ownership and exclusively handle those
entries inside ClutterStage. To still allow removing the entry when an
actor gets unrealized introduce clutter_stage_dequeue_actor_redraw()
similar to what we already have for relayouts.
To be able to efficiently find entries when actors queue redraws, make
pending_queue_redraws a GHashTable, which fits quite nicely and also
allows removing the QueueRedrawEntries actor pointer in favour of the
key of the hashtable.
Since the struct is now private to ClutterStage, we can also rename it
to QueueRedrawEntry.
While at it, also sneak in the removal of the leading underscore from
clutter_stage_queue_actor_redraw().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
Since we now decoupled the "queue-redraw" signal from creating the stage
clip, we can move signal emission into
_clutter_actor_queue_redraw_full() and emit the signal right away when
queueing a redraw on an actor. With that we now no longer have to
accommodate for the stage pending_queue_redraws list changing while
iterating over it.
To ensure we don't emit the signal too often when multiple redraws are
queued on one actor, use the propagated_one_redraw flag to limit the
number of emissions to a single one for every update cycle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
Putting together the redraw clip of the stage never really fitted nicely
with the "queue-redraw" signal emission, it forces us to emit the
signals in a batch and we also use a weird trick to get the old paint
volume that's already on-screen into the final redraw clip (we call
_clutter_actor_propagate_queue_redraw() on the stage).
So start breaking up this association by making the stage explicitely
request the redraw clip from the actor and removing the
ClutterPaintVolume argument from _clutter_actor_finish_queue_redraw().
This is done by adding a private function
clutter_actor_get_redraw_clip() which returns our old (currently
visible) paint volume and the new paint volume.
This also allows removing the check whether a full stage redraw has been
queued in clutter_actor_real_queue_redraw() and we can now just stop the
signal emission if a propagation happened at least once.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
The redraw_pending boolean is used to schedule the first stage update
after starting Clutter. This flag is superfluous because we have the
pending_finish_queue_redraws flag which does the same.
While at it, also remove the redraw_count debug variable, since there
should be better ways to count the number of queued redraws nowadays,
for example Sysprof marks.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1527
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
_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
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
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
CoglMatrix already is a typedef to graphene_matrix_t. This commit
simply drops the CoglMatrix type, and align parameters. There is
no functional change here, it's simply a find-and-replace commit.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
Ideally, we would use Graphene to do that, however as of now Graphene
lacks these APIs so we still need these helpers. Since we're preparing
to get rid of CoglMatrix, move them to a separate file, and rename them
with the 'cogl_graphene' prefix.
Since I'm already touching the world with this change, I'm also renaming
cogl_matrix_transform_point() to cogl_graphene_matrix_project_point(),
as per XXX comment, to make it consistent with the transform/projection
semantics in place.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439