clutter/frame-clock: Add a state for when scheduled "now"
The new CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW state is almost identical to CLUTTER_FRAME_CLOCK_STATE_SCHEDULED, with one important difference being that it avoids updates from being repeatedly rescheduled "now" when multiple calls to clutter_frame_clock_schedule_update_now() are done before the source is actually dispatched. Such repeated calls to schedule an update "now" may actually postpone the dispatch if the CPU is very busy and the source dispatch is delayed, defeating the purpose of scheduling a frame "now". It also allows rescheduling "now" when the frame clock is uninhibited after being inhibited while an update was scheduled "now". This may be important in cases where the frame clock is inhibited for very short periods in which it would otherwise lose the state of being scheduled "now". Scenarios such as this would become more common with the introduction of variable refresh rate since it makes scheduling "now" a commonplace occurrence. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3561>
This commit is contained in:
parent
f72dbc8046
commit
82cdf90a71
@ -55,6 +55,7 @@ typedef enum _ClutterFrameClockState
|
|||||||
CLUTTER_FRAME_CLOCK_STATE_INIT,
|
CLUTTER_FRAME_CLOCK_STATE_INIT,
|
||||||
CLUTTER_FRAME_CLOCK_STATE_IDLE,
|
CLUTTER_FRAME_CLOCK_STATE_IDLE,
|
||||||
CLUTTER_FRAME_CLOCK_STATE_SCHEDULED,
|
CLUTTER_FRAME_CLOCK_STATE_SCHEDULED,
|
||||||
|
CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW,
|
||||||
CLUTTER_FRAME_CLOCK_STATE_DISPATCHING,
|
CLUTTER_FRAME_CLOCK_STATE_DISPATCHING,
|
||||||
CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED,
|
CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED,
|
||||||
} ClutterFrameClockState;
|
} ClutterFrameClockState;
|
||||||
@ -390,6 +391,7 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
|
|||||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||||
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
break;
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||||
@ -411,6 +413,7 @@ clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock)
|
|||||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||||
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
break;
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||||
@ -620,6 +623,11 @@ clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock)
|
|||||||
frame_clock->pending_reschedule = TRUE;
|
frame_clock->pending_reschedule = TRUE;
|
||||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW:
|
||||||
|
frame_clock->pending_reschedule = TRUE;
|
||||||
|
frame_clock->pending_reschedule_now = TRUE;
|
||||||
|
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
||||||
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||||
break;
|
break;
|
||||||
@ -659,6 +667,8 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
|
|||||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||||
next_update_time_us = g_get_monotonic_time ();
|
next_update_time_us = g_get_monotonic_time ();
|
||||||
break;
|
break;
|
||||||
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW:
|
||||||
|
return;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||||
frame_clock->pending_reschedule = TRUE;
|
frame_clock->pending_reschedule = TRUE;
|
||||||
@ -670,7 +680,7 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
|
|||||||
|
|
||||||
frame_clock->next_update_time_us = next_update_time_us;
|
frame_clock->next_update_time_us = next_update_time_us;
|
||||||
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_NOW;
|
||||||
frame_clock->is_next_presentation_time_valid = FALSE;
|
frame_clock->is_next_presentation_time_valid = FALSE;
|
||||||
frame_clock->has_next_frame_deadline = FALSE;
|
frame_clock->has_next_frame_deadline = FALSE;
|
||||||
}
|
}
|
||||||
@ -702,6 +712,7 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
|
|||||||
(frame_clock->next_frame_deadline_us != 0);
|
(frame_clock->next_frame_deadline_us != 0);
|
||||||
break;
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||||
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW:
|
||||||
return;
|
return;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||||
@ -808,6 +819,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
|
|||||||
break;
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||||
|
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED_NOW:
|
||||||
break;
|
break;
|
||||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||||
switch (result)
|
switch (result)
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
stateDiagram
|
stateDiagram
|
||||||
Init --> Scheduled : schedule update() -> now
|
Init --> Scheduled/ScheduledNow : schedule update() -> now
|
||||||
Idle --> Scheduled : schedule update() -> given presentation time
|
Idle --> Scheduled/ScheduledNow : schedule update() -> given presentation time
|
||||||
Scheduled --> Dispatching : target time hit
|
Scheduled/ScheduledNow --> Dispatching : target time hit
|
||||||
Dispatching --> PendingPresented : queued page flip
|
Dispatching --> PendingPresented : queued page flip
|
||||||
Dispatching --> Idle : no queued page flip
|
Dispatching --> Idle : no queued page flip
|
||||||
PendingPresented --> Scheduled : page flipped, if recent schedule update
|
PendingPresented --> Scheduled/ScheduledNow : page flipped, if recent schedule update
|
||||||
PendingPresented --> Idle : page flipped
|
PendingPresented --> Idle : page flipped
|
||||||
```
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user