SF: Reimplement modesetting state machine
The motivation is to:
- Avoid redundant state that can cause data races if stale.
- Consolidate control flow for resolution and refresh rate changes.
- Clarify the desired/pending/active states of the per-display FSM.
For the synced_resolution_switch feature, this fixes the bad state when
DM requests different resolutions in quick succession. Previously, SF::
setDesiredMode failed to emit a mode change event if a mode was already
desired or pending. Now, DMC::setDesiredMode returns DesiredModeAction::
None if and only if (1) the old desired mode has the same resolution, or
(2) there is no desired or pending mode, and the active mode has the
same resolution.
Other notable changes are as follows:
Flow the DisplayModeRequest through the desired/pending/active states.
Consume the desired DisplayModeRequestOpt in initiateDisplayModeChanges,
either through SF::dropModeRequest or DMC::initiateModeChange. Since we
now takeDesiredMode from DMC, mStateLock is no longer needed to ensure
mutual exclusion of setDesiredMode and initiateDisplayModeChanges, i.e.
a concurrent setDesiredMode can no longer race with the few calls to
getDesiredMode in initiateDisplayModeChanges. A future CL will remove
the lock. For the synced_resolution_switch feature, takeDesiredMode
accepts an expected resolution, and only takes a matching desired mode.
Pull the details of SF::finalizeDisplayModeChange into DMC::
finalizeModeChange, which now returns whether there was NoModeChange,
a ResolutionChange, or a RefreshRateChange. Consume the pending request.
Now that DMC does not retain the desired DisplayModeRequest, proceed to
applyActiveMode as soon as finalizeDisplayModeChange ends, rather than
at a later point in the commit, when initiateDisplayModeChanges checks
whether the active and desired modes are the same.
Now that applyActiveMode happens in finalizeDisplayModeChange, it is no
longer called by initiateDisplayModeChanges when the active and desired
modes are the same. However, that branch was taken during boot, where SF
does NOT initiate a mode change, but must still applyActiveMode after it
queries HWC for the active mode. Make an explicit call in initScheduler,
which already did the setRenderRate step of applyActiveMode as a special
case for VRR.
Now that applyActiveMode happens in finalizeDisplayModeChange, simplify
the special case for immediate mode set in initiateDisplayModeChanges.
Bug: 434757601
Bug: 405220949
Flag: com.android.graphics.surfaceflinger.flags.modeset_state_machine
Test: MRR (Multiple Refresh Rates) still works on phone and foldable.
Test: Resolution switch does not fail on phone and external display.
Test: DisplayModeControllerTest
Test: DisplayModeSwitchingTest
Test: FrameRateOverrideTest (CtsGraphicsTestCases)
Change-Id: Iad23030c664175d4e6278ba8b94fcb2a5e66d5fe
Loading
Please register or sign in to comment