IO_METHOD(IoClutter, getDefaultFrameRate) { return IONUMBER(clutter_get_default_frame_rate()); }
/* * master_clock_next_frame_delay: * @master_clock: a #ClutterMasterClock * * Computes the number of delay before we need to draw the next frame. * * Return value: -1 if there is no next frame pending, otherwise the * number of millseconds before the we need to draw the next frame */ static gint master_clock_next_frame_delay (ClutterMasterClock *master_clock) { gint64 now, next; if (!master_clock_is_running (master_clock)) return -1; /* When we have sync-to-vblank, we count on swap-buffer requests (or * swap-buffer-complete events if supported in the backend) to throttle our * frame rate so no additional delay is needed to start the next frame. * * If the master-clock has become idle due to no timeline progression causing * redraws then we can no longer rely on vblank synchronization because the * last real stage update/redraw may have happened a long time ago and so we * fallback to polling for timeline progressions every 1/frame_rate seconds. * * (NB: if there aren't even any timelines running then the master clock will * be completely stopped in master_clock_is_running()) */ if (clutter_feature_available (CLUTTER_FEATURE_SYNC_TO_VBLANK) && !master_clock->idle) { CLUTTER_NOTE (SCHEDULER, "vblank available and updated stages"); return 0; } if (master_clock->prev_tick == 0) { /* If we weren't previously running, then draw the next frame * immediately */ CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately"); return 0; } /* Otherwise, wait at least 1/frame_rate seconds since we last * started a frame */ #if GLIB_CHECK_VERSION (2, 27, 3) now = g_source_get_time (master_clock->source); #else { GTimeVal source_time; g_source_get_current_time (master_clock->source, &source_time); now = source_time.tv_sec * 1000000L + source_time.tv_usec; } #endif next = master_clock->prev_tick; /* If time has gone backwards then there's no way of knowing how long we should wait so let's just dispatch immediately */ if (now <= next) { CLUTTER_NOTE (SCHEDULER, "Time has gone backwards"); return 0; } next += (1000000L / clutter_get_default_frame_rate ()); if (next <= now) { CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs", 1000000L / (gulong) clutter_get_default_frame_rate ()); return 0; } else { CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs", (next - now) / 1000); return (next - now) / 1000; } }