• 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 #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