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