More precisely, wait until no further udev hotplug events have arrived
in 2 seconds.
Keep a list of unique UpdateStatesData structs which have received
hotplug events, and call handle_hotplug_event for all of them once the
timeout expires.
This avoids problems due to some monitors generating hotplug events
when power saving is enabled on locking the session, and then
temporarily appearing disconnected.
v2:
* Make meta_test_disconnect_connect wait and run main context dispatch
before checking the number of logical monitors.
v3:
* Call g_source_unref immediately after g_source_attach, simplifies
source cleanup. (Sebastian Wick)
* Free hotplug devices list in meta_kms_finalize. (Sebastian Wick)
* Add KMS debug logging in on_udev_hotplug & hotplug_timeout.
* Bump timeout to 2 seconds. With my affected monitor, the second udev
hotplug event normally arrives almost a second after the first one,
occasionally more than 1.5 seconds though.
* Use UpdateStatesData with custom compare function for hotplug_devices
list data, since the GUdevDevice / device path string pointer values
are always different.
* Don't wait for timeout if meta_is_udev_test_device returns TRUE, to
hopefully fix VKMS CI tests. Drop meta_test_disconnect_connect changes
again.
v4:
* Use hash table instead of list for hotplug_events set. (Sebastian Wick)
* Add comment describing the keys & values in the hash table. (Sebastian Wick)
* Add KMS debug logging in handle_hotplug_event as well.
* Dropped Closes:, this might not suffice to fully address
https://gitlab.gnome.org/GNOME/mutter/-/issues/3831 after all.
v5:
* Simplify hash table annotation comment. (Sebastian Wick)
v6:
* Rename hotplug_timeout local string pointer to hotplug_event.
* Drop g_clear_pointer in favour of g_autofree in on_udev_hotplug.
(Sebastian Wick)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4209>
Handle NULL string pointer in meta_kms_update_states_in_impl.
Drop second parameter of meta_kms_update_states_sync, which wasn't used
by the external test caller anyway. Split out static update_states_sync
function which takes a hotplug event string pointer instead.
Preparation for next commit.
v2:
* Drop UpdteStatesData for encoded hotplug event strings.
v3:
* Put device path at the end of encoded string, allows simplifying
meta_kms_update_states_in_impl slightly further.
v4: (Sebastian Wick)
* Use g_autofree for hotplug_event string in on_udev_hotplug, fixes
leak.
* Store pointer to hotplug event device path string in local variable in
meta_kms_update_states_in_impl.
v5:
* Initialize `path` local variable to `NULL` and test it instead of the
`hotplug_event` parameter. Avoids (false-positive) compiler warning
about `path` possibly being used uninitialized.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4209>
It forced the power save mode to META_POWER_SAVE_ON when reading the
current KMS state.
This was problematic when a hotplug event is emitted while the session
is locked, which can be triggered by monitors polling all their inputs
for a signal: There's no mechanism to restore the previous power save
mode in this case, so the monitors would fail to actually enter power
saving mode but stayed on with a blank screen. This was at least one
cause of the symptoms described in
https://gitlab.freedesktop.org/drm/amd/-/issues/662 .
Moreover, I suspect it hasn't had any effect for the actual reading of
KMS state since 5f6aee341959 ("kms/update: Make power saving an update
wide change"), as changing the power save mode to META_POWER_SAVE_ON no
longer results in any immediate KMS state change, it's now only taken
into account for the next mode set.
It's not clear what the intended effect was in the first place, it was
originally added as part of 65db8efbe8b1 ("MonitorManager: add a KMS
backend") without rationale. It might have been cargo-culted from
somewhere else. It shouldn't be necessary from a KMS API PoV though.
Also adjust the KMS hotplug test to assert that a hotplug event doesn't
implicitly change the power save mode.
v2: (Sebastian Wick)
* Fix shortlog of commit which added
meta_monitor_manager_native_read_current_state.
v3:
* Adjust KMS hotplug test for the change.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4209>
Unused since f27ca241f9a2 ("renderer/native: Move per frame KMS update
to MetaFrameNative") / a6baa77eab89 ("kms: Split out impl/non-impl
separation into MetaThread(Impl)").
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4209>
As a follow-up to 87cc6633a5, embed a partial copy of the Adwaita cursor theme
and point to it with XCURSOR_PATH to make the test completely independent
from the installed cursor themes.
Indeed, adwaita-icon-theme changed ever so slightly in version 48 so the
ref tests started failing when the new version was installed.
This is a copy of adwaita-icon-theme 47, which is what was used to generate
the ref images.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4252>
This requires reverting the previous changes intended for adapting to
triple buffering.
Fixes these tests randomly failing, also in CI pipelines of MRs not
directly related to any of this.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4290>
As per previous commit we're figuring out the bash location on shebang
using env, let's do it everywhere for coherency, even if in CI fedora
may not yet have issues about this.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4288>
Bash can be in both /usr/bin/bash or /bin/bash (or elsewhere!) depending on
the distro, so let's be generic using env to figure it out.
This comes from a packaging lintian error we get:
E: mutter-16-tests: wrong-path-for-interpreter /usr/bin/bash != /bin/bash
[usr/share/mutter-16/tests/socket-launch.sh]
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4288>
Avoids the following warning in the logs
mutter-x11-frame[4003]: Using
GtkSettings:gtk-application-prefer-dark-theme with libadwaita is
unsupported. Please use AdwStyleManager:color-scheme instead.
When initializing libadwaita, the AdwStyleManager default instance is
initialized taking care of loading the appropriate stylesheet.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4276>
It tests that the cursor renderer can successfully initialize with the
environment variable MUTTER_DEBUG_DISABLE_HW_CURSORS=1.
It would have caught the crash fixed by the previous commit.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4272>
Don't try to realize the cursor sprite for the HW cursor when it's set.
v2:
* Refactor is_hw_cursor_supported helper out of
realize_cursor_sprite_from_wl_buffer_for_crtc. (Jonas Ådahl)
v3:
* Keep meta_crtc_native_is_hw_cursor_supported check in
meta_cursor_renderer_native_update_cursor, to try and avoid
mysterious CI failure.
v4:
* Rename is_hw_cursor_supported → is_hw_cursor_available_for_gpu
and take a MetaGpuKms * parameter.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4272>
We want to ensure that also the stderr is matching our golden files
and at the same time we should be able to see it in logs (especially
when there's a python error to catch).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4277>
While having automatic completions is a very nice feature of gdctl (I
had suggested to use it too :)), it's not something that distros may
have by default and in particular it's not a package in main in ubuntu.
So, make the code less restrictive on completions, since completions is
not a core functionality of the tool and it can definitely work without
them.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4279>
While the `get_key_focus()` method returned the stage itself when
no explicit focus was set, it made sense for the corresponding
setter to accept the stage as synonym for NULL.
But now that the getter always returns the property value, it
makes more sense to expect NULL to unset the key focus.
Keep the current behavior of normalizing the key focus to NULL
in that case to minimize breakage, but print a warning to
use NULL instead.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
Moving the key focus to the stage should be done by unsetting the
focus rather than setting it to the stage itself.
`clutter_stage_set_key_focus()` already "normalizes" the stage to
NULL internally, so this does not change the actual behavior of the
code.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
The method currently returns the stage itself when the property
is NULL.
This has become particularly problematic as the method is detected
as getter by gobject introspection, and gjs now optimizes property
accesses by calling the getter method instead.
Address this by turning the method into a genuine getter without
falling back to the stage.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
While the existing `get_key_focus()` methods looks like a getter of the
`key-focus` property and is detected as such by gobject introspection,
it behaves differently in that it returns the stage if no explicit
focus has been set.
This is about to change, so adjust the couple of cases that rely
on the fallback to the stage.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
Previously if we had no measurements then `compute_max_render_time_us`
would pessimise its answer to ensure triple buffering could be reached:
if (frame_clock->state >= CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE)
ret += refresh_interval_us;
But that also meant entering triple buffering even when not required.
Now we make `compute_max_render_time_us` more honest and return failure
if the answer isn't known (or is disabled). This in turn allows us to
optimize `calculate_next_update_time_us` for this special case, ensuring
triple buffering can be used, but isn't blindly always used. So when
TIMESTAMP_QUERY support is missing we now take the same path as if
presentation timestamps are missing (introduced in 56fc09151d and
improved in 0555a5bbc1), which has the benefit of naturally switching
from double to triple buffering as required without actually having to
measure render times.
This makes a visible difference to the latency when dragging windows in
Xorg, but will also help Wayland sessions on platforms lacking
TIMESTAMP_QUERY such as Raspberry Pi.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
This replaces the DISPATCHED state with new sub-states that are possible
with triple buffering:
DISPATCHED_ONE: Double buffering
DISPATCHED_ONE_AND_SCHEDULED: Scheduled switch to triple buffering
DISPATCHED_ONE_AND_SCHEDULED_NOW: Scheduled switch to triple buffering
DISPATCHED_ONE_AND_SCHEDULED_LATER: Scheduled switch to triple buffering
DISPATCHED_TWO: Triple buffering
Triple buffering is currently disabled until the test cases get updated to
handle it in the next commit.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
Chronologically they already overlap in time as presentation may
complete in the middle of the dispatch function, otherwise they are
contiguous in time. And most switch statements treated the two states
the same already so they're easy to merge into a single `DISPATCHED`
state.
Having fewer states now will make life easier when we add more states
later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
Error diffusion was introduced in 0555a5bbc15 for Nvidia where last
presentation time is always unknown (zero). Dispatch times would drift
apart always being a fraction of a frame late, and accumulated to cause
periodic frame skips. So error diffusion corrected that precisely and
avoided the skips.
That works great with double buffering but less great with triple
buffering. It's certainly still needed with triple buffering but
correcting for a lateness of many milliseconds isn't a good idea. That's
because a dispatch being that late is not due to main loop jitter but due
to Nvidia's swap buffers blocking when the queue is full. So scheduling
the next frame even earlier using last_dispatch_lateness_us would just
perpetuate the problem of swap buffers blocking for too long.
So now we lower the threshold of when error diffusion gets disabled. It's
still high enough to fix the original smoothness problem it was for, but
now low enough to detect Nvidia's occasionally blocking swaps and backs
off in that case.
Since the average duration of a blocking swap is half a frame interval
and we want to distinguish between that and sub-millisecond jitter, the
logical threshold is halfway again: refresh_interval_us/4.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
Although since all SCHEDULED* states basically have the same transitions
it's easier to show them as a single state. The mermaid diagram also won't
render correctly if there is a mix of combined and singular states. We
must use either always combined states or always singular states.
Fixes: 5b214dc2b7 ("clutter/frame-clock: Allow scheduling an update in the future")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
It's analogous to discard_pending_page_flips but represents swaps that
might become flips after the next frame notification callbacks, thanks
to triple buffering. Since the views are being rebuilt and their onscreens
are about to be destroyed, turning those swaps into more flips/posts would
just lead to unexpected behaviour (like trying to flip on a half-destroyed
inactive CRTC).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
All paths out of `meta_onscreen_native_swap_buffers_with_damage` from
here onward would set the same `CLUTTER_FRAME_RESULT_PENDING_PRESENTED`
(or terminate with `g_assert_not_reached`).
Even failed posts set this result because they will do a
`meta_onscreen_native_notify_frame_complete` in
`page_flip_feedback_discarded`.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>