clutter/stage-cogl: Stop schedule_update
repeatedly returning now
That could happen if the backend did not provide presentation timestamps, or if the screen was not changing other than the hardware cursor: if (stage_cogl->last_presentation_time == 0|| stage_cogl->last_presentation_time < now - 150000) { stage_cogl->update_time = now; return; } By setting `update_time` to `now`, master_clock_get_swap_wait_time() returns 0: gint64 now = g_source_get_time (master_clock->source); if (min_update_time < now) { return 0; } else { gint64 delay_us = min_update_time - now; return (delay_us + 999) / 1000; } However, zero is a value unsupported by the default master clock due to: if (swap_delay != 0) return swap_delay; All cases are now handled by extrapolating when the next presentation time would be and calculating an appropriate update time to meet that. We also need to add a check for `update_time == last_update_time`, which is a situation that just became possible since we support old (or zero) values of `last_presentation_time`. This avoids getting more than one stage update per frame interval when input events arrive without triggering a stage redraw (e.g. moving the hardware cursor). https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
This commit is contained in:
parent
a76762a05e
commit
35aa278194
@ -185,18 +185,6 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only extrapolate presentation times for 150ms - this is somewhat
|
|
||||||
* arbitrary. The reasons it might not be accurate for larger times are
|
|
||||||
* that the refresh interval might be wrong or the vertical refresh
|
|
||||||
* might be downclocked if nothing is going on onscreen.
|
|
||||||
*/
|
|
||||||
if (stage_cogl->last_presentation_time == 0||
|
|
||||||
stage_cogl->last_presentation_time < now - 150000)
|
|
||||||
{
|
|
||||||
stage_cogl->update_time = now;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh_rate = stage_cogl->refresh_rate;
|
refresh_rate = stage_cogl->refresh_rate;
|
||||||
if (refresh_rate <= 0.0)
|
if (refresh_rate <= 0.0)
|
||||||
refresh_rate = clutter_get_default_frame_rate ();
|
refresh_rate = clutter_get_default_frame_rate ();
|
||||||
@ -220,6 +208,9 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
|||||||
next_presentation_time += refresh_interval;
|
next_presentation_time += refresh_interval;
|
||||||
|
|
||||||
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
|
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
|
||||||
|
|
||||||
|
if (stage_cogl->update_time == stage_cogl->last_update_time)
|
||||||
|
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint64
|
static gint64
|
||||||
@ -238,6 +229,7 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
|
|||||||
{
|
{
|
||||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||||
|
|
||||||
|
stage_cogl->last_update_time = stage_cogl->update_time;
|
||||||
stage_cogl->update_time = -1;
|
stage_cogl->update_time = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ struct _ClutterStageCogl
|
|||||||
|
|
||||||
gint64 last_presentation_time;
|
gint64 last_presentation_time;
|
||||||
gint64 update_time;
|
gint64 update_time;
|
||||||
|
int64_t last_update_time;
|
||||||
|
|
||||||
/* We only enable clipped redraws after 2 frames, since we've seen
|
/* We only enable clipped redraws after 2 frames, since we've seen
|
||||||
* a lot of drivers can struggle to get going and may output some
|
* a lot of drivers can struggle to get going and may output some
|
||||||
|
Loading…
Reference in New Issue
Block a user