1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "render/rs_image_base.h"
17
18 #include <unistd.h>
19 #include "image_type.h"
20 #include "image/image.h"
21 #include "common/rs_background_thread.h"
22 #ifdef RS_ENABLE_PARALLEL_UPLOAD
23 #include "render/rs_resource_manager.h"
24 #endif
25 #include "common/rs_common_def.h"
26 #include "platform/common/rs_log.h"
27 #include "pipeline/rs_task_dispatcher.h"
28 #include "pipeline/sk_resource_manager.h"
29 #include "property/rs_properties_painter.h"
30 #include "render/rs_image_cache.h"
31 #include "render/rs_pixel_map_util.h"
32 #include "memory/rs_memory_track.h"
33 #include "rs_trace.h"
34 #include "sandbox_utils.h"
35 #include "rs_profiler.h"
36
37 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
38 #include "native_buffer_inner.h"
39 #include "native_window.h"
40 #include "platform/ohos/backend/native_buffer_utils.h"
41 #include "platform/ohos/backend/rs_vulkan_context.h"
42 #endif
43 namespace OHOS::Rosen {
~RSImageBase()44 RSImageBase::~RSImageBase()
45 {
46 if (pixelMap_) {
47 #ifdef ROSEN_OHOS
48 if (renderServiceImage_) {
49 pixelMap_->DecreaseUseCount();
50 }
51 #endif
52 pixelMap_ = nullptr;
53 if (uniqueId_ > 0) {
54 if (renderServiceImage_ || isDrawn_) {
55 RSImageCache::Instance().CollectUniqueId(uniqueId_);
56 } else {
57 RSImageCache::Instance().ReleasePixelMapCache(uniqueId_);
58 }
59 }
60 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
61 if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
62 RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
63 RSTaskDispatcher::GetInstance().PostTask(tid_, [nativeWindowBuffer = nativeWindowBuffer_,
64 cleanupHelper = cleanUpHelper_]() {
65 if (nativeWindowBuffer != nullptr) {
66 DestroyNativeWindowBuffer(nativeWindowBuffer);
67 }
68 if (cleanupHelper != nullptr) {
69 NativeBufferUtils::DeleteVkImage(cleanupHelper);
70 }
71 });
72 }
73 #endif
74 } else { // if pixelMap_ not nullptr, do not release skImage cache
75 if (image_) {
76 image_ = nullptr;
77 if (uniqueId_ > 0) {
78 // if image_ is obtained by RSPixelMapUtil::ExtractSkImage, uniqueId_ here is related to pixelMap,
79 // image_ is not in SkiaImageCache, but still check it here
80 // in this case, the cached image_ will be removed when pixelMap cache is removed
81 RSImageCache::Instance().ReleaseDrawingImageCache(uniqueId_);
82 }
83 }
84 }
85 }
86
87 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
GetColorTypeWithVKFormat(VkFormat vkFormat)88 Drawing::ColorType GetColorTypeWithVKFormat(VkFormat vkFormat)
89 {
90 if (RSSystemProperties::GetGpuApiType() != GpuApiType::VULKAN &&
91 RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
92 return Drawing::COLORTYPE_RGBA_8888;
93 }
94 switch (vkFormat) {
95 case VK_FORMAT_R8G8B8A8_UNORM:
96 return Drawing::COLORTYPE_RGBA_8888;
97 case VK_FORMAT_R16G16B16A16_SFLOAT:
98 return Drawing::COLORTYPE_RGBA_F16;
99 case VK_FORMAT_R5G6B5_UNORM_PACK16:
100 return Drawing::COLORTYPE_RGB_565;
101 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
102 return Drawing::COLORTYPE_RGBA_1010102;
103 default:
104 return Drawing::COLORTYPE_RGBA_8888;
105 }
106 }
107 #endif
108
DrawImage(Drawing::Canvas & canvas,const Drawing::SamplingOptions & samplingOptions,Drawing::SrcRectConstraint constraint)109 void RSImageBase::DrawImage(Drawing::Canvas& canvas, const Drawing::SamplingOptions& samplingOptions,
110 Drawing::SrcRectConstraint constraint)
111 {
112 #ifdef ROSEN_OHOS
113 if (pixelMap_) {
114 pixelMap_->ReMap();
115 }
116 #endif
117 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
118 if (pixelMap_ && pixelMap_->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC) {
119 BindPixelMapToDrawingImage(canvas);
120 }
121 #endif
122 if (!image_) {
123 ConvertPixelMapToDrawingImage();
124 }
125 auto src = RSPropertiesPainter::Rect2DrawingRect(srcRect_);
126 auto dst = RSPropertiesPainter::Rect2DrawingRect(dstRect_);
127 if (image_ == nullptr) {
128 RS_LOGE("RSImageBase::DrawImage image_ is nullptr");
129 return;
130 }
131 canvas.DrawImageRect(*image_, src, dst, samplingOptions, constraint);
132 }
133
SetImage(const std::shared_ptr<Drawing::Image> image)134 void RSImageBase::SetImage(const std::shared_ptr<Drawing::Image> image)
135 {
136 isDrawn_ = false;
137 image_ = image;
138 if (image_) {
139 #ifndef ROSEN_ARKUI_X
140 SKResourceManager::Instance().HoldResource(image);
141 #endif
142 srcRect_.SetAll(0.0, 0.0, image_->GetWidth(), image_->GetHeight());
143 GenUniqueId(image_->GetUniqueID());
144 }
145 }
146
147 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
SetDmaImage(const std::shared_ptr<Drawing::Image> image)148 void RSImageBase::SetDmaImage(const std::shared_ptr<Drawing::Image> image)
149 {
150 isDrawn_ = false;
151 image_ = image;
152 }
153
MarkYUVImage()154 void RSImageBase::MarkYUVImage()
155 {
156 isDrawn_ = false;
157 isYUVImage_ = true;
158 canPurgeShareMemFlag_ = CanPurgeFlag::DISABLED;
159 }
160 #endif
161
SetPixelMap(const std::shared_ptr<Media::PixelMap> & pixelmap)162 void RSImageBase::SetPixelMap(const std::shared_ptr<Media::PixelMap>& pixelmap)
163 {
164 #ifdef ROSEN_OHOS
165 if (pixelMap_) {
166 pixelMap_->DecreaseUseCount();
167 }
168 #endif
169 pixelMap_ = pixelmap;
170 if (pixelMap_) {
171 srcRect_.SetAll(0.0, 0.0, pixelMap_->GetWidth(), pixelMap_->GetHeight());
172 image_ = nullptr;
173 GenUniqueId(pixelMap_->GetUniqueId());
174 }
175 }
176
SetSrcRect(const RectF & srcRect)177 void RSImageBase::SetSrcRect(const RectF& srcRect)
178 {
179 srcRect_ = srcRect;
180 }
181
SetDstRect(const RectF & dstRect)182 void RSImageBase::SetDstRect(const RectF& dstRect)
183 {
184 if (dstRect_ != dstRect) {
185 isDrawn_ = false;
186 }
187 dstRect_ = dstRect;
188 }
189
SetImagePixelAddr(void * addr)190 void RSImageBase::SetImagePixelAddr(void* addr)
191 {
192 imagePixelAddr_ = addr;
193 if (imagePixelAddr_) {
194 canPurgeShareMemFlag_ = CanPurgeFlag::DISABLED;
195 }
196 }
197
UpdateNodeIdToPicture(NodeId nodeId)198 void RSImageBase::UpdateNodeIdToPicture(NodeId nodeId)
199 {
200 if (!nodeId) {
201 return;
202 }
203 if (pixelMap_) {
204 #ifndef ROSEN_ARKUI_X
205 #ifdef ROSEN_OHOS
206 if (RSSystemProperties::GetClosePixelMapFdEnabled()) {
207 MemoryTrack::Instance().UpdatePictureInfo(pixelMap_->GetPixels(), nodeId, ExtractPid(nodeId));
208 } else {
209 MemoryTrack::Instance().UpdatePictureInfo(pixelMap_->GetFd(), nodeId, ExtractPid(nodeId));
210 }
211 #else
212 MemoryTrack::Instance().UpdatePictureInfo(pixelMap_->GetPixels(), nodeId, ExtractPid(nodeId));
213 #endif
214 #endif
215 }
216 if (image_ || imagePixelAddr_) {
217 #ifndef ROSEN_ARKUI_X
218 MemoryTrack::Instance().UpdatePictureInfo(imagePixelAddr_, nodeId, ExtractPid(nodeId));
219 #endif
220 }
221 }
222
Purge()223 void RSImageBase::Purge()
224 {
225 #ifdef ROSEN_OHOS
226 if (canPurgeShareMemFlag_ != CanPurgeFlag::ENABLED ||
227 image_ == nullptr ||
228 uniqueId_ <= 0) {
229 return;
230 }
231 if (!pixelMap_ || pixelMap_->IsUnMap() ||
232 pixelMap_->GetAllocatorType() != Media::AllocatorType::SHARE_MEM_ALLOC) {
233 return;
234 }
235
236 int refCount = RSImageCache::Instance().CheckRefCntAndReleaseImageCache(uniqueId_, pixelMap_, image_);
237 if (refCount > 1) { // skip purge if multi RsImage Holds this PixelMap
238 return;
239 }
240 isDrawn_ = false;
241 image_ = nullptr;
242 #endif
243 }
244
MarkRenderServiceImage()245 void RSImageBase::MarkRenderServiceImage()
246 {
247 renderServiceImage_ = true;
248 #ifdef ROSEN_OHOS
249 if (!pixelMap_) {
250 return;
251 }
252 pixelMap_->IncreaseUseCount();
253 if (canPurgeShareMemFlag_ == CanPurgeFlag::UNINITED &&
254 RSSystemProperties::GetRSImagePurgeEnabled() &&
255 (pixelMap_->GetAllocatorType() == Media::AllocatorType::SHARE_MEM_ALLOC) &&
256 !pixelMap_->IsEditable() &&
257 !pixelMap_->IsAstc() &&
258 !pixelMap_->IsHdr()) {
259 canPurgeShareMemFlag_ = CanPurgeFlag::ENABLED;
260 }
261 #endif
262 }
263
264 #ifdef ROSEN_OHOS
UnmarshallingAndCacheDrawingImage(Parcel & parcel,std::shared_ptr<Drawing::Image> & img,uint64_t uniqueId,void * & imagepixelAddr)265 static bool UnmarshallingAndCacheDrawingImage(
266 Parcel& parcel, std::shared_ptr<Drawing::Image>& img, uint64_t uniqueId, void*& imagepixelAddr)
267 {
268 if (img != nullptr) {
269 // match a cached SkImage
270 if (!RSMarshallingHelper::SkipImage(parcel)) {
271 RS_LOGE("UnmarshalAndCacheSkImage SkipSkImage fail");
272 return false;
273 }
274 } else if (RSMarshallingHelper::Unmarshalling(parcel, img, imagepixelAddr)) {
275 // unmarshalling the SkImage and cache it
276 RSImageCache::Instance().CacheDrawingImage(uniqueId, img);
277 } else {
278 RS_LOGE("UnmarshalAndCacheSkImage fail");
279 return false;
280 }
281 return true;
282 }
283
284
UnmarshallingAndCachePixelMap(Parcel & parcel,std::shared_ptr<Media::PixelMap> & pixelMap,uint64_t uniqueId)285 static bool UnmarshallingAndCachePixelMap(Parcel& parcel, std::shared_ptr<Media::PixelMap>& pixelMap, uint64_t uniqueId)
286 {
287 if (pixelMap != nullptr) {
288 // match a cached pixelMap
289 if (!RSMarshallingHelper::SkipPixelMap(parcel)) {
290 return false;
291 }
292 } else if (RSMarshallingHelper::Unmarshalling(parcel, pixelMap)) {
293 if (pixelMap && !pixelMap->IsEditable()) {
294 // unmarshalling the pixelMap and cache it
295 RSImageCache::Instance().CachePixelMap(uniqueId, pixelMap);
296 }
297 } else {
298 return false;
299 }
300 return true;
301 }
302
UnmarshallingIdAndRect(Parcel & parcel,uint64_t & uniqueId,RectF & srcRect,RectF & dstRect)303 static bool UnmarshallingIdAndRect(Parcel& parcel, uint64_t& uniqueId, RectF& srcRect, RectF& dstRect)
304 {
305 if (!RSMarshallingHelper::Unmarshalling(parcel, uniqueId)) {
306 RS_LOGE("RSImage::Unmarshalling uniqueId fail");
307 return false;
308 }
309 RS_PROFILER_PATCH_NODE_ID(parcel, uniqueId);
310 if (!RSMarshallingHelper::Unmarshalling(parcel, srcRect)) {
311 RS_LOGE("RSImage::Unmarshalling srcRect fail");
312 return false;
313 }
314 if (!RSMarshallingHelper::Unmarshalling(parcel, dstRect)) {
315 RS_LOGE("RSImage::Unmarshalling dstRect fail");
316 return false;
317 }
318 return true;
319 }
320
UnmarshallingDrawingImageAndPixelMap(Parcel & parcel,uint64_t uniqueId,bool & useSkImage,std::shared_ptr<Drawing::Image> & img,std::shared_ptr<Media::PixelMap> & pixelMap,void * & imagepixelAddr)321 bool RSImageBase::UnmarshallingDrawingImageAndPixelMap(Parcel& parcel, uint64_t uniqueId, bool& useSkImage,
322 std::shared_ptr<Drawing::Image>& img, std::shared_ptr<Media::PixelMap>& pixelMap, void*& imagepixelAddr)
323 {
324 if (!RSMarshallingHelper::Unmarshalling(parcel, useSkImage)) {
325 return false;
326 }
327 if (useSkImage) {
328 img = RSImageCache::Instance().GetDrawingImageCache(uniqueId);
329 RS_TRACE_NAME_FMT("RSImageBase::Unmarshalling Image uniqueId:%lu, size:[%d %d], cached:%d",
330 uniqueId, img ? img->GetWidth() : 0, img ? img->GetHeight() : 0, img != nullptr);
331 if (!UnmarshallingAndCacheDrawingImage(parcel, img, uniqueId, imagepixelAddr)) {
332 RS_LOGE("RSImageBase::Unmarshalling UnmarshalAndCacheSkImage fail");
333 return false;
334 }
335 RSMarshallingHelper::SkipPixelMap(parcel);
336 } else {
337 if (!RSMarshallingHelper::SkipImage(parcel)) {
338 return false;
339 }
340 pixelMap = RSImageCache::Instance().GetPixelMapCache(uniqueId);
341 RS_TRACE_NAME_FMT("RSImageBase::Unmarshalling pixelMap uniqueId:%lu, size:[%d %d], cached:%d",
342 uniqueId, pixelMap ? pixelMap->GetWidth() : 0, pixelMap ? pixelMap->GetHeight() : 0, pixelMap != nullptr);
343 if (!UnmarshallingAndCachePixelMap(parcel, pixelMap, uniqueId)) {
344 RS_LOGE("RSImageBase::Unmarshalling UnmarshalAndCachePixelMap fail");
345 return false;
346 }
347 }
348 return true;
349 }
350
IncreaseCacheRefCount(uint64_t uniqueId,bool useSkImage,std::shared_ptr<Media::PixelMap> pixelMap)351 void RSImageBase::IncreaseCacheRefCount(uint64_t uniqueId, bool useSkImage, std::shared_ptr<Media::PixelMap>
352 pixelMap)
353 {
354 if (useSkImage) {
355 RSImageCache::Instance().IncreaseDrawingImageCacheRefCount(uniqueId);
356 } else if (pixelMap && !pixelMap->IsEditable()) {
357 RSImageCache::Instance().IncreasePixelMapCacheRefCount(uniqueId);
358 }
359 }
360
Marshalling(Parcel & parcel) const361 bool RSImageBase::Marshalling(Parcel& parcel) const
362 {
363 std::lock_guard<std::mutex> lock(mutex_);
364 bool success = RSMarshallingHelper::Marshalling(parcel, uniqueId_) &&
365 RSMarshallingHelper::Marshalling(parcel, srcRect_) &&
366 RSMarshallingHelper::Marshalling(parcel, dstRect_) &&
367 parcel.WriteBool(pixelMap_ == nullptr) &&
368 RSMarshallingHelper::Marshalling(parcel, image_) &&
369 RSMarshallingHelper::Marshalling(parcel, pixelMap_);
370 return success;
371 }
372
Unmarshalling(Parcel & parcel)373 RSImageBase* RSImageBase::Unmarshalling(Parcel& parcel)
374 {
375 uint64_t uniqueId;
376 RectF srcRect;
377 RectF dstRect;
378 if (!UnmarshallingIdAndRect(parcel, uniqueId, srcRect, dstRect)) {
379 RS_LOGE("RSImage::Unmarshalling UnmarshalIdAndSize fail");
380 return nullptr;
381 }
382
383 bool useSkImage;
384 std::shared_ptr<Drawing::Image> img = std::make_shared<Drawing::Image>();
385 std::shared_ptr<Media::PixelMap> pixelMap;
386 void* imagepixelAddr = nullptr;
387 if (!UnmarshallingDrawingImageAndPixelMap(parcel, uniqueId, useSkImage, img, pixelMap, imagepixelAddr)) {
388 return nullptr;
389 }
390
391 RSImageBase* rsImage = new RSImageBase();
392 rsImage->SetImage(img);
393 rsImage->SetImagePixelAddr(imagepixelAddr);
394 rsImage->SetPixelMap(pixelMap);
395 rsImage->SetSrcRect(srcRect);
396 rsImage->SetDstRect(dstRect);
397 rsImage->uniqueId_ = uniqueId;
398 rsImage->MarkRenderServiceImage();
399 IncreaseCacheRefCount(uniqueId, useSkImage, pixelMap);
400 return rsImage;
401 }
402 #endif
403
ConvertPixelMapToDrawingImage(bool paraUpload)404 void RSImageBase::ConvertPixelMapToDrawingImage(bool paraUpload)
405 {
406 #if defined(ROSEN_OHOS)
407 // paraUpload only enable in render_service or UnmarshalThread
408 pid_t tid = paraUpload ? getpid() : gettid();
409 #endif
410 if (!image_ && pixelMap_ && !pixelMap_->IsAstc() && !isYUVImage_) {
411 if (!pixelMap_->IsEditable()) {
412 #if defined(ROSEN_OHOS)
413 image_ = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(uniqueId_, tid);
414 #else
415 image_ = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(uniqueId_);
416 #endif
417 }
418 if (!image_) {
419 image_ = RSPixelMapUtil::ExtractDrawingImage(pixelMap_);
420 if (!pixelMap_->IsEditable()) {
421 #if defined(ROSEN_OHOS)
422 RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(uniqueId_, image_, tid);
423 #else
424 RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(uniqueId_, image_);
425 #endif
426 }
427 #ifdef RS_ENABLE_PARALLEL_UPLOAD
428 RSResourceManager::Instance().UploadTexture(paraUpload && renderServiceImage_, image_,
429 pixelMap_, uniqueId_);
430 #endif
431 }
432 }
433 }
434
GetUniqueId() const435 uint64_t RSImageBase::GetUniqueId() const
436 {
437 return uniqueId_;
438 }
439
GenUniqueId(uint32_t id)440 void RSImageBase::GenUniqueId(uint32_t id)
441 {
442 static uint64_t shiftedPid = static_cast<uint64_t>(GetRealPid()) << 32; // 32 for 64-bit unsignd number shift
443 uniqueId_ = shiftedPid | id;
444 }
445
446 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
ProcessYUVImage(std::shared_ptr<Drawing::GPUContext> gpuContext)447 void RSImageBase::ProcessYUVImage(std::shared_ptr<Drawing::GPUContext> gpuContext)
448 {
449 if (!gpuContext) {
450 return;
451 }
452 auto cache = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(uniqueId_, gettid());
453 std::lock_guard<std::mutex> lock(mutex_);
454 if (cache) {
455 image_ = cache;
456 return;
457 }
458 RS_TRACE_NAME("make yuv img");
459 auto image = RSPixelMapUtil::ConvertYUVPixelMapToDrawingImage(gpuContext, pixelMap_);
460 if (image) {
461 image_ = image;
462 SKResourceManager::Instance().HoldResource(image);
463 RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(uniqueId_, image, gettid());
464 } else {
465 RS_LOGE("make yuv image %{public}d (%{public}d, %{public}d) failed",
466 (int)uniqueId_, (int)srcRect_.width_, (int)srcRect_.height_);
467 }
468 }
469 #endif
470
GetPixelMap() const471 std::shared_ptr<Media::PixelMap> RSImageBase::GetPixelMap() const
472 {
473 return pixelMap_;
474 }
475
476 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
MakeFromTextureForVK(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer)477 std::shared_ptr<Drawing::Image> RSImageBase::MakeFromTextureForVK(
478 Drawing::Canvas& canvas, SurfaceBuffer* surfaceBuffer)
479 {
480 if (RSSystemProperties::GetGpuApiType() != GpuApiType::VULKAN &&
481 RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
482 return nullptr;
483 }
484 if (!surfaceBuffer || !canvas.GetGPUContext()) {
485 RS_LOGE("RSImageBase MakeFromTextureForVK surfaceBuffer is nullptr");
486 return nullptr;
487 }
488 if (nativeWindowBuffer_ == nullptr) {
489 sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
490 nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
491 if (!nativeWindowBuffer_) {
492 RS_LOGE("RSImageBase MakeFromTextureForVK create native window buffer fail");
493 return nullptr;
494 }
495 }
496 if (!backendTexture_.IsValid()) {
497 backendTexture_ = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(
498 nativeWindowBuffer_, surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), false);
499 if (backendTexture_.IsValid()) {
500 auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
501 cleanUpHelper_ = new NativeBufferUtils::VulkanCleanupHelper(
502 RsVulkanContext::GetSingleton(), vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
503 } else {
504 return nullptr;
505 }
506 tid_ = gettid();
507 }
508
509 std::shared_ptr<Drawing::Image> dmaImage = std::make_shared<Drawing::Image>();
510 auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
511 Drawing::ColorType colorType = GetColorTypeWithVKFormat(vkTextureInfo->format);
512 Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
513 if (!dmaImage->BuildFromTexture(*canvas.GetGPUContext(), backendTexture_.GetTextureInfo(),
514 Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr, NativeBufferUtils::DeleteVkImage,
515 cleanUpHelper_->Ref())) {
516 RS_LOGE("RSImageBase MakeFromTextureForVK build image failed");
517 return nullptr;
518 }
519 return dmaImage;
520 }
521
BindPixelMapToDrawingImage(Drawing::Canvas & canvas)522 void RSImageBase::BindPixelMapToDrawingImage(Drawing::Canvas& canvas)
523 {
524 if (pixelMap_ && !pixelMap_->IsAstc()) {
525 if (!pixelMap_->IsEditable()) {
526 image_ = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(uniqueId_, gettid());
527 }
528 if (!image_) {
529 image_ = MakeFromTextureForVK(canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap_->GetFd()));
530 if (!pixelMap_->IsEditable() && image_) {
531 SKResourceManager::Instance().HoldResource(image_);
532 RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(uniqueId_, image_, gettid());
533 }
534 }
535 }
536 }
537 #endif
538 }
539