mutter/src
Dor Askayo b8deb4caa0 wayland: Emit frame callbacks when the frame is pending presentation
When Wayland clients send commits without a buffer attached ("empty"
commits), they may lead to stage updates that do not result in any
frame being submitted for presentation ("empty" updates).

Due to how frame scheduling is handled, there can be many such
"empty" updates in a single refresh cycle. If frame callbacks were
emitted after each of these "empty" updates, and if the client
sending "empty" commits was using frame callbacks to throttle the
same logic that results in these "empty" commits being sent, it would
result in a feedback loop between Mutter and the client where the
client would send "empty" commits and Mutter would reply almost
immediately with a frame callback causing the client to send "empty"
commits continuously.

As such, when an "empty" update is detected, frame callbacks are
scheduled to be emitted only once in every refresh cycle, avoiding the
feedback loop.

When a "non-empty" update is detected, frame callbacks are instead
emitted immediately to allow clients to draw their next frame as soon
as possible. It is safe to emit frame callbacks in this case because
the frame for the current refresh cycle is already "finalized" and
that any commit sent by the client at that point would only be handled
in a future refresh cycle.

To implement this, the previous logic had used
meta_frame_native_had_kms_update() to detect "non-empty" updates,
assuming that those would always result in a KMS presentation with the
native backend.

However, this approach misses the fact that virtual monitors do not
use KMS, and as such do not result in KMS presentation even for
"non-empty" updates. As a result, frame callbacks would not be emitted
immediately, resulting in unintended throttling of client rendering.

Instead, assume that it is safe to emit frame callbacks immediately
whenever an update results in the frame clock waiting to be notified
of presentation, since this is also when commits sent by clients are
scheduled to be handled in a future refresh cycle.

This issue was mostly hidden because frame callbacks would be sent
immediately when the target presentation time for the frame had
changed compared to the previous frame. However, this behavior was
removed in 26d8b9c69 ("wayland: Remove unnecessary dispatch of frame
callback source"), exposing the issue.

Fixes: a7a7933e0 ("wayland: Emit frame events in GSource after "empty" updates")
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3263
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3549>
2024-01-26 22:22:52 +00:00
..
backends clutter: Prefer using ClutterTextDirection 2024-01-22 15:02:33 +00:00
common backend/native: Move DrmFormatBuf to cogl-drm-formats 2024-01-03 14:46:41 +01:00
compositor backends: Allow XKB model to be configured 2024-01-18 18:51:42 +00:00
core place: Fix centering transients over parent 2024-01-18 16:07:15 +00:00
frames frames: Notify borders on first content resize 2024-01-03 19:31:51 +00:00
meta clutter: Prefer using ClutterTextDirection 2024-01-22 15:02:33 +00:00
tests wayland: Switch to stable linux-dmabuf protocol 2024-01-22 14:20:30 +00:00
wayland wayland: Emit frame callbacks when the frame is pending presentation 2024-01-26 22:22:52 +00:00
x11 x11: Defer ClutterStage focus actor change until window is focused 2024-01-10 20:56:24 +01:00
meson.build clutter: Prefer using ClutterTextDirection 2024-01-22 15:02:33 +00:00
meta-private-enum-types.c.in build: Add missing include 2022-08-10 20:28:40 +02:00
meta-private-enum-types.h.in cleanup: Switch to pragma once 2023-08-07 22:24:36 +00:00