1 /*
2 * Copyright (c) 2025 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 "rs_trace.h"
17
18 #include "pipeline/rs_logical_display_render_node.h"
19 #include "params/rs_logical_display_render_params.h"
20 #include "visitor/rs_node_visitor.h"
21
22 namespace OHOS::Rosen {
RSLogicalDisplayRenderNode(NodeId id,const RSDisplayNodeConfig & config,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)23 RSLogicalDisplayRenderNode::RSLogicalDisplayRenderNode(NodeId id,
24 const RSDisplayNodeConfig& config, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
25 : RSRenderNode(id, context, isTextureExportNode), screenId_(config.screenId) {}
26
~RSLogicalDisplayRenderNode()27 RSLogicalDisplayRenderNode::~RSLogicalDisplayRenderNode()
28 {
29 RS_LOGI("%{public}s, NodeId:[%{public}" PRIu64 "]", __func__, GetId());
30 }
31
InitRenderParams()32 void RSLogicalDisplayRenderNode::InitRenderParams()
33 {
34 stagingRenderParams_ = std::make_unique<RSLogicalDisplayRenderParams>(GetId());
35 DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(shared_from_this());
36 if (renderDrawable_ == nullptr) {
37 RS_LOGE("RSLogicalDisplayRenderNode::InitRenderParams failed");
38 return;
39 }
40 }
41
OnSync()42 void RSLogicalDisplayRenderNode::OnSync()
43 {
44 RSRenderNode::OnSync();
45 }
46
QuickPrepare(const std::shared_ptr<RSNodeVisitor> & visitor)47 void RSLogicalDisplayRenderNode::QuickPrepare(const std::shared_ptr<RSNodeVisitor>& visitor)
48 {
49 if (!visitor) {
50 return;
51 }
52 ApplyModifiers();
53 visitor->QuickPrepareLogicalDisplayRenderNode(*this);
54 }
55
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)56 void RSLogicalDisplayRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
57 {
58 if (!visitor) {
59 return;
60 }
61 ApplyModifiers();
62 visitor->PrepareLogicalDisplayRenderNode(*this);
63 }
64
Process(const std::shared_ptr<RSNodeVisitor> & visitor)65 void RSLogicalDisplayRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
66 {
67 if (!visitor) {
68 return;
69 }
70 RSRenderNode::RenderTraceDebug();
71 visitor->ProcessLogicalDisplayRenderNode(*this);
72 }
73
UpdateRenderParams()74 void RSLogicalDisplayRenderNode::UpdateRenderParams()
75 {
76 auto logicalDisplayRenderParam = static_cast<RSLogicalDisplayRenderParams*>(stagingRenderParams_.get());
77 if (logicalDisplayRenderParam == nullptr) {
78 RS_LOGE("RSLogicalDisplayRenderNode::UpdateRenderParams logicalDisplayRenderParam is null");
79 return;
80 }
81 logicalDisplayRenderParam->screenId_ = screenId_;
82 logicalDisplayRenderParam->SetTopSurfaceOpaqueRects(std::move(topSurfaceOpaqueRects_));
83 logicalDisplayRenderParam->screenRotation_ = GetScreenRotation();
84 logicalDisplayRenderParam->nodeRotation_ = GetRotation();
85 logicalDisplayRenderParam->isMirrorDisplay_ = IsMirrorDisplay();
86 auto mirroredNode = GetMirrorSource().lock();
87 if (mirroredNode) {
88 logicalDisplayRenderParam->mirrorSourceDrawable_ = mirroredNode->GetRenderDrawable();
89 logicalDisplayRenderParam->virtualScreenMuteStatus_ = virtualScreenMuteStatus_;
90 } else {
91 logicalDisplayRenderParam->mirrorSourceDrawable_.reset();
92 }
93 logicalDisplayRenderParam->isSecurityDisplay_ = GetSecurityDisplay();
94 logicalDisplayRenderParam->specialLayerManager_ = specialLayerManager_;
95 logicalDisplayRenderParam->displaySpecialSurfaceChanged_ = displaySpecialSurfaceChanged_;
96 logicalDisplayRenderParam->isSecurityExemption_ = isSecurityExemption_;
97 logicalDisplayRenderParam->hasSecLayerInVisibleRect_ = hasSecLayerInVisibleRect_;
98 logicalDisplayRenderParam->compositeType_ = compositeType_;
99 logicalDisplayRenderParam->hasSecLayerInVisibleRectChanged_ = hasSecLayerInVisibleRectChanged_;
100 logicalDisplayRenderParam->hasCaptureWindow_ = hasCaptureWindow_;
101 auto screenNode = GetParent().lock();
102 auto screenDrawable = screenNode ? screenNode->GetRenderDrawable() : nullptr;
103 logicalDisplayRenderParam->SetAncestorScreenDrawable(screenDrawable);
104 auto& boundGeo = GetRenderProperties().GetBoundsGeometry();
105 if (boundGeo) {
106 logicalDisplayRenderParam->offsetX_ = boundGeo->GetX();
107 logicalDisplayRenderParam->offsetY_ = boundGeo->GetY();
108 }
109 RSRenderNode::UpdateRenderParams();
110 }
111
GetTopSurfaceOpaqueRegion() const112 Occlusion::Region RSLogicalDisplayRenderNode::GetTopSurfaceOpaqueRegion() const
113 {
114 Occlusion::Region topSurfaceOpaqueRegion;
115 for (const auto& rect : topSurfaceOpaqueRects_) {
116 topSurfaceOpaqueRegion.OrSelf(rect);
117 }
118 return topSurfaceOpaqueRegion;
119 }
120
GetSortedChildren() const121 RSRenderNode::ChildrenListSharedPtr RSLogicalDisplayRenderNode::GetSortedChildren() const
122 {
123 int32_t currentScbPid = GetCurrentScbPid();
124 ChildrenListSharedPtr fullChildrenList = RSRenderNode::GetSortedChildren();
125 if (currentScbPid < 0) {
126 return fullChildrenList;
127 }
128 if (isNeedWaitNewScbPid_) {
129 for (auto it = (*fullChildrenList).rbegin(); it != (*fullChildrenList).rend(); ++it) {
130 auto& child = *it;
131 auto childPid = ExtractPid(child->GetId());
132 if (childPid == currentScbPid) {
133 RS_LOGI("child scb pid equals current scb pid and set valid false");
134 isNeedWaitNewScbPid_ = false;
135 break;
136 }
137 }
138 }
139 if (isNeedWaitNewScbPid_ && lastScbPid_ < 0) {
140 return fullChildrenList;
141 }
142 std::vector<int32_t> oldScbPids = GetOldScbPids();
143 currentChildrenList_->clear();
144 for (auto& child : *fullChildrenList) {
145 if (child == nullptr) {
146 continue;
147 }
148 auto childPid = ExtractPid(child->GetId());
149 auto pidIter = std::find(oldScbPids.begin(), oldScbPids.end(), childPid);
150 // only when isNeedWaitNewScbPid_ is ture, put lastScb's child to currentChildrenList_
151 if (pidIter != oldScbPids.end() && (!isNeedWaitNewScbPid_ || childPid != lastScbPid_)) {
152 child->SetIsOntheTreeOnlyFlag(false);
153 continue;
154 } else if (childPid == currentScbPid) {
155 child->SetIsOntheTreeOnlyFlag(true);
156 }
157 currentChildrenList_->emplace_back(child);
158 }
159 return std::atomic_load_explicit(¤tChildrenList_, std::memory_order_acquire);
160 }
161
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId,NodeId uifirstRootNodeId,NodeId screenNodeId,NodeId logicalDisplayNodeId)162 void RSLogicalDisplayRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId,
163 NodeId cacheNodeId, NodeId uifirstRootNodeId, NodeId screenNodeId, NodeId logicalDisplayNodeId)
164 {
165 // if node is marked as cacheRoot, update subtree status when update surface
166 // in case prepare stage upper cacheRoot cannot specify dirty subnode
167 RSRenderNode::SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId, uifirstRootNodeId,
168 screenNodeId, GetId());
169 }
170
SetWindowContainer(std::shared_ptr<RSBaseRenderNode> container)171 void RSLogicalDisplayRenderNode::SetWindowContainer(std::shared_ptr<RSBaseRenderNode> container)
172 {
173 if (auto oldContainer = std::exchange(windowContainer_, container)) {
174 if (container) {
175 RS_LOGD("RSLogicalDisplayRenderNode::SetWindowContainer oldContainer: %{public}" PRIu64
176 ", newContainer: %{public}" PRIu64, oldContainer->GetId(), container->GetId());
177 } else {
178 RS_LOGD("RSLogicalDisplayRenderNode::SetWindowContainer oldContainer: %{public}" PRIu64,
179 oldContainer->GetId());
180 }
181 }
182 }
183
GetWindowContainer() const184 std::shared_ptr<RSBaseRenderNode> RSLogicalDisplayRenderNode::GetWindowContainer() const
185 {
186 return windowContainer_;
187 }
188
SetScreenStatusNotifyTask(ScreenStatusNotifyTask task)189 void RSLogicalDisplayRenderNode::SetScreenStatusNotifyTask(ScreenStatusNotifyTask task)
190 {
191 screenStatusNotifyTask_ = task;
192 }
193
NotifyScreenNotSwitching()194 void RSLogicalDisplayRenderNode::NotifyScreenNotSwitching()
195 {
196 if (screenStatusNotifyTask_) {
197 screenStatusNotifyTask_(false);
198 ROSEN_LOGI("RSLogicalDisplayRenderNode::NotifyScreenNotSwitching SetScreenSwitchStatus false");
199 RS_TRACE_NAME_FMT("NotifyScreenNotSwitching");
200 }
201 }
202
GetRotation() const203 ScreenRotation RSLogicalDisplayRenderNode::GetRotation() const
204 {
205 auto& boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
206 if (boundsGeoPtr == nullptr) {
207 return ScreenRotation::ROTATION_0;
208 }
209 // -90.0f: convert rotation degree to 4 enum values
210 return static_cast<ScreenRotation>(static_cast<int32_t>(std::roundf(boundsGeoPtr->GetRotation() / -90.0f)) % 4);
211 }
212
IsRotationChanged() const213 bool RSLogicalDisplayRenderNode::IsRotationChanged() const
214 {
215 auto& boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
216 if (boundsGeoPtr == nullptr) {
217 return false;
218 }
219 // boundsGeoPtr->IsNeedClientCompose() return false if rotation degree is times of 90
220 // which means rotation is end.
221 bool isRotationEnd = !boundsGeoPtr->IsNeedClientCompose();
222 return !(ROSEN_EQ(boundsGeoPtr->GetRotation(), lastRotation_) && isRotationEnd);
223 }
224
UpdateRotation()225 void RSLogicalDisplayRenderNode::UpdateRotation()
226 {
227 #ifdef RS_ENABLE_GPU
228 auto displayParams = static_cast<RSLogicalDisplayRenderParams*>(stagingRenderParams_.get());
229 if (displayParams == nullptr) {
230 RS_LOGE("%{public}s displayParams is nullptr", __func__);
231 return;
232 }
233 AddToPendingSyncList();
234
235 auto& boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
236 if (boundsGeoPtr == nullptr) {
237 return;
238 }
239 lastRotationChanged_ = IsRotationChanged();
240 lastRotation_ = boundsGeoPtr->GetRotation();
241 preRotationStatus_ = curRotationStatus_;
242 curRotationStatus_ = IsRotationChanged();
243 displayParams->SetRotationChanged(curRotationStatus_);
244 #endif
245 }
246
IsLastRotationChanged() const247 bool RSLogicalDisplayRenderNode::IsLastRotationChanged() const
248 {
249 return lastRotationChanged_;
250 }
251
GetPreRotationStatus() const252 bool RSLogicalDisplayRenderNode::GetPreRotationStatus() const
253 {
254 return preRotationStatus_;
255 }
256
GetCurRotationStatus() const257 bool RSLogicalDisplayRenderNode::GetCurRotationStatus() const
258 {
259 return curRotationStatus_;
260 }
261
UpdateOffscreenRenderParams(bool needOffscreen)262 void RSLogicalDisplayRenderNode::UpdateOffscreenRenderParams(bool needOffscreen)
263 {
264 auto displayParams = static_cast<RSLogicalDisplayRenderParams*>(stagingRenderParams_.get());
265 if (displayParams == nullptr) {
266 RS_LOGE("RSLogicalDisplayRenderNode::UpdateOffscreenRenderParams displayParams is null");
267 return;
268 }
269 displayParams->SetNeedOffscreen(needOffscreen);
270 }
271
SetSecurityDisplay(bool isSecurityDisplay)272 void RSLogicalDisplayRenderNode::SetSecurityDisplay(bool isSecurityDisplay)
273 {
274 isSecurityDisplay_ = isSecurityDisplay;
275 }
276
GetSecurityDisplay() const277 bool RSLogicalDisplayRenderNode::GetSecurityDisplay() const
278 {
279 return isSecurityDisplay_;
280 }
281
SetMirrorSource(SharedPtr node)282 void RSLogicalDisplayRenderNode::SetMirrorSource(SharedPtr node)
283 {
284 if (!isMirrorDisplay_ || node == nullptr) {
285 return;
286 }
287 mirrorSource_ = node;
288 }
289
ResetMirrorSource()290 void RSLogicalDisplayRenderNode::ResetMirrorSource()
291 {
292 mirrorSource_.reset();
293 }
294
GetMirrorSource() const295 RSLogicalDisplayRenderNode::WeakPtr RSLogicalDisplayRenderNode::GetMirrorSource() const
296 {
297 return mirrorSource_;
298 }
299
SetIsMirrorDisplay(bool isMirror)300 void RSLogicalDisplayRenderNode::SetIsMirrorDisplay(bool isMirror)
301 {
302 if (isMirrorDisplay_ != isMirror) {
303 isMirrorDisplayChanged_ = true;
304 }
305 isMirrorDisplay_ = isMirror;
306 RS_TRACE_NAME_FMT("RSLogicalDisplayRenderNode::SetIsMirrorDisplay, node id:[%" PRIu64 "], isMirrorDisplay: [%d]",
307 GetId(), IsMirrorDisplay());
308 RS_LOGI("RSLogicalDisplayRenderNode::SetIsMirrorDisplay, node id:[%{public}" PRIu64
309 "], isMirrorDisplay: [%{public}d]", GetId(), IsMirrorDisplay());
310 }
311
IsMirrorDisplay() const312 bool RSLogicalDisplayRenderNode::IsMirrorDisplay() const
313 {
314 return isMirrorDisplay_;
315 }
316
IsMirrorDisplayChanged() const317 bool RSLogicalDisplayRenderNode::IsMirrorDisplayChanged() const
318 {
319 return isMirrorDisplayChanged_;
320 }
321
ResetMirrorDisplayChangedFlag()322 void RSLogicalDisplayRenderNode::ResetMirrorDisplayChangedFlag()
323 {
324 isMirrorDisplayChanged_ = false;
325 }
326
SetVirtualScreenMuteStatus(bool virtualScreenMuteStatus)327 void RSLogicalDisplayRenderNode::SetVirtualScreenMuteStatus(bool virtualScreenMuteStatus)
328 {
329 virtualScreenMuteStatus_ = virtualScreenMuteStatus;
330 }
331
GetVirtualScreenMuteStatus() const332 bool RSLogicalDisplayRenderNode::GetVirtualScreenMuteStatus() const
333 {
334 return virtualScreenMuteStatus_;
335 }
336
SetDisplaySpecialSurfaceChanged(bool displaySpecialSurfaceChanged)337 void RSLogicalDisplayRenderNode::SetDisplaySpecialSurfaceChanged(bool displaySpecialSurfaceChanged)
338 {
339 displaySpecialSurfaceChanged_ = displaySpecialSurfaceChanged;
340 }
341
GetMultableSpecialLayerMgr()342 RSSpecialLayerManager& RSLogicalDisplayRenderNode::GetMultableSpecialLayerMgr()
343 {
344 return specialLayerManager_;
345 }
346
GetSpecialLayerMgr() const347 const RSSpecialLayerManager& RSLogicalDisplayRenderNode::GetSpecialLayerMgr() const
348 {
349 return specialLayerManager_;
350 }
351
AddSecurityLayer(NodeId id)352 void RSLogicalDisplayRenderNode::AddSecurityLayer(NodeId id)
353 {
354 securityLayerList_.emplace_back(id);
355 }
356
ClearSecurityLayerList()357 void RSLogicalDisplayRenderNode::ClearSecurityLayerList()
358 {
359 securityLayerList_.clear();
360 }
361
GetSecurityLayerList()362 const std::vector<NodeId>& RSLogicalDisplayRenderNode::GetSecurityLayerList()
363 {
364 return securityLayerList_;
365 }
366
AddSecurityVisibleLayer(NodeId id)367 void RSLogicalDisplayRenderNode::AddSecurityVisibleLayer(NodeId id)
368 {
369 securityVisibleLayerList_.emplace_back(id);
370 }
371
ClearSecurityVisibleLayerList()372 void RSLogicalDisplayRenderNode::ClearSecurityVisibleLayerList()
373 {
374 securityVisibleLayerList_.clear();
375 }
376
GetSecurityVisibleLayerList()377 const std::vector<NodeId>& RSLogicalDisplayRenderNode::GetSecurityVisibleLayerList()
378 {
379 return securityVisibleLayerList_;
380 }
381
SetSecurityExemption(bool isSecurityExemption)382 void RSLogicalDisplayRenderNode::SetSecurityExemption(bool isSecurityExemption)
383 {
384 isSecurityExemption_ = isSecurityExemption;
385 }
386
GetSecurityExemption() const387 bool RSLogicalDisplayRenderNode::GetSecurityExemption() const
388 {
389 return isSecurityExemption_;
390 }
391
SetHasSecLayerInVisibleRect(bool hasSecLayer)392 void RSLogicalDisplayRenderNode::SetHasSecLayerInVisibleRect(bool hasSecLayer)
393 {
394 bool lastHasSecLayerInVisibleRect = hasSecLayerInVisibleRect_;
395 hasSecLayerInVisibleRect_ = hasSecLayer;
396 hasSecLayerInVisibleRectChanged_ =
397 lastHasSecLayerInVisibleRect != hasSecLayerInVisibleRect_;
398 }
399
GetCompositeType() const400 CompositeType RSLogicalDisplayRenderNode::GetCompositeType() const
401 {
402 return compositeType_;
403 }
404
SetCompositeType(CompositeType type)405 void RSLogicalDisplayRenderNode::SetCompositeType(CompositeType type)
406 {
407 compositeType_ = type;
408 }
409
410 } // namespace OHOS::Rosen
411