[gtk+/wip/watson/progress-tracker: 14/30] stack: skip first frame for animations



commit 8285e930322ca7edd2daaa827e56d801e6ff8caa
Author: Matt Watson <mattdangerw gmail com>
Date:   Tue Mar 1 17:19:50 2016 -0800

    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 files changed, 7 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index 77457e3..c37c8e4 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_next_frame (&priv->tracker,
-                                   gdk_frame_clock_get_frame_time (frame_clock));
+  if (priv->first_frame_skipped)
+    gtk_progress_tracker_next_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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]