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