Description: AddFRCSceneInfo

Feature or Bugfix: Feature
Binary Source: No
Signed-off-by: zsw <zhangsongwei2@huawei.com>
This commit is contained in:
zzvscx 2023-11-17 15:12:36 +08:00
parent ab325b7809
commit 99482f5e45
19 changed files with 221 additions and 29 deletions

View File

@ -47,6 +47,8 @@ public:
virtual void RequestFrame();
virtual void FlushFrameRate(int32_t rate) {}
virtual void SetTaskExecutor(const RefPtr<TaskExecutor>& taskExecutor) {}
virtual void SetInstanceId(int32_t instanceId) {}

View File

@ -339,6 +339,10 @@ FrameNode::~FrameNode()
dragManager->UnRegisterDragStatusListener(GetId());
#endif // ENABLE_DRAG_FRAMEWORK
}
auto frameRateManager = pipeline->GetFrameRateManager();
if (frameRateManager) {
frameRateManager->RemoveNodeRate(GetId());
}
}
}
@ -2293,6 +2297,16 @@ std::vector<RefPtr<FrameNode>> FrameNode::GetNodesById(const std::unordered_set<
return nodes;
}
int32_t FrameNode::GetNodeExpectedRate()
{
if (sceneRateMap_.empty()) {
return 0;
}
auto iter = std::max_element(
sceneRateMap_.begin(), sceneRateMap_.end(), [](auto a, auto b) { return a.second < b.second; });
return iter->second;
}
void FrameNode::AddFRCSceneInfo(const std::string& scene, float speed, SceneStatus status)
{
if (SystemProperties::GetDebugEnabled()) {
@ -2301,12 +2315,50 @@ void FrameNode::AddFRCSceneInfo(const std::string& scene, float speed, SceneStat
scene.c_str(), speed, sceneStatusStrs[static_cast<int32_t>(status)].c_str());
}
if (status == SceneStatus::RUNNING) {
return;
auto renderContext = GetRenderContext();
CHECK_NULL_VOID(renderContext);
auto pipelineContext = GetContext();
CHECK_NULL_VOID(pipelineContext);
auto frameRateManager = pipelineContext->GetFrameRateManager();
CHECK_NULL_VOID(frameRateManager);
auto expectedRate = renderContext->CalcExpectedFrameRate(scene, speed);
auto nodeId = GetId();
auto iter = sceneRateMap_.find(scene);
switch (status) {
case SceneStatus::START: {
if (iter == sceneRateMap_.end()) {
if (sceneRateMap_.empty()) {
frameRateManager->AddNodeRate(nodeId);
}
sceneRateMap_.emplace(scene, expectedRate);
frameRateManager->UpdateNodeRate(nodeId, GetNodeExpectedRate());
}
return;
}
case SceneStatus::RUNNING: {
if (iter != sceneRateMap_.end() && iter->second != expectedRate) {
iter->second = expectedRate;
auto nodeExpectedRate = GetNodeExpectedRate();
frameRateManager->UpdateNodeRate(nodeId, nodeExpectedRate);
}
return;
}
case SceneStatus::END: {
if (iter != sceneRateMap_.end()) {
sceneRateMap_.erase(iter);
if (sceneRateMap_.empty()) {
frameRateManager->RemoveNodeRate(nodeId);
} else {
auto nodeExpectedRate = GetNodeExpectedRate();
frameRateManager->UpdateNodeRate(nodeId, nodeExpectedRate);
}
}
return;
}
default:
return;
}
auto context = GetRenderContext();
CHECK_NULL_VOID(context);
context->AddFRCSceneInfo(scene, speed);
}
void FrameNode::CheckSecurityComponentStatus(std::vector<RectF>& rect)

View File

@ -672,6 +672,8 @@ private:
void UpdateParentAbsoluteOffset();
void AddFrameNodeSnapshot(bool isHit, int32_t parentId);
int32_t GetNodeExpectedRate();
// sort in ZIndex.
std::multiset<WeakPtr<FrameNode>, ZIndexComparator> frameChildren_;
RefPtr<GeometryNode> geometryNode_ = MakeRefPtr<GeometryNode>();
@ -734,6 +736,8 @@ private:
RefPtr<FrameNode> overlayNode_;
std::unordered_map<std::string, int32_t> sceneRateMap_;
friend class RosenRenderContext;
friend class RenderContext;
friend class Pattern;

View File

@ -18,6 +18,7 @@ build_component_ng("manager_ng") {
sources = [
"drag_drop/drag_drop_manager.cpp",
"drag_drop/drag_drop_proxy.cpp",
"frame_rate/frame_rate_manager.cpp",
"full_screen/full_screen_manager.cpp",
"safe_area/safe_area_manager.cpp",
"select_overlay/select_overlay_client.cpp",

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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 "frame_rate_manager.h"
namespace OHOS::Ace::NG {
bool FrameRateManager::IsRateChanged()
{
return isRateChanged_;
}
void FrameRateManager::SetIsRateChanged(bool isChanged)
{
isRateChanged_ = isChanged;
}
void FrameRateManager::AddNodeRate(int32_t nodeId, int32_t rate)
{
auto [iter, success] = nodeRateMap_.try_emplace(nodeId, rate);
if (success) {
isRateChanged_ = true;
}
}
void FrameRateManager::RemoveNodeRate(int32_t nodeId)
{
if (auto iter = nodeRateMap_.find(nodeId); iter != nodeRateMap_.end()) {
nodeRateMap_.erase(iter);
isRateChanged_ = true;
}
}
void FrameRateManager::UpdateNodeRate(int32_t nodeId, int32_t rate)
{
if (auto iter = nodeRateMap_.find(nodeId); iter != nodeRateMap_.end() && iter->second != rate) {
iter->second = rate;
isRateChanged_ = true;
}
}
int32_t FrameRateManager::GetExpectedRate()
{
int32_t expectedRate = 0;
if (!nodeRateMap_.empty()) {
auto maxIter = std::max_element(
nodeRateMap_.begin(), nodeRateMap_.end(), [](auto a, auto b) { return a.second < b.second; });
expectedRate = maxIter->second;
}
return expectedRate;
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FRAME_RATE_FRAME_RATE_MANAGER_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FRAME_RATE_FRAME_RATE_MANAGER_H
#include <unordered_map>
#include <algorithm>
#include "base/memory/ace_type.h"
#include "base/utils/noncopyable.h"
namespace OHOS::Ace::NG {
class FrameRateManager : public virtual AceType {
DECLARE_ACE_TYPE(FrameRateManager, AceType);
public:
FrameRateManager() = default;
~FrameRateManager() override = default;
bool IsRateChanged();
void SetIsRateChanged(bool isChanged);
void AddNodeRate(int32_t nodeId, int32_t rate = 0);
void RemoveNodeRate(int32_t nodeId);
void UpdateNodeRate(int32_t nodeId, int32_t rate);
int32_t GetExpectedRate();
private:
std::unordered_map<int32_t, int32_t> nodeRateMap_;
bool isRateChanged_ = false;
ACE_DISALLOW_COPY_AND_MOVE(FrameRateManager);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FRAME_RATE_FRAME_RATE_MANAGER_H

View File

@ -3411,10 +3411,12 @@ void RosenRenderContext::SetFrameGravity(OHOS::Rosen::Gravity gravity)
rsNode_->SetFrameGravity(gravity);
}
void RosenRenderContext::AddFRCSceneInfo(const std::string& scene, float speed)
int32_t RosenRenderContext::CalcExpectedFrameRate(const std::string& scene, float speed)
{
CHECK_NULL_VOID(rsNode_);
rsNode_->AddFRCSceneInfo(scene, speed);
if (rsNode_ == nullptr) {
return 0;
}
return rsNode_->CalcExpectedFrameRate(scene, speed);
}
void RosenRenderContext::ClearDrawCommands()

View File

@ -284,7 +284,7 @@ public:
void SetUsingContentRectForRenderFrame(bool value) override;
void SetFrameGravity(OHOS::Rosen::Gravity gravity) override;
void AddFRCSceneInfo(const std::string& scene, float speed) override;
int32_t CalcExpectedFrameRate(const std::string& scene, float speed) override;
private:
void OnBackgroundImageUpdate(const ImageSourceInfo& src) override;

View File

@ -87,6 +87,14 @@ void RosenWindow::Init()
}
}
void RosenWindow::FlushFrameRate(int32_t rate)
{
if (!rsWindow_ || rate < 0) {
return;
}
rsWindow_->FlushFrameRate(rate);
}
void RosenWindow::RequestFrame()
{
CHECK_NULL_VOID(onShow_);

View File

@ -53,6 +53,8 @@ public:
void SetRootFrameNode(const RefPtr<NG::FrameNode>& root) override;
void FlushFrameRate(int32_t rate) override;
std::shared_ptr<Rosen::RSUIDirector> GetRSUIDirector() const override
{
return rsUIDirector_;

View File

@ -488,7 +488,10 @@ public:
}
virtual void SetFrameGravity(OHOS::Rosen::Gravity gravity) {}
virtual void AddFRCSceneInfo(const std::string& scene, float speed) {}
virtual int32_t CalcExpectedFrameRate(const std::string& scene, float speed)
{
return 0;
}
protected:
RenderContext() = default;

View File

@ -416,6 +416,7 @@ void PipelineContext::FlushVsync(uint64_t nanoTimestamp, uint32_t frameCount)
if (hasAnimation) {
RequestFrame();
}
FlushFrameRate();
FlushMessages();
if (dragCleanTask_) {
dragCleanTask_();
@ -581,6 +582,16 @@ void PipelineContext::FlushPipelineWithoutAnimation()
FlushFocus();
}
void PipelineContext::FlushFrameRate()
{
if (frameRateManager_->IsRateChanged()) {
auto rate = frameRateManager_->GetExpectedRate();
ACE_SCOPED_TRACE("FlushFrameRate Expected frameRate = %d", rate);
window_->FlushFrameRate(rate);
frameRateManager_->SetIsRateChanged(false);
}
}
void PipelineContext::FlushBuild()
{
isRebuildFinished_ = false;

View File

@ -31,6 +31,7 @@
#include "core/components_ng/base/frame_node.h"
#include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
#include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
#include "core/components_ng/manager/frame_rate/frame_rate_manager.h"
#include "core/components_ng/manager/full_screen/full_screen_manager.h"
#include "core/components_ng/manager/safe_area/safe_area_manager.h"
#include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
@ -249,6 +250,11 @@ public:
const RefPtr<DragDropManager>& GetDragDropManager();
const RefPtr<FrameRateManager>& GetFrameRateManager()
{
return frameRateManager_;
}
void FlushBuild() override;
void FlushPipelineImmediately() override;
@ -490,6 +496,8 @@ private:
// only used for static form.
void UpdateFormLinkInfos();
void FlushFrameRate();
template<typename T>
struct NodeCompare {
@ -559,6 +567,7 @@ private:
RefPtr<DragDropManager> dragDropManager_;
RefPtr<SharedOverlayManager> sharedTransitionManager_;
RefPtr<SafeAreaManager> safeAreaManager_ = MakeRefPtr<SafeAreaManager>();
RefPtr<FrameRateManager> frameRateManager_ = MakeRefPtr<FrameRateManager>();
#ifdef WINDOW_SCENE_SUPPORTED
RefPtr<UIExtensionManager> uiExtensionManager_ = MakeRefPtr<UIExtensionManager>();
#endif

View File

@ -34,7 +34,6 @@ public:
MOCK_METHOD1(AnimateHoverEffectScale, void(bool));
MOCK_METHOD1(SetVisible, void(bool));
MOCK_METHOD0(GetLocalTransformMatrix, Matrix4());
MOCK_METHOD2(AddFRCSceneInfo, void(const std::string&, float));
void ResetBlendBgColor() override
{

View File

@ -212,6 +212,7 @@ ohos_source_set("ace_components_manager") {
sources = [
"$ace_root/frameworks/core/components_ng/manager/drag_drop/drag_drop_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/drag_drop/drag_drop_proxy.cpp",
"$ace_root/frameworks/core/components_ng/manager/frame_rate/frame_rate_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/full_screen/full_screen_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp",

View File

@ -56,6 +56,7 @@ ohos_unittest("ace_engine_special_test") {
"$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp",
"$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp",
"$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp",
"$ace_root/frameworks/core/components_ng/manager/frame_rate/frame_rate_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp",
"$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp",
"$ace_root/frameworks/core/components_ng/pattern/flex/flex_layout_algorithm.cpp",

View File

@ -6216,18 +6216,4 @@ HWTEST_F(ListTestNg, EdgeEffectOption004, TestSize.Level1)
EXPECT_TRUE(pattern_->GetAlwaysEnabled());
EXPECT_TRUE(pattern_->scrollable_);
}
/**
* @tc.name: FRCCallback001
* @tc.desc: Test FRC callback
* @tc.type: FUNC
*/
HWTEST_F(ListTestNg, FRCCallback001, TestSize.Level1)
{
Create([](ListModelNG model) {});
auto renderContext = AceType::MakeRefPtr<MockRenderContext>();
frameNode_->renderContext_ = renderContext;
EXPECT_CALL(*renderContext, AddFRCSceneInfo(_, _)).Times(1);
pattern_->NotifyFRCSceneInfo(0.0f, SceneStatus::START);
}
} // namespace OHOS::Ace::NG

View File

@ -52,7 +52,6 @@ constexpr float PERCENT = 0.01; // Percent
constexpr Dimension TRIGGER_REFRESH_DISTANCE = 64.0_vp;
constexpr float DEFAULT_SPEED = 10.0f;
constexpr float DEFAULT_OFFSET = 20.0f;
constexpr int32_t CALL_TIMES = 2;
} // namespace
class RefreshTestNg : public testing::Test, public TestNG {
public:
@ -845,9 +844,6 @@ HWTEST_F(RefreshTestNg, RefreshDragFrameRatio001, TestSize.Level1)
EXPECT_TRUE(!!frameNode);
auto refreshPattern = frameNode->GetPattern<RefreshPattern>();
EXPECT_TRUE(!!refreshPattern);
auto renderContext = AceType::DynamicCast<MockRenderContext>(frameNode->GetRenderContext());
EXPECT_TRUE(!!renderContext);
EXPECT_CALL(*renderContext, AddFRCSceneInfo(_, _)).Times(CALL_TIMES);
refreshPattern->HandleDragStart(true, DEFAULT_SPEED);
refreshPattern->HandleDragUpdate(DEFAULT_OFFSET, DEFAULT_SPEED);
refreshPattern->HandleDragUpdate(DEFAULT_OFFSET, DEFAULT_SPEED);

View File

@ -116,6 +116,7 @@ ohos_unittest("pipeline_context_test_ng") {
"$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp",
"$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp",
"$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp",
"$ace_root/frameworks/core/components_ng/manager/frame_rate/frame_rate_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp",
"$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp",
"$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp",