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 "platform/common/rs_log.h"
20 #include "screen_manager/screen_types.h"
21 #include "visitor/rs_node_visitor.h"
22 #include "transaction/rs_render_service_client.h"
23
24 namespace OHOS {
25 namespace Rosen {
RSDisplayRenderNode(NodeId id,const RSDisplayNodeConfig & config,const std::weak_ptr<RSContext> & context)26 RSDisplayRenderNode::RSDisplayRenderNode(
27 NodeId id, const RSDisplayNodeConfig& config, const std::weak_ptr<RSContext>& context)
28 : RSRenderNode(id, context), RSSurfaceHandler(id), screenId_(config.screenId), offsetX_(0), offsetY_(0),
29 isMirroredDisplay_(config.isMirrored), dirtyManager_(std::make_shared<RSDirtyRegionManager>(true))
30 {
31 RS_LOGI("RSDisplayRenderNode ctor id:%{public}" PRIu64 "", id);
32 MemoryInfo info = {sizeof(*this), ExtractPid(id), id, MEMORY_TYPE::MEM_RENDER_NODE};
33 MemoryTrack::Instance().AddNodeRecord(id, info);
34 }
35
~RSDisplayRenderNode()36 RSDisplayRenderNode::~RSDisplayRenderNode()
37 {
38 RS_LOGI("RSDisplayRenderNode dtor id:%{public}" PRIu64 "", GetId());
39 MemoryTrack::Instance().RemoveNodeRecord(GetId());
40 }
41
CollectSurface(const std::shared_ptr<RSBaseRenderNode> & node,std::vector<RSBaseRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)42 void RSDisplayRenderNode::CollectSurface(
43 const std::shared_ptr<RSBaseRenderNode>& node, std::vector<RSBaseRenderNode::SharedPtr>& vec, bool isUniRender,
44 bool onlyFirstLevel)
45 {
46 for (auto& child : *node->GetSortedChildren()) {
47 child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
48 }
49 }
50
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)51 void RSDisplayRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
52 {
53 if (!visitor) {
54 return;
55 }
56 visitor->PrepareDisplayRenderNode(*this);
57 }
58
Process(const std::shared_ptr<RSNodeVisitor> & visitor)59 void RSDisplayRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
60 {
61 if (!visitor) {
62 return;
63 }
64 RSRenderNode::RenderTraceDebug();
65 visitor->ProcessDisplayRenderNode(*this);
66 }
67
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId)68 void RSDisplayRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId,
69 NodeId cacheNodeId)
70 {
71 // if node is marked as cacheRoot, update subtree status when update surface
72 // in case prepare stage upper cacheRoot cannot specify dirty subnode
73 RSRenderNode::SetIsOnTheTree(flag, GetId(), firstLevelNodeId, cacheNodeId);
74 }
75
GetCompositeType() const76 RSDisplayRenderNode::CompositeType RSDisplayRenderNode::GetCompositeType() const
77 {
78 return compositeType_;
79 }
80
SetCompositeType(RSDisplayRenderNode::CompositeType type)81 void RSDisplayRenderNode::SetCompositeType(RSDisplayRenderNode::CompositeType type)
82 {
83 compositeType_ = type;
84 }
85
SetForceSoftComposite(bool flag)86 void RSDisplayRenderNode::SetForceSoftComposite(bool flag)
87 {
88 forceSoftComposite_ = flag;
89 }
90
IsForceSoftComposite() const91 bool RSDisplayRenderNode::IsForceSoftComposite() const
92 {
93 return forceSoftComposite_;
94 }
95
SetMirrorSource(SharedPtr node)96 void RSDisplayRenderNode::SetMirrorSource(SharedPtr node)
97 {
98 if (!isMirroredDisplay_ || node == nullptr) {
99 return;
100 }
101 mirrorSource_ = node;
102 }
103
ResetMirrorSource()104 void RSDisplayRenderNode::ResetMirrorSource()
105 {
106 mirrorSource_.reset();
107 }
108
IsMirrorDisplay() const109 bool RSDisplayRenderNode::IsMirrorDisplay() const
110 {
111 return isMirroredDisplay_;
112 }
113
SetSecurityDisplay(bool isSecurityDisplay)114 void RSDisplayRenderNode::SetSecurityDisplay(bool isSecurityDisplay)
115 {
116 isSecurityDisplay_ = isSecurityDisplay;
117 }
118
GetSecurityDisplay() const119 bool RSDisplayRenderNode::GetSecurityDisplay() const
120 {
121 return isSecurityDisplay_;
122 }
123
SetIsMirrorDisplay(bool isMirror)124 void RSDisplayRenderNode::SetIsMirrorDisplay(bool isMirror)
125 {
126 isMirroredDisplay_ = isMirror;
127 RS_LOGD("RSDisplayRenderNode::SetIsMirrorDisplay, node id:[%{public}" PRIu64 "], isMirrorDisplay: [%{public}s]",
128 GetId(), IsMirrorDisplay() ? "true" : "false");
129 }
130
SetBootAnimation(bool isBootAnimation)131 void RSDisplayRenderNode::SetBootAnimation(bool isBootAnimation)
132 {
133 ROSEN_LOGD("SetBootAnimation:: id:[%{public}" PRIu64 ", isBootAnimation:%{public}d",
134 GetId(), isBootAnimation);
135 isBootAnimation_ = isBootAnimation;
136
137 auto parent = GetParent().lock();
138 if (parent == nullptr) {
139 return;
140 }
141 if (isBootAnimation) {
142 parent->SetContainBootAnimation(true);
143 }
144 }
145
GetBootAnimation() const146 bool RSDisplayRenderNode::GetBootAnimation() const
147 {
148 return isBootAnimation_;
149 }
150
151 #ifndef ROSEN_CROSS_PLATFORM
CreateSurface(sptr<IBufferConsumerListener> listener)152 bool RSDisplayRenderNode::CreateSurface(sptr<IBufferConsumerListener> listener)
153 {
154 if (consumer_ != nullptr && surface_ != nullptr) {
155 RS_LOGI("RSDisplayRenderNode::CreateSurface already created, return");
156 return true;
157 }
158 consumer_ = IConsumerSurface::Create("DisplayNode");
159 if (consumer_ == nullptr) {
160 RS_LOGE("RSDisplayRenderNode::CreateSurface get consumer surface fail");
161 return false;
162 }
163 SurfaceError ret = consumer_->RegisterConsumerListener(listener);
164 if (ret != SURFACE_ERROR_OK) {
165 RS_LOGE("RSDisplayRenderNode::CreateSurface RegisterConsumerListener fail");
166 return false;
167 }
168 consumerListener_ = listener;
169 auto producer = consumer_->GetProducer();
170 sptr<Surface> surface = Surface::CreateSurfaceAsProducer(producer);
171 surface->SetQueueSize(4); // 4 Buffer rotation
172 auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
173 surface_ = client->CreateRSSurface(surface);
174 RS_LOGI("RSDisplayRenderNode::CreateSurface end");
175 surfaceCreated_ = true;
176 return true;
177 }
178 #endif
179
SkipFrame(uint32_t skipFrameInterval)180 bool RSDisplayRenderNode::SkipFrame(uint32_t skipFrameInterval)
181 {
182 frameCount_++;
183 // ensure skipFrameInterval is not 0
184 if (skipFrameInterval == 0) {
185 return false;
186 }
187 if ((frameCount_ - 1) % skipFrameInterval == 0) {
188 return false;
189 }
190 return true;
191 }
192
GetRotation() const193 ScreenRotation RSDisplayRenderNode::GetRotation() const
194 {
195 auto boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
196 if (boundsGeoPtr == nullptr) {
197 return ScreenRotation::ROTATION_0;
198 }
199 // -90.0f: convert rotation degree to 4 enum values
200 return static_cast<ScreenRotation>(static_cast<int32_t>(std::roundf(boundsGeoPtr->GetRotation() / -90.0f)) % 4);
201 }
202
IsRotationChanged() const203 bool RSDisplayRenderNode::IsRotationChanged() const
204 {
205 auto boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
206 if (boundsGeoPtr == nullptr) {
207 return false;
208 }
209 // boundsGeoPtr->IsNeedClientCompose() return false if rotation degree is times of 90
210 // which means rotation is end.
211 bool isRotationEnd = !boundsGeoPtr->IsNeedClientCompose();
212 return !(ROSEN_EQ(boundsGeoPtr->GetRotation(), lastRotation_) && isRotationEnd);
213 }
214
UpdateRotation()215 void RSDisplayRenderNode::UpdateRotation()
216 {
217 auto boundsGeoPtr = (GetRenderProperties().GetBoundsGeometry());
218 if (boundsGeoPtr == nullptr) {
219 return;
220 }
221 lastRotation_ = boundsGeoPtr->GetRotation();
222 }
223
UpdateDisplayDirtyManager(int32_t bufferage,bool useAlignedDirtyRegion)224 void RSDisplayRenderNode::UpdateDisplayDirtyManager(int32_t bufferage, bool useAlignedDirtyRegion)
225 {
226 dirtyManager_->SetBufferAge(bufferage);
227 dirtyManager_->UpdateDirty(useAlignedDirtyRegion);
228 }
229
ClearCurrentSurfacePos()230 void RSDisplayRenderNode::ClearCurrentSurfacePos()
231 {
232 lastFrameSurfacePos_.clear();
233 lastFrameSurfacePos_.swap(currentFrameSurfacePos_);
234 }
235
236 } // namespace Rosen
237 } // namespace OHOS
238