• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "render/rs_pixel_map_util.h"
17 #include <memory>
18 
19 #include "pixel_map.h"
20 #include "platform/common/rs_log.h"
21 #include "platform/common/rs_system_properties.h"
22 #include "drawing/engine_adapter/impl_interface/bitmap_impl.h"
23 #include "image/yuv_info.h"
24 #include "render/rs_image.h"
25 #ifdef ROSEN_OHOS
26 #include "surface_buffer.h"
27 #endif
28 
29 namespace OHOS {
30 namespace Rosen {
31 using namespace Media;
32 namespace {
33     constexpr float HALF_F = 2;
34 }
35 
36 static const std::map<PixelFormat, GraphicPixelFormat> PIXELMAP_SURFACEBUFFER_FORMAT_MAP = {
37     {PixelFormat::RGB_565, GRAPHIC_PIXEL_FMT_RGB_565},
38     {PixelFormat::RGBA_8888, GRAPHIC_PIXEL_FMT_RGBA_8888},
39     {PixelFormat::BGRA_8888, GRAPHIC_PIXEL_FMT_BGRA_8888},
40     {PixelFormat::RGB_888, GRAPHIC_PIXEL_FMT_RGB_888},
41     {PixelFormat::RGBA_F16, GRAPHIC_PIXEL_FMT_RGBA16_FLOAT},
42     {PixelFormat::NV21, GRAPHIC_PIXEL_FMT_YCRCB_420_SP},
43     {PixelFormat::NV12, GRAPHIC_PIXEL_FMT_YCBCR_420_SP},
44     {PixelFormat::RGBA_1010102, GRAPHIC_PIXEL_FMT_RGBA_1010102},
45     {PixelFormat::YCBCR_P010, GRAPHIC_PIXEL_FMT_YCBCR_P010},
46     {PixelFormat::YCRCB_P010, GRAPHIC_PIXEL_FMT_YCRCB_P010},
47 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
48     {PixelFormat::ASTC_4x4, GRAPHIC_PIXEL_FMT_BLOB},
49     {PixelFormat::ASTC_6x6, GRAPHIC_PIXEL_FMT_BLOB},
50     {PixelFormat::ASTC_8x8, GRAPHIC_PIXEL_FMT_BLOB},
51 #endif
52 };
53 
ColorSpaceToDrawingColorSpace(ColorManager::ColorSpaceName colorSpaceName)54 static std::shared_ptr<Drawing::ColorSpace> ColorSpaceToDrawingColorSpace(
55     ColorManager::ColorSpaceName colorSpaceName)
56 {
57     switch (colorSpaceName) {
58         case ColorManager::ColorSpaceName::DCI_P3:
59         case ColorManager::ColorSpaceName::DISPLAY_P3:
60             return Drawing::ColorSpace::CreateRGB(
61                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::DCIP3);
62         case ColorManager::ColorSpaceName::LINEAR_SRGB:
63             return Drawing::ColorSpace::CreateSRGBLinear();
64         case ColorManager::ColorSpaceName::SRGB:
65             return Drawing::ColorSpace::CreateSRGB();
66         case ColorManager::ColorSpaceName::DISPLAY_BT2020_SRGB:
67             return Drawing::ColorSpace::CreateRGB(
68                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::REC2020);
69         case ColorManager::ColorSpaceName::ADOBE_RGB:
70             return Drawing::ColorSpace::CreateRGB(
71                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::ADOBE_RGB);
72         default:
73             return Drawing::ColorSpace::CreateSRGB();
74     }
75 }
76 
PixelFormatToDrawingColorType(PixelFormat pixelFormat)77 static Drawing::ColorType PixelFormatToDrawingColorType(PixelFormat pixelFormat)
78 {
79     switch (pixelFormat) {
80         case PixelFormat::RGB_565:
81             return Drawing::ColorType::COLORTYPE_RGB_565;
82         case PixelFormat::RGBA_8888:
83             return Drawing::ColorType::COLORTYPE_RGBA_8888;
84         case PixelFormat::BGRA_8888:
85             return Drawing::ColorType::COLORTYPE_BGRA_8888;
86         case PixelFormat::ALPHA_8:
87             return Drawing::ColorType::COLORTYPE_ALPHA_8;
88         case PixelFormat::RGBA_F16:
89             return Drawing::ColorType::COLORTYPE_RGBA_F16;
90         case PixelFormat::RGBA_1010102:
91             return Drawing::ColorType::COLORTYPE_RGBA_1010102;
92         case PixelFormat::UNKNOWN:
93         case PixelFormat::ARGB_8888:
94         case PixelFormat::RGB_888:
95         case PixelFormat::NV21:
96         case PixelFormat::NV12:
97         case PixelFormat::CMYK:
98         default:
99             return Drawing::ColorType::COLORTYPE_UNKNOWN;
100     }
101 }
102 
AlphaTypeToDrawingAlphaType(AlphaType alphaType)103 static Drawing::AlphaType AlphaTypeToDrawingAlphaType(AlphaType alphaType)
104 {
105     switch (alphaType) {
106         case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
107             return Drawing::AlphaType::ALPHATYPE_UNKNOWN;
108         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
109             return Drawing::AlphaType::ALPHATYPE_OPAQUE;
110         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
111             return Drawing::AlphaType::ALPHATYPE_PREMUL;
112         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
113             return Drawing::AlphaType::ALPHATYPE_UNPREMUL;
114         default:
115             return Drawing::AlphaType::ALPHATYPE_UNKNOWN;
116     }
117 }
118 
119 
120 struct PixelMapReleaseContext {
PixelMapReleaseContextOHOS::Rosen::PixelMapReleaseContext121     explicit PixelMapReleaseContext(std::shared_ptr<PixelMap> pixelMap) : pixelMap_(pixelMap)
122     {
123 #ifdef ROSEN_OHOS
124         if (pixelMap_) {
125             pixelMap_->IncreaseUseCount();
126         }
127 #endif
128     }
129 
~PixelMapReleaseContextOHOS::Rosen::PixelMapReleaseContext130     ~PixelMapReleaseContext()
131     {
132 #ifdef ROSEN_OHOS
133         if (pixelMap_) {
134             pixelMap_->DecreaseUseCount();
135         }
136 #endif
137         pixelMap_ = nullptr;
138     }
139 
140 private:
141     std::shared_ptr<PixelMap> pixelMap_;
142 };
143 
PixelMapReleaseProc(const void *,void * context)144 static void PixelMapReleaseProc(const void* /* pixels */, void* context)
145 {
146     PixelMapReleaseContext* ctx = static_cast<PixelMapReleaseContext*>(context);
147     if (ctx) {
148         delete ctx;
149         ctx = nullptr;
150     }
151 }
152 
GetPixelmapColorSpace(const std::shared_ptr<Media::PixelMap> & pixelMap)153 std::shared_ptr<Drawing::ColorSpace> RSPixelMapUtil::GetPixelmapColorSpace(
154     const std::shared_ptr<Media::PixelMap>& pixelMap)
155 {
156     if (!pixelMap) {
157         return Drawing::ColorSpace::CreateSRGB();
158     }
159     return ColorSpaceToDrawingColorSpace(pixelMap->InnerGetGrColorSpace().GetColorSpaceName());
160 }
161 
ExtractDrawingImage(std::shared_ptr<Media::PixelMap> pixelMap)162 std::shared_ptr<Drawing::Image> RSPixelMapUtil::ExtractDrawingImage(
163     std::shared_ptr<Media::PixelMap> pixelMap)
164 {
165     if (!pixelMap) {
166         return nullptr;
167     }
168     ImageInfo imageInfo;
169     pixelMap->GetImageInfo(imageInfo);
170     Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
171         PixelFormatToDrawingColorType(imageInfo.pixelFormat),
172         AlphaTypeToDrawingAlphaType(imageInfo.alphaType),
173         ColorSpaceToDrawingColorSpace(pixelMap->InnerGetGrColorSpace().GetColorSpaceName()) };
174     Drawing::Pixmap imagePixmap(drawingImageInfo,
175         reinterpret_cast<const void*>(pixelMap->GetPixels()), pixelMap->GetRowStride());
176     PixelMapReleaseContext* releaseContext = new PixelMapReleaseContext(pixelMap);
177     auto image = Drawing::Image::MakeFromRaster(imagePixmap, PixelMapReleaseProc, releaseContext);
178     if (!image) {
179         RS_LOGE("RSPixelMapUtil::ExtractDrawingImage fail");
180         delete releaseContext;
181         releaseContext = nullptr;
182     }
183     return image;
184 }
185 
calculateRotatedDimensions(float width,float height,float rotationDegrees)186 std::pair<float, float> calculateRotatedDimensions(float width, float height, float rotationDegrees)
187 {
188     float radians = rotationDegrees * M_PI / 180.0f; // Convert degrees to radians
189 
190     float cosTheta = std::cos(radians);
191     float sinTheta = std::sin(radians);
192 
193     float newWidth = std::abs(width * cosTheta) + std::abs(height * sinTheta);
194     float newHeight = std::abs(width * sinTheta) + std::abs(height * cosTheta);
195 
196     return {newWidth, newHeight};
197 }
198 
ApplyRotationTransform(TransformData & transformData,Drawing::Rect & dst,Drawing::Matrix & matrix,const Size & realSize)199 void ApplyRotationTransform(TransformData& transformData,
200     Drawing::Rect& dst, Drawing::Matrix& matrix, const Size& realSize)
201 {
202     float w = dst.GetWidth();
203     float h = dst.GetHeight();
204     scalar x = dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F;
205     scalar y = dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F;
206     matrix.PreRotate(transformData.rotateD, x, y);
207     dst.SetLeft(x - realSize.width / HALF_F);
208     dst.SetTop(y - realSize.height / HALF_F);
209     dst.SetRight(x + realSize.width / HALF_F);
210     dst.SetBottom(y + realSize.height / HALF_F);
211     auto [newWidth, newHeight] =
212         calculateRotatedDimensions(dst.GetWidth(), dst.GetHeight(), transformData.rotateD);
213     float ratiox = w / (float)newWidth;
214     float ratioy = h / (float)newHeight;
215     matrix.PostScale(ratiox, ratioy, x, y);
216 }
217 
ApplyFitTransform(std::shared_ptr<Media::PixelMap> pixelMap,Drawing::Rect & src,Drawing::Rect & dst,Drawing::Canvas & canvas)218 void ApplyFitTransform(std::shared_ptr<Media::PixelMap> pixelMap,
219     Drawing::Rect& src, Drawing::Rect& dst, Drawing::Canvas& canvas)
220 {
221     const float kEpsilon = 1e-5f;
222     TransformData transformData;
223     pixelMap->GetTransformData(transformData);
224     Size realSize;
225     pixelMap->GetAstcRealSize(realSize);
226     Size pixelmapSize = {pixelMap->GetWidth(), pixelMap->GetHeight()};
227     src.SetRight(src.left_ + realSize.width);
228     src.SetBottom(src.top_ + realSize.height);
229     transformData.rotateD = fmod(fmod(transformData.rotateD, 360.0f) + 360.0f, 360.0f); // Normalize to [0, 360)
230     Drawing::Matrix matrix;
231     if (std::fabs(transformData.rotateD) > kEpsilon) {
232         ApplyRotationTransform(transformData, dst, matrix, realSize);
233     }
234     if (transformData.translateX != 0 || transformData.translateY != 0) {
235         float ratiox = realSize.width /(float)pixelmapSize.width;
236         float ratioy = realSize.height /(float)pixelmapSize.height;
237         if (transformData.translateX > 0) {
238             dst.SetLeft(dst.GetLeft() + (dst.GetWidth() - (dst.GetWidth() * ratiox)));
239         } else {
240             src.SetLeft(src.GetLeft() - transformData.translateX);
241         }
242         if (transformData.translateY > 0) {
243             dst.SetTop(dst.GetTop() + (dst.GetHeight() - (dst.GetHeight() * ratioy)));
244         } else {
245             src.SetTop(src.GetTop() - transformData.translateY);
246         }
247     }
248     if (transformData.flipX) {
249         matrix.PostScale(-1, 1, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
250             dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
251     }
252     if (transformData.flipY) {
253         matrix.PostScale(1, -1, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
254             dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
255     }
256 
257     if (transformData.cropLeft >= 0 && transformData.cropTop >= 0 && transformData.cropWidth > 0 &&
258         transformData.cropHeight > 0 && transformData.cropLeft + transformData.cropWidth <= realSize.width &&
259         transformData.cropTop + transformData.cropHeight <= realSize.height) {
260         src.SetLeft(src.GetLeft() + transformData.cropLeft);
261         src.SetTop(src.GetTop() + transformData.cropTop);
262         src.SetRight(src.GetLeft() + pixelmapSize.width);
263         src.SetBottom(src.GetTop() + pixelmapSize.height);
264     }
265     canvas.ConcatMatrix(matrix);
266 }
267 
ApplyNoneFitTransformstd(std::shared_ptr<Media::PixelMap> pixelMap,Drawing::Rect & src,Drawing::Rect & dst,Drawing::Canvas & canvas)268 void ApplyNoneFitTransformstd(std::shared_ptr<Media::PixelMap> pixelMap,
269     Drawing::Rect& src, Drawing::Rect& dst, Drawing::Canvas& canvas)
270 {
271     const float kEpsilon = 1e-5f;
272     TransformData transformData;
273     pixelMap->GetTransformData(transformData);
274     Size realSize;
275     pixelMap->GetAstcRealSize(realSize);
276     Size pixelmapSize = {pixelMap->GetWidth(), pixelMap->GetHeight()};
277     src.SetRight(src.left_ + realSize.width);
278     src.SetBottom(src.top_ + realSize.height);
279     transformData.rotateD = fmod(fmod(transformData.rotateD, 360.0f) + 360.0f, 360.0f); // Normalize to [0, 360)
280     if (std::fabs(transformData.rotateD) > kEpsilon) {
281         dst.SetLeft(dst.GetLeft() - (realSize.width - pixelmapSize.width) / HALF_F);
282         dst.SetTop(dst.GetTop() - (realSize.height - pixelmapSize.height) / HALF_F);
283         dst.SetRight(dst.GetRight() + (realSize.width - pixelmapSize.width) / HALF_F);
284         dst.SetBottom(dst.GetBottom() + (realSize.height - pixelmapSize.height) / HALF_F);
285     }
286     Drawing::Matrix matrix;
287     matrix.PostRotate(transformData.rotateD, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
288                       dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
289     if (transformData.flipX) {
290         matrix.PostScale(-1, 1, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
291                          dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
292     }
293     if (transformData.flipY) {
294         matrix.PostScale(1, -1, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
295                          dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
296     }
297     canvas.ConcatMatrix(matrix);
298     if (transformData.cropLeft >= 0 && transformData.cropTop >= 0 && transformData.cropWidth > 0 &&
299         transformData.cropHeight > 0 && transformData.cropLeft + transformData.cropWidth <= realSize.width &&
300         transformData.cropTop + transformData.cropHeight <= realSize.height) {
301         src.SetLeft(src.GetLeft() + transformData.cropLeft);
302         src.SetTop(src.GetTop() + transformData.cropTop);
303         src.SetRight(src.GetLeft() + pixelmapSize.width);
304         src.SetBottom(src.GetTop() + pixelmapSize.height);
305     }
306     if (transformData.translateX != 0 && transformData.translateY != 0) {
307         if (transformData.translateX > 0) {
308             dst.SetLeft(dst.GetLeft() + transformData.translateX);
309         } else {
310             src.SetLeft(src.GetLeft() - transformData.translateX);
311         }
312         if (transformData.translateY > 0) {
313             dst.SetTop(dst.GetTop() + transformData.translateY);
314         } else {
315             src.SetTop(src.GetTop() - transformData.translateY);
316         }
317     }
318 }
319 
TransformDataSetForAstc(std::shared_ptr<Media::PixelMap> pixelMap,Drawing::Rect & src,Drawing::Rect & dst,Drawing::Canvas & canvas,ImageFit imageFit)320 void RSPixelMapUtil::TransformDataSetForAstc(std::shared_ptr<Media::PixelMap> pixelMap,
321     Drawing::Rect& src, Drawing::Rect& dst, Drawing::Canvas& canvas, ImageFit imageFit)
322 {
323     if (imageFit != ImageFit::NONE) {
324         return ApplyFitTransform(pixelMap, src, dst, canvas);
325     }
326     return ApplyNoneFitTransformstd(pixelMap, src, dst, canvas);
327 }
328 
DrawPixelMap(Drawing::Canvas & canvas,Media::PixelMap & pixelMap,const Drawing::scalar px,const Drawing::scalar py)329 void RSPixelMapUtil::DrawPixelMap(Drawing::Canvas& canvas, Media::PixelMap& pixelMap,
330                                   const Drawing::scalar px, const Drawing::scalar py)
331 {
332     ImageInfo imageInfo;
333     pixelMap.GetImageInfo(imageInfo);
334     Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
335         PixelFormatToDrawingColorType(imageInfo.pixelFormat),
336         AlphaTypeToDrawingAlphaType(imageInfo.alphaType),
337         ColorSpaceToDrawingColorSpace(pixelMap.InnerGetGrColorSpace().GetColorSpaceName()) };
338     Drawing::Bitmap pixelBitmap;
339     pixelBitmap.InstallPixels(
340         drawingImageInfo, reinterpret_cast<void*>(pixelMap.GetWritablePixels()),
341         static_cast<uint32_t>(pixelMap.GetRowBytes()));
342     canvas.DrawBitmap(pixelBitmap, px, py);
343 }
344 
IsYUVFormat(std::shared_ptr<Media::PixelMap> pixelMap)345 bool RSPixelMapUtil::IsYUVFormat(std::shared_ptr<Media::PixelMap> pixelMap)
346 {
347     if (!pixelMap) {
348         return false;
349     }
350 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
351     if (pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC) {
352         return false;
353     }
354 #endif
355     ImageInfo imageInfo;
356     pixelMap->GetImageInfo(imageInfo);
357     return imageInfo.pixelFormat == PixelFormat::NV21 || imageInfo.pixelFormat == PixelFormat::NV12
358         || imageInfo.pixelFormat == PixelFormat::YCBCR_P010
359         || imageInfo.pixelFormat == PixelFormat::YCRCB_P010;
360 }
361 
YUVPixelFormatToPlaneConfig(PixelFormat pixelFormat)362 static Drawing::YUVInfo::PlaneConfig YUVPixelFormatToPlaneConfig(PixelFormat pixelFormat)
363 {
364     switch (pixelFormat) {
365         case PixelFormat::NV12:
366         case PixelFormat::YCBCR_P010:
367             return Drawing::YUVInfo::PlaneConfig::Y_UV;
368         case PixelFormat::NV21:
369         case PixelFormat::YCRCB_P010:
370             return Drawing::YUVInfo::PlaneConfig::Y_VU;
371         default:
372             return Drawing::YUVInfo::PlaneConfig::UNKNOWN;
373     }
374 }
375 
YUVPixelFormatToSubSampling(PixelFormat pixelFormat)376 static Drawing::YUVInfo::SubSampling YUVPixelFormatToSubSampling(PixelFormat pixelFormat)
377 {
378     switch (pixelFormat) {
379         case PixelFormat::NV12:
380         case PixelFormat::NV21:
381         case PixelFormat::YCBCR_P010:
382         case PixelFormat::YCRCB_P010:
383             return Drawing::YUVInfo::SubSampling::K420;
384         default:
385             return Drawing::YUVInfo::SubSampling::UNKNOWN;
386     }
387 }
388 
YUVPixelFormatToYUVColorSpace(PixelFormat pixelFormat)389 static Drawing::YUVInfo::YUVColorSpace YUVPixelFormatToYUVColorSpace(PixelFormat pixelFormat)
390 {
391     switch (pixelFormat) {
392         case PixelFormat::NV12:
393         case PixelFormat::NV21:
394             return Drawing::YUVInfo::YUVColorSpace::JPEG_FULL_YUVCOLORSPACE;
395         case PixelFormat::YCBCR_P010:
396         case PixelFormat::YCRCB_P010:
397             return Drawing::YUVInfo::YUVColorSpace::BT2020_10BIT_LIMITED_YUVCOLORSPACE;
398         default:
399             return Drawing::YUVInfo::YUVColorSpace::IDENTITY_YUVCOLORSPACE;
400     }
401 }
402 
YUVPixelFormatToYUVDataType(PixelFormat pixelFormat)403 static Drawing::YUVInfo::YUVDataType YUVPixelFormatToYUVDataType(PixelFormat pixelFormat)
404 {
405     switch (pixelFormat) {
406         case PixelFormat::NV12:
407         case PixelFormat::NV21:
408             return Drawing::YUVInfo::YUVDataType::UNORM_8;
409         case PixelFormat::YCBCR_P010:
410         case PixelFormat::YCRCB_P010:
411             return Drawing::YUVInfo::YUVDataType::UNORM_16;
412         default:
413             return Drawing::YUVInfo::YUVDataType::UNORM_8;
414     }
415 }
416 
ConvertYUVPixelMapToDrawingImage(std::shared_ptr<Drawing::GPUContext> gpuContext,std::shared_ptr<Media::PixelMap> pixelMap)417 std::shared_ptr<Drawing::Image> RSPixelMapUtil::ConvertYUVPixelMapToDrawingImage(
418     std::shared_ptr<Drawing::GPUContext> gpuContext, std::shared_ptr<Media::PixelMap> pixelMap)
419 {
420     if (gpuContext && pixelMap && IsYUVFormat(pixelMap)) {
421         ImageInfo imageInfo;
422         pixelMap->GetImageInfo(imageInfo);
423         Drawing::YUVInfo info(pixelMap->GetWidth(), pixelMap->GetHeight(),
424             YUVPixelFormatToPlaneConfig(imageInfo.pixelFormat),
425             YUVPixelFormatToSubSampling(imageInfo.pixelFormat),
426             YUVPixelFormatToYUVColorSpace(imageInfo.pixelFormat),
427             YUVPixelFormatToYUVDataType(imageInfo.pixelFormat));
428 #ifdef RS_ENABLE_GPU
429         return Drawing::Image::MakeFromYUVAPixmaps(*gpuContext, info,
430             const_cast<void *>(reinterpret_cast<const void*>(pixelMap->GetPixels())));
431 #endif
432     }
433     return nullptr;
434 }
435 
IsSupportZeroCopy(std::shared_ptr<Media::PixelMap> pixelMap,const Drawing::SamplingOptions & sampling)436 bool RSPixelMapUtil::IsSupportZeroCopy(std::shared_ptr<Media::PixelMap> pixelMap,
437     const Drawing::SamplingOptions& sampling)
438 {
439     if (!(pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC)) {
440         return false;
441     }
442     if (!CheckFormatConsistency(pixelMap)) {
443         RS_LOGE("RSPixelMapUtil::CheckFormatConsistency fail");
444         return false;
445     }
446     return RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL;
447 }
448 
CheckFormatConsistency(std::shared_ptr<Media::PixelMap> pixelMap)449 bool RSPixelMapUtil::CheckFormatConsistency(std::shared_ptr<Media::PixelMap> pixelMap)
450 {
451 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
452     if (pixelMap->GetFd() == nullptr ||
453         !(pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC)) {
454         return false;
455     }
456     SurfaceBuffer* surfaceBuffer = static_cast<SurfaceBuffer*>(pixelMap->GetFd());
457     if (auto it = PIXELMAP_SURFACEBUFFER_FORMAT_MAP.find(pixelMap->GetPixelFormat());
458         it != PIXELMAP_SURFACEBUFFER_FORMAT_MAP.end()) {
459         return it->second == static_cast<GraphicPixelFormat>(surfaceBuffer->GetFormat());
460     }
461     return false;
462 #endif
463     return false;
464 }
465 } // namespace Rosen
466 } // namespace OHOS
467