1 /*
2 * Copyright (c) 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 "rs_driven_render_manager.h"
17
18 #include <parameters.h>
19 #include "common/rs_obj_abs_geometry.h"
20 #include "common/rs_optional_trace.h"
21 #include "platform/common/rs_log.h"
22 #include "rs_driven_render_ext.h"
23 #include "rs_driven_render_visitor.h"
24
25 namespace OHOS {
26 namespace Rosen {
27 static std::unique_ptr<RSDrivenRenderManager> g_drivenRenderManagerInstance =
28 std::make_unique<RSDrivenRenderManager>();
29
GetInstance()30 RSDrivenRenderManager& RSDrivenRenderManager::GetInstance()
31 {
32 return *g_drivenRenderManagerInstance;
33 }
34
InitInstance()35 void RSDrivenRenderManager::InitInstance()
36 {
37 if (!system::GetBoolParameter("persist.rosen.drivenrender.enabled", true)) {
38 RS_LOGD("RSDrivenRenderManager: driven render not enabled.");
39 return;
40 }
41 if (!RSDrivenRenderExt::Instance().OpenDrivenRenderExt()) {
42 RS_LOGE("RSDrivenRenderManager: init instance failed!");
43 return;
44 }
45 g_drivenRenderManagerInstance->drivenRenderEnabled_ = true;
46 }
47
GetDrivenRenderEnabled() const48 bool RSDrivenRenderManager::GetDrivenRenderEnabled() const
49 {
50 return drivenRenderEnabled_ && system::GetBoolParameter("rosen.debug.drivenrender.enabled", true);
51 }
52
GetUniDrivenRenderMode() const53 const DrivenUniRenderMode& RSDrivenRenderManager::GetUniDrivenRenderMode() const
54 {
55 return uniRenderMode_;
56 }
57
GetUniRenderGlobalZOrder() const58 float RSDrivenRenderManager::GetUniRenderGlobalZOrder() const
59 {
60 return uniRenderGlobalZOrder_;
61 }
62
GetUniRenderSurfaceClipHoleRect() const63 RectI RSDrivenRenderManager::GetUniRenderSurfaceClipHoleRect() const
64 {
65 return uniRenderSurfaceClipHoleRect_;
66 }
67
ClipHoleForDrivenNode(RSPaintFilterCanvas & canvas,const RSCanvasRenderNode & node) const68 bool RSDrivenRenderManager::ClipHoleForDrivenNode(RSPaintFilterCanvas& canvas, const RSCanvasRenderNode& node) const
69 {
70 auto contentSurfaceNode = RSDrivenRenderManager::GetInstance().GetContentSurfaceNode();
71 if (contentSurfaceNode->GetDrivenCanvasNode() == nullptr ||
72 contentSurfaceNode->GetDrivenCanvasNode()->GetId() != node.GetId()) {
73 return false;
74 }
75 auto& property = node.GetRenderProperties();
76 Vector4f clipHoleRect = property.GetBounds();
77 if (clipHoleRect.IsZero()) {
78 clipHoleRect = property.GetFrame();
79 }
80 static int pixel = -1; // clip hole rect should large than content bounds
81 auto x = std::ceil(clipHoleRect.x_ + pixel); // x decrease 1 pixel
82 auto y = std::ceil(clipHoleRect.y_ + pixel); // y decrease 1 pixel
83 auto width = std::floor(clipHoleRect.z_ - (2 * pixel)); // width increase 2 pixels
84 auto height = std::floor(clipHoleRect.w_ - (2 * pixel)); // height increase 2 pixels
85 RRect absClipRRect = RRect({x, y, width, height}, property.GetCornerRadius());
86
87 // clip hole
88 canvas.save();
89 canvas.clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
90 canvas.clear(SK_ColorTRANSPARENT);
91 canvas.restore();
92 return true;
93 }
94
IsValidSurfaceName(RSBaseRenderNode::SharedPtr backgroundNode)95 static bool IsValidSurfaceName(RSBaseRenderNode::SharedPtr backgroundNode)
96 {
97 if (!backgroundNode) {
98 return false;
99 }
100 auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(backgroundNode->GetParent().lock());
101 if (!rsParent) {
102 return false;
103 }
104 return RSDrivenRenderExt::Instance().IsValidSurfaceName(rsParent->GetName());
105 }
106
DoPrepareRenderTask(const DrivenPrepareInfo & info)107 void RSDrivenRenderManager::DoPrepareRenderTask(const DrivenPrepareInfo& info)
108 {
109 bool backgroundDirty = info.dirtyInfo.backgroundDirty;
110 bool contentDirty = info.dirtyInfo.contentDirty;
111 bool nonContentDirty = info.dirtyInfo.nonContentDirty;
112 bool isValidSurface = IsValidSurfaceName(info.backgroundNode);
113 RSBaseRenderNode::SharedPtr currBackground = nullptr;
114 RSBaseRenderNode::SharedPtr currContent = nullptr;
115 DrivenDirtyType dirtyType = info.dirtyInfo.type;
116
117 RS_OPTIONAL_TRACE_NAME("RSDrivenRender:DoPrepareRenderTask backgroundDirty: " +
118 std::to_string(static_cast<int>(backgroundDirty)) +
119 ", contentDirty: " + std::to_string(static_cast<int>(contentDirty)) +
120 ", nonContentDirty: " + std::to_string(static_cast<int>(nonContentDirty)) +
121 ", dirtyType: " + std::to_string(static_cast<int>(dirtyType)) +
122 ", hasInvalidScene: " + std::to_string(static_cast<int>(info.hasInvalidScene)) +
123 ", hasDrivenNodeOnUniTree: " + std::to_string(static_cast<int>(info.hasDrivenNodeOnUniTree)) +
124 ", isValidSurface: " + std::to_string(static_cast<int>(isValidSurface)));
125
126 if (!info.hasInvalidScene && info.hasDrivenNodeOnUniTree &&
127 dirtyType != DrivenDirtyType::INVALID && isValidSurface) {
128 currBackground = info.backgroundNode;
129 currContent = info.contentNode;
130 }
131
132 bool shouldPrepare = false;
133 if (currBackground != nullptr && currContent != nullptr) {
134 shouldPrepare = true;
135 if (contentCanvasNodeId_ != currContent->GetId() || backgroundCanvasNodeId_ != currBackground->GetId()) {
136 contentSurfaceNode_->Reset();
137 backgroundSurfaceNode_->Reset();
138 contentSurfaceNode_->SetDrivenCanvasNode(currContent);
139 backgroundSurfaceNode_->SetDrivenCanvasNode(currBackground);
140 contentCanvasNodeId_ = currContent->GetId();
141 backgroundCanvasNodeId_ = currBackground->GetId();
142 }
143 }
144
145 if (shouldPrepare) {
146 auto visitor = std::make_shared<RSDrivenRenderVisitor>();
147 visitor->SetDirtyInfo(backgroundDirty, contentDirty, nonContentDirty);
148 visitor->SetScreenRect(info.screenRect);
149 contentSurfaceNode_->ResetCurrFrameState();
150 backgroundSurfaceNode_->ResetCurrFrameState();
151 visitor->PrepareDrivenSurfaceRenderNode(*backgroundSurfaceNode_);
152 visitor->PrepareDrivenSurfaceRenderNode(*contentSurfaceNode_);
153 } else {
154 Reset();
155 }
156 UpdateUniDrivenRenderMode(dirtyType);
157
158 if (!isBufferCacheClear_ && !info.hasDrivenNodeOnUniTree) {
159 backgroundSurfaceNode_->ClearBufferCache();
160 contentSurfaceNode_->ClearBufferCache();
161 isBufferCacheClear_ = true;
162 }
163 }
164
DoProcessRenderTask(const DrivenProcessInfo & info)165 void RSDrivenRenderManager::DoProcessRenderTask(const DrivenProcessInfo& info)
166 {
167 std::string traceMsg = "";
168 bool isReusableMode = false;
169 auto currBackground = backgroundSurfaceNode_->GetDrivenCanvasNode();
170 if (currBackground != nullptr && uniRenderMode_ == DrivenUniRenderMode::REUSE_WITH_CLIP_HOLE) {
171 auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(currBackground->GetParent().lock());
172 if (rsParent != nullptr) {
173 isReusableMode = true;
174 traceMsg = "RSDrivenRender::ReusableProcess:[" + rsParent->GetName() + "]" +
175 " " + rsParent->GetDstRect().ToString() +
176 " Alpha: " + std::to_string(rsParent->GetGlobalAlpha()).substr(0, 4); // substr[0]-[4] is alpha value
177 }
178 }
179 if (isReusableMode) {
180 RS_TRACE_BEGIN(traceMsg);
181 }
182
183 auto visitor = std::make_shared<RSDrivenRenderVisitor>();
184 visitor->SetUniProcessor(info.uniProcessor);
185 visitor->SetUniColorSpace(info.uniColorSpace);
186 visitor->SetUniGlobalZOrder(info.uniGlobalZOrder);
187
188 RS_TRACE_BEGIN("RSUniRender:DrivenRenderBackGround");
189 visitor->ProcessDrivenSurfaceRenderNode(*backgroundSurfaceNode_);
190 RS_TRACE_END();
191 RS_TRACE_BEGIN("RSUniRender:DrivenRenderContent");
192 visitor->ProcessDrivenSurfaceRenderNode(*contentSurfaceNode_);
193 RS_TRACE_END();
194
195 uniRenderMode_ = DrivenUniRenderMode::RENDER_WITH_NORMAL;
196 uniRenderGlobalZOrder_ = 0.0;
197 uniRenderSurfaceClipHoleRect_.Clear();
198 if (!backgroundSurfaceNode_->IsDisabledMode() || !contentSurfaceNode_->IsDisabledMode()) {
199 isBufferCacheClear_ = false;
200 }
201
202 if (isReusableMode) {
203 RS_TRACE_END();
204 }
205 }
206
Reset()207 void RSDrivenRenderManager::Reset()
208 {
209 contentSurfaceNode_->Reset();
210 backgroundSurfaceNode_->Reset();
211 contentCanvasNodeId_ = 0;
212 backgroundCanvasNodeId_ = 0;
213 uniRenderMode_ = DrivenUniRenderMode::RENDER_WITH_NORMAL;
214 uniRenderGlobalZOrder_ = 0.0;
215 uniRenderSurfaceClipHoleRect_.Clear();
216 }
217
UpdateUniDrivenRenderMode(DrivenDirtyType dirtyType)218 void RSDrivenRenderManager::UpdateUniDrivenRenderMode(DrivenDirtyType dirtyType)
219 {
220 if (dirtyType == DrivenDirtyType::MARK_DRIVEN) {
221 if (backgroundSurfaceNode_->IsExpandedMode()) {
222 backgroundSurfaceNode_->DisabledRenderMode();
223 }
224 if (contentSurfaceNode_->IsExpandedMode()) {
225 contentSurfaceNode_->DisabledRenderMode();
226 }
227 uniRenderMode_ = DrivenUniRenderMode::RENDER_WITH_NORMAL;
228 } else {
229 // adjust content render mode to load balancing
230 if (backgroundSurfaceNode_->IsExpandedMode() && contentSurfaceNode_->IsExpandedMode()) {
231 contentSurfaceNode_->DisabledRenderMode();
232 }
233
234 // uni-render mode should follow contentSurfaceNode render mode
235 if (contentSurfaceNode_->IsExpandedMode()) {
236 uniRenderMode_ = DrivenUniRenderMode::RENDER_WITH_CLIP_HOLE;
237 uniRenderSurfaceClipHoleRect_ = CalcUniRenderSurfaceClipHoleRect();
238 } else if (contentSurfaceNode_->IsReusableMode()) {
239 uniRenderMode_ = DrivenUniRenderMode::REUSE_WITH_CLIP_HOLE;
240 } else {
241 uniRenderMode_ = DrivenUniRenderMode::RENDER_WITH_NORMAL;
242 }
243 }
244
245 if (backgroundSurfaceNode_->IsDisabledMode() && contentSurfaceNode_->IsDisabledMode()) {
246 uniRenderGlobalZOrder_ = 0.0;
247 } else {
248 uniRenderGlobalZOrder_ = 3.0; // uni-layer z-order
249 }
250
251 auto contentRenderMode = contentSurfaceNode_->GetDrivenSurfaceRenderMode();
252 auto backgroundRenderMode = backgroundSurfaceNode_->GetDrivenSurfaceRenderMode();
253 RS_LOGD("RSDrivenRenderManager: contentRenderMode = %d, backgroundRenderMode = %d, uniRenderMode = %d",
254 contentRenderMode, backgroundRenderMode, uniRenderMode_);
255 }
256
CalcUniRenderSurfaceClipHoleRect()257 RectI RSDrivenRenderManager::CalcUniRenderSurfaceClipHoleRect()
258 {
259 RectI rect;
260 if (contentSurfaceNode_->GetDrivenCanvasNode() != nullptr) {
261 auto canvasNode =
262 RSBaseRenderNode::ReinterpretCast<RSCanvasRenderNode>(contentSurfaceNode_->GetDrivenCanvasNode());
263 if (canvasNode == nullptr) {
264 return rect;
265 }
266 auto& property = canvasNode->GetRenderProperties();
267 Vector4f clipHoleRect = property.GetBounds();
268 if (clipHoleRect.IsZero()) {
269 clipHoleRect = property.GetFrame();
270 }
271 auto geoPtr = (property.GetBoundsGeometry());
272 rect = geoPtr->MapAbsRect(RectF(clipHoleRect.x_, clipHoleRect.y_, clipHoleRect.z_, clipHoleRect.w_));
273 }
274 return rect;
275 }
276 } // namespace Rosen
277 } // namespace OHOS
278