• 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 
25 namespace OHOS {
26 namespace Rosen {
27 using namespace Media;
28 namespace {
29     constexpr float HALF_F = 2;
30 }
31 
ColorSpaceToDrawingColorSpace(ColorManager::ColorSpaceName colorSpaceName)32 static std::shared_ptr<Drawing::ColorSpace> ColorSpaceToDrawingColorSpace(
33     ColorManager::ColorSpaceName colorSpaceName)
34 {
35     switch (colorSpaceName) {
36         case ColorManager::ColorSpaceName::DCI_P3:
37         case ColorManager::ColorSpaceName::DISPLAY_P3:
38             return Drawing::ColorSpace::CreateRGB(
39                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::DCIP3);
40         case ColorManager::ColorSpaceName::LINEAR_SRGB:
41             return Drawing::ColorSpace::CreateSRGBLinear();
42         case ColorManager::ColorSpaceName::SRGB:
43             return Drawing::ColorSpace::CreateSRGB();
44         default:
45             return Drawing::ColorSpace::CreateSRGB();
46     }
47 }
48 
PixelFormatToDrawingColorType(PixelFormat pixelFormat)49 static Drawing::ColorType PixelFormatToDrawingColorType(PixelFormat pixelFormat)
50 {
51     switch (pixelFormat) {
52         case PixelFormat::RGB_565:
53             return Drawing::ColorType::COLORTYPE_RGB_565;
54         case PixelFormat::RGBA_8888:
55             return Drawing::ColorType::COLORTYPE_RGBA_8888;
56         case PixelFormat::BGRA_8888:
57             return Drawing::ColorType::COLORTYPE_BGRA_8888;
58         case PixelFormat::ALPHA_8:
59             return Drawing::ColorType::COLORTYPE_ALPHA_8;
60         case PixelFormat::RGBA_F16:
61             return Drawing::ColorType::COLORTYPE_RGBA_F16;
62         case PixelFormat::RGBA_1010102:
63             return Drawing::ColorType::COLORTYPE_RGBA_1010102;
64         case PixelFormat::UNKNOWN:
65         case PixelFormat::ARGB_8888:
66         case PixelFormat::RGB_888:
67         case PixelFormat::NV21:
68         case PixelFormat::NV12:
69         case PixelFormat::CMYK:
70         default:
71             return Drawing::ColorType::COLORTYPE_UNKNOWN;
72     }
73 }
74 
AlphaTypeToDrawingAlphaType(AlphaType alphaType)75 static Drawing::AlphaType AlphaTypeToDrawingAlphaType(AlphaType alphaType)
76 {
77     switch (alphaType) {
78         case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
79             return Drawing::AlphaType::ALPHATYPE_UNKNOWN;
80         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
81             return Drawing::AlphaType::ALPHATYPE_OPAQUE;
82         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
83             return Drawing::AlphaType::ALPHATYPE_PREMUL;
84         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
85             return Drawing::AlphaType::ALPHATYPE_UNPREMUL;
86         default:
87             return Drawing::AlphaType::ALPHATYPE_UNKNOWN;
88     }
89 }
90 
91 
92 struct PixelMapReleaseContext {
PixelMapReleaseContextOHOS::Rosen::PixelMapReleaseContext93     explicit PixelMapReleaseContext(std::shared_ptr<PixelMap> pixelMap) : pixelMap_(pixelMap)
94     {
95 #ifdef ROSEN_OHOS
96         if (pixelMap_) {
97             pixelMap_->IncreaseUseCount();
98         }
99 #endif
100     }
101 
~PixelMapReleaseContextOHOS::Rosen::PixelMapReleaseContext102     ~PixelMapReleaseContext()
103     {
104 #ifdef ROSEN_OHOS
105         if (pixelMap_) {
106             pixelMap_->DecreaseUseCount();
107         }
108 #endif
109         pixelMap_ = nullptr;
110     }
111 
112 private:
113     std::shared_ptr<PixelMap> pixelMap_;
114 };
115 
PixelMapReleaseProc(const void *,void * context)116 static void PixelMapReleaseProc(const void* /* pixels */, void* context)
117 {
118     PixelMapReleaseContext* ctx = static_cast<PixelMapReleaseContext*>(context);
119     if (ctx) {
120         delete ctx;
121         ctx = nullptr;
122     }
123 }
124 
GetPixelmapColorSpace(const std::shared_ptr<Media::PixelMap> & pixelMap)125 std::shared_ptr<Drawing::ColorSpace> RSPixelMapUtil::GetPixelmapColorSpace(
126     const std::shared_ptr<Media::PixelMap>& pixelMap)
127 {
128     if (!pixelMap) {
129         return Drawing::ColorSpace::CreateSRGB();
130     }
131     return ColorSpaceToDrawingColorSpace(pixelMap->InnerGetGrColorSpace().GetColorSpaceName());
132 }
133 
ExtractDrawingImage(std::shared_ptr<Media::PixelMap> pixelMap)134 std::shared_ptr<Drawing::Image> RSPixelMapUtil::ExtractDrawingImage(
135     std::shared_ptr<Media::PixelMap> pixelMap)
136 {
137     if (!pixelMap) {
138         return nullptr;
139     }
140     ImageInfo imageInfo;
141     pixelMap->GetImageInfo(imageInfo);
142     Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
143         PixelFormatToDrawingColorType(imageInfo.pixelFormat),
144         AlphaTypeToDrawingAlphaType(imageInfo.alphaType),
145         ColorSpaceToDrawingColorSpace(pixelMap->InnerGetGrColorSpace().GetColorSpaceName()) };
146     Drawing::Pixmap imagePixmap(drawingImageInfo,
147         reinterpret_cast<const void*>(pixelMap->GetPixels()), pixelMap->GetRowStride());
148     PixelMapReleaseContext* releaseContext = new PixelMapReleaseContext(pixelMap);
149     auto image = Drawing::Image::MakeFromRaster(imagePixmap, PixelMapReleaseProc, releaseContext);
150     if (!image) {
151         RS_LOGE("RSPixelMapUtil::ExtractDrawingImage fail");
152         delete releaseContext;
153         releaseContext = nullptr;
154     }
155     return image;
156 }
157 
158 
TransformDataSetForAstc(std::shared_ptr<Media::PixelMap> pixelMap,Drawing::Rect & src,Drawing::Rect & dst,Drawing::Canvas & canvas)159 void RSPixelMapUtil::TransformDataSetForAstc(std::shared_ptr<Media::PixelMap> pixelMap,
160                                              Drawing::Rect& src, Drawing::Rect& dst, Drawing::Canvas& canvas)
161 {
162     TransformData transformData;
163     pixelMap->GetTransformData(transformData);
164     Size realSize;
165     pixelMap->GetAstcRealSize(realSize);
166     dst.SetLeft(dst.GetLeft() - (realSize.width - src.GetRight()) / HALF_F);
167     dst.SetTop(dst.GetTop() - (realSize.height - src.GetBottom()) / HALF_F);
168     dst.SetRight(dst.GetRight() + (realSize.width - src.GetRight()) / HALF_F);
169     dst.SetBottom(dst.GetBottom() + (realSize.height - src.GetBottom()) / HALF_F);
170     if (transformData.scaleX != 0 && transformData.scaleY != 0) {
171         src.SetRight(src.GetRight() / abs(transformData.scaleX));
172         src.SetBottom(src.GetBottom() / abs(transformData.scaleY));
173     }
174     Drawing::Matrix matrix;
175     matrix.PostScale(transformData.scaleX, transformData.scaleY, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
176                      dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
177     matrix.PostRotate(transformData.rotateD, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
178                       dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
179     if (transformData.flipX) {
180         matrix.PostScale(-1, 1, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
181                          dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
182     }
183     if (transformData.flipY) {
184         matrix.PostScale(1, -1, dst.GetLeft() / HALF_F + dst.GetRight() / HALF_F,
185                          dst.GetTop() / HALF_F + dst.GetBottom() / HALF_F);
186     }
187     canvas.ConcatMatrix(matrix);
188     if (transformData.cropLeft >= 0 && transformData.cropTop >= 0 && transformData.cropWidth > 0 &&
189         transformData.cropHeight > 0 && transformData.cropLeft + transformData.cropWidth <= realSize.width &&
190         transformData.cropTop + transformData.cropHeight <= realSize.height) {
191         float rightMinus = src.GetRight() - transformData.cropLeft - transformData.cropWidth;
192         float bottomMinus = src.GetBottom() - transformData.cropTop - transformData.cropHeight;
193         src.SetLeft(src.GetLeft() + transformData.cropLeft);
194         src.SetTop(src.GetTop() + transformData.cropTop);
195         src.SetRight(src.GetRight() - rightMinus);
196         src.SetBottom(src.GetBottom() - bottomMinus);
197         dst.SetLeft(dst.GetLeft() + (realSize.width - transformData.cropWidth) / HALF_F);
198         dst.SetTop(dst.GetTop() + (realSize.height - transformData.cropHeight) / HALF_F);
199         dst.SetRight(dst.GetRight() - (realSize.width - transformData.cropWidth) / HALF_F);
200         dst.SetBottom(dst.GetBottom() - (realSize.height - transformData.cropHeight) / HALF_F);
201     }
202     if (transformData.scaleX != 0 && transformData.scaleY != 0) {
203         dst.SetLeft(dst.GetLeft() + transformData.translateX / HALF_F / abs(transformData.scaleX));
204         dst.SetTop(dst.GetTop() + transformData.translateY / HALF_F / abs(transformData.scaleY));
205         dst.SetRight(dst.GetRight() + transformData.translateX / HALF_F / abs(transformData.scaleX));
206         dst.SetBottom(dst.GetBottom() + transformData.translateY / HALF_F / abs(transformData.scaleY));
207     }
208 }
209 
DrawPixelMap(Drawing::Canvas & canvas,Media::PixelMap & pixelMap,const Drawing::scalar px,const Drawing::scalar py)210 void RSPixelMapUtil::DrawPixelMap(Drawing::Canvas& canvas, Media::PixelMap& pixelMap,
211                                   const Drawing::scalar px, const Drawing::scalar py)
212 {
213     ImageInfo imageInfo;
214     pixelMap.GetImageInfo(imageInfo);
215     Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
216         PixelFormatToDrawingColorType(imageInfo.pixelFormat),
217         AlphaTypeToDrawingAlphaType(imageInfo.alphaType),
218         ColorSpaceToDrawingColorSpace(pixelMap.InnerGetGrColorSpace().GetColorSpaceName()) };
219     Drawing::Bitmap pixelBitmap;
220     pixelBitmap.InstallPixels(
221         drawingImageInfo, reinterpret_cast<void*>(pixelMap.GetWritablePixels()),
222         static_cast<uint32_t>(pixelMap.GetRowBytes()));
223     canvas.DrawBitmap(pixelBitmap, px, py);
224 }
225 
IsYUVFormat(std::shared_ptr<Media::PixelMap> pixelMap)226 bool RSPixelMapUtil::IsYUVFormat(std::shared_ptr<Media::PixelMap> pixelMap)
227 {
228     if (!pixelMap) {
229         return false;
230     }
231 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
232     if (pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC) {
233         return false;
234     }
235 #endif
236     ImageInfo imageInfo;
237     pixelMap->GetImageInfo(imageInfo);
238     return imageInfo.pixelFormat == PixelFormat::NV21 || imageInfo.pixelFormat == PixelFormat::NV12
239         || imageInfo.pixelFormat == PixelFormat::YCBCR_P010
240         || imageInfo.pixelFormat == PixelFormat::YCRCB_P010;
241 }
242 
YUVPixelFormatToPlaneConfig(PixelFormat pixelFormat)243 static Drawing::YUVInfo::PlaneConfig YUVPixelFormatToPlaneConfig(PixelFormat pixelFormat)
244 {
245     switch (pixelFormat) {
246         case PixelFormat::NV12:
247         case PixelFormat::YCBCR_P010:
248             return Drawing::YUVInfo::PlaneConfig::Y_UV;
249         case PixelFormat::NV21:
250         case PixelFormat::YCRCB_P010:
251             return Drawing::YUVInfo::PlaneConfig::Y_VU;
252         default:
253             return Drawing::YUVInfo::PlaneConfig::UNKNOWN;
254     }
255 }
256 
YUVPixelFormatToSubSampling(PixelFormat pixelFormat)257 static Drawing::YUVInfo::SubSampling YUVPixelFormatToSubSampling(PixelFormat pixelFormat)
258 {
259     switch (pixelFormat) {
260         case PixelFormat::NV12:
261         case PixelFormat::NV21:
262         case PixelFormat::YCBCR_P010:
263         case PixelFormat::YCRCB_P010:
264             return Drawing::YUVInfo::SubSampling::K420;
265         default:
266             return Drawing::YUVInfo::SubSampling::UNKNOWN;
267     }
268 }
269 
YUVPixelFormatToYUVColorSpace(PixelFormat pixelFormat)270 static Drawing::YUVInfo::YUVColorSpace YUVPixelFormatToYUVColorSpace(PixelFormat pixelFormat)
271 {
272     switch (pixelFormat) {
273         case PixelFormat::NV12:
274         case PixelFormat::NV21:
275             return Drawing::YUVInfo::YUVColorSpace::JPEG_FULL_YUVCOLORSPACE;
276         case PixelFormat::YCBCR_P010:
277         case PixelFormat::YCRCB_P010:
278             return Drawing::YUVInfo::YUVColorSpace::BT2020_10BIT_LIMITED_YUVCOLORSPACE;
279         default:
280             return Drawing::YUVInfo::YUVColorSpace::IDENTITY_YUVCOLORSPACE;
281     }
282 }
283 
YUVPixelFormatToYUVDataType(PixelFormat pixelFormat)284 static Drawing::YUVInfo::YUVDataType YUVPixelFormatToYUVDataType(PixelFormat pixelFormat)
285 {
286     switch (pixelFormat) {
287         case PixelFormat::NV12:
288         case PixelFormat::NV21:
289             return Drawing::YUVInfo::YUVDataType::UNORM_8;
290         case PixelFormat::YCBCR_P010:
291         case PixelFormat::YCRCB_P010:
292             return Drawing::YUVInfo::YUVDataType::UNORM_16;
293         default:
294             return Drawing::YUVInfo::YUVDataType::UNORM_8;
295     }
296 }
297 
ConvertYUVPixelMapToDrawingImage(std::shared_ptr<Drawing::GPUContext> gpuContext,std::shared_ptr<Media::PixelMap> pixelMap)298 std::shared_ptr<Drawing::Image> RSPixelMapUtil::ConvertYUVPixelMapToDrawingImage(
299     std::shared_ptr<Drawing::GPUContext> gpuContext, std::shared_ptr<Media::PixelMap> pixelMap)
300 {
301     if (gpuContext && pixelMap && IsYUVFormat(pixelMap)) {
302         ImageInfo imageInfo;
303         pixelMap->GetImageInfo(imageInfo);
304         Drawing::YUVInfo info(pixelMap->GetWidth(), pixelMap->GetHeight(),
305             YUVPixelFormatToPlaneConfig(imageInfo.pixelFormat),
306             YUVPixelFormatToSubSampling(imageInfo.pixelFormat),
307             YUVPixelFormatToYUVColorSpace(imageInfo.pixelFormat),
308             YUVPixelFormatToYUVDataType(imageInfo.pixelFormat));
309 #ifdef RS_ENABLE_GPU
310         return Drawing::Image::MakeFromYUVAPixmaps(*gpuContext, info,
311             const_cast<void *>(reinterpret_cast<const void*>(pixelMap->GetPixels())));
312 #endif
313     }
314     return nullptr;
315 }
316 
IsSupportZeroCopy(std::shared_ptr<Media::PixelMap> pixelMap,const Drawing::SamplingOptions & sampling)317 bool RSPixelMapUtil::IsSupportZeroCopy(std::shared_ptr<Media::PixelMap> pixelMap,
318     const Drawing::SamplingOptions& sampling)
319 {
320     if (!(pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC)) {
321         return false;
322     }
323     return RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL;
324 }
325 } // namespace Rosen
326 } // namespace OHOS
327