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 #include "recording/recording_canvas.h"
24 #include "memory/rs_memory_track.h"
25 #include "memory/rs_tag_tracker.h"
26 #include "params/rs_render_params.h"
27 #include "pipeline/rs_paint_filter_canvas.h"
28 #include "property/rs_properties_painter.h"
29 #include "render/rs_blur_filter.h"
30 #include "render/rs_light_up_effect_filter.h"
31 #include "platform/common/rs_log.h"
32 #include "platform/common/rs_system_properties.h"
33 #include "visitor/rs_node_visitor.h"
34 #include "property/rs_property_drawable.h"
35
36 namespace OHOS {
37 namespace Rosen {
38 namespace {
39 constexpr PropertyId ANONYMOUS_MODIFIER_ID = 0;
40 }
41
RSCanvasRenderNode(NodeId id,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)42 RSCanvasRenderNode::RSCanvasRenderNode(NodeId id, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
43 : RSRenderNode(id, context, isTextureExportNode)
44 {
45 #ifndef ROSEN_ARKUI_X
46 MemoryInfo info = {sizeof(*this), ExtractPid(id), id, MEMORY_TYPE::MEM_RENDER_NODE};
47 MemoryTrack::Instance().AddNodeRecord(id, info);
48 #endif
49 MemorySnapshot::Instance().AddCpuMemory(ExtractPid(id), sizeof(*this));
50 }
51
~RSCanvasRenderNode()52 RSCanvasRenderNode::~RSCanvasRenderNode()
53 {
54 #ifndef ROSEN_ARKUI_X
55 MemoryTrack::Instance().RemoveNodeRecord(GetId());
56 #endif
57 MemorySnapshot::Instance().RemoveCpuMemory(ExtractPid(GetId()), sizeof(*this));
58 }
59
UpdateRecording(std::shared_ptr<Drawing::DrawCmdList> drawCmds,RSModifierType type,bool isSingleFrameComposer)60 void RSCanvasRenderNode::UpdateRecording(std::shared_ptr<Drawing::DrawCmdList> drawCmds,
61 RSModifierType type, bool isSingleFrameComposer)
62 {
63 if (!drawCmds || drawCmds->IsEmpty()) {
64 return;
65 }
66 auto renderProperty = std::make_shared<RSRenderProperty<Drawing::DrawCmdListPtr>>(drawCmds, ANONYMOUS_MODIFIER_ID);
67 auto renderModifier = std::make_shared<RSDrawCmdListRenderModifier>(renderProperty);
68 renderModifier->SetType(type);
69 AddModifier(renderModifier, isSingleFrameComposer);
70 }
71
ClearRecording()72 void RSCanvasRenderNode::ClearRecording()
73 {
74 RemoveModifier(ANONYMOUS_MODIFIER_ID);
75 }
76
QuickPrepare(const std::shared_ptr<RSNodeVisitor> & visitor)77 void RSCanvasRenderNode::QuickPrepare(const std::shared_ptr<RSNodeVisitor>& visitor)
78 {
79 if (!visitor) {
80 return;
81 }
82 ApplyModifiers();
83 visitor->QuickPrepareCanvasRenderNode(*this);
84 }
85
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)86 void RSCanvasRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
87 {
88 if (!visitor) {
89 return;
90 }
91 ApplyModifiers();
92 visitor->PrepareCanvasRenderNode(*this);
93 }
94
OnTreeStateChanged()95 void RSCanvasRenderNode::OnTreeStateChanged()
96 {
97 if (!IsOnTheTree()) {
98 // clear node groups cache when node is removed from tree
99 if (GetCacheType() == CacheType::CONTENT) {
100 SetCacheType(CacheType::NONE);
101 ClearCacheSurfaceInThread();
102 SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
103 }
104 needClearSurface_ = true;
105 AddToPendingSyncList();
106 }
107 RSRenderNode::OnTreeStateChanged();
108 }
109
OpincGetNodeSupportFlag()110 bool RSCanvasRenderNode::OpincGetNodeSupportFlag()
111 {
112 const auto& property = GetRenderProperties();
113 if (GetSharedTransitionParam() ||
114 property.IsSpherizeValid() ||
115 property.IsAttractionValid() ||
116 property.NeedFilter() ||
117 property.GetUseEffect() ||
118 property.GetColorBlend().has_value() ||
119 IsSelfDrawingNode()) {
120 return false;
121 }
122 return true && RSRenderNode::OpincGetNodeSupportFlag();
123 }
124
Process(const std::shared_ptr<RSNodeVisitor> & visitor)125 void RSCanvasRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
126 {
127 if (!visitor) {
128 return;
129 }
130 RSRenderNode::RenderTraceDebug();
131 visitor->ProcessCanvasRenderNode(*this);
132 }
133
ProcessTransitionBeforeChildren(RSPaintFilterCanvas & canvas)134 void RSCanvasRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
135 {
136 DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
137 }
138
ProcessShadowBatching(RSPaintFilterCanvas & canvas)139 void RSCanvasRenderNode::ProcessShadowBatching(RSPaintFilterCanvas& canvas)
140 {
141 RSAutoCanvasRestore acr(&canvas);
142 DrawPropertyDrawableRange(RSPropertyDrawableSlot::BOUNDS_MATRIX, RSPropertyDrawableSlot::TRANSITION, canvas);
143 DrawPropertyDrawable(RSPropertyDrawableSlot::SHADOW, canvas);
144 }
145
DrawShadow(RSModifierContext & context,RSPaintFilterCanvas & canvas)146 void RSCanvasRenderNode::DrawShadow(RSModifierContext& context, RSPaintFilterCanvas& canvas)
147 {
148 ApplyDrawCmdModifier(context, RSModifierType::TRANSITION);
149 ApplyDrawCmdModifier(context, RSModifierType::ENV_FOREGROUND_COLOR);
150
151 auto parent = GetParent().lock();
152 if (!(parent && parent->GetRenderProperties().GetUseShadowBatching())) {
153 RSPropertiesPainter::DrawShadow(GetRenderProperties(), canvas);
154 RSPropertiesPainter::DrawOutline(GetRenderProperties(), canvas);
155 }
156 }
157
PropertyDrawableRender(RSPaintFilterCanvas & canvas,bool includeProperty)158 void RSCanvasRenderNode::PropertyDrawableRender(RSPaintFilterCanvas& canvas, bool includeProperty)
159 {
160 auto parent = GetParent().lock();
161 if (parent &&
162 parent->GetRenderProperties().GetUseShadowBatching()) {
163 DrawPropertyDrawableRange(
164 RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR, canvas);
165 if (includeProperty) {
166 // Just need to skip RSPropertyDrawableSlot::SHADOW
167 DrawPropertyDrawableRange(
168 RSPropertyDrawableSlot::FOREGROUND_FILTER, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
169 } else {
170 DrawPropertyDrawableRange(
171 RSPropertyDrawableSlot::SAVE_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
172 }
173 } else {
174 if (includeProperty) {
175 DrawPropertyDrawableRange(RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::CLIP_TO_FRAME,
176 canvas);
177 } else {
178 DrawPropertyDrawableRange(RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::OUTLINE, canvas);
179 DrawPropertyDrawableRange(
180 RSPropertyDrawableSlot::SAVE_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
181 }
182 }
183 }
184
ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas & canvas,bool includeProperty)185 void RSCanvasRenderNode::ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas& canvas, bool includeProperty)
186 {
187 PropertyDrawableRender(canvas, includeProperty);
188 }
189
ProcessRenderContents(RSPaintFilterCanvas & canvas)190 void RSCanvasRenderNode::ProcessRenderContents(RSPaintFilterCanvas& canvas)
191 {
192 DrawPropertyDrawable(RSPropertyDrawableSlot::CONTENT_STYLE, canvas);
193 }
194
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)195 void RSCanvasRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
196 {
197 auto parent = GetParent().lock();
198 if (parent &&
199 parent->GetRenderProperties().GetUseShadowBatching()) {
200 DrawPropertyDrawableRange(
201 RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR, canvas);
202 // Just need to skip RSPropertyDrawableSlot::SHADOW
203 DrawPropertyDrawableRange(
204 RSPropertyDrawableSlot::FOREGROUND_FILTER, RSPropertyDrawableSlot::CUSTOM_CLIP_TO_FRAME, canvas);
205 } else {
206 DrawPropertyDrawableRange(
207 RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::CUSTOM_CLIP_TO_FRAME, canvas);
208 }
209 }
210
ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas & canvas)211 void RSCanvasRenderNode::ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas& canvas)
212 {
213 DrawPropertyDrawableRange(
214 RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::PARTICLE_EFFECT, canvas);
215 }
216
ProcessTransitionAfterChildren(RSPaintFilterCanvas & canvas)217 void RSCanvasRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
218 {
219 DrawPropertyDrawableRange(RSPropertyDrawableSlot::PIXEL_STRETCH, RSPropertyDrawableSlot::RESTORE_ALL, canvas);
220 }
221
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)222 void RSCanvasRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
223 {
224 DrawPropertyDrawableRange(RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::RESTORE_ALL, canvas);
225 }
226
ApplyDrawCmdModifier(RSModifierContext & context,RSModifierType type)227 void RSCanvasRenderNode::ApplyDrawCmdModifier(RSModifierContext& context, RSModifierType type)
228 {
229 // temporary workaround, PLANNING: refactor single frame compose without modifing draw cmd list
230 auto& drawCmdModifiers = const_cast<RSRenderContent::DrawCmdContainer&>(GetDrawCmdModifiers());
231 auto itr = drawCmdModifiers.find(type);
232 if (itr == drawCmdModifiers.end() || itr->second.empty()) {
233 return;
234 }
235
236 if (RSSystemProperties::GetSingleFrameComposerEnabled()) {
237 bool needSkip = false;
238 if (GetNodeIsSingleFrameComposer() && singleFrameComposer_ != nullptr) {
239 needSkip = singleFrameComposer_->SingleFrameModifierAddToList(type, itr->second);
240 }
241 for (const auto& modifier : itr->second) {
242 if (singleFrameComposer_ != nullptr && singleFrameComposer_->SingleFrameIsNeedSkip(needSkip, modifier)) {
243 continue;
244 }
245 modifier->Apply(context);
246 }
247 } else {
248 for (const auto& modifier : itr->second) {
249 modifier->Apply(context);
250 }
251 }
252 }
253
InternalDrawContent(RSPaintFilterCanvas & canvas,bool needApplyMatrix)254 void RSCanvasRenderNode::InternalDrawContent(RSPaintFilterCanvas& canvas, bool needApplyMatrix)
255 {
256 RSModifierContext context = { GetMutableRenderProperties(), &canvas };
257
258 if (needApplyMatrix) {
259 DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::CONTENT_STYLE, canvas);
260 } else {
261 DrawPropertyDrawableRange(RSPropertyDrawableSlot::OUTLINE, RSPropertyDrawableSlot::CONTENT_STYLE, canvas);
262 }
263
264 for (auto& child : *GetSortedChildren()) {
265 if (auto canvasChild = ReinterpretCast<RSCanvasRenderNode>(child)) {
266 canvasChild->InternalDrawContent(canvas, true);
267 }
268 }
269
270 if (needApplyMatrix) {
271 DrawPropertyDrawableRange(RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::RESTORE_ALL,
272 canvas);
273 } else {
274 DrawPropertyDrawableRange(RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::PIXEL_STRETCH,
275 canvas);
276 }
277 }
278
SetHDRPresent(bool hasHdrPresent)279 void RSCanvasRenderNode::SetHDRPresent(bool hasHdrPresent)
280 {
281 if (hasHdrPresent_ == hasHdrPresent) {
282 return;
283 }
284 if (IsOnTheTree()) {
285 SetHdrNum(hasHdrPresent, GetInstanceRootNodeId());
286 }
287 hasHdrPresent_ = hasHdrPresent;
288 }
289
GetHDRPresent() const290 bool RSCanvasRenderNode::GetHDRPresent() const
291 {
292 return hasHdrPresent_;
293 }
294
295 // [Attention] Only used in PC window resize scene now
SetLinkedRootNodeId(NodeId rootNodeId)296 void RSCanvasRenderNode::SetLinkedRootNodeId(NodeId rootNodeId)
297 {
298 if (!RSSystemProperties::GetWindowKeyFrameEnabled()) {
299 RS_LOGW("RSCanvasRenderNode::SetLinkedRootNodeId WindowKeyFrame feature disabled");
300 return;
301 }
302
303 linkedRootNodeId_ = rootNodeId;
304 }
305
306 // [Attention] Only used in PC window resize scene now
GetLinkedRootNodeId() const307 NodeId RSCanvasRenderNode::GetLinkedRootNodeId() const
308 {
309 return linkedRootNodeId_;
310 }
311
312 } // namespace Rosen
313 } // namespace OHOS
314