[gnome-builder/wip/plugins] animation: update animation values during GdkFrameClock::after-paint
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/plugins] animation: update animation values during GdkFrameClock::after-paint
- Date: Thu, 11 Jun 2015 00:01:19 +0000 (UTC)
commit 7019f1e06231874348244d2a03c3af40a0b92f7f
Author: Christian Hergert <christian hergert me>
Date: Wed Jun 10 17:01:10 2015 -0700
animation: update animation values during GdkFrameClock::after-paint
This gives us the most amount of time to be able to draw the next frame
during animated sequences. Upon the "update" signal, if we get the same
offset as what we projected, we can avoid the secondary update.
libide/theatrics/ide-animation.c | 96 ++++++++++++++++++++++++++++---------
1 files changed, 72 insertions(+), 24 deletions(-)
---
diff --git a/libide/theatrics/ide-animation.c b/libide/theatrics/ide-animation.c
index fd76bad..3e44557 100644
--- a/libide/theatrics/ide-animation.c
+++ b/libide/theatrics/ide-animation.c
@@ -18,6 +18,7 @@
#include <glib/gi18n.h>
#include <gobject/gvaluecollector.h>
+#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <string.h>
@@ -45,13 +46,15 @@ struct _IdeAnimation
{
GInitiallyUnowned parent_instance;
- gpointer target; /* Target object to animate */
- guint64 begin_msec; /* Time in which animation started */
- guint duration_msec; /* Duration of animation */
- guint mode; /* Tween mode */
- guint tween_handler; /* GSource performing tweens */
- GArray *tweens; /* Array of tweens to perform */
- GdkFrameClock *frame_clock; /* An optional frame-clock for sync. */
+ gpointer target; /* Target object to animate */
+ guint64 begin_msec; /* Time in which animation started */
+ guint duration_msec; /* Duration of animation */
+ guint mode; /* Tween mode */
+ gulong tween_handler; /* GSource or signal handler */
+ gulong after_paint_handler; /* signal handler */
+ gdouble last_offset; /* Track our last offset */
+ GArray *tweens; /* Array of tweens to perform */
+ GdkFrameClock *frame_clock; /* An optional frame-clock for sync. */
};
G_DEFINE_TYPE (IdeAnimation, ide_animation, G_TYPE_INITIALLY_UNOWNED)
@@ -279,29 +282,33 @@ ide_animation_unload_begin_values (IdeAnimation *animation)
/**
* ide_animation_get_offset:
- * @animation: (in): A #IdeAnimation.
+ * @animation: A #IdeAnimation.
+ * @frame_time: the time to present the frame, or 0 for current timing.
*
* Retrieves the position within the animation from 0.0 to 1.0. This
* value is calculated using the msec of the beginning of the animation
* and the current time.
*
* Returns: The offset of the animation from 0.0 to 1.0.
- * Side effects: None.
*/
static gdouble
-ide_animation_get_offset (IdeAnimation *animation)
+ide_animation_get_offset (IdeAnimation *animation,
+ gint64 frame_time)
{
- GdkFrameClock *frame_clock;
gdouble offset;
gint64 frame_msec;
g_return_val_if_fail (IDE_IS_ANIMATION (animation), 0.0);
- if (GTK_IS_WIDGET (animation->target) &&
- (frame_clock = gtk_widget_get_frame_clock (animation->target)))
- frame_msec = gdk_frame_clock_get_frame_time (frame_clock) / 1000UL;
- else
- frame_msec = g_get_monotonic_time () / 1000UL;
+ if (frame_time == 0)
+ {
+ if (animation->frame_clock != NULL)
+ frame_time = gdk_frame_clock_get_frame_time (animation->frame_clock);
+ else
+ frame_time = g_get_monotonic_time ();
+ }
+
+ frame_msec = frame_time / 1000L;
offset = (gdouble) (frame_msec - animation->begin_msec) /
(gdouble) animation->duration_msec;
@@ -447,9 +454,9 @@ ide_animation_set_target (IdeAnimation *animation,
* Side effects: None.
*/
static gboolean
-ide_animation_tick (IdeAnimation *animation)
+ide_animation_tick (IdeAnimation *animation,
+ gdouble offset)
{
- gdouble offset;
gdouble alpha;
GValue value = { 0 };
Tween *tween;
@@ -457,7 +464,9 @@ ide_animation_tick (IdeAnimation *animation)
g_return_val_if_fail (IDE_IS_ANIMATION (animation), FALSE);
- offset = ide_animation_get_offset (animation);
+ if (offset == animation->last_offset)
+ return offset < 1.0;
+
alpha = gAlphaFuncs[animation->mode](offset);
/*
@@ -503,6 +512,8 @@ ide_animation_tick (IdeAnimation *animation)
}
#endif
+ animation->last_offset = offset;
+
return offset < 1.0;
}
@@ -521,8 +532,11 @@ ide_animation_timeout_cb (gpointer user_data)
{
IdeAnimation *animation = user_data;
gboolean ret;
+ gdouble offset;
+
+ offset = ide_animation_get_offset (animation, 0);
- if (!(ret = ide_animation_tick (animation)))
+ if (!(ret = ide_animation_tick (animation, offset)))
ide_animation_stop (animation);
return ret;
@@ -539,13 +553,40 @@ ide_animation_widget_tick_cb (GdkFrameClock *frame_clock,
g_assert (IDE_IS_ANIMATION (animation));
if (animation->tween_handler)
- if (!(ret = ide_animation_tick (animation)))
- ide_animation_stop (animation);
+ {
+ gdouble offset;
+
+ offset = ide_animation_get_offset (animation, 0);
+
+ if (!(ret = ide_animation_tick (animation, offset)))
+ ide_animation_stop (animation);
+ }
return ret;
}
+static void
+ide_animation_widget_after_paint_cb (GdkFrameClock *frame_clock,
+ IdeAnimation *animation)
+{
+ gint64 base_time;
+ gint64 interval;
+ gint64 next_frame_time;
+ gdouble offset;
+
+ g_assert (GDK_IS_FRAME_CLOCK (frame_clock));
+ g_assert (IDE_IS_ANIMATION (animation));
+
+ base_time = gdk_frame_clock_get_frame_time (frame_clock);
+ gdk_frame_clock_get_refresh_info (frame_clock, base_time, &interval, &next_frame_time);
+
+ offset = ide_animation_get_offset (animation, next_frame_time);
+
+ ide_animation_tick (animation, offset);
+}
+
+
/**
* ide_animation_start:
* @animation: (in): A #IdeAnimation.
@@ -573,14 +614,19 @@ ide_animation_start (IdeAnimation *animation)
"update",
G_CALLBACK (ide_animation_widget_tick_cb),
animation);
+ animation->after_paint_handler =
+ g_signal_connect (animation->frame_clock,
+ "after-paint",
+ G_CALLBACK (ide_animation_widget_after_paint_cb),
+ animation);
gdk_frame_clock_begin_updating (animation->frame_clock);
}
else
{
animation->begin_msec = g_get_monotonic_time () / 1000UL;
animation->tween_handler = ide_frame_source_add (FALLBACK_FRAME_RATE,
- ide_animation_timeout_cb,
- animation);
+ ide_animation_timeout_cb,
+ animation);
}
}
@@ -606,6 +652,7 @@ ide_animation_stop (IdeAnimation *animation)
{
gdk_frame_clock_end_updating (animation->frame_clock);
g_signal_handler_disconnect (animation->frame_clock, animation->tween_handler);
+ g_signal_handler_disconnect (animation->frame_clock, animation->after_paint_handler);
animation->tween_handler = 0;
}
else
@@ -892,6 +939,7 @@ ide_animation_init (IdeAnimation *animation)
animation->duration_msec = 250;
animation->mode = IDE_ANIMATION_EASE_IN_OUT_QUAD;
animation->tweens = g_array_new (FALSE, FALSE, sizeof (Tween));
+ animation->last_offset = -G_MINDOUBLE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]