• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_canvas_render_node.h"
17 
18 #include <algorithm>
19 #include "modifier/rs_modifier_type.h"
20 
21 #include "common/rs_obj_abs_geometry.h"
22 #include "common/rs_common_def.h"
23 #ifndef USE_ROSEN_DRAWING
24 #include "include/core/SkCanvas.h"
25 #else
26 #include "recording/recording_canvas.h"
27 #endif
28 #include "memory/rs_memory_track.h"
29 #include "memory/rs_tag_tracker.h"
30 #include "pipeline/rs_paint_filter_canvas.h"
31 #include "property/rs_properties_painter.h"
32 #include "render/rs_blur_filter.h"
33 #include "render/rs_light_up_effect_filter.h"
34 #include "platform/common/rs_log.h"
35 #include "visitor/rs_node_visitor.h"
36 
37 namespace OHOS {
38 namespace Rosen {
39 namespace {
40 constexpr PropertyId ANONYMOUS_MODIFIER_ID = 0;
41 }
42 
RSCanvasRenderNode(NodeId id,std::weak_ptr<RSContext> context)43 RSCanvasRenderNode::RSCanvasRenderNode(NodeId id, std::weak_ptr<RSContext> context) : RSRenderNode(id, context)
44 {
45     MemoryInfo info = {sizeof(*this), ExtractPid(id), id, MEMORY_TYPE::MEM_RENDER_NODE};
46     MemoryTrack::Instance().AddNodeRecord(id, info);
47 }
48 
~RSCanvasRenderNode()49 RSCanvasRenderNode::~RSCanvasRenderNode()
50 {
51     MemoryTrack::Instance().RemoveNodeRecord(GetId());
52 }
53 
54 #ifndef USE_ROSEN_DRAWING
UpdateRecording(std::shared_ptr<DrawCmdList> drawCmds,RSModifierType type)55 void RSCanvasRenderNode::UpdateRecording(std::shared_ptr<DrawCmdList> drawCmds, RSModifierType type)
56 {
57     if (!drawCmds || drawCmds->GetSize() == 0) {
58         return;
59     }
60     auto renderProperty = std::make_shared<RSRenderProperty<DrawCmdListPtr>>(drawCmds, ANONYMOUS_MODIFIER_ID);
61     auto renderModifier = std::make_shared<RSDrawCmdListRenderModifier>(renderProperty);
62     renderModifier->SetType(type);
63     AddModifier(renderModifier);
64 }
65 #else
UpdateRecording(std::shared_ptr<Drawing::DrawCmdList> drawCmds,RSModifierType type)66 void RSCanvasRenderNode::UpdateRecording(std::shared_ptr<Drawing::DrawCmdList> drawCmds, RSModifierType type)
67 {
68     if (!drawCmds || drawCmds->GetData().second == 0) {
69         return;
70     }
71     auto renderProperty = std::make_shared<RSRenderProperty<Drawing::DrawCmdListPtr>>(drawCmds, ANONYMOUS_MODIFIER_ID);
72     auto renderModifier = std::make_shared<RSDrawCmdListRenderModifier>(renderProperty);
73     renderModifier->SetType(type);
74     AddModifier(renderModifier);
75 }
76 #endif
77 
ClearRecording()78 void RSCanvasRenderNode::ClearRecording()
79 {
80     RemoveModifier(ANONYMOUS_MODIFIER_ID);
81 }
82 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)83 void RSCanvasRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
84 {
85     if (!visitor) {
86         return;
87     }
88     visitor->PrepareCanvasRenderNode(*this);
89 }
90 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)91 void RSCanvasRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
92 {
93     std::unique_lock<std::mutex> lock(canvasNodeProcessMutex_);
94     if (!visitor) {
95         return;
96     }
97     RSRenderNode::RenderTraceDebug();
98     visitor->ProcessCanvasRenderNode(*this);
99 }
100 
ProcessTransitionBeforeChildren(RSPaintFilterCanvas & canvas)101 void RSCanvasRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
102 {
103     RSRenderNode::ProcessTransitionBeforeChildren(canvas);
104 }
105 
ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas & canvas)106 void RSCanvasRenderNode::ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas& canvas)
107 {
108     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
109     ApplyDrawCmdModifier(context, RSModifierType::TRANSITION);
110     ApplyDrawCmdModifier(context, RSModifierType::ENV_FOREGROUND_COLOR);
111     RSPropertiesPainter::DrawShadow(GetRenderProperties(), canvas);
112     // In NEW_SKIA version, L96 code will cause dump if the 3rd parameter is true.
113 #ifdef NEW_SKIA
114     RSPropertiesPainter::DrawBackground(GetRenderProperties(), canvas, false);
115 #else
116     RSPropertiesPainter::DrawBackground(GetRenderProperties(), canvas);
117 #endif
118 
119     if (canvas.GetCacheType() != RSPaintFilterCanvas::CacheType::OFFSCREEN) {
120         if (GetRenderProperties().GetUseEffect()) {
121             RSPropertiesPainter::ApplyBackgroundEffect(GetRenderProperties(), canvas);
122         }
123         RSPropertiesPainter::DrawFilter(GetRenderProperties(), canvas, FilterType::BACKGROUND_FILTER);
124     }
125 
126     ApplyDrawCmdModifier(context, RSModifierType::BACKGROUND_STYLE);
127 
128     if (GetRenderProperties().IsDynamicLightUpValid()) {
129         RSPropertiesPainter::DrawDynamicLightUp(GetRenderProperties(), canvas);
130     }
131 
132 #ifndef USE_ROSEN_DRAWING
133     canvasNodeSaveCount_ = canvas.Save();
134 #else
135     canvasNodeSaveCount_ = canvas.SaveAllStatus();
136 #endif
137     ApplyDrawCmdModifier(context, RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY);
138 #ifndef USE_ROSEN_DRAWING
139     canvas.translate(GetRenderProperties().GetFrameOffsetX(), GetRenderProperties().GetFrameOffsetY());
140 #else
141     canvas.Translate(GetRenderProperties().GetFrameOffsetX(), GetRenderProperties().GetFrameOffsetY());
142 #endif
143 
144     if (GetRenderProperties().GetClipToFrame()) {
145     // In NEW_SKIA version, L116 code will cause dump if the 3rd parameter is true.
146 #ifdef NEW_SKIA
147         RSPropertiesPainter::Clip(canvas, GetRenderProperties().GetFrameRect(), false);
148 #else
149         RSPropertiesPainter::Clip(canvas, GetRenderProperties().GetFrameRect());
150 #endif
151     }
152 }
153 
ProcessRenderContents(RSPaintFilterCanvas & canvas)154 void RSCanvasRenderNode::ProcessRenderContents(RSPaintFilterCanvas& canvas)
155 {
156     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
157     ApplyDrawCmdModifier(context, RSModifierType::CONTENT_STYLE);
158 }
159 
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)160 void RSCanvasRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
161 {
162     ProcessTransitionBeforeChildren(canvas);
163     ProcessAnimatePropertyBeforeChildren(canvas);
164 }
165 
ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas & canvas)166 void RSCanvasRenderNode::ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas& canvas)
167 {
168     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
169     ApplyDrawCmdModifier(context, RSModifierType::FOREGROUND_STYLE);
170     RSPropertiesPainter::DrawColorFilter(GetRenderProperties(), canvas);
171 
172     canvas.RestoreStatus(canvasNodeSaveCount_);
173     if (GetRenderProperties().IsLightUpEffectValid()) {
174         RSPropertiesPainter::DrawLightUpEffect(GetRenderProperties(), canvas);
175     }
176     RSPropertiesPainter::DrawFilter(GetRenderProperties(), canvas, FilterType::FOREGROUND_FILTER);
177     auto para = GetRenderProperties().GetLinearGradientBlurPara();
178     RSPropertiesPainter::DrawLinearGradientBlurFilter(GetRenderProperties(), canvas);
179 
180     RSPropertiesPainter::DrawBorder(GetRenderProperties(), canvas);
181     ApplyDrawCmdModifier(context, RSModifierType::OVERLAY_STYLE);
182     RSPropertiesPainter::DrawForegroundColor(GetRenderProperties(), canvas);
183     RSPropertiesPainter::DrawParticle(GetRenderProperties(), canvas);
184 }
185 
ProcessTransitionAfterChildren(RSPaintFilterCanvas & canvas)186 void RSCanvasRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
187 {
188     RSPropertiesPainter::DrawPixelStretch(GetRenderProperties(), canvas);
189     RSRenderNode::ProcessRenderAfterChildren(canvas);
190 }
191 
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)192 void RSCanvasRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
193 {
194     ProcessAnimatePropertyAfterChildren(canvas);
195     ProcessTransitionAfterChildren(canvas);
196     canvas.RestoreEnv();
197 }
198 
ApplyDrawCmdModifier(RSModifierContext & context,RSModifierType type) const199 void RSCanvasRenderNode::ApplyDrawCmdModifier(RSModifierContext& context, RSModifierType type) const
200 {
201     auto itr = drawCmdModifiers_.find(type);
202     if (itr == drawCmdModifiers_.end() || itr->second.empty()) {
203         return;
204     }
205     for (const auto& modifier : itr->second) {
206         modifier->Apply(context);
207     }
208 }
209 
InternalDrawContent(RSPaintFilterCanvas & canvas)210 void RSCanvasRenderNode::InternalDrawContent(RSPaintFilterCanvas& canvas)
211 {
212     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
213 #ifndef USE_ROSEN_DRAWING
214     canvas.translate(GetRenderProperties().GetFrameOffsetX(), GetRenderProperties().GetFrameOffsetY());
215 #else
216     canvas.Translate(GetRenderProperties().GetFrameOffsetX(), GetRenderProperties().GetFrameOffsetY());
217 #endif
218 
219     if (GetRenderProperties().GetClipToFrame()) {
220         RSPropertiesPainter::Clip(canvas, GetRenderProperties().GetFrameRect());
221     }
222     ApplyDrawCmdModifier(context, RSModifierType::CONTENT_STYLE);
223 
224     // temporary solution for drawing children
225     for (auto& child : GetSortedChildren()) {
226         if (auto canvasChild = ReinterpretCast<RSCanvasRenderNode>(child)) {
227             canvasChild->InternalDrawContent(canvas);
228         }
229     }
230 }
231 
OnApplyModifiers()232 void RSCanvasRenderNode::OnApplyModifiers()
233 {
234     GetMutableRenderProperties().backref_ = weak_from_this();
235 }
236 
ProcessDrivenBackgroundRender(RSPaintFilterCanvas & canvas)237 void RSCanvasRenderNode::ProcessDrivenBackgroundRender(RSPaintFilterCanvas& canvas)
238 {
239 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
240     RSRenderNode::ProcessRenderBeforeChildren(canvas);
241     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
242     ApplyDrawCmdModifier(context, RSModifierType::TRANSITION);
243     ApplyDrawCmdModifier(context, RSModifierType::ENV_FOREGROUND_COLOR);
244 
245     RSPropertiesPainter::DrawShadow(GetRenderProperties(), canvas);
246     RSPropertiesPainter::DrawBackground(GetRenderProperties(), canvas);
247     RSPropertiesPainter::DrawFilter(GetRenderProperties(), canvas, FilterType::BACKGROUND_FILTER);
248     ApplyDrawCmdModifier(context, RSModifierType::BACKGROUND_STYLE);
249     RSRenderNode::ProcessRenderAfterChildren(canvas);
250 #endif
251 }
252 
ProcessDrivenContentRender(RSPaintFilterCanvas & canvas)253 void RSCanvasRenderNode::ProcessDrivenContentRender(RSPaintFilterCanvas& canvas)
254 {
255 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
256     canvasNodeSaveCount_ = canvas.Save();
257     canvas.translate(GetRenderProperties().GetFrameOffsetX(), GetRenderProperties().GetFrameOffsetY());
258     DrawDrivenContent(canvas);
259 #endif
260 }
261 
ProcessDrivenContentRenderAfterChildren(RSPaintFilterCanvas & canvas)262 void RSCanvasRenderNode::ProcessDrivenContentRenderAfterChildren(RSPaintFilterCanvas& canvas)
263 {
264 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
265     // Unresolvable bug: Driven render do not support DrawFilter/DrawBorder/FOREGROUND_STYLE/OVERLAY_STYLE
266     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
267     ApplyDrawCmdModifier(context, RSModifierType::FOREGROUND_STYLE);
268 
269     canvas.RestoreStatus(canvasNodeSaveCount_);
270 #endif
271 }
272 
GetDrivenContentClipFrameRect() const273 RectF RSCanvasRenderNode::GetDrivenContentClipFrameRect() const
274 {
275 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
276     // temporary solution for driven content clip
277     RectF rect;
278     auto itr = drawCmdModifiers_.find(RSModifierType::CONTENT_STYLE);
279     if (itr == drawCmdModifiers_.end() || itr->second.empty()) {
280         return rect;
281     }
282     if (!itr->second.empty()) {
283         auto drawCmdModifier = std::static_pointer_cast<RSDrawCmdListRenderModifier>(itr->second.front());
284         if (drawCmdModifier != nullptr) {
285             rect = drawCmdModifier->GetCmdsClipRect();
286         }
287     }
288     return rect;
289 #else
290     return RectF { 0.0f, 0.0f, 0.0f, 0.0f };
291 #endif
292 }
293 
DrawDrivenContent(RSPaintFilterCanvas & canvas)294 void RSCanvasRenderNode::DrawDrivenContent(RSPaintFilterCanvas& canvas)
295 {
296 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
297     RSModifierContext context = { GetMutableRenderProperties(), &canvas };
298     auto itr = drawCmdModifiers_.find(RSModifierType::CONTENT_STYLE);
299     if (itr == drawCmdModifiers_.end() || itr->second.empty()) {
300         return;
301     }
302     int32_t index = 0;
303     for (const auto& modifier : itr->second) {
304         if (index == 0) {
305             // temporary solution for driven content clip
306             auto drawCmdModifier = std::static_pointer_cast<RSDrawCmdListRenderModifier>(modifier);
307             if (drawCmdModifier != nullptr) {
308                 drawCmdModifier->ApplyForDrivenContent(context);
309                 index++;
310                 continue;
311             }
312         }
313         if (modifier != nullptr) {
314             modifier->Apply(context);
315         }
316         index++;
317     }
318 #endif
319 }
320 } // namespace Rosen
321 } // namespace OHOS
322