From 90aee21f2021aebde91b23adff89531665f6f7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 11 Jun 2024 15:26:03 +0200 Subject: [PATCH] clutter/frame-clock: Only update immediately after idle if vsynced If the presentation time isn't known, e.g. if the monitor is virtual and the actual presentation happens far away, the presentation time we actually received tends to be the time a frame was presented to the next layer, meaning practically immediately after painting. When scheduling another update after that, don't assume that if the next calculated update is not the immediate next update, schedule an update sooner, as that will in such cases always be true, meaning we ended up busy looping with constant frame updates being scheduled. Fix this by only triggering that logic if the last presentation time was actually vsync:ed. Part-of: --- clutter/clutter/clutter-frame-clock.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c index 93e4c9329..30a319f60 100644 --- a/clutter/clutter/clutter-frame-clock.c +++ b/clutter/clutter/clutter-frame-clock.c @@ -96,6 +96,8 @@ struct _ClutterFrameClock int64_t last_presentation_time_us; int64_t next_update_time_us; + ClutterFrameInfoFlag last_presentation_flags; + gboolean is_next_presentation_time_valid; int64_t next_presentation_time_us; @@ -357,7 +359,10 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, #endif if (frame_info->presentation_time > 0) - frame_clock->last_presentation_time_us = frame_info->presentation_time; + { + frame_clock->last_presentation_time_us = frame_info->presentation_time; + frame_clock->last_presentation_flags = frame_info->flags; + } frame_clock->got_measurements_last_frame = FALSE; @@ -601,7 +606,8 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock, } } - if (next_presentation_time_us != last_presentation_time_us + refresh_interval_us) + if (frame_clock->last_presentation_flags & CLUTTER_FRAME_INFO_FLAG_VSYNC && + next_presentation_time_us != last_presentation_time_us + refresh_interval_us) { /* There was an idle period since the last presentation, so there seems * be no constantly updating actor. In this case it's best to start