gdk: Enable clock updates when timelines are added to the clock

Enable animation updates from the GdkFrameClock whenever any timeline is
added to the ClutterMasterClockGdk. This may improve animation
smoothness (depending on the GDK backend in use) because it allows GDK
to tweak its frame timing for animation purposes.

https://bugzilla.gnome.org/show_bug.cgi?id=755357
This commit is contained in:
Lionel Landwerlin 2015-09-22 17:27:42 +01:00
parent 9ef5fd104a
commit b9df8524f0

View File

@ -113,6 +113,32 @@ master_clock_schedule_forced_stages_updates (ClutterMasterClockGdk *master_clock
GDK_FRAME_CLOCK_PHASE_PAINT); GDK_FRAME_CLOCK_PHASE_PAINT);
} }
static void
master_clock_sync_frame_clock_update (ClutterMasterClockGdk *master_clock)
{
gboolean updating = master_clock->timelines != NULL;
gpointer frame_clock, stage_list;
GHashTableIter iter;
g_hash_table_iter_init (&iter, master_clock->clock_to_stage);
while (g_hash_table_iter_next (&iter, &frame_clock, &stage_list))
{
gboolean clock_updating =
GPOINTER_TO_UINT (g_object_get_data (frame_clock,
"clutter-master-clock-updating"));
if (clock_updating != updating)
{
if (updating)
gdk_frame_clock_begin_updating (GDK_FRAME_CLOCK (frame_clock));
else
gdk_frame_clock_end_updating (GDK_FRAME_CLOCK (frame_clock));
g_object_set_data (frame_clock,
"clutter-master-clock-updating",
GUINT_TO_POINTER (updating));
}
}
}
static void static void
master_clock_schedule_stage_update (ClutterMasterClockGdk *master_clock, master_clock_schedule_stage_update (ClutterMasterClockGdk *master_clock,
ClutterStage *stage, ClutterStage *stage,
@ -306,9 +332,19 @@ clutter_master_clock_gdk_remove_stage_clock (ClutterMasterClockGdk *master_clock
{ {
if (stages->next == NULL) if (stages->next == NULL)
{ {
/* Deleting the last stage linked to a given clock. We can stop
listening to that clock and also tell the clock we're finish
updating it. */
if (GPOINTER_TO_UINT (g_object_get_data (frame_clock,
"clutter-master-clock-updating")))
{
gdk_frame_clock_end_updating (GDK_FRAME_CLOCK (frame_clock));
g_object_set_data (frame_clock, "clutter-master-clock-updating", NULL);
}
g_signal_handlers_disconnect_by_func (frame_clock, g_signal_handlers_disconnect_by_func (frame_clock,
clutter_master_clock_gdk_update, clutter_master_clock_gdk_update,
master_clock); master_clock);
g_hash_table_remove (master_clock->clock_to_stage, frame_clock); g_hash_table_remove (master_clock->clock_to_stage, frame_clock);
g_list_free (stages); g_list_free (stages);
} }
@ -349,7 +385,12 @@ clutter_master_clock_gdk_add_stage_clock (ClutterMasterClockGdk *master_clock,
stages = g_list_append (stages, stage); stages = g_list_append (stages, stage);
if (master_clock->timelines != NULL) if (master_clock->timelines != NULL)
_clutter_master_clock_start_running ((ClutterMasterClock *) master_clock); {
_clutter_master_clock_start_running ((ClutterMasterClock *) master_clock);
/* We only need to synchronize the frame clock state if we have
timelines running. */
master_clock_sync_frame_clock_update (master_clock);
}
} }
static void static void
@ -501,7 +542,11 @@ clutter_master_clock_gdk_add_timeline (ClutterMasterClock *clock,
timeline); timeline);
if (is_first) if (is_first)
_clutter_master_clock_start_running (clock); {
_clutter_master_clock_start_running (clock);
/* Sync frame clock update state if needed. */
master_clock_sync_frame_clock_update (master_clock);
}
} }
static void static void
@ -512,6 +557,10 @@ clutter_master_clock_gdk_remove_timeline (ClutterMasterClock *clock,
master_clock->timelines = g_slist_remove (master_clock->timelines, master_clock->timelines = g_slist_remove (master_clock->timelines,
timeline); timeline);
/* Sync frame clock update state if we have no more timelines running. */
if (master_clock->timelines == NULL)
master_clock_sync_frame_clock_update (master_clock);
} }
static void static void