diff --git a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp index a8e336351c0a7e17a502b199495813cb0f643a35..142560814e026f0332fecf63e80c6b98eace7556 100755 --- a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp +++ b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp @@ -45,6 +45,7 @@ #include "core/animation/native_curve_helper.h" #include "core/components/theme/app_theme.h" #include "core/components/theme/blur_style_theme.h" +#include "core/common/ace_engine.h" #include "core/common/resource/resource_parse_utils.h" #include "core/components_ng/pattern/overlay/accessibility_focus_paint_node_pattern.h" #include "core/components_ng/pattern/particle/particle_pattern.h" @@ -158,6 +159,23 @@ bool SetDrawNodeChangeCallback() return true; } +static void PropertyNodeChangeCallback() +{ + AceEngine::Get().NotifyContainers([](const RefPtr& container) { + auto pipeline = AceType::DynamicCast(container->GetPipelineContext()); + if (pipeline) { + pipeline->SetNeedCallbackAreaChange(true); + } + }); + Rosen::RSNode::SetNeedCallbackNodeChange(false); +} + +bool SetPropertyNodeChangeCallback() +{ + Rosen::RSNode::SetPropertyNodeChangeCallback(PropertyNodeChangeCallback); + return true; +} + Rosen::Gravity GetRosenGravity(RenderFit renderFit) { static const LinearEnumMapNode gravityMap[] = { @@ -275,6 +293,7 @@ void CancelModifierAnimation(std::shared_ptr& modifier) } // namespace bool RosenRenderContext::initDrawNodeChangeCallback_ = SetDrawNodeChangeCallback(); +bool RosenRenderContext::initPropertyNodeChangeCallback_ = SetPropertyNodeChangeCallback(); float RosenRenderContext::ConvertDimensionToScaleBySize(const Dimension& dimension, float size) { @@ -2390,6 +2409,10 @@ RectF RosenRenderContext::GetPaintRectWithTransform() CHECK_NULL_RETURN(rsNode_, rect); rect = GetPaintRectWithoutTransform(); + if (ShouldSkipAffineTransformation(rsNode_)) { + gRect = rect; + return rect; + } auto translate = rsNode_->GetStagingProperties().GetTranslate(); auto skew = rsNode_->GetStagingProperties().GetSkew(); auto perspective = rsNode_->GetStagingProperties().GetPersp(); @@ -2449,6 +2472,9 @@ std::pair RosenRenderContext::GetPaintRectWithTranslate() return std::make_pair(RectF(0, 0, -1, -1), error); } rect = GetPaintRectWithoutTransform(); + if (ShouldSkipAffineTransformation(rsNode_)) { + return std::make_pair(rect, error); + } auto translate = rsNode_->GetStagingProperties().GetTranslate(); rect.SetOffset(rect.GetOffset() + OffsetF(translate[0], translate[1])); return std::make_pair(rect, error); @@ -2457,6 +2483,9 @@ std::pair RosenRenderContext::GetPaintRectWithTranslate() Matrix4 RosenRenderContext::GetRevertMatrix() { CHECK_NULL_RETURN(rsNode_, {}); + if (ShouldSkipAffineTransformation(rsNode_)) { + return Matrix4(); + } auto center = rsNode_->GetStagingProperties().GetPivot(); Matrix4 rotateMat; #if defined(MODIFIER_NG) @@ -2506,6 +2535,9 @@ Matrix4 RosenRenderContext::GetRevertMatrix() Matrix4 RosenRenderContext::GetMatrix() { CHECK_NULL_RETURN(rsNode_, {}); + if (ShouldSkipAffineTransformation(rsNode_)) { + return Matrix4(); + } auto center = rsNode_->GetStagingProperties().GetPivot(); int32_t degree = rsNode_->GetStagingProperties().GetRotation(); if (rsNode_->GetType() == RSUINodeType::DISPLAY_NODE && degree != 0) { @@ -2540,6 +2572,9 @@ Matrix4 RosenRenderContext::GetMatrix() Matrix4 RosenRenderContext::GetMatrixWithTransformRotate() { CHECK_NULL_RETURN(rsNode_, {}); + if (ShouldSkipAffineTransformation(rsNode_)) { + return Matrix4(); + } auto center = rsNode_->GetStagingProperties().GetPivot(); Matrix4 rotateMat; @@ -2626,6 +2661,9 @@ void RosenRenderContext::GetPointTransformRotate(PointF& point) void RosenRenderContext::GetPointWithTransform(PointF& point) { CHECK_NULL_VOID(rsNode_); + if (ShouldSkipAffineTransformation(rsNode_)) { + return; + } auto skew = rsNode_->GetStagingProperties().GetSkew(); auto scale = rsNode_->GetStagingProperties().GetScale(); point = PointF(point.GetX() / scale[0], point.GetY() / scale[1]); @@ -2677,6 +2715,9 @@ RectF RosenRenderContext::GetPaintRectWithTransformWithoutDegree() RectF rect; CHECK_NULL_RETURN(rsNode_, rect); rect = GetPaintRectWithoutTransform(); + if (ShouldSkipAffineTransformation(rsNode_)) { + return rect; + } auto translate = rsNode_->GetStagingProperties().GetTranslate(); auto skew = rsNode_->GetStagingProperties().GetSkew(); auto perspective = rsNode_->GetStagingProperties().GetPersp(); @@ -8126,6 +8167,24 @@ void RosenRenderContext::MarkNeedDrawNode(bool condition) } } +bool RosenRenderContext::ShouldSkipAffineTransformation(std::shared_ptr rsNode) +{ + if (SystemProperties::GetContainerDeleteFlag() && + rsNode->GetDrawNodeType() != Rosen::DrawNodeType::GeometryPropertyType) { + if (SystemProperties::GetDebugEnabled()) { + TAG_LOGD(AceLogTag::ACE_DEFAULT_DOMAIN, "Should skip affine transformation, node(%{public}d, %{public}s)", + rsNode->GetFrameNodeId(), rsNode->GetFrameNodeTag().c_str()); + } + return true; + } + return false; +} + +void RenderContext::SetNeedCallbackNodeChange(bool needCallback) +{ + Rosen::RSNode::SetNeedCallbackNodeChange(needCallback); +} + std::shared_ptr RosenRenderContext::GetOrCreateTransitionModifier() { if (!transitionModifier_) { diff --git a/frameworks/core/components_ng/render/adapter/rosen_render_context.h b/frameworks/core/components_ng/render/adapter/rosen_render_context.h index fed348e1634515332f96a2b036cd146a2faf1102..b2bbb72e02d3e12830d5d68a19b5b55a3a516bb6 100755 --- a/frameworks/core/components_ng/render/adapter/rosen_render_context.h +++ b/frameworks/core/components_ng/render/adapter/rosen_render_context.h @@ -489,6 +489,7 @@ public: void GetLiveChildren(const RefPtr& node, std::list>& childNodes); void AddRsNodeForCapture(); static bool initDrawNodeChangeCallback_; + static bool initPropertyNodeChangeCallback_; void FreezeCanvasNode(bool freezeFlag = false); void RemoveCanvasNode(); @@ -918,6 +919,7 @@ protected: private: void ModifyCustomBackground(); + bool ShouldSkipAffineTransformation(std::shared_ptr rsNode); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/render/render_context.h b/frameworks/core/components_ng/render/render_context.h index c3c99897bb66155573a8db06193763e5b7d91d48..00e1d64d5dfc6ae791c7b0300cbac711e61f3df7 100644 --- a/frameworks/core/components_ng/render/render_context.h +++ b/frameworks/core/components_ng/render/render_context.h @@ -813,6 +813,8 @@ public: virtual void SetDrawNode() {} + static void SetNeedCallbackNodeChange(bool needCallback); + virtual void UpdateOcclusionCullingStatus(bool enable) {} virtual void SetAnimationPropertyValue(AnimationPropertyType property, const std::vector& value) {} diff --git a/frameworks/core/pipeline_ng/pipeline_context.cpp b/frameworks/core/pipeline_ng/pipeline_context.cpp index 74c60a9d957fc406a2474ebad4134b1bc24fa7b2..aa6da30a63b7b9911aeb132d0a760d28273a0c1e 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.cpp +++ b/frameworks/core/pipeline_ng/pipeline_context.cpp @@ -741,8 +741,17 @@ void PipelineContext::FlushVsync(uint64_t nanoTimestamp, uint32_t frameCount) FlushFocusScroll(); } } - HandleOnAreaChangeEvent(nanoTimestamp); - HandleVisibleAreaChangeEvent(nanoTimestamp); + if (SystemProperties::GetContainerDeleteFlag()) { + if (isNeedCallbackAreaChange_) { + HandleOnAreaChangeEvent(nanoTimestamp); + HandleVisibleAreaChangeEvent(nanoTimestamp); + isNeedCallbackAreaChange_ = false; + RenderContext::SetNeedCallbackNodeChange(true); + } + } else { + HandleOnAreaChangeEvent(nanoTimestamp); + HandleVisibleAreaChangeEvent(nanoTimestamp); + } FlushMouseEventInVsync(); eventManager_->FlushCursorStyleRequests(); if (isNeedFlushAnimationStartTime_) { diff --git a/frameworks/core/pipeline_ng/pipeline_context.h b/frameworks/core/pipeline_ng/pipeline_context.h index 4a568808f7b8b95336e459594dc04c3f184af1a8..9b6cb84a06eb6ab7a21f394445cfdad90a683b4d 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.h +++ b/frameworks/core/pipeline_ng/pipeline_context.h @@ -1255,6 +1255,11 @@ public: void UnregisterArkUIObjectLifecycleCallback(); void FireArkUIObjectLifecycleCallback(void* data); + inline void SetNeedCallbackAreaChange(bool needChange) + { + isNeedCallbackAreaChange_ = needChange; + } + protected: void StartWindowSizeChangeAnimate(int32_t width, int32_t height, WindowSizeChangeReason type, const std::shared_ptr& rsTransaction = nullptr); @@ -1512,6 +1517,7 @@ private: bool isWindowSizeDragging_ = false; KeyBoardAvoidMode prevKeyboardAvoidMode_ = KeyBoardAvoidMode::OFFSET; bool isFreezeFlushMessage_ = false; + bool isNeedCallbackAreaChange_ = true; RefPtr focusNode_; std::function focusOnNodeCallback_; diff --git a/test/unittest/core/pipeline/BUILD.gn b/test/unittest/core/pipeline/BUILD.gn index fe2d143bec235ad3d09868936e52ce2004b51095..ca5ac62263657c35c9148a0b77ff8004c8005b74 100644 --- a/test/unittest/core/pipeline/BUILD.gn +++ b/test/unittest/core/pipeline/BUILD.gn @@ -118,6 +118,7 @@ ace_unittest("pipeline_context_test_ng") { "$ace_root/test/mock/interfaces/mock_content_modifier.cpp", "$ace_root/test/unittest/core/pattern/text/mock/mock_text_layout_adapter.cpp", "mock_input_method_manager.cpp", + "mock_rosen_render_context.cpp", "pipeline_context_test_ng.cpp", "pipeline_context_test_ng_new.cpp", "pipeline_context_test_ng_two.cpp", diff --git a/test/unittest/core/pipeline/mock_rosen_render_context.cpp b/test/unittest/core/pipeline/mock_rosen_render_context.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45b7bff50fbfb7a2661d7fb97d33846415a8f706 --- /dev/null +++ b/test/unittest/core/pipeline/mock_rosen_render_context.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 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 "core/components_ng/render/render_context.h" + +namespace OHOS::Ace::NG { +void RenderContext::SetNeedCallbackNodeChange(bool needCallback) {} +} // namespace OHOS::Ace::NG + diff --git a/test/unittest/core/rosen/rosen_render_context_test.cpp b/test/unittest/core/rosen/rosen_render_context_test.cpp index 96ec54b64df502d1c913848217fd5452f4aff108..274667d8f7cff614380c611252afb904a5ac57b0 100644 --- a/test/unittest/core/rosen/rosen_render_context_test.cpp +++ b/test/unittest/core/rosen/rosen_render_context_test.cpp @@ -2158,4 +2158,25 @@ HWTEST_F(RosenRenderContextTest, RemoveFromTreeTest002, TestSize.Level1) EXPECT_EQ(rosenRenderContext->rsNode_->isOnTheTreeInit_, true); EXPECT_EQ(rosenRenderContext->rsNode_->isOnTheTree_, false); } + +/** + * @tc.name: ShouldSkipAffineTransformation001 + * @tc.desc: Test ShouldSkipAffineTransformation Func. + * @tc.type: FUNC + */ +HWTEST_F(RosenRenderContextTest, ShouldSkipAffineTransformation001, TestSize.Level1) +{ + auto frameNode = FrameNode::GetOrCreateFrameNode("frame", -1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(frameNode, nullptr); + RefPtr rosenRenderContext = InitRosenRenderContext(frameNode); + ASSERT_NE(rosenRenderContext, nullptr); + ASSERT_NE(rosenRenderContext->rsNode_, nullptr); + rosenRenderContext->rsNode_->SetDrawNodeType(Rosen::DrawNodeType::DrawPropertyType); + bool res = rosenRenderContext->ShouldSkipAffineTransformation(rosenRenderContext->rsNode_); + rosenRenderContext->rsNode_->SetDrawNodeType(Rosen::DrawNodeType::GeometryPropertyType); + res = rosenRenderContext->ShouldSkipAffineTransformation(rosenRenderContext->rsNode_); + ASSERT_EQ(res, false); + rosenRenderContext->rsNode_ = nullptr; + ASSERT_EQ(rosenRenderContext->rsNode_, nullptr); +} } // namespace OHOS::Ace::NG