• 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_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