From decb79a3e2203fe3b4d75c82cb3902f022954460 Mon Sep 17 00:00:00 2001 From: r00878997 Date: Tue, 22 Jul 2025 15:21:35 +0800 Subject: [PATCH] fix AreaChange/IsFrameDisappear cache Signed-off-by: renjunkang --- .gitee/CODEOWNERS | 1 + .../core/components_ng/base/frame_node.cpp | 25 ++++++++++++------- .../core/pipeline_ng/pipeline_context.cpp | 7 ++++++ .../core/base/frame_node_test_ng_coverage.cpp | 2 +- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.gitee/CODEOWNERS b/.gitee/CODEOWNERS index 517ac80df0c..5ec30ef837c 100644 --- a/.gitee/CODEOWNERS +++ b/.gitee/CODEOWNERS @@ -3275,6 +3275,7 @@ test/unittest/core/render/ @arkuiframework test/unittest/core/rosen/ @arkuiframework test/unittest/core/svg/ @arkui_image test/unittest/core/syntax/ @arkuistatemgmt +test/unittest/core/base/frame_node_test_ng_coverage.cpp @arkui_architecture test/unittest/interfaces/ @arkuiframework test/unittest/interfaces/ui_input_event_test.cpp @arkuievent test/unittest/interfaces/ace_ui_input_event/ @arkuievent diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index 806ad81498b..d866951cbd2 100755 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -1335,6 +1335,8 @@ void FrameNode::OnAttachToMainTree(bool recursive) } renderContext_->OnNodeAppear(recursive); pattern_->OnAttachToMainTree(); + ClearCachedGlobalOffset(); + ClearCachedIsFrameDisappear(); if (isActive_ && SystemProperties::GetDeveloperModeOn()) { PaintDebugBoundary(SystemProperties::GetDebugBoundaryEnabled()); @@ -1773,6 +1775,9 @@ void FrameNode::TriggerOnAreaChangeCallback(uint64_t nanoTimestamp, int32_t area } eventHub_->HandleOnAreaChange( lastFrameRect_, lastParentOffsetToWindow_, currFrameRect, currParentOffsetToWindow); + } else { + //if in this branch, next time cache is not trusted + ClearCachedGlobalOffset(); } pattern_->OnAreaChangedInner(); } @@ -1908,7 +1913,8 @@ bool FrameNode::IsFrameDisappear(uint64_t timestamp, int32_t isVisibleChangeMinD } bool isFrameDisappear = !isOnShow || !isOnMainTree || !isSelfVisible; if (isFrameDisappear) { - cachedIsFrameDisappear_ = { timestamp, true }; + //if in this branch, next time cache is not trusted + ClearCachedIsFrameDisappear(); return true; } auto result = IsFrameAncestorDisappear(timestamp, isVisibleChangeMinDepth); @@ -1925,10 +1931,13 @@ bool FrameNode::IsFrameAncestorDisappear(uint64_t timestamp, int32_t isVisibleCh bool result = !curIsVisible || !curFrameIsActive; RefPtr parentUi = GetAncestorNodeOfFrame(false); if (!parentUi || result) { - cachedIsFrameDisappear_ = { timestamp, result }; + //if in this branch, next time cache is not trusted + ClearCachedIsFrameDisappear(); return result; } + // if this node have not calculate once, then it will calculate to root + isVisibleChangeMinDepth = cachedIsFrameDisappear_.first > 0 ? isVisibleChangeMinDepth : -1; // MinDepth < 0, it do not work // MinDepth >= 0, and this node have calculate once // MinDepth = 0, no change from last frame, use cache directly @@ -1942,8 +1951,6 @@ bool FrameNode::IsFrameAncestorDisappear(uint64_t timestamp, int32_t isVisibleCh return result; } - // if this node have not calculate once, then it will calculate to root - isVisibleChangeMinDepth = parentIsFrameDisappear.first > 0 ? isVisibleChangeMinDepth : -1; result = result || parentUi->IsFrameAncestorDisappear(timestamp, isVisibleChangeMinDepth); cachedIsFrameDisappear_ = { timestamp, result }; @@ -1960,6 +1967,7 @@ void FrameNode::TriggerVisibleAreaChangeCallback( auto hasInnerCallback = eventHub_->HasVisibleAreaCallback(false); auto hasUserCallback = eventHub_->HasVisibleAreaCallback(true); if (!hasInnerCallback && !hasUserCallback) { + ClearCachedIsFrameDisappear(); return; } auto& visibleAreaUserRatios = eventHub_->GetVisibleAreaRatios(true); @@ -1968,9 +1976,8 @@ void FrameNode::TriggerVisibleAreaChangeCallback( auto& visibleAreaInnerCallback = eventHub_->GetVisibleAreaCallback(false); if (forceDisappear || IsFrameDisappear(timestamp, isVisibleChangeMinDepth)) { if (IsDebugInspectorId()) { - TAG_LOGD(AceLogTag::ACE_UIEVENT, - "OnVisibleAreaChange Node(%{public}s/%{public}d) lastRatio(User:%{public}s/Inner:%{public}s) " - "forceDisappear:%{public}d frameDisappear:%{public}d ", + TAG_LOGD(AceLogTag::ACE_UIEVENT, "OnVisibleAreaChange Node(%{public}s/%{public}d) " + "lastRatio(User:%{public}s/Inner:%{public}s) forceDisappear:%{public}d frameDisappear:%{public}d ", tag_.c_str(), nodeId_, std::to_string(lastVisibleRatio_).c_str(), std::to_string(lastInnerVisibleRatio_).c_str(), forceDisappear, IsFrameDisappear(timestamp)); } @@ -5822,6 +5829,8 @@ OffsetF FrameNode::CalculateOffsetRelativeToWindow(uint64_t nanoTimestamp, bool } } + // if this node have not calculate once, then it will calculate to root + areaChangeMinDepth = cachedGlobalOffset_.first > 0 ? areaChangeMinDepth : -1; auto parent = GetAncestorNodeOfFrame(true); if (parent) { auto parentTimestampOffset = parent->GetCachedGlobalOffset(); @@ -5835,8 +5844,6 @@ OffsetF FrameNode::CalculateOffsetRelativeToWindow(uint64_t nanoTimestamp, bool currOffset = currOffset + parentTimestampOffset.second; SetCachedGlobalOffset({ nanoTimestamp, currOffset }); } else { - // if this node have not calculate once, then it will calculate to root - areaChangeMinDepth = parentTimestampOffset.first > 0 ? areaChangeMinDepth : -1; currOffset = currOffset + parent->CalculateOffsetRelativeToWindow( nanoTimestamp, logFlag, areaChangeMinDepth); SetCachedGlobalOffset({ nanoTimestamp, currOffset }); diff --git a/frameworks/core/pipeline_ng/pipeline_context.cpp b/frameworks/core/pipeline_ng/pipeline_context.cpp index 2bd08aaa7a2..f10154d0976 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.cpp +++ b/frameworks/core/pipeline_ng/pipeline_context.cpp @@ -4401,6 +4401,9 @@ bool PipelineContext::HasDifferentDirectionGesture() const void PipelineContext::AddVisibleAreaChangeNode(const int32_t nodeId) { onVisibleAreaChangeNodeIds_.emplace(nodeId); + auto frameNode = DynamicCast(ElementRegister::GetInstance()->GetUINodeById(nodeId)); + CHECK_NULL_VOID(frameNode); + frameNode->ClearCachedIsFrameDisappear(); } void PipelineContext::AddVisibleAreaChangeNode(const RefPtr& node, @@ -4412,6 +4415,7 @@ void PipelineContext::AddVisibleAreaChangeNode(const RefPtr& node, addInfo.callback = callback; addInfo.isCurrentVisible = false; onVisibleAreaChangeNodeIds_.emplace(node->GetId()); + node->ClearCachedIsFrameDisappear(); if (isUserCallback) { node->SetVisibleAreaUserCallback(ratios, addInfo); } else { @@ -4447,6 +4451,9 @@ void PipelineContext::AddOnAreaChangeNode(int32_t nodeId) { onAreaChangeNodeIds_.emplace(nodeId); isOnAreaChangeNodesCacheVaild_ = false; + auto frameNode = DynamicCast(ElementRegister::GetInstance()->GetUINodeById(nodeId)); + CHECK_NULL_VOID(frameNode); + frameNode->ClearCachedGlobalOffset(); } void PipelineContext::RemoveOnAreaChangeNode(int32_t nodeId) diff --git a/test/unittest/core/base/frame_node_test_ng_coverage.cpp b/test/unittest/core/base/frame_node_test_ng_coverage.cpp index 0e52d644076..2fc8e560cc3 100755 --- a/test/unittest/core/base/frame_node_test_ng_coverage.cpp +++ b/test/unittest/core/base/frame_node_test_ng_coverage.cpp @@ -1512,7 +1512,7 @@ HWTEST_F(FrameNodeTestNg, FrameNodeIsFrameDisappear05, TestSize.Level1) * @tc.expected: expect res is false */ parentLayoutProperty->propVisibility_ = VisibleType::INVISIBLE; - EXPECT_FALSE(frameNode2->IsFrameDisappear(TIMESTAMP_2, 2)); + EXPECT_FALSE(frameNode2->IsFrameDisappear(TIMESTAMP_2, 3)); /** * @tc.steps: step5. call the function IsFrameDisappear and no use TIMESTAMP_1 cache. -- Gitee