已合并
fix: check filter cache when occluded #31583
jieyunwyb1创建于 7月24日
fix: check filter cache when occluded #31583
已合并
共 5 个文件变更+290-20
| @@ -59,6 +59,7 @@ | |||
| 59 | 59 | ||
G | |||
| 60 | 60 | ||
| 61 | 61 | ||
| 62 | + | ||
| 62 | 63 | ||
| 63 | 64 | ||
| 64 | 65 | ||
| @@ -4038,17 +4039,22 @@ void RSUniRenderVisitor::UpdateVisibleEffectChildrenStatus(const RSRenderNode& r | |||
| 4038 | void RSUniRenderVisitor::CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache( | 4039 | void RSUniRenderVisitor::CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache( |
| 4039 | const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager) | 4040 | const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager) |
| 4040 | { | 4041 | { |
| 4042 | + if (RSEffectUtils::ShouldSkipFilterNodeCheckInOccludedSubTree(curSurfaceNode_, rootNode, dirtyManager)) { | ||
| 4043 | + return; | ||
| 4044 | + } | ||
| 4045 | + | ||
| 4041 | auto rotationStatus = GetRotationStatus(); | 4046 | auto rotationStatus = GetRotationStatus(); |
| 4042 | const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap(); | 4047 | const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap(); |
| 4043 | // calculate visibleEffectChild oldDirtyInSurface for effectNode | 4048 | // calculate visibleEffectChild oldDirtyInSurface for effectNode |
| 4044 | - for (auto& child : rootNode.GetVisibleEffectChild()) { | 4049 | + if (dirtyFlag_) { |
| 4045 | - auto& visibleEffectNode = nodeMap.GetRenderNode<RSRenderNode>(child); | 4050 | + for (auto& child : rootNode.GetVisibleEffectChild()) { |
| 4046 | - if (visibleEffectNode == nullptr) { | 4051 | + auto& visibleEffectNode = nodeMap.GetRenderNode<RSRenderNode>(child); |
| 4047 | - continue; | 4052 | + if (visibleEffectNode) { |
| 4053 | + RectI filterRect; | ||
| 4054 | + visibleEffectNode->UpdateFilterRegionInSkippedSubTree( | ||
| 4055 | + dirtyManager, rootNode, filterRect, prepareClipRect_, prepareFilterClipRect_); | ||
| 4056 | + } | ||
| 4048 | } | 4057 | } |
| 4049 | - RectI filterRect; | ||
| 4050 | - visibleEffectNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, | ||
| 4051 | - prepareClipRect_, prepareFilterClipRect_); | ||
| 4052 | } | 4058 | } |
| 4053 | 4059 | ||
| 4054 | for (auto& child : rootNode.GetVisibleFilterChild()) { | 4060 | for (auto& child : rootNode.GetVisibleFilterChild()) { |
| @@ -4061,24 +4067,26 @@ void RSUniRenderVisitor::CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache( | |||
| 4061 | 4067 | ||
| 4062 | // Check if HWC should be disabled for ColorPicker node | 4068 | // Check if HWC should be disabled for ColorPicker node |
| 4063 | HandleColorPickerHwcDisable(*filterNode); | 4069 | HandleColorPickerHwcDisable(*filterNode); |
| 4064 | - // Skip nodes that only have ColorPickerDrawable without any real filter | 4070 | + // Skip nodes that has no blur filter |
| 4065 | - if (filterNode->IsColorPickerOnlyNode()) { | 4071 | + if (!filterNode->HasBlurFilter()) { |
这里为啥需要扩大下层遍历的范围? ![]() ![]() | |||
| 4066 | continue; | 4072 | continue; |
| 4067 | } | 4073 | } |
| 4068 | 4074 | ||
| 4075 | + RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache node[" PRIu64 "]", | ||
| 4076 | + filterNode->GetId()); | ||
| 4069 | auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode); | 4077 | auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode); |
| 4070 | - if (effectNode == nullptr) { | 4078 | + if (effectNode != nullptr) { |
| 4071 | - continue; | 4079 | + effectNode->UpdateChildHasVisibleEffectWithoutEmptyRect(); |
| 4072 | } | 4080 | } |
| 4073 | - effectNode->CheckBlurFilterCacheNeedForceClearOrSave( | 4081 | + filterNode->CheckBlurFilterCacheNeedForceClearOrSave( |
4075的effectNode没判空,下面直接使用 ![]() ![]() | |||
| 4074 | rotationStatus.rotationChanged, rotationStatus.rotationStatusChanged); | 4082 | rotationStatus.rotationChanged, rotationStatus.rotationStatusChanged); |
| 4075 | - effectNode->UpdateChildHasVisibleEffectWithoutEmptyRect(); | 4083 | + filterNode->MarkClearFilterCacheIfEffectChildrenChanged(); |
这里MarkClearFilterCacheIfEffectChildrenChanged和Update之前的顺序颠倒,原因是啥 ![]() ![]() | |||
| 4076 | - effectNode->MarkClearFilterCacheIfEffectChildrenChanged(); | 4084 | + RSEffectUtils::UpdateFilterCacheWithBelowDirtyAndPendingPurge(*filterNode, dirtyManager); |
| 4077 | - RectI filterRect; | 4085 | + if (dirtyFlag_) { |
| 4078 | - effectNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, | 4086 | + RectI filterRect; |
| 4079 | - prepareClipRect_, prepareFilterClipRect_); | 4087 | + UpdateFilterRenderContextForSkippedSubTree(dirtyManager, *filterNode, rootNode, filterRect); |
| 4080 | - effectNode->FilterRectMergeDirtyRectInSkippedSubtree(dirtyManager, filterRect); | 4088 | + } |
| 4081 | - CollectFilterInfoAndUpdateDirty(*effectNode, dirtyManager); | 4089 | + CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager); |
| 4082 | } | 4090 | } |
| 4083 | } | 4091 | } |
| 4084 | 4092 | ||
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 21 | 22 | ||
| 22 | namespace OHOS { | 23 | namespace OHOS { |
| 23 | 24 | ||
| @@ -29,6 +30,23 @@ public: | |||
| 29 | 30 | ||
| 30 | // true:causes filter cache to be generated offscreen. | 31 | // true:causes filter cache to be generated offscreen. |
| 31 | static bool IsOffscreenForFilterCache(RSRenderNode& node); | 32 | static bool IsOffscreenForFilterCache(RSRenderNode& node); |
| 33 | + | ||
| 34 | + // Check if filter node check can be skipped in occluded sub tree. | ||
| 35 | + // Returns true when: | ||
| 36 | + // 1. curSurfaceNode exists (current surface is being processed) | ||
| 37 | + // 2. curSurfaceNode is opaque, no need to consider dirty regions of surface nodes below it | ||
| 38 | + // 3. Current frame dirty region is empty (no content needs update) | ||
| 39 | + // In this case, the sub tree is fully occluded and clean, so filter check can be skipped. | ||
| 40 | + static bool ShouldSkipFilterNodeCheckInOccludedSubTree( | ||
| 41 | + const std::shared_ptr<RSSurfaceRenderNode>& curSurfaceNode, const RSRenderNode& rootNode, | ||
| 42 | + RSDirtyRegionManager& dirtyManager); | ||
| 43 | + | ||
| 44 | + // Update filter cache with current frame dirty region and pending purge filter dirty rect. | ||
| 45 | + // This function processes both material filter and background filter: | ||
| 46 | + // 1. Updates filter cache with current frame dirty region | ||
| 47 | + // 2. Updates pending purge filter dirty rect for cache management | ||
| 48 | + static void UpdateFilterCacheWithBelowDirtyAndPendingPurge(RSRenderNode& node, | ||
| 49 | + RSDirtyRegionManager& dirtyManager); | ||
| 32 | }; | 50 | }; |
| 33 | } // namespace Rosen | 51 | } // namespace Rosen |
| 34 | } // namespace OHOS | 52 | } // namespace OHOS |
| @@ -58,5 +58,29 @@ bool RSEffectUtils::IsOffscreenForFilterCache(RSRenderNode& node) | |||
| 58 | return (node.GetType() == RSRenderNodeType::CANVAS_NODE || node.GetType() == RSRenderNodeType::UNION_NODE) && ( | 58 | return (node.GetType() == RSRenderNodeType::CANVAS_NODE || node.GetType() == RSRenderNodeType::UNION_NODE) && ( |
| 59 | node.GetDrawingCacheType() == RSDrawingCacheType::FOREGROUND_FILTER_CACHE || node.IsForegroundFilterEnable()); | 59 | node.GetDrawingCacheType() == RSDrawingCacheType::FOREGROUND_FILTER_CACHE || node.IsForegroundFilterEnable()); |
| 60 | } | 60 | } |
| 61 | + | ||
| 62 | +bool RSEffectUtils::ShouldSkipFilterNodeCheckInOccludedSubTree( | ||
| 63 | + const std::shared_ptr<RSSurfaceRenderNode>& curSurfaceNode, const RSRenderNode& rootNode, | ||
| 64 | + RSDirtyRegionManager& dirtyManager) | ||
| 65 | +{ | ||
| 66 | + return curSurfaceNode && | ||
| 67 | + !curSurfaceNode->IsTransparent() && | ||
| 68 | + dirtyManager.GetCurrentFrameDirtyRegion().IsEmpty(); | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +void RSEffectUtils::UpdateFilterCacheWithBelowDirtyAndPendingPurge(RSRenderNode& node, | ||
| 72 | + RSDirtyRegionManager& dirtyManager) | ||
| 73 | +{ | ||
| 74 | + if (node.GetRenderProperties().GetMaterialFilter()) { | ||
两种模糊要处理两遍? ![]() ![]() | |||
| 75 | + node.UpdateFilterCacheWithBelowDirty( | ||
| 76 | + Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion()), RSDrawableSlot::MATERIAL_FILTER); | ||
| 77 | + node.UpdatePendingPurgeFilterDirtyRect(dirtyManager, RSDrawableSlot::MATERIAL_FILTER); | ||
| 78 | + } | ||
| 79 | + if (node.GetRenderProperties().GetBackgroundFilter()) { | ||
| 80 | + node.UpdateFilterCacheWithBelowDirty( | ||
| 81 | + Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion())); | ||
| 82 | + node.UpdatePendingPurgeFilterDirtyRect(dirtyManager, RSDrawableSlot::BACKGROUND_FILTER); | ||
| 83 | + } | ||
| 84 | +} | ||
| 61 | } // namespace Rosen | 85 | } // namespace Rosen |
| 62 | -} // namespace OHOS | 86 | +} // namespace OHOS |
| @@ -7712,6 +7712,190 @@ HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClea | |||
| 7712 | } | 7712 | } |
| 7713 | 7713 | ||
| 7714 | /** | 7714 | /** |
| 7715 | + * @tc.name: CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_ShouldSkip001 | ||
| 7716 | + * @tc.desc: Test ShouldSkipFilterNodeCheckInOccludedSubTree returns true when conditions met | ||
| 7717 | + * @tc.type: FUNC | ||
| 7718 | + * @tc.require: issue25152 | ||
| 7719 | + */ | ||
| 7720 | +HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_ShouldSkip001, | ||
| 7721 | + TestSize.Level2) | ||
| 7722 | +{ | ||
| 7723 | + auto rsContext = std::make_shared<RSContext>(); | ||
| 7724 | + auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>(); | ||
| 7725 | + ASSERT_NE(rsUniRenderVisitor, nullptr); | ||
| 7726 | + | ||
| 7727 | + auto curSurfaceNode = std::make_shared<RSSurfaceRenderNode>(1000, rsContext->weak_from_this()); | ||
| 7728 | + curSurfaceNode->InitRenderParams(); | ||
| 7729 | + curSurfaceNode->SetAbilityBGAlpha(255); | ||
| 7730 | + curSurfaceNode->SetGlobalAlpha(1.0f); | ||
| 7731 | + EXPECT_FALSE(curSurfaceNode->IsTransparent()); | ||
| 7732 | + | ||
| 7733 | + auto rsRootRenderNode = std::make_shared<RSSurfaceRenderNode>(0, rsContext->weak_from_this()); | ||
| 7734 | + rsRootRenderNode->InitRenderParams(); | ||
| 7735 | + | ||
| 7736 | + RSDirtyRegionManager dirtyManager; | ||
| 7737 | + | ||
| 7738 | + rsUniRenderVisitor->curSurfaceNode_ = curSurfaceNode; | ||
| 7739 | + rsUniRenderVisitor->CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache(*rsRootRenderNode, dirtyManager); | ||
| 7740 | + | ||
| 7741 | + EXPECT_TRUE(dirtyManager.GetFilterCollector().GetFilterDirtyRegionInfoList(false).empty()); | ||
| 7742 | +} | ||
| 7743 | + | ||
| 7744 | +/** | ||
| 7745 | + * @tc.name: CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_ParentTreeDirty001 | ||
| 7746 | + * @tc.desc: Test rootNode.IsParentTreeDirty() true branch at line 4047 and 4078 | ||
| 7747 | + * @tc.type: FUNC | ||
| 7748 | + * @tc.require: issue25152 | ||
| 7749 | + */ | ||
| 7750 | +HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_ParentTreeDirty001, | ||
| 7751 | + TestSize.Level2) | ||
| 7752 | +{ | ||
| 7753 | + auto rsContext = std::make_shared<RSContext>(); | ||
| 7754 | + auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>(); | ||
| 7755 | + ASSERT_NE(rsUniRenderVisitor, nullptr); | ||
| 7756 | + rsUniRenderVisitor->dirtyFlag_ = true; | ||
| 7757 | + | ||
| 7758 | + auto rsRootRenderNode = std::make_shared<RSSurfaceRenderNode>(0, rsContext->weak_from_this()); | ||
| 7759 | + rsRootRenderNode->InitRenderParams(); | ||
| 7760 | + rsRootRenderNode->SetDirty(); | ||
| 7761 | + | ||
| 7762 | + auto effectNode = std::make_shared<RSEffectRenderNode>(1); | ||
| 7763 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().RegisterRenderNode(effectNode); | ||
| 7764 | + effectNode->GetMutableRenderProperties().backgroundFilter_ = std::make_shared<RSFilter>(); | ||
| 7765 | + effectNode->GetMutableRenderProperties().needFilter_ = true; | ||
| 7766 | + rsRootRenderNode->UpdateVisibleFilterChild(*effectNode); | ||
| 7767 | + rsRootRenderNode->UpdateVisibleEffectChild(*effectNode); | ||
| 7768 | + | ||
| 7769 | + auto canvasNode = std::make_shared<RSCanvasRenderNode>(2); | ||
| 7770 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().RegisterRenderNode(canvasNode); | ||
| 7771 | + canvasNode->GetMutableRenderProperties().backgroundFilter_ = std::make_shared<RSFilter>(); | ||
| 7772 | + canvasNode->GetMutableRenderProperties().needFilter_ = true; | ||
| 7773 | + rsRootRenderNode->UpdateVisibleFilterChild(*canvasNode); | ||
| 7774 | + | ||
| 7775 | + RSDirtyRegionManager dirtyManager; | ||
| 7776 | + rsUniRenderVisitor->CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache(*rsRootRenderNode, dirtyManager); | ||
| 7777 | + | ||
| 7778 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().UnregisterRenderNode(1); | ||
| 7779 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().UnregisterRenderNode(2); | ||
| 7780 | + EXPECT_TRUE(rsRootRenderNode->IsParentTreeDirty()); | ||
| 7781 | +} | ||
| 7782 | + | ||
| 7783 | +/** | ||
| 7784 | + * @tc.name: CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_VisibleEffectChild001 | ||
| 7785 | + * @tc.desc: Test visibleEffectNode not null branch at line 4050 | ||
| 7786 | + * @tc.type: FUNC | ||
| 7787 | + * @tc.require: issue25152 | ||
| 7788 | + */ | ||
| 7789 | +HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_VisibleEffectChild001, | ||
| 7790 | + TestSize.Level2) | ||
| 7791 | +{ | ||
| 7792 | + auto rsContext = std::make_shared<RSContext>(); | ||
| 7793 | + auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>(); | ||
| 7794 | + ASSERT_NE(rsUniRenderVisitor, nullptr); | ||
| 7795 | + rsUniRenderVisitor->dirtyFlag_ = true; | ||
| 7796 | + | ||
| 7797 | + auto rsRootRenderNode = std::make_shared<RSSurfaceRenderNode>(0, rsContext->weak_from_this()); | ||
| 7798 | + rsRootRenderNode->InitRenderParams(); | ||
| 7799 | + rsRootRenderNode->SetDirty(); | ||
| 7800 | + | ||
| 7801 | + auto visibleEffectChild = std::make_shared<RSEffectRenderNode>(100); | ||
| 7802 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().RegisterRenderNode(visibleEffectChild); | ||
| 7803 | + visibleEffectChild->GetMutableRenderProperties().needFilter_ = true; | ||
| 7804 | + rsRootRenderNode->visibleEffectChild_.insert(100); | ||
| 7805 | + | ||
| 7806 | + RSDirtyRegionManager dirtyManager; | ||
| 7807 | + rsUniRenderVisitor->CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache(*rsRootRenderNode, dirtyManager); | ||
| 7808 | + | ||
| 7809 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().UnregisterRenderNode(100); | ||
| 7810 | + EXPECT_TRUE(rsRootRenderNode->IsParentTreeDirty()); | ||
| 7811 | +} | ||
| 7812 | + | ||
| 7813 | +/** | ||
| 7814 | + * @tc.name: CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_VisibleEffectChildNull001 | ||
| 7815 | + * @tc.desc: Test visibleEffectNode null branch at line 4050 | ||
| 7816 | + * @tc.type: FUNC | ||
| 7817 | + * @tc.require: issue25152 | ||
| 7818 | + */ | ||
| 7819 | +HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_VisibleEffectChildNull001, | ||
| 7820 | + TestSize.Level2) | ||
| 7821 | +{ | ||
| 7822 | + auto rsContext = std::make_shared<RSContext>(); | ||
| 7823 | + auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>(); | ||
| 7824 | + ASSERT_NE(rsUniRenderVisitor, nullptr); | ||
| 7825 | + rsUniRenderVisitor->dirtyFlag_ = true; | ||
| 7826 | + | ||
| 7827 | + auto rsRootRenderNode = std::make_shared<RSSurfaceRenderNode>(0, rsContext->weak_from_this()); | ||
| 7828 | + rsRootRenderNode->InitRenderParams(); | ||
| 7829 | + rsRootRenderNode->SetDirty(); | ||
| 7830 | + | ||
| 7831 | + rsRootRenderNode->visibleEffectChild_.insert(200); | ||
| 7832 | + | ||
| 7833 | + RSDirtyRegionManager dirtyManager; | ||
| 7834 | + rsUniRenderVisitor->CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache(*rsRootRenderNode, dirtyManager); | ||
| 7835 | + | ||
| 7836 | + EXPECT_TRUE(rsRootRenderNode->IsParentTreeDirty()); | ||
| 7837 | +} | ||
| 7838 | + | ||
| 7839 | +/** | ||
| 7840 | + * @tc.name: CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_NoBlurFilter001 | ||
| 7841 | + * @tc.desc: Test skipping nodes without blur filter at line 4063 | ||
| 7842 | + * @tc.type: FUNC | ||
| 7843 | + * @tc.require: issue25152 | ||
| 7844 | + */ | ||
| 7845 | +HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_NoBlurFilter001, | ||
| 7846 | + TestSize.Level2) | ||
| 7847 | +{ | ||
| 7848 | + auto rsContext = std::make_shared<RSContext>(); | ||
| 7849 | + auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>(); | ||
| 7850 | + ASSERT_NE(rsUniRenderVisitor, nullptr); | ||
| 7851 | + | ||
| 7852 | + auto rsRootRenderNode = std::make_shared<RSSurfaceRenderNode>(0, rsContext->weak_from_this()); | ||
| 7853 | + rsRootRenderNode->InitRenderParams(); | ||
| 7854 | + | ||
| 7855 | + auto canvasNode = std::make_shared<RSCanvasRenderNode>(1); | ||
| 7856 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().RegisterRenderNode(canvasNode); | ||
| 7857 | + canvasNode->GetMutableRenderProperties().needFilter_ = true; | ||
| 7858 | + rsRootRenderNode->UpdateVisibleFilterChild(*canvasNode); | ||
| 7859 | + | ||
| 7860 | + RSDirtyRegionManager dirtyManager; | ||
| 7861 | + rsUniRenderVisitor->CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache(*rsRootRenderNode, dirtyManager); | ||
| 7862 | + | ||
| 7863 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().UnregisterRenderNode(1); | ||
| 7864 | + EXPECT_TRUE(dirtyManager.GetFilterCollector().GetFilterDirtyRegionInfoList(false).empty()); | ||
| 7865 | +} | ||
| 7866 | + | ||
| 7867 | +/** | ||
| 7868 | + * @tc.name: CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_EffectNodeNotNull001 | ||
| 7869 | + * @tc.desc: Test effectNode != nullptr branch at line 4070 | ||
| 7870 | + * @tc.type: FUNC | ||
| 7871 | + * @tc.require: issue25152 | ||
| 7872 | + */ | ||
| 7873 | +HWTEST_F(RSUniRenderVisitorTest, CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache_EffectNodeNotNull001, | ||
| 7874 | + TestSize.Level2) | ||
| 7875 | +{ | ||
| 7876 | + auto rsContext = std::make_shared<RSContext>(); | ||
| 7877 | + auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>(); | ||
| 7878 | + ASSERT_NE(rsUniRenderVisitor, nullptr); | ||
| 7879 | + rsUniRenderVisitor->dirtyFlag_ = true; | ||
| 7880 | + | ||
| 7881 | + auto rsRootRenderNode = std::make_shared<RSSurfaceRenderNode>(0, rsContext->weak_from_this()); | ||
| 7882 | + rsRootRenderNode->InitRenderParams(); | ||
| 7883 | + rsRootRenderNode->SetDirty(); | ||
| 7884 | + | ||
| 7885 | + auto effectNode = std::make_shared<RSEffectRenderNode>(1); | ||
| 7886 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().RegisterRenderNode(effectNode); | ||
| 7887 | + effectNode->GetMutableRenderProperties().backgroundFilter_ = std::make_shared<RSFilter>(); | ||
| 7888 | + effectNode->GetMutableRenderProperties().needFilter_ = true; | ||
| 7889 | + rsRootRenderNode->UpdateVisibleFilterChild(*effectNode); | ||
| 7890 | + | ||
| 7891 | + RSDirtyRegionManager dirtyManager; | ||
| 7892 | + rsUniRenderVisitor->CheckFilterNodeInOccludedSkippedSubTreeNeedClearCache(*rsRootRenderNode, dirtyManager); | ||
| 7893 | + | ||
| 7894 | + RSMainThread::Instance()->GetContext().GetMutableNodeMap().UnregisterRenderNode(1); | ||
| 7895 | + EXPECT_TRUE(rsRootRenderNode->IsParentTreeDirty()); | ||
| 7896 | +} | ||
| 7897 | + | ||
| 7898 | +/* | ||
| 7715 | * @tc.name: DelayNotifyUIBufferAvailableIfNeedTest001 | 7899 | * @tc.name: DelayNotifyUIBufferAvailableIfNeedTest001 |
| 7716 | * @tc.desc: Cover branch: IsPendingUIBufferNotify=true, entry exists, all siblings ready, flush. | 7900 | * @tc.desc: Cover branch: IsPendingUIBufferNotify=true, entry exists, all siblings ready, flush. |
| 7717 | * @tc.type: FUNC | 7901 | * @tc.type: FUNC |
| @@ -130,5 +130,41 @@ HWTEST_F(RSEffectUtilsTest, AccumulateFilterRenderContext003, TestSize.Level1) | |||
| 130 | EXPECT_TRUE(result); | 130 | EXPECT_TRUE(result); |
| 131 | EXPECT_EQ(filterContext.offscreenNodeId, canvasParent->GetId()); | 131 | EXPECT_EQ(filterContext.offscreenNodeId, canvasParent->GetId()); |
| 132 | } | 132 | } |
| 133 | + | ||
| 134 | +/** | ||
| 135 | + * @tc.name: UpdateFilterCacheWithBelowDirtyAndPendingPurge001 | ||
| 136 | + * @tc.desc: test UpdateFilterCacheWithBelowDirtyAndPendingPurge with MaterialFilter | ||
| 137 | + * @tc.type: FUNC | ||
| 138 | + * @tc.require: issue25152 | ||
| 139 | + */ | ||
| 140 | +HWTEST_F(RSEffectUtilsTest, UpdateFilterCacheWithBelowDirtyAndPendingPurge001, TestSize.Level2) | ||
| 141 | +{ | ||
| 142 | + auto node = std::make_shared<RSCanvasRenderNode>(id, context); | ||
| 143 | + node->GetMutableRenderProperties().GetEffect().materialFilter_ = std::make_shared<RSFilter>(); | ||
| 144 | + | ||
| 145 | + RSDirtyRegionManager dirtyManager; | ||
| 146 | + dirtyManager.MergeDirtyRect(RectI(0, 0, 100, 100)); | ||
| 147 | + | ||
| 148 | + RSEffectUtils::UpdateFilterCacheWithBelowDirtyAndPendingPurge(*node, dirtyManager); | ||
| 149 | + EXPECT_FALSE(dirtyManager.GetCurrentFrameDirtyRegion().IsEmpty()); | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +/** | ||
| 153 | + * @tc.name: UpdateFilterCacheWithBelowDirtyAndPendingPurge002 | ||
| 154 | + * @tc.desc: test UpdateFilterCacheWithBelowDirtyAndPendingPurge with BackgroundFilter | ||
| 155 | + * @tc.type: FUNC | ||
| 156 | + * @tc.require: issue25152 | ||
| 157 | + */ | ||
| 158 | +HWTEST_F(RSEffectUtilsTest, UpdateFilterCacheWithBelowDirtyAndPendingPurge002, TestSize.Level2) | ||
| 159 | +{ | ||
| 160 | + auto node = std::make_shared<RSCanvasRenderNode>(id, context); | ||
| 161 | + node->GetMutableRenderProperties().backgroundFilter_ = std::make_shared<RSFilter>(); | ||
| 162 | + | ||
| 163 | + RSDirtyRegionManager dirtyManager; | ||
| 164 | + dirtyManager.MergeDirtyRect(RectI(0, 0, 100, 100)); | ||
| 165 | + | ||
| 166 | + RSEffectUtils::UpdateFilterCacheWithBelowDirtyAndPendingPurge(*node, dirtyManager); | ||
| 167 | + EXPECT_FALSE(dirtyManager.GetCurrentFrameDirtyRegion().IsEmpty()); | ||
| 168 | +} | ||
| 133 | } // namespace Rosen | 169 | } // namespace Rosen |
| 134 | } // namespace OHOS | 170 | } // namespace OHOS |


ok