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