diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 7cb8cb19d3be67c910ceead891b960d58eee61ca..ee207f6acc1e59daf2b80017521a2e7e4e6311ac 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -885,6 +885,12 @@ public: * @return vsync period. */ virtual int64_t GetVSyncPeriod() { return 0; } + /** + * @brief flush frame rate of linker. + * + * @param rate frame rate. + */ + virtual void FlushFrameRate(uint32_t rate) {} /** * @brief Update Configuration. * diff --git a/wm/include/vsync_station.h b/wm/include/vsync_station.h index 35807103d6ecd4b88ce0f7618c8f21b392531eb5..28a5ee965aec6063bfc97ae59a4dc849c11eee80 100644 --- a/wm/include/vsync_station.h +++ b/wm/include/vsync_station.h @@ -31,6 +31,7 @@ namespace OHOS { namespace Rosen { +class RSFrameRateLinker; class VsyncStation { WM_DECLARE_SINGLE_INSTANCE_BASE(VsyncStation); public: @@ -41,6 +42,8 @@ public: } void RequestVsync(const std::shared_ptr& vsyncCallback); int64_t GetVSyncPeriod(); + void FlushFrameRate(uint32_t rate); + void SetFrameRateLinkerEnable(bool enabled); void RemoveCallback(); void SetIsMainHandlerAvailable(bool available) { @@ -66,6 +69,7 @@ private: bool destroyed_ = false; const std::string VSYNC_THREAD_ID = "VsyncThread"; std::shared_ptr receiver_ = nullptr; + std::shared_ptr frameRateLinker_; std::unordered_set> vsyncCallbacks_; VSyncReceiver::FrameCallback frameCallback_ = { .userData_ = this, diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index 64107dc4d546f04ad36629d08bcea76008aab902..3320eb73fd9d554679c030cb9e0edf1eb77b1a20 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -87,6 +87,7 @@ public: WMError SetAPPWindowIcon(const std::shared_ptr& icon) override; void RequestVsync(const std::shared_ptr& vsyncCallback) override; int64_t GetVSyncPeriod() override; + void FlushFrameRate(uint32_t rate) override; // inherits from session stage WSError SetActive(bool active) override; WSError UpdateRect(const WSRect& rect, SizeChangeReason reason, diff --git a/wm/src/vsync_station.cpp b/wm/src/vsync_station.cpp index 0ec7c8c040bbafe9a36d00c092cdbe05d3934735..d0b7aa8f2f56090580c8be7a088dae6078629301 100644 --- a/wm/src/vsync_station.cpp +++ b/wm/src/vsync_station.cpp @@ -17,6 +17,7 @@ #include "window_frame_trace.h" #include "transaction/rs_interfaces.h" +#include "ui/rs_frame_rate_linker.h" #include "window_manager_hilog.h" using namespace FRAME_TRACE; @@ -66,6 +67,29 @@ int64_t VsyncStation::GetVSyncPeriod() return period; } +void VsyncStation::FlushFrameRate(uint32_t rate) +{ + if (frameRateLinker_ && frameRateLinker_->IsEnable()) { + WLOGI("VsyncStation::FlushFrameRate %{public}d", rate); + FrameRateRange range = {0, RANGE_MAX_REFRESHRATE, rate}; + if (range.IsValid()) { + frameRateLinker_->UpdateFrameRateRange(range); + } + } +} + +void VsyncStation::SetFrameRateLinkerEnable(bool enabled) +{ + if (frameRateLinker_) { + if (!enabled) { + FrameRateRange range = {0, RANGE_MAX_REFRESHRATE, 0}; + WLOGI("VsyncStation::SetFrameRateLinkerEnable false"); + frameRateLinker_->UpdateFrameRateRangeImme(range); + } + frameRateLinker_->SetEnable(enabled); + } +} + void VsyncStation::Init() { if (!hasInitVsyncReceiver_ || !vsyncHandler_) { @@ -81,8 +105,10 @@ void VsyncStation::Init() } } auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance(); + frameRateLinker_ = OHOS::Rosen::RSFrameRateLinker::Create(); while (receiver_ == nullptr) { - receiver_ = rsClient.CreateVSyncReceiver("WM_" + std::to_string(::getpid()), vsyncHandler_); + receiver_ = rsClient.CreateVSyncReceiver("WM_" + std::to_string(::getpid()), frameRateLinker_->GetId(), + vsyncHandler_); } receiver_->Init(); hasInitVsyncReceiver_ = true; diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index 3e7226d7467e05693aaa3b49066741670bdeb658..3c3eb298412bfcba2ee39d61cc9342e6f4548ef4 100755 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -1035,6 +1035,7 @@ void WindowSessionImpl::NotifyAfterForeground(bool needNotifyListeners, bool nee if (needNotifyUiContent) { CALL_UI_CONTENT(Foreground); } + VsyncStation::GetInstance().SetFrameRateLinkerEnable(true); } void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent) @@ -1046,6 +1047,7 @@ void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool nee if (needNotifyUiContent) { CALL_UI_CONTENT(Background); } + VsyncStation::GetInstance().SetFrameRateLinkerEnable(false); } void WindowSessionImpl::NotifyAfterFocused() @@ -1546,6 +1548,12 @@ int64_t WindowSessionImpl::GetVSyncPeriod() return VsyncStation::GetInstance().GetVSyncPeriod(); } +void WindowSessionImpl::FlushFrameRate(uint32_t rate) +{ + std::lock_guard lock(mutex_); + VsyncStation::GetInstance().FlushFrameRate(rate); +} + WMError WindowSessionImpl::UpdateProperty(WSPropertyChangeAction action) { WLOGFD("UpdateProperty, action:%{public}u", action);