From 62b224a8dff39703bec39e13ea954b22029ba3df Mon Sep 17 00:00:00 2001 From: Matt Watson Date: Tue, 1 Mar 2016 17:19:50 -0800 Subject: [PATCH] stack: skip first frame for animations Not the ideal solution for this problem, but in practice leads to much better performance on lower end hardware. Stack does a double draw on the first frame of its animation, of both the old contents (into a cairo surface) and the new contents. Homogeneous stacks only need to reallocate contents on the first frame. On lower powered hardware where our frames will be a good deal slower than the refresh rate anyway, we can assure a smother experience by waiting a frame to start tweening where frame duration will be more consistent. --- gtk/gtkstack.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c index 9f1c445dd7..f7d8da5a6d 100644 --- a/gtk/gtkstack.c +++ b/gtk/gtkstack.c @@ -146,6 +146,7 @@ typedef struct { GtkAllocation last_visible_surface_allocation; guint tick_id; GtkProgressTracker tracker; + gboolean first_frame_skipped; gint last_visible_widget_width; gint last_visible_widget_height; @@ -924,8 +925,11 @@ gtk_stack_transition_cb (GtkWidget *widget, GtkStack *stack = GTK_STACK (widget); GtkStackPrivate *priv = gtk_stack_get_instance_private (stack); - gtk_progress_tracker_advance_frame (&priv->tracker, - gdk_frame_clock_get_frame_time (frame_clock)); + if (priv->first_frame_skipped) + gtk_progress_tracker_advance_frame (&priv->tracker, + gdk_frame_clock_get_frame_time (frame_clock)); + else + priv->first_frame_skipped = TRUE; /* Finish animation early if not mapped anymore */ if (!gtk_widget_get_mapped (widget)) @@ -1017,6 +1021,7 @@ gtk_stack_start_transition (GtkStack *stack, priv->last_visible_child != NULL) { priv->active_transition_type = effective_transition_type (stack, transition_type); + priv->first_frame_skipped = FALSE; gtk_stack_schedule_ticks (stack); gtk_progress_tracker_start (&priv->tracker, priv->transition_duration * 1000,