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