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(¤tChildrenList_, 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