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