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