• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_realtime_refresh_rate_manager.h"
17 
18 #include <chrono>
19 #include <condition_variable>
20 #include <mutex>
21 
22 #include "hgm_core.h"
23 #include "rs_trace.h"
24 #include "pipeline/main_thread/rs_main_thread.h"
25 
26 namespace OHOS::Rosen {
Instance()27 RSRealtimeRefreshRateManager& RSRealtimeRefreshRateManager::Instance()
28 {
29     static RSRealtimeRefreshRateManager instance;
30     return instance;
31 }
32 
SetShowRefreshRateEnabled(bool enabled,int32_t type)33 void RSRealtimeRefreshRateManager::SetShowRefreshRateEnabled(bool enabled, int32_t type)
34 {
35     RS_LOGD("SetShowRefreshRateEnabled: enabled[%{public}d] type[%{public}d]", enabled, type);
36     std::unique_lock<std::mutex> threadLock(threadMutex_);
37     auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
38     if (frameRateMgr == nullptr ||
39         type <= static_cast<int32_t>(RealtimeRefreshRateType::START) ||
40         type >= static_cast<int32_t>(RealtimeRefreshRateType::END)) {
41         return;
42     }
43 
44     RealtimeRefreshRateType enumType = static_cast<RealtimeRefreshRateType>(type);
45     if (enumType == RealtimeRefreshRateType::SHOW) {
46         if (showEnabled_ == enabled) {
47             return;
48         }
49         showEnabled_ = enabled;
50     } else if (enumType == RealtimeRefreshRateType::COLLECT) {
51         if (collectEnabled_ == enabled) {
52             return;
53         }
54         collectEnabled_ = enabled;
55     } else {
56         return;
57     }
58 
59     StatisticsRefreshRateDataLocked(frameRateMgr);
60 }
61 
StatisticsRefreshRateDataLocked(std::shared_ptr<HgmFrameRateManager> frameRateMgr)62 void RSRealtimeRefreshRateManager::StatisticsRefreshRateDataLocked(std::shared_ptr<HgmFrameRateManager> frameRateMgr)
63 {
64     if (!showEnabled_ && !collectEnabled_) {
65         HgmTaskHandleThread::Instance().RemoveEvent(EVENT_ID);
66         isCollectRefreshRateTaskRunning_ = false;
67         std::unique_lock<std::mutex> lock(showRealtimeFrameMutex_);
68         currRealtimeRefreshRateMap_.clear();
69         realtimeFrameCountMap_.clear();
70         return;
71     }
72 
73     if (isCollectRefreshRateTaskRunning_) {
74         return;
75     }
76 
77     startTime_ = std::chrono::steady_clock::now();
78     showRefreshRateTask_ = [this, frameRateMgr] () {
79         std::unique_lock<std::mutex> lock(showRealtimeFrameMutex_);
80         auto diff = std::chrono::duration_cast<std::chrono::nanoseconds>(
81             std::chrono::steady_clock::now() - startTime_);
82         for (auto [screenId, frameCount]: realtimeFrameCountMap_) {
83             uint32_t fps = std::round(frameCount * static_cast<float>(NS_PER_S) / diff.count());
84             fps = fps <= IDLE_FPS_THRESHOLD ? 1u : fps;
85             if (auto iter = currRealtimeRefreshRateMap_.find(screenId);
86                 iter == currRealtimeRefreshRateMap_.end() || iter->second != fps) {
87                 currRealtimeRefreshRateMap_[screenId] = fps;
88                 isRealtimeRefreshRateChange_ = true;
89             }
90         }
91         auto refreshRate = HgmCore::Instance().GetScreenCurrentRefreshRate(frameRateMgr->GetCurScreenId());
92         if (isRealtimeRefreshRateChange_|| lastRefreshRate_ != refreshRate) {
93             lastRefreshRate_ = refreshRate;
94             isRealtimeRefreshRateChange_ = false;
95             if (showEnabled_) {
96                 RSMainThread::Instance()->SetDirtyFlag();
97                 RSMainThread::Instance()->RequestNextVSync();
98             }
99         }
100         startTime_ = std::chrono::steady_clock::now();
101         realtimeFrameCountMap_.clear();
102         HgmTaskHandleThread::Instance().PostEvent(EVENT_ID, showRefreshRateTask_, EVENT_INTERVAL);
103     };
104     isCollectRefreshRateTaskRunning_ = true;
105     HgmTaskHandleThread::Instance().PostEvent(EVENT_ID, showRefreshRateTask_, EVENT_INTERVAL);
106 }
107 
GetRealtimeRefreshRate(ScreenId screenId)108 uint32_t RSRealtimeRefreshRateManager::GetRealtimeRefreshRate(ScreenId screenId)
109 {
110     {
111         std::unique_lock<std::mutex> threadLock(threadMutex_);
112         if (!showEnabled_ && !collectEnabled_) {
113             return 0;
114         }
115     }
116     if (screenId == INVALID_SCREEN_ID) {
117         auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
118         if (frameRateMgr == nullptr) {
119             return DEFAULT_REALTIME_REFRESH_RATE;
120         }
121         screenId = frameRateMgr->GetCurScreenId();
122     }
123     std::unique_lock<std::mutex> lock(showRealtimeFrameMutex_);
124     if (auto iter = currRealtimeRefreshRateMap_.find(screenId); iter != currRealtimeRefreshRateMap_.end()) {
125         uint32_t currentRefreshRate = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(screenId);
126         if (iter->second > currentRefreshRate) {
127             return currentRefreshRate;
128         }
129         return iter->second;
130     }
131     return DEFAULT_REALTIME_REFRESH_RATE;
132 }
133 } // namespace OHOS::Rosen
134