• 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 #include "src/core/SkAutoMalloc.h"
19 #include "src/core/SkReadBuffer.h"
20 #include "src/core/SkWriteBuffer.h"
21 #include "src/image/SkImage_Base.h"
22 
23 #include "draw/surface.h"
24 #include "image/bitmap.h"
25 #include "image/image.h"
26 #include "image/picture.h"
27 #include "utils/data.h"
28 #include "utils/log.h"
29 #include "utils/system_properties.h"
30 
31 #include "skia_bitmap.h"
32 #include "skia_data.h"
33 #include "skia_image_info.h"
34 #include "skia_pixmap.h"
35 #include "skia_surface.h"
36 #include "skia_texture_info.h"
37 
38 #ifdef ACE_ENABLE_GPU
39 #include "include/core/SkYUVAPixmaps.h"
40 #include "skia_gpu_context.h"
41 #endif
42 
43 namespace OHOS {
44 namespace Rosen {
45 namespace Drawing {
SkiaImage()46 SkiaImage::SkiaImage() noexcept : skiaImage_(nullptr) {}
47 
SkiaImage(sk_sp<SkImage> skImg)48 SkiaImage::SkiaImage(sk_sp<SkImage> skImg) noexcept
49 {
50     PostSkImgToTargetThread();
51     skiaImage_ = skImg;
52 }
53 
~SkiaImage()54 SkiaImage::~SkiaImage()
55 {
56     PostSkImgToTargetThread();
57 }
58 
PostSkImgToTargetThread()59 void SkiaImage::PostSkImgToTargetThread()
60 {
61     if (skiaImage_ == nullptr) {
62         return;
63     }
64     auto context = as_IB(skiaImage_.get())->directContext();
65     auto func = SkiaGPUContext::GetPostFunc(sk_ref_sp(context));
66     if (func) {
67         auto image = skiaImage_;
68         func([image]() {});
69     }
70 }
71 
MakeFromRaster(const Pixmap & pixmap,RasterReleaseProc rasterReleaseProc,ReleaseContext releaseContext)72 std::shared_ptr<Image> SkiaImage::MakeFromRaster(const Pixmap& pixmap,
73     RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
74 {
75     auto& skPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
76     sk_sp<SkImage> skImage = SkImage::MakeFromRaster(skPixmap, rasterReleaseProc, releaseContext);
77     if (skImage == nullptr) {
78         LOGD("SkiaImage::MakeFromRaster failed");
79         return nullptr;
80     }
81     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
82     return std::make_shared<Image>(imageImpl);
83 }
84 
MakeRasterData(const ImageInfo & info,std::shared_ptr<Data> pixels,size_t rowBytes)85 std::shared_ptr<Image> SkiaImage::MakeRasterData(const ImageInfo& info, std::shared_ptr<Data> pixels,
86     size_t rowBytes)
87 {
88     if (pixels == nullptr) {
89         LOGD("SkiaImage::MakeRasterData pixels is nullptr");
90         return nullptr;
91     }
92     SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
93     auto skData = pixels->GetImpl<SkiaData>()->GetSkData();
94 
95     sk_sp<SkImage> skImage = SkImage::MakeRasterData(skImageInfo, skData, rowBytes);
96     if (skImage == nullptr) {
97         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
98         return nullptr;
99     }
100     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
101     return std::make_shared<Image>(imageImpl);
102 }
103 
BuildFromBitmap(const Bitmap & bitmap)104 bool SkiaImage::BuildFromBitmap(const Bitmap& bitmap)
105 {
106     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
107     if (skBitmapImpl != nullptr) {
108         const SkBitmap skBitmap = skBitmapImpl->ExportSkiaBitmap();
109         PostSkImgToTargetThread();
110         skiaImage_ = SkImage::MakeFromBitmap(skBitmap);
111         return skiaImage_ != nullptr;
112     }
113     return false;
114 }
115 
116 #ifdef ACE_ENABLE_GPU
MakeFromYUVAPixmaps(GPUContext & gpuContext,const YUVInfo & info,void * memory)117 std::shared_ptr<Image> SkiaImage::MakeFromYUVAPixmaps(GPUContext& gpuContext, const YUVInfo& info, void* memory)
118 {
119     if (!memory) {
120         LOGD("memory nullprt, %{public}s, %{public}d",  __FUNCTION__, __LINE__);
121         return nullptr;
122     }
123 
124     auto grContext = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
125     if (grContext == nullptr) {
126         LOGD("grContext nullprt, %{public}s, %{public}d",  __FUNCTION__, __LINE__);
127         return nullptr;
128     }
129     SkYUVAPixmapInfo pixmapInfo({{info.GetWidth(), info.GetHeight()},
130                                  SkiaYUVInfo::ConvertToSkPlaneConfig(info.GetConfig()),
131                                  SkiaYUVInfo::ConvertToSkSubSampling(info.GetSampling()),
132                                  SkiaYUVInfo::ConvertToSkYUVColorSpace(info.GetColorSpace())},
133                                  SkYUVAPixmapInfo::DataType::kUnorm8,
134                                  nullptr);
135     auto skYUVAPixmaps = SkYUVAPixmaps::FromExternalMemory(pixmapInfo, memory);
136     auto skImage = SkImage::MakeFromYUVAPixmaps(grContext.get(), skYUVAPixmaps);
137     if (skImage == nullptr) {
138         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
139         return nullptr;
140     }
141     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
142     return std::make_shared<Image>(imageImpl);
143 }
144 
BuildFromBitmap(GPUContext & gpuContext,const Bitmap & bitmap)145 bool SkiaImage::BuildFromBitmap(GPUContext& gpuContext, const Bitmap& bitmap)
146 {
147     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
148     auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
149     PostSkImgToTargetThread();
150     skiaImage_ = SkImage::MakeCrossContextFromPixmap(grContext_.get(), skBitmap.pixmap(), false);
151 
152     return (skiaImage_ != nullptr) ? true : false;
153 }
154 
MakeFromEncoded(const std::shared_ptr<Data> & data)155 bool SkiaImage::MakeFromEncoded(const std::shared_ptr<Data>& data)
156 {
157     if (data == nullptr) {
158         LOGD("SkiaImage::MakeFromEncoded failed, data is invalid");
159         return false;
160     }
161 
162     auto skData = data->GetImpl<SkiaData>()->GetSkData();
163     PostSkImgToTargetThread();
164     skiaImage_ = SkImage::MakeFromEncoded(skData);
165     return (skiaImage_ != nullptr);
166 }
167 
BuildSubset(const std::shared_ptr<Image> image,const RectI & rect,GPUContext & gpuContext)168 bool SkiaImage::BuildSubset(const std::shared_ptr<Image> image, const RectI& rect, GPUContext& gpuContext)
169 {
170     if (image == nullptr) {
171         LOGD("SkiaImage::BuildSubset failed, origin Image is invalid");
172         return false;
173     }
174     auto imageImpl = image->GetImpl<SkiaImage>();
175     if (imageImpl == nullptr) {
176         LOGD("SkiaImage::BuildSubset failed, GetImpl failed");
177         return false;
178     }
179     auto skiaImage = imageImpl->GetImage();
180     if (skiaImage == nullptr) {
181         LOGD("SkiaImage::BuildSubset failed, GetImage failed");
182         return false;
183     }
184     auto skiaRect = SkIRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
185     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
186     PostSkImgToTargetThread();
187     skiaImage_ = skiaImage->makeSubset(skiaRect, grContext_.get());
188     return (skiaImage_ != nullptr) ? true : false;
189 }
190 
BuildFromCompressed(GPUContext & gpuContext,const std::shared_ptr<Data> & data,int width,int height,CompressedType type,const std::shared_ptr<ColorSpace> & colorSpace)191 bool SkiaImage::BuildFromCompressed(GPUContext& gpuContext, const std::shared_ptr<Data>& data, int width, int height,
192     CompressedType type, const std::shared_ptr<ColorSpace>& colorSpace)
193 {
194     if (data == nullptr) {
195         LOGD("SkiaImage::BuildFromCompressed, build failed, data is invalid");
196         return false;
197     }
198     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
199     auto skData = data->GetImpl<SkiaData>()->GetSkData();
200     PostSkImgToTargetThread();
201     sk_sp<SkColorSpace> skColorSpace = nullptr;
202     if (colorSpace != nullptr) {
203         auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
204         skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : SkColorSpace::MakeSRGB();
205     }
206     skiaImage_ = SkImage::MakeTextureFromCompressed(grContext_.get(),
207         skData, width, height, static_cast<SkImage::CompressionType>(type),
208         GrMipmapped::kNo, GrProtected::kNo, skColorSpace);
209     return (skiaImage_ != nullptr) ? true : false;
210 }
211 
DeleteCleanupHelper(void (* deleteFunc)(void *),void * cleanupHelper)212 void SkiaImage::DeleteCleanupHelper(void (*deleteFunc)(void*), void* cleanupHelper)
213 {
214     if (deleteFunc == nullptr || cleanupHelper == nullptr) {
215         return;
216     }
217 
218     (*deleteFunc)(cleanupHelper);
219 }
220 
BuildFromTexture(GPUContext & gpuContext,const TextureInfo & info,TextureOrigin origin,BitmapFormat bitmapFormat,const std::shared_ptr<ColorSpace> & colorSpace,void (* deleteFunc)(void *),void * cleanupHelper)221 bool SkiaImage::BuildFromTexture(GPUContext& gpuContext, const TextureInfo& info, TextureOrigin origin,
222     BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace,
223     void (*deleteFunc)(void*), void* cleanupHelper)
224 {
225     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
226     if (!grContext_) {
227         LOGD("SkiaImage BuildFromTexture grContext_ is null");
228         DeleteCleanupHelper(deleteFunc, cleanupHelper);
229         return false;
230     }
231 
232     sk_sp<SkColorSpace> skColorSpace = nullptr;
233     if (colorSpace != nullptr) {
234         auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
235         skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : SkColorSpace::MakeSRGB();
236     } else {
237         skColorSpace = SkColorSpace::MakeSRGB();
238     }
239 
240 #ifdef RS_ENABLE_VK
241     if (SystemProperties::IsUseVulkan()) {
242         const auto& backendTexture = SkiaTextureInfo::ConvertToGrBackendTexture(info);
243         if (!backendTexture.isValid()) {
244             LOGE("SkiaImage BuildFromTexture backend texture is not valid!!!!");
245             DeleteCleanupHelper(deleteFunc, cleanupHelper);
246             return false;
247         }
248         PostSkImgToTargetThread();
249         skiaImage_ = SkImage::MakeFromTexture(grContext_.get(), backendTexture,
250             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
251             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
252             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace, deleteFunc, cleanupHelper);
253     } else {
254         PostSkImgToTargetThread();
255         skiaImage_ = SkImage::MakeFromTexture(grContext_.get(),
256             SkiaTextureInfo::ConvertToGrBackendTexture(info),
257             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
258             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
259             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
260     }
261 #else
262     PostSkImgToTargetThread();
263     skiaImage_ = SkImage::MakeFromTexture(grContext_.get(),  SkiaTextureInfo::ConvertToGrBackendTexture(info),
264         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
265         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
266 #endif
267     if (skiaImage_ == nullptr) {
268         LOGE("SkiaImage::MakeFromTexture skiaImage_ is nullptr!!!! "
269             "TextureInfo format:%{public}u, w:%{public}d, h:%{public}d , bitmapFormat.colorType is %{public}d",
270             info.GetFormat(), info.GetWidth(), info.GetHeight(), static_cast<int>(bitmapFormat.colorType));
271         return false;
272     }
273     return true;
274 }
275 
BuildFromSurface(GPUContext & gpuContext,Surface & surface,TextureOrigin origin,BitmapFormat bitmapFormat,const std::shared_ptr<ColorSpace> & colorSpace)276 bool SkiaImage::BuildFromSurface(GPUContext& gpuContext, Surface& surface, TextureOrigin origin,
277     BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace)
278 {
279     auto skSurface = surface.GetImpl<SkiaSurface>()->GetSkSurface();
280     if (!skSurface) {
281         LOGD("SkiaImage::BuildFromSurface skSurface is null");
282         return false;
283     }
284 
285     GrBackendTexture grBackendTexture
286             = skSurface->getBackendTexture(SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
287     if (!grBackendTexture.isValid()) {
288         LOGD("SkiaImage::BuildFromSurface grBackendTexture is invalid");
289         return false;
290     }
291     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
292 
293     sk_sp<SkColorSpace> skColorSpace = nullptr;
294     if (colorSpace != nullptr) {
295         auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
296         skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : nullptr;
297     }
298     PostSkImgToTargetThread();
299     skiaImage_ = SkImage::MakeFromTexture(grContext_.get(), grBackendTexture,
300         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
301         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
302     return (skiaImage_ != nullptr) ? true : false;
303 }
304 
SetGrBackendTexture(const GrBackendTexture & grBackendTexture)305 void SkiaImage::SetGrBackendTexture(const GrBackendTexture& grBackendTexture)
306 {
307     grBackendTexture_ = grBackendTexture;
308 }
309 
GetBackendTexture(bool flushPendingGrContextIO,TextureOrigin * origin)310 BackendTexture SkiaImage::GetBackendTexture(bool flushPendingGrContextIO, TextureOrigin* origin)
311 {
312     if (skiaImage_ == nullptr) {
313         LOGD("SkiaImage::GetBackendTexture, SkImage is nullptr!");
314         return BackendTexture(false); // invalid
315     }
316     GrBackendTexture skBackendTexture;
317     if (origin == nullptr) {
318         skBackendTexture =
319             skiaImage_->getBackendTexture(flushPendingGrContextIO);
320     } else {
321         GrSurfaceOrigin grOrigin = SkiaTextureInfo::ConvertToGrSurfaceOrigin(*origin);
322         skBackendTexture =
323             skiaImage_->getBackendTexture(flushPendingGrContextIO, &grOrigin);
324     }
325     if (!skBackendTexture.isValid()) {
326         LOGD("SkiaImage::GetBackendTexture, skBackendTexture is nullptr!");
327         return BackendTexture(false); // invalid
328     }
329     auto backendTexture = BackendTexture(true);
330     SetGrBackendTexture(skBackendTexture);
331 #ifdef RS_ENABLE_VK
332     if (SystemProperties::IsUseVulkan()) {
333         TextureInfo info;
334         SkiaTextureInfo::ConvertToVKTexture(skBackendTexture, info);
335         backendTexture.SetTextureInfo(info);
336     } else {
337         backendTexture.SetTextureInfo(SkiaTextureInfo::ConvertToTextureInfo(skBackendTexture));
338     }
339 #else
340     backendTexture.SetTextureInfo(SkiaTextureInfo::ConvertToTextureInfo(skBackendTexture));
341 #endif
342     return backendTexture;
343 }
344 
IsValid(GPUContext * context) const345 bool SkiaImage::IsValid(GPUContext* context) const
346 {
347     if (skiaImage_ == nullptr) {
348         LOGD("SkiaImage::IsValid, skiaImage_ is nullptr!");
349         return false;
350     }
351     if (context == nullptr) {
352         return skiaImage_->isValid(nullptr);
353     }
354     return skiaImage_->isValid(context->GetImpl<SkiaGPUContext>()->GetGrContext().get());
355 }
356 #endif
357 
AsLegacyBitmap(Bitmap & bitmap) const358 bool SkiaImage::AsLegacyBitmap(Bitmap& bitmap) const
359 {
360     if (skiaImage_ == nullptr) {
361         LOGD("SkiaImage::IsValid, skiaImage_ is nullptr!");
362         return false;
363     }
364     SkBitmap newBitmap;
365     if (!skiaImage_->asLegacyBitmap(&newBitmap)) {
366         LOGD("SkiaImage::AsLegacyBitmap failed!");
367         return false;
368     }
369     bitmap.GetImpl<SkiaBitmap>()->SetSkBitmap(newBitmap);
370     return true;
371 }
372 
GetWidth() const373 int SkiaImage::GetWidth() const
374 {
375     return (skiaImage_ == nullptr) ? 0 : skiaImage_->width();
376 }
377 
GetHeight() const378 int SkiaImage::GetHeight() const
379 {
380     return (skiaImage_ == nullptr) ? 0 : skiaImage_->height();
381 }
382 
GetColorType() const383 ColorType SkiaImage::GetColorType() const
384 {
385     return (skiaImage_ == nullptr) ? ColorType::COLORTYPE_UNKNOWN :
386                                      SkiaImageInfo::ConvertToColorType(skiaImage_->colorType());
387 }
388 
GetAlphaType() const389 AlphaType SkiaImage::GetAlphaType() const
390 {
391     return (skiaImage_ == nullptr) ? AlphaType::ALPHATYPE_UNKNOWN :
392                                      SkiaImageInfo::ConvertToAlphaType(skiaImage_->alphaType());
393 }
394 
GetColorSpace() const395 std::shared_ptr<ColorSpace> SkiaImage::GetColorSpace() const
396 {
397     if (skiaImage_ == nullptr) {
398         return nullptr;
399     }
400     sk_sp<SkColorSpace> skColorSpace = skiaImage_->refColorSpace();
401     if (skColorSpace == nullptr) {
402         return nullptr;
403     }
404     std::shared_ptr<ColorSpace> colorSpace = std::make_shared<ColorSpace>();
405     colorSpace->GetImpl<SkiaColorSpace>()->SetColorSpace(skColorSpace);
406     return colorSpace;
407 }
408 
GetUniqueID() const409 uint32_t SkiaImage::GetUniqueID() const
410 {
411     return (skiaImage_ == nullptr) ? 0 : skiaImage_->uniqueID();
412 }
413 
GetImageInfo()414 ImageInfo SkiaImage::GetImageInfo()
415 {
416     if (skiaImage_ == nullptr) {
417         return {};
418     }
419     return SkiaImageInfo::ConvertToRSImageInfo(skiaImage_->imageInfo());
420 }
421 
ReadPixels(Bitmap & bitmap,int x,int y)422 bool SkiaImage::ReadPixels(Bitmap& bitmap, int x, int y)
423 {
424     const auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
425     const auto& skPixmap = skBitmap.pixmap();
426 
427     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skPixmap, x, y);
428 }
429 
ReadPixels(Pixmap & pixmap,int x,int y)430 bool SkiaImage::ReadPixels(Pixmap& pixmap, int x, int y)
431 {
432     auto& skPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
433     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skPixmap, x, y);
434 }
435 
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int32_t srcX,int32_t srcY) const436 bool SkiaImage::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
437     int32_t srcX, int32_t srcY) const
438 {
439     SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(dstInfo);
440     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skImageInfo, dstPixels, dstRowBytes, srcX, srcY);
441 }
442 
IsTextureBacked() const443 bool SkiaImage::IsTextureBacked() const
444 {
445     return (skiaImage_ == nullptr) ? false : skiaImage_->isTextureBacked();
446 }
447 
ScalePixels(const Bitmap & bitmap,const SamplingOptions & sampling,bool allowCachingHint) const448 bool SkiaImage::ScalePixels(const Bitmap& bitmap, const SamplingOptions& sampling, bool allowCachingHint) const
449 {
450     const auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
451     const auto& skPixmap = skBitmap.pixmap();
452 
453     SkSamplingOptions samplingOptions;
454     if (sampling.GetUseCubic()) {
455         samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
456     } else {
457         samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
458             static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
459     }
460 
461     SkImage::CachingHint skCachingHint;
462     if (allowCachingHint) {
463         skCachingHint = SkImage::CachingHint::kAllow_CachingHint;
464     } else {
465         skCachingHint = SkImage::CachingHint::kDisallow_CachingHint;
466     }
467 
468     return (skiaImage_ == nullptr) ? false : skiaImage_->scalePixels(skPixmap, samplingOptions, skCachingHint);
469 }
470 
EncodeToData(EncodedImageFormat encodedImageFormat,int quality) const471 std::shared_ptr<Data> SkiaImage::EncodeToData(EncodedImageFormat encodedImageFormat, int quality) const
472 {
473     if (skiaImage_ == nullptr) {
474         LOGD("SkiaImage::EncodeToData, skiaImage_ is null!");
475         return nullptr;
476     }
477     SkEncodedImageFormat skEncodedImageFormat = SkiaImageInfo::ConvertToSkEncodedImageFormat(encodedImageFormat);
478     auto skData = skiaImage_->encodeToData(skEncodedImageFormat, quality);
479     if (skData == nullptr) {
480         LOGD("SkiaImage::EncodeToData, skData null!");
481         return nullptr;
482     }
483     std::shared_ptr<Data> data = std::make_shared<Data>();
484     data->GetImpl<SkiaData>()->SetSkData(skData);
485     return data;
486 }
487 
IsLazyGenerated() const488 bool SkiaImage::IsLazyGenerated() const
489 {
490     return (skiaImage_ == nullptr) ? false : skiaImage_->isLazyGenerated();
491 }
492 
GetROPixels(Bitmap & bitmap) const493 bool SkiaImage::GetROPixels(Bitmap& bitmap) const
494 {
495     if (skiaImage_ == nullptr) {
496         LOGD("SkiaImage::GetROPixels, skiaImage_ is null!");
497         return false;
498     }
499     auto context = as_IB(skiaImage_.get())->directContext();
500     if (!as_IB(skiaImage_.get())->getROPixels(context, &bitmap.GetImpl<SkiaBitmap>()->GetSkBitmap())) {
501         LOGD("skiaImge getROPixels failed");
502         return false;
503     }
504     return true;
505 }
506 
MakeRasterImage() const507 std::shared_ptr<Image> SkiaImage::MakeRasterImage() const
508 {
509     if (skiaImage_ == nullptr) {
510         return nullptr;
511     }
512     sk_sp<SkImage> skImage = skiaImage_->makeRasterImage();
513     if (skImage == nullptr) {
514         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
515         return nullptr;
516     }
517     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
518     return std::make_shared<Image>(imageImpl);
519 }
520 
CanPeekPixels() const521 bool SkiaImage::CanPeekPixels() const
522 {
523     SkPixmap pixmap;
524     if (skiaImage_ == nullptr || !skiaImage_->peekPixels(&pixmap)) {
525         return false;
526     }
527     return true;
528 }
529 
IsOpaque() const530 bool SkiaImage::IsOpaque() const
531 {
532     return (skiaImage_ == nullptr) ? false : skiaImage_->isOpaque();
533 }
534 
HintCacheGpuResource() const535 void SkiaImage::HintCacheGpuResource() const
536 {
537     as_IB(skiaImage_.get())->hintCacheGpuResource();
538 }
539 
GetImage() const540 const sk_sp<SkImage> SkiaImage::GetImage() const
541 {
542     return skiaImage_;
543 }
544 
SetSkImage(const sk_sp<SkImage> & skImage)545 void SkiaImage::SetSkImage(const sk_sp<SkImage>& skImage)
546 {
547     PostSkImgToTargetThread();
548     skiaImage_ = skImage;
549 }
550 
551 #ifdef ACE_ENABLE_GPU
GetGrContext() const552 sk_sp<GrDirectContext> SkiaImage::GetGrContext() const
553 {
554     return grContext_;
555 }
556 #endif
557 
Serialize() const558 std::shared_ptr<Data> SkiaImage::Serialize() const
559 {
560     if (skiaImage_ == nullptr) {
561         LOGD("SkiaImage::Serialize, SkImage is nullptr!");
562         return nullptr;
563     }
564 
565     SkBinaryWriteBuffer writer;
566     bool type = skiaImage_->isLazyGenerated();
567     writer.writeBool(type);
568     if (type) {
569         writer.writeImage(skiaImage_.get());
570         size_t length = writer.bytesWritten();
571         std::shared_ptr<Data> data = std::make_shared<Data>();
572         data->BuildUninitialized(length);
573         writer.writeToMemory(data->WritableData());
574         return data;
575     } else {
576         SkBitmap bitmap;
577 
578         auto context = as_IB(skiaImage_.get())->directContext();
579         if (!as_IB(skiaImage_.get())->getROPixels(context, &bitmap)) {
580             LOGD("SkiaImage::SerializeNoLazyImage SkImage getROPixels failed");
581             return nullptr;
582         }
583         SkPixmap pixmap;
584         if (!bitmap.peekPixels(&pixmap)) {
585             LOGD("SkiaImage::SerializeNoLazyImage SkImage peekPixels failed");
586             return nullptr;
587         }
588         size_t rb = pixmap.rowBytes();
589         int32_t width = pixmap.width();
590         int32_t height = pixmap.height();
591         const void* addr = pixmap.addr();
592         size_t size = pixmap.computeByteSize();
593 
594         writer.writeUInt(size);
595         writer.writeByteArray(addr, size);
596         writer.writeUInt(rb);
597         writer.write32(width);
598         writer.write32(height);
599 
600         writer.writeUInt(pixmap.colorType());
601         writer.writeUInt(pixmap.alphaType());
602 
603         if (pixmap.colorSpace() == nullptr) {
604             writer.writeUInt(0);
605         } else {
606             auto data = pixmap.colorSpace()->serialize();
607             writer.writeUInt(data->size());
608             writer.writeByteArray(data->data(), data->size());
609         }
610         size_t length = writer.bytesWritten();
611         std::shared_ptr<Data> data = std::make_shared<Data>();
612         data->BuildUninitialized(length);
613         writer.writeToMemory(data->WritableData());
614         return data;
615     }
616 }
617 
Deserialize(std::shared_ptr<Data> data)618 bool SkiaImage::Deserialize(std::shared_ptr<Data> data)
619 {
620     if (data == nullptr) {
621         LOGD("SkiaImage::Deserialize, data is invalid!");
622         return false;
623     }
624 
625     SkReadBuffer reader(data->GetData(), data->GetSize());
626     bool type = reader.readBool();
627     if (type) {
628         PostSkImgToTargetThread();
629         skiaImage_ = reader.readImage();
630         return skiaImage_ != nullptr;
631     } else {
632         size_t pixmapSize = reader.readUInt();
633         SkAutoMalloc pixBuffer(pixmapSize);
634         if (!reader.readByteArray(pixBuffer.get(), pixmapSize)) {
635             return false;
636         }
637 
638         size_t rb = reader.readUInt();
639         int32_t width = reader.read32();
640         int32_t height = reader.read32();
641 
642         SkColorType colorType = static_cast<SkColorType>(reader.readUInt());
643         SkAlphaType alphaType = static_cast<SkAlphaType>(reader.readUInt());
644         sk_sp<SkColorSpace> colorSpace;
645 
646         size_t size = reader.readUInt();
647         if (size == 0) {
648             colorSpace = nullptr;
649         } else {
650             SkAutoMalloc colorBuffer(size);
651             if (!reader.readByteArray(colorBuffer.get(), size)) {
652                 return false;
653             }
654             colorSpace = SkColorSpace::Deserialize(colorBuffer.get(), size);
655         }
656 
657         SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
658         auto skData = SkData::MakeWithCopy(const_cast<void*>(pixBuffer.get()), pixmapSize);
659         PostSkImgToTargetThread();
660         skiaImage_ = SkImage::MakeRasterData(imageInfo, skData, rb);
661         return true;
662     }
663 }
664 } // namespace Drawing
665 } // namespace Rosen
666 } // namespace OHOS
667