1 /*
2  * Copyright (c) 2021-2023 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 "pipeline/rs_display_render_node.h"
17 
18 #include "common/rs_obj_abs_geometry.h"
19 #include "common/rs_optional_trace.h"
20 #include "params/rs_display_render_params.h"
21 #include "pipeline/rs_render_node.h"
22 #include "pipeline/rs_surface_render_node.h"
23 #include "platform/common/rs_log.h"
24 #include "screen_manager/screen_types.h"
25 #include "visitor/rs_node_visitor.h"
26 #include "transaction/rs_render_service_client.h"
27 namespace OHOS {
28 namespace Rosen {
29 constexpr int64_t MAX_JITTER_NS = 2000000; // 2ms
30 
RSDisplayRenderNode(NodeId id,const RSDisplayNodeConfig & config,const std::weak_ptr<RSContext> & context)31 RSDisplayRenderNode::RSDisplayRenderNode(
32     NodeId id, const RSDisplayNodeConfig& config, const std::weak_ptr<RSContext>& context)
33     : RSRenderNode(id, context), screenId_(config.screenId), offsetX_(0), offsetY_(0),
34       isMirroredDisplay_(config.isMirrored), dirtyManager_(std::make_shared<RSDirtyRegionManager>(true))
35 {
36     RS_LOGI("RSDisplayRenderNode ctor id:%{public}" PRIu64 "", id);
37     MemoryInfo info = {sizeof(*this), ExtractPid(id), id, MEMORY_TYPE::MEM_RENDER_NODE};
38     MemoryTrack::Instance().AddNodeRecord(id, info);
39 }
40 
~RSDisplayRenderNode()41 RSDisplayRenderNode::~RSDisplayRenderNode()
42 {
43     RS_LOGI("RSDisplayRenderNode dtor id:%{public}" PRIu64 "", GetId());
44     MemoryTrack::Instance().RemoveNodeRecord(GetId());
45 }
46 
CollectSurface(const std::shared_ptr<RSBaseRenderNode> & node,std::vector<RSBaseRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)47 void RSDisplayRenderNode::CollectSurface(
48     const std::shared_ptr<RSBaseRenderNode>& node, std::vector<RSBaseRenderNode::SharedPtr>& vec, bool isUniRender,
49     bool onlyFirstLevel)
50 {
51     for (auto& child : *node->GetSortedChildren()) {
52         child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
53     }
54 }
55 
QuickPrepare(const std::shared_ptr<RSNodeVisitor> & visitor)56 void RSDisplayRenderNode::QuickPrepare(const std::shared_ptr<RSNodeVisitor>& visitor)
57 {
58     if (!visitor) {
59         return;
60     }
61     ApplyModifiers();
62     visitor->QuickPrepareDisplayRenderNode(*this);
63 }
64 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)65 void RSDisplayRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
66 {
67     if (!visitor) {
68         return;
69     }
70     ApplyModifiers();
71     visitor->PrepareDisplayRenderNode(*this);
72 }
73 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)74 void RSDisplayRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
75 {
76     if (!visitor) {
77         return;
78     }
79     RSRenderNode::RenderTraceDebug();
80     visitor->ProcessDisplayRenderNode(*this);
81 }
82 
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId,NodeId uifirstRootNodeId,NodeId displayNodeId)83 void RSDisplayRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId,
84     NodeId cacheNodeId, NodeId uifirstRootNodeId, NodeId displayNodeId)
85 {
86     // if node is marked as cacheRoot, update subtree status when update surface
87     // in case prepare stage upper cacheRoot cannot specify dirty subnode
88     RSRenderNode::SetIsOnTheTree(flag, GetId(), firstLevelNodeId, cacheNodeId, uifirstRootNodeId, GetId());
89 }
90 
GetCompositeType() const91 RSDisplayRenderNode::CompositeType RSDisplayRenderNode::GetCompositeType() const
92 {
93     return compositeType_;
94 }
95 
SetCompositeType(RSDisplayRenderNode::CompositeType type)96 void RSDisplayRenderNode::SetCompositeType(RSDisplayRenderNode::CompositeType type)
97 {
98     compositeType_ = type;
99 }
100 
SetForceSoftComposite(bool flag)101 void RSDisplayRenderNode::SetForceSoftComposite(bool flag)
102 {
103     forceSoftComposite_ = flag;
104 }
105 
IsForceSoftComposite() const106 bool RSDisplayRenderNode::IsForceSoftComposite() const
107 {
108     return forceSoftComposite_;
109 }
110 
SetMirrorSource(SharedPtr node)111 void RSDisplayRenderNode::SetMirrorSource(SharedPtr node)
112 {
113     if (!isMirroredDisplay_ || node == nullptr) {
114         return;
115     }
116     mirrorSource_ = node;
117 }
118 
ResetMirrorSource()119 void RSDisplayRenderNode::ResetMirrorSource()
120 {
121     mirrorSource_.reset();
122 }
123 
IsMirrorDisplay() const124 bool RSDisplayRenderNode::IsMirrorDisplay() const
125 {
126     return isMirroredDisplay_;
127 }
128 
SetSecurityDisplay(bool isSecurityDisplay)129 void RSDisplayRenderNode::SetSecurityDisplay(bool isSecurityDisplay)
130 {
131     isSecurityDisplay_ = isSecurityDisplay;
132 }
133 
GetSecurityDisplay() const134 bool RSDisplayRenderNode::GetSecurityDisplay() const
135 {
136     return isSecurityDisplay_;
137 }
138 
SetIsMirrorDisplay(bool isMirror)139 void RSDisplayRenderNode::SetIsMirrorDisplay(bool isMirror)
140 {
141     isMirroredDisplay_ = isMirror;
142     RS_LOGD("RSDisplayRenderNode::SetIsMirrorDisplay, node id:[%{public}" PRIu64 "], isMirrorDisplay: [%{public}s]",
143         GetId(), IsMirrorDisplay() ? "true" : "false");
144 }
145 
SetBootAnimation(bool isBootAnimation)146 void RSDisplayRenderNode::SetBootAnimation(bool isBootAnimation)
147 {
148     ROSEN_LOGD("SetBootAnimation:: id:[%{public}" PRIu64 ", isBootAnimation:%{public}d",
149         GetId(), isBootAnimation);
150     isBootAnimation_ = isBootAnimation;
151 
152     auto parent = GetParent().lock();
153     if (parent == nullptr) {
154         return;
155     }
156     if (isBootAnimation) {
157         parent->SetContainBootAnimation(true);
158     }
159 }
160 
GetBootAnimation() const161 bool RSDisplayRenderNode::GetBootAnimation() const
162 {
163     return isBootAnimation_;
164 }
165 
InitRenderParams()166 void RSDisplayRenderNode::InitRenderParams()
167 {
168     stagingRenderParams_ = std::make_unique<RSDisplayRenderParams>(GetId());
169     DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(shared_from_this());
170     if (renderDrawable_ == nullptr) {
171         RS_LOGE("RSDisplayRenderNode::InitRenderParams failed");
172         return;
173     }
174 }
175 
OnSync()176 void RSDisplayRenderNode::OnSync()
177 {
178     RS_OPTIONAL_TRACE_NAME_FMT("RSDisplayRenderNode::OnSync global dirty[%s]",
179         dirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str());
180     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
181     if (displayParams == nullptr) {
182         RS_LOGE("RSDisplayRenderNode::OnSync displayParams is null");
183         return;
184     }
185     if (!renderDrawable_) {
186         return;
187     }
188     auto syncDirtyManager = renderDrawable_->GetSyncDirtyManager();
189     dirtyManager_->OnSync(syncDirtyManager);
190     displayParams->SetZoomed(curZoomState_);
191     displayParams->SetNeedSync(true);
192     RSRenderNode::OnSync();
193     HandleCurMainAndLeashSurfaceNodes();
194 }
195 
HandleCurMainAndLeashSurfaceNodes()196 void RSDisplayRenderNode::HandleCurMainAndLeashSurfaceNodes()
197 {
198     surfaceCountForMultiLayersPerf_ = 0;
199     for (const auto& surface : curMainAndLeashSurfaceNodes_) {
200         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
201         if (!surfaceNode || surfaceNode->IsLeashWindow()) {
202             continue;
203         }
204         surfaceCountForMultiLayersPerf_++;
205     }
206     curMainAndLeashSurfaceNodes_.clear();
207 }
208 
RecordMainAndLeashSurfaces(RSBaseRenderNode::SharedPtr surface)209 void RSDisplayRenderNode::RecordMainAndLeashSurfaces(RSBaseRenderNode::SharedPtr surface)
210 {
211     curMainAndLeashSurfaceNodes_.push_back(surface);
212 }
213 
UpdateRenderParams()214 void RSDisplayRenderNode::UpdateRenderParams()
215 {
216     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
217     if (displayParams == nullptr) {
218         RS_LOGE("RSDisplayRenderNode::UpdateRenderParams displayParams is null");
219         return;
220     }
221     displayParams->offsetX_ = GetDisplayOffsetX();
222     displayParams->offsetY_ = GetDisplayOffsetY();
223     displayParams->nodeRotation_ = GetRotation();
224     auto mirroredNode = GetMirrorSource().lock();
225     if (mirroredNode) {
226         displayParams->mirrorSourceDrawable_ = mirroredNode->GetRenderDrawable();
227     }
228     displayParams->isSecurityExemption_ = isSecurityExemption_;
229     displayParams->mirrorSourceId_ = mirroredNode ? mirroredNode->GetId() : INVALID_NODEID;
230 
231     RSRenderNode::UpdateRenderParams();
232 }
233 
UpdateScreenRenderParams(ScreenRenderParams & screenRenderParams)234 void RSDisplayRenderNode::UpdateScreenRenderParams(ScreenRenderParams& screenRenderParams)
235 {
236     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
237     if (displayParams == nullptr) {
238         RS_LOGE("RSDisplayRenderNode::UpdateScreenRenderParams displayParams is null");
239         return;
240     }
241     displayParams->screenId_ = GetScreenId();
242     displayParams->screenRotation_ = GetScreenRotation();
243     displayParams->compositeType_ = GetCompositeType();
244     displayParams->isMirrorScreen_ = IsMirrorScreen();
245     displayParams->isSecurityDisplay_ = GetSecurityDisplay();
246     displayParams->screenInfo_ = std::move(screenRenderParams.screenInfo);
247     displayParams->displayHasSecSurface_ = std::move(screenRenderParams.displayHasSecSurface);
248     displayParams->displayHasSkipSurface_ = std::move(screenRenderParams.displayHasSkipSurface);
249     displayParams->displayHasProtectedSurface_ = std::move(screenRenderParams.displayHasProtectedSurface);
250     displayParams->displaySpecailSurfaceChanged_ = std::move(screenRenderParams.displaySpecailSurfaceChanged);
251     displayParams->hasCaptureWindow_ = std::move(screenRenderParams.hasCaptureWindow);
252 }
253 
UpdateOffscreenRenderParams(bool needOffscreen)254 void RSDisplayRenderNode::UpdateOffscreenRenderParams(bool needOffscreen)
255 {
256     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
257     if (displayParams == nullptr) {
258         RS_LOGE("RSDisplayRenderNode::UpdateOffscreenRenderParams displayParams is null");
259         return;
260     }
261     displayParams->SetNeedOffscreen(needOffscreen);
262 }
263 
UpdatePartialRenderParams()264 void RSDisplayRenderNode::UpdatePartialRenderParams()
265 {
266     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
267     if (displayParams == nullptr) {
268         RS_LOGE("RSDisplayRenderNode::UpdatePartialRenderParams displayParams is null");
269         return;
270     }
271     displayParams->SetAllMainAndLeashSurfaces(curMainAndLeashSurfaceNodes_);
272 }
273 
SkipFrame(uint32_t refreshRate,uint32_t skipFrameInterval)274 bool RSDisplayRenderNode::SkipFrame(uint32_t refreshRate, uint32_t skipFrameInterval)
275 {
276     if (refreshRate == 0 || skipFrameInterval <= 1) {
277         return false;
278     }
279     int64_t currentTime = std::chrono::duration_cast<std::chrono::nanoseconds>(
280         std::chrono::steady_clock::now().time_since_epoch()).count();
281     // when refreshRate % skipFrameInterval != 0 means the skipFrameInterval is the virtual screen refresh rate
282     if (refreshRate % skipFrameInterval != 0) {
283         int64_t minFrameInterval = 1000000000LL / skipFrameInterval;
284         if (minFrameInterval == 0) {
285             return false;
286         }
287         // lastRefreshTime_ is next frame expected refresh time for virtual display
288         if (lastRefreshTime_ <= 0) {
289             lastRefreshTime_ = currentTime + minFrameInterval;
290             return false;
291         }
292         if (currentTime < (lastRefreshTime_ - MAX_JITTER_NS)) {
293             return true;
294         }
295         int64_t intervalNums = (currentTime - lastRefreshTime_ + MAX_JITTER_NS) / minFrameInterval;
296         lastRefreshTime_ += (intervalNums + 1) * minFrameInterval;
297         return false;
298     }
299     // the skipFrameInterval is equal to 60 divide the virtual screen refresh rate
300     int64_t refreshInterval = currentTime - lastRefreshTime_;
301     // 1000000000ns == 1s, 110/100 allows 10% over.
302     bool needSkip = refreshInterval < (1000000000LL / refreshRate) * (skipFrameInterval - 1) * 110 / 100;
303     if (!needSkip) {
304         lastRefreshTime_ = currentTime;
305     }
306     return needSkip;
307 }
308 
SetDisplayGlobalZOrder(float zOrder)309 void RSDisplayRenderNode::SetDisplayGlobalZOrder(float zOrder)
310 {
311     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
312     if (displayParams == nullptr) {
313         RS_LOGE("RSDisplayRenderNode::SetDisplayGlobalZOrder displayParams is null");
314         return;
315     }
316     displayParams->SetGlobalZOrder(zOrder);
317 }
318 
319 
GetRotation() const320 ScreenRotation RSDisplayRenderNode::GetRotation() const
321 {
322     auto& boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
323     if (boundsGeoPtr == nullptr) {
324         return ScreenRotation::ROTATION_0;
325     }
326     // -90.0f: convert rotation degree to 4 enum values
327     return static_cast<ScreenRotation>(static_cast<int32_t>(std::roundf(boundsGeoPtr->GetRotation() / -90.0f)) % 4);
328 }
329 
IsRotationChanged() const330 bool RSDisplayRenderNode::IsRotationChanged() const
331 {
332     auto& boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
333     if (boundsGeoPtr == nullptr) {
334         return false;
335     }
336     // boundsGeoPtr->IsNeedClientCompose() return false if rotation degree is times of 90
337     // which means rotation is end.
338     bool isRotationEnd = !boundsGeoPtr->IsNeedClientCompose();
339     return !(ROSEN_EQ(boundsGeoPtr->GetRotation(), lastRotation_) && isRotationEnd);
340 }
341 
UpdateRotation()342 void RSDisplayRenderNode::UpdateRotation()
343 {
344     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
345     if (displayParams == nullptr) {
346         RS_LOGE("%{public}s displayParams is nullptr", __func__);
347         return;
348     }
349     AddToPendingSyncList();
350 
351     auto& boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
352     if (boundsGeoPtr == nullptr) {
353         return;
354     }
355     lastRotationChanged = IsRotationChanged();
356     lastRotation_ = boundsGeoPtr->GetRotation();
357     preRotationStatus_ = curRotationStatus_;
358     curRotationStatus_ = IsRotationChanged();
359     displayParams->SetRotationChanged(curRotationStatus_);
360 }
361 
UpdateDisplayDirtyManager(int32_t bufferage,bool useAlignedDirtyRegion)362 void RSDisplayRenderNode::UpdateDisplayDirtyManager(int32_t bufferage, bool useAlignedDirtyRegion)
363 {
364     dirtyManager_->SetBufferAge(bufferage);
365     dirtyManager_->UpdateDirty(useAlignedDirtyRegion);
366 }
367 
ClearCurrentSurfacePos()368 void RSDisplayRenderNode::ClearCurrentSurfacePos()
369 {
370     lastFrameSurfacePos_ = std::move(currentFrameSurfacePos_);
371     lastFrameSurfacesByDescZOrder_ = std::move(currentFrameSurfacesByDescZOrder_);
372 }
373 
SetMainAndLeashSurfaceDirty(bool isDirty)374 void RSDisplayRenderNode::SetMainAndLeashSurfaceDirty(bool isDirty)
375 {
376     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
377     if (displayParams == nullptr) {
378         RS_LOGE("%{public}s displayParams is nullptr", __func__);
379         return;
380     }
381     displayParams->SetMainAndLeashSurfaceDirty(isDirty);
382     if (stagingRenderParams_->NeedSync()) {
383         AddToPendingSyncList();
384     }
385 }
386 
SetHDRPresent(bool hdrPresent)387 void RSDisplayRenderNode::SetHDRPresent(bool hdrPresent)
388 {
389     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
390     if (displayParams == nullptr) {
391         RS_LOGE("%{public}s displayParams is nullptr", __func__);
392         return;
393     }
394     displayParams->SetHDRPresent(hdrPresent);
395     if (stagingRenderParams_->NeedSync()) {
396         AddToPendingSyncList();
397     }
398 }
399 
SetBrightnessRatio(float brightnessRatio)400 void RSDisplayRenderNode::SetBrightnessRatio(float brightnessRatio)
401 {
402     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
403     displayParams->SetBrightnessRatio(brightnessRatio);
404     if (stagingRenderParams_->NeedSync()) {
405         AddToPendingSyncList();
406     }
407 }
408 
SetColorSpace(const GraphicColorGamut & colorSpace)409 void RSDisplayRenderNode::SetColorSpace(const GraphicColorGamut& colorSpace)
410 {
411     auto displayParams = static_cast<RSDisplayRenderParams*>(stagingRenderParams_.get());
412     if (displayParams == nullptr) {
413         RS_LOGE("%{public}s displayParams is nullptr", __func__);
414         return;
415     }
416     displayParams->SetNewColorSpace(colorSpace);
417     if (stagingRenderParams_->NeedSync()) {
418         AddToPendingSyncList();
419     }
420     colorSpace_ = colorSpace;
421 }
422 
GetColorSpace() const423 GraphicColorGamut RSDisplayRenderNode::GetColorSpace() const
424 {
425     return colorSpace_;
426 }
427 
GetSortedChildren() const428 RSRenderNode::ChildrenListSharedPtr RSDisplayRenderNode::GetSortedChildren() const
429 {
430     int32_t currentScbPid = GetCurrentScbPid();
431     ChildrenListSharedPtr fullChildrenList = RSRenderNode::GetSortedChildren();
432     if (currentScbPid < 0) {
433         return fullChildrenList;
434     }
435     if (isNeedWaitNewScbPid_) {
436         for (auto it = (*fullChildrenList).rbegin(); it != (*fullChildrenList).rend(); ++it) {
437             auto& child = *it;
438             auto childPid = ExtractPid(child->GetId());
439             if (childPid == currentScbPid) {
440                 RS_LOGI("child scb pid equals current scb pid");
441                 isNeedWaitNewScbPid_ = false;
442                 break;
443             }
444         }
445     }
446     if (isNeedWaitNewScbPid_) {
447         return fullChildrenList;
448     }
449     std::vector<int32_t> oldScbPids = GetOldScbPids();
450     currentChildrenList_->clear();
451     for (auto& child : *fullChildrenList) {
452         if (child == nullptr) {
453             continue;
454         }
455         auto childPid = ExtractPid(child->GetId());
456         auto pidIter = std::find(oldScbPids.begin(), oldScbPids.end(), childPid);
457         if (pidIter != oldScbPids.end()) {
458             child->SetIsOntheTreeOnlyFlag(false);
459             continue;
460         } else if (childPid == currentScbPid) {
461             child->SetIsOntheTreeOnlyFlag(true);
462         }
463         currentChildrenList_->emplace_back(child);
464     }
465     return std::atomic_load_explicit(&currentChildrenList_, std::memory_order_acquire);
466 }
467 
GetDisappearedSurfaceRegionBelowCurrent(NodeId currentSurface) const468 Occlusion::Region RSDisplayRenderNode::GetDisappearedSurfaceRegionBelowCurrent(NodeId currentSurface) const
469 {
470     Occlusion::Region result;
471     auto it = std::find_if(lastFrameSurfacesByDescZOrder_.begin(), lastFrameSurfacesByDescZOrder_.end(),
472         [currentSurface](const std::pair<NodeId, RectI>& surface) { return surface.first == currentSurface; });
473     if (it == lastFrameSurfacesByDescZOrder_.end()) {
474         return result;
475     }
476 
477     for (++it; it != lastFrameSurfacesByDescZOrder_.end(); ++it) {
478         if (currentFrameSurfacePos_.count(it->first) != 0) {
479             break;
480         }
481         Occlusion::Region disappearedSurface{ Occlusion::Rect{ it->second } };
482         result.OrSelf(disappearedSurface);
483     }
484     return result;
485 }
486 
IsZoomStateChange() const487 bool RSDisplayRenderNode::IsZoomStateChange() const
488 {
489     return preZoomState_ != curZoomState_;
490 }
491 } // namespace Rosen
492 } // namespace OHOS
493