1 /*
2 * Copyright (c) 2022 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 "modifier/rs_render_modifier.h"
17
18 #include <memory>
19 #include <unordered_map>
20
21 #include "modifier/rs_modifier_type.h"
22 #include "pipeline/rs_draw_cmd_list.h"
23 #include "pipeline/rs_paint_filter_canvas.h"
24 #include "property/rs_properties.h"
25 #include "property/rs_properties_painter.h"
26
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
30 using ModifierUnmarshallingFunc = RSRenderModifier* (*)(Parcel& parcel);
31
32 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP) \
33 { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* { \
34 std::shared_ptr<RSRenderAnimatableProperty<TYPE>> prop; \
35 if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) { \
36 return nullptr; \
37 } \
38 auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop); \
39 if (!modifier) { \
40 return nullptr; \
41 } \
42 return modifier; \
43 }, \
44 },
45
46 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE) \
47 { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* { \
48 std::shared_ptr<RSRenderProperty<TYPE>> prop; \
49 if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) { \
50 return nullptr; \
51 } \
52 auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop); \
53 if (!modifier) { \
54 return nullptr; \
55 } \
56 return modifier; \
57 }, \
58 },
59
60 static std::unordered_map<RSModifierType, ModifierUnmarshallingFunc> funcLUT = {
61 #include "modifier/rs_modifiers_def.in"
__anonc7d3d22d0202() 62 { RSModifierType::EXTENDED, [](Parcel& parcel) -> RSRenderModifier* {
63 std::shared_ptr<RSRenderProperty<std::shared_ptr<DrawCmdList>>> prop;
64 int16_t type;
65 bool hasOverlayBounds = false;
66 if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type) ||
67 !parcel.ReadBool(hasOverlayBounds)) {
68 return nullptr;
69 }
70 RSDrawCmdListRenderModifier* modifier = new RSDrawCmdListRenderModifier(prop);
71 modifier->SetType(static_cast<RSModifierType>(type));
72 if (hasOverlayBounds) {
73 // OVERLAY_STYLE
74 int32_t left;
75 int32_t top;
76 int32_t width;
77 int32_t height;
78 if (!(parcel.ReadInt32(left) && parcel.ReadInt32(top) &&
79 parcel.ReadInt32(width) && parcel.ReadInt32(height))) {
80 return nullptr;
81 }
82 modifier->SetOverlayBounds(std::make_shared<RectI>(left, top, width, height));
83 }
84 return modifier;
85 },
86 },
87 };
88
89 #undef DECLARE_ANIMATABLE_MODIFIER
90 #undef DECLARE_NOANIMATABLE_MODIFIER
91 }
92
Apply(RSModifierContext & context)93 void RSDrawCmdListRenderModifier::Apply(RSModifierContext& context)
94 {
95 if (context.canvas_) {
96 auto cmds = property_->Get();
97 RSPropertiesPainter::DrawFrame(context.property_, *context.canvas_, cmds);
98 }
99 }
100
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)101 void RSDrawCmdListRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
102 {
103 if (auto property = std::static_pointer_cast<RSRenderProperty<DrawCmdListPtr>>(prop)) {
104 property_->Set(property->Get());
105 }
106 }
107
Marshalling(Parcel & parcel)108 bool RSDrawCmdListRenderModifier::Marshalling(Parcel& parcel)
109 {
110 if (parcel.WriteInt16(static_cast<int16_t>(RSModifierType::EXTENDED)) &&
111 RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType())) &&
112 parcel.WriteBool(overlayRect_ != nullptr)) {
113 if (overlayRect_ != nullptr) {
114 return parcel.WriteInt32(overlayRect_->GetLeft()) && parcel.WriteInt32(overlayRect_->GetTop()) &&
115 parcel.WriteInt32(overlayRect_->GetWidth()) && parcel.WriteInt32(overlayRect_->GetHeight());
116 }
117 return true;
118 }
119 return false;
120 }
121
Unmarshalling(Parcel & parcel)122 RSRenderModifier* RSRenderModifier::Unmarshalling(Parcel& parcel)
123 {
124 int16_t type = 0;
125 if (!parcel.ReadInt16(type)) {
126 return nullptr;
127 }
128 auto it = funcLUT.find(static_cast<RSModifierType>(type));
129 if (it == funcLUT.end()) {
130 ROSEN_LOGE("RSRenderModifier Unmarshalling cannot find func in lut %d", type);
131 return nullptr;
132 }
133 return it->second(parcel);
134 }
135
136 namespace {
137 template<typename T>
Add(T a,T b)138 T Add(T a, T b)
139 {
140 return a + b;
141 }
142 template<typename T>
Multiply(T a,T b)143 T Multiply(T a, T b)
144 {
145 return a * b;
146 }
147 template<typename T>
Replace(T a,T b)148 T Replace(T a, T b)
149 {
150 return b;
151 }
152 } // namespace
153
154 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP) \
155 bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel) \
156 { \
157 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_); \
158 return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::MODIFIER_TYPE)) && \
159 RSMarshallingHelper::Marshalling(parcel, renderProperty); \
160 } \
161 void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) \
162 { \
163 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_); \
164 context.property_.Set##MODIFIER_NAME( \
165 DELTA_OP(context.property_.Get##MODIFIER_NAME(), renderProperty->Get())); \
166 } \
167 void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
168 { \
169 if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(prop)) { \
170 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_); \
171 renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get()); \
172 } \
173 }
174
175 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE) \
176 bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel) \
177 { \
178 auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_); \
179 return parcel.WriteInt16(static_cast<short>(RSModifierType::MODIFIER_TYPE)) && \
180 RSMarshallingHelper::Marshalling(parcel, renderProperty); \
181 } \
182 void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) \
183 { \
184 auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_); \
185 context.property_.Set##MODIFIER_NAME(renderProperty->Get()); \
186 } \
187 void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
188 { \
189 if (auto property = std::static_pointer_cast<RSRenderProperty<TYPE>>(prop)) { \
190 auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_); \
191 renderProperty->Set(property->Get()); \
192 } \
193 }
194
195 #include "modifier/rs_modifiers_def.in"
196
197 #undef DECLARE_ANIMATABLE_MODIFIER
198 #undef DECLARE_NOANIMATABLE_MODIFIER
199 } // namespace Rosen
200 } // namespace OHOS
201