1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "feature/composite_layer/rs_composite_layer_utils.h"
17
18 #include "platform/common/rs_log.h"
19 #include "transaction/rs_interfaces.h"
20 #include "ui/rs_root_node.h"
21 #include "ui/rs_surface_node.h"
22 #include "ui/rs_texture_export.h"
23
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 #ifndef ROSEN_CROSS_PLATFORM
28 constexpr uint32_t COMPOSITE_SURFACE_SIZE = 5;
29 #endif
30 }
RSCompositeLayerUtils(const std::shared_ptr<RSNode> & rootNode,uint32_t zOrder)31 RSCompositeLayerUtils::RSCompositeLayerUtils(const std::shared_ptr<RSNode>& rootNode, uint32_t zOrder)
32 {
33 rootNode_ = rootNode;
34 topLayerZOrder_ = zOrder;
35 if (RSSystemProperties::GetRSClientMultiInstanceEnabled()) {
36 rsUiDirector_ = RSUIDirector::Create();
37 rsUiDirector_->Init(true, true);
38 }
39 }
40
~RSCompositeLayerUtils()41 RSCompositeLayerUtils::~RSCompositeLayerUtils() {}
42
CreateCompositeLayer()43 bool RSCompositeLayerUtils::CreateCompositeLayer()
44 {
45 if (rootNode_ == nullptr) {
46 return false;
47 }
48
49 if (auto surfaceNode = rootNode_->ReinterpretCastTo<RSSurfaceNode>()) {
50 RSSurfaceNodeConfig config;
51 config.SurfaceNodeName = surfaceNode->GetName();
52 if (RSSystemProperties::GetRSClientMultiInstanceEnabled()) {
53 compositeNode_ = RSSurfaceNode::Create(config, false, rsUiDirector_->GetRSUIContext());
54 rsUiDirector_->SetRSSurfaceNode(compositeNode_);
55 } else {
56 compositeNode_ = RSSurfaceNode::Create(config, false);
57 }
58 }
59
60 if (compositeNode_ == nullptr) {
61 RS_LOGE("RSCompositeLayerUtils::CreateCompositeLayer compositeNode_ is null");
62 return false;
63 }
64
65 auto parent = rootNode_->GetParent();
66 if (parent == nullptr) {
67 RS_LOGE("RSCompositeLayerUtils::CreateCompositeLayer rootNode hasn't parent");
68 return false;
69 }
70 auto bounds = rootNode_->GetStagingProperties().GetBounds();
71 compositeNode_->SetBounds({bounds.x_, bounds.y_, bounds.z_, bounds.w_});
72 if (RSSystemProperties::GetRSClientMultiInstanceEnabled()) {
73 rsUiDirector_->SendMessages();
74 }
75
76 #ifndef ROSEN_CROSS_PLATFORM
77 parent->AddChild(compositeNode_);
78 rootNode_->RemoveFromTree();
79 auto surface = compositeNode_->GetSurface();
80 if (!surface) {
81 return false;
82 }
83 auto surfaceId = surface->GetUniqueId();
84 surface->SetQueueSize(COMPOSITE_SURFACE_SIZE);
85 textureExport_ = std::make_shared<RSTextureExport>(rootNode_, surfaceId);
86 textureExport_->DoTextureExport();
87 RSInterfaces::GetInstance().SetLayerTopForHWC(compositeNode_->GetId(), true, topLayerZOrder_);
88 return true;
89 #else
90 return false;
91 #endif
92 }
93
UpdateVirtualNodeBounds(const Vector4f & bounds)94 void RSCompositeLayerUtils::UpdateVirtualNodeBounds(const Vector4f& bounds)
95 {
96 if (textureExport_) {
97 textureExport_->UpdateBufferInfo(bounds.x_, bounds.y_, bounds.z_, bounds.w_);
98 }
99 if (compositeNode_) {
100 compositeNode_->SetBounds({bounds.x_, bounds.y_, bounds.z_, bounds.w_});
101 if (RSSystemProperties::GetRSClientMultiInstanceEnabled()) {
102 rsUiDirector_->SendMessages();
103 }
104 }
105 }
106
GetTopLayerZOrder()107 uint32_t RSCompositeLayerUtils::GetTopLayerZOrder()
108 {
109 return topLayerZOrder_;
110 }
111
GetCompositeNode()112 std::shared_ptr<RSSurfaceNode> RSCompositeLayerUtils::GetCompositeNode()
113 {
114 return compositeNode_;
115 }
116
DealWithSelfDrawCompositeNode(std::shared_ptr<RSNode> node,uint32_t zOrder)117 bool RSCompositeLayerUtils::DealWithSelfDrawCompositeNode(std::shared_ptr<RSNode> node, uint32_t zOrder)
118 {
119 if (!node || node->GetChildren().size() != 1) {
120 return false;
121 }
122 auto child = node->GetChildren()[0].lock();
123 if (!child) {
124 return false;
125 }
126 auto surfaceNode = child->ReinterpretCastTo<RSSurfaceNode>();
127 if (surfaceNode && surfaceNode->IsSelfDrawingNode()) {
128 RSInterfaces::GetInstance().SetLayerTopForHWC(surfaceNode->GetId(), true, zOrder);
129 return true;
130 }
131 return false;
132 }
133 } // namespace Rosen
134 } // namespace OHOS