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