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;
|
gboolean is_next_presentation_time_valid;
|
||||||
int64_t next_presentation_time_us;
|
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
|
/* Buffer must be submitted to KMS and GPU rendering must be finished
|
||||||
* this amount of time before the next presentation time.
|
* this amount of time before the next presentation time.
|
||||||
@ -451,7 +453,7 @@ static void
|
|||||||
calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||||
int64_t *out_next_update_time_us,
|
int64_t *out_next_update_time_us,
|
||||||
int64_t *out_next_presentation_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 last_presentation_time_us;
|
||||||
int64_t now_us;
|
int64_t now_us;
|
||||||
@ -474,7 +476,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
|||||||
now_us;
|
now_us;
|
||||||
|
|
||||||
*out_next_presentation_time_us = 0;
|
*out_next_presentation_time_us = 0;
|
||||||
*out_min_render_time_allowed_us = 0;
|
*out_next_frame_deadline_us = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,7 +585,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
|||||||
}
|
}
|
||||||
else
|
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_presentation_time_us += refresh_interval_us;
|
||||||
|
|
||||||
next_update_time_us = next_presentation_time_us - max_render_time_allowed_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_update_time_us = next_update_time_us;
|
||||||
*out_next_presentation_time_us = next_presentation_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
|
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);
|
g_source_set_ready_time (frame_clock->source, next_update_time_us);
|
||||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED;
|
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED;
|
||||||
frame_clock->is_next_presentation_time_valid = FALSE;
|
frame_clock->is_next_presentation_time_valid = FALSE;
|
||||||
|
frame_clock->has_next_frame_deadline = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -686,9 +689,11 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
|
|||||||
calculate_next_update_time_us (frame_clock,
|
calculate_next_update_time_us (frame_clock,
|
||||||
&next_update_time_us,
|
&next_update_time_us,
|
||||||
&frame_clock->next_presentation_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->is_next_presentation_time_valid =
|
||||||
(frame_clock->next_presentation_time_us != 0);
|
(frame_clock->next_presentation_time_us != 0);
|
||||||
|
frame_clock->has_next_frame_deadline =
|
||||||
|
(frame_clock->next_frame_deadline_us != 0);
|
||||||
break;
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||||
return;
|
return;
|
||||||
@ -770,7 +775,9 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
|
|||||||
frame->frame_count = frame_count;
|
frame->frame_count = frame_count;
|
||||||
frame->has_target_presentation_time = frame_clock->is_next_presentation_time_valid;
|
frame->has_target_presentation_time = frame_clock->is_next_presentation_time_valid;
|
||||||
frame->target_presentation_time_us = frame_clock->next_presentation_time_us;
|
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()");
|
COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockEvents, "Clutter::FrameListener::before_frame()");
|
||||||
if (iface->before_frame)
|
if (iface->before_frame)
|
||||||
|
@ -30,7 +30,9 @@ struct _ClutterFrame
|
|||||||
|
|
||||||
gboolean has_target_presentation_time;
|
gboolean has_target_presentation_time;
|
||||||
int64_t target_presentation_time_us;
|
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;
|
gboolean has_result;
|
||||||
ClutterFrameResult result;
|
ClutterFrameResult result;
|
||||||
|
@ -76,12 +76,12 @@ clutter_frame_get_target_presentation_time (ClutterFrame *frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
clutter_frame_get_min_render_time_allowed (ClutterFrame *frame,
|
clutter_frame_get_frame_deadline (ClutterFrame *frame,
|
||||||
int64_t *min_render_time_allowed_us)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -44,8 +44,8 @@ gboolean clutter_frame_get_target_presentation_time (ClutterFrame *frame,
|
|||||||
int64_t *target_presentation_time_us);
|
int64_t *target_presentation_time_us);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
gboolean clutter_frame_get_min_render_time_allowed (ClutterFrame *frame,
|
gboolean clutter_frame_get_frame_deadline (ClutterFrame *frame,
|
||||||
int64_t *min_render_time_allowed_us);
|
int64_t *frame_deadline_us);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
void clutter_frame_set_result (ClutterFrame *frame,
|
void clutter_frame_set_result (ClutterFrame *frame,
|
||||||
|
@ -295,8 +295,6 @@ on_after_update (ClutterStage *stage,
|
|||||||
MetaBackend *backend = meta_context_get_backend (context);
|
MetaBackend *backend = meta_context_get_backend (context);
|
||||||
MetaFrameNative *frame_native;
|
MetaFrameNative *frame_native;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
int64_t min_render_time_allowed_us;
|
|
||||||
int64_t target_presentation_time_us;
|
|
||||||
int64_t frame_deadline_us;
|
int64_t frame_deadline_us;
|
||||||
|
|
||||||
if (!META_IS_BACKEND_NATIVE (backend))
|
if (!META_IS_BACKEND_NATIVE (backend))
|
||||||
@ -310,19 +308,14 @@ on_after_update (ClutterStage *stage,
|
|||||||
source = ensure_source_for_stage_view (compositor, stage_view);
|
source = ensure_source_for_stage_view (compositor, stage_view);
|
||||||
|
|
||||||
if (meta_frame_native_had_kms_update (frame_native) ||
|
if (meta_frame_native_had_kms_update (frame_native) ||
|
||||||
!clutter_frame_get_min_render_time_allowed (frame,
|
!clutter_frame_get_frame_deadline (frame,
|
||||||
&min_render_time_allowed_us) ||
|
&frame_deadline_us))
|
||||||
!clutter_frame_get_target_presentation_time (frame,
|
|
||||||
&target_presentation_time_us))
|
|
||||||
{
|
{
|
||||||
g_source_set_ready_time (source, -1);
|
g_source_set_ready_time (source, -1);
|
||||||
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_deadline_us = target_presentation_time_us -
|
|
||||||
min_render_time_allowed_us;
|
|
||||||
|
|
||||||
if (frame_deadline_us <= g_get_monotonic_time ())
|
if (frame_deadline_us <= g_get_monotonic_time ())
|
||||||
{
|
{
|
||||||
g_source_set_ready_time (source, -1);
|
g_source_set_ready_time (source, -1);
|
||||||
|
Loading…
Reference in New Issue
Block a user