• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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