1
2 /*
3 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "ui/rs_surface_node.h"
18
19 #include <algorithm>
20 #include <string>
21
22 #include "command/rs_base_node_command.h"
23 #include "command/rs_surface_node_command.h"
24 #include "pipeline/rs_node_map.h"
25 #include "pipeline/rs_render_thread.h"
26 #include "platform/common/rs_log.h"
27 #if !defined(__gnu_linux__) && !defined(_WIN32) && !defined(__APPLE__)
28 #include "platform/drawing/rs_surface_converter.h"
29 #endif
30 #include "render_context/render_context.h"
31 #include "transaction/rs_render_service_client.h"
32 #include "transaction/rs_transaction_proxy.h"
33 #include "ui/rs_proxy_node.h"
34
35 namespace OHOS {
36 namespace Rosen {
Create(const RSSurfaceNodeConfig & surfaceNodeConfig,bool isWindow)37 RSSurfaceNode::SharedPtr RSSurfaceNode::Create(const RSSurfaceNodeConfig& surfaceNodeConfig, bool isWindow)
38 {
39 return Create(surfaceNodeConfig, RSSurfaceNodeType::DEFAULT, isWindow);
40 }
41
Create(const RSSurfaceNodeConfig & surfaceNodeConfig,RSSurfaceNodeType type,bool isWindow)42 RSSurfaceNode::SharedPtr RSSurfaceNode::Create(const RSSurfaceNodeConfig& surfaceNodeConfig,
43 RSSurfaceNodeType type, bool isWindow)
44 {
45 auto transactionProxy = RSTransactionProxy::GetInstance();
46 if (transactionProxy == nullptr) {
47 return nullptr;
48 }
49
50 SharedPtr node(new RSSurfaceNode(surfaceNodeConfig, isWindow));
51 RSNodeMap::MutableInstance().RegisterNode(node);
52
53 // create node in RS
54 RSSurfaceRenderNodeConfig config = {
55 .id = node->GetId(),
56 .name = node->name_,
57 .onRender = surfaceNodeConfig.onRender,
58 };
59 if (!isWindow) {
60 config.nodeType = RSSurfaceNodeType::SELF_DRAWING_NODE;
61 } else {
62 config.nodeType = type;
63 }
64
65 RS_LOGD("RSSurfaceNode::Create %s type %d", config.name.c_str(), config.nodeType);
66
67 if (!node->CreateNodeAndSurface(config)) {
68 ROSEN_LOGE("RSSurfaceNode::Create, create node and surface failed");
69 return nullptr;
70 }
71
72 node->SetClipToFrame(true);
73 // create node in RT
74 if (!isWindow) {
75 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeCreate>(node->GetId());
76 transactionProxy->AddCommand(command, isWindow);
77
78 command = std::make_unique<RSSurfaceNodeConnectToNodeInRenderService>(node->GetId());
79 transactionProxy->AddCommand(command, isWindow);
80
81 command = std::make_unique<RSSurfaceNodeSetCallbackForRenderThreadRefresh>(
82 node->GetId(), [] { RSRenderThread::Instance().RequestNextVSync(); });
83 transactionProxy->AddCommand(command, isWindow);
84 node->SetFrameGravity(Gravity::RESIZE);
85 }
86 if (node->GetName().find("battery_panel") != std::string::npos ||
87 node->GetName().find("sound_panel") != std::string::npos) {
88 node->SetFrameGravity(Gravity::TOP_LEFT);
89 } else {
90 node->SetFrameGravity(Gravity::RESIZE);
91 }
92 ROSEN_LOGD("RsDebug RSSurfaceNode::Create id:%" PRIu64, node->GetId());
93 return node;
94 }
95
CreateNodeInRenderThread()96 void RSSurfaceNode::CreateNodeInRenderThread()
97 {
98 if (!IsRenderServiceNode()) {
99 ROSEN_LOGI("RsDebug RSSurfaceNode::CreateNodeInRenderThread id:%" PRIu64 " already has RT Node", GetId());
100 return;
101 }
102
103 auto transactionProxy = RSTransactionProxy::GetInstance();
104 if (transactionProxy == nullptr) {
105 return;
106 }
107
108 isChildOperationDisallowed_ = true;
109 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeCreate>(GetId());
110 transactionProxy->AddCommand(command, false);
111
112 command = std::make_unique<RSSurfaceNodeConnectToNodeInRenderService>(GetId());
113 transactionProxy->AddCommand(command, false);
114
115 command = std::make_unique<RSSurfaceNodeSetCallbackForRenderThreadRefresh>(
116 GetId(), [] { RSRenderThread::Instance().RequestNextVSync(); });
117 transactionProxy->AddCommand(command, false);
118
119 command = std::make_unique<RSSurfaceNodeSetSurfaceNodeType>(GetId(), RSSurfaceNodeType::ABILITY_COMPONENT_NODE);
120 transactionProxy->AddCommand(command, true);
121 isRenderServiceNode_ = false;
122 }
123
AddChild(std::shared_ptr<RSBaseNode> child,int index)124 void RSSurfaceNode::AddChild(std::shared_ptr<RSBaseNode> child, int index)
125 {
126 if (isChildOperationDisallowed_) {
127 ROSEN_LOGE("RSSurfaceNode::AddChild for non RenderServiceNodeType surfaceNode is not allowed");
128 return;
129 }
130 RSBaseNode::AddChild(child, index);
131 }
132
RemoveChild(std::shared_ptr<RSBaseNode> child)133 void RSSurfaceNode::RemoveChild(std::shared_ptr<RSBaseNode> child)
134 {
135 if (isChildOperationDisallowed_) {
136 ROSEN_LOGE("RSSurfaceNode::RemoveChild for non RenderServiceNodeType surfaceNode is not allowed");
137 return;
138 }
139 RSBaseNode::RemoveChild(child);
140 }
141
ClearChildren()142 void RSSurfaceNode::ClearChildren()
143 {
144 if (isChildOperationDisallowed_) {
145 ROSEN_LOGE("RSSurfaceNode::ClearChildren for non RenderServiceNodeType surfaceNode is not allowed");
146 return;
147 }
148 RSBaseNode::ClearChildren();
149 }
150
GetFollowType() const151 FollowType RSSurfaceNode::GetFollowType() const
152 {
153 if (!IsUniRenderEnabled() && !isRenderServiceNode_) {
154 return FollowType::FOLLOW_TO_PARENT;
155 }
156 if (IsUniRenderEnabled() && !isRenderServiceNode_ && !RSSystemProperties::IsUniRenderMode()) {
157 return FollowType::FOLLOW_TO_PARENT;
158 }
159 return FollowType::NONE;
160 }
161
OnBoundsSizeChanged() const162 void RSSurfaceNode::OnBoundsSizeChanged() const
163 {
164 auto bounds = GetStagingProperties().GetBounds();
165 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeUpdateSurfaceDefaultSize>(
166 GetId(), bounds.z_, bounds.w_);
167 auto transactionProxy = RSTransactionProxy::GetInstance();
168 if (transactionProxy != nullptr) {
169 transactionProxy->AddCommand(command, true);
170 }
171 }
172
SetSecurityLayer(bool isSecurityLayer)173 void RSSurfaceNode::SetSecurityLayer(bool isSecurityLayer)
174 {
175 isSecurityLayer_ = isSecurityLayer;
176 std::unique_ptr<RSCommand> command =
177 std::make_unique<RSSurfaceNodeSetSecurityLayer>(GetId(), isSecurityLayer);
178 auto transactionProxy = RSTransactionProxy::GetInstance();
179 if (transactionProxy != nullptr) {
180 transactionProxy->AddCommand(command, true);
181 }
182 ROSEN_LOGD("RSSurfaceNode::SetSecurityLayer, surfaceNodeId:[%" PRIu64 "] isSecurityLayer:%s", GetId(),
183 isSecurityLayer ? "true" : "false");
184 }
185
GetSecurityLayer() const186 bool RSSurfaceNode::GetSecurityLayer() const
187 {
188 return isSecurityLayer_;
189 }
190
191 #if !defined(__gnu_linux__) && !defined(_WIN32) && !defined(__APPLE__)
SetColorSpace(ColorGamut colorSpace)192 void RSSurfaceNode::SetColorSpace(ColorGamut colorSpace)
193 {
194 colorSpace_ = colorSpace;
195 std::unique_ptr<RSCommand> command =
196 std::make_unique<RSSurfaceNodeSetColorSpace>(GetId(), colorSpace);
197 auto transactionProxy = RSTransactionProxy::GetInstance();
198 if (transactionProxy != nullptr) {
199 transactionProxy->AddCommand(command, true);
200 }
201 }
202 #endif
203
SetAbilityBGAlpha(uint8_t alpha)204 void RSSurfaceNode::SetAbilityBGAlpha(uint8_t alpha)
205 {
206 std::unique_ptr<RSCommand> command =
207 std::make_unique<RSSurfaceNodeSetAbilityBGAlpha>(GetId(), alpha);
208 auto transactionProxy = RSTransactionProxy::GetInstance();
209 if (transactionProxy != nullptr) {
210 transactionProxy->AddCommand(command, true);
211 }
212 }
213
SetIsNotifyUIBufferAvailable(bool available)214 void RSSurfaceNode::SetIsNotifyUIBufferAvailable(bool available)
215 {
216 std::unique_ptr<RSCommand> command =
217 std::make_unique<RSSurfaceNodeSetIsNotifyUIBufferAvailable>(GetId(), available);
218 auto transactionProxy = RSTransactionProxy::GetInstance();
219 if (transactionProxy != nullptr) {
220 transactionProxy->AddCommand(command, true);
221 }
222 }
223
SetBufferAvailableCallback(BufferAvailableCallback callback)224 bool RSSurfaceNode::SetBufferAvailableCallback(BufferAvailableCallback callback)
225 {
226 {
227 std::lock_guard<std::mutex> lock(mutex_);
228 callback_ = callback;
229 }
230 auto renderServiceClient =
231 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
232 if (renderServiceClient == nullptr) {
233 return false;
234 }
235 return renderServiceClient->RegisterBufferAvailableListener(GetId(), [weakThis = weak_from_this()]() {
236 auto rsSurfaceNode = RSBaseNode::ReinterpretCast<RSSurfaceNode>(weakThis.lock());
237 if (rsSurfaceNode == nullptr) {
238 ROSEN_LOGE("RSSurfaceNode::SetBufferAvailableCallback this == null");
239 return;
240 }
241 BufferAvailableCallback actualCallback;
242 {
243 std::lock_guard<std::mutex> lock(rsSurfaceNode->mutex_);
244 actualCallback = rsSurfaceNode->callback_;
245 }
246 actualCallback();
247 });
248 }
249
SetAnimationFinished()250 void RSSurfaceNode::SetAnimationFinished()
251 {
252 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetAnimationFinished>(GetId());
253 auto transactionProxy = RSTransactionProxy::GetInstance();
254 if (transactionProxy != nullptr) {
255 transactionProxy->AddCommand(command, true);
256 transactionProxy->FlushImplicitTransaction();
257 }
258 }
259
Marshalling(Parcel & parcel) const260 bool RSSurfaceNode::Marshalling(Parcel& parcel) const
261 {
262 return parcel.WriteUint64(GetId()) && parcel.WriteString(name_) && parcel.WriteBool(IsRenderServiceNode());
263 }
264
Unmarshalling(Parcel & parcel)265 std::shared_ptr<RSSurfaceNode> RSSurfaceNode::Unmarshalling(Parcel& parcel)
266 {
267 uint64_t id = UINT64_MAX;
268 std::string name;
269 bool isRenderServiceNode = false;
270 if (!(parcel.ReadUint64(id) && parcel.ReadString(name) && parcel.ReadBool(isRenderServiceNode))) {
271 ROSEN_LOGE("RSSurfaceNode::Unmarshalling, read param failed");
272 return nullptr;
273 }
274 RSSurfaceNodeConfig config = { name };
275
276 if (auto prevNode = RSNodeMap::Instance().GetNode(id)) {
277 // if the node id is already in the map, we should not create a new node
278 return prevNode->ReinterpretCastTo<RSSurfaceNode>();
279 }
280
281 SharedPtr surfaceNode(new RSSurfaceNode(config, isRenderServiceNode, id));
282 RSNodeMap::MutableInstance().RegisterNode(surfaceNode);
283
284 // for nodes constructed by unmarshalling, we should not destroy the corresponding render node on destruction
285 surfaceNode->skipDestroyCommandInDestructor_ = true;
286
287 return surfaceNode;
288 }
289
UnmarshallingAsProxyNode(Parcel & parcel)290 RSNode::SharedPtr RSSurfaceNode::UnmarshallingAsProxyNode(Parcel& parcel)
291 {
292 uint64_t id = UINT64_MAX;
293 std::string name;
294 bool isRenderServiceNode = false;
295 if (!(parcel.ReadUint64(id) && parcel.ReadString(name) && parcel.ReadBool(isRenderServiceNode))) {
296 ROSEN_LOGE("RSSurfaceNode::Unmarshalling, read param failed");
297 return nullptr;
298 }
299
300 // Create RSProxyNode by unmarshalling RSSurfaceNode, return existing node if it exists in RSNodeMap.
301 return RSProxyNode::Create(id, name);
302 }
303
CreateNode(const RSSurfaceRenderNodeConfig & config)304 bool RSSurfaceNode::CreateNode(const RSSurfaceRenderNodeConfig& config)
305 {
306 return std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient())
307 ->CreateNode(config);
308 }
309
CreateNodeAndSurface(const RSSurfaceRenderNodeConfig & config)310 bool RSSurfaceNode::CreateNodeAndSurface(const RSSurfaceRenderNodeConfig& config)
311 {
312 surface_ = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient())
313 ->CreateNodeAndSurface(config);
314 return (surface_ != nullptr);
315 }
316
317 #if !defined(__gnu_linux__) && !defined(_WIN32) && !defined(__APPLE__)
GetSurface() const318 sptr<OHOS::Surface> RSSurfaceNode::GetSurface() const
319 {
320 if (surface_ == nullptr) {
321 ROSEN_LOGE("RSSurfaceNode::GetSurface, surface_ is nullptr");
322 return nullptr;
323 }
324 auto ohosSurface = RSSurfaceConverter::ConvertToOhosSurface(surface_);
325 return ohosSurface;
326 }
327 #endif
328
NeedForcedSendToRemote() const329 bool RSSurfaceNode::NeedForcedSendToRemote() const
330 {
331 if (IsRenderServiceNode()) {
332 // RSRenderSurfaceNode in RS only need send property message to RenderService.
333 return false;
334 } else {
335 // RSRenderSurfaceNode in RT need send property message both to RenderService & RenderThread.
336 return true;
337 }
338 }
339
ResetContextAlpha() const340 void RSSurfaceNode::ResetContextAlpha() const
341 {
342 // temporarily fix: manually set contextAlpha in RT and RS to 0.0f, to avoid residual alpha/context matrix from
343 // previous animation. this value will be overwritten in RenderThreadVisitor::ProcessSurfaceRenderNode.
344 auto transactionProxy = RSTransactionProxy::GetInstance();
345 if (transactionProxy == nullptr) {
346 return;
347 }
348
349 std::unique_ptr<RSCommand> commandRS = std::make_unique<RSSurfaceNodeSetContextAlpha>(GetId(), 0.0f);
350 transactionProxy->AddCommand(commandRS, true);
351 }
352
SetAppFreeze(bool isAppFreeze)353 void RSSurfaceNode::SetAppFreeze(bool isAppFreeze)
354 {
355 std::unique_ptr<RSCommand> command =
356 std::make_unique<RSSurfaceNodeSetAppFreeze>(GetId(), isAppFreeze);
357 auto transactionProxy = RSTransactionProxy::GetInstance();
358 if (transactionProxy != nullptr) {
359 transactionProxy->AddCommand(command, true);
360 }
361 }
362
SetContainerWindow(bool hasContainerWindow,float density)363 void RSSurfaceNode::SetContainerWindow(bool hasContainerWindow, float density)
364 {
365 std::unique_ptr<RSCommand> command =
366 std::make_unique<RSSurfaceNodeSetContainerWindow>(GetId(), hasContainerWindow, density);
367 auto transactionProxy = RSTransactionProxy::GetInstance();
368 if (transactionProxy != nullptr) {
369 transactionProxy->AddCommand(command, true);
370 }
371 }
372
SetWindowId(uint32_t windowId)373 void RSSurfaceNode::SetWindowId(uint32_t windowId)
374 {
375 windowId_ = windowId;
376 }
377
RSSurfaceNode(const RSSurfaceNodeConfig & config,bool isRenderServiceNode)378 RSSurfaceNode::RSSurfaceNode(const RSSurfaceNodeConfig& config, bool isRenderServiceNode)
379 : RSNode(isRenderServiceNode), name_(config.SurfaceNodeName)
380 {}
381
RSSurfaceNode(const RSSurfaceNodeConfig & config,bool isRenderServiceNode,NodeId id)382 RSSurfaceNode::RSSurfaceNode(const RSSurfaceNodeConfig& config, bool isRenderServiceNode, NodeId id)
383 : RSNode(isRenderServiceNode, id), name_(config.SurfaceNodeName)
384 {}
385
~RSSurfaceNode()386 RSSurfaceNode::~RSSurfaceNode()
387 {
388 auto transactionProxy = RSTransactionProxy::GetInstance();
389 if (skipDestroyCommandInDestructor_) {
390 // for ability view and remote window, we should destroy the corresponding render node in RenderThread
391 if (transactionProxy != nullptr) {
392 std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeDestroy>(GetId());
393 transactionProxy->AddCommand(command, false, FollowType::FOLLOW_TO_PARENT, GetId());
394 }
395 return;
396 }
397 auto renderServiceClient =
398 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
399 if (renderServiceClient != nullptr) {
400 renderServiceClient->UnregisterBufferAvailableListener(GetId());
401 }
402 if (!IsRenderServiceNode() && transactionProxy != nullptr) {
403 std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeDestroy>(GetId());
404 transactionProxy->AddCommand(command, true, FollowType::FOLLOW_TO_PARENT, GetId());
405 }
406 }
407
408 } // namespace Rosen
409 } // namespace OHOS
410