• 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     std::vector<Drawing::Point> radiusValue(imageInfo.radius, imageInfo.radius + CORNER_SIZE);
81     rsImage_->SetRadius(radiusValue);
82     rsImage_->SetScale(imageInfo.scale);
83     imageInfo_ = imageInfo;
84 }
85 
RSExtendImageObject(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::AdaptiveImageInfo & imageInfo)86 RSExtendImageObject::RSExtendImageObject(const std::shared_ptr<Media::PixelMap>& pixelMap,
87     const Drawing::AdaptiveImageInfo& imageInfo)
88 {
89     if (pixelMap) {
90 #ifdef ROSEN_OHOS
91         if (RSSystemProperties::GetDumpUIPixelmapEnabled()) {
92             CommonTools::SavePixelmapToFile(pixelMap, "/data/storage/el1/base/imageObject_");
93         }
94 #endif
95         rsImage_ = std::make_shared<RSImage>();
96         rsImage_->SetPixelMap(pixelMap);
97         rsImage_->SetImageFit(imageInfo.fitNum);
98         rsImage_->SetImageRepeat(imageInfo.repeatNum);
99         std::vector<Drawing::Point> radiusValue(imageInfo.radius, imageInfo.radius + CORNER_SIZE);
100         rsImage_->SetRadius(radiusValue);
101         rsImage_->SetScale(imageInfo.scale);
102         rsImage_->SetDyamicRangeMode(imageInfo.dynamicRangeMode);
103         RectF frameRect(imageInfo.frameRect.GetLeft(),
104                         imageInfo.frameRect.GetTop(),
105                         imageInfo.frameRect.GetRight(),
106                         imageInfo.frameRect.GetBottom());
107         rsImage_->SetFrameRect(frameRect);
108     }
109 }
110 
SetNodeId(NodeId id)111 void RSExtendImageObject::SetNodeId(NodeId id)
112 {
113     if (rsImage_) {
114         rsImage_->UpdateNodeIdToPicture(id);
115     }
116 }
117 
SetPaint(Drawing::Paint paint)118 void RSExtendImageObject::SetPaint(Drawing::Paint paint)
119 {
120     if (rsImage_) {
121         rsImage_->SetPaint(paint);
122     }
123 }
124 
Purge()125 void RSExtendImageObject::Purge()
126 {
127     if (rsImage_) {
128         rsImage_->Purge();
129     }
130 }
131 
Playback(Drawing::Canvas & canvas,const Drawing::Rect & rect,const Drawing::SamplingOptions & sampling,bool isBackground)132 void RSExtendImageObject::Playback(Drawing::Canvas& canvas, const Drawing::Rect& rect,
133     const Drawing::SamplingOptions& sampling, bool isBackground)
134 {
135 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
136     if (!rsImage_) {
137         return;
138     }
139     std::shared_ptr<Media::PixelMap> pixelmap = rsImage_->GetPixelMap();
140     if (pixelmap && pixelmap->IsAstc()) {
141         if (auto recordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas())) {
142             Drawing::AdaptiveImageInfo imageInfo = rsImage_->GetAdaptiveImageInfoWithCustomizedFrameRect(rect);
143             recordingCanvas->DrawPixelMapWithParm(pixelmap, imageInfo, sampling);
144             return;
145         }
146     }
147     if (canvas.GetRecordingCanvas()) {
148         image_ = RSPixelMapUtil::ExtractDrawingImage(pixelmap);
149         if (image_) {
150 #ifndef ROSEN_ARKUI_X
151             SKResourceManager::Instance().HoldResource(image_);
152 #endif
153             rsImage_->SetDmaImage(image_);
154         }
155         rsImage_->CanvasDrawImage(canvas, rect, sampling, isBackground);
156         return;
157     }
158     PreProcessPixelMap(canvas, pixelmap, sampling);
159 #endif
160     rsImage_->CanvasDrawImage(canvas, rect, sampling, isBackground);
161 }
162 
Marshalling(Parcel & parcel) const163 bool RSExtendImageObject::Marshalling(Parcel &parcel) const
164 {
165     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
166     return ret;
167 }
168 
Unmarshalling(Parcel & parcel)169 RSExtendImageObject *RSExtendImageObject::Unmarshalling(Parcel &parcel)
170 {
171     auto object = new RSExtendImageObject();
172     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
173     if (!ret) {
174         delete object;
175         return nullptr;
176     }
177     return object;
178 }
179 
180 #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)181 void RSExtendImageObject::PreProcessPixelMap(Drawing::Canvas& canvas, const std::shared_ptr<Media::PixelMap>& pixelMap,
182     const Drawing::SamplingOptions& sampling)
183 {
184     if (!pixelMap || !rsImage_) {
185         return;
186     }
187     auto colorSpace = RSPixelMapUtil::GetPixelmapColorSpace(pixelMap);
188 #ifdef USE_VIDEO_PROCESSING_ENGINE
189     if (pixelMap->IsHdr()) {
190         colorSpace = Drawing::ColorSpace::CreateSRGB();
191     }
192 #endif
193     if (!pixelMap->IsAstc() && RSPixelMapUtil::IsSupportZeroCopy(pixelMap, sampling)) {
194 #if defined(RS_ENABLE_GL)
195         if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
196             if (GetDrawingImageFromSurfaceBuffer(canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()))) {
197                 rsImage_->SetDmaImage(image_);
198             }
199         }
200 #endif
201 #if defined(RS_ENABLE_VK)
202         if (RSSystemProperties::IsUseVukan()) {
203             if (GetRsImageCache(canvas, pixelMap,
204                 reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()), colorSpace)) {
205                 rsImage_->SetDmaImage(image_);
206             }
207         }
208 #endif
209         return;
210     }
211     if (pixelMap->IsAstc()) {
212         std::shared_ptr<Drawing::Data> fileData = std::make_shared<Drawing::Data>();
213         // After RS is switched to Vulkan, the judgment of GpuApiType can be deleted.
214         if (pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC &&
215             RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN) {
216             if (!nativeWindowBuffer_) {
217                 sptr<SurfaceBuffer> surfaceBuf(reinterpret_cast<SurfaceBuffer *>(pixelMap->GetFd()));
218                 nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&surfaceBuf);
219             }
220             OH_NativeBuffer* nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(nativeWindowBuffer_);
221             if (nativeBuffer == nullptr || !fileData->BuildFromOHNativeBuffer(nativeBuffer, pixelMap->GetCapacity())) {
222                 LOGE("PreProcessPixelMap data BuildFromOHNativeBuffer fail");
223                 return;
224             }
225         } else {
226             const void* data = pixelMap->GetPixels();
227             if (pixelMap->GetCapacity() > ASTC_HEADER_SIZE &&
228                 (data == nullptr || !fileData->BuildWithoutCopy((void*)((char*) data + ASTC_HEADER_SIZE),
229                 pixelMap->GetCapacity() - ASTC_HEADER_SIZE))) {
230                 LOGE("PreProcessPixelMap data BuildWithoutCopy fail");
231                 return;
232             }
233         }
234         rsImage_->SetCompressData(fileData);
235         return;
236     }
237     if (RSPixelMapUtil::IsYUVFormat(pixelMap)) {
238         rsImage_->MarkYUVImage();
239     }
240 }
241 #endif
242 
243 #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)244 bool RSExtendImageObject::GetRsImageCache(Drawing::Canvas& canvas, const std::shared_ptr<Media::PixelMap>& pixelMap,
245     SurfaceBuffer *surfaceBuffer, const std::shared_ptr<Drawing::ColorSpace>& colorSpace)
246 {
247     if (pixelMap == nullptr) {
248         return false;
249     }
250     std::shared_ptr<Drawing::Image> imageCache = nullptr;
251     if (!pixelMap->IsEditable()) {
252         imageCache = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(
253             rsImage_->GetUniqueId(), gettid());
254     }
255     if (imageCache) {
256         this->image_ = imageCache;
257     } else {
258         bool ret = MakeFromTextureForVK(
259             canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()), colorSpace);
260         if (ret && image_ && !pixelMap->IsEditable()) {
261             SKResourceManager::Instance().HoldResource(image_);
262             RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(
263                 rsImage_->GetUniqueId(), image_, gettid());
264         }
265         return ret;
266     }
267     return true;
268 }
269 #endif
270 
271 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_GL)
GetDrawingImageFromSurfaceBuffer(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer)272 bool RSExtendImageObject::GetDrawingImageFromSurfaceBuffer(Drawing::Canvas& canvas, SurfaceBuffer* surfaceBuffer)
273 {
274     if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
275         return false;
276     }
277     if (surfaceBuffer == nullptr) {
278         RS_LOGE("GetDrawingImageFromSurfaceBuffer surfaceBuffer is nullptr");
279         return false;
280     }
281     if (nativeWindowBuffer_ == nullptr) {
282         sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
283         nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
284         if (!nativeWindowBuffer_) {
285             RS_LOGE("GetDrawingImageFromSurfaceBuffer create native window buffer fail");
286             return false;
287         }
288     }
289     EGLint attrs[] = { EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE };
290 
291     auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
292     if (eglImage_ == EGL_NO_IMAGE_KHR) {
293         eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs);
294         if (eglImage_ == EGL_NO_IMAGE_KHR) {
295             RS_LOGE("%{public}s create egl image fail %{public}d", __func__, eglGetError());
296             return false;
297         }
298         tid_ = gettid();
299     }
300 
301     // Create texture object
302     if (texId_ == 0U) {
303         glGenTextures(1, &texId_);
304         glBindTexture(GL_TEXTURE_2D, texId_);
305         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
306         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
307         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
308         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
309         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(eglImage_));
310     }
311 
312     Drawing::TextureInfo externalTextureInfo;
313     externalTextureInfo.SetWidth(surfaceBuffer->GetWidth());
314     externalTextureInfo.SetHeight(surfaceBuffer->GetHeight());
315     externalTextureInfo.SetIsMipMapped(false);
316     externalTextureInfo.SetTarget(GL_TEXTURE_2D);
317     externalTextureInfo.SetID(texId_);
318     externalTextureInfo.SetFormat(GL_RGBA8_OES);
319 
320     Drawing::BitmapFormat bitmapFormat = {
321         Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
322     if (!canvas.GetGPUContext()) {
323         RS_LOGE("GetDrawingImageFromSurfaceBuffer gpu context is nullptr");
324         return false;
325     }
326 
327     image_ = std::make_shared<Drawing::Image>();
328 #ifndef ROSEN_EMULATOR
329     auto surfaceOrigin = Drawing::TextureOrigin::TOP_LEFT;
330 #else
331     auto surfaceOrigin = Drawing::TextureOrigin::BOTTOM_LEFT;
332 #endif
333     if (!image_->BuildFromTexture(*(canvas.GetGPUContext()), externalTextureInfo,
334         surfaceOrigin, bitmapFormat,
335         std::make_shared<Drawing::ColorSpace>(Drawing::ColorSpace::ColorSpaceType::SRGB))) {
336         RS_LOGE("BuildFromTexture failed");
337         return false;
338     }
339     return true;
340 }
341 #endif
342 
343 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
MakeFromTextureForVK(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer,const std::shared_ptr<Drawing::ColorSpace> & colorSpace)344 bool RSExtendImageObject::MakeFromTextureForVK(Drawing::Canvas& canvas, SurfaceBuffer *surfaceBuffer,
345     const std::shared_ptr<Drawing::ColorSpace>& colorSpace)
346 {
347     if (!RSSystemProperties::IsUseVukan()) {
348         return false;
349     }
350     if (surfaceBuffer == nullptr || surfaceBuffer->GetBufferHandle() == nullptr) {
351         RS_LOGE("MakeFromTextureForVK surfaceBuffer is nullptr or buffer handle is nullptr");
352         return false;
353     }
354     if (nativeWindowBuffer_ == nullptr) {
355         sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
356         nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
357         if (!nativeWindowBuffer_) {
358             RS_LOGE("MakeFromTextureForVK create native window buffer fail");
359             return false;
360         }
361     }
362     if (!backendTexture_.IsValid()) {
363         backendTexture_ = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(nativeWindowBuffer_,
364             surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), false);
365         if (backendTexture_.IsValid()) {
366             auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
367             if (!vkTextureInfo) {
368                 return false;
369             }
370             cleanUpHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
371                 vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
372         } else {
373             return false;
374         }
375         tid_ = gettid();
376     }
377 
378     auto context = canvas.GetGPUContext();
379     if (!context) {
380         RS_LOGE("MakeFromTextureForVK gpu context is nullptr");
381         return false;
382     }
383     image_ = std::make_shared<Drawing::Image>();
384     auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
385     if (!vkTextureInfo || !cleanUpHelper_) {
386         return false;
387     }
388     Drawing::ColorType colorType = GetColorTypeFromVKFormat(vkTextureInfo->format);
389     Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
390     if (!image_->BuildFromTexture(*context, backendTexture_.GetTextureInfo(),
391         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, colorSpace,
392         NativeBufferUtils::DeleteVkImage,
393         cleanUpHelper_->Ref())) {
394         RS_LOGE("MakeFromTextureForVK build image failed");
395         return false;
396     }
397     return true;
398 }
399 #endif
400 
~RSExtendImageObject()401 RSExtendImageObject::~RSExtendImageObject()
402 {
403 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_GL)
404     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
405         RSTaskDispatcher::GetInstance().PostTask(tid_, [texId = texId_,
406                                                         nativeWindowBuffer = nativeWindowBuffer_,
407                                                         eglImage = eglImage_]() {
408             if (texId != 0U) {
409                 glBindTexture(GL_TEXTURE_2D, 0);
410                 glDeleteTextures(1, &texId);
411             }
412             if (nativeWindowBuffer != nullptr) {
413                 DestroyNativeWindowBuffer(nativeWindowBuffer);
414             }
415             if (eglImage != EGL_NO_IMAGE_KHR) {
416                 auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
417                 eglDestroyImageKHR(disp, eglImage);
418             }
419         });
420     }
421 #endif
422 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
423     if (RSSystemProperties::IsUseVukan()) {
424         RSTaskDispatcher::GetInstance().PostTask(tid_, [nativeWindowBuffer = nativeWindowBuffer_,
425             cleanupHelper = cleanUpHelper_]() {
426             if (nativeWindowBuffer != nullptr) {
427                 DestroyNativeWindowBuffer(nativeWindowBuffer);
428             }
429             if (cleanupHelper != nullptr) {
430                 NativeBufferUtils::DeleteVkImage(cleanupHelper);
431             }
432         });
433     }
434 #endif
435 }
436 
RSExtendImageBaseObj(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::Rect & src,const Drawing::Rect & dst)437 RSExtendImageBaseObj::RSExtendImageBaseObj(const std::shared_ptr<Media::PixelMap>& pixelMap, const Drawing::Rect& src,
438     const Drawing::Rect& dst)
439 {
440     if (pixelMap) {
441         rsImage_ = std::make_shared<RSImageBase>();
442         rsImage_->SetPixelMap(pixelMap);
443         rsImage_->SetSrcRect(RectF(src.GetLeft(), src.GetTop(), src.GetWidth(), src.GetHeight()));
444         rsImage_->SetDstRect(RectF(dst.GetLeft(), dst.GetTop(), dst.GetWidth(), dst.GetHeight()));
445     }
446 }
447 
Playback(Drawing::Canvas & canvas,const Drawing::Rect & rect,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)448 void RSExtendImageBaseObj::Playback(Drawing::Canvas& canvas, const Drawing::Rect& rect,
449     const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint)
450 {
451     if (rsImage_) {
452         rsImage_->DrawImage(canvas, sampling, constraint);
453     }
454 }
455 
SetNodeId(NodeId id)456 void RSExtendImageBaseObj::SetNodeId(NodeId id)
457 {
458     if (rsImage_) {
459         rsImage_->UpdateNodeIdToPicture(id);
460     }
461 }
462 
Purge()463 void RSExtendImageBaseObj::Purge()
464 {
465     if (rsImage_) {
466         rsImage_->Purge();
467     }
468 }
469 
Marshalling(Parcel & parcel) const470 bool RSExtendImageBaseObj::Marshalling(Parcel &parcel) const
471 {
472     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
473     return ret;
474 }
475 
Unmarshalling(Parcel & parcel)476 RSExtendImageBaseObj *RSExtendImageBaseObj::Unmarshalling(Parcel &parcel)
477 {
478     auto object = new RSExtendImageBaseObj();
479     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
480     if (!ret) {
481         delete object;
482         return nullptr;
483     }
484     return object;
485 }
486 
Playback(Drawing::Canvas * canvas,const Drawing::Rect * rect)487 void RSExtendDrawFuncObj::Playback(Drawing::Canvas* canvas, const Drawing::Rect* rect)
488 {
489     if (drawFunc_) {
490         drawFunc_(canvas, rect);
491     }
492 }
493 
Marshalling(Parcel & parcel) const494 bool RSExtendDrawFuncObj::Marshalling(Parcel &parcel) const
495 {
496     return false;
497 }
498 
Unmarshalling(Parcel & parcel)499 RSExtendDrawFuncObj *RSExtendDrawFuncObj::Unmarshalling(Parcel &parcel)
500 {
501     return nullptr;
502 }
503 
504 namespace Drawing {
505 /* DrawImageWithParmOpItem */
506 UNMARSHALLING_REGISTER(DrawImageWithParm, DrawOpItem::IMAGE_WITH_PARM_OPITEM,
507     DrawImageWithParmOpItem::Unmarshalling, sizeof(DrawImageWithParmOpItem::ConstructorHandle));
508 
DrawImageWithParmOpItem(const DrawCmdList & cmdList,DrawImageWithParmOpItem::ConstructorHandle * handle)509 DrawImageWithParmOpItem::DrawImageWithParmOpItem(
510     const DrawCmdList& cmdList, DrawImageWithParmOpItem::ConstructorHandle* handle)
511     : DrawWithPaintOpItem(cmdList, handle->paintHandle, IMAGE_WITH_PARM_OPITEM), sampling_(handle->sampling)
512 {
513     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
514 }
515 
DrawImageWithParmOpItem(const std::shared_ptr<Image> & image,const std::shared_ptr<Data> & data,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)516 DrawImageWithParmOpItem::DrawImageWithParmOpItem(const std::shared_ptr<Image>& image, const std::shared_ptr<Data>& data,
517     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
518     : DrawWithPaintOpItem(paint, IMAGE_WITH_PARM_OPITEM), sampling_(sampling)
519 {
520     objectHandle_ = std::make_shared<RSExtendImageObject>(image, data, rsImageInfo);
521 }
522 
Unmarshalling(const DrawCmdList & cmdList,void * handle)523 std::shared_ptr<DrawOpItem> DrawImageWithParmOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
524 {
525     return std::make_shared<DrawImageWithParmOpItem>(
526         cmdList, static_cast<DrawImageWithParmOpItem::ConstructorHandle*>(handle));
527 }
528 
Marshalling(DrawCmdList & cmdList)529 void DrawImageWithParmOpItem::Marshalling(DrawCmdList& cmdList)
530 {
531     PaintHandle paintHandle;
532     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
533     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
534     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle);
535 }
536 
Playback(Canvas * canvas,const Rect * rect)537 void DrawImageWithParmOpItem::Playback(Canvas* canvas, const Rect* rect)
538 {
539     if (objectHandle_ == nullptr) {
540         LOGE("DrawImageWithParmOpItem objectHandle is nullptr!");
541         return;
542     }
543     canvas->AttachPaint(paint_);
544     objectHandle_->Playback(*canvas, *rect, sampling_, false);
545 }
546 
SetNodeId(NodeId id)547 void DrawImageWithParmOpItem::SetNodeId(NodeId id)
548 {
549     if (objectHandle_ == nullptr) {
550         LOGE("DrawImageWithParmOpItem objectHandle is nullptr!");
551         return;
552     }
553     objectHandle_->SetNodeId(id);
554 }
555 
556 /* DrawPixelMapWithParmOpItem */
557 UNMARSHALLING_REGISTER(DrawPixelMapWithParm, DrawOpItem::PIXELMAP_WITH_PARM_OPITEM,
558     DrawPixelMapWithParmOpItem::Unmarshalling, sizeof(DrawPixelMapWithParmOpItem::ConstructorHandle));
559 
DrawPixelMapWithParmOpItem(const DrawCmdList & cmdList,DrawPixelMapWithParmOpItem::ConstructorHandle * handle)560 DrawPixelMapWithParmOpItem::DrawPixelMapWithParmOpItem(
561     const DrawCmdList& cmdList, DrawPixelMapWithParmOpItem::ConstructorHandle* handle)
562     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_WITH_PARM_OPITEM), sampling_(handle->sampling)
563 {
564     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
565 }
566 
DrawPixelMapWithParmOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)567 DrawPixelMapWithParmOpItem::DrawPixelMapWithParmOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap,
568     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
569     : DrawWithPaintOpItem(paint, PIXELMAP_WITH_PARM_OPITEM), sampling_(sampling)
570 {
571     objectHandle_ = std::make_shared<RSExtendImageObject>(pixelMap, rsImageInfo);
572 }
573 
Unmarshalling(const DrawCmdList & cmdList,void * handle)574 std::shared_ptr<DrawOpItem> DrawPixelMapWithParmOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
575 {
576     return std::make_shared<DrawPixelMapWithParmOpItem>(
577         cmdList, static_cast<DrawPixelMapWithParmOpItem::ConstructorHandle*>(handle));
578 }
579 
Marshalling(DrawCmdList & cmdList)580 void DrawPixelMapWithParmOpItem::Marshalling(DrawCmdList& cmdList)
581 {
582     PaintHandle paintHandle;
583     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
584     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
585     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle);
586 }
587 
Playback(Canvas * canvas,const Rect * rect)588 void DrawPixelMapWithParmOpItem::Playback(Canvas* canvas, const Rect* rect)
589 {
590     if (objectHandle_ == nullptr) {
591         LOGE("DrawPixelMapWithParmOpItem objectHandle is nullptr!");
592         return;
593     }
594     objectHandle_->SetPaint(paint_);
595     canvas->AttachPaint(paint_);
596     objectHandle_->Playback(*canvas, *rect, sampling_, false);
597 }
598 
SetNodeId(NodeId id)599 void DrawPixelMapWithParmOpItem::SetNodeId(NodeId id)
600 {
601     if (objectHandle_ == nullptr) {
602         LOGE("DrawPixelMapWithParmOpItem objectHandle is nullptr!");
603         return;
604     }
605     objectHandle_->SetNodeId(id);
606 }
607 
608 /* DrawPixelMapRectOpItem */
609 UNMARSHALLING_REGISTER(DrawPixelMapRect, DrawOpItem::PIXELMAP_RECT_OPITEM,
610     DrawPixelMapRectOpItem::Unmarshalling, sizeof(DrawPixelMapRectOpItem::ConstructorHandle));
611 
DrawPixelMapRectOpItem(const DrawCmdList & cmdList,DrawPixelMapRectOpItem::ConstructorHandle * handle)612 DrawPixelMapRectOpItem::DrawPixelMapRectOpItem(
613     const DrawCmdList& cmdList, DrawPixelMapRectOpItem::ConstructorHandle* handle)
614     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_RECT_OPITEM), sampling_(handle->sampling),
615       constraint_(handle->constraint)
616 {
617     objectHandle_ = CmdListHelper::GetImageBaseObjFromCmdList(cmdList, handle->objectHandle);
618 }
619 
DrawPixelMapRectOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint,const Paint & paint)620 DrawPixelMapRectOpItem::DrawPixelMapRectOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap, const Rect& src,
621     const Rect& dst, const SamplingOptions& sampling, SrcRectConstraint constraint, const Paint& paint)
622     : DrawWithPaintOpItem(paint, PIXELMAP_RECT_OPITEM), sampling_(sampling), constraint_(constraint)
623 {
624     objectHandle_ = std::make_shared<RSExtendImageBaseObj>(pixelMap, src, dst);
625 }
626 
Unmarshalling(const DrawCmdList & cmdList,void * handle)627 std::shared_ptr<DrawOpItem> DrawPixelMapRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
628 {
629     return std::make_shared<DrawPixelMapRectOpItem>(
630         cmdList, static_cast<DrawPixelMapRectOpItem::ConstructorHandle*>(handle));
631 }
632 
Marshalling(DrawCmdList & cmdList)633 void DrawPixelMapRectOpItem::Marshalling(DrawCmdList& cmdList)
634 {
635     PaintHandle paintHandle;
636     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
637     auto objectHandle = CmdListHelper::AddImageBaseObjToCmdList(cmdList, objectHandle_);
638     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, constraint_, paintHandle);
639 }
640 
Playback(Canvas * canvas,const Rect * rect)641 void DrawPixelMapRectOpItem::Playback(Canvas* canvas, const Rect* rect)
642 {
643     if (objectHandle_ == nullptr) {
644         LOGE("DrawPixelMapRectOpItem objectHandle is nullptr!");
645         return;
646     }
647     canvas->AttachPaint(paint_);
648     objectHandle_->Playback(*canvas, *rect, sampling_, constraint_);
649 }
650 
SetNodeId(NodeId id)651 void DrawPixelMapRectOpItem::SetNodeId(NodeId id)
652 {
653     if (objectHandle_ == nullptr) {
654         LOGE("DrawPixelMapRectOpItem objectHandle is nullptr!");
655         return;
656     }
657     objectHandle_->SetNodeId(id);
658 }
659 
660 /* DrawFuncOpItem */
661 UNMARSHALLING_REGISTER(DrawFunc, DrawOpItem::DRAW_FUNC_OPITEM,
662     DrawFuncOpItem::Unmarshalling, sizeof(DrawFuncOpItem::ConstructorHandle));
663 
DrawFuncOpItem(const DrawCmdList & cmdList,DrawFuncOpItem::ConstructorHandle * handle)664 DrawFuncOpItem::DrawFuncOpItem(const DrawCmdList& cmdList, DrawFuncOpItem::ConstructorHandle* handle)
665     : DrawOpItem(DRAW_FUNC_OPITEM)
666 {
667     objectHandle_ = CmdListHelper::GetDrawFuncObjFromCmdList(cmdList, handle->funcObjectId);
668 }
669 
DrawFuncOpItem(RecordingCanvas::DrawFunc && drawFunc)670 DrawFuncOpItem::DrawFuncOpItem(RecordingCanvas::DrawFunc&& drawFunc) : DrawOpItem(DRAW_FUNC_OPITEM)
671 {
672     objectHandle_ = std::make_shared<RSExtendDrawFuncObj>(std::move(drawFunc));
673 }
674 
Unmarshalling(const DrawCmdList & cmdList,void * handle)675 std::shared_ptr<DrawOpItem> DrawFuncOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
676 {
677     return std::make_shared<DrawFuncOpItem>(cmdList, static_cast<DrawFuncOpItem::ConstructorHandle*>(handle));
678 }
679 
Marshalling(DrawCmdList & cmdList)680 void DrawFuncOpItem::Marshalling(DrawCmdList& cmdList)
681 {
682     auto objectHandle = CmdListHelper::AddDrawFuncObjToCmdList(cmdList, objectHandle_);
683     cmdList.AddOp<ConstructorHandle>(objectHandle);
684 }
685 
Playback(Canvas * canvas,const Rect * rect)686 void DrawFuncOpItem::Playback(Canvas* canvas, const Rect* rect)
687 {
688     if (objectHandle_) {
689         objectHandle_->Playback(canvas, rect);
690     }
691 }
692 
693 #ifdef ROSEN_OHOS
694 /* DrawSurfaceBufferOpItem */
695 UNMARSHALLING_REGISTER(DrawSurfaceBuffer, DrawOpItem::SURFACEBUFFER_OPITEM,
696     DrawSurfaceBufferOpItem::Unmarshalling, sizeof(DrawSurfaceBufferOpItem::ConstructorHandle));
697 
DrawSurfaceBufferOpItem(const DrawCmdList & cmdList,DrawSurfaceBufferOpItem::ConstructorHandle * handle)698 DrawSurfaceBufferOpItem::DrawSurfaceBufferOpItem(const DrawCmdList& cmdList,
699     DrawSurfaceBufferOpItem::ConstructorHandle* handle)
700     : DrawWithPaintOpItem(cmdList, handle->paintHandle, SURFACEBUFFER_OPITEM),
701       surfaceBufferInfo_(nullptr, handle->surfaceBufferInfo.offSetX_, handle->surfaceBufferInfo.offSetY_,
702                          handle->surfaceBufferInfo.width_, handle->surfaceBufferInfo.height_,
703                          handle->surfaceBufferInfo.pid_, handle->surfaceBufferInfo.uid_)
704 {
705     auto surfaceBufferEntry = CmdListHelper::GetSurfaceBufferEntryFromCmdList(cmdList, handle->surfaceBufferId);
706     surfaceBufferInfo_.surfaceBuffer_ = surfaceBufferEntry->surfaceBuffer_;
707     surfaceBufferInfo_.acquireFence_ = surfaceBufferEntry->acquireFence_;
708 }
709 
~DrawSurfaceBufferOpItem()710 DrawSurfaceBufferOpItem::~DrawSurfaceBufferOpItem()
711 {
712     OnDestruct();
713     Clear();
714 }
715 
Unmarshalling(const DrawCmdList & cmdList,void * handle)716 std::shared_ptr<DrawOpItem> DrawSurfaceBufferOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
717 {
718     return std::make_shared<DrawSurfaceBufferOpItem>(cmdList,
719         static_cast<DrawSurfaceBufferOpItem::ConstructorHandle*>(handle));
720 }
721 
Marshalling(DrawCmdList & cmdList)722 void DrawSurfaceBufferOpItem::Marshalling(DrawCmdList& cmdList)
723 {
724     PaintHandle paintHandle;
725     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
726     std::shared_ptr<SurfaceBufferEntry> surfaceBufferEntry =
727         std::make_shared<SurfaceBufferEntry>(surfaceBufferInfo_.surfaceBuffer_, surfaceBufferInfo_.acquireFence_);
728     cmdList.AddOp<ConstructorHandle>(
729         CmdListHelper::AddSurfaceBufferEntryToCmdList(cmdList, surfaceBufferEntry),
730         surfaceBufferInfo_.offSetX_, surfaceBufferInfo_.offSetY_,
731         surfaceBufferInfo_.width_, surfaceBufferInfo_.height_,
732         surfaceBufferInfo_.pid_, surfaceBufferInfo_.uid_, paintHandle);
733 }
734 
735 namespace {
736     std::function<void(pid_t, uint64_t, uint32_t)> surfaceBufferFenceCallback;
737 }
738 
OnDestruct()739 void DrawSurfaceBufferOpItem::OnDestruct()
740 {
741     if (surfaceBufferFenceCallback && surfaceBufferInfo_.surfaceBuffer_) {
742         std::invoke(surfaceBufferFenceCallback, surfaceBufferInfo_.pid_,
743             surfaceBufferInfo_.uid_, surfaceBufferInfo_.surfaceBuffer_->GetSeqNum());
744     }
745 }
746 
RegisterSurfaceBufferCallback(std::function<void (pid_t,uint64_t,uint32_t)> callback)747 void DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback(
748     std::function<void(pid_t, uint64_t, uint32_t)> callback)
749 {
750     if (std::exchange(surfaceBufferFenceCallback, callback)) {
751         RS_LOGE("DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback"
752             " registered callback twice incorrectly.");
753     }
754 }
755 
Playback(Canvas * canvas,const Rect * rect)756 void DrawSurfaceBufferOpItem::Playback(Canvas* canvas, const Rect* rect)
757 {
758     if (auto recordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas->GetRecordingCanvas())) {
759         recordingCanvas->DrawSurfaceBuffer(surfaceBufferInfo_);
760         return;
761     }
762     Clear();
763 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
764     if (surfaceBufferInfo_.surfaceBuffer_ == nullptr) {
765         LOGE("SurfaceBufferOpItem::Draw surfaceBuffer_ is nullptr");
766         return;
767     }
768     nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&(surfaceBufferInfo_.surfaceBuffer_));
769     if (!nativeWindowBuffer_) {
770         LOGE("create nativeWindowBuffer_ fail.");
771         return;
772     }
773 #endif
774     canvas->AttachPaint(paint_);
775     Draw(canvas);
776 }
777 
Clear()778 void DrawSurfaceBufferOpItem::Clear()
779 {
780 #ifdef RS_ENABLE_GL
781     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
782         if (texId_ != 0U) {
783             glDeleteTextures(1, &texId_);
784         }
785         if (eglImage_ != EGL_NO_IMAGE_KHR) {
786             auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
787             eglDestroyImageKHR(disp, eglImage_);
788         }
789     }
790 #endif
791 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
792     if (nativeWindowBuffer_ != nullptr) {
793         DestroyNativeWindowBuffer(nativeWindowBuffer_);
794         nativeWindowBuffer_ = nullptr;
795     }
796 #endif
797 }
798 
Draw(Canvas * canvas)799 void DrawSurfaceBufferOpItem::Draw(Canvas* canvas)
800 {
801 #ifdef RS_ENABLE_VK
802     if (RSSystemProperties::IsUseVulkan()) {
803         DrawWithVulkan(canvas);
804         return;
805     }
806 #endif
807 #ifdef RS_ENABLE_GL
808     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
809         DrawWithGles(canvas);
810         return;
811     }
812 #endif
813 }
814 
CreateBitmapFormat(int32_t bufferFormat)815 Drawing::BitmapFormat DrawSurfaceBufferOpItem::CreateBitmapFormat(int32_t bufferFormat)
816 {
817     bool isRgbx = bufferFormat == OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBX_8888;
818     return { isRgbx ? Drawing::ColorType::COLORTYPE_RGB_888X : Drawing::ColorType::COLORTYPE_RGBA_8888,
819         isRgbx ? Drawing::AlphaType::ALPHATYPE_OPAQUE : Drawing::AlphaType::ALPHATYPE_PREMUL };
820 }
821 
DrawWithVulkan(Canvas * canvas)822 void DrawSurfaceBufferOpItem::DrawWithVulkan(Canvas* canvas)
823 {
824 #ifdef RS_ENABLE_VK
825     if (surfaceBufferInfo_.acquireFence_) {
826         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::DrawWithVulkan waitfence");
827         int res = surfaceBufferInfo_.acquireFence_->Wait(FENCE_WAIT_TIME);
828         if (res < 0) {
829             LOGW("DrawSurfaceBufferOpItem::DrawWithVulkan waitfence timeout");
830         }
831     }
832     auto backendTexture = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(nativeWindowBuffer_,
833         surfaceBufferInfo_.surfaceBuffer_->GetWidth(), surfaceBufferInfo_.surfaceBuffer_->GetHeight());
834     if (!backendTexture.IsValid()) {
835         LOGE("DrawSurfaceBufferOpItem::Draw backendTexture is not valid");
836         return;
837     }
838     if (!canvas->GetGPUContext()) {
839         LOGE("DrawSurfaceBufferOpItem::Draw gpu context is nullptr");
840         return;
841     }
842     Drawing::BitmapFormat bitmapFormat = CreateBitmapFormat(surfaceBufferInfo_.surfaceBuffer_->GetFormat());
843     auto image = std::make_shared<Drawing::Image>();
844     auto vkTextureInfo = backendTexture.GetTextureInfo().GetVKTextureInfo();
845     if (!vkTextureInfo || !image->BuildFromTexture(*canvas->GetGPUContext(), backendTexture.GetTextureInfo(),
846         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr, NativeBufferUtils::DeleteVkImage,
847         new NativeBufferUtils::VulkanCleanupHelper(
848             RsVulkanContext::GetSingleton(), vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory))) {
849         LOGE("DrawSurfaceBufferOpItem::Draw image BuildFromTexture failed");
850         return;
851     }
852     canvas->DrawImageRect(*image, Rect{
853         surfaceBufferInfo_.offSetX_, surfaceBufferInfo_.offSetY_,
854         surfaceBufferInfo_.offSetX_ + surfaceBufferInfo_.width_,
855         surfaceBufferInfo_.offSetY_ + surfaceBufferInfo_.height_},
856         Drawing::SamplingOptions());
857 #endif
858 }
859 
DrawWithGles(Canvas * canvas)860 void DrawSurfaceBufferOpItem::DrawWithGles(Canvas* canvas)
861 {
862 #ifdef RS_ENABLE_GL
863     if (surfaceBufferInfo_.acquireFence_) {
864         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::DrawWithGles waitfence");
865         int res = surfaceBufferInfo_.acquireFence_->Wait(FENCE_WAIT_TIME);
866         if (res < 0) {
867             LOGW("DrawSurfaceBufferOpItem::DrawWithGles waitfence timeout");
868         }
869     }
870     if (!CreateEglTextureId()) {
871         return;
872     }
873     GrGLTextureInfo textureInfo = { GL_TEXTURE_EXTERNAL_OES, texId_, GL_RGBA8_OES };
874 
875     GrBackendTexture backendTexture(
876         surfaceBufferInfo_.width_, surfaceBufferInfo_.height_, GrMipMapped::kNo, textureInfo);
877 
878     Drawing::TextureInfo externalTextureInfo;
879     externalTextureInfo.SetWidth(surfaceBufferInfo_.width_);
880     externalTextureInfo.SetHeight(surfaceBufferInfo_.height_);
881     externalTextureInfo.SetIsMipMapped(false);
882     externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
883     externalTextureInfo.SetID(texId_);
884     externalTextureInfo.SetFormat(GL_RGBA8_OES);
885     Drawing::BitmapFormat bitmapFormat = CreateBitmapFormat(surfaceBufferInfo_.surfaceBuffer_->GetFormat());
886     if (!canvas->GetGPUContext()) {
887         LOGE("DrawSurfaceBufferOpItem::Draw: gpu context is nullptr");
888         return;
889     }
890 #ifndef ROSEN_EMULATOR
891     auto surfaceOrigin = Drawing::TextureOrigin::TOP_LEFT;
892 #else
893     auto surfaceOrigin = Drawing::TextureOrigin::BOTTOM_LEFT;
894 #endif
895     auto newImage = std::make_shared<Drawing::Image>();
896     if (!newImage->BuildFromTexture(*canvas->GetGPUContext(), externalTextureInfo,
897         surfaceOrigin, bitmapFormat, nullptr)) {
898         LOGE("DrawSurfaceBufferOpItem::Draw: image BuildFromTexture failed");
899         return;
900     }
901     canvas->DrawImage(*newImage, surfaceBufferInfo_.offSetX_, surfaceBufferInfo_.offSetY_, Drawing::SamplingOptions());
902 #endif // RS_ENABLE_GL
903 }
904 
CreateEglTextureId()905 bool DrawSurfaceBufferOpItem::CreateEglTextureId()
906 {
907     EGLint attrs[] = { EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE };
908 
909     auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
910     eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs);
911     if (eglImage_ == EGL_NO_IMAGE_KHR) {
912         DestroyNativeWindowBuffer(nativeWindowBuffer_);
913         nativeWindowBuffer_ = nullptr;
914         LOGE("%{public}s create egl image fail %{public}d", __func__, eglGetError());
915         return false;
916     }
917 
918     // save
919     GLuint originTexture;
920     glGetIntegerv(GL_TEXTURE_BINDING_2D, reinterpret_cast<GLint *>(&originTexture));
921     GLint minFilter;
922     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, &minFilter);
923     GLint magFilter;
924     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, &magFilter);
925     GLint wrapS;
926     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, &wrapS);
927     GLint wrapT;
928     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, &wrapT);
929 
930     // Create texture object
931     texId_ = 0;
932     glGenTextures(1, &texId_);
933     glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId_);
934     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
935     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
936     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
937     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
938     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(eglImage_));
939 
940     // restore
941     glBindTexture(GL_TEXTURE_EXTERNAL_OES, originTexture);
942     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
943     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, magFilter);
944     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, wrapS);
945     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, wrapT);
946 
947     return true;
948 }
949 #endif
950 }
951 } // namespace Rosen
952 } // namespace OHOS
953