1 /*
2 * Copyright (c) 2025 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 "feature/hyper_graphic_manager/hgm_context.h"
17
18 #include "common/rs_optional_trace.h"
19 #include "parameters.h"
20 #include "pipeline/hardware_thread/rs_realtime_refresh_rate_manager.h"
21 #include "pipeline/main_thread/rs_main_thread.h"
22
23 namespace OHOS {
24 namespace Rosen {
25
HgmContext()26 HgmContext::HgmContext()
27 {
28 rsFrameRateLinker_ = std::make_shared<RSRenderFrameRateLinker>(
29 [](const RSRenderFrameRateLinker& linker) { HgmCore::Instance().SetHgmTaskFlag(true); });
30 }
31
InitHgmTaskHandleThread(sptr<VSyncController> rsVSyncController,sptr<VSyncController> appVSyncController,sptr<VSyncGenerator> vsyncGenerator,sptr<VSyncDistributor> appVSyncDistributor)32 void HgmContext::InitHgmTaskHandleThread(
33 sptr<VSyncController> rsVSyncController, sptr<VSyncController> appVSyncController,
34 sptr<VSyncGenerator> vsyncGenerator, sptr<VSyncDistributor> appVSyncDistributor)
35 {
36 RS_LOGI("HgmTaskHandleThread init");
37 auto forceUpdateTask = [this](bool idleTimerExpired, bool forceUpdate) {
38 RSMainThread::Instance()->PostTask([this, idleTimerExpired, forceUpdate]() {
39 RS_TRACE_NAME_FMT("HgmContext::TimerExpiredCallback Run idleTimerExpiredFlag: %s forceUpdateFlag: %s",
40 idleTimerExpired ? "True" : "False", forceUpdate ? "True" : "False");
41 if (lastForceUpdateVsyncId_ != currVsyncId_) {
42 lastForceUpdateVsyncId_ = currVsyncId_;
43 RSMainThread::Instance()->SetForceUpdateUniRenderFlag(forceUpdate);
44 RSMainThread::Instance()->RequestNextVSync("ltpoForceUpdate");
45 }
46 });
47 };
48 HgmTaskHandleThread::Instance().PostSyncTask([
49 forceUpdateTask, rsVSyncController,
50 appVSyncController, vsyncGenerator, appVSyncDistributor]() {
51 auto frameRateMgr = OHOS::Rosen::HgmCore::Instance().GetFrameRateMgr();
52 if (frameRateMgr == nullptr) {
53 return;
54 }
55 frameRateMgr->SetForceUpdateCallback(forceUpdateTask);
56 frameRateMgr->Init(rsVSyncController, appVSyncController, vsyncGenerator, appVSyncDistributor);
57 });
58 }
59
FrameRateGetFunc(const RSPropertyUnit unit,float velocity,int32_t area,int32_t length)60 int32_t HgmContext::FrameRateGetFunc(
61 const RSPropertyUnit unit, float velocity, int32_t area, int32_t length)
62 {
63 auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
64 if (frameRateMgr != nullptr) {
65 return frameRateMgr->GetExpectedFrameRate(unit, velocity, area, length);
66 }
67 return 0;
68 }
69
ProcessHgmFrameRate(uint64_t timestamp,sptr<VSyncDistributor> rsVSyncDistributor,uint64_t vsyncId)70 void HgmContext::ProcessHgmFrameRate(
71 uint64_t timestamp, sptr<VSyncDistributor> rsVSyncDistributor, uint64_t vsyncId)
72 {
73 currVsyncId_ = vsyncId;
74 int changed = 0;
75 if (bool enable = RSSystemParameters::GetShowRefreshRateEnabled(&changed); changed != 0) {
76 RSRealtimeRefreshRateManager::Instance().SetShowRefreshRateEnabled(enable, 1);
77 }
78 bool isUiDvsyncOn = rsVSyncDistributor != nullptr ? rsVSyncDistributor->IsUiDvsyncOn() : false;
79 auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
80 if (frameRateMgr == nullptr || rsVSyncDistributor == nullptr) {
81 return;
82 }
83
84 static std::once_flag initUIFwkTableFlag;
85 std::call_once(initUIFwkTableFlag, [this]() {
86 if (auto config = HgmCore::Instance().GetPolicyConfigData(); config != nullptr) {
87 RSMainThread::Instance()->GetContext().SetUiFrameworkTypeTable(config->appBufferList_);
88 }
89 });
90
91 // Check and processing refresh rate task.
92 frameRateMgr->ProcessPendingRefreshRate(
93 timestamp, vsyncId, rsVSyncDistributor->GetRefreshRate(), isUiDvsyncOn);
94 if (rsFrameRateLinker_ != nullptr) {
95 auto rsCurrRange = rsCurrRange_;
96 rsCurrRange.type_ = RS_ANIMATION_FRAME_RATE_TYPE;
97 HgmEnergyConsumptionPolicy::Instance().GetAnimationIdleFps(rsCurrRange);
98 rsFrameRateLinker_->SetExpectedRange(rsCurrRange);
99 RS_TRACE_NAME_FMT("rsCurrRange = (%d, %d, %d)", rsCurrRange.min_, rsCurrRange.max_, rsCurrRange.preferred_);
100 }
101 rsCurrRange_.IsValid() ? frameRateMgr->GetRsFrameRateTimer().Start() : frameRateMgr->GetRsFrameRateTimer().Stop();
102
103 bool needRefresh = frameRateMgr->UpdateUIFrameworkDirtyNodes(
104 RSMainThread::Instance()->GetContext().GetUiFrameworkDirtyNodes(), timestamp);
105 bool setHgmTaskFlag = HgmCore::Instance().SetHgmTaskFlag(false);
106 auto& rsVsyncRateReduceManager = RSMainThread::Instance()->GetRSVsyncRateReduceManager();
107 bool vrateStatusChange = rsVsyncRateReduceManager.SetVSyncRatesChangeStatus(false);
108 bool isVideoCallVsyncChange = HgmEnergyConsumptionPolicy::Instance().GetVideoCallVsyncChange();
109 if (!vrateStatusChange && !setHgmTaskFlag && !needRefresh && !isVideoCallVsyncChange &&
110 HgmCore::Instance().GetPendingScreenRefreshRate() == frameRateMgr->GetCurrRefreshRate()) {
111 return;
112 }
113 HgmTaskHandleThread::Instance().PostTask([timestamp, rsFrameRateLinker = rsFrameRateLinker_,
114 appFrameRateLinkers = RSMainThread::Instance()->GetContext().GetFrameRateLinkerMap().Get(),
115 linkers = rsVsyncRateReduceManager.GetVrateMap()]() mutable {
116 RS_TRACE_NAME("ProcessHgmFrameRate");
117 if (auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr(); frameRateMgr != nullptr) {
118 frameRateMgr->UniProcessDataForLtpo(timestamp, rsFrameRateLinker, appFrameRateLinkers, linkers);
119 }
120 });
121 }
122 } // namespace Rosen
123 } // namespace OHOS