• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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