From a36e2bc764ba493a07c982995e1f76eac53a9383 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 1 Jun 2020 10:53:24 +0200 Subject: [PATCH] Fix frameclock going backwards When we run the frameclock RUN_FLUSH_IDLE idle before the paint, then gdk_frame_clock_flush_idle() sets ``` priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT ``` at the end if there is a paint comming. But, before doing the paint cycle it may handle other X events, and during that time the phase is set to BEFORE_PAINT. This means that the current check on whether we're inside a paint is wrong: ``` if (priv->phase != GDK_FRAME_CLOCK_PHASE_NONE && priv->phase != GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS) return priv->smoothed_frame_time_base; ``` This caused us to sometimes use this smoothed_frame_time_base even though we previously reported a later value during PHASE_NONE, thus being non-monotonic. We can't just additionally check for the BEGIN_PAINT phase though, becasue if we are in the paint loop actually doing that phase we should use the time base. Instead we check for `!(BEFORE_PAINT && in_paint_idle)`. --- gdk/gdkframeclockidle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c index bbb4e2d26e..ef32ad518a 100644 --- a/gdk/gdkframeclockidle.c +++ b/gdk/gdkframeclockidle.c @@ -236,7 +236,8 @@ gdk_frame_clock_idle_get_frame_time (GdkFrameClock *clock) /* can't change frame time during a paint */ if (priv->phase != GDK_FRAME_CLOCK_PHASE_NONE && - priv->phase != GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS) + priv->phase != GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS && + (priv->phase != GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT || priv->in_paint_idle)) return priv->smoothed_frame_time_base; /* Outside a paint, pick something smoothed close to now */