已合并
crossNode节点收集适配 #31940
crossNode节点收集适配 #31940
已合并
sunzy创建于 8月3日
共 3 个文件变更+256-0
@@ -1199,6 +1199,26 @@ void RSUniRenderVisitor::CollectHwcAndFilterNodesToParent(RSRenderNode& node, bo
1199 }1199 }
1200}1200}
1201 1201 
1202+void RSUniRenderVisitor::CollectHwcAndFilterNodesForCrossNode(RSSurfaceRenderNode& node,
1203+ bool isParentPrepareInReverseOrder)
1204+{
1205+ auto sourceRenderNode = node.GetSourceCrossNode().lock();
1206+ auto sourceSurfaceNode = sourceRenderNode ?
1207+ sourceRenderNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1208+ if (sourceSurfaceNode) {
1209+ // Clone: mirror the source's aggregated list into the current node.
1210+ auto& cloneNodeList = node.GetAllHwcNodeAndFilterNode();
1211+ cloneNodeList = sourceSurfaceNode->GetAllHwcNodeAndFilterNode();
L
LLyBbq8月7日

cloneNodeList 作用

likedislike
sunzy
sunzy
8月7日 评论:
1212+ } else if (node.IsCloneCrossNode()) {
1213+ // Error case: no resolvable source, drop stale data.
1214+ node.ClearAllHwcNodeAndFilterNode();
1215+ }
1216+ if (curScreenNode_ && curScreenNode_->GetId() != node.GetId()) {
1217+ CollectHwcAndFilterNodesToParent(node, isParentPrepareInReverseOrder,
1218+ RSUniHwcComputeUtil::IsBlendNeedFilter(node));
1219+ }
1220+}
1221+ 
G
Ggaoweihua8月4日

做好验证

likedislike
1202void RSUniRenderVisitor::QuickPrepareDepthRenderNode(RSDepthRenderNode& node, bool isParentPrepareInReverseOrder)1222void RSUniRenderVisitor::QuickPrepareDepthRenderNode(RSDepthRenderNode& node, bool isParentPrepareInReverseOrder)
1203{1223{
1204 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareDepthRenderNode nodeId[%llu]", node.GetId());1224 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareDepthRenderNode nodeId[%llu]", node.GetId());
@@ -1328,6 +1348,7 @@ void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node
1328 RSSpecialLayerUtils::DealWithSpecialLayer(node, *curLogicalDisplayNode_, needCalcScreenSpecialLayer);1348 RSSpecialLayerUtils::DealWithSpecialLayer(node, *curLogicalDisplayNode_, needCalcScreenSpecialLayer);
1329 // avoid cross node subtree visited twice or more1349 // avoid cross node subtree visited twice or more
1330 if (CheckSkipAndPrepareForCrossNode(node)) {1350 if (CheckSkipAndPrepareForCrossNode(node)) {
1351+ CollectHwcAndFilterNodesForCrossNode(node, isParentPrepareInReverseOrder);
chuchengcheng

为啥没加到hwcVisitor里?

likedislike
sunzy
sunzy
8月24日 评论:
1331 return;1352 return;
1332 }1353 }
1333 // 0. init curSurface info and check node info1354 // 0. init curSurface info and check node info
@@ -177,6 +177,8 @@ private:
177 void CollectHwcAndFilterNodesInSkippedSubTree(RSRenderNode& node);177 void CollectHwcAndFilterNodesInSkippedSubTree(RSRenderNode& node);
178 void CollectHwcAndFilterNodesToParent(RSRenderNode& node, bool isParentPrepareInReverseOrder = false,178 void CollectHwcAndFilterNodesToParent(RSRenderNode& node, bool isParentPrepareInReverseOrder = false,
179 bool isBlendNeedFilter = false);179 bool isBlendNeedFilter = false);
180+ // Propagate the cross-node subtree's selfDrawing/filter nodes to the parent when its traversal is skipped.
181+ void CollectHwcAndFilterNodesForCrossNode(RSSurfaceRenderNode& node, bool isParentPrepareInReverseOrder = false);
180 // restore node's flag and filter dirty collection182 // restore node's flag and filter dirty collection
181 void PostPrepare(RSRenderNode& node, bool isParentPrepareInReverseOrder = false, bool subTreeSkipped = false);183 void PostPrepare(RSRenderNode& node, bool isParentPrepareInReverseOrder = false, bool subTreeSkipped = false);
182 void UpdateNodeVisibleRegion(RSSurfaceRenderNode& node);184 void UpdateNodeVisibleRegion(RSSurfaceRenderNode& node);
@@ -11227,6 +11227,239 @@ HWTEST_F(RSUniRenderVisitorTest, QuickPrepareProtectiveSolidRenderNode006, TestS
11227 EXPECT_FLOAT_EQ(layerInfo.alpha, 0.8f);11227 EXPECT_FLOAT_EQ(layerInfo.alpha, 0.8f);
11228}11228}
11229 11229 
11230+ 
11231+/**
11232+ * @tc.name: CollectHwcAndFilterNodesForCrossNode001
11233+ * @tc.desc: Clone cross-node with a valid source mirrors the source's aggregated node list into
11234+ * itself and propagates it to the parent; the parent ends up holding both source subtree
11235+ * nodes and the clone self when the clone is hardware-enabled.
11236+ * @tc.type: FUNC
11237+ */
11238+HWTEST_F(RSUniRenderVisitorTest, CollectHwcAndFilterNodesForCrossNode001, TestSize.Level1)
11239+{
11240+ auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>();
11241+ ASSERT_NE(rsUniRenderVisitor, nullptr);
11242+ 
11243+ // Source cross-node: carries one hardware-enabled child node aggregated in its list.
11244+ auto sourceNode = RSTestUtil::CreateSurfaceNode();
11245+ ASSERT_NE(sourceNode, nullptr);
11246+ sourceNode->isCrossNode_ = true;
11247+ auto sourceChild = RSTestUtil::CreateSurfaceNode();
11248+ ASSERT_NE(sourceChild, nullptr);
11249+ sourceChild->isHardwareEnabledNode_ = true;
11250+ sourceChild->nodeType_ = RSSurfaceNodeType::SELF_DRAWING_NODE;
11251+ sourceNode->ClearAllHwcNodeAndFilterNode();
11252+ sourceNode->GetAllHwcNodeAndFilterNode().push_back(sourceChild);
11253+ 
11254+ // Clone cross-node referencing the source; it is hardware-enabled so it will also insert itself.
11255+ auto cloneNode = RSTestUtil::CreateSurfaceNode();
11256+ ASSERT_NE(cloneNode, nullptr);
11257+ cloneNode->isCrossNode_ = true;
11258+ cloneNode->isCloneCrossNode_ = true;
11259+ cloneNode->sourceCrossNode_ = sourceNode;
11260+ cloneNode->isHardwareEnabledNode_ = true;
11261+ cloneNode->nodeType_ = RSSurfaceNodeType::SELF_DRAWING_NODE;
11262+ // Pre-populate stale data to verify the rebuild clears it.
11263+ auto staleNode = RSTestUtil::CreateSurfaceNode();
11264+ cloneNode->GetAllHwcNodeAndFilterNode().push_back(staleNode);
11265+ ASSERT_EQ(cloneNode->GetAllHwcNodeAndFilterNode().size(), 1u);
11266+ 
11267+ // Parent surface node so collection has somewhere to propagate.
11268+ auto parent = RSTestUtil::CreateSurfaceNode();
11269+ ASSERT_NE(parent, nullptr);
11270+ parent->AddChild(cloneNode, -1);
11271+ ASSERT_FALSE(cloneNode->GetParent().expired());
11272+ 
11273+ // curScreenNode_ with a different id from cloneNode so the collection guard passes.
11274+ auto rsContext = std::make_shared<RSContext>();
11275+ rsUniRenderVisitor->curScreenNode_ = std::make_shared<RSScreenRenderNode>(1000, 0, rsContext);
11276+ ASSERT_NE(rsUniRenderVisitor->curScreenNode_, nullptr);
11277+ ASSERT_NE(rsUniRenderVisitor->curScreenNode_->GetId(), cloneNode->GetId());
11278+ 
11279+ rsUniRenderVisitor->CollectHwcAndFilterNodesForCrossNode(*cloneNode, false);
11280+ 
11281+ // Clone list now holds the clone self at the front (self-inserted by
11282+ // CollectHwcAndFilterNodesToParent because the clone is hardware-enabled) followed by the
11283+ // mirrored source child; the stale entry was cleared.
11284+ ASSERT_EQ(cloneNode->GetAllHwcNodeAndFilterNode().size(), 2u);
11285+ auto cloneFront = cloneNode->GetAllHwcNodeAndFilterNode()[0].lock();
11286+ auto cloneSecond = cloneNode->GetAllHwcNodeAndFilterNode()[1].lock();
11287+ ASSERT_NE(cloneFront, nullptr);
11288+ ASSERT_NE(cloneSecond, nullptr);
11289+ EXPECT_EQ(cloneFront->GetId(), cloneNode->GetId());
11290+ EXPECT_EQ(cloneSecond->GetId(), sourceChild->GetId());
11291+ 
11292+ // Parent holds the same entries, appended in forward order.
11293+ ASSERT_EQ(parent->GetAllHwcNodeAndFilterNode().size(), 2u);
11294+ auto parentFirst = parent->GetAllHwcNodeAndFilterNode()[0].lock();
11295+ auto parentSecond = parent->GetAllHwcNodeAndFilterNode()[1].lock();
11296+ ASSERT_NE(parentFirst, nullptr);
11297+ ASSERT_NE(parentSecond, nullptr);
11298+ EXPECT_EQ(parentFirst->GetId(), cloneNode->GetId());
11299+ EXPECT_EQ(parentSecond->GetId(), sourceChild->GetId());
11300+}
11301+ 
11302+/**
11303+ * @tc.name: CollectHwcAndFilterNodesForCrossNode002
11304+ * @tc.desc: Clone cross-node whose source cannot be resolved (error case) clears any stale data and
11305+ * does not propagate stale entries to the parent.
11306+ * @tc.type: FUNC
11307+ */
11308+HWTEST_F(RSUniRenderVisitorTest, CollectHwcAndFilterNodesForCrossNode002, TestSize.Level1)
11309+{
11310+ auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>();
11311+ ASSERT_NE(rsUniRenderVisitor, nullptr);
11312+ 
11313+ auto cloneNode = RSTestUtil::CreateSurfaceNode();
11314+ ASSERT_NE(cloneNode, nullptr);
11315+ cloneNode->isCrossNode_ = true;
11316+ cloneNode->isCloneCrossNode_ = true;
11317+ // sourceCrossNode_ intentionally left empty to simulate the error case.
11318+ auto staleNode = RSTestUtil::CreateSurfaceNode();
11319+ cloneNode->GetAllHwcNodeAndFilterNode().push_back(staleNode);
11320+ ASSERT_EQ(cloneNode->GetAllHwcNodeAndFilterNode().size(), 1u);
11321+ 
11322+ auto parent = RSTestUtil::CreateSurfaceNode();
11323+ ASSERT_NE(parent, nullptr);
11324+ parent->AddChild(cloneNode, -1);
11325+ 
11326+ auto rsContext = std::make_shared<RSContext>();
11327+ rsUniRenderVisitor->curScreenNode_ = std::make_shared<RSScreenRenderNode>(1001, 0, rsContext);
11328+ ASSERT_NE(rsUniRenderVisitor->curScreenNode_, nullptr);
11329+ 
11330+ rsUniRenderVisitor->CollectHwcAndFilterNodesForCrossNode(*cloneNode, false);
11331+ 
11332+ // Clone list cleared; clone is not hardware-enabled so nothing is inserted back.
11333+ EXPECT_EQ(cloneNode->GetAllHwcNodeAndFilterNode().size(), 0u);
11334+ EXPECT_EQ(parent->GetAllHwcNodeAndFilterNode().size(), 0u);
11335+}
11336+ 
11337+/**
11338+ * @tc.name: CollectHwcAndFilterNodesForCrossNode003
11339+ * @tc.desc: Source cross-node (not a clone) keeps its existing aggregated list untouched and just
11340+ * propagates it to the parent; its own contents are neither cleared nor rebuilt.
11341+ * @tc.type: FUNC
11342+ */
11343+HWTEST_F(RSUniRenderVisitorTest, CollectHwcAndFilterNodesForCrossNode003, TestSize.Level1)
11344+{
11345+ auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>();
11346+ ASSERT_NE(rsUniRenderVisitor, nullptr);
11347+ 
11348+ // Source cross-node already holds a hardware-enabled child aggregated during the first-visit prepare.
11349+ auto sourceNode = RSTestUtil::CreateSurfaceNode();
11350+ ASSERT_NE(sourceNode, nullptr);
11351+ sourceNode->isCrossNode_ = true;
11352+ auto sourceChild = RSTestUtil::CreateSurfaceNode();
11353+ ASSERT_NE(sourceChild, nullptr);
11354+ sourceChild->isHardwareEnabledNode_ = true;
11355+ sourceChild->nodeType_ = RSSurfaceNodeType::SELF_DRAWING_NODE;
11356+ sourceNode->GetAllHwcNodeAndFilterNode().push_back(sourceChild);
11357+ ASSERT_EQ(sourceNode->GetAllHwcNodeAndFilterNode().size(), 1u);
11358+ 
11359+ auto parent = RSTestUtil::CreateSurfaceNode();
11360+ ASSERT_NE(parent, nullptr);
11361+ parent->AddChild(sourceNode, -1);
11362+ 
11363+ auto rsContext = std::make_shared<RSContext>();
11364+ rsUniRenderVisitor->curScreenNode_ = std::make_shared<RSScreenRenderNode>(1002, 0, rsContext);
11365+ ASSERT_NE(rsUniRenderVisitor->curScreenNode_, nullptr);
11366+ ASSERT_NE(rsUniRenderVisitor->curScreenNode_->GetId(), sourceNode->GetId());
11367+ 
11368+ rsUniRenderVisitor->CollectHwcAndFilterNodesForCrossNode(*sourceNode, true);
11369+ 
11370+ // Source list is preserved as-is (not cleared, not rebuilt).
11371+ ASSERT_EQ(sourceNode->GetAllHwcNodeAndFilterNode().size(), 1u);
11372+ auto preservedChild = sourceNode->GetAllHwcNodeAndFilterNode().front().lock();
11373+ ASSERT_NE(preservedChild, nullptr);
11374+ EXPECT_EQ(preservedChild->GetId(), sourceChild->GetId());
11375+ 
11376+ // Parent receives the source child in reverse-order insertion (front), source itself not added
11377+ // because it is not hardware-enabled.
11378+ ASSERT_EQ(parent->GetAllHwcNodeAndFilterNode().size(), 1u);
11379+ auto parentChild = parent->GetAllHwcNodeAndFilterNode().front().lock();
11380+ ASSERT_NE(parentChild, nullptr);
11381+ EXPECT_EQ(parentChild->GetId(), sourceChild->GetId());
11382+}
11383+ 
11384+/**
11385+ * @tc.name: CollectHwcAndFilterNodesForCrossNode004
11386+ * @tc.desc: When curScreenNode_ is null the collection guard skips CollectHwcAndFilterNodesToParent;
11387+ * the clone list rebuild still runs but nothing is propagated upward.
11388+ * @tc.type: FUNC
11389+ */
11390+HWTEST_F(RSUniRenderVisitorTest, CollectHwcAndFilterNodesForCrossNode004, TestSize.Level1)
11391+{
11392+ auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>();
11393+ ASSERT_NE(rsUniRenderVisitor, nullptr);
11394+ ASSERT_EQ(rsUniRenderVisitor->curScreenNode_, nullptr);
11395+ 
11396+ auto sourceNode = RSTestUtil::CreateSurfaceNode();
11397+ ASSERT_NE(sourceNode, nullptr);
11398+ sourceNode->isCrossNode_ = true;
11399+ auto sourceChild = RSTestUtil::CreateSurfaceNode();
11400+ ASSERT_NE(sourceChild, nullptr);
11401+ sourceChild->isHardwareEnabledNode_ = true;
11402+ sourceChild->nodeType_ = RSSurfaceNodeType::SELF_DRAWING_NODE;
11403+ sourceNode->GetAllHwcNodeAndFilterNode().push_back(sourceChild);
11404+ 
11405+ auto cloneNode = RSTestUtil::CreateSurfaceNode();
11406+ ASSERT_NE(cloneNode, nullptr);
11407+ cloneNode->isCrossNode_ = true;
11408+ cloneNode->isCloneCrossNode_ = true;
11409+ cloneNode->sourceCrossNode_ = sourceNode;
11410+ 
11411+ auto parent = RSTestUtil::CreateSurfaceNode();
11412+ ASSERT_NE(parent, nullptr);
11413+ parent->AddChild(cloneNode, -1);
11414+ ASSERT_EQ(parent->GetAllHwcNodeAndFilterNode().size(), 0u);
11415+ 
11416+ rsUniRenderVisitor->CollectHwcAndFilterNodesForCrossNode(*cloneNode, false);
11417+ 
11418+ // Clone list rebuild happened; parent propagation skipped because curScreenNode_ is null.
11419+ ASSERT_EQ(cloneNode->GetAllHwcNodeAndFilterNode().size(), 1u);
11420+ EXPECT_EQ(parent->GetAllHwcNodeAndFilterNode().size(), 0u);
11421+}
11422+ 
11423+/**
11424+ * @tc.name: CollectHwcAndFilterNodesForCrossNode005
11425+ * @tc.desc: When the node itself is the current screen root (same id) the collection guard skips
11426+ * propagation to a non-existent parent, while the clone list rebuild still runs.
11427+ * @tc.type: FUNC
11428+ */
11429+HWTEST_F(RSUniRenderVisitorTest, CollectHwcAndFilterNodesForCrossNode005, TestSize.Level1)
11430+{
11431+ auto rsUniRenderVisitor = std::make_shared<RSUniRenderVisitor>();
11432+ ASSERT_NE(rsUniRenderVisitor, nullptr);
11433+ 
11434+ auto sourceNode = RSTestUtil::CreateSurfaceNode();
11435+ ASSERT_NE(sourceNode, nullptr);
11436+ sourceNode->isCrossNode_ = true;
11437+ auto sourceChild = RSTestUtil::CreateSurfaceNode();
11438+ ASSERT_NE(sourceChild, nullptr);
11439+ sourceChild->isHardwareEnabledNode_ = true;
11440+ sourceChild->nodeType_ = RSSurfaceNodeType::SELF_DRAWING_NODE;
11441+ sourceNode->GetAllHwcNodeAndFilterNode().push_back(sourceChild);
11442+ 
11443+ auto cloneNode = RSTestUtil::CreateSurfaceNode();
11444+ ASSERT_NE(cloneNode, nullptr);
11445+ cloneNode->isCrossNode_ = true;
11446+ cloneNode->isCloneCrossNode_ = true;
11447+ cloneNode->sourceCrossNode_ = sourceNode;
11448+ 
11449+ // Make curScreenNode_ share the clone id to hit the skip-collection guard.
11450+ auto rsContext = std::make_shared<RSContext>();
11451+ rsUniRenderVisitor->curScreenNode_ = std::make_shared<RSScreenRenderNode>(cloneNode->GetId(), 0, rsContext);
11452+ ASSERT_EQ(rsUniRenderVisitor->curScreenNode_->GetId(), cloneNode->GetId());
11453+ 
11454+ rsUniRenderVisitor->CollectHwcAndFilterNodesForCrossNode(*cloneNode, false);
11455+ 
11456+ // Rebuild of the clone list still happened; no parent to propagate to in this config.
11457+ ASSERT_EQ(cloneNode->GetAllHwcNodeAndFilterNode().size(), 1u);
11458+ auto mirrored = cloneNode->GetAllHwcNodeAndFilterNode().front().lock();
11459+ ASSERT_NE(mirrored, nullptr);
11460+ EXPECT_EQ(mirrored->GetId(), sourceChild->GetId());
11461+}
11462+ 
11230/**11463/**
11231 * @tc.name: CollectVirtualScreenNodeId_ManagerNull11464 * @tc.name: CollectVirtualScreenNodeId_ManagerNull
11232 * @tc.desc: Test CollectVirtualScreenNodeId when virtualScreenParallelManager_ is nullptr11465 * @tc.desc: Test CollectVirtualScreenNodeId when virtualScreenParallelManager_ is nullptr