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