On a hybrid machine with i915 primary and nvidia-drm (470) secondary,
`meta_render_device_egl_stream_initable_init` calls
`meta_kms_inhibit_kernel_thread` to change from the default 'kernel'
thread type to 'user'. And soon after that it would
`meta_render_device_egl_stream_finalize` because I'm not actually
using that GPU, and calls `meta_kms_uninhibit_kernel_thread`.
So during startup Mutter would default to a realtime kernel thread,
switch to a user thread (which doesn't support realtime), and then
switch back to a realtime kernel thread.
In the middle of all that, while the thread type was 'user' and
realtime disabled, something was invoking `ensure_crtc_frame` which
created a `CrtcFrame` without a deadline timer. Soon after that the
thread type changed back to 'kernel' with deadline timers expected, but
our existing `CrtcFrame` has no deadline timer associated with it. And
so it would never fire, causing the cursor to freeze whenever the primary
plane isn't changing. And the problem was permanent, not just the first
frame because each `CrtcFrame` gets repeatedly reused (maybe shouldn't
be called a "Frame"?).
Now we adapt to switching between kernel and user thread types by adding
and removing the deadline timer as required.
Close: https://gitlab.gnome.org/GNOME/mutter/-/issues/3464
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3950>
If we finish compositing in time, the composited result will be
submitted prior to the deadline timer is triggered, and we'll be fine,
and if not, at least the cursor updates will be smooth, which makes it
appear smoother than not.
There is a risk that this can negatively impact composited updates when
moving the cursor, so make it possible to toggle a paint-debug flag for
now until this has been more tested.
This also mean we need to disarm the deadline timer after handling
update, as there might be a scheduled cursor update pending, but we
already handled it, so disarm the timer.
Here is an illustration of the difference.
In the following scenario, with disarming, the composited frame E, and
the cursor movement C gets presented. With this branch, only the cursor
movement C gets presented.
```
* A: beginning of composited frame
* B: begin notification reaches KMS thread
* C: cursor moved
* D: calculated deadline dispatch time (disabled with the branch)
* E: KMS update posted
* F: KMS update reaches KMS thread
* G: actual deadline (and with branch and gets committed)
Compositor thread: --------A---------------E---------
\ \
\ \
KMS thread: -----------B------C----D---F-G----
```
In the following scenario, by not disarming, the cursor update C will be
presented, and the would-be-delayed composited frame E would be delayed
anyway, i.e. fixing cursor stutter.
```
* A: beginning of composited frame
* B: begin notification reaches KMS thread
* C: cursor moved
* D: calculated deadline dispatch time (and with branch will be dispatched)
* E: KMS update posted
* F: actual deadline
* G: KMS update reaches KMS thread (and with branch gets postponed)
Compositor thread: --------A---------------E---------
\ \
\ \
KMS thread: -----------B------C----D-F-G------
```
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3184>
Although we track updates for EGL_DEVICE, they are often empty because
the primary plane has a custom page flip method. That means there's
no CRTC latched yet, but we do know exactly which CRTC is associated
with the flip. Set it so the update can still be processed.
Fixes: 27ed069766 ("kms/impl-device: Add deadline based KMS commit scheduling")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3939>
The relationship between MetaKmsConnector and MetaDrmLease is already
stored in MetaDrmLeaseManager::leased_connectors.
Change the type of MetaDrmLeaseManager::connectors to a GList.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3922>
As in the protocol definition for wp_drm_lease_connector_v1::withdrawn:
Sent to indicate that the compositor will no longer honor requests
for DRM leases which include this connector. [...] Compositors are
encouraged to send this event when [...] the connector gets leased
to a client.
Withdrawn the leased connectors and, if they are available once the
lease finishes, advertise them again.
Related to: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/322/
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3922>
And stop passing in the color states from the RendererNative. We also
keep the color states updated by listening for changes in the color
device.
The RendererX11Cm has a single view and no mapping to a specific color
device, so we handle the absense of a color device as well and rely on
ClutterStageView to have the default color states.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3930>
This allows us to destroy and create a new offscreen dynamically, when
the rotation or color state changes.
An idle gsource with priority higher than CLUTTER_PRIORITY_REDRAW is
used to ensure the an offscreen exists when required without having to
allocate in the redraw process.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3930>
When triple buffering, `meta_onscreen_native_prepare_frame` for the next
frame is called before `notify_view_crtc_presented` for the previous frame.
So our booleans were unfortunately still TRUE in the second prepare_frame,
resulting in two frames with the same property updates.
When double buffering, having roughly one frame interval between
`meta_onscreen_native_prepare_frame` and `notify_view_crtc_presented`
meant that property updates signalled between the swap and presentation
wouldn't get attached to a KMS update, and would be forgotten when
`notify_view_crtc_presented` resets the flags to FALSE.
To solve these we now keep a separate flag and counter per property,
tracking invalidation and pending updates respectively. The latter is a
counter rather than a boolean in support of triple buffering where two
updates may be pending concurrently (next and posted).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3912>
Because if the current theme has exceeded the dimensions of
`DRM_CAP_CURSOR_WIDTH/HEIGHT` then the warning is just going to repeat
every time the cursor changes. We still fall back to software cursors
just fine so it's not important to repeat the warning.
In Mutter 46 the warning was "Invalid theme cursor size". Same problem.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3597
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3924>
by executing `global.context.get_debug_control().exported = true`.
This makes it possible to get access to the debug service without having
to start with `--enable-debug`.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3902>
It won't be used until later when we flip, and in fact assigning
it early could have led to its own assertion failing on the next frame
in the unlikely event that we return with "Failed to ensure KMS FB ID...
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3891>
Introduced in libinput 1.26 this feature allows restricting the
tablet tool pressure range to a subset of its physical range. The
use-case is either to require some higher-than-usual minimum pressure
before the pen reacts, or lower-than-usual pressure to reach the maximum
logical pressure.
libinput takes a [0.0, 1.0] normalized range which we expose as percent
in the gsettings. The wacom driver doesn't have an exact equivalent but
it has a Threshold setting (range [1, 2048]) that defines when a button
is generated for tip down.
See gsettings-desktop-schemas!84
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3794>
Stylus actions that don't map into LMR or back/forward are now created
as a clutter button event with a button number of zero. Nothing is
actually done with those events for now, they're just discarded later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3649>
For stylus buttons we apply a button mapping, e.g. secondary button ->
right. This mapping was previously applied to the clutter event's evdev
code only, not the actual clutter button. As a result, gnome-shell would
always treat the BTN_STYLUS as middle and BTN_STYLUS2 as right,
regardless of the mapping.
Move the mapping up so we first adjust our evcode, then proceed with
the usual mappings.
Note that this temporary breaks the stylus mapping to Back/Forward which
will be fixed in a follow-up commit.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3649>
Use the helper function for mapping a stylus tool evdev code to a
clutter button code. This fixes a (theoretical) issue - if a tool were
to send any button other than the one we handled those would likely be
BTN_SIDE and friends and we'd likely end up with negative button
numbers. The BTN_TOOL_PEN range is not predicable enough to do any sort
of calculation conversion because things like BTN_TOOL_DOUBLETAP have
specific meanings that aren't actually buttons.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3649>
Instead of using cairo for scaling and rotating cursors before putting
them on a plane, use Cogl. For now still download them back to the CPU
so we can place them on a dumb buffer, but can explore rendering to a
DMA buffer directly as a future improvement.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
Allow compositing in a linear color space and do so either when forcing
it via the debug controls D-Bus API, or when the experimental HDR mode
is enabled.
This relies on paint nodes etc to actually transform everything into the
linear target color space, which isn't done yet, so enabling it right
now will cause a broken result. Yet, introduce this now, so that
painting can be fixed piece by piece.
Linear blending is automatically enabled on monitors where HDR is
enabled, as this makes it possible to use an linear color space when
blending content from different color spaces with different transfer
functions.
Linear blending requires extra precision, i.e. 16 bit per channel
in the intermediate buffer due how the values are distributed,
so only enable the experimental HDR mode if the Cogl context supports
half float formats.
By default, no intermadiate linear offscreen framebuffer is used.
To test, do e.g.
./tools/debug-control.py --toggle ForceLinearBlending
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
This reverts commit a3082b8eb3.
We don't find the VKMS device with this commit because it is on seat0
and not on META_BACKEND_TEST_INPUT_SEAT.
The other way around, i.e. returning seat0 in all cases also doesn't
work because *something* hangs if the default seat referrs to the real
seat0 instead of the nonesense META_BACKEND_TEST_INPUT_SEAT.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3869>
Fixes error building against libdrm >= 2.4.122:
../src/backends/native/meta-kms-plane.c:67:8: error: redefinition of ‘struct drm_plane_size_hint’
67 | struct drm_plane_size_hint {
| ^~~~~~~~~~~~~~~~~~~
In file included from /usr/local/include/libdrm/drm.h:1025,
from /usr/local/include/xf86drm.h:40,
from ../src/backends/native/meta-kms-plane-private.h:20,
from ../src/backends/native/meta-kms-plane.c:21:
/usr/local/include/libdrm/drm_mode.h:866:8: note: originally defined here
866 | struct drm_plane_size_hint {
| ^~~~~~~~~~~~~~~~~~~
Suggested by Jonas Ådahl.
v2:
* Use has_type. (Sebastian Wick)
v3: (jadahl)
* Bump meson requirement to 1.3.0 for compiler.has_type()
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3556
Fixes: 0ca933baec ("backend/native: Adds support for SIZE_HINTS Cursor Plane Property")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3848>
In meta_seat_impl_remove_virtual_input_device(), the 'device'
variable is first removed from MetaSeatImpl, then a "device
removed" event is generated with it.
The problem here is that, if this is the last reference of
'device', the removal from MetaSeatImpl will destroy it. Then
the freed variable will be used to create the "device removed"
event, which is a use-after-free situation.
Fix that by owning an extra ref to 'device' as long as the
function is executing. Do this by declaring a g_autoptr
variable with the extra ref. This g_autoptr variable is cleaned
up by the end of the function, which achieves the desired effect.
Spotted by Coverity.
CID: #1594046
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3835>
Instead of having get_seat_id() handle most cases, and then special
casing another case outside of it, let it handle them all, making all
users just able to call get_seat_id().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3812>