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