blob: 9ec603d5f636e1cb579beb498202ef2924446d1c [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 };
73
74 DesiredModeAction setDesiredMode(PhysicalDisplayId, DisplayModeRequest&&)
75 EXCLUDES(mDisplayLock);
76
77 using DisplayModeRequestOpt = ftl::Optional<DisplayModeRequest>;
78
79 DisplayModeRequestOpt getDesiredMode(PhysicalDisplayId) const EXCLUDES(mDisplayLock);
80 void clearDesiredMode(PhysicalDisplayId) EXCLUDES(mDisplayLock);
81
82 DisplayModeRequestOpt getPendingMode(PhysicalDisplayId) const REQUIRES(kMainThreadContext)
83 EXCLUDES(mDisplayLock);
84 bool isModeSetPending(PhysicalDisplayId) const REQUIRES(kMainThreadContext)
85 EXCLUDES(mDisplayLock);
86
87 scheduler::FrameRateMode getActiveMode(PhysicalDisplayId) const EXCLUDES(mDisplayLock);
88
89 bool initiateModeChange(PhysicalDisplayId, DisplayModeRequest&&,
90 const hal::VsyncPeriodChangeConstraints&,
91 hal::VsyncPeriodChangeTimeline& outTimeline)
92 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
93
94 void finalizeModeChange(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
95 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
96
97 void setActiveMode(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
98 EXCLUDES(mDisplayLock);
Dominik Laskowski6e465152022-09-28 11:00:25 -040099
Dominik Laskowski43839672024-08-04 02:01:48 -0400100 void updateKernelIdleTimer(PhysicalDisplayId) REQUIRES(kMainThreadContext)
101 EXCLUDES(mDisplayLock);
102
103 struct KernelIdleTimerState {
104 std::optional<DisplayModeId> desiredModeIdOpt = std::nullopt;
105 bool isEnabled = false;
106 };
107
108 KernelIdleTimerState getKernelIdleTimerState(PhysicalDisplayId) const
109 REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
110
Dominik Laskowski6e465152022-09-28 11:00:25 -0400111private:
112 struct Display {
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400113 template <size_t N>
114 std::string concatId(const char (&)[N]) const;
Dominik Laskowski6e465152022-09-28 11:00:25 -0400115
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400116 Display(DisplaySnapshotRef, RefreshRateSelectorPtr);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400117 Display(DisplaySnapshotRef snapshot, DisplayModes modes, DisplayModeId activeModeId,
118 scheduler::RefreshRateSelector::Config config)
119 : Display(snapshot,
120 std::make_shared<scheduler::RefreshRateSelector>(std::move(modes),
121 activeModeId, config)) {}
Dominik Laskowski6e465152022-09-28 11:00:25 -0400122 const DisplaySnapshotRef snapshot;
123 const RefreshRateSelectorPtr selectorPtr;
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400124
125 const std::string pendingModeFpsTrace;
126 const std::string activeModeFpsTrace;
127 const std::string renderRateFpsTrace;
128
129 std::mutex desiredModeLock;
130 DisplayModeRequestOpt desiredModeOpt GUARDED_BY(desiredModeLock);
131 TracedOrdinal<bool> hasDesiredModeTrace GUARDED_BY(desiredModeLock);
132
133 DisplayModeRequestOpt pendingModeOpt GUARDED_BY(kMainThreadContext);
134 bool isModeSetPending GUARDED_BY(kMainThreadContext) = false;
Dominik Laskowski43839672024-08-04 02:01:48 -0400135
136 bool isKernelIdleTimerEnabled GUARDED_BY(kMainThreadContext) = false;
Dominik Laskowski6e465152022-09-28 11:00:25 -0400137 };
138
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400139 using DisplayPtr = std::unique_ptr<Display>;
140
141 void setActiveModeLocked(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
142 REQUIRES(mDisplayLock);
143
Dominik Laskowski43839672024-08-04 02:01:48 -0400144 using KernelIdleTimerController = scheduler::RefreshRateSelector::KernelIdleTimerController;
145 void updateKernelIdleTimer(PhysicalDisplayId, std::chrono::milliseconds timeout,
146 KernelIdleTimerController) REQUIRES(mDisplayLock);
147
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400148 // Set once when initializing the DisplayModeController, which the HWComposer must outlive.
149 HWComposer* mComposerPtr = nullptr;
150
151 ActiveModeListener mActiveModeListener;
152
153 mutable std::mutex mDisplayLock;
154 ui::PhysicalDisplayMap<PhysicalDisplayId, DisplayPtr> mDisplays GUARDED_BY(mDisplayLock);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400155};
156
157} // namespace android::display