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