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