frame clock: Track if paint is caused by thaw or not

When we get to a paint cycle we now know if this was caused by a
thaw, which typically means last frame was drawn, or some other event.

In the first case the time of the cycle is tied to the vblank in some
sense, and in the others it is essentially random. We can use this
information to compute better frame times. (Will be done in later
commits.)

(cherry picked from commit 82c314f1af3fca776d4e7796ab7555b7182c8464)
This commit is contained in:
Alexander Larsson
2020-06-05 11:16:57 +02:00
parent ede4d06192
commit 87721d0da7

View File

@ -57,6 +57,7 @@ struct _GdkFrameClockIdlePrivate
GdkFrameClockPhase phase; GdkFrameClockPhase phase;
guint in_paint_idle : 1; guint in_paint_idle : 1;
guint paint_is_thaw : 1;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
guint begin_period : 1; guint begin_period : 1;
#endif #endif
@ -276,7 +277,8 @@ gdk_frame_clock_idle_get_frame_time (GdkFrameClock *clock)
(priv)->updating_count > 0)) (priv)->updating_count > 0))
static void static void
maybe_start_idle (GdkFrameClockIdle *clock_idle) maybe_start_idle (GdkFrameClockIdle *clock_idle,
gboolean caused_by_thaw)
{ {
GdkFrameClockIdlePrivate *priv = clock_idle->priv; GdkFrameClockIdlePrivate *priv = clock_idle->priv;
@ -304,6 +306,7 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle)
if (!priv->in_paint_idle && if (!priv->in_paint_idle &&
priv->paint_idle_id == 0 && RUN_PAINT_IDLE (priv)) priv->paint_idle_id == 0 && RUN_PAINT_IDLE (priv))
{ {
priv->paint_is_thaw = caused_by_thaw;
priv->paint_idle_id = gdk_threads_add_timeout_full (GDK_PRIORITY_REDRAW, priv->paint_idle_id = gdk_threads_add_timeout_full (GDK_PRIORITY_REDRAW,
min_interval, min_interval,
gdk_frame_clock_paint_idle, gdk_frame_clock_paint_idle,
@ -563,7 +566,7 @@ gdk_frame_clock_paint_idle (void *data)
{ {
priv->min_next_frame_time = compute_min_next_frame_time (clock_idle, priv->min_next_frame_time = compute_min_next_frame_time (clock_idle,
priv->frame_time); priv->frame_time);
maybe_start_idle (clock_idle); maybe_start_idle (clock_idle, FALSE);
} }
if (priv->freeze_count == 0) if (priv->freeze_count == 0)
@ -580,7 +583,7 @@ gdk_frame_clock_idle_request_phase (GdkFrameClock *clock,
GdkFrameClockIdlePrivate *priv = clock_idle->priv; GdkFrameClockIdlePrivate *priv = clock_idle->priv;
priv->requested |= phase; priv->requested |= phase;
maybe_start_idle (clock_idle); maybe_start_idle (clock_idle, FALSE);
} }
static void static void
@ -599,7 +602,7 @@ gdk_frame_clock_idle_begin_updating (GdkFrameClock *clock)
#endif #endif
priv->updating_count++; priv->updating_count++;
maybe_start_idle (clock_idle); maybe_start_idle (clock_idle, FALSE);
} }
static void static void
@ -651,7 +654,7 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock)
priv->freeze_count--; priv->freeze_count--;
if (priv->freeze_count == 0) if (priv->freeze_count == 0)
{ {
maybe_start_idle (clock_idle); maybe_start_idle (clock_idle, TRUE);
/* If nothing is requested so we didn't start an idle, we need /* If nothing is requested so we didn't start an idle, we need
* to skip to the end of the state chain, since the idle won't * to skip to the end of the state chain, since the idle won't
* run and do it for us. * run and do it for us.