summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clutter/clutter/clutter-frame-clock.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c
index 4d441c364..4361df704 100644
--- a/clutter/clutter/clutter-frame-clock.c
+++ b/clutter/clutter/clutter-frame-clock.c
@@ -85,6 +85,7 @@ struct _ClutterFrameClock
int64_t last_dispatch_time_us;
int64_t last_dispatch_lateness_us;
int64_t last_presentation_time_us;
+ int64_t next_update_time_us;
gboolean is_next_presentation_time_valid;
int64_t next_presentation_time_us;
@@ -96,6 +97,8 @@ struct _ClutterFrameClock
/* Last KMS buffer submission time. */
int64_t last_flip_time_us;
+ /* Last few durations between desired and effective dispatch start. */
+ EstimateQueue dispatch_lateness_us;
/* Last few durations between dispatch start and buffer swap. */
EstimateQueue dispatch_to_swap_us;
/* Last few durations between buffer swap and GPU rendering finish. */
@@ -273,6 +276,9 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
if (frame_info->presentation_time > 0)
frame_clock->last_presentation_time_us = frame_info->presentation_time;
+ estimate_queue_add_value (&frame_clock->dispatch_lateness_us,
+ frame_clock->last_dispatch_lateness_us);
+
frame_clock->got_measurements_last_frame = FALSE;
if (frame_info->cpu_time_before_buffer_swap_us != 0 &&
@@ -290,7 +296,8 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
frame_info->cpu_time_before_buffer_swap_us;
CLUTTER_NOTE (FRAME_TIMINGS,
- "dispatch2swap %ld µs, swap2render %ld µs, swap2flip %ld µs",
+ "update2dispatch %ld µs, dispatch2swap %ld µs, swap2render %ld µs, swap2flip %ld µs",
+ frame_clock->last_dispatch_lateness_us,
dispatch_to_swap_us,
swap_to_rendering_done_us,
swap_to_flip_us);
@@ -304,6 +311,11 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
frame_clock->got_measurements_last_frame = TRUE;
}
+ else
+ {
+ CLUTTER_NOTE (FRAME_TIMINGS, "update2dispatch %ld µs",
+ frame_clock->last_dispatch_lateness_us);
+ }
if (frame_info->refresh_rate > 1.0)
{
@@ -350,6 +362,7 @@ static int64_t
clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
{
int64_t refresh_interval_us;
+ int64_t max_dispatch_lateness_us = 0;
int64_t max_dispatch_to_swap_us = 0;
int64_t max_swap_to_rendering_done_us = 0;
int64_t max_swap_to_flip_us = 0;
@@ -365,6 +378,9 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i)
{
+ max_dispatch_lateness_us =
+ MAX (max_dispatch_lateness_us,
+ frame_clock->dispatch_lateness_us.values[i]);
max_dispatch_to_swap_us =
MAX (max_dispatch_to_swap_us,
frame_clock->dispatch_to_swap_us.values[i]);
@@ -378,6 +394,7 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
/* Max render time shows how early the frame clock needs to be dispatched
* to make it to the predicted next presentation time. It is composed of:
+ * - An estimate of dispatch start lateness.
* - An estimate of duration from dispatch start to buffer swap.
* - Maximum between estimates of duration from buffer swap to GPU rendering
* finish and duration from buffer swap to buffer submission to KMS. This
@@ -387,6 +404,7 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
* - A constant to account for variations in the above estimates.
*/
max_render_time_us =
+ max_dispatch_lateness_us +
max_dispatch_to_swap_us +
MAX (max_swap_to_rendering_done_us, max_swap_to_flip_us) +
frame_clock->vblank_duration_us +
@@ -612,6 +630,7 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
g_warn_if_fail (next_update_time_us != -1);
+ frame_clock->next_update_time_us = next_update_time_us;
g_source_set_ready_time (frame_clock->source, next_update_time_us);
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED;
frame_clock->is_next_presentation_time_valid = FALSE;
@@ -650,6 +669,7 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
g_warn_if_fail (next_update_time_us != -1);
+ frame_clock->next_update_time_us = next_update_time_us;
g_source_set_ready_time (frame_clock->source, next_update_time_us);
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED;
}
@@ -672,9 +692,13 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
this_dispatch_time_us = time_us;
#endif
- ideal_dispatch_time_us = (frame_clock->last_dispatch_time_us -
- frame_clock->last_dispatch_lateness_us) +
- frame_clock->refresh_interval_us;
+
+ ideal_dispatch_time_us = frame_clock->next_update_time_us;
+
+ if (ideal_dispatch_time_us <= 0)
+ ideal_dispatch_time_us = (frame_clock->last_dispatch_time_us -
+ frame_clock->last_dispatch_lateness_us) +
+ frame_clock->refresh_interval_us;
lateness_us = time_us - ideal_dispatch_time_us;
if (lateness_us < 0 || lateness_us >= frame_clock->refresh_interval_us)
@@ -770,6 +794,7 @@ clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
GString *
clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock)
{
+ int64_t max_dispatch_lateness_us = 0;
int64_t max_dispatch_to_swap_us = 0;
int64_t max_swap_to_rendering_done_us = 0;
int64_t max_swap_to_flip_us = 0;
@@ -787,6 +812,9 @@ clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clo
for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i)
{
+ max_dispatch_lateness_us =
+ MAX (max_dispatch_lateness_us,
+ frame_clock->dispatch_lateness_us.values[i]);
max_dispatch_to_swap_us =
MAX (max_dispatch_to_swap_us,
frame_clock->dispatch_to_swap_us.values[i]);
@@ -800,6 +828,8 @@ clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clo
g_string_append_printf (string, "\nVblank duration: %ld µs +",
frame_clock->vblank_duration_us);
+ g_string_append_printf (string, "\nDispatch lateness: %ld µs +",
+ max_dispatch_lateness_us);
g_string_append_printf (string, "\nDispatch to swap: %ld µs +",
max_dispatch_to_swap_us);
g_string_append_printf (string, "\nmax(Swap to rendering done: %ld µs,",