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 #ifndef RENDER_SERVICE_BASE_TRANSACTION_RS_MARSHALLING_HELPER_H
17 #define RENDER_SERVICE_BASE_TRANSACTION_RS_MARSHALLING_HELPER_H
18 
19 #include <map>
20 #include <memory>
21 #include <optional>
22 #include <parcel.h>
23 #include <thread>
24 
25 #include "common/rs_common_def.h"
26 #include "common/rs_macros.h"
27 
28 #include "image/image.h"
29 #include "text/hm_symbol.h"
30 
31 
32 namespace OHOS {
33 namespace Media {
34 class PixelMap;
35 }
36 namespace Rosen {
37 class RSExtendImageObject;
38 class RSExtendImageBaseObj;
39 namespace Drawing {
40 class DrawCmdList;
41 class RecordCmd;
42 class MaskCmdList;
43 class Data;
44 class Image;
45 class Bitmap;
46 class Typeface;
47 }
48 class RSFilter;
49 class RSImage;
50 class RSImageBase;
51 class RSMask;
52 class RSPath;
53 class RSLinearGradientBlurPara;
54 class MotionBlurParam;
55 class RSMagnifierParams;
56 class EmitterUpdater;
57 class ParticleNoiseField;
58 class ParticleNoiseFields;
59 template<typename T>
60 class RenderParticleParaType;
61 class EmitterConfig;
62 class ParticleVelocity;
63 class RenderParticleColorParaType;
64 class ParticleRenderParams;
65 class RSRenderCurveAnimation;
66 class RSRenderParticleAnimation;
67 class RSRenderInterpolatingSpringAnimation;
68 class RSRenderKeyframeAnimation;
69 class RSRenderPathAnimation;
70 class RSRenderSpringAnimation;
71 class RSRenderTransition;
72 class RSRenderTransitionEffect;
73 class RSRenderModifier;
74 class RSRenderPropertyBase;
75 template<typename T>
76 class RSRenderProperty;
77 template<typename T>
78 class RSRenderAnimatableProperty;
79 class RSShader;
80 template<typename T>
81 class RectT;
82 template<typename T>
83 class RRectT;
84 
85 class RSB_EXPORT RSMarshallingHelper {
86 public:
87     // default marshalling and unmarshalling method for POD types
88     // [PLANNING]: implement marshalling & unmarshalling methods for other types (e.g. RSImage, drawCMDList)
89     template<typename T>
Marshalling(Parcel & parcel,const T & val)90     static bool Marshalling(Parcel& parcel, const T& val)
91     {
92         return parcel.WriteUnpadBuffer(&val, sizeof(T));
93     }
94     template<typename T>
Unmarshalling(Parcel & parcel,T & val)95     static bool Unmarshalling(Parcel& parcel, T& val)
96     {
97         if (const uint8_t* buff = parcel.ReadUnpadBuffer(sizeof(T))) {
98             if (buff == nullptr) {
99                 return false;
100             }
101             val = *(reinterpret_cast<const T*>(buff));
102             return true;
103         }
104         return false;
105     }
106 
Marshalling(Parcel & parcel,const std::string & val)107     static bool Marshalling(Parcel& parcel, const std::string& val)
108     {
109         return parcel.WriteString(val);
110     }
Unmarshalling(Parcel & parcel,std::string & val)111     static bool Unmarshalling(Parcel& parcel, std::string& val)
112     {
113         return parcel.ReadString(val);
114     }
115 
116     template<typename T>
MarshallingArray(Parcel & parcel,const T * val,int count)117     static bool MarshallingArray(Parcel& parcel, const T* val, int count)
118     {
119         if (count <= 0) {
120             return true;
121         }
122         return parcel.WriteUnpadBuffer(val, count * sizeof(T));
123     }
124     template<typename T>
UnmarshallingArray(Parcel & parcel,T * & val,int count)125     static bool UnmarshallingArray(Parcel& parcel, T*& val, int count)
126     {
127         if (count <= 0) {
128             return false;
129         }
130         if (const uint8_t* buff = parcel.ReadUnpadBuffer(count * sizeof(T))) {
131             if (buff == nullptr) {
132                 return false;
133             }
134             val = reinterpret_cast<const T*>(buff);
135             return true;
136         }
137         return false;
138     }
139 
140     template<typename T>
MarshallingVec(Parcel & parcel,const std::vector<T> & val)141     static bool MarshallingVec(Parcel& parcel, const std::vector<T>& val)
142     {
143         int size = val.size();
144         Marshalling(parcel, size);
145         for (int i = 0; i < size; i++) {
146             if (!Marshalling(parcel, val[i])) {
147                 return false;
148             }
149         }
150         return true;
151     }
152 
153     template<typename T>
UnmarshallingVec(Parcel & parcel,std::vector<T> & val)154     static bool UnmarshallingVec(Parcel& parcel, std::vector<T>& val)
155     {
156         int size = 0;
157         Unmarshalling(parcel, size);
158         if (size < 0) {
159             return false;
160         }
161         val.clear();
162         for (int i = 0; i < size; i++) {
163             T tmp;
164             if (!Unmarshalling(parcel, tmp)) {
165                 return false;
166             }
167             val.push_back(tmp);
168         }
169         return true;
170     }
171 
172     template<typename T>
MarshallingVec2(Parcel & parcel,const std::vector<std::vector<T>> & val)173     static bool MarshallingVec2(Parcel& parcel, const std::vector<std::vector<T>>& val)
174     {
175         int size = val.size();
176         Marshalling(parcel, size);
177         for (int i = 0; i < size; i++) {
178             if (!MarshallingVec(parcel, val[i])) {
179                 return false;
180             }
181         }
182         return true;
183     }
184 
185     template<typename T>
UnmarshallingVec2(Parcel & parcel,std::vector<std::vector<T>> & val)186     static bool UnmarshallingVec2(Parcel& parcel, std::vector<std::vector<T>>& val)
187     {
188         int size = 0;
189         Unmarshalling(parcel, size);
190         if (size < 0) {
191             return false;
192         }
193         val.clear();
194         for (int i = 0; i < size; i++) {
195             std::vector<T> tmp;
196             if (!UnmarshallingVec(parcel, tmp)) {
197                 return false;
198             }
199             val.push_back(tmp);
200         }
201         return true;
202     }
203 
204     static RSB_EXPORT bool Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val,
205         bool isRecordCmd = false);
206     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val,
207         uint32_t* opItemCount = nullptr);
208     static RSB_EXPORT bool Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::RecordCmd>& val);
209     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::RecordCmd>& val,
210         uint32_t* opItemCount = nullptr);
211     static RSB_EXPORT bool Marshalling(Parcel& parcel, std::shared_ptr<Drawing::Typeface>& val);
212     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::Typeface>& val);
213     static RSB_EXPORT bool Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::Image>& val);
214     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::Image>& val);
215     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::Image>& val, void*& imagepixelAddr);
216     static RSB_EXPORT bool UnmarshallingNoLazyGeneratedImage(Parcel& parcel,
217     std::shared_ptr<Drawing::Image>& val, void*& imagepixelAddr);
218     static RSB_EXPORT bool ReadColorSpaceFromParcel(Parcel& parcel, std::shared_ptr<Drawing::ColorSpace>& colorSpace);
219 
220     // reloaded marshalling & unmarshalling function for types
221 #define DECLARE_FUNCTION_OVERLOAD(TYPE)                                  \
222     static RSB_EXPORT bool Marshalling(Parcel& parcel, const TYPE& val); \
223     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, TYPE& val);
224 
225     // basic types
226     DECLARE_FUNCTION_OVERLOAD(bool)
227     DECLARE_FUNCTION_OVERLOAD(int8_t)
228     DECLARE_FUNCTION_OVERLOAD(uint8_t)
229     DECLARE_FUNCTION_OVERLOAD(int16_t)
230     DECLARE_FUNCTION_OVERLOAD(uint16_t)
231     DECLARE_FUNCTION_OVERLOAD(int32_t)
232     DECLARE_FUNCTION_OVERLOAD(uint32_t)
233     DECLARE_FUNCTION_OVERLOAD(int64_t)
234     DECLARE_FUNCTION_OVERLOAD(uint64_t)
235     DECLARE_FUNCTION_OVERLOAD(float)
236     DECLARE_FUNCTION_OVERLOAD(double)
237     // skia types
238     DECLARE_FUNCTION_OVERLOAD(Drawing::Matrix)
239     DECLARE_FUNCTION_OVERLOAD(Drawing::Bitmap)
240     static bool SkipData(Parcel& parcel);
241     static bool SkipImage(Parcel& parcel);
242     // RS types
243     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSShader>)
244     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSPath>)
245     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSLinearGradientBlurPara>)
246     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<MotionBlurParam>)
247     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSMagnifierParams>)
248     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<EmitterUpdater>)
249     DECLARE_FUNCTION_OVERLOAD(std::vector<std::shared_ptr<EmitterUpdater>>)
250     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<ParticleNoiseField>)
251     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<ParticleNoiseFields>)
252     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSFilter>)
253     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSMask>)
254     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSImage>)
255     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSImageBase>)
256     DECLARE_FUNCTION_OVERLOAD(EmitterConfig)
257     DECLARE_FUNCTION_OVERLOAD(ParticleVelocity)
258     DECLARE_FUNCTION_OVERLOAD(RenderParticleParaType<float>)
259     DECLARE_FUNCTION_OVERLOAD(RenderParticleColorParaType)
260     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<ParticleRenderParams>)
261     DECLARE_FUNCTION_OVERLOAD(std::vector<std::shared_ptr<ParticleRenderParams>>)
262     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSExtendImageObject>)
263     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSExtendImageBaseObj>)
264     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<Drawing::MaskCmdList>)
265     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<Media::PixelMap>)
266     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RectT<float>>)
267     DECLARE_FUNCTION_OVERLOAD(RRectT<float>)
268     static bool SkipPixelMap(Parcel& parcel);
269     // animation
270     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSRenderTransition>)
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSRenderTransitionEffect>)271     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSRenderTransitionEffect>)
272 
273     DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSRenderModifier>)
274 #undef DECLARE_FUNCTION_OVERLOAD
275 
276     // reloaded marshalling & unmarshalling function for animation
277 #define DECLARE_ANIMATION_OVERLOAD(TEMPLATE)                                       \
278     static bool Marshalling(Parcel& parcel, const std::shared_ptr<TEMPLATE>& val); \
279     static bool Unmarshalling(Parcel& parcel, std::shared_ptr<TEMPLATE>& val);
280 
281     DECLARE_ANIMATION_OVERLOAD(RSRenderCurveAnimation)
282     DECLARE_ANIMATION_OVERLOAD(RSRenderParticleAnimation)
283     DECLARE_ANIMATION_OVERLOAD(RSRenderInterpolatingSpringAnimation)
284     DECLARE_ANIMATION_OVERLOAD(RSRenderKeyframeAnimation)
285     DECLARE_ANIMATION_OVERLOAD(RSRenderSpringAnimation)
286     DECLARE_ANIMATION_OVERLOAD(RSRenderPathAnimation)
287 #undef DECLARE_ANIMATION_OVERLOAD
288 
289 #define DECLARE_TEMPLATE_OVERLOAD(TEMPLATE)                                                      \
290     template<typename T>                                                                         \
291     static RSB_EXPORT bool Marshalling(Parcel& parcel, const std::shared_ptr<TEMPLATE<T>>& val); \
292     template<typename T>                                                                         \
293     static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<TEMPLATE<T>>& val);
294 
295     DECLARE_TEMPLATE_OVERLOAD(RSRenderProperty)
296     DECLARE_TEMPLATE_OVERLOAD(RSRenderAnimatableProperty)
297 #undef DECLARE_TEMPLATE_OVERLOAD
298 
299     // reloaded marshalling & unmarshalling function for std::map
300     template<typename T, typename P>
301     static bool Marshalling(Parcel& parcel, const std::map<T, P>& val)
302     {
303         if (!parcel.WriteUint32(val.size())) {
304             return false;
305         }
306         for (const auto& [key, value] : val) {
307             if (!Marshalling(parcel, key) || !Marshalling(parcel, value)) {
308                 return false;
309             }
310         }
311         return true;
312     }
313     template<typename T, typename P>
Unmarshalling(Parcel & parcel,std::map<T,P> & val)314     static bool Unmarshalling(Parcel& parcel, std::map<T, P>& val)
315     {
316         uint32_t size = 0;
317         if (!Unmarshalling(parcel, size)) {
318             return false;
319         }
320         val.clear();
321         for (uint32_t i = 0; i < size; ++i) {
322             T key;
323             P value;
324             if (!Unmarshalling(parcel, key) || !Unmarshalling(parcel, value)) {
325                 return false;
326             }
327             val.emplace(key, value);
328         }
329         return true;
330     }
331 
332     static bool Marshalling(Parcel& parcel, const std::shared_ptr<RSRenderPropertyBase>& val);
333     static bool Unmarshalling(Parcel& parcel, std::shared_ptr<RSRenderPropertyBase>& val);
334 
335     // reloaded marshalling & unmarshalling function for std::vector
336     template<typename T>
Marshalling(Parcel & parcel,const std::vector<T> & val)337     static bool Marshalling(Parcel& parcel, const std::vector<T>& val)
338     {
339         bool success = parcel.WriteUint32(val.size());
340         for (const auto& item : val) {
341             success = success && Marshalling(parcel, item);
342         }
343         return success;
344     }
345     template<typename T>
Unmarshalling(Parcel & parcel,std::vector<T> & val)346     static bool Unmarshalling(Parcel& parcel, std::vector<T>& val)
347     {
348         uint32_t size = 0;
349         if (!Unmarshalling(parcel, size)) {
350             return false;
351         }
352         val.clear();
353         for (uint32_t i = 0; i < size; ++i) {
354             // in-place unmarshalling
355             T tmp;
356             if (!Unmarshalling(parcel, tmp)) {
357                 return false;
358             }
359             val.emplace_back(tmp);
360         }
361         return true;
362     }
363 
364     // reloaded marshalling & unmarshalling function for std::optional
365     template<typename T>
Marshalling(Parcel & parcel,const std::optional<T> & val)366     static bool Marshalling(Parcel& parcel, const std::optional<T>& val)
367     {
368         if (!val.has_value()) {
369             parcel.WriteBool(false);
370             return true;
371         }
372         parcel.WriteBool(true);
373         return Marshalling(parcel, val.value());
374     }
375     template<typename T>
Unmarshalling(Parcel & parcel,std::optional<T> & val)376     static bool Unmarshalling(Parcel& parcel, std::optional<T>& val)
377     {
378         if (!parcel.ReadBool()) {
379             val.reset();
380             return true;
381         }
382         T value;
383         if (!Unmarshalling(parcel, value)) {
384             return false;
385         }
386         val = value;
387         return true;
388     }
389 
390     template<class T1, class T2>
Marshalling(Parcel & parcel,const std::pair<T1,T2> & val)391     static bool Marshalling(Parcel& parcel, const std::pair<T1, T2>& val)
392     {
393         return Marshalling(parcel, val.first) && Marshalling(parcel, val.second);
394     }
395     template<class T1, class T2>
Unmarshalling(Parcel & parcel,std::pair<T1,T2> & val)396     static bool Unmarshalling(Parcel& parcel, std::pair<T1, T2>& val)
397     {
398         return Unmarshalling(parcel, val.first) && Unmarshalling(parcel, val.second);
399     }
400 
401     template<typename T, typename... Args>
Marshalling(Parcel & parcel,const T & first,const Args &...args)402     static bool Marshalling(Parcel& parcel, const T& first, const Args&... args)
403     {
404         return Marshalling(parcel, first) && Marshalling(parcel, args...);
405     }
406     template<typename T, typename... Args>
Unmarshalling(Parcel & parcel,T & first,Args &...args)407     static bool Unmarshalling(Parcel& parcel, T& first, Args&... args)
408     {
409         return Unmarshalling(parcel, first) && Unmarshalling(parcel, args...);
410     }
411 
412     static bool Marshalling(Parcel& parcel, std::shared_ptr<Drawing::Data> val);
413     static bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::Data>& val);
414     static bool UnmarshallingWithCopy(Parcel& parcel, std::shared_ptr<Drawing::Data>& val);
415 
416     static void BeginNoSharedMem(std::thread::id tid);
417     static void EndNoSharedMem();
418     static bool GetUseSharedMem(std::thread::id tid);
419 private:
420     static bool WriteToParcel(Parcel& parcel, const void* data, size_t size);
421     static const void* ReadFromParcel(Parcel& parcel, size_t size, bool& isMalloc);
422     static bool SkipFromParcel(Parcel& parcel, size_t size);
423     static const void* ReadFromAshmem(Parcel& parcel, size_t size, bool& isMalloc);
424 
425     static constexpr size_t MAX_DATA_SIZE = 128 * 1024 * 1024; // 128M
426     static constexpr size_t MIN_DATA_SIZE = 8 * 1024;          // 8k
427 
428 #ifdef RS_PROFILER_ENABLED
429     friend class RSProfiler;
430 #endif
431 };
432 
433 } // namespace Rosen
434 } // namespace OHOS
435 
436 #endif // RENDER_SERVICE_BASE_TRANSACTION_RS_MARSHALLING_HELPER_H
437