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_node_command.h"
24 #include "command/rs_surface_node_command.h"
25 #include "ipc_callbacks/rs_rt_refresh_callback.h"
26 #include "pipeline/rs_node_map.h"
27 #include "pipeline/rs_render_thread.h"
28 #include "platform/common/rs_log.h"
29 #ifndef ROSEN_CROSS_PLATFORM
30 #include "platform/drawing/rs_surface_converter.h"
31 #endif
32 #ifdef NEW_RENDER_CONTEXT
33 #include "render_context_base.h"
34 #else
35 #include "render_context/render_context.h"
36 #endif
37 #include "transaction/rs_render_service_client.h"
38 #include "transaction/rs_transaction_proxy.h"
39 #include "ui/rs_proxy_node.h"
40
41 namespace OHOS {
42 namespace Rosen {
Create(const RSSurfaceNodeConfig & surfaceNodeConfig,bool isWindow)43 RSSurfaceNode::SharedPtr RSSurfaceNode::Create(const RSSurfaceNodeConfig& surfaceNodeConfig, bool isWindow)
44 {
45 return Create(surfaceNodeConfig, RSSurfaceNodeType::DEFAULT, isWindow);
46 }
47
Create(const RSSurfaceNodeConfig & surfaceNodeConfig,RSSurfaceNodeType type,bool isWindow)48 RSSurfaceNode::SharedPtr RSSurfaceNode::Create(const RSSurfaceNodeConfig& surfaceNodeConfig,
49 RSSurfaceNodeType type, bool isWindow)
50 {
51 auto transactionProxy = RSTransactionProxy::GetInstance();
52 if (transactionProxy == nullptr) {
53 return nullptr;
54 }
55
56 SharedPtr node(new RSSurfaceNode(surfaceNodeConfig, isWindow));
57 RSNodeMap::MutableInstance().RegisterNode(node);
58
59 // create node in RS
60 RSSurfaceRenderNodeConfig config = {
61 .id = node->GetId(),
62 .name = node->name_,
63 .bundleName = node->bundleName_,
64 .additionalData = surfaceNodeConfig.additionalData,
65 };
66 if (!isWindow) {
67 config.nodeType = RSSurfaceNodeType::SELF_DRAWING_NODE;
68 } else {
69 config.nodeType = type;
70 }
71
72 RS_LOGD("RSSurfaceNode::Create name:%s bundleName: %s type: %d",
73 config.name.c_str(), config.bundleName.c_str(), config.nodeType);
74
75 if (!node->CreateNodeAndSurface(config)) {
76 ROSEN_LOGE("RSSurfaceNode::Create, create node and surface failed");
77 return nullptr;
78 }
79
80 node->SetClipToFrame(true);
81 // create node in RT (only when in divided render and isRenderServiceNode_ == false)
82 if (!node->IsRenderServiceNode()) {
83 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeCreate>(node->GetId());
84 transactionProxy->AddCommand(command, isWindow);
85
86 command = std::make_unique<RSSurfaceNodeConnectToNodeInRenderService>(node->GetId());
87 transactionProxy->AddCommand(command, isWindow);
88
89 RSRTRefreshCallback::Instance().SetRefresh([] { RSRenderThread::Instance().RequestNextVSync(); });
90 command = std::make_unique<RSSurfaceNodeSetCallbackForRenderThreadRefresh>(node->GetId(), true);
91 transactionProxy->AddCommand(command, isWindow);
92 node->SetFrameGravity(Gravity::RESIZE);
93 }
94
95 if (node->GetName().find("battery_panel") != std::string::npos ||
96 node->GetName().find("sound_panel") != std::string::npos ||
97 node->GetName().find("RosenWeb") != std::string::npos) {
98 node->SetFrameGravity(Gravity::TOP_LEFT);
99 } else if (!isWindow) {
100 node->SetFrameGravity(Gravity::RESIZE);
101 }
102 ROSEN_LOGD("RsDebug RSSurfaceNode::Create id:%" PRIu64, node->GetId());
103 return node;
104 }
105
CreateNodeInRenderThread()106 void RSSurfaceNode::CreateNodeInRenderThread()
107 {
108 if (!IsRenderServiceNode()) {
109 ROSEN_LOGI("RsDebug RSSurfaceNode::CreateNodeInRenderThread id:%" PRIu64 " already has RT Node", GetId());
110 return;
111 }
112
113 auto transactionProxy = RSTransactionProxy::GetInstance();
114 if (transactionProxy == nullptr) {
115 return;
116 }
117
118 isChildOperationDisallowed_ = true;
119 isRenderServiceNode_ = false;
120 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetSurfaceNodeType>(GetId(),
121 static_cast<uint8_t>(RSSurfaceNodeType::ABILITY_COMPONENT_NODE));
122 transactionProxy->AddCommand(command, true);
123
124 // create node in RT (only when in divided render and isRenderServiceNode_ == false)
125 if (!IsRenderServiceNode()) {
126 command = std::make_unique<RSSurfaceNodeCreate>(GetId());
127 transactionProxy->AddCommand(command, false);
128
129 command = std::make_unique<RSSurfaceNodeConnectToNodeInRenderService>(GetId());
130 transactionProxy->AddCommand(command, false);
131
132 RSRTRefreshCallback::Instance().SetRefresh([] { RSRenderThread::Instance().RequestNextVSync(); });
133 command = std::make_unique<RSSurfaceNodeSetCallbackForRenderThreadRefresh>(GetId(), true);
134 transactionProxy->AddCommand(command, false);
135 }
136 }
137
AddChild(std::shared_ptr<RSBaseNode> child,int index)138 void RSSurfaceNode::AddChild(std::shared_ptr<RSBaseNode> child, int index)
139 {
140 if (isChildOperationDisallowed_) {
141 ROSEN_LOGE("RSSurfaceNode::AddChild for non RenderServiceNodeType surfaceNode is not allowed");
142 return;
143 }
144 RSBaseNode::AddChild(child, index);
145 }
146
RemoveChild(std::shared_ptr<RSBaseNode> child)147 void RSSurfaceNode::RemoveChild(std::shared_ptr<RSBaseNode> child)
148 {
149 if (isChildOperationDisallowed_) {
150 ROSEN_LOGE("RSSurfaceNode::RemoveChild for non RenderServiceNodeType surfaceNode is not allowed");
151 return;
152 }
153 RSBaseNode::RemoveChild(child);
154 }
155
ClearChildren()156 void RSSurfaceNode::ClearChildren()
157 {
158 if (isChildOperationDisallowed_) {
159 ROSEN_LOGE("RSSurfaceNode::ClearChildren for non RenderServiceNodeType surfaceNode is not allowed");
160 return;
161 }
162 RSBaseNode::ClearChildren();
163 }
164
GetFollowType() const165 FollowType RSSurfaceNode::GetFollowType() const
166 {
167 if (IsRenderServiceNode()) {
168 return FollowType::NONE;
169 } else {
170 return FollowType::FOLLOW_TO_PARENT;
171 }
172 }
173
MarkUIHidden(bool isHidden)174 void RSSurfaceNode::MarkUIHidden(bool isHidden)
175 {
176 auto transactionProxy = RSTransactionProxy::GetInstance();
177 if (transactionProxy == nullptr) {
178 return;
179 }
180 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeMarkUIHidden>(GetId(), isHidden);
181 transactionProxy->AddCommand(command, IsRenderServiceNode());
182 transactionProxy->FlushImplicitTransaction();
183 }
184
OnBoundsSizeChanged() const185 void RSSurfaceNode::OnBoundsSizeChanged() const
186 {
187 auto bounds = GetStagingProperties().GetBounds();
188 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeUpdateSurfaceDefaultSize>(
189 GetId(), bounds.z_, bounds.w_);
190 auto transactionProxy = RSTransactionProxy::GetInstance();
191 if (transactionProxy != nullptr) {
192 transactionProxy->AddCommand(command, true);
193 }
194 }
195
SetSecurityLayer(bool isSecurityLayer)196 void RSSurfaceNode::SetSecurityLayer(bool isSecurityLayer)
197 {
198 isSecurityLayer_ = isSecurityLayer;
199 std::unique_ptr<RSCommand> command =
200 std::make_unique<RSSurfaceNodeSetSecurityLayer>(GetId(), isSecurityLayer);
201 auto transactionProxy = RSTransactionProxy::GetInstance();
202 if (transactionProxy != nullptr) {
203 transactionProxy->AddCommand(command, true);
204 }
205 ROSEN_LOGD("RSSurfaceNode::SetSecurityLayer, surfaceNodeId:[%" PRIu64 "] isSecurityLayer:%s", GetId(),
206 isSecurityLayer ? "true" : "false");
207 }
208
GetSecurityLayer() const209 bool RSSurfaceNode::GetSecurityLayer() const
210 {
211 return isSecurityLayer_;
212 }
213
SetFingerprint(bool hasFingerprint)214 void RSSurfaceNode::SetFingerprint(bool hasFingerprint)
215 {
216 hasFingerprint_ = hasFingerprint;
217 std::unique_ptr<RSCommand> command =
218 std::make_unique<RSSurfaceNodeSetFingerprint>(GetId(), hasFingerprint);
219 auto transactionProxy = RSTransactionProxy::GetInstance();
220 if (transactionProxy != nullptr) {
221 transactionProxy->AddCommand(command, true);
222 }
223 ROSEN_LOGD("RSSurfaceNode::SetFingerprint, surfaceNodeId:[%" PRIu64 "] hasFingerprint:%s", GetId(),
224 hasFingerprint ? "true" : "false");
225 }
226
GetFingerprint() const227 bool RSSurfaceNode::GetFingerprint() const
228 {
229 return hasFingerprint_;
230 }
231
232 #ifndef ROSEN_CROSS_PLATFORM
SetColorSpace(GraphicColorGamut colorSpace)233 void RSSurfaceNode::SetColorSpace(GraphicColorGamut colorSpace)
234 {
235 colorSpace_ = colorSpace;
236 std::unique_ptr<RSCommand> command =
237 std::make_unique<RSSurfaceNodeSetColorSpace>(GetId(), colorSpace);
238 auto transactionProxy = RSTransactionProxy::GetInstance();
239 if (transactionProxy != nullptr) {
240 transactionProxy->AddCommand(command, true);
241 }
242 }
243 #endif
244
SetAbilityBGAlpha(uint8_t alpha)245 void RSSurfaceNode::SetAbilityBGAlpha(uint8_t alpha)
246 {
247 std::unique_ptr<RSCommand> command =
248 std::make_unique<RSSurfaceNodeSetAbilityBGAlpha>(GetId(), alpha);
249 auto transactionProxy = RSTransactionProxy::GetInstance();
250 if (transactionProxy != nullptr) {
251 transactionProxy->AddCommand(command, true);
252 }
253 }
254
SetIsNotifyUIBufferAvailable(bool available)255 void RSSurfaceNode::SetIsNotifyUIBufferAvailable(bool available)
256 {
257 std::unique_ptr<RSCommand> command =
258 std::make_unique<RSSurfaceNodeSetIsNotifyUIBufferAvailable>(GetId(), available);
259 auto transactionProxy = RSTransactionProxy::GetInstance();
260 if (transactionProxy != nullptr) {
261 transactionProxy->AddCommand(command, true);
262 }
263 }
264
SetBufferAvailableCallback(BufferAvailableCallback callback)265 bool RSSurfaceNode::SetBufferAvailableCallback(BufferAvailableCallback callback)
266 {
267 {
268 std::lock_guard<std::mutex> lock(mutex_);
269 callback_ = callback;
270 }
271 auto renderServiceClient =
272 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
273 if (renderServiceClient == nullptr) {
274 return false;
275 }
276 return renderServiceClient->RegisterBufferAvailableListener(GetId(), [weakThis = weak_from_this()]() {
277 auto rsSurfaceNode = RSBaseNode::ReinterpretCast<RSSurfaceNode>(weakThis.lock());
278 if (rsSurfaceNode == nullptr) {
279 ROSEN_LOGE("RSSurfaceNode::SetBufferAvailableCallback this == null");
280 return;
281 }
282 BufferAvailableCallback actualCallback;
283 {
284 std::lock_guard<std::mutex> lock(rsSurfaceNode->mutex_);
285 actualCallback = rsSurfaceNode->callback_;
286 }
287 actualCallback();
288 });
289 }
290
SetAnimationFinished()291 void RSSurfaceNode::SetAnimationFinished()
292 {
293 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetAnimationFinished>(GetId());
294 auto transactionProxy = RSTransactionProxy::GetInstance();
295 if (transactionProxy != nullptr) {
296 transactionProxy->AddCommand(command, true);
297 transactionProxy->FlushImplicitTransaction();
298 }
299 }
300
Marshalling(Parcel & parcel) const301 bool RSSurfaceNode::Marshalling(Parcel& parcel) const
302 {
303 return parcel.WriteUint64(GetId()) && parcel.WriteString(name_) && parcel.WriteBool(IsRenderServiceNode());
304 }
305
Unmarshalling(Parcel & parcel)306 std::shared_ptr<RSSurfaceNode> RSSurfaceNode::Unmarshalling(Parcel& parcel)
307 {
308 uint64_t id = UINT64_MAX;
309 std::string name;
310 bool isRenderServiceNode = false;
311 if (!(parcel.ReadUint64(id) && parcel.ReadString(name) && parcel.ReadBool(isRenderServiceNode))) {
312 ROSEN_LOGE("RSSurfaceNode::Unmarshalling, read param failed");
313 return nullptr;
314 }
315 RSSurfaceNodeConfig config = { name };
316
317 if (auto prevNode = RSNodeMap::Instance().GetNode(id)) {
318 // if the node id is already in the map, we should not create a new node
319 return prevNode->ReinterpretCastTo<RSSurfaceNode>();
320 }
321
322 SharedPtr surfaceNode(new RSSurfaceNode(config, isRenderServiceNode, id));
323 RSNodeMap::MutableInstance().RegisterNode(surfaceNode);
324
325 // for nodes constructed by unmarshalling, we should not destroy the corresponding render node on destruction
326 surfaceNode->skipDestroyCommandInDestructor_ = true;
327
328 return surfaceNode;
329 }
330
UnmarshallingAsProxyNode(Parcel & parcel)331 RSNode::SharedPtr RSSurfaceNode::UnmarshallingAsProxyNode(Parcel& parcel)
332 {
333 uint64_t id = UINT64_MAX;
334 std::string name;
335 bool isRenderServiceNode = false;
336 if (!(parcel.ReadUint64(id) && parcel.ReadString(name) && parcel.ReadBool(isRenderServiceNode))) {
337 ROSEN_LOGE("RSSurfaceNode::Unmarshalling, read param failed");
338 return nullptr;
339 }
340
341 // Create RSProxyNode by unmarshalling RSSurfaceNode, return existing node if it exists in RSNodeMap.
342 return RSProxyNode::Create(id, name);
343 }
344
CreateNode(const RSSurfaceRenderNodeConfig & config)345 bool RSSurfaceNode::CreateNode(const RSSurfaceRenderNodeConfig& config)
346 {
347 return std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient())->
348 CreateNode(config);
349 }
350
CreateNodeAndSurface(const RSSurfaceRenderNodeConfig & config)351 bool RSSurfaceNode::CreateNodeAndSurface(const RSSurfaceRenderNodeConfig& config)
352 {
353 surface_ = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient())->
354 CreateNodeAndSurface(config);
355 return (surface_ != nullptr);
356 }
357
358 #ifndef ROSEN_CROSS_PLATFORM
GetSurface() const359 sptr<OHOS::Surface> RSSurfaceNode::GetSurface() const
360 {
361 if (surface_ == nullptr) {
362 ROSEN_LOGE("RSSurfaceNode::GetSurface, surface_ is nullptr");
363 return nullptr;
364 }
365 auto ohosSurface = RSSurfaceConverter::ConvertToOhosSurface(surface_);
366 return ohosSurface;
367 }
368 #endif
369
NeedForcedSendToRemote() const370 bool RSSurfaceNode::NeedForcedSendToRemote() const
371 {
372 if (IsRenderServiceNode()) {
373 // Property message should be sent to RenderService.
374 return false;
375 } else {
376 // Only when in divided render and isRenderServiceNode_ == false
377 // property message should be sent to RenderService & RenderThread.
378 return true;
379 }
380 }
381
ResetContextAlpha() const382 void RSSurfaceNode::ResetContextAlpha() const
383 {
384 // temporarily fix: manually set contextAlpha in RT and RS to 0.0f, to avoid residual alpha/context matrix from
385 // previous animation. this value will be overwritten in RenderThreadVisitor::ProcessSurfaceRenderNode.
386 auto transactionProxy = RSTransactionProxy::GetInstance();
387 if (transactionProxy == nullptr) {
388 return;
389 }
390
391 std::unique_ptr<RSCommand> commandRS = std::make_unique<RSSurfaceNodeSetContextAlpha>(GetId(), 0.0f);
392 transactionProxy->AddCommand(commandRS, true);
393 }
394
SetContainerWindow(bool hasContainerWindow,float density)395 void RSSurfaceNode::SetContainerWindow(bool hasContainerWindow, float density)
396 {
397 std::unique_ptr<RSCommand> command =
398 std::make_unique<RSSurfaceNodeSetContainerWindow>(GetId(), hasContainerWindow, density);
399 auto transactionProxy = RSTransactionProxy::GetInstance();
400 if (transactionProxy != nullptr) {
401 transactionProxy->AddCommand(command, true);
402 }
403 }
404
SetWindowId(uint32_t windowId)405 void RSSurfaceNode::SetWindowId(uint32_t windowId)
406 {
407 windowId_ = windowId;
408 }
409
SetFreeze(bool isFreeze)410 void RSSurfaceNode::SetFreeze(bool isFreeze)
411 {
412 if (!IsUniRenderEnabled()) {
413 ROSEN_LOGE("SetFreeze is not supported in separate render");
414 return;
415 }
416 std::unique_ptr<RSCommand> command = std::make_unique<RSSetFreeze>(GetId(), isFreeze);
417 auto transactionProxy = RSTransactionProxy::GetInstance();
418 if (transactionProxy != nullptr) {
419 transactionProxy->AddCommand(command, true);
420 }
421 }
422
SplitSurfaceNodeName(std::string surfaceNodeName)423 std::pair<std::string, std::string> RSSurfaceNode::SplitSurfaceNodeName(std::string surfaceNodeName)
424 {
425 if (auto position = surfaceNodeName.find("#"); position != std::string::npos) {
426 return std::make_pair(surfaceNodeName.substr(0, position), surfaceNodeName.substr(position + 1));
427 }
428 return std::make_pair("", surfaceNodeName);
429 }
430
RSSurfaceNode(const RSSurfaceNodeConfig & config,bool isRenderServiceNode)431 RSSurfaceNode::RSSurfaceNode(const RSSurfaceNodeConfig& config, bool isRenderServiceNode)
432 : RSNode(isRenderServiceNode)
433 {
434 auto result = SplitSurfaceNodeName(config.SurfaceNodeName);
435 bundleName_ = result.first;
436 name_ = result.second;
437 }
438
RSSurfaceNode(const RSSurfaceNodeConfig & config,bool isRenderServiceNode,NodeId id)439 RSSurfaceNode::RSSurfaceNode(const RSSurfaceNodeConfig& config, bool isRenderServiceNode, NodeId id)
440 : RSNode(isRenderServiceNode, id)
441 {
442 auto result = SplitSurfaceNodeName(config.SurfaceNodeName);
443 bundleName_ = result.first;
444 name_ = result.second;
445 }
446
~RSSurfaceNode()447 RSSurfaceNode::~RSSurfaceNode()
448 {
449 auto transactionProxy = RSTransactionProxy::GetInstance();
450 if (transactionProxy == nullptr) {
451 return;
452 }
453
454 // For abilityComponent and remote window, we should destroy the corresponding render node in RenderThread
455 // The destructor of render node in RenderService should controlled by application
456 // Command sent only in divided render
457 if (skipDestroyCommandInDestructor_ && !IsUniRenderEnabled()) {
458 std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeDestroy>(GetId());
459 transactionProxy->AddCommand(command, false, FollowType::FOLLOW_TO_PARENT, GetId());
460 return;
461 }
462
463 auto renderServiceClient =
464 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
465 if (renderServiceClient != nullptr) {
466 renderServiceClient->UnregisterBufferAvailableListener(GetId());
467 }
468
469 // For self-drawing surfaceNode, we should destroy the corresponding render node in RenderService
470 // Command sent only in divided render
471 if (!IsRenderServiceNode()) {
472 std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeDestroy>(GetId());
473 transactionProxy->AddCommand(command, true, FollowType::FOLLOW_TO_PARENT, GetId());
474 return;
475 }
476 }
477
AttachToDisplay(uint64_t screenId)478 void RSSurfaceNode::AttachToDisplay(uint64_t screenId)
479 {
480 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeAttachToDisplay>(GetId(), screenId);
481 auto transactionProxy = RSTransactionProxy::GetInstance();
482 if (transactionProxy != nullptr) {
483 transactionProxy->AddCommand(command, IsRenderServiceNode());
484 }
485 }
486
DetachToDisplay(uint64_t screenId)487 void RSSurfaceNode::DetachToDisplay(uint64_t screenId)
488 {
489 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeDetachToDisplay>(GetId(), screenId);
490 auto transactionProxy = RSTransactionProxy::GetInstance();
491 if (transactionProxy != nullptr) {
492 transactionProxy->AddCommand(command, IsRenderServiceNode());
493 }
494 }
495
SetHardwareEnabled(bool isEnabled)496 void RSSurfaceNode::SetHardwareEnabled(bool isEnabled)
497 {
498 auto renderServiceClient =
499 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
500 if (renderServiceClient != nullptr) {
501 renderServiceClient->SetHardwareEnabled(GetId(), isEnabled);
502 }
503 }
504 } // namespace Rosen
505 } // namespace OHOS
506