• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "pipeline/rs_draw_cmd.h"
17 #include "pipeline/rs_recording_canvas.h"
18 #include "platform/common/rs_log.h"
19 #include "render/rs_pixel_map_util.h"
20 #include "render/rs_image_cache.h"
21 #include "recording/cmd_list_helper.h"
22 #include "recording/draw_cmd_list.h"
23 #include "rs_trace.h"
24 #include "utils/system_properties.h"
25 #include "pipeline/rs_task_dispatcher.h"
26 #include "platform/common/rs_system_properties.h"
27 #include "pipeline/sk_resource_manager.h"
28 #ifdef ROSEN_OHOS
29 #include "common/rs_common_tools.h"
30 #include "native_buffer_inner.h"
31 #include "native_window.h"
32 #endif
33 #ifdef RS_ENABLE_VK
34 #include "include/gpu/GrBackendSemaphore.h"
35 #include "platform/ohos/backend/native_buffer_utils.h"
36 #include "platform/ohos/backend/rs_vulkan_context.h"
37 #endif
38 
39 #include "include/gpu/GrDirectContext.h"
40 
41 namespace OHOS {
42 namespace Rosen {
43 constexpr int32_t CORNER_SIZE = 4;
44 #ifdef ROSEN_OHOS
45 constexpr uint32_t FENCE_WAIT_TIME = 3000; // ms
46 #endif
47 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
48 constexpr uint8_t ASTC_HEADER_SIZE = 16;
49 #endif
50 
51 #ifdef RS_ENABLE_VK
GetColorTypeFromVKFormat(VkFormat vkFormat)52 Drawing::ColorType GetColorTypeFromVKFormat(VkFormat vkFormat)
53 {
54     if (!RSSystemProperties::IsUseVukan()) {
55         return Drawing::COLORTYPE_RGBA_8888;
56     }
57     switch (vkFormat) {
58         case VK_FORMAT_R8G8B8A8_UNORM:
59             return Drawing::COLORTYPE_RGBA_8888;
60         case VK_FORMAT_R16G16B16A16_SFLOAT:
61             return Drawing::COLORTYPE_RGBA_F16;
62         case VK_FORMAT_R5G6B5_UNORM_PACK16:
63             return Drawing::COLORTYPE_RGB_565;
64         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
65             return Drawing::COLORTYPE_RGBA_1010102;
66         default:
67             return Drawing::COLORTYPE_RGBA_8888;
68     }
69 }
70 #endif
71 
RSExtendImageObject(const std::shared_ptr<Drawing::Image> & image,const std::shared_ptr<Drawing::Data> & data,const Drawing::AdaptiveImageInfo & imageInfo)72 RSExtendImageObject::RSExtendImageObject(const std::shared_ptr<Drawing::Image>& image,
73     const std::shared_ptr<Drawing::Data>& data, const Drawing::AdaptiveImageInfo& imageInfo)
74 {
75     rsImage_ = std::make_shared<RSImage>();
76     rsImage_->SetImage(image);
77     rsImage_->SetCompressData(data, imageInfo.uniqueId, imageInfo.width, imageInfo.height);
78     rsImage_->SetImageFit(imageInfo.fitNum);
79     rsImage_->SetImageRepeat(imageInfo.repeatNum);
80     rsImage_->SetImageRotateDegree(imageInfo.rotateDegree);
81     std::vector<Drawing::Point> radiusValue(imageInfo.radius, imageInfo.radius + CORNER_SIZE);
82     rsImage_->SetRadius(radiusValue);
83     rsImage_->SetScale(imageInfo.scale);
84     rsImage_->SetFitMatrix(imageInfo.fitMatrix);
85     imageInfo_ = imageInfo;
86 }
87 
RSExtendImageObject(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::AdaptiveImageInfo & imageInfo)88 RSExtendImageObject::RSExtendImageObject(const std::shared_ptr<Media::PixelMap>& pixelMap,
89     const Drawing::AdaptiveImageInfo& imageInfo)
90 {
91     if (pixelMap) {
92 #ifdef ROSEN_OHOS
93         if (RSSystemProperties::GetDumpUIPixelmapEnabled()) {
94             CommonTools::SavePixelmapToFile(pixelMap, "/data/storage/el1/base/imageObject_");
95         }
96 #endif
97         rsImage_ = std::make_shared<RSImage>();
98         rsImage_->SetPixelMap(pixelMap);
99         rsImage_->SetImageFit(imageInfo.fitNum);
100         rsImage_->SetImageRotateDegree(imageInfo.rotateDegree);
101         rsImage_->SetImageRepeat(imageInfo.repeatNum);
102         std::vector<Drawing::Point> radiusValue(imageInfo.radius, imageInfo.radius + CORNER_SIZE);
103         rsImage_->SetRadius(radiusValue);
104         rsImage_->SetScale(imageInfo.scale);
105         rsImage_->SetDynamicRangeMode(imageInfo.dynamicRangeMode);
106         RectF frameRect(imageInfo.frameRect.GetLeft(),
107                         imageInfo.frameRect.GetTop(),
108                         imageInfo.frameRect.GetRight(),
109                         imageInfo.frameRect.GetBottom());
110         rsImage_->SetFrameRect(frameRect);
111         rsImage_->SetFitMatrix(imageInfo.fitMatrix);
112     }
113 }
114 
SetNodeId(NodeId id)115 void RSExtendImageObject::SetNodeId(NodeId id)
116 {
117     if (rsImage_) {
118         rsImage_->UpdateNodeIdToPicture(id);
119     }
120 }
121 
SetPaint(Drawing::Paint paint)122 void RSExtendImageObject::SetPaint(Drawing::Paint paint)
123 {
124     if (rsImage_) {
125         rsImage_->SetPaint(paint);
126     }
127 }
128 
Purge()129 void RSExtendImageObject::Purge()
130 {
131     if (rsImage_) {
132         rsImage_->Purge();
133     }
134 }
135 
Playback(Drawing::Canvas & canvas,const Drawing::Rect & rect,const Drawing::SamplingOptions & sampling,bool isBackground)136 void RSExtendImageObject::Playback(Drawing::Canvas& canvas, const Drawing::Rect& rect,
137     const Drawing::SamplingOptions& sampling, bool isBackground)
138 {
139 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
140     if (!rsImage_) {
141         return;
142     }
143     std::shared_ptr<Media::PixelMap> pixelmap = rsImage_->GetPixelMap();
144     if (pixelmap && pixelmap->IsAstc()) {
145         if (auto recordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas())) {
146             Drawing::AdaptiveImageInfo imageInfo = rsImage_->GetAdaptiveImageInfoWithCustomizedFrameRect(rect);
147             recordingCanvas->DrawPixelMapWithParm(pixelmap, imageInfo, sampling);
148             return;
149         }
150     }
151     if (canvas.GetRecordingCanvas()) {
152         image_ = RSPixelMapUtil::ExtractDrawingImage(pixelmap);
153         if (image_) {
154             SKResourceManager::Instance().HoldResource(image_);
155             rsImage_->SetDmaImage(image_);
156         }
157         rsImage_->CanvasDrawImage(canvas, rect, sampling, isBackground);
158         return;
159     }
160     PreProcessPixelMap(canvas, pixelmap, sampling);
161 #endif
162     rsImage_->CanvasDrawImage(canvas, rect, sampling, isBackground);
163 }
164 
Marshalling(Parcel & parcel) const165 bool RSExtendImageObject::Marshalling(Parcel &parcel) const
166 {
167     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
168     return ret;
169 }
170 
Unmarshalling(Parcel & parcel)171 RSExtendImageObject *RSExtendImageObject::Unmarshalling(Parcel &parcel)
172 {
173     auto object = new RSExtendImageObject();
174     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
175     if (!ret) {
176         delete object;
177         return nullptr;
178     }
179     return object;
180 }
181 
182 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
PreProcessPixelMap(Drawing::Canvas & canvas,const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::SamplingOptions & sampling)183 void RSExtendImageObject::PreProcessPixelMap(Drawing::Canvas& canvas, const std::shared_ptr<Media::PixelMap>& pixelMap,
184     const Drawing::SamplingOptions& sampling)
185 {
186     if (!pixelMap || !rsImage_) {
187         return;
188     }
189     auto colorSpace = RSPixelMapUtil::GetPixelmapColorSpace(pixelMap);
190 #ifdef USE_VIDEO_PROCESSING_ENGINE
191     if (pixelMap->IsHdr()) {
192         colorSpace = Drawing::ColorSpace::CreateSRGB();
193     }
194 #endif
195     if (!pixelMap->IsAstc() && RSPixelMapUtil::IsSupportZeroCopy(pixelMap, sampling)) {
196 #if defined(RS_ENABLE_GL)
197         if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL &&
198             GetDrawingImageFromSurfaceBuffer(canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()))) {
199             rsImage_->SetDmaImage(image_);
200         }
201 #endif
202 #if defined(RS_ENABLE_VK)
203         if (RSSystemProperties::IsUseVukan() &&
204             GetRsImageCache(canvas, pixelMap, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()), colorSpace)) {
205             rsImage_->SetDmaImage(image_);
206         }
207 #endif
208         return;
209     }
210     if (pixelMap->IsAstc()) {
211         std::shared_ptr<Drawing::Data> fileData = std::make_shared<Drawing::Data>();
212         // After RS is switched to Vulkan, the judgment of GpuApiType can be deleted.
213         if (pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC &&
214             RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN) {
215             if (!nativeWindowBuffer_) {
216                 sptr<SurfaceBuffer> sfBuffer(reinterpret_cast<SurfaceBuffer *>(pixelMap->GetFd()));
217                 nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
218             }
219             OH_NativeBuffer* nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(nativeWindowBuffer_);
220             if (nativeBuffer == nullptr || !fileData->BuildFromOHNativeBuffer(nativeBuffer, pixelMap->GetCapacity())) {
221                 LOGE("PreProcessPixelMap data BuildFromOHNativeBuffer fail");
222                 return;
223             }
224         } else {
225             const void* data = pixelMap->GetPixels();
226             if (pixelMap->GetCapacity() > ASTC_HEADER_SIZE &&
227                 (data == nullptr || !fileData->BuildWithoutCopy((void*)((char*) data + ASTC_HEADER_SIZE),
228                 pixelMap->GetCapacity() - ASTC_HEADER_SIZE))) {
229                 LOGE("PreProcessPixelMap data BuildWithoutCopy fail");
230                 return;
231             }
232         }
233         rsImage_->SetCompressData(fileData);
234         return;
235     }
236     if (RSPixelMapUtil::IsYUVFormat(pixelMap)) {
237         rsImage_->MarkYUVImage();
238     }
239 }
240 #endif
241 
242 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
GetRsImageCache(Drawing::Canvas & canvas,const std::shared_ptr<Media::PixelMap> & pixelMap,SurfaceBuffer * surfaceBuffer,const std::shared_ptr<Drawing::ColorSpace> & colorSpace)243 bool RSExtendImageObject::GetRsImageCache(Drawing::Canvas& canvas, const std::shared_ptr<Media::PixelMap>& pixelMap,
244     SurfaceBuffer *surfaceBuffer, const std::shared_ptr<Drawing::ColorSpace>& colorSpace)
245 {
246     if (pixelMap == nullptr) {
247         return false;
248     }
249     std::shared_ptr<Drawing::Image> imageCache = nullptr;
250     if (!pixelMap->IsEditable()) {
251         imageCache = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(
252             rsImage_->GetUniqueId(), gettid());
253     }
254     if (imageCache) {
255         this->image_ = imageCache;
256     } else {
257         bool ret = MakeFromTextureForVK(
258             canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()), colorSpace);
259         if (ret && image_ && !pixelMap->IsEditable()) {
260             SKResourceManager::Instance().HoldResource(image_);
261             RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(
262                 rsImage_->GetUniqueId(), image_, gettid());
263         }
264         return ret;
265     }
266     return true;
267 }
268 #endif
269 
270 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_GL)
GetDrawingImageFromSurfaceBuffer(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer)271 bool RSExtendImageObject::GetDrawingImageFromSurfaceBuffer(Drawing::Canvas& canvas, SurfaceBuffer* surfaceBuffer)
272 {
273     if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
274         return false;
275     }
276     if (surfaceBuffer == nullptr) {
277         RS_LOGE("GetDrawingImageFromSurfaceBuffer surfaceBuffer is nullptr");
278         return false;
279     }
280     if (nativeWindowBuffer_ == nullptr) {
281         sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
282         nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
283         if (!nativeWindowBuffer_) {
284             RS_LOGE("GetDrawingImageFromSurfaceBuffer create native window buffer fail");
285             return false;
286         }
287     }
288     EGLint attrs[] = { EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE };
289 
290     auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
291     if (eglImage_ == EGL_NO_IMAGE_KHR) {
292         eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs);
293         if (eglImage_ == EGL_NO_IMAGE_KHR) {
294             RS_LOGE("%{public}s create egl image fail %{public}d", __func__, eglGetError());
295             return false;
296         }
297         tid_ = gettid();
298     }
299 
300     // Create texture object
301     if (texId_ == 0U) {
302         glGenTextures(1, &texId_);
303         glBindTexture(GL_TEXTURE_2D, texId_);
304         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
305         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
306         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
307         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
308         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(eglImage_));
309     }
310 
311     Drawing::TextureInfo externalTextureInfo;
312     externalTextureInfo.SetWidth(surfaceBuffer->GetWidth());
313     externalTextureInfo.SetHeight(surfaceBuffer->GetHeight());
314     externalTextureInfo.SetIsMipMapped(false);
315     externalTextureInfo.SetTarget(GL_TEXTURE_2D);
316     externalTextureInfo.SetID(texId_);
317     externalTextureInfo.SetFormat(GL_RGBA8_OES);
318 
319     Drawing::BitmapFormat bitmapFormat = {
320         Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
321     if (!canvas.GetGPUContext()) {
322         RS_LOGE("GetDrawingImageFromSurfaceBuffer gpu context is nullptr");
323         return false;
324     }
325 
326     image_ = std::make_shared<Drawing::Image>();
327 #ifndef ROSEN_EMULATOR
328     auto surfaceOrigin = Drawing::TextureOrigin::TOP_LEFT;
329 #else
330     auto surfaceOrigin = Drawing::TextureOrigin::BOTTOM_LEFT;
331 #endif
332     if (!image_->BuildFromTexture(*(canvas.GetGPUContext()), externalTextureInfo,
333         surfaceOrigin, bitmapFormat,
334         std::make_shared<Drawing::ColorSpace>(Drawing::ColorSpace::ColorSpaceType::SRGB))) {
335         RS_LOGE("BuildFromTexture failed");
336         return false;
337     }
338     return true;
339 }
340 #endif
341 
342 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
MakeFromTextureForVK(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer,const std::shared_ptr<Drawing::ColorSpace> & colorSpace)343 bool RSExtendImageObject::MakeFromTextureForVK(Drawing::Canvas& canvas, SurfaceBuffer *surfaceBuffer,
344     const std::shared_ptr<Drawing::ColorSpace>& colorSpace)
345 {
346     if (!RSSystemProperties::IsUseVukan()) {
347         return false;
348     }
349     if (surfaceBuffer == nullptr || surfaceBuffer->GetBufferHandle() == nullptr) {
350         RS_LOGE("MakeFromTextureForVK surfaceBuffer is nullptr or buffer handle is nullptr");
351         return false;
352     }
353     if (nativeWindowBuffer_ == nullptr) {
354         sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
355         nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
356         if (!nativeWindowBuffer_) {
357             RS_LOGE("MakeFromTextureForVK create native window buffer fail");
358             return false;
359         }
360     }
361     if (!backendTexture_.IsValid()) {
362         backendTexture_ = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(nativeWindowBuffer_,
363             surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), false);
364         if (backendTexture_.IsValid()) {
365             auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
366             if (!vkTextureInfo) {
367                 return false;
368             }
369             cleanUpHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
370                 vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
371         } else {
372             return false;
373         }
374         tid_ = gettid();
375     }
376 
377     auto context = canvas.GetGPUContext();
378     if (!context) {
379         RS_LOGE("MakeFromTextureForVK gpu context is nullptr");
380         return false;
381     }
382     image_ = std::make_shared<Drawing::Image>();
383     auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
384     if (!vkTextureInfo || !cleanUpHelper_) {
385         return false;
386     }
387     Drawing::ColorType colorType = GetColorTypeFromVKFormat(vkTextureInfo->format);
388     Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
389     if (!image_->BuildFromTexture(*context, backendTexture_.GetTextureInfo(),
390         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, colorSpace,
391         NativeBufferUtils::DeleteVkImage,
392         cleanUpHelper_->Ref())) {
393         RS_LOGE("MakeFromTextureForVK build image failed");
394         return false;
395     }
396     return true;
397 }
398 #endif
399 
~RSExtendImageObject()400 RSExtendImageObject::~RSExtendImageObject()
401 {
402 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_GL)
403     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
404         RSTaskDispatcher::GetInstance().PostTask(tid_, [texId = texId_,
405                                                         nativeWindowBuffer = nativeWindowBuffer_,
406                                                         eglImage = eglImage_]() {
407             if (texId != 0U) {
408                 glBindTexture(GL_TEXTURE_2D, 0);
409                 glDeleteTextures(1, &texId);
410             }
411             if (nativeWindowBuffer != nullptr) {
412                 DestroyNativeWindowBuffer(nativeWindowBuffer);
413             }
414             if (eglImage != EGL_NO_IMAGE_KHR) {
415                 auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
416                 eglDestroyImageKHR(disp, eglImage);
417             }
418         });
419     }
420 #endif
421 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
422     if (RSSystemProperties::IsUseVukan()) {
423         RSTaskDispatcher::GetInstance().PostTask(tid_, [nativeWindowBuffer = nativeWindowBuffer_,
424             cleanupHelper = cleanUpHelper_]() {
425             if (nativeWindowBuffer != nullptr) {
426                 DestroyNativeWindowBuffer(nativeWindowBuffer);
427             }
428             if (cleanupHelper != nullptr) {
429                 NativeBufferUtils::DeleteVkImage(cleanupHelper);
430             }
431         });
432     }
433 #endif
434 }
435 
RSExtendImageBaseObj(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::Rect & src,const Drawing::Rect & dst)436 RSExtendImageBaseObj::RSExtendImageBaseObj(const std::shared_ptr<Media::PixelMap>& pixelMap, const Drawing::Rect& src,
437     const Drawing::Rect& dst)
438 {
439     if (pixelMap) {
440         rsImage_ = std::make_shared<RSImageBase>();
441         rsImage_->SetPixelMap(pixelMap);
442         rsImage_->SetSrcRect(RectF(src.GetLeft(), src.GetTop(), src.GetWidth(), src.GetHeight()));
443         rsImage_->SetDstRect(RectF(dst.GetLeft(), dst.GetTop(), dst.GetWidth(), dst.GetHeight()));
444     }
445 }
446 
Playback(Drawing::Canvas & canvas,const Drawing::Rect & rect,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)447 void RSExtendImageBaseObj::Playback(Drawing::Canvas& canvas, const Drawing::Rect& rect,
448     const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint)
449 {
450     if (rsImage_) {
451         rsImage_->DrawImage(canvas, sampling, constraint);
452     }
453 }
454 
SetNodeId(NodeId id)455 void RSExtendImageBaseObj::SetNodeId(NodeId id)
456 {
457     if (rsImage_) {
458         rsImage_->UpdateNodeIdToPicture(id);
459     }
460 }
461 
Purge()462 void RSExtendImageBaseObj::Purge()
463 {
464     if (rsImage_) {
465         rsImage_->Purge();
466     }
467 }
468 
Marshalling(Parcel & parcel) const469 bool RSExtendImageBaseObj::Marshalling(Parcel &parcel) const
470 {
471     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
472     return ret;
473 }
474 
Unmarshalling(Parcel & parcel)475 RSExtendImageBaseObj *RSExtendImageBaseObj::Unmarshalling(Parcel &parcel)
476 {
477     auto object = new RSExtendImageBaseObj();
478     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
479     if (!ret) {
480         delete object;
481         return nullptr;
482     }
483     return object;
484 }
485 
Playback(Drawing::Canvas * canvas,const Drawing::Rect * rect)486 void RSExtendDrawFuncObj::Playback(Drawing::Canvas* canvas, const Drawing::Rect* rect)
487 {
488     if (drawFunc_) {
489         drawFunc_(canvas, rect);
490     }
491 }
492 
Marshalling(Parcel & parcel) const493 bool RSExtendDrawFuncObj::Marshalling(Parcel &parcel) const
494 {
495     return false;
496 }
497 
Unmarshalling(Parcel & parcel)498 RSExtendDrawFuncObj *RSExtendDrawFuncObj::Unmarshalling(Parcel &parcel)
499 {
500     return nullptr;
501 }
502 
503 namespace Drawing {
504 /* DrawImageWithParmOpItem */
505 UNMARSHALLING_REGISTER(DrawImageWithParm, DrawOpItem::IMAGE_WITH_PARM_OPITEM,
506     DrawImageWithParmOpItem::Unmarshalling, sizeof(DrawImageWithParmOpItem::ConstructorHandle));
507 
DrawImageWithParmOpItem(const DrawCmdList & cmdList,DrawImageWithParmOpItem::ConstructorHandle * handle)508 DrawImageWithParmOpItem::DrawImageWithParmOpItem(
509     const DrawCmdList& cmdList, DrawImageWithParmOpItem::ConstructorHandle* handle)
510     : DrawWithPaintOpItem(cmdList, handle->paintHandle, IMAGE_WITH_PARM_OPITEM), sampling_(handle->sampling)
511 {
512     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
513 }
514 
DrawImageWithParmOpItem(const std::shared_ptr<Image> & image,const std::shared_ptr<Data> & data,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)515 DrawImageWithParmOpItem::DrawImageWithParmOpItem(const std::shared_ptr<Image>& image, const std::shared_ptr<Data>& data,
516     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
517     : DrawWithPaintOpItem(paint, IMAGE_WITH_PARM_OPITEM), sampling_(sampling)
518 {
519     objectHandle_ = std::make_shared<RSExtendImageObject>(image, data, rsImageInfo);
520 }
521 
Unmarshalling(const DrawCmdList & cmdList,void * handle)522 std::shared_ptr<DrawOpItem> DrawImageWithParmOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
523 {
524     return std::make_shared<DrawImageWithParmOpItem>(
525         cmdList, static_cast<DrawImageWithParmOpItem::ConstructorHandle*>(handle));
526 }
527 
Marshalling(DrawCmdList & cmdList)528 void DrawImageWithParmOpItem::Marshalling(DrawCmdList& cmdList)
529 {
530     PaintHandle paintHandle;
531     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
532     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
533     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle);
534 }
535 
Playback(Canvas * canvas,const Rect * rect)536 void DrawImageWithParmOpItem::Playback(Canvas* canvas, const Rect* rect)
537 {
538     if (objectHandle_ == nullptr) {
539         LOGE("DrawImageWithParmOpItem objectHandle is nullptr!");
540         return;
541     }
542     canvas->AttachPaint(paint_);
543     objectHandle_->Playback(*canvas, *rect, sampling_, false);
544 }
545 
SetNodeId(NodeId id)546 void DrawImageWithParmOpItem::SetNodeId(NodeId id)
547 {
548     if (objectHandle_ == nullptr) {
549         LOGE("DrawImageWithParmOpItem objectHandle is nullptr!");
550         return;
551     }
552     objectHandle_->SetNodeId(id);
553 }
554 
555 /* DrawPixelMapWithParmOpItem */
556 UNMARSHALLING_REGISTER(DrawPixelMapWithParm, DrawOpItem::PIXELMAP_WITH_PARM_OPITEM,
557     DrawPixelMapWithParmOpItem::Unmarshalling, sizeof(DrawPixelMapWithParmOpItem::ConstructorHandle));
558 
DrawPixelMapWithParmOpItem(const DrawCmdList & cmdList,DrawPixelMapWithParmOpItem::ConstructorHandle * handle)559 DrawPixelMapWithParmOpItem::DrawPixelMapWithParmOpItem(
560     const DrawCmdList& cmdList, DrawPixelMapWithParmOpItem::ConstructorHandle* handle)
561     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_WITH_PARM_OPITEM), sampling_(handle->sampling)
562 {
563     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
564 }
565 
DrawPixelMapWithParmOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)566 DrawPixelMapWithParmOpItem::DrawPixelMapWithParmOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap,
567     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
568     : DrawWithPaintOpItem(paint, PIXELMAP_WITH_PARM_OPITEM), sampling_(sampling)
569 {
570     objectHandle_ = std::make_shared<RSExtendImageObject>(pixelMap, rsImageInfo);
571 }
572 
Unmarshalling(const DrawCmdList & cmdList,void * handle)573 std::shared_ptr<DrawOpItem> DrawPixelMapWithParmOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
574 {
575     return std::make_shared<DrawPixelMapWithParmOpItem>(
576         cmdList, static_cast<DrawPixelMapWithParmOpItem::ConstructorHandle*>(handle));
577 }
578 
Marshalling(DrawCmdList & cmdList)579 void DrawPixelMapWithParmOpItem::Marshalling(DrawCmdList& cmdList)
580 {
581     PaintHandle paintHandle;
582     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
583     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
584     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle);
585 }
586 
Playback(Canvas * canvas,const Rect * rect)587 void DrawPixelMapWithParmOpItem::Playback(Canvas* canvas, const Rect* rect)
588 {
589     if (objectHandle_ == nullptr) {
590         LOGE("DrawPixelMapWithParmOpItem objectHandle is nullptr!");
591         return;
592     }
593     objectHandle_->SetPaint(paint_);
594     canvas->AttachPaint(paint_);
595     objectHandle_->Playback(*canvas, *rect, sampling_, false);
596 }
597 
SetNodeId(NodeId id)598 void DrawPixelMapWithParmOpItem::SetNodeId(NodeId id)
599 {
600     if (objectHandle_ == nullptr) {
601         LOGE("DrawPixelMapWithParmOpItem objectHandle is nullptr!");
602         return;
603     }
604     objectHandle_->SetNodeId(id);
605 }
606 
607 /* DrawPixelMapRectOpItem */
608 UNMARSHALLING_REGISTER(DrawPixelMapRect, DrawOpItem::PIXELMAP_RECT_OPITEM,
609     DrawPixelMapRectOpItem::Unmarshalling, sizeof(DrawPixelMapRectOpItem::ConstructorHandle));
610 
DrawPixelMapRectOpItem(const DrawCmdList & cmdList,DrawPixelMapRectOpItem::ConstructorHandle * handle)611 DrawPixelMapRectOpItem::DrawPixelMapRectOpItem(
612     const DrawCmdList& cmdList, DrawPixelMapRectOpItem::ConstructorHandle* handle)
613     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_RECT_OPITEM), sampling_(handle->sampling),
614       constraint_(handle->constraint)
615 {
616     objectHandle_ = CmdListHelper::GetImageBaseObjFromCmdList(cmdList, handle->objectHandle);
617 }
618 
DrawPixelMapRectOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint,const Paint & paint)619 DrawPixelMapRectOpItem::DrawPixelMapRectOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap, const Rect& src,
620     const Rect& dst, const SamplingOptions& sampling, SrcRectConstraint constraint, const Paint& paint)
621     : DrawWithPaintOpItem(paint, PIXELMAP_RECT_OPITEM), sampling_(sampling), constraint_(constraint)
622 {
623     objectHandle_ = std::make_shared<RSExtendImageBaseObj>(pixelMap, src, dst);
624 }
625 
Unmarshalling(const DrawCmdList & cmdList,void * handle)626 std::shared_ptr<DrawOpItem> DrawPixelMapRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
627 {
628     return std::make_shared<DrawPixelMapRectOpItem>(
629         cmdList, static_cast<DrawPixelMapRectOpItem::ConstructorHandle*>(handle));
630 }
631 
Marshalling(DrawCmdList & cmdList)632 void DrawPixelMapRectOpItem::Marshalling(DrawCmdList& cmdList)
633 {
634     PaintHandle paintHandle;
635     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
636     auto objectHandle = CmdListHelper::AddImageBaseObjToCmdList(cmdList, objectHandle_);
637     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, constraint_, paintHandle);
638 }
639 
Playback(Canvas * canvas,const Rect * rect)640 void DrawPixelMapRectOpItem::Playback(Canvas* canvas, const Rect* rect)
641 {
642     if (objectHandle_ == nullptr) {
643         LOGE("DrawPixelMapRectOpItem objectHandle is nullptr!");
644         return;
645     }
646     canvas->AttachPaint(paint_);
647     objectHandle_->Playback(*canvas, *rect, sampling_, constraint_);
648 }
649 
SetNodeId(NodeId id)650 void DrawPixelMapRectOpItem::SetNodeId(NodeId id)
651 {
652     if (objectHandle_ == nullptr) {
653         LOGE("DrawPixelMapRectOpItem objectHandle is nullptr!");
654         return;
655     }
656     objectHandle_->SetNodeId(id);
657 }
658 
659 /* DrawFuncOpItem */
660 UNMARSHALLING_REGISTER(DrawFunc, DrawOpItem::DRAW_FUNC_OPITEM,
661     DrawFuncOpItem::Unmarshalling, sizeof(DrawFuncOpItem::ConstructorHandle));
662 
DrawFuncOpItem(const DrawCmdList & cmdList,DrawFuncOpItem::ConstructorHandle * handle)663 DrawFuncOpItem::DrawFuncOpItem(const DrawCmdList& cmdList, DrawFuncOpItem::ConstructorHandle* handle)
664     : DrawOpItem(DRAW_FUNC_OPITEM)
665 {
666     objectHandle_ = CmdListHelper::GetDrawFuncObjFromCmdList(cmdList, handle->funcObjectId);
667 }
668 
DrawFuncOpItem(RecordingCanvas::DrawFunc && drawFunc)669 DrawFuncOpItem::DrawFuncOpItem(RecordingCanvas::DrawFunc&& drawFunc) : DrawOpItem(DRAW_FUNC_OPITEM)
670 {
671     objectHandle_ = std::make_shared<RSExtendDrawFuncObj>(std::move(drawFunc));
672 }
673 
Unmarshalling(const DrawCmdList & cmdList,void * handle)674 std::shared_ptr<DrawOpItem> DrawFuncOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
675 {
676     return std::make_shared<DrawFuncOpItem>(cmdList, static_cast<DrawFuncOpItem::ConstructorHandle*>(handle));
677 }
678 
Marshalling(DrawCmdList & cmdList)679 void DrawFuncOpItem::Marshalling(DrawCmdList& cmdList)
680 {
681     auto objectHandle = CmdListHelper::AddDrawFuncObjToCmdList(cmdList, objectHandle_);
682     cmdList.AddOp<ConstructorHandle>(objectHandle);
683 }
684 
Playback(Canvas * canvas,const Rect * rect)685 void DrawFuncOpItem::Playback(Canvas* canvas, const Rect* rect)
686 {
687     if (objectHandle_) {
688         objectHandle_->Playback(canvas, rect);
689     }
690 }
691 
692 #ifdef ROSEN_OHOS
693 /* DrawSurfaceBufferOpItem */
694 UNMARSHALLING_REGISTER(DrawSurfaceBuffer, DrawOpItem::SURFACEBUFFER_OPITEM,
695     DrawSurfaceBufferOpItem::Unmarshalling, sizeof(DrawSurfaceBufferOpItem::ConstructorHandle));
696 
DrawSurfaceBufferOpItem(const DrawCmdList & cmdList,DrawSurfaceBufferOpItem::ConstructorHandle * handle)697 DrawSurfaceBufferOpItem::DrawSurfaceBufferOpItem(
698     const DrawCmdList& cmdList, DrawSurfaceBufferOpItem::ConstructorHandle* handle)
699     : DrawWithPaintOpItem(cmdList, handle->paintHandle, SURFACEBUFFER_OPITEM),
700       surfaceBufferInfo_(nullptr, handle->surfaceBufferInfo.dstRect_.GetLeft(),
701           handle->surfaceBufferInfo.dstRect_.GetTop(), handle->surfaceBufferInfo.dstRect_.GetWidth(),
702           handle->surfaceBufferInfo.dstRect_.GetHeight(), handle->surfaceBufferInfo.pid_,
703           handle->surfaceBufferInfo.uid_, nullptr, handle->surfaceBufferInfo.srcRect_)
704 {
705     auto surfaceBufferEntry = CmdListHelper::GetSurfaceBufferEntryFromCmdList(cmdList, handle->surfaceBufferId);
706     if (surfaceBufferEntry) {
707         surfaceBufferInfo_.surfaceBuffer_ = surfaceBufferEntry->surfaceBuffer_;
708         surfaceBufferInfo_.acquireFence_ = surfaceBufferEntry->acquireFence_;
709     }
710 }
711 
~DrawSurfaceBufferOpItem()712 DrawSurfaceBufferOpItem::~DrawSurfaceBufferOpItem()
713 {
714     OnDestruct();
715     Clear();
716 }
717 
Unmarshalling(const DrawCmdList & cmdList,void * handle)718 std::shared_ptr<DrawOpItem> DrawSurfaceBufferOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
719 {
720     return std::make_shared<DrawSurfaceBufferOpItem>(cmdList,
721         static_cast<DrawSurfaceBufferOpItem::ConstructorHandle*>(handle));
722 }
723 
Marshalling(DrawCmdList & cmdList)724 void DrawSurfaceBufferOpItem::Marshalling(DrawCmdList& cmdList)
725 {
726     PaintHandle paintHandle;
727     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
728     std::shared_ptr<SurfaceBufferEntry> surfaceBufferEntry =
729         std::make_shared<SurfaceBufferEntry>(surfaceBufferInfo_.surfaceBuffer_, surfaceBufferInfo_.acquireFence_);
730     cmdList.AddOp<ConstructorHandle>(CmdListHelper::AddSurfaceBufferEntryToCmdList(cmdList, surfaceBufferEntry),
731         surfaceBufferInfo_.dstRect_.GetLeft(), surfaceBufferInfo_.dstRect_.GetTop(),
732         surfaceBufferInfo_.dstRect_.GetWidth(), surfaceBufferInfo_.dstRect_.GetHeight(), surfaceBufferInfo_.pid_,
733         surfaceBufferInfo_.uid_, surfaceBufferInfo_.srcRect_, paintHandle);
734 }
735 
736 namespace {
737     std::function<void(const DrawSurfaceBufferFinishCbData&)> surfaceBufferFinishCb;
738     std::function<void(const DrawSurfaceBufferAfterAcquireCbData&)> surfaceBufferAfterAcquireCb;
739     std::function<NodeId()> getRootNodeIdForRT;
740     bool contextIsUniRender = true;
741 }
742 
OnDestruct()743 void DrawSurfaceBufferOpItem::OnDestruct()
744 {
745     ReleaseBuffer();
746 }
747 
SetIsUniRender(bool isUniRender)748 void DrawSurfaceBufferOpItem::SetIsUniRender(bool isUniRender)
749 {
750     contextIsUniRender = isUniRender;
751 }
752 
OnAfterDraw()753 void DrawSurfaceBufferOpItem::OnAfterDraw()
754 {
755     isRendered_ = true;
756     if (contextIsUniRender) {
757         return;
758     }
759     rootNodeId_ = getRootNodeIdForRT ? std::invoke(getRootNodeIdForRT) : INVALID_NODEID;
760 #ifdef RS_ENABLE_GL
761     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
762         auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
763         auto sync = eglCreateSyncKHR(disp, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
764         if (sync == EGL_NO_SYNC_KHR) {
765             RS_LOGE("DrawSurfaceBufferOpItem::OnAfterDraw Error on eglCreateSyncKHR %{public}d",
766                 static_cast<int>(eglGetError()));
767             return;
768         }
769         auto fd = eglDupNativeFenceFDANDROID(disp, sync);
770         eglDestroySyncKHR(disp, sync);
771         if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
772             RS_LOGE("DrawSurfaceBufferOpItem::OnAfterDraw: Error on eglDupNativeFenceFD");
773             return;
774         }
775         releaseFence_ = new (std::nothrow) SyncFence(fd);
776         if (!releaseFence_) {
777             releaseFence_ = SyncFence::INVALID_FENCE;
778         }
779     }
780 #endif
781 }
782 
ReleaseBuffer()783 void DrawSurfaceBufferOpItem::ReleaseBuffer()
784 {
785     if (surfaceBufferFinishCb && surfaceBufferInfo_.surfaceBuffer_) {
786         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::ReleaseBuffer %s Release, isNeedTriggerCbDirectly = %d",
787             std::to_string(surfaceBufferInfo_.surfaceBuffer_->GetSeqNum()).c_str(),
788             releaseFence_ && releaseFence_->IsValid());
789         std::invoke(surfaceBufferFinishCb, DrawSurfaceBufferFinishCbData {
790             .uid = surfaceBufferInfo_.uid_,
791             .pid = surfaceBufferInfo_.pid_,
792             .surfaceBufferId = surfaceBufferInfo_.surfaceBuffer_->GetSeqNum(),
793             .rootNodeId = rootNodeId_,
794             .releaseFence = releaseFence_,
795             .isRendered = isRendered_,
796             .isNeedTriggerCbDirectly = releaseFence_ && releaseFence_->IsValid(),
797         });
798     }
799 }
800 
OnAfterAcquireBuffer()801 void DrawSurfaceBufferOpItem::OnAfterAcquireBuffer()
802 {
803     if (surfaceBufferAfterAcquireCb && surfaceBufferInfo_.surfaceBuffer_) {
804         std::invoke(surfaceBufferAfterAcquireCb, DrawSurfaceBufferAfterAcquireCbData {
805             .uid = surfaceBufferInfo_.uid_,
806             .pid = surfaceBufferInfo_.pid_,
807         });
808     }
809 }
810 
RegisterSurfaceBufferCallback(DrawSurfaceBufferOpItemCb callbacks)811 void DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback(
812     DrawSurfaceBufferOpItemCb callbacks)
813 {
814     if (std::exchange(surfaceBufferFinishCb, callbacks.OnFinish)) {
815         RS_LOGE("DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback"
816             " registered OnFinish twice incorrectly.");
817     }
818     if (std::exchange(surfaceBufferAfterAcquireCb, callbacks.OnAfterAcquireBuffer)) {
819         RS_LOGE("DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback"
820             " registered OnAfterAcquireBuffer twice incorrectly.");
821     }
822 }
823 
RegisterGetRootNodeIdFuncForRT(std::function<NodeId ()> func)824 void DrawSurfaceBufferOpItem::RegisterGetRootNodeIdFuncForRT(std::function<NodeId()> func)
825 {
826     if (std::exchange(getRootNodeIdForRT, func)) {
827         RS_LOGE("DrawSurfaceBufferOpItem::RegisterGetRootNodeIdFuncForRT"
828             " registered OnFinish twice incorrectly.");
829     }
830 }
831 
Playback(Canvas * canvas,const Rect * rect)832 void DrawSurfaceBufferOpItem::Playback(Canvas* canvas, const Rect* rect)
833 {
834     if (auto recordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas->GetRecordingCanvas())) {
835         recordingCanvas->DrawSurfaceBuffer(surfaceBufferInfo_);
836         return;
837     }
838     Clear();
839 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
840     if (surfaceBufferInfo_.surfaceBuffer_ == nullptr) {
841         LOGE("SurfaceBufferOpItem::Draw surfaceBuffer_ is nullptr");
842         return;
843     }
844     nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&(surfaceBufferInfo_.surfaceBuffer_));
845     if (!nativeWindowBuffer_) {
846         LOGE("create nativeWindowBuffer_ fail.");
847         return;
848     }
849 #endif
850     canvas->AttachPaint(paint_);
851     Draw(canvas);
852 }
853 
Clear()854 void DrawSurfaceBufferOpItem::Clear()
855 {
856 #ifdef RS_ENABLE_GL
857     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
858         if (texId_ != 0U) {
859             glDeleteTextures(1, &texId_);
860         }
861         if (eglImage_ != EGL_NO_IMAGE_KHR) {
862             auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
863             eglDestroyImageKHR(disp, eglImage_);
864         }
865     }
866 #endif
867 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
868     if (nativeWindowBuffer_ != nullptr) {
869         DestroyNativeWindowBuffer(nativeWindowBuffer_);
870         nativeWindowBuffer_ = nullptr;
871     }
872 #endif
873 }
874 
Draw(Canvas * canvas)875 void DrawSurfaceBufferOpItem::Draw(Canvas* canvas)
876 {
877 #ifdef RS_ENABLE_VK
878     if (RSSystemProperties::IsUseVulkan()) {
879         DrawWithVulkan(canvas);
880     }
881 #endif
882 #ifdef RS_ENABLE_GL
883     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
884         DrawWithGles(canvas);
885     }
886 #endif
887     OnAfterDraw();
888 }
889 
CreateBitmapFormat(int32_t bufferFormat)890 Drawing::BitmapFormat DrawSurfaceBufferOpItem::CreateBitmapFormat(int32_t bufferFormat)
891 {
892     switch (bufferFormat) {
893         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBA_8888 : {
894             return {
895                 .colorType = Drawing::ColorType::COLORTYPE_RGBA_8888,
896                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
897             };
898         }
899         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBX_8888 : {
900             return {
901                 .colorType = Drawing::ColorType::COLORTYPE_RGB_888X,
902                 .alphaType = Drawing::AlphaType::ALPHATYPE_OPAQUE,
903             };
904         }
905         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_BGRA_8888 : {
906             return {
907                 .colorType = Drawing::ColorType::COLORTYPE_BGRA_8888,
908                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
909             };
910         }
911         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGB_565 : {
912             return {
913                 .colorType = Drawing::ColorType::COLORTYPE_RGB_565,
914                 .alphaType = Drawing::AlphaType::ALPHATYPE_OPAQUE,
915             };
916         }
917         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBA_1010102 : {
918             return {
919                 .colorType = Drawing::ColorType::COLORTYPE_RGBA_1010102,
920                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
921             };
922         }
923         default : {
924             return {
925                 .colorType = Drawing::ColorType::COLORTYPE_RGBA_8888,
926                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
927             };
928         }
929     }
930 }
931 
932 #ifdef RS_ENABLE_GL
GetGLTextureFormatByBitmapFormat(Drawing::ColorType colorType)933 GLenum DrawSurfaceBufferOpItem::GetGLTextureFormatByBitmapFormat(Drawing::ColorType colorType)
934 {
935     switch (colorType) {
936         case Drawing::ColorType::COLORTYPE_ALPHA_8 : {
937             return GL_ALPHA8_OES;
938         }
939         case Drawing::ColorType::COLORTYPE_RGB_888X : {
940             return GL_RGBA8_OES;
941         }
942         case Drawing::ColorType::COLORTYPE_RGB_565 : {
943             return GL_RGB565_OES;
944         }
945         case Drawing::ColorType::COLORTYPE_RGBA_1010102 : {
946             return GL_RGB10_A2_EXT;
947         }
948         case Drawing::ColorType::COLORTYPE_BGRA_8888 : {
949             return GL_BGRA8_EXT;
950         }
951         case Drawing::ColorType::COLORTYPE_RGBA_8888 : {
952             return GL_RGBA8_OES;
953         }
954         case Drawing::ColorType::COLORTYPE_RGBA_F16 : {
955             return GL_RGBA16F_EXT;
956         }
957         case Drawing::ColorType::COLORTYPE_GRAY_8 :
958             [[fallthrough]];
959         case Drawing::ColorType::COLORTYPE_ARGB_4444 :
960             [[fallthrough]];
961         case Drawing::ColorType::COLORTYPE_N32 :
962             [[fallthrough]];
963         default : {
964             return GL_RGBA8_OES;
965         }
966     }
967 }
968 #endif
969 
DrawWithVulkan(Canvas * canvas)970 void DrawSurfaceBufferOpItem::DrawWithVulkan(Canvas* canvas)
971 {
972 #ifdef RS_ENABLE_VK
973     if (surfaceBufferInfo_.acquireFence_) {
974         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::DrawWithVulkan waitfence");
975         int res = surfaceBufferInfo_.acquireFence_->Wait(FENCE_WAIT_TIME);
976         if (res < 0) {
977             LOGW("DrawSurfaceBufferOpItem::DrawWithVulkan waitfence timeout");
978         } else {
979             OnAfterAcquireBuffer();
980         }
981     }
982     auto backendTexture = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(nativeWindowBuffer_,
983         surfaceBufferInfo_.surfaceBuffer_->GetWidth(), surfaceBufferInfo_.surfaceBuffer_->GetHeight());
984     if (!backendTexture.IsValid()) {
985         LOGE("DrawSurfaceBufferOpItem::Draw backendTexture is not valid");
986         return;
987     }
988     if (!canvas->GetGPUContext()) {
989         LOGE("DrawSurfaceBufferOpItem::Draw gpu context is nullptr");
990         return;
991     }
992     Drawing::BitmapFormat bitmapFormat = CreateBitmapFormat(surfaceBufferInfo_.surfaceBuffer_->GetFormat());
993     auto image = std::make_shared<Drawing::Image>();
994     auto vkTextureInfo = backendTexture.GetTextureInfo().GetVKTextureInfo();
995     if (!vkTextureInfo || !image->BuildFromTexture(*canvas->GetGPUContext(), backendTexture.GetTextureInfo(),
996         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr, NativeBufferUtils::DeleteVkImage,
997         new NativeBufferUtils::VulkanCleanupHelper(
998             RsVulkanContext::GetSingleton(), vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory))) {
999         LOGE("DrawSurfaceBufferOpItem::Draw image BuildFromTexture failed");
1000         return;
1001     }
1002     canvas->DrawImageRect(*image, surfaceBufferInfo_.srcRect_, surfaceBufferInfo_.dstRect_, Drawing::SamplingOptions());
1003 #endif
1004 }
1005 
DrawWithGles(Canvas * canvas)1006 void DrawSurfaceBufferOpItem::DrawWithGles(Canvas* canvas)
1007 {
1008 #ifdef RS_ENABLE_GL
1009     if (surfaceBufferInfo_.acquireFence_) {
1010         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::DrawWithGles waitfence");
1011         int res = surfaceBufferInfo_.acquireFence_->Wait(FENCE_WAIT_TIME);
1012         if (res < 0) {
1013             LOGW("DrawSurfaceBufferOpItem::DrawWithGles waitfence timeout");
1014         } else {
1015             OnAfterAcquireBuffer();
1016         }
1017     }
1018     if (!CreateEglTextureId()) {
1019         return;
1020     }
1021     Drawing::BitmapFormat bitmapFormat = CreateBitmapFormat(surfaceBufferInfo_.surfaceBuffer_->GetFormat());
1022     Drawing::TextureInfo externalTextureInfo;
1023     externalTextureInfo.SetWidth(surfaceBufferInfo_.dstRect_.GetWidth());
1024     externalTextureInfo.SetHeight(surfaceBufferInfo_.dstRect_.GetHeight());
1025     externalTextureInfo.SetIsMipMapped(false);
1026     externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
1027     externalTextureInfo.SetID(texId_);
1028     externalTextureInfo.SetFormat(GetGLTextureFormatByBitmapFormat(bitmapFormat.colorType));
1029     if (!canvas->GetGPUContext()) {
1030         LOGE("DrawSurfaceBufferOpItem::Draw: gpu context is nullptr");
1031         return;
1032     }
1033 #ifndef ROSEN_EMULATOR
1034     auto surfaceOrigin = Drawing::TextureOrigin::TOP_LEFT;
1035 #else
1036     auto surfaceOrigin = Drawing::TextureOrigin::BOTTOM_LEFT;
1037 #endif
1038     auto newImage = std::make_shared<Drawing::Image>();
1039     if (!newImage->BuildFromTexture(*canvas->GetGPUContext(), externalTextureInfo,
1040         surfaceOrigin, bitmapFormat, nullptr)) {
1041         LOGE("DrawSurfaceBufferOpItem::Draw: image BuildFromTexture failed");
1042         return;
1043     }
1044     canvas->DrawImage(*newImage, surfaceBufferInfo_.dstRect_.GetLeft(), surfaceBufferInfo_.dstRect_.GetTop(),
1045         Drawing::SamplingOptions());
1046 #endif // RS_ENABLE_GL
1047 }
1048 
CreateEglTextureId()1049 bool DrawSurfaceBufferOpItem::CreateEglTextureId()
1050 {
1051     EGLint attrs[] = { EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE };
1052 
1053     auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1054     eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs);
1055     if (eglImage_ == EGL_NO_IMAGE_KHR) {
1056         DestroyNativeWindowBuffer(nativeWindowBuffer_);
1057         nativeWindowBuffer_ = nullptr;
1058         LOGE("%{public}s create egl image fail %{public}d", __func__, eglGetError());
1059         return false;
1060     }
1061 
1062     // save
1063     GLuint originTexture;
1064     glGetIntegerv(GL_TEXTURE_BINDING_2D, reinterpret_cast<GLint *>(&originTexture));
1065     GLint minFilter;
1066     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, &minFilter);
1067     GLint magFilter;
1068     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, &magFilter);
1069     GLint wrapS;
1070     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, &wrapS);
1071     GLint wrapT;
1072     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, &wrapT);
1073 
1074     // Create texture object
1075     texId_ = 0;
1076     glGenTextures(1, &texId_);
1077     glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId_);
1078     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1079     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1080     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1081     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1082     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(eglImage_));
1083 
1084     // restore
1085     glBindTexture(GL_TEXTURE_EXTERNAL_OES, originTexture);
1086     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
1087     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, magFilter);
1088     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, wrapS);
1089     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, wrapT);
1090 
1091     return true;
1092 }
1093 #endif
1094 }
1095 } // namespace Rosen
1096 } // namespace OHOS
1097