1 /*
2 * Copyright (c) 2021-2022 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 "command/rs_display_node_command.h"
17
18 #include "pipeline/rs_screen_render_node.h"
19 #include "pipeline/rs_logical_display_render_node.h"
20 #include "pipeline/rs_render_node_gc.h"
21 #include "platform/common/rs_log.h"
22
23 namespace OHOS {
24 namespace Rosen {
25
26 /**
27 * @brief This function is used to set the display node by screen id.
28 * @param context The context of the render service
29 * @param id The screen id of the display node
30 * @param lambda The lambda function to set the display node.
31 * @return Returns true if the display node is set successfully, otherwise returns false;
32 */
33 template <class Lambda>
TrySetScreenNodeByScreenId(RSContext & context,ScreenId id,Lambda && lambda)34 bool TrySetScreenNodeByScreenId(RSContext& context, ScreenId id, Lambda&& lambda)
35 {
36 auto& nodeMap = context.GetMutableNodeMap();
37 bool nodeExists = false;
38 nodeMap.TraverseScreenNodes([&lambda, &nodeExists, id](auto& node) {
39 if (!node || node->GetScreenId() != id) {
40 return;
41 }
42 nodeExists = true;
43 lambda(node);
44 });
45 return nodeExists;
46 }
47
Create(RSContext & context,NodeId id,const RSDisplayNodeConfig & config)48 void DisplayNodeCommandHelper::Create(RSContext& context, NodeId id, const RSDisplayNodeConfig& config)
49 {
50 auto node = std::shared_ptr<RSLogicalDisplayRenderNode>(new RSLogicalDisplayRenderNode(id,
51 config, context.weak_from_this()), RSRenderNodeGC::NodeDestructor);
52 auto& nodeMap = context.GetMutableNodeMap();
53 nodeMap.RegisterRenderNode(node);
54
55 auto lambda = [&node](auto& screenRenderNode) {
56 screenRenderNode->AddChild(node);
57 };
58 if (!TrySetScreenNodeByScreenId(context, config.screenId, lambda)) {
59 RS_LOGE("%{public}s Invalid ScreenId NodeId: %{public}" PRIu64
60 ", curNodeId: %{public}" PRIu64, __func__, config.screenId, id);
61 }
62
63 SetDisplayMode(context, id, config);
64 }
65
CreateWithConfigInRS(RSContext & context,NodeId id,const RSDisplayNodeConfig & config)66 std::shared_ptr<RSLogicalDisplayRenderNode> DisplayNodeCommandHelper::CreateWithConfigInRS(
67 RSContext& context, NodeId id, const RSDisplayNodeConfig& config)
68 {
69 auto node = std::shared_ptr<RSLogicalDisplayRenderNode>(new RSLogicalDisplayRenderNode(id, config,
70 context.weak_from_this()), RSRenderNodeGC::NodeDestructor);
71 return node;
72 }
73
AddDisplayNodeToTree(RSContext & context,NodeId id)74 void DisplayNodeCommandHelper::AddDisplayNodeToTree(RSContext& context, NodeId id)
75 {
76 auto& nodeMap = context.GetMutableNodeMap();
77 auto logicalDisplayNode = nodeMap.GetRenderNode<RSLogicalDisplayRenderNode>(id);
78 if (logicalDisplayNode == nullptr) {
79 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, id);
80 return;
81 }
82 auto screenId = logicalDisplayNode->GetScreenId();
83 if (screenId == INVALID_SCREEN_ID) {
84 RS_LOGE("%{public}s failed, screenId must be set before display node add to true", __func__);
85 return;
86 }
87 auto lambda = [&logicalDisplayNode](const std::shared_ptr<RSScreenRenderNode>& screenRenderNode) {
88 screenRenderNode->AddChild(logicalDisplayNode);
89 };
90 if (!TrySetScreenNodeByScreenId(context, screenId, lambda)) {
91 RS_LOGE("%{public}s Invalid ScreenId NodeId: %{public}" PRIu64
92 ", curNodeId: %{public}" PRIu64, __func__, screenId, id);
93 logicalDisplayNode->NotifySetOnTreeFlag();
94 } else {
95 logicalDisplayNode->ResetSetOnTreeFlag();
96 }
97 }
98
RemoveDisplayNodeFromTree(RSContext & context,NodeId id)99 void DisplayNodeCommandHelper::RemoveDisplayNodeFromTree(RSContext& context, NodeId id)
100 {
101 auto& nodeMap = context.GetMutableNodeMap();
102 auto logicalDisplayNode = nodeMap.GetRenderNode<RSLogicalDisplayRenderNode>(id);
103 if (logicalDisplayNode == nullptr) {
104 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, id);
105 return;
106 }
107
108 auto lambda = [&logicalDisplayNode](const std::shared_ptr<RSScreenRenderNode>& screenRenderNode) {
109 screenRenderNode->RemoveChild(logicalDisplayNode);
110 };
111 auto screenId = logicalDisplayNode->GetScreenId();
112 if (!TrySetScreenNodeByScreenId(context, screenId, lambda)) {
113 RS_LOGE("%{public}s Invalid ScreenId NodeId: %{public}" PRIu64
114 ", curNodeId: %{public}" PRIu64, __func__, screenId, id);
115 }
116 logicalDisplayNode->ResetSetOnTreeFlag();
117 }
118
SetScreenId(RSContext & context,NodeId id,uint64_t screenId)119 void DisplayNodeCommandHelper::SetScreenId(RSContext& context, NodeId id, uint64_t screenId)
120 {
121 auto& nodeMap = context.GetMutableNodeMap();
122 auto logicalDisplayNode = nodeMap.GetRenderNode<RSLogicalDisplayRenderNode>(id);
123 if (logicalDisplayNode == nullptr) {
124 RS_LOGE("DisplayNodeCommandHelper::%{public}s, displayNode node found, id:[%{public}" PRIu64
125 "], screenId:[%{public}" PRIu64 "]", __func__, id, screenId);
126 return;
127 }
128
129 logicalDisplayNode->SetScreenId(screenId);
130 logicalDisplayNode->NotifyScreenNotSwitching();
131 auto lambda = [&logicalDisplayNode](auto& screenRenderNode) {
132 screenRenderNode->AddChild(logicalDisplayNode);
133 };
134 if (!TrySetScreenNodeByScreenId(context, screenId, lambda)) {
135 RS_LOGE("%{public}s Invalid ScreenId NodeId: %{public}" PRIu64
136 ", curNodeId: %{public}" PRIu64, __func__, screenId, id);
137 }
138 }
139
SetForceCloseHdr(RSContext & context,NodeId id,bool isForceCloseHdr)140 void DisplayNodeCommandHelper::SetForceCloseHdr(RSContext& context, NodeId id, bool isForceCloseHdr)
141 {
142 if (auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(id)) {
143 auto screenId = node->GetScreenId();
144 auto lambda = [isForceCloseHdr] (auto& node) {
145 node->SetForceCloseHdr(isForceCloseHdr);
146 };
147 if (!TrySetScreenNodeByScreenId(context, screenId, lambda)) {
148 RS_LOGE("%{public}s Invalid ScreenId NodeId: %{public}" PRIu64
149 ", curNodeId: %{public}" PRIu64, __func__, screenId, id);
150 }
151 } else {
152 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, id);
153 }
154 }
155
SetScreenRotation(RSContext & context,NodeId id,const ScreenRotation & screenRotation)156 void DisplayNodeCommandHelper::SetScreenRotation(RSContext& context, NodeId id, const ScreenRotation& screenRotation)
157 {
158 if (auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(id)) {
159 node->SetScreenRotation(screenRotation);
160 } else {
161 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, id);
162 }
163 }
164
SetSecurityDisplay(RSContext & context,NodeId id,bool isSecurityDisplay)165 void DisplayNodeCommandHelper::SetSecurityDisplay(RSContext& context, NodeId id, bool isSecurityDisplay)
166 {
167 if (auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(id)) {
168 node->SetSecurityDisplay(isSecurityDisplay);
169 } else {
170 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, id);
171 }
172 }
173
SetDisplayMode(RSContext & context,NodeId id,const RSDisplayNodeConfig & config)174 void DisplayNodeCommandHelper::SetDisplayMode(RSContext& context, NodeId id, const RSDisplayNodeConfig& config)
175 {
176 auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(id);
177 if (node == nullptr) {
178 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, id);
179 return;
180 }
181
182 bool isMirror = config.isMirrored;
183 node->SetIsMirrorDisplay(isMirror);
184 if (isMirror) {
185 NodeId mirroredNodeId = config.mirrorNodeId;
186 auto& nodeMap = context.GetNodeMap();
187 auto mirrorSourceNode = nodeMap.GetRenderNode<RSLogicalDisplayRenderNode>(mirroredNodeId);
188 if (mirrorSourceNode == nullptr) {
189 ROSEN_LOGW("DisplayNodeCommandHelper::SetDisplayMode fail, displayNodeId:[%{public}" PRIu64 "]"
190 "mirroredNodeId:[%{public}" PRIu64 "]", id, mirroredNodeId);
191 return;
192 }
193 node->SetMirrorSource(mirrorSourceNode);
194 } else {
195 node->ResetMirrorSource();
196 }
197 }
198
SetBootAnimation(RSContext & context,NodeId nodeId,bool isBootAnimation)199 void DisplayNodeCommandHelper::SetBootAnimation(RSContext& context, NodeId nodeId, bool isBootAnimation)
200 {
201 if (auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(nodeId)) {
202 node->SetBootAnimation(isBootAnimation);
203 } else {
204 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, nodeId);
205 }
206 }
207
SetScbNodePid(RSContext & context,NodeId nodeId,const std::vector<int32_t> & oldScbPids,int32_t currentScbPid)208 void DisplayNodeCommandHelper::SetScbNodePid(RSContext& context, NodeId nodeId,
209 const std::vector<int32_t>& oldScbPids, int32_t currentScbPid)
210 {
211 if (auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(nodeId)) {
212 RS_LOGI("SetScbNodePid NodeId:[%{public}" PRIu64 "] currentPid:[%{public}d]", nodeId, currentScbPid);
213 node->SetScbNodePid(oldScbPids, currentScbPid);
214 } else {
215 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, nodeId);
216 }
217 }
218
SetVirtualScreenMuteStatus(RSContext & context,NodeId nodeId,bool virtualScreenMuteStatus)219 void DisplayNodeCommandHelper::SetVirtualScreenMuteStatus(RSContext& context, NodeId nodeId,
220 bool virtualScreenMuteStatus)
221 {
222 if (auto node = context.GetNodeMap().GetRenderNode<RSLogicalDisplayRenderNode>(nodeId)) {
223 RS_LOGI("SetVirtualScreenMuteStatus NodeId:[%{public}" PRIu64 "]"
224 " screenId: %{public}" PRIu64 " virtualScreenMuteStatus: %{public}d",
225 nodeId, node->GetScreenId(), virtualScreenMuteStatus);
226 node->SetVirtualScreenMuteStatus(virtualScreenMuteStatus);
227 } else {
228 RS_LOGE("%{public}s Invalid NodeId curNodeId: %{public}" PRIu64, __func__, nodeId);
229 }
230 }
231
232 } // namespace Rosen
233 } // namespace OHOS
234