• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "skia_image.h"
17 
18 #ifdef USE_M133_SKIA
19 #include "src/base/SkAutoMalloc.h"
20 #include "include/encode/SkJpegEncoder.h"
21 #include "include/encode/SkPngEncoder.h"
22 #include "include/encode/SkWebpEncoder.h"
23 #else
24 #include "src/core/SkAutoMalloc.h"
25 #endif
26 #include "src/core/SkReadBuffer.h"
27 #include "src/core/SkWriteBuffer.h"
28 #include "src/image/SkImage_Base.h"
29 
30 #include "draw/surface.h"
31 #include "image/bitmap.h"
32 #include "image/image.h"
33 #include "image/picture.h"
34 #include "utils/data.h"
35 #include "utils/log.h"
36 #include "utils/system_properties.h"
37 
38 #include "skia_bitmap.h"
39 #include "skia_data.h"
40 #include "skia_image_info.h"
41 #include "skia_pixmap.h"
42 #include "skia_surface.h"
43 #include "skia_texture_info.h"
44 
45 #ifdef RS_ENABLE_GPU
46 #include "include/core/SkYUVAPixmaps.h"
47 #include "skia_gpu_context.h"
48 #endif
49 
50 namespace OHOS {
51 namespace Rosen {
52 namespace Drawing {
SkiaImage()53 SkiaImage::SkiaImage() noexcept : skiaImage_(nullptr) {}
54 
SkiaImage(sk_sp<SkImage> skImg)55 SkiaImage::SkiaImage(sk_sp<SkImage> skImg) noexcept
56 {
57     PostSkImgToTargetThread();
58     skiaImage_ = skImg;
59 }
60 
~SkiaImage()61 SkiaImage::~SkiaImage()
62 {
63     PostSkImgToTargetThread();
64 }
65 
PostSkImgToTargetThread()66 void SkiaImage::PostSkImgToTargetThread()
67 {
68     if (skiaImage_ == nullptr) {
69         return;
70     }
71 #ifdef RS_ENABLE_GPU
72     auto context = as_IB(skiaImage_.get())->directContext();
73     auto func = SkiaGPUContext::GetPostFunc(sk_ref_sp(context));
74     if (func) {
75         func([image = skiaImage_.release()]() { SkSafeUnref(image); });
76     }
77 #endif
78 }
79 
MakeFromRaster(const Pixmap & pixmap,RasterReleaseProc rasterReleaseProc,ReleaseContext releaseContext)80 std::shared_ptr<Image> SkiaImage::MakeFromRaster(const Pixmap& pixmap,
81     RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
82 {
83     auto& skPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
84 #ifdef USE_M133_SKIA
85     sk_sp<SkImage> skImage = SkImages::RasterFromPixmap(skPixmap, rasterReleaseProc, releaseContext);
86 #else
87     sk_sp<SkImage> skImage = SkImage::MakeFromRaster(skPixmap, rasterReleaseProc, releaseContext);
88 #endif
89     if (skImage == nullptr) {
90         LOGD("SkiaImage::MakeFromRaster failed");
91         return nullptr;
92     }
93     std::shared_ptr<Image> image = std::make_shared<Image>();
94     image->GetImpl<SkiaImage>()->SetSkImage(skImage);
95     return image;
96 }
97 
MakeRasterData(const ImageInfo & info,std::shared_ptr<Data> pixels,size_t rowBytes)98 std::shared_ptr<Image> SkiaImage::MakeRasterData(const ImageInfo& info, std::shared_ptr<Data> pixels,
99     size_t rowBytes)
100 {
101     if (pixels == nullptr) {
102         LOGD("SkiaImage::MakeRasterData pixels is nullptr");
103         return nullptr;
104     }
105     SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
106     auto skData = pixels->GetImpl<SkiaData>()->GetSkData();
107 
108 #ifdef USE_M133_SKIA
109     sk_sp<SkImage> skImage = SkImages::RasterFromData(skImageInfo, skData, rowBytes);
110 #else
111     sk_sp<SkImage> skImage = SkImage::MakeRasterData(skImageInfo, skData, rowBytes);
112 #endif
113     if (skImage == nullptr) {
114         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
115         return nullptr;
116     }
117     std::shared_ptr<Image> image = std::make_shared<Image>();
118     image->GetImpl<SkiaImage>()->SetSkImage(skImage);
119     return image;
120 }
121 
BuildFromBitmap(const Bitmap & bitmap)122 bool SkiaImage::BuildFromBitmap(const Bitmap& bitmap)
123 {
124     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
125     if (skBitmapImpl != nullptr) {
126         const SkBitmap skBitmap = skBitmapImpl->ExportSkiaBitmap();
127         PostSkImgToTargetThread();
128 #ifdef USE_M133_SKIA
129         skiaImage_ = SkImages::RasterFromBitmap(skBitmap);
130 #else
131         skiaImage_ = SkImage::MakeFromBitmap(skBitmap);
132 #endif
133         return skiaImage_ != nullptr;
134     }
135     return false;
136 }
137 
138 #ifdef RS_ENABLE_GPU
MakeFromYUVAPixmaps(GPUContext & gpuContext,const YUVInfo & info,void * memory)139 std::shared_ptr<Image> SkiaImage::MakeFromYUVAPixmaps(GPUContext& gpuContext, const YUVInfo& info, void* memory)
140 {
141     if (!memory) {
142         LOGD("memory nullprt, %{public}s, %{public}d",  __FUNCTION__, __LINE__);
143         return nullptr;
144     }
145 
146     auto grContext = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
147     if (grContext == nullptr) {
148         LOGD("grContext nullprt, %{public}s, %{public}d",  __FUNCTION__, __LINE__);
149         return nullptr;
150     }
151     SkYUVAPixmapInfo pixmapInfo({{info.GetWidth(), info.GetHeight()},
152                                  SkiaYUVInfo::ConvertToSkPlaneConfig(info.GetConfig()),
153                                  SkiaYUVInfo::ConvertToSkSubSampling(info.GetSampling()),
154                                  SkiaYUVInfo::ConvertToSkYUVColorSpace(info.GetColorSpace())},
155                                  SkiaYUVInfo::ConvertToSkDataType(info.GetDataType()),
156                                  nullptr);
157     auto skYUVAPixmaps = SkYUVAPixmaps::FromExternalMemory(pixmapInfo, memory);
158 #ifdef USE_M133_SKIA
159     auto skImage = SkImages::TextureFromYUVAPixmaps(grContext.get(), skYUVAPixmaps);
160 #else
161     auto skImage = SkImage::MakeFromYUVAPixmaps(grContext.get(), skYUVAPixmaps);
162 #endif
163     if (skImage == nullptr) {
164         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
165         return nullptr;
166     }
167     std::shared_ptr<Image> image = std::make_shared<Image>();
168     image->GetImpl<SkiaImage>()->SetSkImage(skImage);
169     return image;
170 }
171 
BuildFromBitmap(GPUContext & gpuContext,const Bitmap & bitmap)172 bool SkiaImage::BuildFromBitmap(GPUContext& gpuContext, const Bitmap& bitmap)
173 {
174     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
175     auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
176     PostSkImgToTargetThread();
177 #ifdef USE_M133_SKIA
178     skiaImage_ = SkImages::CrossContextTextureFromPixmap(grContext_.get(), skBitmap.pixmap(), false);
179 #else
180     skiaImage_ = SkImage::MakeCrossContextFromPixmap(grContext_.get(), skBitmap.pixmap(), false);
181 #endif
182 
183     return (skiaImage_ != nullptr) ? true : false;
184 }
185 
MakeFromEncoded(const std::shared_ptr<Data> & data)186 bool SkiaImage::MakeFromEncoded(const std::shared_ptr<Data>& data)
187 {
188     if (data == nullptr) {
189         LOGD("SkiaImage::MakeFromEncoded failed, data is invalid");
190         return false;
191     }
192 
193     auto skData = data->GetImpl<SkiaData>()->GetSkData();
194     PostSkImgToTargetThread();
195 #ifdef USE_M133_SKIA
196     skiaImage_ = SkImages::DeferredFromEncodedData(skData);
197 #else
198     skiaImage_ = SkImage::MakeFromEncoded(skData);
199 #endif
200     return (skiaImage_ != nullptr);
201 }
202 
BuildSubset(const std::shared_ptr<Image> image,const RectI & rect,GPUContext & gpuContext)203 bool SkiaImage::BuildSubset(const std::shared_ptr<Image> image, const RectI& rect, GPUContext& gpuContext)
204 {
205     if (image == nullptr) {
206         LOGD("SkiaImage::BuildSubset failed, origin Image is invalid");
207         return false;
208     }
209     auto imageImpl = image->GetImpl<SkiaImage>();
210     if (imageImpl == nullptr) {
211         LOGD("SkiaImage::BuildSubset failed, GetImpl failed");
212         return false;
213     }
214     auto skiaImage = imageImpl->GetImage();
215     if (skiaImage == nullptr) {
216         LOGD("SkiaImage::BuildSubset failed, GetImage failed");
217         return false;
218     }
219 
220     auto skiaRect = SkIRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
221     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
222     PostSkImgToTargetThread();
223 #ifdef USE_M133_SKIA
224     skiaImage_ = skiaImage->makeSubset(grContext_.get(), skiaRect);
225 #else
226     skiaImage_ = skiaImage->makeSubset(skiaRect, grContext_.get());
227 #endif
228     return (skiaImage_ != nullptr) ? true : false;
229 }
230 
BuildFromCompressed(GPUContext & gpuContext,const std::shared_ptr<Data> & data,int width,int height,CompressedType type,const std::shared_ptr<ColorSpace> & colorSpace)231 bool SkiaImage::BuildFromCompressed(GPUContext& gpuContext, const std::shared_ptr<Data>& data, int width, int height,
232     CompressedType type, const std::shared_ptr<ColorSpace>& colorSpace)
233 {
234     if (data == nullptr) {
235         LOGD("SkiaImage::BuildFromCompressed, build failed, data is invalid");
236         return false;
237     }
238     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
239     auto skData = data->GetImpl<SkiaData>()->GetSkData();
240     PostSkImgToTargetThread();
241     sk_sp<SkColorSpace> skColorSpace = nullptr;
242     if (colorSpace != nullptr) {
243         auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
244         skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : SkColorSpace::MakeSRGB();
245     }
246 #ifdef USE_M133_SKIA
247     skiaImage_ = SkImages::TextureFromCompressedTextureData(grContext_.get(), skData, width, height,
248         static_cast<SkTextureCompressionType>(type), skgpu::Mipmapped::kNo, GrProtected::kNo, skColorSpace);
249 #else
250     skiaImage_ = SkImage::MakeTextureFromCompressed(grContext_.get(),
251         skData, width, height, static_cast<SkImage::CompressionType>(type),
252         GrMipmapped::kNo, GrProtected::kNo, skColorSpace);
253 #endif
254     return (skiaImage_ != nullptr) ? true : false;
255 }
256 
DeleteCleanupHelper(void (* deleteFunc)(void *),void * cleanupHelper)257 void SkiaImage::DeleteCleanupHelper(void (*deleteFunc)(void*), void* cleanupHelper)
258 {
259     if (deleteFunc == nullptr || cleanupHelper == nullptr) {
260         return;
261     }
262 
263     (*deleteFunc)(cleanupHelper);
264 }
265 
BuildFromTexture(GPUContext & gpuContext,const TextureInfo & info,TextureOrigin origin,BitmapFormat bitmapFormat,const std::shared_ptr<ColorSpace> & colorSpace,void (* deleteFunc)(void *),void * cleanupHelper)266 bool SkiaImage::BuildFromTexture(GPUContext& gpuContext, const TextureInfo& info, TextureOrigin origin,
267     BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace,
268     void (*deleteFunc)(void*), void* cleanupHelper)
269 {
270     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
271     if (!grContext_) {
272         LOGD("SkiaImage BuildFromTexture grContext_ is null");
273         DeleteCleanupHelper(deleteFunc, cleanupHelper);
274         return false;
275     }
276 
277     sk_sp<SkColorSpace> skColorSpace = nullptr;
278     if (colorSpace != nullptr) {
279         auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
280         skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : SkColorSpace::MakeSRGB();
281     } else {
282         skColorSpace = SkColorSpace::MakeSRGB();
283     }
284 
285 #ifdef RS_ENABLE_VK
286     if (SystemProperties::IsUseVulkan()) {
287         const auto& backendTexture = SkiaTextureInfo::ConvertToGrBackendTexture(info);
288         if (!backendTexture.isValid()) {
289             LOGE("SkiaImage BuildFromTexture backend texture is not valid!!!!");
290             DeleteCleanupHelper(deleteFunc, cleanupHelper);
291             return false;
292         }
293         PostSkImgToTargetThread();
294 #ifdef USE_M133_SKIA
295         skiaImage_ = SkImages::BorrowTextureFrom(grContext_.get(), backendTexture,
296             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
297             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
298             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace, deleteFunc, cleanupHelper);
299 #else
300         skiaImage_ = SkImage::MakeFromTexture(grContext_.get(), backendTexture,
301             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
302             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
303             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace, deleteFunc, cleanupHelper);
304 #endif
305     } else {
306         PostSkImgToTargetThread();
307 #ifdef USE_M133_SKIA
308         skiaImage_ = SkImages::BorrowTextureFrom(grContext_.get(),
309             SkiaTextureInfo::ConvertToGrBackendTexture(info),
310             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
311             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
312             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
313 #else
314         skiaImage_ = SkImage::MakeFromTexture(grContext_.get(),
315             SkiaTextureInfo::ConvertToGrBackendTexture(info),
316             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
317             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
318             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
319 #endif
320     }
321 #else
322     PostSkImgToTargetThread();
323 #ifdef USE_M133_SKIA
324     skiaImage_ = SkImages::BorrowTextureFrom(grContext_.get(), SkiaTextureInfo::ConvertToGrBackendTexture(info),
325         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
326         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
327 #else
328     skiaImage_ = SkImage::MakeFromTexture(grContext_.get(),  SkiaTextureInfo::ConvertToGrBackendTexture(info),
329         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
330         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
331 #endif
332 #endif
333     if (skiaImage_ == nullptr) {
334         LOGE("SkiaImage::MakeFromTexture skiaImage_ is nullptr!!!! "
335             "TextureInfo format:%{public}u, w:%{public}d, h:%{public}d , bitmapFormat.colorType is %{public}d",
336             info.GetFormat(), info.GetWidth(), info.GetHeight(), static_cast<int>(bitmapFormat.colorType));
337         return false;
338     }
339     return true;
340 }
341 
BuildFromSurface(GPUContext & gpuContext,Surface & surface,TextureOrigin origin,BitmapFormat bitmapFormat,const std::shared_ptr<ColorSpace> & colorSpace)342 bool SkiaImage::BuildFromSurface(GPUContext& gpuContext, Surface& surface, TextureOrigin origin,
343     BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace)
344 {
345     auto skSurface = surface.GetImpl<SkiaSurface>()->GetSkSurface();
346     if (!skSurface) {
347         LOGD("SkiaImage::BuildFromSurface skSurface is null");
348         return false;
349     }
350 
351 #ifdef USE_M133_SKIA
352     GrBackendTexture grBackendTexture =
353         SkSurfaces::GetBackendTexture(skSurface.get(), SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
354 #else
355     GrBackendTexture grBackendTexture
356             = skSurface->getBackendTexture(SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
357 #endif
358     if (!grBackendTexture.isValid()) {
359         LOGD("SkiaImage::BuildFromSurface grBackendTexture is invalid");
360         return false;
361     }
362     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
363 
364     sk_sp<SkColorSpace> skColorSpace = nullptr;
365     if (colorSpace != nullptr) {
366         auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
367         skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : nullptr;
368     }
369     PostSkImgToTargetThread();
370 #ifdef USE_M133_SKIA
371     skiaImage_ = SkImages::BorrowTextureFrom(grContext_.get(), grBackendTexture,
372         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
373         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
374 #else
375     skiaImage_ = SkImage::MakeFromTexture(grContext_.get(), grBackendTexture,
376         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
377         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
378 #endif
379     return (skiaImage_ != nullptr) ? true : false;
380 }
381 
SetGrBackendTexture(const GrBackendTexture & grBackendTexture)382 void SkiaImage::SetGrBackendTexture(const GrBackendTexture& grBackendTexture)
383 {
384     grBackendTexture_ = grBackendTexture;
385 }
386 
GetBackendTexture(bool flushPendingGrContextIO,TextureOrigin * origin)387 BackendTexture SkiaImage::GetBackendTexture(bool flushPendingGrContextIO, TextureOrigin* origin)
388 {
389     if (skiaImage_ == nullptr) {
390         LOGD("SkiaImage::GetBackendTexture, SkImage is nullptr!");
391         return BackendTexture(false); // invalid
392     }
393     GrBackendTexture skBackendTexture;
394 #ifdef USE_M133_SKIA
395     if (origin == nullptr) {
396         SkImages::GetBackendTextureFromImage(skiaImage_.get(), &skBackendTexture, flushPendingGrContextIO);
397     } else {
398         GrSurfaceOrigin grOrigin = SkiaTextureInfo::ConvertToGrSurfaceOrigin(*origin);
399         SkImages::GetBackendTextureFromImage(skiaImage_.get(), &skBackendTexture, flushPendingGrContextIO, &grOrigin);
400         *origin = static_cast<TextureOrigin>(grOrigin);
401     }
402 #else
403     if (origin == nullptr) {
404         skBackendTexture =
405             skiaImage_->getBackendTexture(flushPendingGrContextIO);
406     } else {
407         GrSurfaceOrigin grOrigin;
408         skBackendTexture =
409             skiaImage_->getBackendTexture(flushPendingGrContextIO, &grOrigin);
410         *origin = static_cast<TextureOrigin>(grOrigin);
411     }
412 #endif
413     if (!skBackendTexture.isValid()) {
414         LOGD("SkiaImage::GetBackendTexture, skBackendTexture is nullptr!");
415         return BackendTexture(false); // invalid
416     }
417     auto backendTexture = BackendTexture(true);
418     SetGrBackendTexture(skBackendTexture);
419 #ifdef RS_ENABLE_VK
420     if (SystemProperties::IsUseVulkan()) {
421         TextureInfo info;
422         SkiaTextureInfo::ConvertToVKTexture(skBackendTexture, info);
423         backendTexture.SetTextureInfo(info);
424     } else {
425         backendTexture.SetTextureInfo(SkiaTextureInfo::ConvertToTextureInfo(skBackendTexture));
426     }
427 #else
428     backendTexture.SetTextureInfo(SkiaTextureInfo::ConvertToTextureInfo(skBackendTexture));
429 #endif
430     return backendTexture;
431 }
432 
IsValid(GPUContext * context) const433 bool SkiaImage::IsValid(GPUContext* context) const
434 {
435     if (skiaImage_ == nullptr) {
436         LOGD("SkiaImage::IsValid, skiaImage_ is nullptr!");
437         return false;
438     }
439     if (context == nullptr) {
440         return skiaImage_->isValid(nullptr);
441     }
442     return skiaImage_->isValid(context->GetImpl<SkiaGPUContext>()->GetGrContext().get());
443 }
444 #endif
445 
AsLegacyBitmap(Bitmap & bitmap) const446 bool SkiaImage::AsLegacyBitmap(Bitmap& bitmap) const
447 {
448     if (skiaImage_ == nullptr) {
449         LOGD("SkiaImage::IsValid, skiaImage_ is nullptr!");
450         return false;
451     }
452     SkBitmap newBitmap;
453     if (!skiaImage_->asLegacyBitmap(&newBitmap)) {
454         LOGD("SkiaImage::AsLegacyBitmap failed!");
455         return false;
456     }
457     bitmap.GetImpl<SkiaBitmap>()->SetSkBitmap(newBitmap);
458     return true;
459 }
460 
GetWidth() const461 int SkiaImage::GetWidth() const
462 {
463     return (skiaImage_ == nullptr) ? 0 : skiaImage_->width();
464 }
465 
GetHeight() const466 int SkiaImage::GetHeight() const
467 {
468     return (skiaImage_ == nullptr) ? 0 : skiaImage_->height();
469 }
470 
GetColorType() const471 ColorType SkiaImage::GetColorType() const
472 {
473     return (skiaImage_ == nullptr) ? ColorType::COLORTYPE_UNKNOWN :
474                                      SkiaImageInfo::ConvertToColorType(skiaImage_->colorType());
475 }
476 
GetAlphaType() const477 AlphaType SkiaImage::GetAlphaType() const
478 {
479     return (skiaImage_ == nullptr) ? AlphaType::ALPHATYPE_UNKNOWN :
480                                      SkiaImageInfo::ConvertToAlphaType(skiaImage_->alphaType());
481 }
482 
GetColorSpace() const483 std::shared_ptr<ColorSpace> SkiaImage::GetColorSpace() const
484 {
485     if (skiaImage_ == nullptr) {
486         return nullptr;
487     }
488     sk_sp<SkColorSpace> skColorSpace = skiaImage_->refColorSpace();
489     if (skColorSpace == nullptr) {
490         return nullptr;
491     }
492     std::shared_ptr<ColorSpace> colorSpace = std::make_shared<ColorSpace>();
493     colorSpace->GetImpl<SkiaColorSpace>()->SetColorSpace(skColorSpace);
494     return colorSpace;
495 }
496 
GetUniqueID() const497 uint32_t SkiaImage::GetUniqueID() const
498 {
499     return (skiaImage_ == nullptr) ? 0 : skiaImage_->uniqueID();
500 }
501 
GetImageInfo()502 ImageInfo SkiaImage::GetImageInfo()
503 {
504     if (skiaImage_ == nullptr) {
505         return {};
506     }
507     return SkiaImageInfo::ConvertToRSImageInfo(skiaImage_->imageInfo());
508 }
509 
ReadPixels(Bitmap & bitmap,int x,int y)510 bool SkiaImage::ReadPixels(Bitmap& bitmap, int x, int y)
511 {
512     const auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
513     const auto& skPixmap = skBitmap.pixmap();
514 
515     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skPixmap, x, y);
516 }
517 
ReadPixels(Pixmap & pixmap,int x,int y)518 bool SkiaImage::ReadPixels(Pixmap& pixmap, int x, int y)
519 {
520     auto& skPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
521     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skPixmap, x, y);
522 }
523 
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int32_t srcX,int32_t srcY) const524 bool SkiaImage::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
525     int32_t srcX, int32_t srcY) const
526 {
527     SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(dstInfo);
528     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skImageInfo, dstPixels, dstRowBytes, srcX, srcY);
529 }
530 
IsTextureBacked() const531 bool SkiaImage::IsTextureBacked() const
532 {
533     return (skiaImage_ == nullptr) ? false : skiaImage_->isTextureBacked();
534 }
535 
ScalePixels(const Bitmap & bitmap,const SamplingOptions & sampling,bool allowCachingHint) const536 bool SkiaImage::ScalePixels(const Bitmap& bitmap, const SamplingOptions& sampling, bool allowCachingHint) const
537 {
538     const auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
539     const auto& skPixmap = skBitmap.pixmap();
540 
541     SkSamplingOptions samplingOptions;
542     if (sampling.GetUseCubic()) {
543         samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
544     } else {
545         samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
546             static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
547     }
548 
549     SkImage::CachingHint skCachingHint;
550     if (allowCachingHint) {
551         skCachingHint = SkImage::CachingHint::kAllow_CachingHint;
552     } else {
553         skCachingHint = SkImage::CachingHint::kDisallow_CachingHint;
554     }
555 
556     return (skiaImage_ == nullptr) ? false : skiaImage_->scalePixels(skPixmap, samplingOptions, skCachingHint);
557 }
558 
EncodeToData(EncodedImageFormat encodedImageFormat,int quality) const559 std::shared_ptr<Data> SkiaImage::EncodeToData(EncodedImageFormat encodedImageFormat, int quality) const
560 {
561     if (skiaImage_ == nullptr) {
562         LOGD("SkiaImage::EncodeToData, skiaImage_ is null!");
563         return nullptr;
564     }
565 #ifdef USE_M133_SKIA
566     auto grContext = as_IB(skiaImage_.get())->directContext();
567     sk_sp<SkData> skData = nullptr;
568     if (encodedImageFormat == EncodedImageFormat::PNG) {
569         SkPngEncoder::Options options;
570         skData = SkPngEncoder::Encode(grContext, skiaImage_.get(), options);
571     } else if (encodedImageFormat == EncodedImageFormat::JPEG) {
572         SkJpegEncoder::Options options;
573         options.fQuality = quality;
574         skData = SkJpegEncoder::Encode(grContext, skiaImage_.get(), options);
575     } else if (encodedImageFormat == EncodedImageFormat::WEBP) {
576         SkWebpEncoder::Options options;
577         if (quality == 100) { // quality is 100
578             options.fCompression = SkWebpEncoder::Compression::kLossless;
579             options.fQuality = 75; // default options quality is 75
580         } else {
581             options.fCompression = SkWebpEncoder::Compression::kLossy;
582             options.fQuality = quality;
583         }
584         skData = SkWebpEncoder::Encode(grContext, skiaImage_.get(), options);
585     } else {
586         LOGD("SkiaImage::EncodeToData failed, unsupported format!");
587         return nullptr;
588     }
589 #else
590     SkEncodedImageFormat skEncodedImageFormat = SkiaImageInfo::ConvertToSkEncodedImageFormat(encodedImageFormat);
591     auto skData = skiaImage_->encodeToData(skEncodedImageFormat, quality);
592 #endif
593     if (skData == nullptr) {
594         LOGD("SkiaImage::EncodeToData, skData null!");
595         return nullptr;
596     }
597     std::shared_ptr<Data> data = std::make_shared<Data>();
598     data->GetImpl<SkiaData>()->SetSkData(skData);
599     return data;
600 }
601 
IsLazyGenerated() const602 bool SkiaImage::IsLazyGenerated() const
603 {
604     return (skiaImage_ == nullptr) ? false : skiaImage_->isLazyGenerated();
605 }
606 
GetROPixels(Bitmap & bitmap) const607 bool SkiaImage::GetROPixels(Bitmap& bitmap) const
608 {
609     if (skiaImage_ == nullptr) {
610         LOGD("SkiaImage::GetROPixels, skiaImage_ is null!");
611         return false;
612     }
613     auto context = as_IB(skiaImage_.get())->directContext();
614     if (!as_IB(skiaImage_.get())->getROPixels(context, &bitmap.GetImpl<SkiaBitmap>()->GetSkBitmap())) {
615         LOGD("skiaImge getROPixels failed");
616         return false;
617     }
618     return true;
619 }
620 
MakeRasterImage() const621 std::shared_ptr<Image> SkiaImage::MakeRasterImage() const
622 {
623     if (skiaImage_ == nullptr) {
624         return nullptr;
625     }
626     sk_sp<SkImage> skImage = skiaImage_->makeRasterImage();
627     if (skImage == nullptr) {
628         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
629         return nullptr;
630     }
631     std::shared_ptr<Image> image = std::make_shared<Image>();
632     image->GetImpl<SkiaImage>()->SetSkImage(skImage);
633     return image;
634 }
635 
CanPeekPixels() const636 bool SkiaImage::CanPeekPixels() const
637 {
638     SkPixmap pixmap;
639     if (skiaImage_ == nullptr || !skiaImage_->peekPixels(&pixmap)) {
640         return false;
641     }
642     return true;
643 }
644 
IsOpaque() const645 bool SkiaImage::IsOpaque() const
646 {
647     return (skiaImage_ == nullptr) ? false : skiaImage_->isOpaque();
648 }
649 
HintCacheGpuResource() const650 void SkiaImage::HintCacheGpuResource() const
651 {
652     as_IB(skiaImage_.get())->hintCacheGpuResource();
653 }
654 
GetImage() const655 const sk_sp<SkImage> SkiaImage::GetImage() const
656 {
657     return skiaImage_;
658 }
659 
SetSkImage(const sk_sp<SkImage> & skImage)660 void SkiaImage::SetSkImage(const sk_sp<SkImage>& skImage)
661 {
662     PostSkImgToTargetThread();
663     skiaImage_ = skImage;
664 }
665 
666 #ifdef RS_ENABLE_GPU
GetGrContext() const667 sk_sp<GrDirectContext> SkiaImage::GetGrContext() const
668 {
669     return grContext_;
670 }
671 #endif
672 
Serialize() const673 std::shared_ptr<Data> SkiaImage::Serialize() const
674 {
675     if (skiaImage_ == nullptr) {
676         LOGD("SkiaImage::Serialize, SkImage is nullptr!");
677         return nullptr;
678     }
679 
680 #ifdef USE_M133_SKIA
681     SkBinaryWriteBuffer writer({});
682 #else
683     SkBinaryWriteBuffer writer;
684 #endif
685     bool type = skiaImage_->isLazyGenerated();
686     writer.writeBool(type);
687     if (type) {
688         writer.writeImage(skiaImage_.get());
689         size_t length = writer.bytesWritten();
690         std::shared_ptr<Data> data = std::make_shared<Data>();
691         data->BuildUninitialized(length);
692         writer.writeToMemory(data->WritableData());
693         return data;
694     } else {
695         SkBitmap bitmap;
696 
697         auto context = as_IB(skiaImage_.get())->directContext();
698         if (!as_IB(skiaImage_.get())->getROPixels(context, &bitmap)) {
699             LOGD("SkiaImage::SerializeNoLazyImage SkImage getROPixels failed");
700             return nullptr;
701         }
702         SkPixmap pixmap;
703         if (!bitmap.peekPixels(&pixmap)) {
704             LOGD("SkiaImage::SerializeNoLazyImage SkImage peekPixels failed");
705             return nullptr;
706         }
707         size_t rb = pixmap.rowBytes();
708         int32_t width = pixmap.width();
709         int32_t height = pixmap.height();
710         const void* addr = pixmap.addr();
711         size_t size = pixmap.computeByteSize();
712 
713         writer.writeUInt(size);
714         writer.writeByteArray(addr, size);
715         writer.writeUInt(rb);
716         writer.write32(width);
717         writer.write32(height);
718 
719         writer.writeUInt(pixmap.colorType());
720         writer.writeUInt(pixmap.alphaType());
721 
722         if (pixmap.colorSpace() == nullptr) {
723             writer.writeUInt(0);
724         } else {
725             auto data = pixmap.colorSpace()->serialize();
726             writer.writeUInt(data->size());
727             writer.writeByteArray(data->data(), data->size());
728         }
729         size_t length = writer.bytesWritten();
730         std::shared_ptr<Data> data = std::make_shared<Data>();
731         data->BuildUninitialized(length);
732         writer.writeToMemory(data->WritableData());
733         return data;
734     }
735 }
736 
Deserialize(std::shared_ptr<Data> data)737 bool SkiaImage::Deserialize(std::shared_ptr<Data> data)
738 {
739     if (data == nullptr) {
740         LOGD("SkiaImage::Deserialize, data is invalid!");
741         return false;
742     }
743 
744     SkReadBuffer reader(data->GetData(), data->GetSize());
745     bool type = reader.readBool();
746     if (type) {
747         PostSkImgToTargetThread();
748         skiaImage_ = reader.readImage();
749         return skiaImage_ != nullptr;
750     } else {
751         size_t pixmapSize = reader.readUInt();
752         SkAutoMalloc pixBuffer(pixmapSize);
753         if (!reader.readByteArray(pixBuffer.get(), pixmapSize)) {
754             return false;
755         }
756 
757         size_t rb = reader.readUInt();
758         int32_t width = reader.read32();
759         int32_t height = reader.read32();
760 
761         SkColorType colorType = static_cast<SkColorType>(reader.readUInt());
762         SkAlphaType alphaType = static_cast<SkAlphaType>(reader.readUInt());
763         sk_sp<SkColorSpace> colorSpace;
764 
765         size_t size = reader.readUInt();
766         if (size == 0) {
767             colorSpace = nullptr;
768         } else {
769             SkAutoMalloc colorBuffer(size);
770             if (!reader.readByteArray(colorBuffer.get(), size)) {
771                 return false;
772             }
773             colorSpace = SkColorSpace::Deserialize(colorBuffer.get(), size);
774         }
775 
776         SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
777         auto skData = SkData::MakeWithCopy(const_cast<void*>(pixBuffer.get()), pixmapSize);
778         PostSkImgToTargetThread();
779 #ifdef USE_M133_SKIA
780         skiaImage_ = SkImages::RasterFromData(imageInfo, skData, rb);
781 #else
782         skiaImage_ = SkImage::MakeRasterData(imageInfo, skData, rb);
783 #endif
784 
785         return true;
786     }
787 }
788 
SetHeadroom(float headroom)789 void SkiaImage::SetHeadroom(float headroom)
790 {
791     LOGD("SkiaImage does not support SetHeadroom!");
792 }
793 
GetHeadroom() const794 float SkiaImage::GetHeadroom() const
795 {
796     LOGD("SkiaImage does not support GetHeadroom!");
797     return 1.0f;
798 }
799 } // namespace Drawing
800 } // namespace Rosen
801 } // namespace OHOS
802