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