1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rs_frame_rate_policy.h"
17 
18 #include "modifier/rs_modifier_type.h"
19 #include "platform/common/rs_log.h"
20 #include "rs_trace.h"
21 #include "transaction/rs_interfaces.h"
22 #include "ui/rs_ui_director.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 constexpr float INCH_2_MM = 25.4f;
28 }
29 
GetInstance()30 RSFrameRatePolicy* RSFrameRatePolicy::GetInstance()
31 {
32     static RSFrameRatePolicy instance;
33     return &instance;
34 }
35 
~RSFrameRatePolicy()36 RSFrameRatePolicy::~RSFrameRatePolicy()
37 {
38 }
39 
RegisterHgmConfigChangeCallback()40 void RSFrameRatePolicy::RegisterHgmConfigChangeCallback()
41 {
42     auto callback =
43         [this](std::shared_ptr<RSHgmConfigData> data) { this->RSFrameRatePolicy::HgmConfigChangeCallback(data); };
44     if (RSInterfaces::GetInstance().RegisterHgmConfigChangeCallback(callback) != NO_ERROR) {
45         ROSEN_LOGE("RegisterHgmConfigChangeCallback failed");
46     }
47 }
48 
HgmConfigChangeCallback(std::shared_ptr<RSHgmConfigData> configData)49 void RSFrameRatePolicy::HgmConfigChangeCallback(std::shared_ptr<RSHgmConfigData> configData)
50 {
51     if (configData == nullptr) {
52         ROSEN_LOGE("RSFrameRatePolicy configData is null");
53         return;
54     }
55 
56     auto data = configData->GetConfigData();
57     if (data.empty()) {
58         return;
59     }
60     {
61         std::lock_guard<std::mutex> lock(mutex_);
62         ppi_ = configData->GetPpi();
63         xDpi_ = configData->GetXDpi();
64         yDpi_ = configData->GetYDpi();
65         for (auto item : data) {
66             if (item.animType.empty() || item.animName.empty()) {
67                 return;
68             }
69             animAttributes_[item.animType][item.animName] = {item.minSpeed, item.maxSpeed, item.preferredFps};
70             ROSEN_LOGD("RSFrameRatePolicy: config item type = %{public}s, name = %{public}s, "\
71                 "minSpeed = %{public}d, maxSpeed = %{public}d, preferredFps = %{public}d",
72                 item.animType.c_str(), item.animName.c_str(), static_cast<int>(item.minSpeed),
73                 static_cast<int>(item.maxSpeed), static_cast<int>(item.preferredFps));
74         }
75     }
76 }
77 
HgmRefreshRateModeChangeCallback(int32_t refreshRateMode)78 void RSFrameRatePolicy::HgmRefreshRateModeChangeCallback(int32_t refreshRateMode)
79 {
80     RSUIDirector::PostFrameRateTask([this, refreshRateMode]() {
81         ROSEN_LOGD("HgmRefreshRateModeChangeCallback refreshRateMode: %{public}d", refreshRateMode);
82         currentRefreshRateModeName_ = refreshRateMode;
83     });
84 }
85 
GetRefreshRateModeName() const86 int32_t RSFrameRatePolicy::GetRefreshRateModeName() const
87 {
88     return currentRefreshRateModeName_;
89 }
90 
GetPreferredFps(const std::string & scene,float speed)91 int32_t RSFrameRatePolicy::GetPreferredFps(const std::string& scene, float speed)
92 {
93     std::lock_guard<std::mutex> lock(mutex_);
94     if (animAttributes_.count(scene) == 0 || ppi_ == 0) {
95         return 0;
96     }
97     float speedMM = speed / ppi_ * INCH_2_MM;
98     const auto& attributes = animAttributes_[scene];
99     auto iter = std::find_if(attributes.begin(), attributes.end(), [&speedMM](const auto& pair) {
100         return speedMM >= pair.second.minSpeed && (speedMM < pair.second.maxSpeed ||
101             pair.second.maxSpeed == -1);
102     });
103     if (iter != attributes.end()) {
104         RS_TRACE_NAME_FMT("GetPreferredFps: scene: %s, speed: %f, rate: %d",
105             scene.c_str(), speedMM, iter->second.preferredFps);
106         return iter->second.preferredFps;
107     }
108     return 0;
109 }
110 
GetExpectedFrameRate(const RSPropertyUnit unit,float velocity)111 int32_t RSFrameRatePolicy::GetExpectedFrameRate(const RSPropertyUnit unit, float velocity)
112 {
113     switch (unit) {
114         case RSPropertyUnit::PIXEL_POSITION:
115             return GetPreferredFps("translate", velocity);
116         case RSPropertyUnit::PIXEL_SIZE:
117         case RSPropertyUnit::RATIO_SCALE:
118             return GetPreferredFps("scale", velocity);
119         case RSPropertyUnit::ANGLE_ROTATION:
120             return GetPreferredFps("rotation", velocity);
121         default:
122             return 0;
123     }
124 }
125 } // namespace Rosen
126 } // namespace OHOS