1 /* 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> 20 #include <mutex> 21 #include <string> 22 #include <utility> 23 24 #include <android-base/thread_annotations.h> 25 #include <ftl/function.h> 26 #include <ftl/optional.h> 27 #include <ui/DisplayId.h> 28 #include <ui/DisplayMap.h> 29 30 #include "Display/DisplayModeRequest.h" 31 #include "Display/DisplaySnapshotRef.h" 32 #include "DisplayHardware/DisplayMode.h" 33 #include "Scheduler/RefreshRateSelector.h" 34 #include "ThreadContext.h" 35 #include "TracedOrdinal.h" 36 37 namespace android { 38 class HWComposer; 39 } // namespace android 40 41 namespace android::display { 42 43 // Selects the DisplayMode of each physical display, in accordance with DisplayManager policy and 44 // certain heuristic signals. 45 class DisplayModeController { 46 public: 47 using ActiveModeListener = ftl::Function<void(PhysicalDisplayId, Fps vsyncRate, Fps renderFps)>; 48 49 DisplayModeController() = default; 50 setHwComposer(HWComposer * composerPtr)51 void setHwComposer(HWComposer* composerPtr) { mComposerPtr = composerPtr; } setActiveModeListener(const ActiveModeListener & listener)52 void setActiveModeListener(const ActiveModeListener& listener) { 53 mActiveModeListener = listener; 54 } 55 56 // TODO: b/241285876 - Remove once ownership is no longer shared with DisplayDevice. 57 using RefreshRateSelectorPtr = std::shared_ptr<scheduler::RefreshRateSelector>; 58 59 // Used by tests to inject an existing RefreshRateSelector. 60 // 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); 99 100 private: 101 struct Display { 102 template <size_t N> 103 std::string concatId(const char (&)[N]) const; 104 105 Display(DisplaySnapshotRef, RefreshRateSelectorPtr); DisplayDisplay106 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)) {} 111 const DisplaySnapshotRef snapshot; 112 const RefreshRateSelectorPtr selectorPtr; 113 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; 124 }; 125 126 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); 138 }; 139 140 } // namespace android::display 141