blob: 258b04b876ecfc746d5bbe7d4d064057c49d7cc7 [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
100private:
101 struct Display {
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400102 template <size_t N>
103 std::string concatId(const char (&)[N]) const;
Dominik Laskowski6e465152022-09-28 11:00:25 -0400104
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400105 Display(DisplaySnapshotRef, RefreshRateSelectorPtr);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400106 Display(DisplaySnapshotRef snapshot, DisplayModes modes, DisplayModeId activeModeId,
107 scheduler::RefreshRateSelector::Config config)
108 : Display(snapshot,
109 std::make_shared<scheduler::RefreshRateSelector>(std::move(modes),
110 activeModeId, config)) {}
Dominik Laskowski6e465152022-09-28 11:00:25 -0400111 const DisplaySnapshotRef snapshot;
112 const RefreshRateSelectorPtr selectorPtr;
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400113
114 const std::string pendingModeFpsTrace;
115 const std::string activeModeFpsTrace;
116 const std::string renderRateFpsTrace;
117
118 std::mutex desiredModeLock;
119 DisplayModeRequestOpt desiredModeOpt GUARDED_BY(desiredModeLock);
120 TracedOrdinal<bool> hasDesiredModeTrace GUARDED_BY(desiredModeLock);
121
122 DisplayModeRequestOpt pendingModeOpt GUARDED_BY(kMainThreadContext);
123 bool isModeSetPending GUARDED_BY(kMainThreadContext) = false;
Dominik Laskowski6e465152022-09-28 11:00:25 -0400124 };
125
Dominik Laskowski5c989f52024-04-11 13:57:14 -0400126 using DisplayPtr = std::unique_ptr<Display>;
127
128 void setActiveModeLocked(PhysicalDisplayId, DisplayModeId, Fps vsyncRate, Fps renderFps)
129 REQUIRES(mDisplayLock);
130
131 // Set once when initializing the DisplayModeController, which the HWComposer must outlive.
132 HWComposer* mComposerPtr = nullptr;
133
134 ActiveModeListener mActiveModeListener;
135
136 mutable std::mutex mDisplayLock;
137 ui::PhysicalDisplayMap<PhysicalDisplayId, DisplayPtr> mDisplays GUARDED_BY(mDisplayLock);
Dominik Laskowski6e465152022-09-28 11:00:25 -0400138};
139
140} // namespace android::display