• 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 <sstream>
17 
18 #include "common/rs_optional_trace.h"
19 #include "pipeline/rs_draw_cmd.h"
20 #include "pipeline/rs_recording_canvas.h"
21 #include "platform/common/rs_log.h"
22 #include "render/rs_pixel_map_util.h"
23 #include "render/rs_image_cache.h"
24 #include "recording/cmd_list_helper.h"
25 #include "recording/draw_cmd_list.h"
26 #include "rs_trace.h"
27 #include "utils/system_properties.h"
28 #include "pipeline/rs_task_dispatcher.h"
29 #include "platform/common/rs_system_properties.h"
30 #include "pipeline/sk_resource_manager.h"
31 #ifdef ROSEN_OHOS
32 #include "common/rs_common_tools.h"
33 #include "native_buffer_inner.h"
34 #include "native_window.h"
35 #endif
36 #ifdef RS_ENABLE_VK
37 #ifdef USE_M133_SKIA
38 #include "include/gpu/ganesh/GrBackendSemaphore.h"
39 #else
40 #include "include/gpu/GrBackendSemaphore.h"
41 #endif
42 #include "platform/ohos/backend/native_buffer_utils.h"
43 #include "platform/ohos/backend/rs_vulkan_context.h"
44 #endif
45 
46 #ifdef USE_M133_SKIA
47 #include "include/gpu/ganesh/GrDirectContext.h"
48 #else
49 #include "include/gpu/GrDirectContext.h"
50 #endif
51 #ifdef SUBTREE_PARALLEL_ENABLE
52 #include "rs_parallel_misc.h"
53 #endif
54 
55 namespace OHOS {
56 namespace Rosen {
57 constexpr int32_t CORNER_SIZE = 4;
58 #if (defined(ROSEN_OHOS) && defined(RS_ENABLE_GPU))
59 constexpr uint32_t FENCE_WAIT_TIME = 3000; // ms
60 #endif
61 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
62 constexpr uint8_t ASTC_HEADER_SIZE = 16;
63 #endif
64 
65 #ifdef RS_ENABLE_VK
GetColorTypeFromVKFormat(VkFormat vkFormat)66 Drawing::ColorType GetColorTypeFromVKFormat(VkFormat vkFormat)
67 {
68     if (!RSSystemProperties::IsUseVulkan()) {
69         return Drawing::COLORTYPE_RGBA_8888;
70     }
71     switch (vkFormat) {
72         case VK_FORMAT_R8G8B8A8_UNORM:
73             return Drawing::COLORTYPE_RGBA_8888;
74         case VK_FORMAT_R16G16B16A16_SFLOAT:
75             return Drawing::COLORTYPE_RGBA_F16;
76         case VK_FORMAT_R5G6B5_UNORM_PACK16:
77             return Drawing::COLORTYPE_RGB_565;
78         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
79             return Drawing::COLORTYPE_RGBA_1010102;
80         default:
81             return Drawing::COLORTYPE_RGBA_8888;
82     }
83 }
84 
WaitFence(const sptr<SyncFence> & fence)85 bool WaitFence(const sptr<SyncFence>& fence)
86 {
87     if (fence == nullptr) {
88         return false;
89     }
90     int ret = fence->Wait(FENCE_WAIT_TIME);
91     auto fenceFd = fence->Get();
92     if (ret < 0 && fenceFd != -1) {
93         return false;
94     }
95     return true;
96 }
97 #endif
98 
RSExtendImageObject(const std::shared_ptr<Drawing::Image> & image,const std::shared_ptr<Drawing::Data> & data,const Drawing::AdaptiveImageInfo & imageInfo)99 RSExtendImageObject::RSExtendImageObject(const std::shared_ptr<Drawing::Image>& image,
100     const std::shared_ptr<Drawing::Data>& data, const Drawing::AdaptiveImageInfo& imageInfo)
101 {
102     rsImage_ = std::make_shared<RSImage>();
103     rsImage_->SetImage(image);
104     rsImage_->SetCompressData(data, imageInfo.uniqueId, imageInfo.width, imageInfo.height);
105     rsImage_->SetImageFit(imageInfo.fitNum);
106     rsImage_->SetImageRepeat(imageInfo.repeatNum);
107     rsImage_->SetImageRotateDegree(imageInfo.rotateDegree);
108     std::vector<Drawing::Point> radiusValue(imageInfo.radius, imageInfo.radius + CORNER_SIZE);
109     rsImage_->SetRadius(radiusValue);
110     rsImage_->SetScale(imageInfo.scale);
111     rsImage_->SetDynamicRangeMode(imageInfo.dynamicRangeMode);
112     rsImage_->SetFitMatrix(imageInfo.fitMatrix);
113     rsImage_->SetOrientationFit(imageInfo.orientationNum);
114     imageInfo_ = imageInfo;
115 }
116 
RSExtendImageObject(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::AdaptiveImageInfo & imageInfo)117 RSExtendImageObject::RSExtendImageObject(const std::shared_ptr<Media::PixelMap>& pixelMap,
118     const Drawing::AdaptiveImageInfo& imageInfo)
119 {
120     if (pixelMap) {
121 #ifdef ROSEN_OHOS
122         if (RSSystemProperties::GetDumpUIPixelmapEnabled()) {
123             CommonTools::SavePixelmapToFile(pixelMap, "/data/storage/el1/base/imageObject_");
124         }
125 #endif
126         rsImage_ = std::make_shared<RSImage>();
127         rsImage_->SetPixelMap(pixelMap);
128         rsImage_->SetImageFit(imageInfo.fitNum);
129         rsImage_->SetImageRotateDegree(imageInfo.rotateDegree);
130         rsImage_->SetImageRepeat(imageInfo.repeatNum);
131         std::vector<Drawing::Point> radiusValue(imageInfo.radius, imageInfo.radius + CORNER_SIZE);
132         rsImage_->SetRadius(radiusValue);
133         rsImage_->SetScale(imageInfo.scale);
134         rsImage_->SetDynamicRangeMode(imageInfo.dynamicRangeMode);
135         RectF frameRect(imageInfo.frameRect.GetLeft(),
136                         imageInfo.frameRect.GetTop(),
137                         imageInfo.frameRect.GetRight(),
138                         imageInfo.frameRect.GetBottom());
139         rsImage_->SetFrameRect(frameRect);
140         rsImage_->SetFitMatrix(imageInfo.fitMatrix);
141         rsImage_->SetOrientationFit(imageInfo.orientationNum);
142     }
143 }
144 
SetNodeId(NodeId id)145 void RSExtendImageObject::SetNodeId(NodeId id)
146 {
147     if (rsImage_) {
148         rsImage_->UpdateNodeIdToPicture(id);
149     }
150     nodeId_ = id;
151 }
152 
GetNodeId() const153 NodeId RSExtendImageObject::GetNodeId() const
154 {
155     return nodeId_;
156 }
157 
SetPaint(Drawing::Paint paint)158 void RSExtendImageObject::SetPaint(Drawing::Paint paint)
159 {
160     if (rsImage_) {
161         rsImage_->SetPaint(paint);
162     }
163 }
164 
Purge()165 void RSExtendImageObject::Purge()
166 {
167     if (rsImage_) {
168         rsImage_->Purge();
169     }
170 }
171 
IsValid()172 bool RSExtendImageObject::IsValid()
173 {
174     return rsImage_ != nullptr && rsImage_->GetPixelMap() != nullptr;
175 }
176 
Dump(std::string & dump)177 void RSExtendImageObject::Dump(std::string& dump)
178 {
179     if (rsImage_ == nullptr) {
180         dump += " rsImage is nullptr";
181     } else {
182         std::string rsImageDump;
183         rsImage_->Dump(rsImageDump, 0);
184         rsImageDump.erase(
185             std::remove_if(rsImageDump.begin(),
186             rsImageDump.end(),
187             [](auto c) { return c == '\t' || c == '\n'; }),
188             rsImageDump.end()
189         );
190         dump += rsImageDump;
191     }
192 }
193 
Playback(Drawing::Canvas & canvas,const Drawing::Rect & rect,const Drawing::SamplingOptions & sampling,bool isBackground)194 void RSExtendImageObject::Playback(Drawing::Canvas& canvas, const Drawing::Rect& rect,
195     const Drawing::SamplingOptions& sampling, bool isBackground)
196 {
197 #if defined(ROSEN_OHOS) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
198     if (!rsImage_) {
199         return;
200     }
201     std::shared_ptr<Media::PixelMap> pixelmap = rsImage_->GetPixelMap();
202     bool isPurgeable = rsImage_->IsPurgeable();
203     RSImageBase::PixelMapUseCountGuard guard = {pixelmap, isPurgeable};
204     if (isPurgeable) {
205         rsImage_->DePurge();
206     }
207     if (pixelmap && pixelmap->IsAstc()) {
208         if (auto recordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas())) {
209             Drawing::AdaptiveImageInfo imageInfo = rsImage_->GetAdaptiveImageInfoWithCustomizedFrameRect(rect);
210             if (isPurgeable) {
211                 pixelmap->IncreaseUseCount();
212             }
213             recordingCanvas->DrawPixelMapWithParm(pixelmap, imageInfo, sampling);
214             return;
215         }
216     }
217     if (canvas.GetRecordingCanvas()) {
218         image_ = RSPixelMapUtil::ExtractDrawingImage(pixelmap);
219         if (image_) {
220 #ifndef ROSEN_ARKUI_X
221             SKResourceManager::Instance().HoldResource(image_);
222 #endif
223             rsImage_->SetDmaImage(image_);
224         }
225         rsImage_->CanvasDrawImage(canvas, rect, sampling, isBackground);
226         return;
227     }
228     PreProcessPixelMap(canvas, pixelmap, sampling);
229 #endif
230     rsImage_->CanvasDrawImage(canvas, rect, sampling, isBackground);
231 }
232 
Marshalling(Parcel & parcel) const233 bool RSExtendImageObject::Marshalling(Parcel &parcel) const
234 {
235     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
236     return ret;
237 }
238 
Unmarshalling(Parcel & parcel)239 RSExtendImageObject *RSExtendImageObject::Unmarshalling(Parcel &parcel)
240 {
241     auto object = new RSExtendImageObject();
242     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
243     if (!ret) {
244         delete object;
245         return nullptr;
246     }
247     if (object->rsImage_) {
248         object->rsImage_->MarkPurgeable();
249     }
250     return object;
251 }
252 
253 #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)254 void RSExtendImageObject::PreProcessPixelMap(Drawing::Canvas& canvas, const std::shared_ptr<Media::PixelMap>& pixelMap,
255     const Drawing::SamplingOptions& sampling)
256 {
257     if (!pixelMap || !rsImage_) {
258         return;
259     }
260     auto colorSpace = RSPixelMapUtil::GetPixelmapColorSpace(pixelMap);
261     RS_OPTIONAL_TRACE_NAME_FMT("RSExtendImageObject::PreProcessPixelMap pixelMap width: %d, height: %d,"
262         " colorSpaceName: %d, isHDR: %d",
263         pixelMap->GetWidth(), pixelMap->GetHeight(), pixelMap->InnerGetGrColorSpace().GetColorSpaceName(),
264         pixelMap->IsHdr());
265 #ifdef USE_VIDEO_PROCESSING_ENGINE
266     if (pixelMap->IsHdr()) {
267         colorSpace = Drawing::ColorSpace::CreateSRGB();
268     }
269 #endif
270     if (!pixelMap->IsAstc() && RSPixelMapUtil::IsSupportZeroCopy(pixelMap, sampling)) {
271 #if defined(RS_ENABLE_GL)
272         if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL &&
273             GetDrawingImageFromSurfaceBuffer(canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()))) {
274             rsImage_->SetDmaImage(image_);
275         }
276 #endif
277 #if defined(RS_ENABLE_VK)
278         if (RSSystemProperties::IsUseVukan() &&
279             GetRsImageCache(canvas, pixelMap, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()), colorSpace)) {
280             rsImage_->SetDmaImage(image_);
281         }
282 #endif
283         return;
284     }
285     if (pixelMap->IsAstc()) {
286         std::shared_ptr<Drawing::Data> fileData = std::make_shared<Drawing::Data>();
287         // After RS is switched to Vulkan, the judgment of GpuApiType can be deleted.
288         if (pixelMap->GetAllocatorType() == Media::AllocatorType::DMA_ALLOC &&
289             (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
290             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR)) {
291             if (!nativeWindowBuffer_) {
292                 sptr<SurfaceBuffer> sfBuffer(reinterpret_cast<SurfaceBuffer *>(pixelMap->GetFd()));
293                 nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
294             }
295             OH_NativeBuffer* nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(nativeWindowBuffer_);
296             if (nativeBuffer == nullptr || !fileData->BuildFromOHNativeBuffer(nativeBuffer, pixelMap->GetCapacity())) {
297                 LOGE("PreProcessPixelMap data BuildFromOHNativeBuffer fail");
298                 return;
299             }
300         } else {
301             const void* data = pixelMap->GetPixels();
302             if (pixelMap->GetCapacity() > ASTC_HEADER_SIZE &&
303                 (data == nullptr || !fileData->BuildWithoutCopy((void*)((char*) data + ASTC_HEADER_SIZE),
304                 pixelMap->GetCapacity() - ASTC_HEADER_SIZE))) {
305                 LOGE("PreProcessPixelMap data BuildWithoutCopy fail");
306                 return;
307             }
308         }
309         rsImage_->SetCompressData(fileData);
310         return;
311     }
312     if (RSPixelMapUtil::IsYUVFormat(pixelMap)) {
313         rsImage_->MarkYUVImage();
314     }
315 }
316 #endif
317 
318 #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)319 bool RSExtendImageObject::GetRsImageCache(Drawing::Canvas& canvas, const std::shared_ptr<Media::PixelMap>& pixelMap,
320     SurfaceBuffer *surfaceBuffer, const std::shared_ptr<Drawing::ColorSpace>& colorSpace)
321 {
322     if (pixelMap == nullptr) {
323         return false;
324     }
325     if (rsImage_ == nullptr) {
326         return false;
327     }
328     std::shared_ptr<Drawing::Image> imageCache = nullptr;
329     pid_t threadId = gettid();
330 #ifdef SUBTREE_PARALLEL_ENABLE
331     // Adapt to the subtree feature to ensure the correct thread ID(TID) is set.
332     RSParallelMisc::AdaptSubTreeThreadId(canvas, threadId);
333 #endif
334     if (!pixelMap->IsEditable()) {
335         imageCache = RSImageCache::Instance().GetRenderDrawingImageCacheByPixelMapId(
336             rsImage_->GetUniqueId(), threadId);
337     }
338     if (imageCache) {
339         this->image_ = imageCache;
340     } else {
341         bool ret = MakeFromTextureForVK(
342             canvas, reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()), colorSpace);
343         if (ret && image_ && !pixelMap->IsEditable()) {
344             SKResourceManager::Instance().HoldResource(image_);
345             RSImageCache::Instance().CacheRenderDrawingImageByPixelMapId(
346                 rsImage_->GetUniqueId(), image_, threadId);
347         }
348         return ret;
349     }
350     return true;
351 }
352 #endif
353 
354 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_GL)
GetDrawingImageFromSurfaceBuffer(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer)355 bool RSExtendImageObject::GetDrawingImageFromSurfaceBuffer(Drawing::Canvas& canvas, SurfaceBuffer* surfaceBuffer)
356 {
357     if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
358         return false;
359     }
360     if (surfaceBuffer == nullptr) {
361         RS_LOGE("GetDrawingImageFromSurfaceBuffer surfaceBuffer is nullptr");
362         return false;
363     }
364     if (nativeWindowBuffer_ == nullptr) {
365         sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
366         nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
367         if (!nativeWindowBuffer_) {
368             RS_LOGE("GetDrawingImageFromSurfaceBuffer create native window buffer fail");
369             return false;
370         }
371     }
372     EGLint attrs[] = {
373         EGL_IMAGE_PRESERVED,
374         EGL_TRUE,
375         EGL_NONE,
376     };
377 
378     auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
379     if (eglImage_ == EGL_NO_IMAGE_KHR) {
380         eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs);
381         if (eglImage_ == EGL_NO_IMAGE_KHR) {
382             RS_LOGE("%{public}s create egl image fail %{public}d", __func__, eglGetError());
383             return false;
384         }
385         tid_ = gettid();
386     }
387 
388     // Create texture object
389     if (texId_ == 0U) {
390         glGenTextures(1, &texId_);
391         glBindTexture(GL_TEXTURE_2D, texId_);
392         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
393         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
394         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
395         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
396         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(eglImage_));
397     }
398 
399     Drawing::TextureInfo externalTextureInfo;
400     externalTextureInfo.SetWidth(surfaceBuffer->GetWidth());
401     externalTextureInfo.SetHeight(surfaceBuffer->GetHeight());
402     externalTextureInfo.SetIsMipMapped(false);
403     externalTextureInfo.SetTarget(GL_TEXTURE_2D);
404     externalTextureInfo.SetID(texId_);
405     externalTextureInfo.SetFormat(GL_RGBA8_OES);
406 
407     Drawing::BitmapFormat bitmapFormat = {
408         Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
409     if (!canvas.GetGPUContext()) {
410         RS_LOGE("GetDrawingImageFromSurfaceBuffer gpu context is nullptr");
411         return false;
412     }
413 
414     image_ = std::make_shared<Drawing::Image>();
415     if (!image_->BuildFromTexture(*(canvas.GetGPUContext()), externalTextureInfo,
416         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat,
417         std::make_shared<Drawing::ColorSpace>(Drawing::ColorSpace::ColorSpaceType::SRGB))) {
418         RS_LOGE("BuildFromTexture failed");
419         return false;
420     }
421     return true;
422 }
423 #endif
424 
425 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
MakeFromTextureForVK(Drawing::Canvas & canvas,SurfaceBuffer * surfaceBuffer,const std::shared_ptr<Drawing::ColorSpace> & colorSpace)426 bool RSExtendImageObject::MakeFromTextureForVK(Drawing::Canvas& canvas, SurfaceBuffer *surfaceBuffer,
427     const std::shared_ptr<Drawing::ColorSpace>& colorSpace)
428 {
429     if (!RSSystemProperties::IsUseVulkan()) {
430         return false;
431     }
432     if (surfaceBuffer == nullptr || surfaceBuffer->GetBufferHandle() == nullptr) {
433         RS_LOGE("MakeFromTextureForVK surfaceBuffer is nullptr or buffer handle is nullptr");
434         return false;
435     }
436     if (nativeWindowBuffer_ == nullptr) {
437         sptr<SurfaceBuffer> sfBuffer(surfaceBuffer);
438         nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&sfBuffer);
439         if (!nativeWindowBuffer_) {
440             RS_LOGE("MakeFromTextureForVK create native window buffer fail");
441             return false;
442         }
443     }
444     if (!backendTexture_.IsValid()) {
445         backendTexture_ = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(nativeWindowBuffer_,
446             surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), false);
447         if (backendTexture_.IsValid()) {
448             auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
449             if (!vkTextureInfo) {
450                 return false;
451             }
452             cleanUpHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
453                 vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
454         } else {
455             return false;
456         }
457         tid_ = gettid();
458     }
459 
460     auto context = canvas.GetGPUContext();
461     if (!context) {
462         RS_LOGE("MakeFromTextureForVK gpu context is nullptr");
463         return false;
464     }
465     image_ = std::make_shared<Drawing::Image>();
466     auto vkTextureInfo = backendTexture_.GetTextureInfo().GetVKTextureInfo();
467     if (!vkTextureInfo || !cleanUpHelper_) {
468         return false;
469     }
470     Drawing::ColorType colorType = GetColorTypeFromVKFormat(vkTextureInfo->format);
471     Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
472     if (!image_->BuildFromTexture(*context, backendTexture_.GetTextureInfo(),
473         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, colorSpace,
474         NativeBufferUtils::DeleteVkImage,
475         cleanUpHelper_->Ref())) {
476         RS_LOGE("MakeFromTextureForVK build image failed");
477         return false;
478     }
479     return true;
480 }
481 #endif
482 
~RSExtendImageObject()483 RSExtendImageObject::~RSExtendImageObject()
484 {
485 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_GL)
486     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
487         RSTaskDispatcher::GetInstance().PostTask(tid_, [texId = texId_,
488                                                         nativeWindowBuffer = nativeWindowBuffer_,
489                                                         eglImage = eglImage_]() {
490             if (texId != 0U) {
491                 glBindTexture(GL_TEXTURE_2D, 0);
492                 glDeleteTextures(1, &texId);
493             }
494             if (nativeWindowBuffer != nullptr) {
495                 DestroyNativeWindowBuffer(nativeWindowBuffer);
496             }
497             if (eglImage != EGL_NO_IMAGE_KHR) {
498                 auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
499                 eglDestroyImageKHR(disp, eglImage);
500             }
501         });
502     }
503 #endif
504 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_VK)
505     if (RSSystemProperties::IsUseVulkan()) {
506         pid_t targetTid = RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR ? 0 : tid_;
507         RSTaskDispatcher::GetInstance().PostTask(targetTid, [nativeWindowBuffer = nativeWindowBuffer_,
508             cleanupHelper = cleanUpHelper_]() {
509             if (nativeWindowBuffer != nullptr) {
510                 DestroyNativeWindowBuffer(nativeWindowBuffer);
511             }
512             if (cleanupHelper != nullptr) {
513                 NativeBufferUtils::DeleteVkImage(cleanupHelper);
514             }
515         });
516     }
517 #endif
518 }
519 
RSExtendImageBaseObj(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::Rect & src,const Drawing::Rect & dst)520 RSExtendImageBaseObj::RSExtendImageBaseObj(const std::shared_ptr<Media::PixelMap>& pixelMap, const Drawing::Rect& src,
521     const Drawing::Rect& dst)
522 {
523     if (pixelMap) {
524         rsImage_ = std::make_shared<RSImageBase>();
525         rsImage_->SetPixelMap(pixelMap);
526         rsImage_->SetSrcRect(RectF(src.GetLeft(), src.GetTop(), src.GetWidth(), src.GetHeight()));
527         rsImage_->SetDstRect(RectF(dst.GetLeft(), dst.GetTop(), dst.GetWidth(), dst.GetHeight()));
528     }
529 }
530 
Playback(Drawing::Canvas & canvas,const Drawing::Rect & rect,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)531 void RSExtendImageBaseObj::Playback(Drawing::Canvas& canvas, const Drawing::Rect& rect,
532     const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint)
533 {
534     if (rsImage_) {
535         rsImage_->DrawImage(canvas, sampling, constraint);
536     }
537 }
538 
SetNodeId(NodeId id)539 void RSExtendImageBaseObj::SetNodeId(NodeId id)
540 {
541     if (rsImage_) {
542         rsImage_->UpdateNodeIdToPicture(id);
543     }
544 }
545 
Purge()546 void RSExtendImageBaseObj::Purge()
547 {
548     if (rsImage_) {
549         rsImage_->Purge();
550     }
551 }
552 
Marshalling(Parcel & parcel) const553 bool RSExtendImageBaseObj::Marshalling(Parcel &parcel) const
554 {
555     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
556     return ret;
557 }
558 
Unmarshalling(Parcel & parcel)559 RSExtendImageBaseObj *RSExtendImageBaseObj::Unmarshalling(Parcel &parcel)
560 {
561     auto object = new RSExtendImageBaseObj();
562     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
563     if (!ret) {
564         delete object;
565         return nullptr;
566     }
567     if (object->rsImage_) {
568         object->rsImage_->MarkPurgeable();
569     }
570     return object;
571 }
572 
RSExtendImageNineObject(const std::shared_ptr<Media::PixelMap> & pixelMap)573 RSExtendImageNineObject::RSExtendImageNineObject(const std::shared_ptr<Media::PixelMap>& pixelMap)
574 {
575     if (pixelMap) {
576         rsImage_ = std::make_shared<RSImageBase>();
577         rsImage_->SetPixelMap(pixelMap);
578     }
579 }
580 
Playback(Drawing::Canvas & canvas,const Drawing::RectI & center,const Drawing::Rect & dst,Drawing::FilterMode filterMode)581 void RSExtendImageNineObject::Playback(Drawing::Canvas& canvas, const Drawing::RectI& center,
582     const Drawing::Rect& dst, Drawing::FilterMode filterMode)
583 {
584     if (rsImage_) {
585         rsImage_->DrawImageNine(canvas, center, dst, filterMode);
586     }
587 }
588 
SetNodeId(NodeId id)589 void RSExtendImageNineObject::SetNodeId(NodeId id)
590 {
591     if (rsImage_) {
592         rsImage_->UpdateNodeIdToPicture(id);
593     }
594 }
595 
Purge()596 void RSExtendImageNineObject::Purge()
597 {
598     if (rsImage_) {
599         rsImage_->Purge();
600     }
601 }
602 
Marshalling(Parcel & parcel) const603 bool RSExtendImageNineObject::Marshalling(Parcel &parcel) const
604 {
605     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
606     return ret;
607 }
608 
Unmarshalling(Parcel & parcel)609 RSExtendImageNineObject *RSExtendImageNineObject::Unmarshalling(Parcel &parcel)
610 {
611     auto object = new RSExtendImageNineObject();
612     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
613     if (!ret) {
614         delete object;
615         return nullptr;
616     }
617     return object;
618 }
619 
RSExtendImageLatticeObject(const std::shared_ptr<Media::PixelMap> & pixelMap)620 RSExtendImageLatticeObject::RSExtendImageLatticeObject(const std::shared_ptr<Media::PixelMap>& pixelMap)
621 {
622     if (pixelMap) {
623         rsImage_ = std::make_shared<RSImageBase>();
624         rsImage_->SetPixelMap(pixelMap);
625     }
626 }
627 
Playback(Drawing::Canvas & canvas,const Drawing::Lattice & lattice,const Drawing::Rect & dst,Drawing::FilterMode filterMode)628 void RSExtendImageLatticeObject::Playback(Drawing::Canvas& canvas, const Drawing::Lattice& lattice,
629     const Drawing::Rect& dst, Drawing::FilterMode filterMode)
630 {
631     if (rsImage_) {
632         rsImage_->DrawImageLattice(canvas, lattice, dst, filterMode);
633     }
634 }
635 
SetNodeId(NodeId id)636 void RSExtendImageLatticeObject::SetNodeId(NodeId id)
637 {
638     if (rsImage_) {
639         rsImage_->UpdateNodeIdToPicture(id);
640     }
641 }
642 
Purge()643 void RSExtendImageLatticeObject::Purge()
644 {
645     if (rsImage_) {
646         rsImage_->Purge();
647     }
648 }
649 
Marshalling(Parcel & parcel) const650 bool RSExtendImageLatticeObject::Marshalling(Parcel &parcel) const
651 {
652     bool ret = RSMarshallingHelper::Marshalling(parcel, rsImage_);
653     return ret;
654 }
655 
Unmarshalling(Parcel & parcel)656 RSExtendImageLatticeObject *RSExtendImageLatticeObject::Unmarshalling(Parcel &parcel)
657 {
658     auto object = new RSExtendImageLatticeObject();
659     bool ret = RSMarshallingHelper::Unmarshalling(parcel, object->rsImage_);
660     if (!ret) {
661         delete object;
662         return nullptr;
663     }
664     return object;
665 }
666 
Playback(Drawing::Canvas * canvas,const Drawing::Rect * rect)667 void RSExtendDrawFuncObj::Playback(Drawing::Canvas* canvas, const Drawing::Rect* rect)
668 {
669     if (drawFunc_) {
670         drawFunc_(canvas, rect);
671     }
672 }
673 
Marshalling(Parcel & parcel) const674 bool RSExtendDrawFuncObj::Marshalling(Parcel &parcel) const
675 {
676     return false;
677 }
678 
Unmarshalling(Parcel & parcel)679 RSExtendDrawFuncObj *RSExtendDrawFuncObj::Unmarshalling(Parcel &parcel)
680 {
681     return nullptr;
682 }
683 
684 namespace Drawing {
685 /* DrawImageWithParmOpItem */
686 UNMARSHALLING_REGISTER(DrawImageWithParm, DrawOpItem::IMAGE_WITH_PARM_OPITEM,
687     DrawImageWithParmOpItem::Unmarshalling, sizeof(DrawImageWithParmOpItem::ConstructorHandle));
688 
DrawImageWithParmOpItem(const DrawCmdList & cmdList,DrawImageWithParmOpItem::ConstructorHandle * handle)689 DrawImageWithParmOpItem::DrawImageWithParmOpItem(
690     const DrawCmdList& cmdList, DrawImageWithParmOpItem::ConstructorHandle* handle)
691     : DrawWithPaintOpItem(cmdList, handle->paintHandle, IMAGE_WITH_PARM_OPITEM), sampling_(handle->sampling)
692 {
693     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
694 }
695 
DrawImageWithParmOpItem(const std::shared_ptr<Image> & image,const std::shared_ptr<Data> & data,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)696 DrawImageWithParmOpItem::DrawImageWithParmOpItem(const std::shared_ptr<Image>& image, const std::shared_ptr<Data>& data,
697     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
698     : DrawWithPaintOpItem(paint, IMAGE_WITH_PARM_OPITEM), sampling_(sampling)
699 {
700     objectHandle_ = std::make_shared<RSExtendImageObject>(image, data, rsImageInfo);
701 }
702 
Unmarshalling(const DrawCmdList & cmdList,void * handle)703 std::shared_ptr<DrawOpItem> DrawImageWithParmOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
704 {
705     return std::make_shared<DrawImageWithParmOpItem>(
706         cmdList, static_cast<DrawImageWithParmOpItem::ConstructorHandle*>(handle));
707 }
708 
Marshalling(DrawCmdList & cmdList)709 void DrawImageWithParmOpItem::Marshalling(DrawCmdList& cmdList)
710 {
711     PaintHandle paintHandle;
712     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
713     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
714     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle);
715 }
716 
Playback(Canvas * canvas,const Rect * rect)717 void DrawImageWithParmOpItem::Playback(Canvas* canvas, const Rect* rect)
718 {
719     if (objectHandle_ == nullptr) {
720         LOGE("DrawImageWithParmOpItem objectHandle is nullptr!");
721         return;
722     }
723     canvas->AttachPaint(paint_);
724     objectHandle_->Playback(*canvas, *rect, sampling_, false);
725 }
726 
SetNodeId(NodeId id)727 void DrawImageWithParmOpItem::SetNodeId(NodeId id)
728 {
729     if (objectHandle_ == nullptr) {
730         LOGE("DrawImageWithParmOpItem objectHandle is nullptr!");
731         return;
732     }
733     objectHandle_->SetNodeId(id);
734 }
735 
Dump(std::string & out) const736 void DrawImageWithParmOpItem::Dump(std::string& out) const
737 {
738     out += "[sampling:";
739     sampling_.Dump(out);
740     out += " objectHandle:";
741 
742     std::stringstream stream;
743     stream << std::hex << objectHandle_.get() << "]";
744     out += std::string(stream.str());
745 }
746 
747 /* DrawPixelMapWithParmOpItem */
748 UNMARSHALLING_REGISTER(DrawPixelMapWithParm, DrawOpItem::PIXELMAP_WITH_PARM_OPITEM,
749     DrawPixelMapWithParmOpItem::Unmarshalling, sizeof(DrawPixelMapWithParmOpItem::ConstructorHandle));
750 
DrawPixelMapWithParmOpItem(const DrawCmdList & cmdList,DrawPixelMapWithParmOpItem::ConstructorHandle * handle)751 DrawPixelMapWithParmOpItem::DrawPixelMapWithParmOpItem(
752     const DrawCmdList& cmdList, DrawPixelMapWithParmOpItem::ConstructorHandle* handle)
753     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_WITH_PARM_OPITEM), sampling_(handle->sampling)
754 {
755     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
756 }
757 
DrawPixelMapWithParmOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)758 DrawPixelMapWithParmOpItem::DrawPixelMapWithParmOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap,
759     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
760     : DrawWithPaintOpItem(paint, PIXELMAP_WITH_PARM_OPITEM), sampling_(sampling)
761 {
762     objectHandle_ = std::make_shared<RSExtendImageObject>(pixelMap, rsImageInfo);
763 }
764 
Unmarshalling(const DrawCmdList & cmdList,void * handle)765 std::shared_ptr<DrawOpItem> DrawPixelMapWithParmOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
766 {
767     return std::make_shared<DrawPixelMapWithParmOpItem>(
768         cmdList, static_cast<DrawPixelMapWithParmOpItem::ConstructorHandle*>(handle));
769 }
770 
Marshalling(DrawCmdList & cmdList)771 void DrawPixelMapWithParmOpItem::Marshalling(DrawCmdList& cmdList)
772 {
773     PaintHandle paintHandle;
774     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
775     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
776     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle);
777 }
778 
Playback(Canvas * canvas,const Rect * rect)779 void DrawPixelMapWithParmOpItem::Playback(Canvas* canvas, const Rect* rect)
780 {
781     if (objectHandle_ == nullptr) {
782         LOGE("DrawPixelMapWithParmOpItem objectHandle is nullptr!");
783         return;
784     }
785     objectHandle_->SetPaint(paint_);
786     canvas->AttachPaint(paint_);
787     objectHandle_->Playback(*canvas, *rect, sampling_, false);
788 }
789 
SetNodeId(NodeId id)790 void DrawPixelMapWithParmOpItem::SetNodeId(NodeId id)
791 {
792     if (objectHandle_ == nullptr) {
793         LOGE("DrawPixelMapWithParmOpItem objectHandle is nullptr!");
794         return;
795     }
796     objectHandle_->SetNodeId(id);
797 }
798 
DumpItems(std::string & out) const799 void DrawPixelMapWithParmOpItem::DumpItems(std::string& out) const
800 {
801     out += " sampling";
802     sampling_.Dump(out);
803 
804     if (objectHandle_ == nullptr) {
805         out += " objectHandle_ is nullptr";
806     } else {
807         objectHandle_->Dump(out);
808     }
809 }
810 
811 #ifdef RS_ENABLE_VK
812 /* DrawHybridPixelMapOpItem */
813 UNMARSHALLING_REGISTER(DrawHybridPixelMapOpItem, DrawOpItem::HYBRID_RENDER_PIXELMAP_OPITEM,
814     DrawHybridPixelMapOpItem::Unmarshalling, sizeof(DrawHybridPixelMapOpItem::ConstructorHandle));
815 
DrawHybridPixelMapOpItem(const DrawCmdList & cmdList,DrawHybridPixelMapOpItem::ConstructorHandle * handle)816 DrawHybridPixelMapOpItem::DrawHybridPixelMapOpItem(
817     const DrawCmdList& cmdList, DrawHybridPixelMapOpItem::ConstructorHandle* handle)
818     : DrawWithPaintOpItem(cmdList, handle->paintHandle, HYBRID_RENDER_PIXELMAP_OPITEM), sampling_(handle->sampling),
819     isRenderForeground_(handle->isRenderForeground)
820 {
821     objectHandle_ = CmdListHelper::GetImageObjectFromCmdList(cmdList, handle->objectHandle);
822     auto entry = CmdListHelper::GetSurfaceBufferEntryFromCmdList(cmdList, handle->entryId);
823     if (entry != nullptr) {
824         fence_ = entry->acquireFence_;
825     }
826 }
827 
DrawHybridPixelMapOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const AdaptiveImageInfo & rsImageInfo,const SamplingOptions & sampling,const Paint & paint)828 DrawHybridPixelMapOpItem::DrawHybridPixelMapOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap,
829     const AdaptiveImageInfo& rsImageInfo, const SamplingOptions& sampling, const Paint& paint)
830     : DrawWithPaintOpItem(paint, HYBRID_RENDER_PIXELMAP_OPITEM), sampling_(sampling)
831 {
832     objectHandle_ = std::make_shared<RSExtendImageObject>(pixelMap, rsImageInfo);
833 }
834 
Marshalling(DrawCmdList & cmdList)835 void DrawHybridPixelMapOpItem::Marshalling(DrawCmdList& cmdList)
836 {
837     PaintHandle paintHandle;
838     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
839     auto objectHandle = CmdListHelper::AddImageObjectToCmdList(cmdList, objectHandle_);
840     uint32_t entryId = CmdListHelper::AddSurfaceBufferEntryToCmdList(cmdList,
841         std::make_shared<SurfaceBufferEntry>(nullptr, fence_));
842     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, paintHandle, entryId, isRenderForeground_);
843 }
844 
Unmarshalling(const DrawCmdList & cmdList,void * handle)845 std::shared_ptr<DrawOpItem> DrawHybridPixelMapOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
846 {
847     return std::make_shared<DrawHybridPixelMapOpItem>(
848         cmdList, static_cast<DrawHybridPixelMapOpItem::ConstructorHandle*>(handle));
849 }
850 
SetNodeId(NodeId id)851 void DrawHybridPixelMapOpItem::SetNodeId(NodeId id)
852 {
853     if (objectHandle_ == nullptr) {
854         LOGE("DrawHybridPixelMapOpItem objectHandle is nullptr!");
855         return;
856     }
857     objectHandle_->SetNodeId(id);
858 }
859 
Playback(Canvas * canvas,const Rect * rect)860 void DrawHybridPixelMapOpItem::Playback(Canvas* canvas, const Rect* rect)
861 {
862     if (objectHandle_ == nullptr) {
863         LOGE("DrawHybridPixelMapOpItem objectHandle is nullptr!");
864         return;
865     }
866 
867     OHOS::Rosen::RSPaintFilterCanvas* paintCanvas = static_cast<OHOS::Rosen::RSPaintFilterCanvas*>(canvas);
868     Drawing::Filter filter;
869 
870     filter.SetColorFilter(ColorFilter::CreateBlendModeColorFilter(paintCanvas->GetEnvForegroundColor(),
871         BlendMode::SRC_ATOP));
872     paint_.SetFilter(filter);
873     if (isRenderForeground_) {
874         objectHandle_->SetPaint(paint_);
875         paintCanvas->AttachPaintWithColor(paint_);
876     } else {
877         paintCanvas->AttachPaint(paint_);
878     }
879     if (objectHandle_->IsValid() && !WaitFence(fence_)) {
880         if (auto rsExtendImageObject = static_cast<RSExtendImageObject*>(objectHandle_.get())) {
881             RS_TRACE_NAME_FMT("DrawHybridPixelMap waitfence error, nodeId: %llu", rsExtendImageObject->GetNodeId());
882             LOGW("DrawHybridPixelMap waitfence timeout, nodeId: %{public}lu", rsExtendImageObject->GetNodeId());
883         }
884     }
885     objectHandle_->Playback(*paintCanvas, *rect, sampling_, false);
886 }
887 
DumpItems(std::string & out) const888 void DrawHybridPixelMapOpItem::DumpItems(std::string& out) const
889 {
890     out += " sampling";
891     sampling_.Dump(out);
892     out += " foreground:" + std::to_string(isRenderForeground_);
893     if (fence_ != nullptr) {
894         out += " fenceFd:" + std::to_string(fence_->Get());
895     }
896 }
897 #endif
898 
899 /* DrawPixelMapRectOpItem */
900 UNMARSHALLING_REGISTER(DrawPixelMapRect, DrawOpItem::PIXELMAP_RECT_OPITEM,
901     DrawPixelMapRectOpItem::Unmarshalling, sizeof(DrawPixelMapRectOpItem::ConstructorHandle));
902 
DrawPixelMapRectOpItem(const DrawCmdList & cmdList,DrawPixelMapRectOpItem::ConstructorHandle * handle)903 DrawPixelMapRectOpItem::DrawPixelMapRectOpItem(
904     const DrawCmdList& cmdList, DrawPixelMapRectOpItem::ConstructorHandle* handle)
905     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_RECT_OPITEM), sampling_(handle->sampling),
906       constraint_(handle->constraint)
907 {
908     objectHandle_ = CmdListHelper::GetImageBaseObjFromCmdList(cmdList, handle->objectHandle);
909 }
910 
DrawPixelMapRectOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint,const Paint & paint)911 DrawPixelMapRectOpItem::DrawPixelMapRectOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap, const Rect& src,
912     const Rect& dst, const SamplingOptions& sampling, SrcRectConstraint constraint, const Paint& paint)
913     : DrawWithPaintOpItem(paint, PIXELMAP_RECT_OPITEM), sampling_(sampling), constraint_(constraint)
914 {
915     objectHandle_ = std::make_shared<RSExtendImageBaseObj>(pixelMap, src, dst);
916 }
917 
Unmarshalling(const DrawCmdList & cmdList,void * handle)918 std::shared_ptr<DrawOpItem> DrawPixelMapRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
919 {
920     return std::make_shared<DrawPixelMapRectOpItem>(
921         cmdList, static_cast<DrawPixelMapRectOpItem::ConstructorHandle*>(handle));
922 }
923 
Marshalling(DrawCmdList & cmdList)924 void DrawPixelMapRectOpItem::Marshalling(DrawCmdList& cmdList)
925 {
926     PaintHandle paintHandle;
927     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
928     auto objectHandle = CmdListHelper::AddImageBaseObjToCmdList(cmdList, objectHandle_);
929     cmdList.AddOp<ConstructorHandle>(objectHandle, sampling_, constraint_, paintHandle);
930 }
931 
Playback(Canvas * canvas,const Rect * rect)932 void DrawPixelMapRectOpItem::Playback(Canvas* canvas, const Rect* rect)
933 {
934     if (objectHandle_ == nullptr) {
935         LOGE("DrawPixelMapRectOpItem objectHandle is nullptr!");
936         return;
937     }
938     canvas->AttachPaint(paint_);
939     objectHandle_->Playback(*canvas, *rect, sampling_, constraint_);
940 }
941 
SetNodeId(NodeId id)942 void DrawPixelMapRectOpItem::SetNodeId(NodeId id)
943 {
944     if (objectHandle_ == nullptr) {
945         LOGE("DrawPixelMapRectOpItem objectHandle is nullptr!");
946         return;
947     }
948     objectHandle_->SetNodeId(id);
949 }
950 
DumpItems(std::string & out) const951 void DrawPixelMapRectOpItem::DumpItems(std::string& out) const
952 {
953     out += " sampling";
954     sampling_.Dump(out);
955 }
956 
957 /* DrawPixelMapNineOpItem */
958 UNMARSHALLING_REGISTER(DrawPixelMapNine, DrawOpItem::PIXELMAP_NINE_OPITEM,
959     DrawPixelMapNineOpItem::Unmarshalling, sizeof(DrawPixelMapNineOpItem::ConstructorHandle));
960 
DrawPixelMapNineOpItem(const DrawCmdList & cmdList,DrawPixelMapNineOpItem::ConstructorHandle * handle)961 DrawPixelMapNineOpItem::DrawPixelMapNineOpItem(
962     const DrawCmdList& cmdList, DrawPixelMapNineOpItem::ConstructorHandle* handle)
963     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_NINE_OPITEM), center_(handle->center),
964       dst_(handle->dst), filterMode_(handle->filterMode)
965 {
966     objectHandle_ = CmdListHelper::GetImageNineObjecFromCmdList(cmdList, handle->objectHandle);
967 }
968 
DrawPixelMapNineOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::RectI & center,const Drawing::Rect & dst,Drawing::FilterMode filterMode,const Paint & paint)969 DrawPixelMapNineOpItem::DrawPixelMapNineOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap,
970     const Drawing::RectI& center, const Drawing::Rect& dst, Drawing::FilterMode filterMode, const Paint& paint)
971     : DrawWithPaintOpItem(paint, PIXELMAP_NINE_OPITEM), center_(center), dst_(dst), filterMode_(filterMode)
972 {
973     objectHandle_ = std::make_shared<RSExtendImageNineObject>(pixelMap);
974 }
975 
Unmarshalling(const DrawCmdList & cmdList,void * handle)976 std::shared_ptr<DrawOpItem> DrawPixelMapNineOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
977 {
978     return std::make_shared<DrawPixelMapNineOpItem>(
979         cmdList, static_cast<DrawPixelMapNineOpItem::ConstructorHandle*>(handle));
980 }
981 
Marshalling(DrawCmdList & cmdList)982 void DrawPixelMapNineOpItem::Marshalling(DrawCmdList& cmdList)
983 {
984     PaintHandle paintHandle;
985     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
986     auto objectHandle = CmdListHelper::AddImageNineObjecToCmdList(cmdList, objectHandle_);
987     cmdList.AddOp<ConstructorHandle>(objectHandle, center_, dst_, filterMode_, paintHandle);
988 }
989 
Playback(Canvas * canvas,const Rect * rect)990 void DrawPixelMapNineOpItem::Playback(Canvas* canvas, const Rect* rect)
991 {
992     if (objectHandle_ == nullptr) {
993         LOGE("DrawPixelMapNineOpItem objectHandle is nullptr!");
994         return;
995     }
996     canvas->AttachPaint(paint_);
997     objectHandle_->Playback(*canvas, center_, dst_, filterMode_);
998 }
999 
SetNodeId(NodeId id)1000 void DrawPixelMapNineOpItem::SetNodeId(NodeId id)
1001 {
1002     if (objectHandle_ == nullptr) {
1003         LOGE("DrawPixelMapNineOpItem objectHandle is nullptr!");
1004         return;
1005     }
1006     objectHandle_->SetNodeId(id);
1007 }
1008 
DumpItems(std::string & out) const1009 void DrawPixelMapNineOpItem::DumpItems(std::string& out) const
1010 {
1011     out += " DrawPixelMapNineOpItem";
1012 }
1013 
1014 /* DrawPixelMapLatticeOpItem */
1015 UNMARSHALLING_REGISTER(DrawPixelMapLattice, DrawOpItem::PIXELMAP_LATTICE_OPITEM,
1016     DrawPixelMapLatticeOpItem::Unmarshalling, sizeof(DrawPixelMapLatticeOpItem::ConstructorHandle));
1017 
DrawPixelMapLatticeOpItem(const DrawCmdList & cmdList,DrawPixelMapLatticeOpItem::ConstructorHandle * handle)1018 DrawPixelMapLatticeOpItem::DrawPixelMapLatticeOpItem(
1019     const DrawCmdList& cmdList, DrawPixelMapLatticeOpItem::ConstructorHandle* handle)
1020     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIXELMAP_LATTICE_OPITEM),
1021       dst_(handle->dst), filterMode_(handle->filterMode)
1022 {
1023     objectHandle_ = CmdListHelper::GetImageLatticeObjecFromCmdList(cmdList, handle->objectHandle);
1024     lattice_ = CmdListHelper::GetLatticeFromCmdList(cmdList, handle->latticeHandle);
1025 }
1026 
DrawPixelMapLatticeOpItem(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::Lattice & lattice,const Drawing::Rect & dst,Drawing::FilterMode filterMode,const Paint & paint)1027 DrawPixelMapLatticeOpItem::DrawPixelMapLatticeOpItem(const std::shared_ptr<Media::PixelMap>& pixelMap,
1028     const Drawing::Lattice& lattice, const Drawing::Rect& dst, Drawing::FilterMode filterMode, const Paint& paint)
1029     : DrawWithPaintOpItem(paint, PIXELMAP_LATTICE_OPITEM), lattice_(lattice), dst_(dst), filterMode_(filterMode)
1030 {
1031     objectHandle_ = std::make_shared<RSExtendImageLatticeObject>(pixelMap);
1032 }
1033 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1034 std::shared_ptr<DrawOpItem> DrawPixelMapLatticeOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1035 {
1036     return std::make_shared<DrawPixelMapLatticeOpItem>(
1037         cmdList, static_cast<DrawPixelMapLatticeOpItem::ConstructorHandle*>(handle));
1038 }
1039 
Marshalling(DrawCmdList & cmdList)1040 void DrawPixelMapLatticeOpItem::Marshalling(DrawCmdList& cmdList)
1041 {
1042     PaintHandle paintHandle;
1043     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1044     auto objectHandle = CmdListHelper::AddImageLatticeObjecToCmdList(cmdList, objectHandle_);
1045     auto latticeHandle = CmdListHelper::AddLatticeToCmdList(cmdList, lattice_);
1046     cmdList.AddOp<ConstructorHandle>(objectHandle, latticeHandle, dst_, filterMode_, paintHandle);
1047 }
1048 
Playback(Canvas * canvas,const Rect * rect)1049 void DrawPixelMapLatticeOpItem::Playback(Canvas* canvas, const Rect* rect)
1050 {
1051     if (objectHandle_ == nullptr) {
1052         LOGE("DrawPixelMapLatticeOpItem objectHandle is nullptr!");
1053         return;
1054     }
1055     canvas->AttachPaint(paint_);
1056     objectHandle_->Playback(*canvas, lattice_, dst_, filterMode_);
1057 }
1058 
SetNodeId(NodeId id)1059 void DrawPixelMapLatticeOpItem::SetNodeId(NodeId id)
1060 {
1061     if (objectHandle_ == nullptr) {
1062         LOGE("DrawPixelMapLatticeOpItem objectHandle is nullptr!");
1063         return;
1064     }
1065     objectHandle_->SetNodeId(id);
1066 }
1067 
DumpItems(std::string & out) const1068 void DrawPixelMapLatticeOpItem::DumpItems(std::string& out) const
1069 {
1070     out += " DrawPixelMapLatticeOpItem";
1071 }
1072 
1073 /* DrawFuncOpItem */
1074 UNMARSHALLING_REGISTER(DrawFunc, DrawOpItem::DRAW_FUNC_OPITEM,
1075     DrawFuncOpItem::Unmarshalling, sizeof(DrawFuncOpItem::ConstructorHandle));
1076 
DrawFuncOpItem(const DrawCmdList & cmdList,DrawFuncOpItem::ConstructorHandle * handle)1077 DrawFuncOpItem::DrawFuncOpItem(const DrawCmdList& cmdList, DrawFuncOpItem::ConstructorHandle* handle)
1078     : DrawOpItem(DRAW_FUNC_OPITEM)
1079 {
1080     objectHandle_ = CmdListHelper::GetDrawFuncObjFromCmdList(cmdList, handle->funcObjectId);
1081 }
1082 
DrawFuncOpItem(RecordingCanvas::DrawFunc && drawFunc)1083 DrawFuncOpItem::DrawFuncOpItem(RecordingCanvas::DrawFunc&& drawFunc) : DrawOpItem(DRAW_FUNC_OPITEM)
1084 {
1085     objectHandle_ = std::make_shared<RSExtendDrawFuncObj>(std::move(drawFunc));
1086 }
1087 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1088 std::shared_ptr<DrawOpItem> DrawFuncOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1089 {
1090     if (handle == nullptr) {
1091         LOGE("Unmarshalling handle is nullptr!");
1092         return nullptr;
1093     }
1094     return std::make_shared<DrawFuncOpItem>(cmdList, static_cast<DrawFuncOpItem::ConstructorHandle*>(handle));
1095 }
1096 
Marshalling(DrawCmdList & cmdList)1097 void DrawFuncOpItem::Marshalling(DrawCmdList& cmdList)
1098 {
1099     auto objectHandle = CmdListHelper::AddDrawFuncObjToCmdList(cmdList, objectHandle_);
1100     cmdList.AddOp<ConstructorHandle>(objectHandle);
1101 }
1102 
Playback(Canvas * canvas,const Rect * rect)1103 void DrawFuncOpItem::Playback(Canvas* canvas, const Rect* rect)
1104 {
1105     if (objectHandle_) {
1106         objectHandle_->Playback(canvas, rect);
1107     }
1108 }
1109 
1110 #ifdef ROSEN_OHOS
1111 /* DrawSurfaceBufferOpItem */
1112 UNMARSHALLING_REGISTER(DrawSurfaceBuffer, DrawOpItem::SURFACEBUFFER_OPITEM,
1113     DrawSurfaceBufferOpItem::Unmarshalling, sizeof(DrawSurfaceBufferOpItem::ConstructorHandle));
1114 
DrawSurfaceBufferOpItem(const DrawCmdList & cmdList,DrawSurfaceBufferOpItem::ConstructorHandle * handle)1115 DrawSurfaceBufferOpItem::DrawSurfaceBufferOpItem(
1116     const DrawCmdList& cmdList, DrawSurfaceBufferOpItem::ConstructorHandle* handle)
1117     : DrawWithPaintOpItem(cmdList, handle->paintHandle, SURFACEBUFFER_OPITEM),
1118       surfaceBufferInfo_(nullptr, handle->surfaceBufferInfo.dstRect_.GetLeft(),
1119           handle->surfaceBufferInfo.dstRect_.GetTop(), handle->surfaceBufferInfo.dstRect_.GetWidth(),
1120           handle->surfaceBufferInfo.dstRect_.GetHeight(), handle->surfaceBufferInfo.pid_,
1121           handle->surfaceBufferInfo.uid_, nullptr, handle->surfaceBufferInfo.transform_,
1122           handle->surfaceBufferInfo.srcRect_),
1123       isNeedDrawDirectly_(!IsValidRemoteAddress(handle->surfaceBufferInfo.pid_,
1124           handle->surfaceBufferInfo.uid_))
1125 {
1126     auto surfaceBufferEntry = CmdListHelper::GetSurfaceBufferEntryFromCmdList(cmdList, handle->surfaceBufferId);
1127     if (surfaceBufferEntry) {
1128         surfaceBufferInfo_.surfaceBuffer_ = surfaceBufferEntry->surfaceBuffer_;
1129         surfaceBufferInfo_.acquireFence_ = surfaceBufferEntry->acquireFence_;
1130     }
1131 }
1132 
~DrawSurfaceBufferOpItem()1133 DrawSurfaceBufferOpItem::~DrawSurfaceBufferOpItem()
1134 {
1135     OnDestruct();
1136     Clear();
1137 }
1138 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1139 std::shared_ptr<DrawOpItem> DrawSurfaceBufferOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1140 {
1141     return std::make_shared<DrawSurfaceBufferOpItem>(cmdList,
1142         static_cast<DrawSurfaceBufferOpItem::ConstructorHandle*>(handle));
1143 }
1144 
Marshalling(DrawCmdList & cmdList)1145 void DrawSurfaceBufferOpItem::Marshalling(DrawCmdList& cmdList)
1146 {
1147     PaintHandle paintHandle;
1148     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1149     std::shared_ptr<SurfaceBufferEntry> surfaceBufferEntry =
1150         std::make_shared<SurfaceBufferEntry>(surfaceBufferInfo_.surfaceBuffer_, surfaceBufferInfo_.acquireFence_);
1151     cmdList.AddOp<ConstructorHandle>(CmdListHelper::AddSurfaceBufferEntryToCmdList(cmdList, surfaceBufferEntry),
1152         surfaceBufferInfo_.dstRect_.GetLeft(), surfaceBufferInfo_.dstRect_.GetTop(),
1153         surfaceBufferInfo_.dstRect_.GetWidth(), surfaceBufferInfo_.dstRect_.GetHeight(), surfaceBufferInfo_.pid_,
1154         surfaceBufferInfo_.uid_, surfaceBufferInfo_.transform_, surfaceBufferInfo_.srcRect_, paintHandle);
1155 }
1156 
1157 namespace {
1158     std::function<void(const DrawSurfaceBufferFinishCbData&)> surfaceBufferFinishCb;
1159     std::function<void(const DrawSurfaceBufferAfterAcquireCbData&)> surfaceBufferAfterAcquireCb;
1160     std::function<NodeId()> getRootNodeIdForRT;
1161     bool contextIsUniRender = true;
1162 }
1163 
OnDestruct()1164 void DrawSurfaceBufferOpItem::OnDestruct()
1165 {
1166     ReleaseBuffer();
1167 }
1168 
SetIsUniRender(bool isUniRender)1169 void DrawSurfaceBufferOpItem::SetIsUniRender(bool isUniRender)
1170 {
1171     contextIsUniRender = isUniRender;
1172 }
1173 
OnBeforeDraw()1174 void DrawSurfaceBufferOpItem::OnBeforeDraw()
1175 {
1176     switch (MapGraphicTransformType(surfaceBufferInfo_.transform_)) {
1177         case GraphicTransformType::GRAPHIC_ROTATE_90 :
1178             [[fallthrough]];
1179         case GraphicTransformType::GRAPHIC_ROTATE_270 : {
1180             isNeedRotateDstRect_ = true;
1181             break;
1182         }
1183         default:
1184             break;
1185     }
1186 }
1187 
OnAfterDraw()1188 void DrawSurfaceBufferOpItem::OnAfterDraw()
1189 {
1190     isRendered_ = true;
1191     if (contextIsUniRender || IsNeedDrawDirectly()) {
1192         return;
1193     }
1194     rootNodeId_ = getRootNodeIdForRT ? std::invoke(getRootNodeIdForRT) : INVALID_NODEID;
1195 #ifdef RS_ENABLE_GL
1196     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
1197         auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1198         auto sync = eglCreateSyncKHR(disp, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
1199         if (sync == EGL_NO_SYNC_KHR) {
1200             RS_LOGE("DrawSurfaceBufferOpItem::OnAfterDraw Error on eglCreateSyncKHR %{public}d",
1201                 static_cast<int>(eglGetError()));
1202             return;
1203         }
1204         auto fd = eglDupNativeFenceFDANDROID(disp, sync);
1205         eglDestroySyncKHR(disp, sync);
1206         if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
1207             RS_LOGE("DrawSurfaceBufferOpItem::OnAfterDraw: Error on eglDupNativeFenceFD");
1208             return;
1209         }
1210         releaseFence_ = new (std::nothrow) SyncFence(fd);
1211         if (!releaseFence_) {
1212             releaseFence_ = SyncFence::INVALID_FENCE;
1213         }
1214     }
1215 #endif
1216 }
1217 
ReleaseBuffer()1218 void DrawSurfaceBufferOpItem::ReleaseBuffer()
1219 {
1220     if (IsNeedDrawDirectly()) {
1221         return;
1222     }
1223     if (surfaceBufferFinishCb && surfaceBufferInfo_.surfaceBuffer_) {
1224         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::ReleaseBuffer %s Release, isNeedTriggerCbDirectly = %d",
1225             std::to_string(surfaceBufferInfo_.surfaceBuffer_->GetSeqNum()).c_str(),
1226             releaseFence_ && releaseFence_->IsValid());
1227         std::invoke(surfaceBufferFinishCb, DrawSurfaceBufferFinishCbData {
1228             .uid = surfaceBufferInfo_.uid_,
1229             .pid = surfaceBufferInfo_.pid_,
1230             .surfaceBufferId = surfaceBufferInfo_.surfaceBuffer_->GetSeqNum(),
1231             .rootNodeId = rootNodeId_,
1232             .releaseFence = releaseFence_,
1233             .isRendered = isRendered_,
1234             .isNeedTriggerCbDirectly = releaseFence_ && releaseFence_->IsValid(),
1235         });
1236     }
1237 }
1238 
OnAfterAcquireBuffer()1239 void DrawSurfaceBufferOpItem::OnAfterAcquireBuffer()
1240 {
1241     if (IsNeedDrawDirectly()) {
1242         return;
1243     }
1244     if (surfaceBufferAfterAcquireCb && surfaceBufferInfo_.surfaceBuffer_) {
1245         std::invoke(surfaceBufferAfterAcquireCb, DrawSurfaceBufferAfterAcquireCbData {
1246             .uid = surfaceBufferInfo_.uid_,
1247             .pid = surfaceBufferInfo_.pid_,
1248         });
1249     }
1250 }
1251 
RegisterSurfaceBufferCallback(DrawSurfaceBufferOpItemCb callbacks)1252 void DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback(
1253     DrawSurfaceBufferOpItemCb callbacks)
1254 {
1255     if (std::exchange(surfaceBufferFinishCb, callbacks.OnFinish)) {
1256         RS_LOGE("DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback"
1257             " registered OnFinish twice incorrectly.");
1258     }
1259     if (std::exchange(surfaceBufferAfterAcquireCb, callbacks.OnAfterAcquireBuffer)) {
1260         RS_LOGE("DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback"
1261             " registered OnAfterAcquireBuffer twice incorrectly.");
1262     }
1263 }
1264 
RegisterGetRootNodeIdFuncForRT(std::function<NodeId ()> func)1265 void DrawSurfaceBufferOpItem::RegisterGetRootNodeIdFuncForRT(std::function<NodeId()> func)
1266 {
1267     if (std::exchange(getRootNodeIdForRT, func)) {
1268         RS_LOGE("DrawSurfaceBufferOpItem::RegisterGetRootNodeIdFuncForRT"
1269             " registered OnAfterAcquireBuffer twice incorrectly.");
1270     }
1271 }
1272 
Playback(Canvas * canvas,const Rect * rect)1273 void DrawSurfaceBufferOpItem::Playback(Canvas* canvas, const Rect* rect)
1274 {
1275     if (auto recordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas->GetRecordingCanvas())) {
1276         recordingCanvas->DrawSurfaceBuffer(surfaceBufferInfo_);
1277         return;
1278     }
1279     Clear();
1280 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1281     if (surfaceBufferInfo_.surfaceBuffer_ == nullptr) {
1282         LOGE("SurfaceBufferOpItem::Draw surfaceBuffer_ is nullptr");
1283         return;
1284     }
1285     nativeWindowBuffer_ = CreateNativeWindowBufferFromSurfaceBuffer(&(surfaceBufferInfo_.surfaceBuffer_));
1286     if (!nativeWindowBuffer_) {
1287         LOGE("create nativeWindowBuffer_ fail.");
1288         return;
1289     }
1290 #endif
1291     canvas->AttachPaint(paint_);
1292     DealWithRotate(canvas);
1293     Draw(canvas);
1294 }
1295 
Clear()1296 void DrawSurfaceBufferOpItem::Clear()
1297 {
1298 #ifdef RS_ENABLE_GL
1299     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
1300         if (texId_ != 0U) {
1301             glDeleteTextures(1, &texId_);
1302         }
1303         if (eglImage_ != EGL_NO_IMAGE_KHR) {
1304             auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1305             eglDestroyImageKHR(disp, eglImage_);
1306         }
1307     }
1308 #endif
1309 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1310     if (nativeWindowBuffer_ != nullptr) {
1311         DestroyNativeWindowBuffer(nativeWindowBuffer_);
1312         nativeWindowBuffer_ = nullptr;
1313     }
1314 #endif
1315 }
1316 
DealWithRotate(Canvas * canvas)1317 void DrawSurfaceBufferOpItem::DealWithRotate(Canvas* canvas)
1318 {
1319     // The first step rotates the center of the buffer by the corresponding
1320     // number of degrees, and in the second step we translate according to
1321     // the relative coordinates.
1322     // The purpose of our translation is to align the 'upper left corner'
1323     // of the relative coordinates to ensure that after rotating the buffer,
1324     // the buffer can be drawn in the correct viewport.
1325     auto halfW = surfaceBufferInfo_.dstRect_.GetWidth() / 2.f;
1326     auto halfH = surfaceBufferInfo_.dstRect_.GetHeight() / 2.f;
1327     auto halfWHDiff = halfW - halfH;
1328     switch (MapGraphicTransformType(surfaceBufferInfo_.transform_)) {
1329         case GraphicTransformType::GRAPHIC_ROTATE_90 : {
1330             canvas->Rotate(-90,
1331                 canvas->GetTotalMatrix().Get(Drawing::Matrix::PERSP_0) + halfW,
1332                 canvas->GetTotalMatrix().Get(Drawing::Matrix::PERSP_1) + halfH);
1333             canvas->Translate(halfWHDiff, -halfWHDiff);
1334             break;
1335         }
1336         case GraphicTransformType::GRAPHIC_ROTATE_180 : {
1337             canvas->Rotate(-180,
1338                 canvas->GetTotalMatrix().Get(Drawing::Matrix::PERSP_0) + halfW,
1339                 canvas->GetTotalMatrix().Get(Drawing::Matrix::PERSP_1) + halfH);
1340             break;
1341         }
1342         case GraphicTransformType::GRAPHIC_ROTATE_270 : {
1343             canvas->Rotate(-270,
1344                 canvas->GetTotalMatrix().Get(Drawing::Matrix::PERSP_0) + halfW,
1345                 canvas->GetTotalMatrix().Get(Drawing::Matrix::PERSP_1) + halfH);
1346             canvas->Translate(halfWHDiff, -halfWHDiff);
1347             break;
1348         }
1349         default:
1350             break;
1351     }
1352 }
1353 
Draw(Canvas * canvas)1354 void DrawSurfaceBufferOpItem::Draw(Canvas* canvas)
1355 {
1356     OnBeforeDraw();
1357 #ifdef RS_ENABLE_VK
1358     if (RSSystemProperties::IsUseVulkan()) {
1359         DrawWithVulkan(canvas);
1360     }
1361 #endif
1362 #ifdef RS_ENABLE_GL
1363     if (SystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
1364         DrawWithGles(canvas);
1365     }
1366 #endif
1367     OnAfterDraw();
1368 }
1369 
CreateBitmapFormat(int32_t bufferFormat)1370 Drawing::BitmapFormat DrawSurfaceBufferOpItem::CreateBitmapFormat(int32_t bufferFormat)
1371 {
1372     switch (bufferFormat) {
1373         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBA_8888 : {
1374             return {
1375                 .colorType = Drawing::ColorType::COLORTYPE_RGBA_8888,
1376                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
1377             };
1378         }
1379         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBX_8888 : {
1380             return {
1381                 .colorType = Drawing::ColorType::COLORTYPE_RGB_888X,
1382                 .alphaType = Drawing::AlphaType::ALPHATYPE_OPAQUE,
1383             };
1384         }
1385         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_BGRA_8888 : {
1386             return {
1387                 .colorType = Drawing::ColorType::COLORTYPE_BGRA_8888,
1388                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
1389             };
1390         }
1391         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGB_565 : {
1392             return {
1393                 .colorType = Drawing::ColorType::COLORTYPE_RGB_565,
1394                 .alphaType = Drawing::AlphaType::ALPHATYPE_OPAQUE,
1395             };
1396         }
1397         case OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBA_1010102 : {
1398             return {
1399                 .colorType = Drawing::ColorType::COLORTYPE_RGBA_1010102,
1400                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
1401             };
1402         }
1403         default : {
1404             return {
1405                 .colorType = Drawing::ColorType::COLORTYPE_RGBA_8888,
1406                 .alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL,
1407             };
1408         }
1409     }
1410 }
1411 
1412 #ifdef RS_ENABLE_GL
GetGLTextureFormatByBitmapFormat(Drawing::ColorType colorType)1413 GLenum DrawSurfaceBufferOpItem::GetGLTextureFormatByBitmapFormat(Drawing::ColorType colorType)
1414 {
1415     switch (colorType) {
1416         case Drawing::ColorType::COLORTYPE_ALPHA_8 : {
1417             return GL_ALPHA8_OES;
1418         }
1419         case Drawing::ColorType::COLORTYPE_RGB_888X : {
1420             return GL_RGBA8_OES;
1421         }
1422         case Drawing::ColorType::COLORTYPE_RGB_565 : {
1423             return GL_RGB565_OES;
1424         }
1425         case Drawing::ColorType::COLORTYPE_RGBA_1010102 : {
1426             return GL_RGB10_A2_EXT;
1427         }
1428         case Drawing::ColorType::COLORTYPE_BGRA_8888 : {
1429             return GL_BGRA8_EXT;
1430         }
1431         case Drawing::ColorType::COLORTYPE_RGBA_8888 : {
1432             return GL_RGBA8_OES;
1433         }
1434         case Drawing::ColorType::COLORTYPE_RGBA_F16 : {
1435             return GL_RGBA16F_EXT;
1436         }
1437         case Drawing::ColorType::COLORTYPE_GRAY_8 :
1438             [[fallthrough]];
1439         case Drawing::ColorType::COLORTYPE_ARGB_4444 :
1440             [[fallthrough]];
1441         case Drawing::ColorType::COLORTYPE_N32 :
1442             [[fallthrough]];
1443         default : {
1444             return GL_RGBA8_OES;
1445         }
1446     }
1447 }
1448 #endif
1449 
DrawWithVulkan(Canvas * canvas)1450 void DrawSurfaceBufferOpItem::DrawWithVulkan(Canvas* canvas)
1451 {
1452 #ifdef RS_ENABLE_VK
1453     if (surfaceBufferInfo_.acquireFence_) {
1454         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::DrawWithVulkan waitfence");
1455         int res = surfaceBufferInfo_.acquireFence_->Wait(FENCE_WAIT_TIME);
1456         if (res < 0) {
1457             LOGW("DrawSurfaceBufferOpItem::DrawWithVulkan waitfence timeout");
1458         } else {
1459             OnAfterAcquireBuffer();
1460         }
1461     }
1462     auto backendTexture = NativeBufferUtils::MakeBackendTextureFromNativeBuffer(nativeWindowBuffer_,
1463         surfaceBufferInfo_.surfaceBuffer_->GetWidth(), surfaceBufferInfo_.surfaceBuffer_->GetHeight());
1464     if (!backendTexture.IsValid()) {
1465         LOGE("DrawSurfaceBufferOpItem::Draw backendTexture is not valid");
1466         return;
1467     }
1468     if (!canvas->GetGPUContext()) {
1469         LOGE("DrawSurfaceBufferOpItem::Draw gpu context is nullptr");
1470         return;
1471     }
1472     Drawing::BitmapFormat bitmapFormat = CreateBitmapFormat(surfaceBufferInfo_.surfaceBuffer_->GetFormat());
1473     auto image = std::make_shared<Drawing::Image>();
1474     auto vkTextureInfo = backendTexture.GetTextureInfo().GetVKTextureInfo();
1475     if (!vkTextureInfo || !image->BuildFromTexture(*canvas->GetGPUContext(), backendTexture.GetTextureInfo(),
1476         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr, NativeBufferUtils::DeleteVkImage,
1477         new NativeBufferUtils::VulkanCleanupHelper(
1478             RsVulkanContext::GetSingleton(), vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory))) {
1479         LOGE("DrawSurfaceBufferOpItem::Draw image BuildFromTexture failed");
1480         return;
1481     }
1482     auto rotatedRect = surfaceBufferInfo_.dstRect_;
1483     if (isNeedRotateDstRect_) {
1484         auto width = rotatedRect.GetWidth();
1485         auto height = rotatedRect.GetHeight();
1486         std::swap(width, height);
1487         rotatedRect.SetRight(rotatedRect.GetLeft() + width);
1488         rotatedRect.SetBottom(rotatedRect.GetTop() + height);
1489     }
1490     canvas->DrawImageRect(*image, surfaceBufferInfo_.srcRect_, rotatedRect,
1491         CreateSamplingOptions(canvas->GetTotalMatrix()));
1492 #endif
1493 }
1494 
DrawWithGles(Canvas * canvas)1495 void DrawSurfaceBufferOpItem::DrawWithGles(Canvas* canvas)
1496 {
1497 #ifdef RS_ENABLE_GL
1498     if (surfaceBufferInfo_.acquireFence_) {
1499         RS_TRACE_NAME_FMT("DrawSurfaceBufferOpItem::DrawWithGles waitfence");
1500         int res = surfaceBufferInfo_.acquireFence_->Wait(FENCE_WAIT_TIME);
1501         if (res < 0) {
1502             LOGW("DrawSurfaceBufferOpItem::DrawWithGles waitfence timeout");
1503         } else {
1504             OnAfterAcquireBuffer();
1505         }
1506     }
1507     if (!CreateEglTextureId()) {
1508         return;
1509     }
1510     auto rotatedRect = surfaceBufferInfo_.dstRect_;
1511     if (isNeedRotateDstRect_) {
1512         auto width = rotatedRect.GetWidth();
1513         auto height = rotatedRect.GetHeight();
1514         std::swap(width, height);
1515         rotatedRect.SetRight(rotatedRect.GetLeft() + width);
1516         rotatedRect.SetBottom(rotatedRect.GetTop() + height);
1517     }
1518 
1519     Drawing::BitmapFormat bitmapFormat = CreateBitmapFormat(surfaceBufferInfo_.surfaceBuffer_->GetFormat());
1520     Drawing::TextureInfo externalTextureInfo;
1521     externalTextureInfo.SetWidth(rotatedRect.GetWidth());
1522     externalTextureInfo.SetHeight(rotatedRect.GetHeight());
1523     externalTextureInfo.SetIsMipMapped(false);
1524     externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
1525     externalTextureInfo.SetID(texId_);
1526     externalTextureInfo.SetFormat(GetGLTextureFormatByBitmapFormat(bitmapFormat.colorType));
1527     if (!canvas->GetGPUContext()) {
1528         LOGE("DrawSurfaceBufferOpItem::Draw: gpu context is nullptr");
1529         return;
1530     }
1531     auto newImage = std::make_shared<Drawing::Image>();
1532     if (!newImage->BuildFromTexture(*canvas->GetGPUContext(), externalTextureInfo,
1533         Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr)) {
1534         LOGE("DrawSurfaceBufferOpItem::Draw: image BuildFromTexture failed");
1535         return;
1536     }
1537     canvas->DrawImage(*newImage, rotatedRect.GetLeft(), rotatedRect.GetTop(),
1538         CreateSamplingOptions(canvas->GetTotalMatrix()));
1539 #endif // RS_ENABLE_GL
1540 }
1541 
CreateSamplingOptions(const Drawing::Matrix & matrix)1542 Drawing::SamplingOptions DrawSurfaceBufferOpItem::CreateSamplingOptions(const Drawing::Matrix& matrix)
1543 {
1544     auto scaleX = matrix.Get(Drawing::Matrix::SCALE_X);
1545     auto scaleY = matrix.Get(Drawing::Matrix::SCALE_Y);
1546     auto skewX = matrix.Get(Drawing::Matrix::SKEW_X);
1547     auto skewY = matrix.Get(Drawing::Matrix::SKEW_Y);
1548     if (ROSEN_EQ(skewX, 0.0f) && ROSEN_EQ(skewY, 0.0f)) {
1549         if (!ROSEN_EQ(std::abs(scaleX), 1.0f) || !ROSEN_EQ(std::abs(scaleY), 1.0f)) {
1550             // has scale
1551             return Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
1552         }
1553     } else if (ROSEN_EQ(scaleX, 0.0f) && ROSEN_EQ(scaleY, 0.0f)) {
1554         if (!ROSEN_EQ(std::abs(skewX), 1.0f) || !ROSEN_EQ(std::abs(skewY), 1.0f)) {
1555             // has scale
1556             return Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
1557         }
1558     } else {
1559         // skew and/or non 90 degrees rotation
1560         return Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
1561     }
1562     return Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NONE);
1563 }
1564 
MapGraphicTransformType(GraphicTransformType origin)1565 GraphicTransformType DrawSurfaceBufferOpItem::MapGraphicTransformType(GraphicTransformType origin)
1566 {
1567     GraphicTransformType rotation;
1568     switch (origin) {
1569         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
1570             [[fallthrough]];
1571         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90:
1572             rotation = GraphicTransformType::GRAPHIC_ROTATE_90;
1573             break;
1574         case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
1575             [[fallthrough]];
1576         case GraphicTransformType::GRAPHIC_FLIP_V_ROT180:
1577             rotation = GraphicTransformType::GRAPHIC_ROTATE_180;
1578             break;
1579         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270:
1580             [[fallthrough]];
1581         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270:
1582             rotation = GraphicTransformType::GRAPHIC_ROTATE_270;
1583             break;
1584         default:
1585             rotation = origin;
1586             break;
1587     }
1588     return rotation;
1589 }
1590 
IsNeedDrawDirectly() const1591 bool DrawSurfaceBufferOpItem::IsNeedDrawDirectly() const
1592 {
1593     return isNeedDrawDirectly_;
1594 }
1595 
IsValidRemoteAddress(pid_t pid,uint64_t uid)1596 bool DrawSurfaceBufferOpItem::IsValidRemoteAddress(pid_t pid, uint64_t uid)
1597 {
1598     return pid != 0 && uid != 0ull;
1599 }
1600 
CreateEglTextureId()1601 bool DrawSurfaceBufferOpItem::CreateEglTextureId()
1602 {
1603 #ifdef RS_ENABLE_GL
1604     EGLint attrs[] = { EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE };
1605 
1606     auto disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1607     eglImage_ = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer_, attrs);
1608     if (eglImage_ == EGL_NO_IMAGE_KHR) {
1609         DestroyNativeWindowBuffer(nativeWindowBuffer_);
1610         nativeWindowBuffer_ = nullptr;
1611         LOGE("%{public}s create egl image fail %{public}d", __func__, eglGetError());
1612         return false;
1613     }
1614 
1615     // save
1616     GLuint originTexture;
1617     glGetIntegerv(GL_TEXTURE_BINDING_2D, reinterpret_cast<GLint *>(&originTexture));
1618     GLint minFilter;
1619     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, &minFilter);
1620     GLint magFilter;
1621     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, &magFilter);
1622     GLint wrapS;
1623     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, &wrapS);
1624     GLint wrapT;
1625     glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, &wrapT);
1626 
1627     // Create texture object
1628     texId_ = 0;
1629     glGenTextures(1, &texId_);
1630     glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId_);
1631     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1632     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1633     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1634     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1635     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(eglImage_));
1636 
1637     // restore
1638     glBindTexture(GL_TEXTURE_EXTERNAL_OES, originTexture);
1639     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
1640     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, magFilter);
1641     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, wrapS);
1642     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, wrapT);
1643 #endif
1644     return true;
1645 }
1646 
DumpItems(std::string & out) const1647 void DrawSurfaceBufferOpItem::DumpItems(std::string& out) const
1648 {
1649     out += " surfaceBufferInfo[width:" + std::to_string(surfaceBufferInfo_.dstRect_.GetWidth());
1650     out += " height:" + std::to_string(surfaceBufferInfo_.dstRect_.GetHeight());
1651     out += " offSetX:" + std::to_string(surfaceBufferInfo_.dstRect_.GetLeft());
1652     out += " offSetY:" + std::to_string(surfaceBufferInfo_.dstRect_.GetTop());
1653     out += " transform: " + std::to_string(surfaceBufferInfo_.transform_);
1654     out += "]";
1655 #ifdef RS_ENABLE_GL
1656     out += " texId:" + std::to_string(texId_);
1657 #endif
1658 }
1659 #endif
1660 }
1661 } // namespace Rosen
1662 } // namespace OHOS
1663