1 /*
2  * Copyright (C) 2024 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 <message_parcel.h>
17 #include <securec.h>
18 #include <surface_buffer.h>
19 #include <sys/mman.h>
20 
21 #include "media_errors.h"
22 #include "pixel_map.h"
23 #ifdef RS_PROFILER_SUPPORTS_PIXELMAP_YUV_EXT
24 #include "pixel_yuv_ext.h"
25 #else
26 #include "pixel_yuv.h"
27 #endif
28 #include "rs_profiler.h"
29 #include "rs_profiler_cache.h"
30 #include "rs_profiler_log.h"
31 #include "rs_profiler_utils.h"
32 #include "rs_profiler_log.h"
33 
34 #include "transaction/rs_marshalling_helper.h"
35 #include "platform/common/rs_system_properties.h"
36 
37 namespace OHOS::Media {
38 
IncrementSurfaceBufferReference(sptr<SurfaceBuffer>& buffer)39 static SurfaceBuffer* IncrementSurfaceBufferReference(sptr<SurfaceBuffer>& buffer)
40 {
41     if (auto object = buffer.GetRefPtr()) {
42         auto ref = reinterpret_cast<OHOS::RefBase*>(object);
43         ref->IncStrongRef(ref);
44         return object;
45     }
46     return nullptr;
47 }
48 
IsDataValid(const void* data, size_t size)49 static bool IsDataValid(const void* data, size_t size)
50 {
51     return data && (size > 0);
52 }
53 
GenerateRawCopy(const uint8_t* data, size_t size)54 static std::vector<uint8_t> GenerateRawCopy(const uint8_t* data, size_t size)
55 {
56     std::vector<uint8_t> out;
57     if (IsDataValid(data, size)) {
58         out.insert(out.end(), data, data + size);
59     }
60     return out;
61 }
62 
GenerateMiniatureAstc(const uint8_t* data, size_t size)63 static std::vector<uint8_t> GenerateMiniatureAstc(const uint8_t* data, size_t size)
64 {
65     constexpr uint32_t astcBytesPerPixel = 16u;
66     return GenerateRawCopy(data, astcBytesPerPixel);
67 }
68 
GenerateMiniature(const uint8_t* data, size_t size, uint32_t pixelBytes)69 static std::vector<uint8_t> GenerateMiniature(const uint8_t* data, size_t size, uint32_t pixelBytes)
70 {
71     if (!IsDataValid(data, size)) {
72         return {};
73     }
74 
75     constexpr uint32_t rgbaBytesPerPixel = 4u;
76     constexpr uint32_t pixelBytesThreshold = 256u; // in case the pixelBytes field in the map has invalid value
77     const uint32_t bytesPerPixel =
78         ((pixelBytes > 0) && (pixelBytes < pixelBytesThreshold)) ? pixelBytes : rgbaBytesPerPixel;
79 
80     const auto pixelCount = size / bytesPerPixel;
81 
82     std::vector<uint64_t> averageValue(bytesPerPixel, 0);
83     constexpr uint32_t sampleCount = 100u;
84     for (uint32_t sample = 0; sample < sampleCount; sample++) {
85         for (uint32_t channel = 0; channel < bytesPerPixel; channel++) {
86             const size_t dataIdx = (sample * pixelCount / sampleCount) * bytesPerPixel + channel;
87             averageValue[channel] += (dataIdx < size) ? data[dataIdx] : 0;
88         }
89     }
90 
91     std::vector<uint8_t> out(bytesPerPixel, 0);
92     for (uint32_t i = 0; i < bytesPerPixel; i++) {
93         out[i] = static_cast<uint8_t>(averageValue[i] / sampleCount);
94     }
95     return out;
96 }
97 
GenerateImageData(const uint8_t* data, size_t size, bool isAstc, uint32_t pixelBytes)98 static std::vector<uint8_t> GenerateImageData(const uint8_t* data, size_t size, bool isAstc, uint32_t pixelBytes)
99 {
100     if (!Rosen::RSProfiler::IsBetaRecordEnabled()) {
101         return GenerateRawCopy(data, size);
102     }
103 
104     return isAstc ? GenerateMiniatureAstc(data, size) : GenerateMiniature(data, size, pixelBytes);
105 }
106 
GenerateImageData(const uint8_t* data, size_t size, PixelMap& map)107 static std::vector<uint8_t> GenerateImageData(const uint8_t* data, size_t size, PixelMap& map)
108 {
109     return GenerateImageData(data, size, map.IsAstc(), map.GetPixelBytes());
110 }
111 
CopyImageData(const uint8_t* srcImage, size_t srcSize, uint8_t* dstImage, size_t dstSize)112 static bool CopyImageData(const uint8_t* srcImage, size_t srcSize, uint8_t* dstImage, size_t dstSize)
113 {
114     if (!srcImage || !dstImage || (srcSize == 0) || (dstSize == 0) || (srcSize > dstSize)) {
115         return false;
116     }
117 
118     if (dstSize == srcSize) {
119         return Rosen::Utils::Move(dstImage, dstSize, srcImage, srcSize);
120     }
121 
122     for (size_t offset = 0; offset < dstSize;) {
123         const size_t size = std::min(dstSize - offset, srcSize);
124         if (!Rosen::Utils::Move(dstImage + offset, size, srcImage, size)) {
125             return false;
126         }
127         offset += size;
128     }
129 
130     return true;
131 }
132 
CopyImageData(const std::vector<uint8_t>& data, uint8_t* dstImage, size_t dstSize)133 static bool CopyImageData(const std::vector<uint8_t>& data, uint8_t* dstImage, size_t dstSize)
134 {
135     return CopyImageData(data.data(), data.size(), dstImage, dstSize);
136 }
137 
CopyImageData(const Rosen::Image* image, uint8_t* dstImage, size_t dstSize)138 static bool CopyImageData(const Rosen::Image* image, uint8_t* dstImage, size_t dstSize)
139 {
140     return image ? CopyImageData(image->data, dstImage, dstSize) : false;
141 }
142 
143 struct UnmarshallingContext {
144 public:
145     static constexpr int headerLength = 24; // NOLINT
146 
147 public:
UnmarshallingContextOHOS::Media::UnmarshallingContext148     explicit UnmarshallingContext(Parcel& parcel) : parcel(parcel) {}
149 
GatherImageFromFileOHOS::Media::UnmarshallingContext150     bool GatherImageFromFile(const Rosen::Image* image)
151     {
152         if ((size <= 0) || (size > Rosen::Image::maxSize)) {
153             return false;
154         }
155 
156         base = new (std::nothrow) uint8_t[size];
157         if (!base) {
158             return false;
159         }
160 
161         if (!CopyImageData(image, base, size)) {
162             delete[] base;
163             base = nullptr;
164             return false;
165         }
166 
167         context = nullptr;
168         return true;
169     }
170 
GatherDmaImageFromFileOHOS::Media::UnmarshallingContext171     bool GatherDmaImageFromFile(const Rosen::Image* image)
172     {
173         if ((size <= 0) || (size > Rosen::Image::maxSize)) {
174             return false;
175         }
176 
177         sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
178         if (!surfaceBuffer) {
179             return false;
180         }
181 
182         const BufferRequestConfig config = { .width = image->dmaWidth,
183             .height = image->dmaHeight,
184             .strideAlignment = image->dmaStride,
185             .format = image->dmaFormat,
186             .usage = image->dmaUsage };
187         surfaceBuffer->Alloc(config);
188 
189         base = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
190         if (base && CopyImageData(image, base, image->dmaSize)) {
191             context = IncrementSurfaceBufferReference(surfaceBuffer);
192             return true;
193         }
194         return false;
195     }
196 
IsAshmemSizeValidOHOS::Media::UnmarshallingContext197     bool IsAshmemSizeValid(int32_t file) const
198     {
199         return astc || (static_cast<int32_t>(size) == AshmemGetSize(file));
200     }
201 
IsYUVOHOS::Media::UnmarshallingContext202     bool IsYUV() const
203     {
204         return (info.pixelFormat == PixelFormat::NV12) || (info.pixelFormat == PixelFormat::NV21) ||
205                (info.pixelFormat == PixelFormat::YCBCR_P010) || (info.pixelFormat == PixelFormat::YCRCB_P010);
206     }
207 
IsASTCOHOS::Media::UnmarshallingContext208     bool IsASTC() const
209     {
210         return (info.pixelFormat == PixelFormat::ASTC_4x4) || (info.pixelFormat == PixelFormat::ASTC_6x6) ||
211                (info.pixelFormat == PixelFormat::ASTC_8x8);
212     }
213 
IsRGBAOHOS::Media::UnmarshallingContext214     bool IsRGBA() const
215     {
216         return (info.pixelFormat == PixelFormat::ARGB_8888) || (info.pixelFormat == PixelFormat::BGRA_8888) ||
217                (info.pixelFormat == PixelFormat::RGBA_8888) || (info.pixelFormat == PixelFormat::RGBA_1010102) ||
218                (info.pixelFormat == PixelFormat::CMYK) || (info.pixelFormat == PixelFormat::RGBA_F16) ||
219                (info.pixelFormat == PixelFormat::RGBA_U16);
220     }
221 
IsRGBOHOS::Media::UnmarshallingContext222     bool IsRGB() const
223     {
224         return (info.pixelFormat == PixelFormat::RGB_888) || (info.pixelFormat == PixelFormat::RGB_565);
225     }
226 
IsR8OHOS::Media::UnmarshallingContext227     bool IsR8() const
228     {
229         return (info.pixelFormat == PixelFormat::ALPHA_8);
230     }
231 
IsFormatValidOHOS::Media::UnmarshallingContext232     bool IsFormatValid() const
233     {
234         return IsR8() || IsRGB() || IsRGBA() || IsASTC() || IsYUV();
235     }
236 
IsSizeValidOHOS::Media::UnmarshallingContext237     bool IsSizeValid() const
238     {
239         const auto rawSize = static_cast<size_t>(rowPitch * info.size.height);
240         return (astc || IsYUV() || (size == rawSize) || (info.pixelFormat == PixelFormat::RGBA_F16));
241     }
242 
243 public:
244     Parcel& parcel;
245     std::unique_ptr<PixelMap> map;
246     ImageInfo info;
247     bool editable = false;
248     bool astc = false;
249     int32_t csm = 0;
250     uint32_t versionId = 0u;
251     AllocatorType allocType = AllocatorType::DEFAULT;
252     size_t rowPitch = 0;
253     size_t size = 0;
254     uint8_t* base = nullptr;
255     void* context = nullptr;
256 };
257 
258 // This class has to be 'reimplemented' here to get access to the PixelMap's private functions.
259 // It works ONLY thanks to the 'friend class ImageSource' in PixelMap.
260 class ImageSource {
261 public:
262     static PixelMap* Unmarshal(Parcel& parcel);
263     static bool Marshal(Parcel& parcel, PixelMap& map);
264 
265 private:
266     static void CacheImage(
267         uint64_t id, const std::vector<uint8_t>& data, size_t skipBytes, BufferHandle* bufferHandle = nullptr);
268     static Rosen::Image* GetCachedImage(uint64_t id);
269 
270     static uint8_t* MapImage(int32_t file, size_t size, int32_t flags);
271     static void UnmapImage(void* image, size_t size);
272 
273     static void OnClientMarshalling(PixelMap& map, uint64_t id);
274 
275     static bool InitUnmarshalling(UnmarshallingContext& context);
276     static bool UnmarshalFromSharedMemory(UnmarshallingContext& context, uint64_t id);
277     static bool UnmarshalFromDMA(UnmarshallingContext& context, uint64_t id);
278     static bool UnmarshalFromData(UnmarshallingContext& context);
279     static PixelMap* FinalizeUnmarshalling(UnmarshallingContext& context);
280 };
281 
CacheImage( uint64_t id, const std::vector<uint8_t>& data, size_t skipBytes, BufferHandle* bufferHandle)282 void ImageSource::CacheImage(
283     uint64_t id, const std::vector<uint8_t>& data, size_t skipBytes, BufferHandle* bufferHandle)
284 {
285     if (data.empty()) {
286         return;
287     }
288 
289     if (bufferHandle && ((bufferHandle->width == 0) || (bufferHandle->height == 0))) {
290         return;
291     }
292 
293     if (Rosen::RSProfiler::GetMode() != Rosen::Mode::WRITE && Rosen::RSProfiler::GetMode() != Rosen::Mode::WRITE_EMUL) {
294         return;
295     }
296 
297     Rosen::Image image;
298     image.data = data;
299 
300     if (bufferHandle) {
301         image.dmaSize = static_cast<size_t>(bufferHandle->size);
302         image.dmaWidth = bufferHandle->width;
303         image.dmaHeight = bufferHandle->height;
304         image.dmaStride = bufferHandle->stride;
305         image.dmaFormat = bufferHandle->format;
306         image.dmaUsage = bufferHandle->usage;
307     }
308 
309     image.parcelSkipBytes = skipBytes;
310     Rosen::ImageCache::Add(id, std::move(image));
311 }
312 
GetCachedImage(uint64_t id)313 Rosen::Image* ImageSource::GetCachedImage(uint64_t id)
314 {
315     return Rosen::ImageCache::Get(id);
316 }
317 
MapImage(int32_t file, size_t size, int32_t flags)318 uint8_t* ImageSource::MapImage(int32_t file, size_t size, int32_t flags)
319 {
320     auto image = ::mmap(nullptr, size, flags, MAP_SHARED, file, 0);
321     return (image != MAP_FAILED) ? reinterpret_cast<uint8_t*>(image) : nullptr; // NOLINT
322 }
323 
UnmapImage(void* image, size_t size)324 void ImageSource::UnmapImage(void* image, size_t size)
325 {
326     if (IsDataValid(image, size)) {
327         ::munmap(image, size);
328     }
329 }
330 
InitUnmarshalling(UnmarshallingContext& context)331 bool ImageSource::InitUnmarshalling(UnmarshallingContext& context)
332 {
333     if (!PixelMap::ReadImageInfo(context.parcel, context.info)) {
334         HRPE("Unmarshal: PixelMap::ReadImageInfo failed");
335         return false;
336     }
337 
338     if (context.IsYUV()) {
339 #ifdef RS_PROFILER_SUPPORTS_PIXELMAP_YUV_EXT
340         context.map = std::make_unique<PixelYuvExt>();
341         HRPI("Unmarshal: PixelYuvExt creation in progress...");
342 #else
343         context.map = std::make_unique<PixelYuv>();
344         HRPI("Unmarshal: PixelYuv creation in progress...");
345 #endif
346     } else {
347         context.map = std::make_unique<PixelMap>();
348         HRPI("Unmarshal: PixelMap creation in progress...");
349     }
350 
351     if (!context.map) {
352         HRPE("Unmarshal: Pixel map creation failed");
353         return false;
354     }
355 
356     context.editable = context.parcel.ReadBool();
357     context.astc = context.parcel.ReadBool();
358     context.allocType = static_cast<AllocatorType>(context.parcel.ReadInt32());
359     context.csm = context.parcel.ReadInt32();
360     context.rowPitch = static_cast<size_t>(context.parcel.ReadInt32());
361     context.versionId = context.parcel.ReadUint32();
362     context.size = static_cast<size_t>(context.parcel.ReadInt32());
363 
364     if (!context.IsFormatValid()) {
365         HRPE("Unmarshal: Invalid pixel format");
366         return false;
367     }
368 
369     if (!context.IsSizeValid()) {
370         HRPE("Unmarshal: Invalid size");
371         return false;
372     }
373 
374     context.map->SetEditable(context.editable);
375     context.map->SetAstc(context.astc);
376     context.map->SetVersionId(context.versionId);
377     return true;
378 }
379 
UnmarshalFromSharedMemory(UnmarshallingContext& context, uint64_t id)380 bool ImageSource::UnmarshalFromSharedMemory(UnmarshallingContext& context, uint64_t id)
381 {
382     constexpr int32_t invalidFile = -1;
383     const auto file =
384         Rosen::RSProfiler::IsParcelMock(context.parcel) ? invalidFile : PixelMap::ReadFileDescriptor(context.parcel);
385     if (file < 0) {
386         if (auto image = GetCachedImage(id)) {
387             if (context.GatherImageFromFile(image)) {
388                 context.parcel.SkipBytes(UnmarshallingContext::headerLength);
389                 return true;
390             }
391         }
392         HRPE("Unmarshal: SharedMemory: Cached image fetch failed");
393         return false;
394     }
395 
396     if (!context.IsAshmemSizeValid(file)) {
397         ::close(file);
398         HRPE("Unmarshal: SharedMemory: Invalid file size");
399         return false;
400     }
401 
402     auto image = MapImage(file, context.size, PROT_READ | PROT_WRITE);
403     if (!image) {
404         image = MapImage(file, context.size, PROT_READ);
405     }
406 
407     if (!image) {
408         ::close(file);
409         HRPE("Unmarshal: SharedMemory: Cannot map an image from a file");
410         return false;
411     }
412 
413     const auto imageData = GenerateImageData(image, context.size, *context.map);
414     CacheImage(id, imageData, UnmarshallingContext::headerLength);
415 
416     context.context = new int32_t();
417     if (!context.context) {
418         UnmapImage(image, context.size);
419         ::close(file);
420         HRPE("Unmarshal: SharedMemory: Cannot allocate memory for a file handle");
421         return false;
422     }
423     *static_cast<int32_t*>(context.context) = file;
424     context.base = image;
425     return true;
426 }
427 
UnmarshalFromDMA(UnmarshallingContext& context, uint64_t id)428 bool ImageSource::UnmarshalFromDMA(UnmarshallingContext& context, uint64_t id)
429 {
430     auto image = Rosen::RSProfiler::IsParcelMock(context.parcel) ? GetCachedImage(id) : nullptr;
431     if (image) {
432         // REPLAY IMAGE
433         context.parcel.SkipBytes(image->parcelSkipBytes);
434         return context.GatherDmaImageFromFile(image);
435     }
436 
437     const size_t readPosition = context.parcel.GetReadPosition();
438 
439     sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
440     surfaceBuffer->ReadFromMessageParcel(static_cast<MessageParcel&>(context.parcel));
441     context.base = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
442     context.context = IncrementSurfaceBufferReference(surfaceBuffer);
443 
444     if (auto bufferHandle = surfaceBuffer->GetBufferHandle()) {
445         // RECORD IMAGE
446         const auto imageData = GenerateImageData(context.base, bufferHandle->size, *context.map);
447         CacheImage(id, imageData, context.parcel.GetReadPosition() - readPosition, bufferHandle);
448     }
449 
450     return true;
451 }
452 
UnmarshalFromData(UnmarshallingContext& context)453 bool ImageSource::UnmarshalFromData(UnmarshallingContext& context)
454 {
455     context.base = PixelMap::ReadImageData(context.parcel, static_cast<int32_t>(context.size));
456     if (!context.base) {
457         HRPE("Unmarshal: PixelMap::ReadImageData failed");
458         return false;
459     }
460     return true;
461 }
462 
FinalizeUnmarshalling(UnmarshallingContext& context)463 PixelMap* ImageSource::FinalizeUnmarshalling(UnmarshallingContext& context)
464 {
465     if (context.map->SetImageInfo(context.info) != SUCCESS) {
466         if (context.map->freePixelMapProc_) {
467             context.map->freePixelMapProc_(context.base, context.context, context.size);
468         }
469         PixelMap::ReleaseMemory(context.allocType, context.base, context.context, context.size);
470         if (context.context && (context.allocType == AllocatorType::SHARE_MEM_ALLOC)) {
471             delete static_cast<int32_t*>(context.context);
472         }
473 
474         HRPE("Unmarshal: PixelMap::SetImageInfo failed");
475         return nullptr;
476     }
477 
478     context.map->SetPixelsAddr(context.base, context.context, context.size, context.allocType, nullptr);
479 
480     if (!context.map->ReadTransformData(context.parcel, context.map.get())) {
481         HRPE("Unmarshal: PixelMap::ReadTransformData failed");
482         return nullptr;
483     }
484 
485     if (!context.map->ReadAstcRealSize(context.parcel, context.map.get())) {
486         HRPE("Unmarshal: PixelMap::ReadAstcRealSize failed");
487         return nullptr;
488     }
489 
490     if (!context.map->ReadYuvDataInfoFromParcel(context.parcel, context.map.get())) {
491         HRPE("Unmarshal: PixelMap::ReadYuvDataInfoFromParcel failed");
492         return nullptr;
493     }
494 
495     HRPI("Unmarshal: Done");
496     return context.map.release();
497 }
498 
Unmarshal(Parcel& parcel)499 PixelMap* ImageSource::Unmarshal(Parcel& parcel)
500 {
501     const uint64_t id = parcel.ReadUint64();
502     UnmarshallingContext context { parcel };
503 
504     if (!InitUnmarshalling(context)) {
505         return nullptr;
506     }
507 
508 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(A_PLATFORM)
509     if (context.allocType == AllocatorType::SHARE_MEM_ALLOC) {
510         if (!UnmarshalFromSharedMemory(context, id)) {
511             return nullptr;
512         }
513     } else if (context.allocType == AllocatorType::DMA_ALLOC) {
514         if (!UnmarshalFromDMA(context, id)) {
515             return nullptr;
516         }
517     } else {
518         if (!UnmarshalFromData(context)) {
519             return nullptr;
520         }
521     }
522 #else
523     if (!UnmarshalFromData(context)) {
524         return nullptr;
525     }
526 #endif
527 
528     return FinalizeUnmarshalling(context);
529 }
530 
OnClientMarshalling(Media::PixelMap& map, uint64_t id)531 void ImageSource::OnClientMarshalling(Media::PixelMap& map, uint64_t id)
532 {
533     if (Rosen::RSProfiler::IsSharedMemoryEnabled()) {
534         return;
535     }
536 
537     const auto descriptor = map.GetFd();
538     if (!descriptor) {
539         return;
540     }
541 
542     if (map.GetAllocatorType() == AllocatorType::DMA_ALLOC) {
543         auto surfaceBuffer = reinterpret_cast<SurfaceBuffer*>(descriptor);
544         if (auto bufferHandle = surfaceBuffer->GetBufferHandle()) {
545             const auto imageData = GenerateImageData(
546                 reinterpret_cast<const uint8_t*>(surfaceBuffer->GetVirAddr()), bufferHandle->size, map);
547             MessageParcel parcel2;
548             surfaceBuffer->WriteToMessageParcel(parcel2);
549             size_t bufferHandleSize = parcel2.GetReadableBytes();
550             CacheImage(id, imageData, bufferHandleSize, bufferHandle);
551         }
552     } else {
553         const size_t size = map.isAstc_ ? map.pixelsSize_ :
554             static_cast<size_t>(map.rowDataSize_ * map.imageInfo_.size.height);
555         if (auto image = MapImage(*reinterpret_cast<const int32_t*>(map.GetFd()), size, PROT_READ)) {
556             const auto imageData = GenerateImageData(image, size, map);
557             CacheImage(id, imageData, UnmarshallingContext::headerLength);
558             UnmapImage(image, size);
559         }
560     }
561 }
562 
Marshal(Parcel& parcel, Media::PixelMap& map)563 bool ImageSource::Marshal(Parcel& parcel, Media::PixelMap& map)
564 {
565     const uint64_t id = Rosen::ImageCache::New();
566     if (!parcel.WriteUint64(id) || !map.Marshalling(parcel)) {
567         return false;
568     }
569     OnClientMarshalling(map, id);
570     return true;
571 }
572 
573 } // namespace OHOS::Media
574 
575 namespace OHOS::Rosen {
576 
577 using PixelMapHelper = Media::ImageSource;
578 
UnmarshalPixelMap(Parcel& parcel)579 Media::PixelMap* RSProfiler::UnmarshalPixelMap(Parcel& parcel)
580 {
581     bool isClientEnabled = false;
582     if (!parcel.ReadBool(isClientEnabled)) {
583         HRPE("Unable to read is_client_enabled for image");
584         return nullptr;
585     }
586     if (!isClientEnabled) {
587         return Media::PixelMap::Unmarshalling(parcel);
588     }
589 
590     return PixelMapHelper::Unmarshal(parcel);
591 }
592 
SkipPixelMap(Parcel& parcel)593 bool RSProfiler::SkipPixelMap(Parcel& parcel)
594 {
595     if (RSProfiler::IsEnabled() && RSProfiler::GetMode() == Mode::WRITE) {
596         std::shared_ptr<Media::PixelMap> pixelMap;
597         RSMarshallingHelper::Unmarshalling(parcel, pixelMap);
598         return true;
599     }
600     return false;
601 }
602 
MarshalPixelMap(Parcel& parcel, const std::shared_ptr<Media::PixelMap>& map)603 bool RSProfiler::MarshalPixelMap(Parcel& parcel, const std::shared_ptr<Media::PixelMap>& map)
604 {
605     if (!map) {
606         return false;
607     }
608 
609     bool isClientEnabled = RSSystemProperties::GetProfilerEnabled();
610     if (!parcel.WriteBool(isClientEnabled)) {
611         HRPE("Unable to write is_client_enabled for image");
612         return false;
613     }
614 
615     if (!isClientEnabled) {
616         return map->Marshalling(parcel);
617     }
618 
619     return PixelMapHelper::Marshal(parcel, *map);
620 }
621 
622 } // namespace OHOS::Rosen