1 /*
2  * Copyright (c) 2022-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 #ifndef RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_EXTENDED_MODIFIER_H
17 #define RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_EXTENDED_MODIFIER_H
18 
19 #include "command/rs_node_command.h"
20 #include "common/rs_common_def.h"
21 #include "common/rs_macros.h"
22 #include "modifier/rs_modifier.h"
23 #include "pipeline/rs_draw_cmd_list.h"
24 #include "transaction/rs_transaction_proxy.h"
25 #include "ui/rs_canvas_node.h"
26 
27 
28 namespace OHOS {
29 namespace Rosen {
30 struct RSDrawingContext {
31     Drawing::Canvas* canvas;
32     float width;
33     float height;
34 };
35 
36 class RSC_EXPORT RSExtendedModifierHelper {
37 public:
38     static RSDrawingContext CreateDrawingContext(NodeId nodeId);
39     static std::shared_ptr<RSRenderModifier> CreateRenderModifier(
40         RSDrawingContext& ctx, PropertyId id, RSModifierType type);
41     static std::shared_ptr<Drawing::DrawCmdList> FinishDrawing(RSDrawingContext& ctx);
42 };
43 
44 class RSC_EXPORT RSExtendedModifier : public RSModifier {
45 public:
46     RSExtendedModifier(const std::shared_ptr<RSPropertyBase>& property = {})
47         : RSModifier(property, RSModifierType::EXTENDED)
48     {
49         property_->SetIsCustom(true);
50     }
51     virtual ~RSExtendedModifier() = default;
52 
GetModifierType()53     RSModifierType GetModifierType() const override
54     {
55         return RSModifierType::EXTENDED;
56     }
57     virtual void Draw(RSDrawingContext& context) const = 0;
58 
59 protected:
60     explicit RSExtendedModifier(const RSModifierType type, const std::shared_ptr<RSPropertyBase>& property = {})
61         : RSModifier(property, type)
62     {
63         property_->SetIsCustom(true);
64     }
65 
GetPropertyModifierType()66     RSPropertyModifierType GetPropertyModifierType() const override
67     {
68         return RSPropertyModifierType::CUSTOM;
69     }
70 
CreateRenderModifier()71     std::shared_ptr<RSRenderModifier> CreateRenderModifier() const override
72     {
73         auto node = property_->target_.lock();
74         if (node == nullptr) {
75             return nullptr;
76         }
77         RSDrawingContext ctx = RSExtendedModifierHelper::CreateDrawingContext(node->GetId());
78         Draw(ctx);
79         return RSExtendedModifierHelper::CreateRenderModifier(ctx, property_->GetId(), GetModifierType());
80     }
81 
UpdateToRender()82     void UpdateToRender() override
83     {
84         auto node = property_->target_.lock();
85         if (node == nullptr) {
86             return;
87         }
88         RSDrawingContext ctx = RSExtendedModifierHelper::CreateDrawingContext(node->GetId());
89         Draw(ctx);
90         auto drawCmdList = RSExtendedModifierHelper::FinishDrawing(ctx);
91         bool isEmpty = drawCmdList == nullptr;
92         if (lastDrawCmdListEmpty_ && isEmpty) {
93             return;
94         }
95         if (drawCmdList) {
96             drawCmdList->SetIsNeedUnmarshalOnDestruct(!node->IsRenderServiceNode());
97         }
98         lastDrawCmdListEmpty_ = isEmpty;
99 
100         std::unique_ptr<RSCommand> command = std::make_unique<RSUpdatePropertyDrawCmdList>(
101             node->GetId(), drawCmdList, property_->id_, UPDATE_TYPE_OVERWRITE);
102         auto transactionProxy = RSTransactionProxy::GetInstance();
103         if (transactionProxy != nullptr) {
104             transactionProxy->AddCommand(command, node->IsRenderServiceNode());
105             if (node->NeedForcedSendToRemote()) {
106                 std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSUpdatePropertyDrawCmdList>(
107                     node->GetId(), drawCmdList, property_->id_, UPDATE_TYPE_OVERWRITE);
108                 transactionProxy->AddCommand(commandForRemote, true, node->GetFollowType(), node->GetId());
109             }
110         }
111     }
112 private:
113     bool lastDrawCmdListEmpty_ = false;
114 };
115 
116 class RS_EXPORT RSGeometryTransModifier : public RSExtendedModifier {
117 public:
RSGeometryTransModifier()118     RSGeometryTransModifier() : RSExtendedModifier(RSModifierType::GEOMETRYTRANS)
119     {}
120     virtual ~RSGeometryTransModifier() = default;
121 
GetModifierType()122     RSModifierType GetModifierType() const override
123     {
124         return RSModifierType::GEOMETRYTRANS;
125     }
126 
Draw(RSDrawingContext & context)127     void Draw(RSDrawingContext& context) const override {};
128 
129     virtual Drawing::Matrix GeometryEffect(float width, float height) const = 0;
130 
131 protected:
CreateRenderModifier()132     std::shared_ptr<RSRenderModifier> CreateRenderModifier() const override
133     {
134         auto node = property_->target_.lock();
135         if (node == nullptr) {
136             return nullptr;
137         }
138         auto canvasnode = RSNodeMap::Instance().GetNode<RSCanvasNode>(node->GetId());
139         if (canvasnode == nullptr) {
140             return nullptr;
141         }
142         auto renderProperty = std::make_shared<RSRenderProperty<Drawing::Matrix>>(
143             GeometryEffect(canvasnode->GetPaintWidth(), canvasnode->GetPaintHeight()), property_->GetId());
144         auto renderModifier = std::make_shared<RSGeometryTransRenderModifier>(renderProperty);
145         return renderModifier;
146     }
147 
UpdateToRender()148     void UpdateToRender() override
149     {
150         auto node = property_->target_.lock();
151         if (node == nullptr) {
152             return;
153         }
154         auto canvasnode = RSNodeMap::Instance().GetNode<RSCanvasNode>(node->GetId());
155         if (canvasnode == nullptr) {
156             return;
157         }
158         auto matrix = GeometryEffect(canvasnode->GetPaintWidth(), canvasnode->GetPaintHeight());
159         std::unique_ptr<RSCommand> command = std::make_unique<RSUpdatePropertyDrawingMatrix>(
160             node->GetId(), matrix, property_->id_, UPDATE_TYPE_OVERWRITE);
161         auto transactionProxy = RSTransactionProxy::GetInstance();
162         if (transactionProxy != nullptr) {
163             transactionProxy->AddCommand(command, node->IsRenderServiceNode());
164             if (node->NeedForcedSendToRemote()) {
165                 std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSUpdatePropertyDrawingMatrix>(
166                     node->GetId(), matrix, property_->id_, UPDATE_TYPE_OVERWRITE);
167                 transactionProxy->AddCommand(commandForRemote, true, node->GetFollowType(), node->GetId());
168             }
169         }
170     }
171 };
172 
173 class RSC_EXPORT RSTransitionModifier : public RSExtendedModifier {
174 public:
RSTransitionModifier()175     RSTransitionModifier() : RSExtendedModifier(RSModifierType::TRANSITION)
176     {}
177 
GetModifierType()178     RSModifierType GetModifierType() const override
179     {
180         return RSModifierType::TRANSITION;
181     }
182 
183     virtual void Active() = 0;
184 
185     virtual void Identity() = 0;
186 };
187 
188 class RSC_EXPORT RSBackgroundStyleModifier : public RSExtendedModifier {
189 public:
RSBackgroundStyleModifier()190     RSBackgroundStyleModifier() : RSExtendedModifier(RSModifierType::BACKGROUND_STYLE)
191     {}
192 
GetModifierType()193     RSModifierType GetModifierType() const override
194     {
195         return RSModifierType::BACKGROUND_STYLE;
196     }
197 };
198 
199 class RSC_EXPORT RSContentStyleModifier : public RSExtendedModifier {
200 public:
RSContentStyleModifier()201     RSContentStyleModifier() : RSExtendedModifier(RSModifierType::CONTENT_STYLE)
202     {}
203 
GetModifierType()204     RSModifierType GetModifierType() const override
205     {
206         return RSModifierType::CONTENT_STYLE;
207     }
208 };
209 
210 class RSC_EXPORT RSForegroundStyleModifier : public RSExtendedModifier {
211 public:
RSForegroundStyleModifier()212     RSForegroundStyleModifier() : RSExtendedModifier(RSModifierType::FOREGROUND_STYLE)
213     {}
214 
GetModifierType()215     RSModifierType GetModifierType() const override
216     {
217         return RSModifierType::FOREGROUND_STYLE;
218     }
219 };
220 
221 class RSC_EXPORT RSOverlayStyleModifier : public RSExtendedModifier {
222 public:
RSOverlayStyleModifier()223     RSOverlayStyleModifier() : RSExtendedModifier(RSModifierType::OVERLAY_STYLE)
224     {}
225 
GetModifierType()226     RSModifierType GetModifierType() const override
227     {
228         return RSModifierType::OVERLAY_STYLE;
229     }
230 };
231 
232 class RSC_EXPORT RSNodeModifier : public RSExtendedModifier {
233 public:
RSNodeModifier()234     RSNodeModifier() : RSExtendedModifier(RSModifierType::NODE_MODIFIER)
235     {}
236 
GetModifierType()237     RSModifierType GetModifierType() const override
238     {
239         return RSModifierType::NODE_MODIFIER;
240     }
241 
242     virtual void Modify(RSNode& target) const = 0;
243 
244 private:
OnAttachToNode(const std::weak_ptr<RSNode> & target)245     void OnAttachToNode(const std::weak_ptr<RSNode>& target) override
246     {
247         target_ = target;
248     }
249 
UpdateToRender()250     void UpdateToRender() override
251     {
252         auto node = target_.lock();
253         if (node == nullptr) {
254             return;
255         }
256         Modify(*node);
257     }
258 
Draw(RSDrawingContext & context)259     void Draw(RSDrawingContext& context) const override final {}
260 
261     std::weak_ptr<RSNode> target_;
262 };
263 } // namespace Rosen
264 } // namespace OHOS
265 
266 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_EXTENDED_MODIFIER_H
267