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(®ion);
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