kms/impl-device: Use deadline timer for all updates

Not with VRR though, because the deadline timer fires at most every 33ms
then.

Previously, the deadline timer was used only for cursor-only updates.
Using it for other updates means they pick up the latest cursor position
available at the deadline, resulting in the lowest possible input→output
latency for cursor movement.

TTBOMK this unlocks the full potential of the KMS thread given the
current atomic KMS API.

v2:
* Don't call meta_kms_update_merge_from with twice the same update
  pointer.
v3:
* Don't arm deadline timer if crtc_frame->pending_page_flip is true.
v4:
* Tweak want_deadline_timer indentation per check-code-style CI job.
v5:
* Also check crtc_frame->await_flush for want_deadline_timer.
v6:
* Tweak coding style to keep lines shorter. (Jonas Ådahl)

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3964>
This commit is contained in:
Michel Dänzer 2024-08-19 18:56:20 +02:00 committed by Marge Bot
parent 315dfaa5d4
commit 23f3c17f0c

View File

@ -1840,6 +1840,7 @@ meta_kms_impl_device_update_ready (MetaThreadImpl *impl,
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
MetaKmsImplDevicePrivate *priv = MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device); meta_kms_impl_device_get_instance_private (impl_device);
gboolean want_deadline_timer;
MetaKmsUpdate *update; MetaKmsUpdate *update;
MetaKmsCrtc *latch_crtc; MetaKmsCrtc *latch_crtc;
MetaKmsFeedback *feedback; MetaKmsFeedback *feedback;
@ -1853,24 +1854,39 @@ meta_kms_impl_device_update_ready (MetaThreadImpl *impl,
latch_crtc = g_steal_pointer (&crtc_frame->submitted_update.latch_crtc); latch_crtc = g_steal_pointer (&crtc_frame->submitted_update.latch_crtc);
if (crtc_frame->pending_page_flip && want_deadline_timer =
!crtc_frame->await_flush &&
is_using_deadline_timer (impl_device) &&
!meta_kms_crtc_get_current_state (crtc_frame->crtc)->vrr.enabled;
if ((want_deadline_timer || crtc_frame->pending_page_flip) &&
!meta_kms_update_get_mode_sets (update)) !meta_kms_update_get_mode_sets (update))
{ {
g_assert (latch_crtc); if (crtc_frame->pending_page_flip)
{
g_assert (latch_crtc);
meta_topic (META_DEBUG_KMS, meta_topic (META_DEBUG_KMS,
"Queuing update on CRTC %u (%s): pending page flip", "Queuing update on CRTC %u (%s): pending page flip",
meta_kms_crtc_get_id (latch_crtc), meta_kms_crtc_get_id (latch_crtc),
priv->path); priv->path);
}
queue_update (impl_device, crtc_frame, update); queue_update (impl_device, crtc_frame, update);
return GINT_TO_POINTER (TRUE);
if (crtc_frame->pending_page_flip ||
ensure_deadline_timer_armed (impl_device, crtc_frame))
return GINT_TO_POINTER (TRUE);
} }
if (crtc_frame->pending_update) if (crtc_frame->pending_update)
{ {
meta_kms_update_merge_from (crtc_frame->pending_update, update); if (update != crtc_frame->pending_update)
meta_kms_update_free (update); {
meta_kms_update_merge_from (crtc_frame->pending_update, update);
meta_kms_update_free (update);
}
update = g_steal_pointer (&crtc_frame->pending_update); update = g_steal_pointer (&crtc_frame->pending_update);
disarm_crtc_frame_deadline_timer (crtc_frame); disarm_crtc_frame_deadline_timer (crtc_frame);
} }