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