1
0
Fork 0

clutter/frame-clock: Add environment variable MUTTER_DEBUG_TRIPLE_BUFFERING

With possible values {never, auto, always} where auto is the default.

This also allows some unification with automatic throttling for
direct scanout.
This commit is contained in:
Daniel van Vugt 2022-03-10 16:44:14 +08:00
parent 53888593a8
commit cc9fdb67ce

View file

@ -42,6 +42,15 @@ enum
static guint signals[N_SIGNALS];
typedef enum
{
TRIPLE_BUFFERING_MODE_NEVER,
TRIPLE_BUFFERING_MODE_AUTO,
TRIPLE_BUFFERING_MODE_ALWAYS,
} TripleBufferingMode;
static TripleBufferingMode triple_buffering_mode = TRIPLE_BUFFERING_MODE_AUTO;
#define SYNC_DELAY_FALLBACK_FRACTION 0.875
#define MINIMUM_REFRESH_RATE 30.f
@ -917,6 +926,12 @@ void
clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
{
int64_t next_update_time_us = -1;
TripleBufferingMode current_mode = triple_buffering_mode;
if (current_mode == TRIPLE_BUFFERING_MODE_AUTO &&
(frame_clock->last_flip_hints &
CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED))
current_mode = TRIPLE_BUFFERING_MODE_NEVER;
if (frame_clock->inhibit_count > 0)
{
@ -940,20 +955,31 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED_NOW:
return;
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE:
if (frame_clock->last_flip_hints & CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED)
switch (current_mode)
{
/* Force double buffering, disable triple buffering */
case TRIPLE_BUFFERING_MODE_NEVER:
frame_clock->pending_reschedule = TRUE;
return;
case TRIPLE_BUFFERING_MODE_AUTO:
calculate_next_update_time_us (frame_clock,
&next_update_time_us,
&frame_clock->next_presentation_time_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);
frame_clock->state =
CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED;
break;
case TRIPLE_BUFFERING_MODE_ALWAYS:
next_update_time_us = g_get_monotonic_time ();
frame_clock->next_presentation_time_us = 0;
frame_clock->is_next_presentation_time_valid = FALSE;
frame_clock->state =
CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED;
break;
}
calculate_next_update_time_us (frame_clock,
&next_update_time_us,
&frame_clock->next_presentation_time_us,
&frame_clock->next_frame_deadline_us);
frame_clock->is_next_presentation_time_valid =
(frame_clock->next_presentation_time_us != 0);
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED;
break;
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_TWO:
frame_clock->pending_reschedule = TRUE;
@ -1395,6 +1421,15 @@ static void
clutter_frame_clock_class_init (ClutterFrameClockClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
const char *mode_str;
mode_str = g_getenv ("MUTTER_DEBUG_TRIPLE_BUFFERING");
if (!g_strcmp0 (mode_str, "never"))
triple_buffering_mode = TRIPLE_BUFFERING_MODE_NEVER;
else if (!g_strcmp0 (mode_str, "auto"))
triple_buffering_mode = TRIPLE_BUFFERING_MODE_AUTO;
else if (!g_strcmp0 (mode_str, "always"))
triple_buffering_mode = TRIPLE_BUFFERING_MODE_ALWAYS;
object_class->dispose = clutter_frame_clock_dispose;