• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "rs_base_render_engine.h"
17 #include <memory>
18 
19 #include "v2_1/cm_color_space.h"
20 #ifdef RS_ENABLE_EGLIMAGE
21 #include "src/gpu/gl/GrGLDefines.h"
22 #endif
23 
24 #include "pipeline/render_thread/rs_divided_render_util.h"
25 #include "common/rs_optional_trace.h"
26 #include "memory/rs_tag_tracker.h"
27 #include "pipeline/rs_uni_render_judgement.h"
28 #include "platform/common/rs_log.h"
29 #include "platform/common/rs_system_properties.h"
30 #if (defined(RS_ENABLE_GPU) && defined(RS_ENABLE_GL))
31 #include "platform/ohos/backend/rs_surface_ohos_gl.h"
32 #endif
33 #include "platform/ohos/backend/rs_surface_ohos_raster.h"
34 #ifdef RS_ENABLE_VK
35 #include "platform/ohos/backend/rs_vulkan_context.h"
36 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
37 #endif
38 #ifdef USE_VIDEO_PROCESSING_ENGINE
39 #include "render/rs_colorspace_convert.h"
40 #endif
41 #include "render/rs_drawing_filter.h"
42 #include "render/rs_skia_filter.h"
43 #include "metadata_helper.h"
44 #ifdef RS_ENABLE_GPU
45 #include "drawable/rs_display_render_node_drawable.h"
46 #endif
47 
48 namespace OHOS {
49 namespace Rosen {
50 constexpr float DEFAULT_DISPLAY_NIT = 500.0f;
51 
RSBaseRenderEngine()52 RSBaseRenderEngine::RSBaseRenderEngine()
53 {
54 }
55 
~RSBaseRenderEngine()56 RSBaseRenderEngine::~RSBaseRenderEngine() noexcept
57 {
58 }
59 
Init(bool independentContext)60 void RSBaseRenderEngine::Init(bool independentContext)
61 {
62     (void)independentContext;
63 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
64     renderContext_ = std::make_shared<RenderContext>();
65 #ifdef RS_ENABLE_GL
66     if (!RSSystemProperties::IsUseVulkan()) {
67         renderContext_->InitializeEglContext();
68     }
69 #endif
70     if (RSUniRenderJudgement::IsUniRender()) {
71         RS_LOGI("RSRenderEngine::RSRenderEngine set new cacheDir");
72         renderContext_->SetUniRenderMode(true);
73     }
74 #if defined(RS_ENABLE_VK)
75     if (RSSystemProperties::IsUseVulkan()) {
76         skContext_ = RsVulkanContext::GetSingleton().CreateDrawingContext();
77         vkImageManager_ = std::make_shared<RSVkImageManager>();
78         renderContext_->SetUpGpuContext(skContext_);
79     } else {
80         renderContext_->SetUpGpuContext();
81     }
82 #else
83     renderContext_->SetUpGpuContext();
84 #endif
85 #endif // RS_ENABLE_GL || RS_ENABLE_VK
86 #if (defined(RS_ENABLE_EGLIMAGE) && defined(RS_ENABLE_GPU))
87     eglImageManager_ = std::make_shared<RSEglImageManager>(renderContext_->GetEGLDisplay());
88 #endif // RS_ENABLE_EGLIMAGE
89 #ifdef RS_ENABLE_VK
90     if (RSSystemProperties::IsUseVulkan()) {
91         skContext_ = RsVulkanContext::GetSingleton().CreateDrawingContext();
92         vkImageManager_ = std::make_shared<RSVkImageManager>();
93     }
94 #endif
95 #ifdef USE_VIDEO_PROCESSING_ENGINE
96     colorSpaceConverterDisplay_ = Media::VideoProcessingEngine::ColorSpaceConverterDisplay::Create();
97 #endif
98 }
99 
InitCapture(bool independentContext)100 void RSBaseRenderEngine::InitCapture(bool independentContext)
101 {
102 #ifdef RS_ENABLE_GPU
103     (void)independentContext;
104     if (captureRenderContext_) {
105         return;
106     }
107 #endif
108 
109 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
110     captureRenderContext_ = std::make_shared<RenderContext>();
111 #ifdef RS_ENABLE_GL
112     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
113         captureRenderContext_->InitializeEglContext();
114     }
115 #endif
116     if (RSUniRenderJudgement::IsUniRender()) {
117         captureRenderContext_->SetUniRenderMode(true);
118     }
119 #if defined(RS_ENABLE_VK)
120     if (RSSystemProperties::IsUseVulkan()) {
121         captureSkContext_ = RsVulkanContext::GetSingleton().CreateDrawingContext();
122         captureRenderContext_->SetUpGpuContext(captureSkContext_);
123     } else {
124         captureRenderContext_->SetUpGpuContext();
125     }
126 #else
127     captureRenderContext_->SetUpGpuContext();
128 #endif
129 #endif // RS_ENABLE_GL || RS_ENABLE_VK
130 }
131 
ResetCurrentContext()132 void RSBaseRenderEngine::ResetCurrentContext()
133 {
134 #ifdef RS_ENABLE_GPU
135     if (renderContext_ == nullptr) {
136         RS_LOGE("This render context is nullptr.");
137         return;
138     }
139 #endif
140 #if (defined RS_ENABLE_GL)
141     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
142         renderContext_->ShareMakeCurrentNoSurface(EGL_NO_CONTEXT);
143         if (captureRenderContext_) {
144             captureRenderContext_->ShareMakeCurrentNoSurface(EGL_NO_CONTEXT);
145         }
146     }
147 #endif
148 
149 #if defined(RS_ENABLE_VK) // end RS_ENABLE_GL and enter RS_ENABLE_VK
150     if (RSSystemProperties::IsUseVulkan()) {
151         renderContext_->AbandonContext();
152         if (captureRenderContext_) {
153             captureRenderContext_->AbandonContext();
154         }
155     }
156 #endif // end RS_ENABLE_GL and RS_ENABLE_VK
157 }
158 
NeedForceCPU(const std::vector<LayerInfoPtr> & layers)159 bool RSBaseRenderEngine::NeedForceCPU(const std::vector<LayerInfoPtr>& layers)
160 {
161     bool forceCPU = false;
162     for (const auto& layer: layers) {
163         if (layer == nullptr) {
164             continue;
165         }
166 
167         auto buffer = layer->GetBuffer();
168         if (buffer == nullptr) {
169             continue;
170         }
171 
172 #ifndef RS_ENABLE_EGLIMAGE
173         const auto bufferFormat = buffer->GetFormat();
174         if (bufferFormat == GRAPHIC_PIXEL_FMT_YCRCB_420_SP || bufferFormat == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
175             forceCPU = true;
176             break;
177         }
178 #endif
179     }
180 
181     return forceCPU;
182 }
183 
CreateEglImageFromBuffer(RSPaintFilterCanvas & canvas,const sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & acquireFence,const uint32_t threadIndex,const std::shared_ptr<Drawing::ColorSpace> & drawingColorSpace)184 std::shared_ptr<Drawing::Image> RSBaseRenderEngine::CreateEglImageFromBuffer(RSPaintFilterCanvas& canvas,
185     const sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& acquireFence, const uint32_t threadIndex,
186     const std::shared_ptr<Drawing::ColorSpace>& drawingColorSpace)
187 {
188 #if (defined(RS_ENABLE_EGLIMAGE) && defined(RS_ENABLE_GPU))
189 #if defined(RS_ENABLE_GL)
190     if (!RSSystemProperties::IsUseVulkan() && canvas.GetGPUContext() == nullptr) {
191         RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer GrContext is null!");
192         return nullptr;
193     }
194 #endif // RS_ENABLE_GL
195 #if defined(RS_ENABLE_VK)
196     if (RSSystemProperties::IsUseVulkan() && renderContext_->GetDrGPUContext() == nullptr) {
197         RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer GrContext is null!");
198         return nullptr;
199     }
200 #endif // RS_ENABLE_VK
201     auto eglTextureId = eglImageManager_->MapEglImageFromSurfaceBuffer(buffer, acquireFence, threadIndex);
202     if (eglTextureId == 0) {
203         RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer MapEglImageFromSurfaceBuffer return invalid texture ID");
204         return nullptr;
205     }
206     auto pixelFmt = buffer->GetFormat();
207     auto bitmapFormat = RSBaseRenderUtil::GenerateDrawingBitmapFormat(buffer);
208 
209     auto image = std::make_shared<Drawing::Image>();
210     Drawing::TextureInfo externalTextureInfo;
211     externalTextureInfo.SetWidth(buffer->GetSurfaceBufferWidth());
212     externalTextureInfo.SetHeight(buffer->GetSurfaceBufferHeight());
213 
214 #ifndef ROSEN_EMULATOR
215     auto surfaceOrigin = Drawing::TextureOrigin::TOP_LEFT;
216 #else
217     auto surfaceOrigin = Drawing::TextureOrigin::BOTTOM_LEFT;
218 #endif
219 
220 #if defined(RS_ENABLE_GL)
221     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
222         externalTextureInfo.SetIsMipMapped(false);
223         externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
224         externalTextureInfo.SetID(eglTextureId);
225         auto glType = GR_GL_RGBA8;
226         if (pixelFmt == GRAPHIC_PIXEL_FMT_BGRA_8888) {
227             glType = GR_GL_BGRA8;
228         } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010 || pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010 ||
229             pixelFmt == GRAPHIC_PIXEL_FMT_RGBA_1010102) {
230             glType = GR_GL_RGB10_A2;
231         }
232         externalTextureInfo.SetFormat(glType);
233         if (!image->BuildFromTexture(*canvas.GetGPUContext(), externalTextureInfo,
234             surfaceOrigin, bitmapFormat, drawingColorSpace)) {
235             RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer image BuildFromTexture failed");
236             return nullptr;
237         }
238     }
239 #endif
240 
241 #if defined(RS_ENABLE_VK)
242     if (RSSystemProperties::IsUseVulkan() &&
243         !image->BuildFromTexture(*renderContext_->GetDrGPUContext(), externalTextureInfo,
244         surfaceOrigin, bitmapFormat, drawingColorSpace)) {
245         RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer image BuildFromTexture failed");
246         return nullptr;
247     }
248 #endif
249     return image;
250 #else
251     return nullptr;
252 #endif // RS_ENABLE_EGLIMAGE
253 }
254 
RequestFrame(const std::shared_ptr<RSSurfaceOhos> & rsSurface,const BufferRequestConfig & config,bool forceCPU,bool useAFBC,const FrameContextConfig & frameContextConfig)255 std::unique_ptr<RSRenderFrame> RSBaseRenderEngine::RequestFrame(
256     const std::shared_ptr<RSSurfaceOhos>& rsSurface,
257     const BufferRequestConfig& config, bool forceCPU, bool useAFBC,
258     const FrameContextConfig& frameContextConfig)
259 {
260 #ifdef RS_ENABLE_VK
261     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
262         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
263         skContext_ = RsVulkanContext::GetSingleton().CreateDrawingContext();
264         if (renderContext_ == nullptr) {
265             return nullptr;
266         }
267         renderContext_->SetUpGpuContext(skContext_);
268     }
269 #endif
270     if (rsSurface == nullptr) {
271         RS_LOGE("RSBaseRenderEngine::RequestFrame: surface is null!");
272         return nullptr;
273     }
274     RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::RequestFrame(RSSurface)");
275 #ifdef RS_ENABLE_VK
276     RSTagTracker tagTracker(skContext_.get(), RSTagTracker::TAGTYPE::TAG_ACQUIRE_SURFACE);
277 #endif
278     rsSurface->SetColorSpace(config.colorGamut);
279     rsSurface->SetSurfacePixelFormat(config.format);
280     if (frameContextConfig.isVirtual) {
281         RS_LOGD("RSBaseRenderEngine::RequestFrame: Mirror Screen Set Timeout to 0.");
282         rsSurface->SetTimeOut(frameContextConfig.timeOut);
283     }
284     auto bufferUsage = config.usage;
285 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
286     if (forceCPU) {
287         bufferUsage |= BUFFER_USAGE_CPU_WRITE;
288     }
289 #else
290     bufferUsage |= BUFFER_USAGE_CPU_WRITE;
291 #endif
292     if (frameContextConfig.isProtected) {
293         bufferUsage |= BUFFER_USAGE_PROTECTED;
294     }
295     rsSurface->SetSurfaceBufferUsage(bufferUsage);
296 
297     // check if we can use GPU context
298 #ifdef RS_ENABLE_GL
299     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL &&
300         renderContext_ != nullptr) {
301         rsSurface->SetRenderContext(renderContext_.get());
302     }
303 #endif
304 #ifdef RS_ENABLE_VK
305     if (RSSystemProperties::IsUseVulkan() && skContext_ != nullptr) {
306         std::static_pointer_cast<RSSurfaceOhosVulkan>(rsSurface)->SetSkContext(skContext_);
307     }
308 #endif
309     auto surfaceFrame = rsSurface->RequestFrame(config.width, config.height, 0, useAFBC,
310         frameContextConfig.isProtected);
311     RS_OPTIONAL_TRACE_END();
312     if (surfaceFrame == nullptr) {
313         RS_LOGE("RSBaseRenderEngine::RequestFrame: request SurfaceFrame failed!");
314         return nullptr;
315     }
316     return std::make_unique<RSRenderFrame>(rsSurface, std::move(surfaceFrame));
317 }
318 
RequestFrame(const sptr<Surface> & targetSurface,const BufferRequestConfig & config,bool forceCPU,bool useAFBC,const FrameContextConfig & frameContextConfig)319 std::unique_ptr<RSRenderFrame> RSBaseRenderEngine::RequestFrame(const sptr<Surface>& targetSurface,
320     const BufferRequestConfig& config, bool forceCPU, bool useAFBC,
321     const FrameContextConfig& frameContextConfig)
322 {
323     RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::RequestFrame(targetSurface)");
324     if (targetSurface == nullptr) {
325         RS_LOGE("RSBaseRenderEngine::RequestFrame: surface is null!");
326         RS_OPTIONAL_TRACE_END();
327         return nullptr;
328     }
329 
330     std::shared_ptr<RSSurfaceOhos> rsSurface = nullptr;
331 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
332     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
333         if (forceCPU) {
334             rsSurface = std::make_shared<RSSurfaceOhosRaster>(targetSurface);
335         } else {
336             rsSurface = std::make_shared<RSSurfaceOhosGl>(targetSurface);
337         }
338     }
339 #endif
340 #if (defined RS_ENABLE_VK)
341     if (RSSystemProperties::IsUseVulkan()) {
342         rsSurface = std::make_shared<RSSurfaceOhosVulkan>(targetSurface);
343     }
344 #endif
345     if (rsSurface == nullptr) {
346         rsSurface = std::make_shared<RSSurfaceOhosRaster>(targetSurface);
347     }
348     RS_OPTIONAL_TRACE_END();
349     return RequestFrame(rsSurface, config, forceCPU, useAFBC, frameContextConfig);
350 }
351 
MakeRSSurface(const sptr<Surface> & targetSurface,bool forceCPU)352 std::shared_ptr<RSSurfaceOhos> RSBaseRenderEngine::MakeRSSurface(const sptr<Surface>& targetSurface, bool forceCPU)
353 {
354     RS_TRACE_FUNC();
355     if (targetSurface == nullptr) {
356         RS_LOGE("RSBaseRenderEngine::MakeRSSurface: surface is null!");
357         RS_OPTIONAL_TRACE_END();
358         return nullptr;
359     }
360 
361     std::shared_ptr<RSSurfaceOhos> rsSurface = nullptr;
362 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
363     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
364         if (forceCPU) {
365             rsSurface = std::make_shared<RSSurfaceOhosRaster>(targetSurface);
366         } else {
367             rsSurface = std::make_shared<RSSurfaceOhosGl>(targetSurface);
368         }
369     }
370 #endif
371 #if (defined RS_ENABLE_VK)
372     if (RSSystemProperties::IsUseVulkan()) {
373         rsSurface = std::make_shared<RSSurfaceOhosVulkan>(targetSurface);
374     }
375 #endif
376     if (rsSurface == nullptr) {
377         rsSurface = std::make_shared<RSSurfaceOhosRaster>(targetSurface);
378     }
379     return rsSurface;
380 }
381 
SetUiTimeStamp(const std::unique_ptr<RSRenderFrame> & renderFrame,std::shared_ptr<RSSurfaceOhos> surfaceOhos)382 void RSBaseRenderEngine::SetUiTimeStamp(const std::unique_ptr<RSRenderFrame>& renderFrame,
383     std::shared_ptr<RSSurfaceOhos> surfaceOhos)
384 {
385     if (surfaceOhos == nullptr) {
386         RS_LOGE("RSBaseRenderEngine::SetUiTimeStamp: surfaceOhos is null!");
387         return;
388     }
389 
390     if (renderFrame == nullptr) {
391         RS_LOGE("RSBaseRenderEngine::SetUiTimeStamp: renderFrame is null!.");
392         return;
393     }
394 
395     auto& frame = renderFrame->GetFrame();
396     surfaceOhos->SetUiTimeStamp(frame);
397 }
398 
DrawDisplayNodeWithParams(RSPaintFilterCanvas & canvas,RSDisplayRenderNode & node,BufferDrawParam & params)399 void RSBaseRenderEngine::DrawDisplayNodeWithParams(RSPaintFilterCanvas& canvas, RSDisplayRenderNode& node,
400     BufferDrawParam& params)
401 {
402     if (params.useCPU) {
403         DrawBuffer(canvas, params);
404     }
405 #ifdef RS_ENABLE_GPU
406     else {
407         auto drawable = node.GetRenderDrawable();
408         if (!drawable) {
409             return;
410         }
411         auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
412         RegisterDeleteBufferListener(displayDrawable->GetRSSurfaceHandlerOnDraw()->GetConsumer());
413         DrawImage(canvas, params);
414     }
415 #endif
416 }
417 
DrawDisplayNodeWithParams(RSPaintFilterCanvas & canvas,RSSurfaceHandler & surfaceHandler,BufferDrawParam & drawParam)418 void RSBaseRenderEngine::DrawDisplayNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceHandler& surfaceHandler,
419     BufferDrawParam& drawParam)
420 {
421     if (drawParam.useCPU) {
422         DrawBuffer(canvas, drawParam);
423     } else {
424         RegisterDeleteBufferListener(surfaceHandler.GetConsumer());
425         DrawImage(canvas, drawParam);
426     }
427 }
428 
SetColorFilterMode(ColorFilterMode mode)429 void RSBaseRenderEngine::SetColorFilterMode(ColorFilterMode mode)
430 {
431     std::lock_guard<std::mutex> lock(colorFilterMutex_);
432     uint32_t uMode = static_cast<uint32_t>(mode);
433     uint32_t uInvertMode = static_cast<uint32_t>(ColorFilterMode::INVERT_COLOR_ENABLE_MODE);
434     uint32_t ucolorFilterMode = static_cast<uint32_t>(colorFilterMode_);
435     bool isInvertModeEnabled = ((ucolorFilterMode & uInvertMode) == uInvertMode);
436 
437     switch (mode) {
438         case ColorFilterMode::INVERT_COLOR_DISABLE_MODE: {
439             if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
440                 colorFilterMode_ = static_cast<ColorFilterMode>(ucolorFilterMode & ~uInvertMode);
441             }
442             break;
443         }
444         case ColorFilterMode::INVERT_COLOR_ENABLE_MODE: {
445             if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
446                 colorFilterMode_ = static_cast<ColorFilterMode>(ucolorFilterMode | uInvertMode);
447             } else {
448                 colorFilterMode_ = mode;
449             }
450             break;
451         }
452         case ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE:
453         case ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE:
454         case ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE: {
455             if (isInvertModeEnabled) {
456                 colorFilterMode_ = static_cast<ColorFilterMode>(uMode | uInvertMode);
457             } else {
458                 colorFilterMode_ = mode;
459             }
460             break;
461         }
462         case ColorFilterMode::DALTONIZATION_NORMAL_MODE: {
463             if (isInvertModeEnabled) {
464                 colorFilterMode_ = ColorFilterMode::INVERT_COLOR_ENABLE_MODE;
465             } else {
466                 colorFilterMode_ = ColorFilterMode::COLOR_FILTER_END;
467             }
468             break;
469         }
470 
471         // INVERT_DALTONIZATION_PROTANOMALY_MODE, INVERT_DALTONIZATION_DEUTERANOMALY_MODE
472         // INVERT_DALTONIZATION_TRITANOMALY_MODE and COLOR_FILTER_END can not be set directly
473         case ColorFilterMode::INVERT_DALTONIZATION_PROTANOMALY_MODE: // fall-through
474         case ColorFilterMode::INVERT_DALTONIZATION_DEUTERANOMALY_MODE: // fall-through
475         case ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE: // fall-through
476         case ColorFilterMode::COLOR_FILTER_END: // fall-through
477         default: {
478             colorFilterMode_ = ColorFilterMode::COLOR_FILTER_END;
479             break;
480         }
481     }
482 }
483 
GetColorFilterMode()484 ColorFilterMode RSBaseRenderEngine::GetColorFilterMode()
485 {
486     std::lock_guard<std::mutex> lock(colorFilterMutex_);
487     return colorFilterMode_;
488 }
489 
SetHighContrast(bool enabled)490 void RSBaseRenderEngine::SetHighContrast(bool enabled)
491 {
492     isHighContrastEnabled_ = enabled;
493 }
494 
IsHighContrastEnabled()495 bool RSBaseRenderEngine::IsHighContrastEnabled()
496 {
497     return isHighContrastEnabled_;
498 }
499 
DrawBuffer(RSPaintFilterCanvas & canvas,BufferDrawParam & params)500 void RSBaseRenderEngine::DrawBuffer(RSPaintFilterCanvas& canvas, BufferDrawParam& params)
501 {
502     RS_TRACE_NAME("RSBaseRenderEngine::DrawBuffer(CPU)");
503     Drawing::Bitmap bitmap;
504     std::vector<uint8_t> newBuffer;
505     if (!RSBaseRenderUtil::ConvertBufferToBitmap(params.buffer, newBuffer, params.targetColorGamut, bitmap,
506         params.metaDatas)) {
507         RS_LOGE("RSDividedRenderUtil::DrawBuffer: create bitmap failed.");
508         return;
509     }
510     Drawing::Image drImage;
511     drImage.BuildFromBitmap(bitmap);
512     canvas.DrawImageRect(drImage, params.srcRect, params.dstRect, Drawing::SamplingOptions(),
513         Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
514 }
515 
516 #ifdef USE_VIDEO_PROCESSING_ENGINE
ConvertDrawingColorSpaceToSpaceInfo(const std::shared_ptr<Drawing::ColorSpace> & colorSpace,HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceInfo & colorSpaceInfo)517 bool RSBaseRenderEngine::ConvertDrawingColorSpaceToSpaceInfo(const std::shared_ptr<Drawing::ColorSpace>& colorSpace,
518     HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceInfo& colorSpaceInfo)
519 {
520     using namespace HDI::Display::Graphic::Common::V1_0;
521     CM_ColorSpaceType colorSpaceType = CM_COLORSPACE_NONE;
522     if (colorSpace == nullptr || colorSpace->Equals(nullptr) || colorSpace->IsSRGB()) {
523         colorSpaceType = CM_SRGB_FULL;
524     } else if (colorSpace->Equals(Drawing::ColorSpace::CreateRGB(
525         Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::DCIP3))) {
526         colorSpaceType = CM_P3_FULL;
527     } else if (colorSpace->Equals(Drawing::ColorSpace::CreateRGB(
528         Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::ADOBE_RGB))) {
529         colorSpaceType = CM_ADOBERGB_FULL;
530     } else if (colorSpace->Equals(Drawing::ColorSpace::CreateRGB(
531         Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::REC2020))) {
532         colorSpaceType = CM_DISPLAY_BT2020_SRGB;
533     } else {
534         RS_LOGD("RSBaseRenderEngine::ConvertDrawingColorSpaceToSpaceInfo color space not supported");
535         return false;
536     }
537 
538     GSError ret = MetadataHelper::ConvertColorSpaceTypeToInfo(colorSpaceType, colorSpaceInfo);
539     if (ret != GSERROR_OK) {
540         RS_LOGE("RSBaseRenderEngine::ConvertDrawingColorSpaceToSpaceInfo ConvertColorSpaceTypeToInfo failed with \
541             %{public}u.", ret);
542         return false;
543     }
544 
545     return true;
546 }
547 
GetCanvasColorSpace(const RSPaintFilterCanvas & canvas)548 std::shared_ptr<Drawing::ColorSpace> RSBaseRenderEngine::GetCanvasColorSpace(const RSPaintFilterCanvas& canvas)
549 {
550     auto surface = canvas.GetSurface();
551     if (surface == nullptr) {
552         return nullptr;
553     }
554 
555     return surface->GetImageInfo().GetColorSpace();
556 }
557 
SetColorSpaceConverterDisplayParameter(const BufferDrawParam & params,Media::VideoProcessingEngine::ColorSpaceConverterDisplayParameter & parameter)558 bool RSBaseRenderEngine::SetColorSpaceConverterDisplayParameter(
559     const BufferDrawParam& params, Media::VideoProcessingEngine::ColorSpaceConverterDisplayParameter& parameter)
560 {
561     using namespace HDI::Display::Graphic::Common::V1_0;
562 
563     CM_HDR_Metadata_Type hdrMetadataType = CM_METADATA_NONE;
564     GSError ret = MetadataHelper::GetHDRMetadataType(params.buffer, hdrMetadataType);
565     if (ret != GSERROR_OK) {
566         RS_LOGD("RSBaseRenderEngine::ColorSpaceConvertor GetHDRMetadataType failed with %{public}u.", ret);
567     }
568 
569     parameter.inputColorSpace.metadataType = hdrMetadataType;
570     parameter.outputColorSpace.metadataType = hdrMetadataType;
571 
572 #ifdef USE_VIDEO_PROCESSING_ENGINE
573     RSColorSpaceConvert::Instance().GetHDRStaticMetadata(params.buffer, parameter.staticMetadata, ret);
574     RSColorSpaceConvert::Instance().GetHDRDynamicMetadata(params.buffer, parameter.dynamicMetadata, ret);
575     RSColorSpaceConvert::Instance().GetFOVMetadata(params.buffer,
576         parameter.adaptiveFOVMetadata, ret);
577 #endif
578 
579     parameter.width = params.buffer->GetWidth();
580     parameter.height = params.buffer->GetHeight();
581     parameter.tmoNits = params.tmoNits;
582     parameter.currentDisplayNits = params.displayNits;
583     parameter.sdrNits = params.sdrNits;
584     // color temperature
585     parameter.layerLinearMatrix = params.layerLinearMatrix;
586 
587     RS_LOGD("RSBaseRenderEngine::ColorSpaceConvertor parameter inPrimaries = %{public}u, inMetadataType = %{public}u, "
588             "outPrimaries = %{public}u, outMetadataType = %{public}u, "
589             "tmoNits = %{public}.2f, currentDisplayNits = %{public}.2f, sdrNits = %{public}.2f",
590             parameter.inputColorSpace.colorSpaceInfo.primaries, parameter.inputColorSpace.metadataType,
591             parameter.outputColorSpace.colorSpaceInfo.primaries, parameter.outputColorSpace.metadataType,
592             parameter.tmoNits, parameter.currentDisplayNits, parameter.sdrNits);
593 
594     return true;
595 }
596 
ColorSpaceConvertor(std::shared_ptr<Drawing::ShaderEffect> & inputShader,BufferDrawParam & params,Media::VideoProcessingEngine::ColorSpaceConverterDisplayParameter & parameter)597 void RSBaseRenderEngine::ColorSpaceConvertor(std::shared_ptr<Drawing::ShaderEffect> &inputShader,
598     BufferDrawParam& params, Media::VideoProcessingEngine::ColorSpaceConverterDisplayParameter& parameter)
599 {
600     RS_OPTIONAL_TRACE_BEGIN("RSBaseRenderEngine::ColorSpaceConvertor");
601 
602     if (!SetColorSpaceConverterDisplayParameter(params, parameter)) {
603         RS_OPTIONAL_TRACE_END();
604         return;
605     }
606 
607     if(!inputShader) {
608         RS_LOGE("RSBaseRenderEngine::ColorSpaceConvertor inputShader is null");
609         RS_OPTIONAL_TRACE_END();
610         return;
611     }
612     if (params.isHdrRedraw) {
613         parameter.disableHdrFloatHeadRoom = true;
614     } else if (params.isHdrToSdr) {
615         parameter.sdrNits = DEFAULT_DISPLAY_NIT;
616         parameter.tmoNits = DEFAULT_DISPLAY_NIT;
617         parameter.currentDisplayNits = DEFAULT_DISPLAY_NIT;
618         parameter.layerLinearMatrix = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f};
619     }
620 
621     std::shared_ptr<Drawing::ShaderEffect> outputShader;
622     auto convRet = colorSpaceConverterDisplay_->Process(inputShader, outputShader, parameter);
623     if (convRet != Media::VideoProcessingEngine::VPE_ALGO_ERR_OK) {
624         RS_LOGE("RSBaseRenderEngine::ColorSpaceConvertor colorSpaceConverterDisplay failed with %{public}u.", convRet);
625         RS_OPTIONAL_TRACE_END();
626         return;
627     }
628     if (outputShader == nullptr) {
629         RS_LOGE("RSBaseRenderEngine::ColorSpaceConvertor outputShader is nullptr.");
630         RS_OPTIONAL_TRACE_END();
631         return;
632     }
633     params.paint.SetShaderEffect(outputShader);
634     RS_OPTIONAL_TRACE_END();
635 }
636 #endif
637 
ConvertColorGamutToDrawingColorSpace(GraphicColorGamut colorGamut)638 std::shared_ptr<Drawing::ColorSpace> RSBaseRenderEngine::ConvertColorGamutToDrawingColorSpace(
639     GraphicColorGamut colorGamut)
640 {
641     std::shared_ptr<Drawing::ColorSpace>  colorSpace = nullptr;
642     switch (colorGamut) {
643         case GRAPHIC_COLOR_GAMUT_DISPLAY_P3:
644             colorSpace = Drawing::ColorSpace::CreateRGB(
645                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::DCIP3);
646             break;
647         case GRAPHIC_COLOR_GAMUT_ADOBE_RGB:
648             colorSpace = Drawing::ColorSpace::CreateRGB(
649                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::ADOBE_RGB);
650             break;
651         case GRAPHIC_COLOR_GAMUT_BT2020:
652             colorSpace = Drawing::ColorSpace::CreateRGB(
653                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::REC2020);
654             break;
655         default:
656             colorSpace = Drawing::ColorSpace::CreateSRGB();
657             break;
658     }
659 
660     return colorSpace;
661 }
662 
ConvertColorSpaceNameToDrawingColorSpace(OHOS::ColorManager::ColorSpaceName colorSpaceName)663 std::shared_ptr<Drawing::ColorSpace> RSBaseRenderEngine::ConvertColorSpaceNameToDrawingColorSpace(
664     OHOS::ColorManager::ColorSpaceName colorSpaceName)
665 {
666     std::shared_ptr<Drawing::ColorSpace>  colorSpace = nullptr;
667     switch (colorSpaceName) {
668         case OHOS::ColorManager::ColorSpaceName::DISPLAY_P3:
669         case OHOS::ColorManager::ColorSpaceName::DCI_P3:
670             colorSpace = Drawing::ColorSpace::CreateRGB(
671                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::DCIP3);
672             break;
673         case OHOS::ColorManager::ColorSpaceName::ADOBE_RGB:
674             colorSpace = Drawing::ColorSpace::CreateRGB(
675                 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::ADOBE_RGB);
676             break;
677         default:
678             colorSpace = Drawing::ColorSpace::CreateSRGB();
679             break;
680     }
681     return colorSpace;
682 }
683 
DumpVkImageInfo(std::string & dumpString)684 void RSBaseRenderEngine::DumpVkImageInfo(std::string &dumpString)
685 {
686 #ifdef RS_ENABLE_VK
687     if (RSSystemProperties::IsUseVulkan() && vkImageManager_) {
688         vkImageManager_->DumpVkImageInfo(dumpString);
689     }
690 #else
691     (void) dumpString;
692 #endif
693 }
694 
CreateImageFromBuffer(RSPaintFilterCanvas & canvas,BufferDrawParam & params,VideoInfo & videoInfo)695 std::shared_ptr<Drawing::Image> RSBaseRenderEngine::CreateImageFromBuffer(RSPaintFilterCanvas& canvas,
696     BufferDrawParam& params, VideoInfo& videoInfo)
697 {
698     std::shared_ptr<Drawing::AutoCanvasRestore> acr = nullptr;
699     if (params.preRotation) {
700         acr = std::make_shared<Drawing::AutoCanvasRestore>(canvas, true);
701         canvas.ResetMatrix();
702     }
703 
704     auto image = std::make_shared<Drawing::Image>();
705     if (!RSBaseRenderUtil::IsBufferValid(params.buffer)) {
706         RS_LOGE("RSBaseRenderEngine::CreateImageFromBuffer invalid buffer!");
707         return nullptr;
708     }
709     videoInfo.drawingColorSpace_ = Drawing::ColorSpace::CreateSRGB();
710 #ifdef USE_VIDEO_PROCESSING_ENGINE
711     videoInfo.parameter_ = {};
712     videoInfo.retGetColorSpaceInfo_ = MetadataHelper::GetColorSpaceInfo(params.buffer,
713         videoInfo.parameter_.inputColorSpace.colorSpaceInfo);
714     if (videoInfo.retGetColorSpaceInfo_ == GSERROR_OK) {
715         videoInfo.drawingColorSpace_ = GetCanvasColorSpace(canvas);
716     }
717 #endif
718 
719 #ifdef RS_ENABLE_VK
720     if (RSSystemProperties::IsUseVulkan()) {
721         auto imageCache = vkImageManager_->MapVkImageFromSurfaceBuffer(params.buffer,
722             params.acquireFence, params.threadIndex, params.screenId);
723         if (params.buffer != nullptr && params.buffer->GetBufferDeleteFromCacheFlag()) {
724             vkImageManager_->UnMapVkImageFromSurfaceBuffer(params.buffer->GetSeqNum(), true);
725         }
726         auto bitmapFormat = RSBaseRenderUtil::GenerateDrawingBitmapFormat(params.buffer);
727 #ifndef ROSEN_EMULATOR
728         auto surfaceOrigin = Drawing::TextureOrigin::TOP_LEFT;
729 #else
730         auto surfaceOrigin = Drawing::TextureOrigin::BOTTOM_LEFT;
731 #endif
732         auto contextDrawingVk = canvas.GetGPUContext();
733         if (contextDrawingVk == nullptr || image == nullptr || imageCache == nullptr) {
734             RS_LOGE("contextDrawingVk or image or imageCache is nullptr.");
735             return nullptr;
736         }
737         auto& backendTexture = imageCache->GetBackendTexture();
738         if (!image->BuildFromTexture(*contextDrawingVk, backendTexture.GetTextureInfo(),
739             surfaceOrigin, bitmapFormat, videoInfo.drawingColorSpace_,
740             NativeBufferUtils::DeleteVkImage, imageCache->RefCleanupHelper())) {
741             ROSEN_LOGE("RSBaseRenderEngine::CreateImageFromBuffer: backendTexture is not valid!!!");
742             return nullptr;
743         }
744     }
745 #endif // RS_ENABLE_VK
746 
747 #ifdef RS_ENABLE_GL // RS_ENABLE_GL
748     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
749         image = CreateEglImageFromBuffer(canvas, params.buffer, params.acquireFence, params.threadIndex,
750             videoInfo.drawingColorSpace_);
751         if (image == nullptr) {
752             RS_LOGE("RSBaseRenderEngine::CreateImageFromBuffer: image is nullptr!");
753             return nullptr;
754         }
755     }
756 #endif // RS_ENABLE_GL
757     return image;
758 }
759 
DrawImage(RSPaintFilterCanvas & canvas,BufferDrawParam & params)760 void RSBaseRenderEngine::DrawImage(RSPaintFilterCanvas& canvas, BufferDrawParam& params)
761 {
762     RS_TRACE_NAME_FMT("RSBaseRenderEngine::DrawImage(GPU) targetColorGamut=%d", params.targetColorGamut);
763     RSMainThread::GPUCompositonCacheGuard guard;
764     VideoInfo videoInfo;
765     auto image = CreateImageFromBuffer(canvas, params, videoInfo);
766     if (image == nullptr) {
767         return;
768     }
769     Drawing::SamplingOptions samplingOptions;
770     if (!RSSystemProperties::GetUniRenderEnabled()) {
771         samplingOptions = Drawing::SamplingOptions();
772     } else {
773         if (params.isMirror) {
774             samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST);
775         } else {
776             samplingOptions = NeedBilinearInterpolation(params, canvas.GetTotalMatrix())
777                                   ? Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE)
778                                   : Drawing::SamplingOptions();
779         }
780     }
781 
782     if (params.targetColorGamut == GRAPHIC_COLOR_GAMUT_SRGB) {
783         canvas.AttachBrush(params.paint);
784         canvas.DrawImageRect(*image, params.srcRect, params.dstRect, samplingOptions,
785             Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
786         canvas.DetachBrush();
787     } else {
788 #ifdef USE_VIDEO_PROCESSING_ENGINE
789 
790     // For sdr brightness ratio
791     if (ROSEN_LNE(params.brightnessRatio, DEFAULT_BRIGHTNESS_RATIO) && !params.isHdrRedraw) {
792         Drawing::Filter filter = params.paint.GetFilter();
793         Drawing::ColorMatrix luminanceMatrix;
794         luminanceMatrix.SetScale(params.brightnessRatio, params.brightnessRatio, params.brightnessRatio, 1.0f);
795         auto luminanceColorFilter =
796             std::make_shared<Drawing::ColorFilter>(Drawing::ColorFilter::FilterType::MATRIX, luminanceMatrix);
797         filter.SetColorFilter(luminanceColorFilter);
798         params.paint.SetFilter(filter);
799     }
800 
801     if (videoInfo.retGetColorSpaceInfo_ != GSERROR_OK) {
802         RS_LOGD("RSBaseRenderEngine::DrawImage GetColorSpaceInfo failed with %{public}u.",
803             videoInfo.retGetColorSpaceInfo_);
804         DrawImageRect(canvas, image, params, samplingOptions);
805         return;
806     }
807 
808     Media::VideoProcessingEngine::CM_ColorSpaceInfo& inClrInfo = videoInfo.parameter_.inputColorSpace.colorSpaceInfo;
809     Media::VideoProcessingEngine::CM_ColorSpaceInfo& outClrInfo = videoInfo.parameter_.outputColorSpace.colorSpaceInfo;
810     if (!ConvertDrawingColorSpaceToSpaceInfo(videoInfo.drawingColorSpace_, outClrInfo)) {
811         RS_LOGD("RSBaseRenderEngine::DrawImage ConvertDrawingColorSpaceToSpaceInfo failed");
812         DrawImageRect(canvas, image, params, samplingOptions);
813         return;
814     }
815 
816     if (inClrInfo.primaries == outClrInfo.primaries && inClrInfo.transfunc == outClrInfo.transfunc &&
817         !params.hasMetadata) {
818         RS_LOGD("RSBaseRenderEngine::DrawImage primaries and transfunc equal with no metadata.");
819         DrawImageRect(canvas, image, params, samplingOptions);
820         return;
821     }
822 
823     // HDR to SDR, all xxxNits reset to 500, layerLinearMatrix reset to 3x3 Identity matrix
824     params.isHdrToSdr = canvas.IsOnMultipleScreen() || (!canvas.GetHdrOn() && !params.hasMetadata) ||
825         !RSSystemProperties::GetHdrVideoEnabled();
826 
827     Drawing::Matrix matrix;
828     auto srcWidth = params.srcRect.GetWidth();
829     auto srcHeight = params.srcRect.GetHeight();
830     auto sx = params.dstRect.GetWidth() / srcWidth;
831     auto sy = params.dstRect.GetHeight() / srcHeight;
832     auto tx = params.dstRect.GetLeft() - params.srcRect.GetLeft() * sx;
833     auto ty = params.dstRect.GetTop() - params.srcRect.GetTop() * sy;
834     if (ROSEN_EQ(srcWidth, 0.0f) || ROSEN_EQ(srcHeight, 0.0f)) {
835         RS_LOGE("RSBaseRenderEngine::DrawImage image srcRect params invalid.");
836     }
837     matrix.SetScaleTranslate(sx, sy, tx, ty);
838     auto imageShader = Drawing::ShaderEffect::CreateImageShader(
839         *image, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, samplingOptions, matrix);
840     if (imageShader == nullptr) {
841         RS_LOGW("RSBaseRenderEngine::DrawImage imageShader is nullptr.");
842     } else {
843         params.paint.SetShaderEffect(imageShader);
844         ColorSpaceConvertor(imageShader, params, videoInfo.parameter_);
845     }
846     canvas.AttachBrush(params.paint);
847     canvas.DrawRect(params.dstRect);
848     canvas.DetachBrush();
849 #else
850     DrawImageRect(canvas, image, params, samplingOptions);
851 #endif // USE_VIDEO_PROCESSING_ENGINE
852     }
853 }
854 
DrawImageRect(RSPaintFilterCanvas & canvas,std::shared_ptr<Drawing::Image> image,BufferDrawParam & params,Drawing::SamplingOptions & samplingOptions)855 void RSBaseRenderEngine::DrawImageRect(RSPaintFilterCanvas& canvas, std::shared_ptr<Drawing::Image> image,
856     BufferDrawParam& params, Drawing::SamplingOptions& samplingOptions)
857 {
858     canvas.AttachBrush(params.paint);
859     canvas.DrawImageRect(*image, params.srcRect, params.dstRect, samplingOptions,
860         Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
861     canvas.DetachBrush();
862 }
863 
NeedBilinearInterpolation(const BufferDrawParam & params,const Drawing::Matrix & matrix)864 bool RSBaseRenderEngine::NeedBilinearInterpolation(const BufferDrawParam& params, const Drawing::Matrix& matrix)
865 {
866     if (!params.useBilinearInterpolation) {
867         return false;
868     }
869     if (!ROSEN_EQ(params.dstRect.GetWidth(), params.srcRect.GetWidth()) ||
870         !ROSEN_EQ(params.dstRect.GetHeight(), params.srcRect.GetHeight())) {
871         return true;
872     }
873     auto scaleX = matrix.Get(Drawing::Matrix::SCALE_X);
874     auto scaleY = matrix.Get(Drawing::Matrix::SCALE_Y);
875     auto skewX = matrix.Get(Drawing::Matrix::SKEW_X);
876     auto skewY = matrix.Get(Drawing::Matrix::SKEW_Y);
877     if (ROSEN_EQ(skewX, 0.0f) && ROSEN_EQ(skewY, 0.0f)) {
878         if (!ROSEN_EQ(std::abs(scaleX), 1.0f) || !ROSEN_EQ(std::abs(scaleY), 1.0f)) {
879             // has scale
880             return true;
881         }
882     } else if (ROSEN_EQ(scaleX, 0.0f) && ROSEN_EQ(scaleY, 0.0f)) {
883         if (!ROSEN_EQ(std::abs(skewX), 1.0f) || !ROSEN_EQ(std::abs(skewY), 1.0f)) {
884             // has scale
885             return true;
886         }
887     } else {
888         // skew and/or non 90 degrees rotation
889         return true;
890     }
891     return false;
892 }
893 
RegisterDeleteBufferListener(const sptr<IConsumerSurface> & consumer,bool isForUniRedraw)894 void RSBaseRenderEngine::RegisterDeleteBufferListener(const sptr<IConsumerSurface>& consumer, bool isForUniRedraw)
895 {
896 #ifdef RS_ENABLE_VK
897     if (RSSystemProperties::IsUseVulkan()) {
898         auto regUnMapVkImageFunc = [this, isForUniRedraw](int32_t bufferId) {
899             RSMainThread::Instance()->AddToUnmappedCacheSet(bufferId);
900             RSMainThread::Instance()->AddToUnmappedMirrorCacheSet(bufferId);
901         };
902         if (consumer == nullptr ||
903             (consumer->RegisterDeleteBufferListener(regUnMapVkImageFunc, isForUniRedraw) != GSERROR_OK)) {
904             RS_LOGE("RSBaseRenderEngine::RegisterDeleteBufferListener: failed to register UnMapVkImage callback.");
905         }
906         return;
907     }
908 #endif // #ifdef RS_ENABLE_VK
909 
910 #if (defined(RS_ENABLE_EGLIMAGE) && defined(RS_ENABLE_GPU))
911     auto regUnMapEglImageFunc = [this, isForUniRedraw](int32_t bufferId) {
912         RSMainThread::Instance()->AddToUnmappedCacheSet(bufferId);
913     };
914     if (consumer == nullptr ||
915         (consumer->RegisterDeleteBufferListener(regUnMapEglImageFunc, isForUniRedraw) != GSERROR_OK)) {
916         RS_LOGE("RSBaseRenderEngine::RegisterDeleteBufferListener: failed to register UnMapEglImage callback.");
917     }
918 #endif // #ifdef RS_ENABLE_EGLIMAGE
919 }
920 
RegisterDeleteBufferListener(RSSurfaceHandler & handler)921 void RSBaseRenderEngine::RegisterDeleteBufferListener(RSSurfaceHandler& handler)
922 {
923 #ifdef RS_ENABLE_VK
924     if (RSSystemProperties::IsUseVulkan()) {
925         auto regUnMapVkImageFunc = [this](int32_t bufferId) {
926             RSMainThread::Instance()->AddToUnmappedCacheSet(bufferId);
927         };
928         handler.RegisterDeleteBufferListener(regUnMapVkImageFunc);
929         return;
930     }
931 #endif // #ifdef RS_ENABLE_VK
932 
933 #if (defined(RS_ENABLE_EGLIMAGE) && defined(RS_ENABLE_GPU))
934     auto regUnMapEglImageFunc = [this](int32_t bufferId) {
935         RSMainThread::Instance()->AddToUnmappedCacheSet(bufferId);
936     };
937     handler.RegisterDeleteBufferListener(regUnMapEglImageFunc);
938 #endif // #ifdef RS_ENABLE_EGLIMAGE
939 }
940 
ShrinkCachesIfNeeded(bool isForUniRedraw)941 void RSBaseRenderEngine::ShrinkCachesIfNeeded(bool isForUniRedraw)
942 {
943 #ifdef RS_ENABLE_VK
944     if (RSSystemProperties::IsUseVulkan()) {
945         if (vkImageManager_ != nullptr) {
946             vkImageManager_->ShrinkCachesIfNeeded();
947         }
948         return;
949     }
950 #endif // RS_ENABLE_VK
951 
952 #if (defined(RS_ENABLE_EGLIMAGE) && defined(RS_ENABLE_GPU))
953     if (eglImageManager_ != nullptr) {
954         eglImageManager_->ShrinkCachesIfNeeded(isForUniRedraw);
955     }
956 #endif // RS_ENABLE_EGLIMAGE
957 }
958 
ClearCacheSet(const std::set<uint32_t> & unmappedCache,bool isMatchVirtualScreen)959 void RSBaseRenderEngine::ClearCacheSet(const std::set<uint32_t>& unmappedCache, bool isMatchVirtualScreen)
960 {
961 #ifdef RS_ENABLE_VK
962     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
963         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
964         if (vkImageManager_ != nullptr) {
965             for (auto id : unmappedCache) {
966                 vkImageManager_->UnMapVkImageFromSurfaceBuffer(id, isMatchVirtualScreen);
967             }
968         }
969     }
970 #endif // RS_ENABLE_VK
971 
972 #if (defined(RS_ENABLE_EGLIMAGE) && defined(RS_ENABLE_GPU))
973     if (eglImageManager_ != nullptr) {
974         for (auto id : unmappedCache) {
975             eglImageManager_->UnMapEglImageFromSurfaceBuffer(id);
976         }
977     }
978 #endif // RS_ENABLE_EGLIMAGE
979 }
980 
ClearVirtualScreenCacheSet()981 void RSBaseRenderEngine::ClearVirtualScreenCacheSet()
982 {
983 #ifdef RS_ENABLE_VK
984     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
985         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
986         if (vkImageManager_ != nullptr) {
987             vkImageManager_->UnMapAllVkImageVirtualScreenCache();
988         }
989     }
990 #endif // RS_ENABLE_VK
991 }
992 } // namespace Rosen
993 } // namespace OHOS
994