blob: 82af61a032ecfb21cf5da84e1df7626c55981c63 [file] [log] [blame]
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "FrameRateOverrideMappings.h"
#include <common/FlagManager.h>
namespace android::scheduler {
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
std::optional<Fps> FrameRateOverrideMappings::getFrameRateOverrideForUid(
uid_t uid, bool supportsFrameRateOverrideByContent) const {
std::lock_guard lock(mFrameRateOverridesLock);
{
const auto iter = mFrameRateOverridesFromBackdoor.find(uid);
if (iter != mFrameRateOverridesFromBackdoor.end()) {
return iter->second;
}
}
if (!FlagManager::getInstance().game_default_frame_rate()) {
const auto iter = mFrameRateOverridesFromGameManager.find(uid);
if (iter != mFrameRateOverridesFromGameManager.end()) {
return iter->second;
}
}
if (!supportsFrameRateOverrideByContent) {
return std::nullopt;
}
{
const auto iter = mFrameRateOverridesByContent.find(uid);
if (iter != mFrameRateOverridesByContent.end()) {
return iter->second;
}
}
return std::nullopt;
}
std::vector<FrameRateOverride> FrameRateOverrideMappings::getAllFrameRateOverrides(
bool supportsFrameRateOverrideByContent) {
std::lock_guard lock(mFrameRateOverridesLock);
std::vector<FrameRateOverride> overrides;
overrides.reserve(maxOverridesCount());
for (const auto& [uid, frameRate] : mFrameRateOverridesFromBackdoor) {
overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
}
if (!FlagManager::getInstance().game_default_frame_rate()) {
for (const auto& [uid, frameRate] : mFrameRateOverridesFromGameManager) {
if (std::find_if(overrides.begin(), overrides.end(),
[uid = uid](auto i) { return i.uid == uid; }) == overrides.end()) {
overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
}
}
}
if (!supportsFrameRateOverrideByContent) {
return overrides;
}
for (const auto& [uid, frameRate] : mFrameRateOverridesByContent) {
if (std::find_if(overrides.begin(), overrides.end(),
[uid = uid](auto i) { return i.uid == uid; }) == overrides.end()) {
overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
}
}
return overrides;
}
void FrameRateOverrideMappings::dump(utils::Dumper& dumper) const {
using namespace std::string_view_literals;
std::lock_guard lock(mFrameRateOverridesLock);
const bool hasOverrides = maxOverridesCount() > 0;
dumper.dump("FrameRateOverrides"sv, hasOverrides ? ""sv : "none"sv);
if (!hasOverrides) return;
dump(dumper, "setFrameRate"sv, mFrameRateOverridesByContent);
if (!FlagManager::getInstance().game_default_frame_rate()) {
dump(dumper, "GameManager"sv, mFrameRateOverridesFromGameManager);
}
dump(dumper, "Backdoor"sv, mFrameRateOverridesFromBackdoor);
}
void FrameRateOverrideMappings::dump(utils::Dumper& dumper, std::string_view name,
const UidToFrameRateOverride& overrides) const {
if (overrides.empty()) return;
utils::Dumper::Indent indent(dumper);
dumper.dump(name);
{
utils::Dumper::Indent indent(dumper);
for (const auto& [uid, frameRate] : overrides) {
using namespace std::string_view_literals;
dumper.dump("(uid, frameRate)"sv, uid, frameRate);
}
}
}
bool FrameRateOverrideMappings::updateFrameRateOverridesByContent(
const UidToFrameRateOverride& frameRateOverrides) {
std::lock_guard lock(mFrameRateOverridesLock);
if (!std::equal(mFrameRateOverridesByContent.begin(), mFrameRateOverridesByContent.end(),
frameRateOverrides.begin(), frameRateOverrides.end(),
[](const auto& lhs, const auto& rhs) {
return lhs.first == rhs.first && isApproxEqual(lhs.second, rhs.second);
})) {
mFrameRateOverridesByContent = frameRateOverrides;
return true;
}
return false;
}
void FrameRateOverrideMappings::setGameModeRefreshRateForUid(FrameRateOverride frameRateOverride) {
std::lock_guard lock(mFrameRateOverridesLock);
if (frameRateOverride.frameRateHz != 0.f) {
mFrameRateOverridesFromGameManager[frameRateOverride.uid] =
Fps::fromValue(frameRateOverride.frameRateHz);
} else {
mFrameRateOverridesFromGameManager.erase(frameRateOverride.uid);
}
}
void FrameRateOverrideMappings::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverride) {
std::lock_guard lock(mFrameRateOverridesLock);
if (frameRateOverride.frameRateHz != 0.f) {
mFrameRateOverridesFromBackdoor[frameRateOverride.uid] =
Fps::fromValue(frameRateOverride.frameRateHz);
} else {
mFrameRateOverridesFromBackdoor.erase(frameRateOverride.uid);
}
}
} // namespace android::scheduler