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