blob: af3e909bcf3b1ae6948d4cd3932991496b5a7ace [file] [log] [blame]
Dominik Laskowski6e465152022-09-28 11:00:25 -04001/*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <memory>
Dominik Laskowski5c989f52024-04-11 13:57:14 -040020#include <mutex>
21#include <string>
Dominik Laskowski6e465152022-09-28 11:00:25 -040022#include <utility>
23
24#include <android-base/thread_annotations.h>
Dominik Laskowski5c989f52024-04-11 13:57:14 -040025#include <ftl/function.h>
26#include <ftl/optional.h>
Dominik Laskowski6e465152022-09-28 11:00:25 -040027#include <ui/DisplayId.h>
28#include <ui/DisplayMap.h>
29
Dominik Laskowski5c989f52024-04-11 13:57:14 -040030#include "Display/DisplayModeRequest.h"
Dominik Laskowski6e465152022-09-28 11:00:25 -040031#include "Display/DisplaySnapshotRef.h"
32#include "DisplayHardware/DisplayMode.h"
33#include "Scheduler/RefreshRateSelector.h"
34#include "ThreadContext.h"
Dominik Laskowski5c989f52024-04-11 13:57:14 -040035#include "TracedOrdinal.h"
36
37namespace android {
38class HWComposer;
39} // namespace android
Dominik Laskowski6e465152022-09-28 11:00:25 -040040
41namespace android::display {
42
43// Selects the DisplayMode of each physical display, in accordance with DisplayManager policy and
44// certain heuristic signals.
45class DisplayModeController {
46public:
Dominik Laskowski5c989f52024-04-11 13:57:14 -040047 using ActiveModeListener = ftl::Function<void(PhysicalDisplayId, Fps vsyncRate, Fps renderFps)>;
Dominik Laskowski6e465152022-09-28 11:00:25 -040048
Dominik Laskowski5c989f52024-04-11 13:57:14 -040049 DisplayModeController() = default;
50
51 void setHwComposer(HWComposer* composerPtr) { mComposerPtr = composerPtr; }
52 void setActiveModeListener(const ActiveModeListener& listener) {
53 mActiveModeListener = listener;
54 }
55
56 // TODO: b/241285876 - Remove once ownership is no longer shared with DisplayDevice.
Dominik Laskowski6e465152022-09-28 11:00:25 -040057 using RefreshRateSelectorPtr = std::shared_ptr<scheduler::RefreshRateSelector>;
58
Dominik Laskowski6e465152022-09-28 11:00:25 -040059 // Used by tests to inject an existing RefreshRateSelector.
Dominik Laskowski5c989f52024-04-11 13:57:14 -040060 // TODO: b/241285876 - Remove this.
61 void registerDisplay(PhysicalDisplayId, DisplaySnapshotRef, RefreshRateSelectorPtr)
62 EXCLUDES(mDisplayLock);
63
64 // The referenced DisplaySnapshot must outlive the registration.
65 void registerDisplay(DisplaySnapshotRef, DisplayModeId, scheduler::RefreshRateSelector::Config)
66 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
67 void unregisterDisplay(PhysicalDisplayId) REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
68
69 // Returns `nullptr` if the display is no longer registered (or never was).
70 RefreshRateSelectorPtr selectorPtrFor(PhysicalDisplayId) const EXCLUDES(mDisplayLock);
71
72 enum class DesiredModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch };
Manasi Navarefc2a4a72024-11-12 23:59:21 +000073 enum class ModeChangeResult { Changed, Rejected, Aborted };
Dominik Laskowski5c989f52024-04-11 13:57:14 -040074
75 DesiredModeAction setDesiredMode(PhysicalDisplayId, DisplayModeRequest&&)
76 EXCLUDES(mDisplayLock);
77
78 using DisplayModeRequestOpt = ftl::Optional<DisplayModeRequest>;
79
80 DisplayModeRequestOpt getDesiredMode(PhysicalDisplayId) const EXCLUDES(mDisplayLock);
81 void clearDesiredMode(PhysicalDisplayId) EXCLUDES(mDisplayLock);
82
83 DisplayModeRequestOpt getPendingMode(PhysicalDisplayId) const REQUIRES(kMainThreadContext)
84 EXCLUDES(mDisplayLock);
85 bool isModeSetPending(PhysicalDisplayId) const REQUIRES(kMainThreadContext)
86 EXCLUDES(mDisplayLock);
87
88 scheduler::FrameRateMode getActiveMode(PhysicalDisplayId) const EXCLUDES(mDisplayLock);
89
Manasi Navarefc2a4a72024-11-12 23:59:21 +000090 ModeChangeResult initiateModeChange(PhysicalDisplayId, DisplayModeRequest&&,
91 const hal::VsyncPeriodChangeConstraints&,
92 hal::VsyncPeriodChangeTimeline& outTimeline)
Dominik Laskowski5c989f52024-04-11 13:57:14 -040093 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
94
95 void finalizeModeChange(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
96 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
97
98 void setActiveMode(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
99 EXCLUDES(mDisplayLock);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400100
Dominik Laskowski43839672024-08-04 02:01:48 -0400101 void updateKernelIdleTimer(PhysicalDisplayId) REQUIRES(kMainThreadContext)
102 EXCLUDES(mDisplayLock);
103
104 struct KernelIdleTimerState {
105 std::optional<DisplayModeId> desiredModeIdOpt = std::nullopt;
106 bool isEnabled = false;
107 };
108
109 KernelIdleTimerState getKernelIdleTimerState(PhysicalDisplayId) const
110 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
111
Dominik Laskowski6e465152022-09-28 11:00:25 -0400112private:
113 struct Display {
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400114 template <size_t N>
115 std::string concatId(const char (&)[N]) const;
Dominik Laskowski6e465152022-09-28 11:00:25 -0400116
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400117 Display(DisplaySnapshotRef, RefreshRateSelectorPtr);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400118 Display(DisplaySnapshotRef snapshot, DisplayModes modes, DisplayModeId activeModeId,
119 scheduler::RefreshRateSelector::Config config)
120 : Display(snapshot,
121 std::make_shared<scheduler::RefreshRateSelector>(std::move(modes),
122 activeModeId, config)) {}
Dominik Laskowski6e465152022-09-28 11:00:25 -0400123 const DisplaySnapshotRef snapshot;
124 const RefreshRateSelectorPtr selectorPtr;
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400125
126 const std::string pendingModeFpsTrace;
127 const std::string activeModeFpsTrace;
128 const std::string renderRateFpsTrace;
129
130 std::mutex desiredModeLock;
131 DisplayModeRequestOpt desiredModeOpt GUARDED_BY(desiredModeLock);
132 TracedOrdinal<bool> hasDesiredModeTrace GUARDED_BY(desiredModeLock);
133
134 DisplayModeRequestOpt pendingModeOpt GUARDED_BY(kMainThreadContext);
135 bool isModeSetPending GUARDED_BY(kMainThreadContext) = false;
Dominik Laskowski43839672024-08-04 02:01:48 -0400136
137 bool isKernelIdleTimerEnabled GUARDED_BY(kMainThreadContext) = false;
Dominik Laskowski6e465152022-09-28 11:00:25 -0400138 };
139
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400140 using DisplayPtr = std::unique_ptr<Display>;
141
142 void setActiveModeLocked(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
143 REQUIRES(mDisplayLock);
144
Dominik Laskowski43839672024-08-04 02:01:48 -0400145 using KernelIdleTimerController = scheduler::RefreshRateSelector::KernelIdleTimerController;
146 void updateKernelIdleTimer(PhysicalDisplayId, std::chrono::milliseconds timeout,
147 KernelIdleTimerController) REQUIRES(mDisplayLock);
148
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400149 // Set once when initializing the DisplayModeController, which the HWComposer must outlive.
150 HWComposer* mComposerPtr = nullptr;
151
152 ActiveModeListener mActiveModeListener;
153
154 mutable std::mutex mDisplayLock;
155 ui::PhysicalDisplayMap<PhysicalDisplayId, DisplayPtr> mDisplays GUARDED_BY(mDisplayLock);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400156};
157
158} // namespace android::display