• 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 "transaction/rs_marshalling_helper.h"
17 
18 #include <memory>
19 #include <message_parcel.h>
20 #include <sys/mman.h>
21 #include <unistd.h>
22 
23 #include "ashmem.h"
24 #include "include/core/SkDrawable.h"
25 #include "include/core/SkImage.h"
26 #include "include/core/SkPaint.h"
27 #include "include/core/SkPicture.h"
28 #include "include/core/SkSerialProcs.h"
29 #include "include/core/SkStream.h"
30 #include "include/core/SkTextBlob.h"
31 #include "include/core/SkTypeface.h"
32 #include "include/core/SkVertices.h"
33 #include "pixel_map.h"
34 #include "securec.h"
35 #include "src/core/SkAutoMalloc.h"
36 #include "src/core/SkPaintPriv.h"
37 #include "src/core/SkReadBuffer.h"
38 #include "src/core/SkWriteBuffer.h"
39 #include "src/image/SkImage_Base.h"
40 
41 #include "animation/rs_render_curve_animation.h"
42 #include "animation/rs_render_keyframe_animation.h"
43 #include "animation/rs_render_path_animation.h"
44 #include "animation/rs_render_spring_animation.h"
45 #include "animation/rs_render_transition.h"
46 #include "common/rs_color.h"
47 #include "common/rs_common_def.h"
48 #include "common/rs_matrix3.h"
49 #include "common/rs_vector4.h"
50 #include "modifier/rs_render_modifier.h"
51 #include "pipeline/rs_draw_cmd_list.h"
52 #include "platform/common/rs_log.h"
53 #include "render/rs_blur_filter.h"
54 #include "render/rs_filter.h"
55 #include "render/rs_image.h"
56 #include "render/rs_material_filter.h"
57 #include "render/rs_path.h"
58 #include "render/rs_shader.h"
59 #include "transaction/rs_ashmem_helper.h"
60 
61 namespace OHOS {
62 namespace Rosen {
63 
64 #define MARSHALLING_AND_UNMARSHALLING(TYPE, TYPENAME)                      \
65     bool RSMarshallingHelper::Marshalling(Parcel& parcel, const TYPE& val) \
66     {                                                                      \
67         return parcel.Write##TYPENAME(val);                                \
68     }                                                                      \
69     bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, TYPE& val)     \
70     {                                                                      \
71         return parcel.Read##TYPENAME(val);                                 \
72     }
73 
74 // basic types
75 MARSHALLING_AND_UNMARSHALLING(bool, Bool)
76 MARSHALLING_AND_UNMARSHALLING(int8_t, Int8)
77 MARSHALLING_AND_UNMARSHALLING(uint8_t, Uint8)
78 MARSHALLING_AND_UNMARSHALLING(int16_t, Int16)
79 MARSHALLING_AND_UNMARSHALLING(uint16_t, Uint16)
80 MARSHALLING_AND_UNMARSHALLING(int32_t, Int32)
81 MARSHALLING_AND_UNMARSHALLING(uint32_t, Uint32)
82 MARSHALLING_AND_UNMARSHALLING(int64_t, Int64)
83 MARSHALLING_AND_UNMARSHALLING(uint64_t, Uint64)
84 MARSHALLING_AND_UNMARSHALLING(float, Float)
85 MARSHALLING_AND_UNMARSHALLING(double, Double)
86 
87 #undef MARSHALLING_AND_UNMARSHALLING
88 
89 namespace {
90 template<typename T, typename P>
sk_reinterpret_cast(sk_sp<P> ptr)91 static inline sk_sp<T> sk_reinterpret_cast(sk_sp<P> ptr)
92 {
93     return sk_sp<T>(static_cast<T*>(SkSafeRef(ptr.get())));
94 }
95 } // namespace
96 
97 // SkData
Marshalling(Parcel & parcel,sk_sp<SkData> val)98 bool RSMarshallingHelper::Marshalling(Parcel& parcel, sk_sp<SkData> val)
99 {
100     if (!val) {
101         return parcel.WriteInt32(-1);
102     }
103 
104     bool ret = parcel.WriteInt32(val->size());
105     if (val->size() == 0) {
106         ROSEN_LOGW("unirender: RSMarshallingHelper::Marshalling SkData size is 0");
107         return ret;
108     }
109 
110     ret = ret && RSMarshallingHelper::WriteToParcel(parcel, val->data(), val->size());
111     if (!ret) {
112         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Marshalling SkData");
113     }
114     return ret;
115 }
Unmarshalling(Parcel & parcel,sk_sp<SkData> & val)116 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkData>& val)
117 {
118     int32_t size = parcel.ReadInt32();
119     if (size == -1) {
120         val = nullptr;
121         return true;
122     }
123     if (size == 0) {
124         ROSEN_LOGW("unirender: RSMarshallingHelper::Unmarshalling SkData size is 0");
125         val = SkData::MakeEmpty();
126         return true;
127     }
128 
129     const void* data = RSMarshallingHelper::ReadFromParcel(parcel, size);
130     if (data == nullptr) {
131         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkData");
132         return false;
133     }
134 
135     if (static_cast<uint32_t>(size) < MIN_DATA_SIZE) {
136         val = SkData::MakeWithoutCopy(data, size);
137     } else {
138         val = SkData::MakeFromMalloc(data, size);
139     }
140     return val != nullptr;
141 }
SkipSkData(Parcel & parcel)142 bool RSMarshallingHelper::SkipSkData(Parcel& parcel)
143 {
144     int32_t size = parcel.ReadInt32();
145     if (size <= 0) {
146         return true;
147     }
148     return SkipFromParcel(parcel, size);
149 }
150 
UnmarshallingWithCopy(Parcel & parcel,sk_sp<SkData> & val)151 bool RSMarshallingHelper::UnmarshallingWithCopy(Parcel& parcel, sk_sp<SkData>& val)
152 {
153     bool success = Unmarshalling(parcel, val);
154     if (success) {
155         if (val && val->size() < MIN_DATA_SIZE) {
156             val = SkData::MakeWithCopy(val->data(), val->size());
157         }
158     }
159     return success;
160 }
161 
162 // SkTypeface serial proc
SerializeTypeface(SkTypeface * tf,void * ctx)163 sk_sp<SkData> RSMarshallingHelper::SerializeTypeface(SkTypeface* tf, void* ctx)
164 {
165     if (tf == nullptr) {
166         ROSEN_LOGD("unirender: RSMarshallingHelper::SerializeTypeface SkTypeface is nullptr");
167         return nullptr;
168     }
169     return tf->serialize();
170 }
171 
172 // SkTypeface deserial proc
DeserializeTypeface(const void * data,size_t length,void * ctx)173 sk_sp<SkTypeface> RSMarshallingHelper::DeserializeTypeface(const void* data, size_t length, void* ctx)
174 {
175     SkMemoryStream stream(data, length);
176     return SkTypeface::MakeDeserialize(&stream);
177 }
178 
179 // SkTextBlob
Marshalling(Parcel & parcel,const sk_sp<SkTextBlob> & val)180 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkTextBlob>& val)
181 {
182     sk_sp<SkData> data;
183     if (!val) {
184         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling SkTextBlob is nullptr");
185         return Marshalling(parcel, data);
186     }
187     SkSerialProcs serialProcs;
188     serialProcs.fTypefaceProc = &RSMarshallingHelper::SerializeTypeface;
189     data = val->serialize(serialProcs);
190     return Marshalling(parcel, data);
191 }
Unmarshalling(Parcel & parcel,sk_sp<SkTextBlob> & val)192 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkTextBlob>& val)
193 {
194     sk_sp<SkData> data;
195     if (!Unmarshalling(parcel, data)) {
196         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkTextBlob");
197         return false;
198     }
199     if (data == nullptr) {
200         val = nullptr;
201         return true;
202     }
203     SkDeserialProcs deserialProcs;
204     deserialProcs.fTypefaceProc = &RSMarshallingHelper::DeserializeTypeface;
205     val = SkTextBlob::Deserialize(data->data(), data->size(), deserialProcs);
206     return val != nullptr;
207 }
208 
209 // SkPaint
Marshalling(Parcel & parcel,const SkPaint & val)210 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const SkPaint& val)
211 {
212     SkBinaryWriteBuffer writer;
213     writer.writePaint(val);
214     size_t length = writer.bytesWritten();
215     sk_sp<SkData> data = SkData::MakeUninitialized(length);
216     writer.writeToMemory(data->writable_data());
217     return Marshalling(parcel, data);
218 }
Unmarshalling(Parcel & parcel,SkPaint & val)219 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, SkPaint& val)
220 {
221     sk_sp<SkData> data;
222     if (!Unmarshalling(parcel, data)) {
223         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkPaint");
224         return false;
225     }
226     SkReadBuffer reader(data->data(), data->size());
227     reader.readPaint(&val, nullptr);
228     return true;
229 }
230 
231 // SkImage
Marshalling(Parcel & parcel,const sk_sp<SkImage> & val)232 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkImage>& val)
233 {
234     if (!val) {
235         return parcel.WriteInt32(-1);
236     }
237     int32_t type = val->isLazyGenerated();
238     parcel.WriteInt32(type);
239     if (type == 1) {
240         ROSEN_LOGD("RSMarshallingHelper::Marshalling SkImage isLazyGenerated");
241         SkBinaryWriteBuffer writer;
242         writer.writeImage(val.get());
243         size_t length = writer.bytesWritten();
244         sk_sp<SkData> data = SkData::MakeUninitialized(length);
245         writer.writeToMemory(data->writable_data());
246         return Marshalling(parcel, data);
247     } else {
248         SkBitmap bitmap;
249         if (!as_IB(val.get())->getROPixels(&bitmap)) {
250             ROSEN_LOGE("RSMarshallingHelper::Marshalling SkImage getROPixels failed");
251             return false;
252         }
253         SkPixmap pixmap;
254         if (!bitmap.peekPixels(&pixmap)) {
255             ROSEN_LOGE("RSMarshallingHelper::Marshalling SkImage peekPixels failed");
256             return false;
257         }
258         size_t rb = pixmap.rowBytes();
259         int width = pixmap.width();
260         int height = pixmap.height();
261         const void* addr = pixmap.addr();
262         size_t size = rb * static_cast<size_t>(height);
263 
264         parcel.WriteUint32(size);
265         if (!WriteToParcel(parcel, addr, size)) {
266             ROSEN_LOGE("RSMarshallingHelper::Marshalling SkImage WriteToParcel failed");
267             return false;
268         }
269 
270         parcel.WriteUint32(rb);
271         parcel.WriteInt32(width);
272         parcel.WriteInt32(height);
273 
274         parcel.WriteUint32(pixmap.colorType());
275         parcel.WriteUint32(pixmap.alphaType());
276 
277         if (pixmap.colorSpace() == nullptr) {
278             parcel.WriteUint32(0);
279             return true;
280         } else {
281             auto data = pixmap.colorSpace()->serialize();
282             parcel.WriteUint32(data->size());
283             if (!WriteToParcel(parcel, data->data(), data->size())) {
284                 ROSEN_LOGE("RSMarshallingHelper::Marshalling SkImage WriteToParcel colorSpace failed");
285                 return false;
286             }
287         }
288         return true;
289     }
290 }
291 
Unmarshalling(Parcel & parcel,sk_sp<SkImage> & val)292 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkImage>& val)
293 {
294     int32_t type = parcel.ReadInt32();
295     if (type == -1) {
296         val = nullptr;
297         return true;
298     }
299     if (type == 1) {
300         sk_sp<SkData> data;
301         ROSEN_LOGD("RSMarshallingHelper::Unmarshalling lazy");
302         if (!Unmarshalling(parcel, data)) {
303             ROSEN_LOGE("failed RSMarshallingHelper::Unmarshalling SkImage");
304             return false;
305         }
306         SkReadBuffer reader(data->data(), data->size());
307         val = reader.readImage();
308         return val != nullptr;
309     } else {
310         size_t pixmapSize = parcel.ReadUint32();
311         const void* addr = RSMarshallingHelper::ReadFromParcel(parcel, pixmapSize);
312         if (addr == nullptr) {
313             ROSEN_LOGE("failed RSMarshallingHelper::Unmarshalling SkData addr");
314             return false;
315         }
316 
317         size_t rb = parcel.ReadUint32();
318         int width = parcel.ReadInt32();
319         int height = parcel.ReadInt32();
320 
321         SkColorType colorType = static_cast<SkColorType>(parcel.ReadUint32());
322         SkAlphaType alphaType = static_cast<SkAlphaType>(parcel.ReadUint32());
323         sk_sp<SkColorSpace> colorSpace;
324 
325         size_t size = parcel.ReadUint32();
326         if (size == 0) {
327             colorSpace = nullptr;
328         } else {
329             const void* data = RSMarshallingHelper::ReadFromParcel(parcel, size);
330             if (data == nullptr) {
331                 ROSEN_LOGE("failed RSMarshallingHelper::Unmarshalling SkData data");
332                 return false;
333             }
334             colorSpace = SkColorSpace::Deserialize(data, size);
335             if (size >= MIN_DATA_SIZE) {
336                 free(const_cast<void*>(data));
337             }
338         }
339 
340         SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
341         auto skData = pixmapSize < MIN_DATA_SIZE ? SkData::MakeWithCopy(addr, pixmapSize)
342                                                  : SkData::MakeFromMalloc(addr, pixmapSize);
343         val = SkImage::MakeRasterData(imageInfo, skData, rb);
344         return val != nullptr;
345     }
346 }
347 
SkipSkImage(Parcel & parcel)348 bool RSMarshallingHelper::SkipSkImage(Parcel& parcel)
349 {
350     int32_t type = parcel.ReadInt32();
351     if (type == -1) {
352         return true;
353     }
354     sk_sp<SkData> data;
355     if (type == 1) {
356         ROSEN_LOGD("RSMarshallingHelper::SkipSkImage lazy");
357         return SkipSkData(parcel);
358     } else {
359         size_t pixmapSize = parcel.ReadUint32();
360         if (!SkipFromParcel(parcel, pixmapSize)) {
361             ROSEN_LOGE("failed RSMarshallingHelper::SkipSkImage SkData addr");
362             return false;
363         }
364 
365         parcel.ReadUint32();
366         parcel.ReadInt32();
367         parcel.ReadInt32();
368         parcel.ReadUint32();
369         parcel.ReadUint32();
370         size_t size = parcel.ReadUint32();
371         return size == 0 ? true : SkipFromParcel(parcel, size);
372     }
373 }
374 
375 // SkPicture
Marshalling(Parcel & parcel,const sk_sp<SkPicture> & val)376 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkPicture>& val)
377 {
378     sk_sp<SkData> data;
379     if (!val) {
380         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling SkPicture is nullptr");
381         return Marshalling(parcel, data);
382     }
383     data = val->serialize();
384     return Marshalling(parcel, data);
385 }
Unmarshalling(Parcel & parcel,sk_sp<SkPicture> & val)386 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkPicture>& val)
387 {
388     sk_sp<SkData> data;
389     if (!Unmarshalling(parcel, data)) {
390         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkPicture");
391         return false;
392     }
393     if (data == nullptr) {
394         val = nullptr;
395         return true;
396     }
397     val = SkPicture::MakeFromData(data->data(), data->size());
398     return val != nullptr;
399 }
400 
401 // SkVertices
Marshalling(Parcel & parcel,const sk_sp<SkVertices> & val)402 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkVertices>& val)
403 {
404     sk_sp<SkData> data;
405     if (!val) {
406         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling SkVertices is nullptr");
407         return Marshalling(parcel, data);
408     }
409     data = val->encode();
410     return Marshalling(parcel, data);
411 }
Unmarshalling(Parcel & parcel,sk_sp<SkVertices> & val)412 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkVertices>& val)
413 {
414     sk_sp<SkData> data;
415     if (!Unmarshalling(parcel, data)) {
416         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkVertices");
417         return false;
418     }
419     if (data == nullptr) {
420         val = nullptr;
421         return true;
422     }
423     val = SkVertices::Decode(data->data(), data->size());
424     return val != nullptr;
425 }
426 
427 // SkRect
Marshalling(Parcel & parcel,const SkRect & rect)428 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const SkRect& rect)
429 {
430     SkBinaryWriteBuffer writer;
431     writer.writeRect(rect);
432     size_t length = writer.bytesWritten();
433     sk_sp<SkData> data = SkData::MakeUninitialized(length);
434     writer.writeToMemory(data->writable_data());
435     return Marshalling(parcel, data);
436 }
Unmarshalling(Parcel & parcel,SkRect & rect)437 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, SkRect& rect)
438 {
439     sk_sp<SkData> data;
440     if (!Unmarshalling(parcel, data)) {
441         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkRect");
442         return false;
443     }
444     SkReadBuffer reader(data->data(), data->size());
445     reader.readRect(&rect);
446     return true;
447 }
448 
449 // SkRegion
Marshalling(Parcel & parcel,const SkRegion & region)450 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const SkRegion& region)
451 {
452     SkBinaryWriteBuffer writer;
453     writer.writeRegion(region);
454     size_t length = writer.bytesWritten();
455     sk_sp<SkData> data = SkData::MakeUninitialized(length);
456     writer.writeToMemory(data->writable_data());
457     return Marshalling(parcel, data);
458 }
Unmarshalling(Parcel & parcel,SkRegion & region)459 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, SkRegion& region)
460 {
461     sk_sp<SkData> data;
462     if (!Unmarshalling(parcel, data)) {
463         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkRegion");
464         return false;
465     }
466     SkReadBuffer reader(data->data(), data->size());
467     reader.readRegion(&region);
468     return true;
469 }
470 
471 // SKPath
Marshalling(Parcel & parcel,const SkPath & val)472 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const SkPath& val)
473 {
474     SkBinaryWriteBuffer writer;
475     writer.writePath(val);
476     size_t length = writer.bytesWritten();
477     sk_sp<SkData> data = SkData::MakeUninitialized(length);
478     writer.writeToMemory(data->writable_data());
479     return Marshalling(parcel, data);
480 }
Unmarshalling(Parcel & parcel,SkPath & val)481 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, SkPath& val)
482 {
483     sk_sp<SkData> data;
484     if (!Unmarshalling(parcel, data)) {
485         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SKPath");
486         return false;
487     }
488     SkReadBuffer reader(data->data(), data->size());
489     reader.readPath(&val);
490     return true;
491 }
492 
493 // SkFlattenable
Marshalling(Parcel & parcel,const sk_sp<SkFlattenable> & val)494 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkFlattenable>& val)
495 {
496     if (!val) {
497         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling SkFlattenable is nullptr");
498         return parcel.WriteInt32(-1);
499     }
500     sk_sp<SkData> data = val->serialize();
501     return parcel.WriteInt32(val->getFlattenableType()) && Marshalling(parcel, data);
502 }
Unmarshalling(Parcel & parcel,sk_sp<SkFlattenable> & val)503 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkFlattenable>& val)
504 {
505     int32_t type = parcel.ReadInt32();
506     if (type == -1) {
507         val = nullptr;
508         return true;
509     }
510     sk_sp<SkData> data;
511     if (!Unmarshalling(parcel, data)) {
512         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkFlattenable");
513         return false;
514     }
515     val = SkFlattenable::Deserialize(static_cast<SkFlattenable::Type>(type), data->data(), data->size());
516     return val != nullptr;
517 }
518 
519 // SkDrawable
Marshalling(Parcel & parcel,const sk_sp<SkDrawable> & val)520 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkDrawable>& val)
521 {
522     if (!val) {
523         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling SkDrawable is nullptr");
524     }
525     return Marshalling(parcel, sk_sp<SkFlattenable>(val));
526 }
Unmarshalling(Parcel & parcel,sk_sp<SkDrawable> & val)527 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkDrawable>& val)
528 {
529     sk_sp<SkFlattenable> flattenablePtr;
530     if (!Unmarshalling(parcel, flattenablePtr)) {
531         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkDrawable");
532         return false;
533     }
534     val = sk_reinterpret_cast<SkDrawable>(flattenablePtr);
535     return true;
536 }
537 
538 // SkImageFilter
Marshalling(Parcel & parcel,const sk_sp<SkImageFilter> & val)539 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const sk_sp<SkImageFilter>& val)
540 {
541     if (!val) {
542         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling SkImageFilter is nullptr");
543     }
544     return Marshalling(parcel, sk_sp<SkFlattenable>(val));
545 }
Unmarshalling(Parcel & parcel,sk_sp<SkImageFilter> & val)546 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, sk_sp<SkImageFilter>& val)
547 {
548     sk_sp<SkFlattenable> flattenablePtr;
549     if (!Unmarshalling(parcel, flattenablePtr)) {
550         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling SkImageFilter");
551         return false;
552     }
553     val = sk_reinterpret_cast<SkImageFilter>(flattenablePtr);
554     return true;
555 }
556 
557 // RSShader
Marshalling(Parcel & parcel,const std::shared_ptr<RSShader> & val)558 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<RSShader>& val)
559 {
560     if (!val) {
561         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling RSShader is nullptr");
562         return parcel.WriteInt32(-1);
563     }
564     return parcel.WriteInt32(1) && Marshalling(parcel, sk_sp<SkFlattenable>(val->GetSkShader()));
565 }
Unmarshalling(Parcel & parcel,std::shared_ptr<RSShader> & val)566 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSShader>& val)
567 {
568     if (parcel.ReadInt32() == -1) {
569         val = nullptr;
570         return true;
571     }
572     sk_sp<SkFlattenable> flattenablePtr;
573     if (!Unmarshalling(parcel, flattenablePtr)) {
574         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling RSShader");
575         return false;
576     }
577     auto shaderPtr = sk_reinterpret_cast<SkShader>(flattenablePtr);
578     val = RSShader::CreateRSShader(shaderPtr);
579     return val != nullptr;
580 }
581 
582 // RSPath
Marshalling(Parcel & parcel,const std::shared_ptr<RSPath> & val)583 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<RSPath>& val)
584 {
585     if (!val) {
586         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling RSPath is nullptr");
587         return parcel.WriteInt32(-1);
588     }
589     return parcel.WriteInt32(1) && Marshalling(parcel, val->GetSkiaPath());
590 }
591 
Unmarshalling(Parcel & parcel,std::shared_ptr<RSPath> & val)592 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSPath>& val)
593 {
594     if (parcel.ReadInt32() == -1) {
595         val = nullptr;
596         return true;
597     }
598     SkPath path;
599     if (!Unmarshalling(parcel, path)) {
600         ROSEN_LOGE("unirender: failed RSMarshallingHelper::Unmarshalling RSPath");
601         return false;
602     }
603     val = RSPath::CreateRSPath(path);
604     return val != nullptr;
605 }
606 
607 // RSMask
Marshalling(Parcel & parcel,const std::shared_ptr<RSMask> & val)608 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<RSMask>& val)
609 {
610     if (!val) {
611         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling RSMask is nullptr");
612         return parcel.WriteInt32(-1);
613     }
614     return parcel.WriteInt32(1) && val->Marshalling(parcel);
615 }
Unmarshalling(Parcel & parcel,std::shared_ptr<RSMask> & val)616 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSMask>& val)
617 {
618     if (parcel.ReadInt32() == -1) {
619         val = nullptr;
620         return true;
621     }
622     val.reset(RSMask::Unmarshalling(parcel));
623     return val != nullptr;
624 }
625 
626 // RSFilter
Marshalling(Parcel & parcel,const std::shared_ptr<RSFilter> & val)627 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<RSFilter>& val)
628 {
629     if (!val) {
630         return parcel.WriteInt32(RSFilter::NONE);
631     }
632     bool success = parcel.WriteInt32(static_cast<int>(val->GetFilterType()));
633     switch (val->GetFilterType()) {
634         case RSFilter::BLUR: {
635             auto blur = std::static_pointer_cast<RSBlurFilter>(val);
636             success = success && parcel.WriteFloat(blur->GetBlurRadiusX()) && parcel.WriteFloat(blur->GetBlurRadiusY());
637             break;
638         }
639         case RSFilter::MATERIAL: {
640             auto material = std::static_pointer_cast<RSMaterialFilter>(val);
641             success = success && parcel.WriteInt32(material->style_) && parcel.WriteFloat(material->dipScale_) &&
642                       parcel.WriteInt32(material->colorMode_);
643             break;
644         }
645         default:
646             break;
647     }
648     return success;
649 }
Unmarshalling(Parcel & parcel,std::shared_ptr<RSFilter> & val)650 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSFilter>& val)
651 {
652     int type = 0;
653     bool success = parcel.ReadInt32(type);
654     switch (static_cast<RSFilter::FilterType>(type)) {
655         case RSFilter::BLUR: {
656             float blurRadiusX;
657             float blurRadiusY;
658             success = success && parcel.ReadFloat(blurRadiusX) && parcel.ReadFloat(blurRadiusY);
659             if (success) {
660                 val = RSFilter::CreateBlurFilter(blurRadiusX, blurRadiusY);
661             }
662             break;
663         }
664         case RSFilter::MATERIAL: {
665             int style;
666             float dipScale;
667             int colorMode;
668             success = success && parcel.ReadInt32(style) && parcel.ReadFloat(dipScale) && parcel.ReadInt32(colorMode);
669             if (success) {
670                 val = RSFilter::CreateMaterialFilter(style, dipScale, static_cast<BLUR_COLOR_MODE>(colorMode));
671             }
672             break;
673         }
674         default: {
675             val = nullptr;
676             break;
677         }
678     }
679     return success;
680 }
681 
682 // RSImage
Marshalling(Parcel & parcel,const std::shared_ptr<RSImage> & val)683 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<RSImage>& val)
684 {
685     if (!val) {
686         ROSEN_LOGD("unirender: RSMarshallingHelper::Marshalling RSImage is nullptr");
687         return parcel.WriteInt32(-1);
688     }
689     return parcel.WriteInt32(1) && val->Marshalling(parcel);
690 }
Unmarshalling(Parcel & parcel,std::shared_ptr<RSImage> & val)691 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSImage>& val)
692 {
693     if (parcel.ReadInt32() == -1) {
694         val = nullptr;
695         return true;
696     }
697     val.reset(RSImage::Unmarshalling(parcel));
698     return val != nullptr;
699 }
700 
701 // Media::PixelMap
Marshalling(Parcel & parcel,const std::shared_ptr<Media::PixelMap> & val)702 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Media::PixelMap>& val)
703 {
704     if (!val) {
705         return parcel.WriteInt32(-1);
706     }
707     if (!(parcel.WriteInt32(1) && val->Marshalling(parcel))) {
708         ROSEN_LOGE("failed RSMarshallingHelper::Marshalling Media::PixelMap");
709         return false;
710     }
711     return true;
712 }
Unmarshalling(Parcel & parcel,std::shared_ptr<Media::PixelMap> & val)713 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Media::PixelMap>& val)
714 {
715     if (parcel.ReadInt32() == -1) {
716         val = nullptr;
717         return true;
718     }
719     val.reset(Media::PixelMap::Unmarshalling(parcel));
720     if (val == nullptr) {
721         ROSEN_LOGE("failed RSMarshallingHelper::Unmarshalling Media::PixelMap");
722         return false;
723     }
724     return true;
725 }
726 
727 #define MARSHALLING_AND_UNMARSHALLING(TYPE)                                                 \
728     bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<TYPE>& val) \
729     {                                                                                       \
730         return parcel.WriteParcelable(val.get());                                           \
731     }                                                                                       \
732     bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<TYPE>& val)     \
733     {                                                                                       \
734         val.reset(parcel.ReadParcelable<TYPE>());                                           \
735         return val != nullptr;                                                              \
736     }
737 MARSHALLING_AND_UNMARSHALLING(RSRenderTransition)
MARSHALLING_AND_UNMARSHALLING(RSRenderTransitionEffect)738 MARSHALLING_AND_UNMARSHALLING(RSRenderTransitionEffect)
739 MARSHALLING_AND_UNMARSHALLING(DrawCmdList)
740 #undef MARSHALLING_AND_UNMARSHALLING
741 
742 #define MARSHALLING_AND_UNMARSHALLING(TEMPLATE)                                                 \
743     bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<TEMPLATE>& val) \
744     {                                                                                           \
745         return parcel.WriteParcelable(val.get());                                               \
746     }                                                                                           \
747     bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<TEMPLATE>& val)     \
748     {                                                                                           \
749         val.reset(parcel.ReadParcelable<TEMPLATE>());                                           \
750         return val != nullptr;                                                                  \
751     }
752 
753 MARSHALLING_AND_UNMARSHALLING(RSRenderCurveAnimation)
754 MARSHALLING_AND_UNMARSHALLING(RSRenderKeyframeAnimation)
755 MARSHALLING_AND_UNMARSHALLING(RSRenderSpringAnimation)
756 MARSHALLING_AND_UNMARSHALLING(RSRenderPathAnimation)
757 #undef MARSHALLING_AND_UNMARSHALLING
758 
759 bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<RSRenderModifier>& val)
760 {
761     return val != nullptr && val->Marshalling(parcel);
762 }
Unmarshalling(Parcel & parcel,std::shared_ptr<RSRenderModifier> & val)763 bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSRenderModifier>& val)
764 {
765     val.reset(RSRenderModifier::Unmarshalling(parcel));
766     return val != nullptr;
767 }
768 
769 #define MARSHALLING_AND_UNMARSHALLING(TEMPLATE)                                                    \
770     template<typename T>                                                                           \
771     bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<TEMPLATE<T>>& val) \
772     {                                                                                              \
773         return parcel.WriteUint64(val->GetId()) && Marshalling(parcel, val->Get());                \
774     }                                                                                              \
775     template<typename T>                                                                           \
776     bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<TEMPLATE<T>>& val)     \
777     {                                                                                              \
778         PropertyId id = 0;                                                                         \
779         if (!parcel.ReadUint64(id)) {                                                              \
780             return false;                                                                          \
781         }                                                                                          \
782         T value;                                                                                   \
783         if (!Unmarshalling(parcel, value)) {                                                       \
784             return false;                                                                          \
785         }                                                                                          \
786         val.reset(new TEMPLATE<T>(value, id));                                                     \
787         return val != nullptr;                                                                     \
788     }
789 
790 MARSHALLING_AND_UNMARSHALLING(RSRenderProperty)
MARSHALLING_AND_UNMARSHALLING(RSRenderAnimatableProperty)791 MARSHALLING_AND_UNMARSHALLING(RSRenderAnimatableProperty)
792 #undef MARSHALLING_AND_UNMARSHALLING
793 
794 #define EXPLICIT_INSTANTIATION(TEMPLATE, TYPE)                                                                  \
795     template bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<TEMPLATE<TYPE>>& val); \
796     template bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<TEMPLATE<TYPE>>& val);
797 
798 #define BATCH_EXPLICIT_INSTANTIATION(TEMPLATE)                  \
799     EXPLICIT_INSTANTIATION(TEMPLATE, bool)                      \
800     EXPLICIT_INSTANTIATION(TEMPLATE, float)                     \
801     EXPLICIT_INSTANTIATION(TEMPLATE, int)                       \
802     EXPLICIT_INSTANTIATION(TEMPLATE, Color)                     \
803     EXPLICIT_INSTANTIATION(TEMPLATE, Gravity)                   \
804     EXPLICIT_INSTANTIATION(TEMPLATE, Matrix3f)                  \
805     EXPLICIT_INSTANTIATION(TEMPLATE, Quaternion)                \
806     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<RSFilter>) \
807     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<RSImage>)  \
808     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<RSMask>)   \
809     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<RSPath>)   \
810     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<RSShader>) \
811     EXPLICIT_INSTANTIATION(TEMPLATE, Vector2f)                  \
812     EXPLICIT_INSTANTIATION(TEMPLATE, Vector4<uint32_t>)         \
813     EXPLICIT_INSTANTIATION(TEMPLATE, Vector4<Color>)            \
814     EXPLICIT_INSTANTIATION(TEMPLATE, Vector4f)                  \
815     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<DrawCmdList>)
816 
817 BATCH_EXPLICIT_INSTANTIATION(RSRenderProperty)
818 
819 #undef EXPLICIT_INSTANTIATION
820 #undef BATCH_EXPLICIT_INSTANTIATION
821 
822 #define EXPLICIT_INSTANTIATION(TEMPLATE, TYPE)                                                                  \
823     template bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<TEMPLATE<TYPE>>& val); \
824     template bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<TEMPLATE<TYPE>>& val);
825 
826 #define BATCH_EXPLICIT_INSTANTIATION(TEMPLATE)                  \
827     EXPLICIT_INSTANTIATION(TEMPLATE, float)                     \
828     EXPLICIT_INSTANTIATION(TEMPLATE, int)                       \
829     EXPLICIT_INSTANTIATION(TEMPLATE, Color)                     \
830     EXPLICIT_INSTANTIATION(TEMPLATE, Matrix3f)                  \
831     EXPLICIT_INSTANTIATION(TEMPLATE, Quaternion)                \
832     EXPLICIT_INSTANTIATION(TEMPLATE, std::shared_ptr<RSFilter>) \
833     EXPLICIT_INSTANTIATION(TEMPLATE, Vector2f)                  \
834     EXPLICIT_INSTANTIATION(TEMPLATE, Vector4<Color>)            \
835     EXPLICIT_INSTANTIATION(TEMPLATE, Vector4f)
836 
837 BATCH_EXPLICIT_INSTANTIATION(RSRenderAnimatableProperty)
838 
839 #undef EXPLICIT_INSTANTIATION
840 #undef BATCH_EXPLICIT_INSTANTIATION
841 
842 bool RSMarshallingHelper::WriteToParcel(Parcel& parcel, const void* data, size_t size)
843 {
844     if (data == nullptr) {
845         ROSEN_LOGE("RSMarshallingHelper::WriteToParcel data is nullptr");
846         return false;
847     }
848     if (size > MAX_DATA_SIZE) {
849         ROSEN_LOGD("RSMarshallingHelper::WriteToParcel data exceed MAX_DATA_SIZE, size:%zu", size);
850     }
851 
852     if (!parcel.WriteUint32(size)) {
853         return false;
854     }
855     if (size < MIN_DATA_SIZE) {
856         return parcel.WriteUnpadBuffer(data, size);
857     }
858 
859     // write to ashmem
860     auto ashmemAllocator = AshmemAllocator::CreateAshmemAllocator(size, PROT_READ | PROT_WRITE);
861     if (!ashmemAllocator) {
862         ROSEN_LOGE("RSMarshallingHelper::WriteToParcel CreateAshmemAllocator fail");
863         return false;
864     }
865     int fd = ashmemAllocator->GetFd();
866     if (!(static_cast<MessageParcel*>(&parcel)->WriteFileDescriptor(fd))) {
867         ROSEN_LOGE("RSMarshallingHelper::WriteToParcel WriteFileDescriptor error");
868         return false;
869     }
870     if (!ashmemAllocator->WriteToAshmem(data, size)) {
871         ROSEN_LOGE("RSMarshallingHelper::WriteToParcel memcpy_s failed");
872         return false;
873     }
874     return true;
875 }
876 
ReadFromParcel(Parcel & parcel,size_t size)877 const void* RSMarshallingHelper::ReadFromParcel(Parcel& parcel, size_t size)
878 {
879     uint32_t bufferSize = parcel.ReadUint32();
880     if (static_cast<unsigned int>(bufferSize) != size) {
881         ROSEN_LOGE("RSMarshallingHelper::ReadFromParcel size mismatch");
882         return nullptr;
883     }
884 
885     if (static_cast<unsigned int>(bufferSize) < MIN_DATA_SIZE) {
886         return parcel.ReadUnpadBuffer(size);
887     }
888     // read from ashmem
889     int fd = static_cast<MessageParcel*>(&parcel)->ReadFileDescriptor();
890     auto ashmemAllocator = AshmemAllocator::CreateAshmemAllocatorWithFd(fd, size, PROT_READ);
891     if (!ashmemAllocator) {
892         ROSEN_LOGE("RSMarshallingHelper::ReadFromParcel CreateAshmemAllocator fail");
893         return nullptr;
894     }
895     return ashmemAllocator->CopyFromAshmem(size);
896 }
897 
SkipFromParcel(Parcel & parcel,size_t size)898 bool RSMarshallingHelper::SkipFromParcel(Parcel& parcel, size_t size)
899 {
900     int32_t bufferSize = parcel.ReadInt32();
901     if (static_cast<unsigned int>(bufferSize) != size) {
902         ROSEN_LOGE("RSMarshallingHelper::SkipFromParcel size mismatch");
903         return false;
904     }
905 
906     if (static_cast<unsigned int>(bufferSize) < MIN_DATA_SIZE) {
907         parcel.SkipBytes(size);
908         return true;
909     }
910     // read from ashmem
911     int fd = static_cast<MessageParcel*>(&parcel)->ReadFileDescriptor();
912     auto ashmemAllocator = AshmemAllocator::CreateAshmemAllocatorWithFd(fd, size, PROT_READ);
913     return ashmemAllocator != nullptr;
914 }
915 } // namespace Rosen
916 } // namespace OHOS
917