clutter/frame-clock,wayland: Calculate frame deadline during scheduling
Calculate the frame deadline in ClutterFrameClock's calculate_next_update_time_us() rather than in MetaWaylandCompositor's on_after_update(). The specifics of the deadline calculation for a given frame should be implementation detail of the frame clock and and remain internal to allow extensibility. This extensibility is specifically useful for scenarios where a different deadline calculation is needed due to alternative frame scheduling logic, such as for VRR. No change in behavior. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3521>
This commit is contained in:
parent
d5c2f20d55
commit
3e4a330ae7
@ -79,7 +79,9 @@ struct _ClutterFrameClock
|
||||
|
||||
gboolean is_next_presentation_time_valid;
|
||||
int64_t next_presentation_time_us;
|
||||
int64_t min_render_time_allowed_us;
|
||||
|
||||
gboolean has_next_frame_deadline;
|
||||
int64_t next_frame_deadline_us;
|
||||
|
||||
/* Buffer must be submitted to KMS and GPU rendering must be finished
|
||||
* this amount of time before the next presentation time.
|
||||
@ -451,7 +453,7 @@ static void
|
||||
calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||
int64_t *out_next_update_time_us,
|
||||
int64_t *out_next_presentation_time_us,
|
||||
int64_t *out_min_render_time_allowed_us)
|
||||
int64_t *out_next_frame_deadline_us)
|
||||
{
|
||||
int64_t last_presentation_time_us;
|
||||
int64_t now_us;
|
||||
@ -474,7 +476,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||
now_us;
|
||||
|
||||
*out_next_presentation_time_us = 0;
|
||||
*out_min_render_time_allowed_us = 0;
|
||||
*out_next_frame_deadline_us = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -583,7 +585,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||
}
|
||||
else
|
||||
{
|
||||
while (next_presentation_time_us < now_us + min_render_time_allowed_us)
|
||||
while (next_presentation_time_us - min_render_time_allowed_us < now_us)
|
||||
next_presentation_time_us += refresh_interval_us;
|
||||
|
||||
next_update_time_us = next_presentation_time_us - max_render_time_allowed_us;
|
||||
@ -593,7 +595,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||
|
||||
*out_next_update_time_us = next_update_time_us;
|
||||
*out_next_presentation_time_us = next_presentation_time_us;
|
||||
*out_min_render_time_allowed_us = min_render_time_allowed_us;
|
||||
*out_next_frame_deadline_us = next_presentation_time_us - min_render_time_allowed_us;
|
||||
}
|
||||
|
||||
void
|
||||
@ -664,6 +666,7 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
|
||||
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;
|
||||
frame_clock->has_next_frame_deadline = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -686,9 +689,11 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
|
||||
calculate_next_update_time_us (frame_clock,
|
||||
&next_update_time_us,
|
||||
&frame_clock->next_presentation_time_us,
|
||||
&frame_clock->min_render_time_allowed_us);
|
||||
&frame_clock->next_frame_deadline_us);
|
||||
frame_clock->is_next_presentation_time_valid =
|
||||
(frame_clock->next_presentation_time_us != 0);
|
||||
frame_clock->has_next_frame_deadline =
|
||||
(frame_clock->next_frame_deadline_us != 0);
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
return;
|
||||
@ -770,7 +775,9 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
|
||||
frame->frame_count = frame_count;
|
||||
frame->has_target_presentation_time = frame_clock->is_next_presentation_time_valid;
|
||||
frame->target_presentation_time_us = frame_clock->next_presentation_time_us;
|
||||
frame->min_render_time_allowed_us = frame_clock->min_render_time_allowed_us;
|
||||
|
||||
frame->has_frame_deadline = frame_clock->has_next_frame_deadline;
|
||||
frame->frame_deadline_us = frame_clock->next_frame_deadline_us;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockEvents, "Clutter::FrameListener::before_frame()");
|
||||
if (iface->before_frame)
|
||||
|
@ -30,7 +30,9 @@ struct _ClutterFrame
|
||||
|
||||
gboolean has_target_presentation_time;
|
||||
int64_t target_presentation_time_us;
|
||||
int64_t min_render_time_allowed_us;
|
||||
|
||||
gboolean has_frame_deadline;
|
||||
int64_t frame_deadline_us;
|
||||
|
||||
gboolean has_result;
|
||||
ClutterFrameResult result;
|
||||
|
@ -76,12 +76,12 @@ clutter_frame_get_target_presentation_time (ClutterFrame *frame,
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_frame_get_min_render_time_allowed (ClutterFrame *frame,
|
||||
int64_t *min_render_time_allowed_us)
|
||||
clutter_frame_get_frame_deadline (ClutterFrame *frame,
|
||||
int64_t *frame_deadline_us)
|
||||
{
|
||||
if (frame->has_target_presentation_time)
|
||||
if (frame->has_frame_deadline)
|
||||
{
|
||||
*min_render_time_allowed_us = frame->min_render_time_allowed_us;
|
||||
*frame_deadline_us = frame->frame_deadline_us;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -44,8 +44,8 @@ gboolean clutter_frame_get_target_presentation_time (ClutterFrame *frame,
|
||||
int64_t *target_presentation_time_us);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_frame_get_min_render_time_allowed (ClutterFrame *frame,
|
||||
int64_t *min_render_time_allowed_us);
|
||||
gboolean clutter_frame_get_frame_deadline (ClutterFrame *frame,
|
||||
int64_t *frame_deadline_us);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_set_result (ClutterFrame *frame,
|
||||
|
@ -295,8 +295,6 @@ on_after_update (ClutterStage *stage,
|
||||
MetaBackend *backend = meta_context_get_backend (context);
|
||||
MetaFrameNative *frame_native;
|
||||
GSource *source;
|
||||
int64_t min_render_time_allowed_us;
|
||||
int64_t target_presentation_time_us;
|
||||
int64_t frame_deadline_us;
|
||||
|
||||
if (!META_IS_BACKEND_NATIVE (backend))
|
||||
@ -310,19 +308,14 @@ on_after_update (ClutterStage *stage,
|
||||
source = ensure_source_for_stage_view (compositor, stage_view);
|
||||
|
||||
if (meta_frame_native_had_kms_update (frame_native) ||
|
||||
!clutter_frame_get_min_render_time_allowed (frame,
|
||||
&min_render_time_allowed_us) ||
|
||||
!clutter_frame_get_target_presentation_time (frame,
|
||||
&target_presentation_time_us))
|
||||
!clutter_frame_get_frame_deadline (frame,
|
||||
&frame_deadline_us))
|
||||
{
|
||||
g_source_set_ready_time (source, -1);
|
||||
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
||||
return;
|
||||
}
|
||||
|
||||
frame_deadline_us = target_presentation_time_us -
|
||||
min_render_time_allowed_us;
|
||||
|
||||
if (frame_deadline_us <= g_get_monotonic_time ())
|
||||
{
|
||||
g_source_set_ready_time (source, -1);
|
||||
|
Loading…
Reference in New Issue
Block a user