• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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