xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2022 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "FrameRateOverrideMappings.h"
18*38e8c45fSAndroid Build Coastguard Worker #include <common/FlagManager.h>
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker namespace android::scheduler {
21*38e8c45fSAndroid Build Coastguard Worker using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
22*38e8c45fSAndroid Build Coastguard Worker 
getFrameRateOverrideForUid(uid_t uid,bool supportsFrameRateOverrideByContent) const23*38e8c45fSAndroid Build Coastguard Worker std::optional<Fps> FrameRateOverrideMappings::getFrameRateOverrideForUid(
24*38e8c45fSAndroid Build Coastguard Worker         uid_t uid, bool supportsFrameRateOverrideByContent) const {
25*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mFrameRateOverridesLock);
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker     {
28*38e8c45fSAndroid Build Coastguard Worker         const auto iter = mFrameRateOverridesFromBackdoor.find(uid);
29*38e8c45fSAndroid Build Coastguard Worker         if (iter != mFrameRateOverridesFromBackdoor.end()) {
30*38e8c45fSAndroid Build Coastguard Worker             return iter->second;
31*38e8c45fSAndroid Build Coastguard Worker         }
32*38e8c45fSAndroid Build Coastguard Worker     }
33*38e8c45fSAndroid Build Coastguard Worker 
34*38e8c45fSAndroid Build Coastguard Worker     if (!FlagManager::getInstance().game_default_frame_rate()) {
35*38e8c45fSAndroid Build Coastguard Worker         const auto iter = mFrameRateOverridesFromGameManager.find(uid);
36*38e8c45fSAndroid Build Coastguard Worker         if (iter != mFrameRateOverridesFromGameManager.end()) {
37*38e8c45fSAndroid Build Coastguard Worker             return iter->second;
38*38e8c45fSAndroid Build Coastguard Worker         }
39*38e8c45fSAndroid Build Coastguard Worker     }
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker     if (!supportsFrameRateOverrideByContent) {
42*38e8c45fSAndroid Build Coastguard Worker         return std::nullopt;
43*38e8c45fSAndroid Build Coastguard Worker     }
44*38e8c45fSAndroid Build Coastguard Worker 
45*38e8c45fSAndroid Build Coastguard Worker     {
46*38e8c45fSAndroid Build Coastguard Worker         const auto iter = mFrameRateOverridesByContent.find(uid);
47*38e8c45fSAndroid Build Coastguard Worker         if (iter != mFrameRateOverridesByContent.end()) {
48*38e8c45fSAndroid Build Coastguard Worker             return iter->second;
49*38e8c45fSAndroid Build Coastguard Worker         }
50*38e8c45fSAndroid Build Coastguard Worker     }
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker     return std::nullopt;
53*38e8c45fSAndroid Build Coastguard Worker }
54*38e8c45fSAndroid Build Coastguard Worker 
getAllFrameRateOverrides(bool supportsFrameRateOverrideByContent)55*38e8c45fSAndroid Build Coastguard Worker std::vector<FrameRateOverride> FrameRateOverrideMappings::getAllFrameRateOverrides(
56*38e8c45fSAndroid Build Coastguard Worker         bool supportsFrameRateOverrideByContent) {
57*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mFrameRateOverridesLock);
58*38e8c45fSAndroid Build Coastguard Worker 
59*38e8c45fSAndroid Build Coastguard Worker     std::vector<FrameRateOverride> overrides;
60*38e8c45fSAndroid Build Coastguard Worker     overrides.reserve(maxOverridesCount());
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [uid, frameRate] : mFrameRateOverridesFromBackdoor) {
63*38e8c45fSAndroid Build Coastguard Worker         overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
64*38e8c45fSAndroid Build Coastguard Worker     }
65*38e8c45fSAndroid Build Coastguard Worker 
66*38e8c45fSAndroid Build Coastguard Worker     if (!FlagManager::getInstance().game_default_frame_rate()) {
67*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [uid, frameRate] : mFrameRateOverridesFromGameManager) {
68*38e8c45fSAndroid Build Coastguard Worker             if (std::find_if(overrides.begin(), overrides.end(),
69*38e8c45fSAndroid Build Coastguard Worker                              [uid = uid](auto i) { return i.uid == uid; }) == overrides.end()) {
70*38e8c45fSAndroid Build Coastguard Worker                 overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
71*38e8c45fSAndroid Build Coastguard Worker             }
72*38e8c45fSAndroid Build Coastguard Worker         }
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker     if (!supportsFrameRateOverrideByContent) {
76*38e8c45fSAndroid Build Coastguard Worker         return overrides;
77*38e8c45fSAndroid Build Coastguard Worker     }
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [uid, frameRate] : mFrameRateOverridesByContent) {
80*38e8c45fSAndroid Build Coastguard Worker         if (std::find_if(overrides.begin(), overrides.end(),
81*38e8c45fSAndroid Build Coastguard Worker                          [uid = uid](auto i) { return i.uid == uid; }) == overrides.end()) {
82*38e8c45fSAndroid Build Coastguard Worker             overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
83*38e8c45fSAndroid Build Coastguard Worker         }
84*38e8c45fSAndroid Build Coastguard Worker     }
85*38e8c45fSAndroid Build Coastguard Worker 
86*38e8c45fSAndroid Build Coastguard Worker     return overrides;
87*38e8c45fSAndroid Build Coastguard Worker }
88*38e8c45fSAndroid Build Coastguard Worker 
dump(utils::Dumper & dumper) const89*38e8c45fSAndroid Build Coastguard Worker void FrameRateOverrideMappings::dump(utils::Dumper& dumper) const {
90*38e8c45fSAndroid Build Coastguard Worker     using namespace std::string_view_literals;
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mFrameRateOverridesLock);
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker     const bool hasOverrides = maxOverridesCount() > 0;
95*38e8c45fSAndroid Build Coastguard Worker     dumper.dump("FrameRateOverrides"sv, hasOverrides ? ""sv : "none"sv);
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     if (!hasOverrides) return;
98*38e8c45fSAndroid Build Coastguard Worker 
99*38e8c45fSAndroid Build Coastguard Worker     dump(dumper, "setFrameRate"sv, mFrameRateOverridesByContent);
100*38e8c45fSAndroid Build Coastguard Worker     if (!FlagManager::getInstance().game_default_frame_rate()) {
101*38e8c45fSAndroid Build Coastguard Worker         dump(dumper, "GameManager"sv, mFrameRateOverridesFromGameManager);
102*38e8c45fSAndroid Build Coastguard Worker     }
103*38e8c45fSAndroid Build Coastguard Worker     dump(dumper, "Backdoor"sv, mFrameRateOverridesFromBackdoor);
104*38e8c45fSAndroid Build Coastguard Worker }
105*38e8c45fSAndroid Build Coastguard Worker 
dump(utils::Dumper & dumper,std::string_view name,const UidToFrameRateOverride & overrides) const106*38e8c45fSAndroid Build Coastguard Worker void FrameRateOverrideMappings::dump(utils::Dumper& dumper, std::string_view name,
107*38e8c45fSAndroid Build Coastguard Worker                                      const UidToFrameRateOverride& overrides) const {
108*38e8c45fSAndroid Build Coastguard Worker     if (overrides.empty()) return;
109*38e8c45fSAndroid Build Coastguard Worker 
110*38e8c45fSAndroid Build Coastguard Worker     utils::Dumper::Indent indent(dumper);
111*38e8c45fSAndroid Build Coastguard Worker     dumper.dump(name);
112*38e8c45fSAndroid Build Coastguard Worker     {
113*38e8c45fSAndroid Build Coastguard Worker         utils::Dumper::Indent indent(dumper);
114*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [uid, frameRate] : overrides) {
115*38e8c45fSAndroid Build Coastguard Worker             using namespace std::string_view_literals;
116*38e8c45fSAndroid Build Coastguard Worker             dumper.dump("(uid, frameRate)"sv, uid, frameRate);
117*38e8c45fSAndroid Build Coastguard Worker         }
118*38e8c45fSAndroid Build Coastguard Worker     }
119*38e8c45fSAndroid Build Coastguard Worker }
120*38e8c45fSAndroid Build Coastguard Worker 
updateFrameRateOverridesByContent(const UidToFrameRateOverride & frameRateOverrides)121*38e8c45fSAndroid Build Coastguard Worker bool FrameRateOverrideMappings::updateFrameRateOverridesByContent(
122*38e8c45fSAndroid Build Coastguard Worker         const UidToFrameRateOverride& frameRateOverrides) {
123*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mFrameRateOverridesLock);
124*38e8c45fSAndroid Build Coastguard Worker     if (!std::equal(mFrameRateOverridesByContent.begin(), mFrameRateOverridesByContent.end(),
125*38e8c45fSAndroid Build Coastguard Worker                     frameRateOverrides.begin(), frameRateOverrides.end(),
126*38e8c45fSAndroid Build Coastguard Worker                     [](const auto& lhs, const auto& rhs) {
127*38e8c45fSAndroid Build Coastguard Worker                         return lhs.first == rhs.first && isApproxEqual(lhs.second, rhs.second);
128*38e8c45fSAndroid Build Coastguard Worker                     })) {
129*38e8c45fSAndroid Build Coastguard Worker         mFrameRateOverridesByContent = frameRateOverrides;
130*38e8c45fSAndroid Build Coastguard Worker         return true;
131*38e8c45fSAndroid Build Coastguard Worker     }
132*38e8c45fSAndroid Build Coastguard Worker     return false;
133*38e8c45fSAndroid Build Coastguard Worker }
134*38e8c45fSAndroid Build Coastguard Worker 
setGameModeRefreshRateForUid(FrameRateOverride frameRateOverride)135*38e8c45fSAndroid Build Coastguard Worker void FrameRateOverrideMappings::setGameModeRefreshRateForUid(FrameRateOverride frameRateOverride) {
136*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mFrameRateOverridesLock);
137*38e8c45fSAndroid Build Coastguard Worker     if (frameRateOverride.frameRateHz != 0.f) {
138*38e8c45fSAndroid Build Coastguard Worker         mFrameRateOverridesFromGameManager[frameRateOverride.uid] =
139*38e8c45fSAndroid Build Coastguard Worker                 Fps::fromValue(frameRateOverride.frameRateHz);
140*38e8c45fSAndroid Build Coastguard Worker     } else {
141*38e8c45fSAndroid Build Coastguard Worker         mFrameRateOverridesFromGameManager.erase(frameRateOverride.uid);
142*38e8c45fSAndroid Build Coastguard Worker     }
143*38e8c45fSAndroid Build Coastguard Worker }
144*38e8c45fSAndroid Build Coastguard Worker 
setPreferredRefreshRateForUid(FrameRateOverride frameRateOverride)145*38e8c45fSAndroid Build Coastguard Worker void FrameRateOverrideMappings::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverride) {
146*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard lock(mFrameRateOverridesLock);
147*38e8c45fSAndroid Build Coastguard Worker     if (frameRateOverride.frameRateHz != 0.f) {
148*38e8c45fSAndroid Build Coastguard Worker         mFrameRateOverridesFromBackdoor[frameRateOverride.uid] =
149*38e8c45fSAndroid Build Coastguard Worker                 Fps::fromValue(frameRateOverride.frameRateHz);
150*38e8c45fSAndroid Build Coastguard Worker     } else {
151*38e8c45fSAndroid Build Coastguard Worker         mFrameRateOverridesFromBackdoor.erase(frameRateOverride.uid);
152*38e8c45fSAndroid Build Coastguard Worker     }
153*38e8c45fSAndroid Build Coastguard Worker }
154*38e8c45fSAndroid Build Coastguard Worker } // namespace android::scheduler
155