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 #ifndef RS_CORE_PIPELINE_BASE_RENDER_ENGINE_H
17 #define RS_CORE_PIPELINE_BASE_RENDER_ENGINE_H
18 
19 #include <memory>
20 
21 #include "hdi_layer_info.h"
22 #include "pipeline/rs_paint_filter_canvas.h"
23 #include "pipeline/rs_display_render_node.h"
24 #include "pipeline/rs_surface_render_node.h"
25 #ifdef RS_ENABLE_VK
26 #include "rs_vk_image_manager.h"
27 #endif
28 #include "include/gpu/GrDirectContext.h"
29 #include "rs_base_render_util.h"
30 
31 #ifdef NEW_RENDER_CONTEXT
32 #include "render_backend/rs_render_surface_frame.h"
33 #include "ohos/rs_render_surface_ohos.h"
34 #include "render_context_base.h"
35 #else
36 #include "platform/drawing/rs_surface_frame.h"
37 #include "platform/ohos/rs_surface_ohos.h"
38 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
39 #include "render_context/render_context.h"
40 #endif // RS_ENABLE_GL || RS_ENABLE_VK
41 #endif
42 #ifdef RS_ENABLE_EGLIMAGE
43 #include "rs_egl_image_manager.h"
44 #endif // RS_ENABLE_EGLIMAGE
45 #ifdef USE_VIDEO_PROCESSING_ENGINE
46 #include "colorspace_converter_display.h"
47 #endif
48 
49 namespace OHOS {
50 namespace Rosen {
51 namespace DrawableV2 {
52 class RSDisplayRenderNodeDrawable;
53 class RSSurfaceRenderNodeDrawable;
54 }
55 struct FrameContextConfig {
56 public:
FrameContextConfigFrameContextConfig57     FrameContextConfig(bool isProtected, bool independentContext)
58     {
59         this->isProtected = isProtected;
60         this->independentContext = independentContext;
61     }
62     bool isProtected = false;
63     bool independentContext = false;
64     bool isVirtual = false;
65     int32_t timeOut = 3000; // ms
66 };
67 // The RenderFrame can do auto flush
68 class RSRenderFrame {
69 public:
70     // we guarantee when constructing this object, all parameters are valid.
71 #ifdef NEW_RENDER_CONTEXT
RSRenderFrame(const std::shared_ptr<RSRenderSurfaceOhos> & target)72     explicit RSRenderFrame(const std::shared_ptr<RSRenderSurfaceOhos>& target)
73         : targetSurface_(target)
74     {
75     }
76 #else
77     RSRenderFrame(const std::shared_ptr<RSSurfaceOhos>& target, std::unique_ptr<RSSurfaceFrame>&& frame)
78         : targetSurface_(target), surfaceFrame_(std::move(frame))
79     {
80     }
81 #endif
~RSRenderFrame()82     ~RSRenderFrame() noexcept
83     {
84         Flush();
85     }
86 
87     // noncopyable
88     RSRenderFrame(const RSRenderFrame&) = delete;
89     void operator=(const RSRenderFrame&) = delete;
90 #ifdef NEW_RENDER_CONTEXT
Flush()91     void Flush() noexcept
92     {
93         if (targetSurface_ != nullptr) {
94             targetSurface_->FlushFrame();
95             targetSurface_ = nullptr;
96         }
97     }
98 #else
Flush()99     void Flush() noexcept
100     {
101         if (targetSurface_ != nullptr && surfaceFrame_ != nullptr) {
102             targetSurface_->FlushFrame(surfaceFrame_);
103             targetSurface_ = nullptr;
104             surfaceFrame_ = nullptr;
105         }
106     }
107 #endif
108 #ifdef NEW_RENDER_CONTEXT
GetSurface()109     const std::shared_ptr<RSRenderSurfaceOhos>& GetSurface() const
110 #else
111     const std::shared_ptr<RSSurfaceOhos>& GetSurface() const
112 #endif
113     {
114         return targetSurface_;
115     }
116 #ifndef NEW_RENDER_CONTEXT
GetFrame()117     const std::unique_ptr<RSSurfaceFrame>& GetFrame() const
118     {
119         return surfaceFrame_;
120     }
121 #endif
GetCanvas()122     std::unique_ptr<RSPaintFilterCanvas> GetCanvas()
123     {
124 #ifdef NEW_RENDER_CONTEXT
125         return std::make_unique<RSPaintFilterCanvas>(targetSurface_->GetSurface().get());
126 #else
127         return std::make_unique<RSPaintFilterCanvas>(surfaceFrame_->GetSurface().get());
128 #endif
129     }
130 
GetBufferAge()131     int32_t GetBufferAge()
132     {
133 #ifdef NEW_RENDER_CONTEXT
134         return targetSurface_ != nullptr ? targetSurface_->GetBufferAge() : 0;
135 #else
136         return surfaceFrame_ != nullptr ? surfaceFrame_->GetBufferAge() : 0;
137 #endif
138     }
139 
SetDamageRegion(const std::vector<RectI> & rects)140     void SetDamageRegion(const std::vector<RectI> &rects)
141     {
142 #ifdef NEW_RENDER_CONTEXT
143         if (targetSurface_ != nullptr) {
144             targetSurface_ ->SetDamageRegion(rects);
145         }
146 #else
147         if (surfaceFrame_ != nullptr) {
148             surfaceFrame_->SetDamageRegion(rects);
149         }
150 #endif
151     }
152 private:
153 #ifdef NEW_RENDER_CONTEXT
154     std::shared_ptr<RSRenderSurfaceOhos> targetSurface_;
155 #else
156     std::shared_ptr<RSSurfaceOhos> targetSurface_;
157     std::unique_ptr<RSSurfaceFrame> surfaceFrame_;
158 #endif
159 };
160 
161 // function that will be called before drawing Buffer / Image.
162 using PreProcessFunc = std::function<void(RSPaintFilterCanvas&, BufferDrawParam&)>;
163 // function that will be called after drawing Buffer / Image.
164 using PostProcessFunc = std::function<void(RSPaintFilterCanvas&, BufferDrawParam&)>;
165 
166 // This render engine aims to do the client composition for all surfaces that hardware can't handle.
167 class RSBaseRenderEngine {
168 public:
169     RSBaseRenderEngine();
170     virtual ~RSBaseRenderEngine() noexcept;
171     void Init(bool independentContext = false);
172     void InitCapture(bool independentContext = false);
173     RSBaseRenderEngine(const RSBaseRenderEngine&) = delete;
174     void operator=(const RSBaseRenderEngine&) = delete;
175 
176     // [PLANNING]: this is a work-around for the lack of colorgamut conversion and yuv support in GPU.
177     // We should remove this function in someday.
178     static bool NeedForceCPU(const std::vector<LayerInfoPtr>& layers);
179 
180     // There would only one user(thread) to renderFrame(request frame) at one time.
181     // for framebuffer surface
182     std::unique_ptr<RSRenderFrame> RequestFrame(const sptr<Surface>& targetSurface,
183         const BufferRequestConfig& config, bool forceCPU = false, bool useAFBC = true,
184         const FrameContextConfig& frameContextConfig = {false, false});
185 
186     // There would only one user(thread) to renderFrame(request frame) at one time.
187 #ifdef NEW_RENDER_CONTEXT
188     std::unique_ptr<RSRenderFrame> RequestFrame(const std::shared_ptr<RSRenderSurfaceOhos>& rsSurface,
189         const BufferRequestConfig& config, bool forceCPU = false, bool useAFBC = true,
190         const FrameContextConfig& frameContextConfig = {false, false});
191     std::shared_ptr<RSRenderSurfaceOhos> MakeRSSurface(const sptr<Surface>& targetSurface, bool forceCPU);
192     void SetUiTimeStamp(const std::unique_ptr<RSRenderFrame>& renderFrame,
193         std::shared_ptr<RSRenderSurfaceOhos> surfaceOhos);
194 #else
195     std::unique_ptr<RSRenderFrame> RequestFrame(const std::shared_ptr<RSSurfaceOhos>& rsSurface,
196         const BufferRequestConfig& config, bool forceCPU = false, bool useAFBC = true,
197         const FrameContextConfig& frameContextConfig = {false, false});
198     std::shared_ptr<RSSurfaceOhos> MakeRSSurface(const sptr<Surface>& targetSurface, bool forceCPU);
199     void SetUiTimeStamp(const std::unique_ptr<RSRenderFrame>& renderFrame,
200         std::shared_ptr<RSSurfaceOhos> surfaceOhos);
201 #endif
202 
203     virtual void DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
204         BufferDrawParam& params, PreProcessFunc preProcess = nullptr, PostProcessFunc postProcess = nullptr) = 0;
205     virtual void DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas,
206         DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, BufferDrawParam& params,
207         PreProcessFunc preProcess = nullptr, PostProcessFunc postProcess = nullptr) {}
208 
209     virtual void DrawUIFirstCacheWithParams(RSPaintFilterCanvas& canvas, BufferDrawParam& params) = 0;
210 
211     void DrawDisplayNodeWithParams(RSPaintFilterCanvas& canvas, RSDisplayRenderNode& node,
212         BufferDrawParam& params);
213     void DrawDisplayNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceHandler& surfaceHandler,
214         BufferDrawParam& drawParam);
215     void RegisterDeleteBufferListener(const sptr<IConsumerSurface>& consumer, bool isForUniRedraw = false);
216     void RegisterDeleteBufferListener(RSSurfaceHandler& handler);
217 
218 #ifdef USE_VIDEO_PROCESSING_ENGINE
219     virtual void DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU = false,
220         const ScreenInfo& screenInfo = {}, GraphicColorGamut colorGamut = GRAPHIC_COLOR_GAMUT_SRGB) = 0;
221 #else
222     virtual void DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU = false,
223         const ScreenInfo& screenInfo = {}) = 0;
224 #endif
225 
226     static void DrawBuffer(RSPaintFilterCanvas& canvas, BufferDrawParam& params);
227 
228     void ShrinkCachesIfNeeded(bool isForUniRedraw = false);
229     void ClearCacheSet(const std::set<int32_t> unmappedCache);
230     static void SetColorFilterMode(ColorFilterMode mode);
231     static ColorFilterMode GetColorFilterMode();
232     static void SetHighContrast(bool enabled);
233     static bool IsHighContrastEnabled();
234 
235 #if defined(NEW_RENDER_CONTEXT)
GetRenderContext()236     const std::shared_ptr<RenderContextBase>& GetRenderContext() const
237     {
238         return renderContext_;
239     }
GetDrawingContext()240     const std::shared_ptr<DrawingContext>& GetDrawingContext() const
241     {
242         return drawingContext_;
243     }
244 #else
245 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
GetRenderContext()246     const std::shared_ptr<RenderContext>& GetRenderContext()
247     {
248         return renderContext_;
249     }
GetCaptureRenderContext()250     const std::shared_ptr<RenderContext>& GetCaptureRenderContext()
251     {
252         return captureRenderContext_;
253     }
254 #endif // RS_ENABLE_GL || RS_ENABLE_VK
255 #endif
256     void ResetCurrentContext();
257 
258 #ifdef RS_ENABLE_EGLIMAGE
GetEglImageManager()259     const std::shared_ptr<RSEglImageManager>& GetEglImageManager()
260     {
261         return eglImageManager_;
262     }
263 #endif // RS_ENABLE_EGLIMAGE
264 #ifdef USE_VIDEO_PROCESSING_ENGINE
265     void ColorSpaceConvertor(std::shared_ptr<Drawing::ShaderEffect> &inputShader, BufferDrawParam& params,
266         Media::VideoProcessingEngine::ColorSpaceConverterDisplayParameter& parameter);
267 #endif
268     static std::shared_ptr<Drawing::ColorSpace> ConvertColorGamutToDrawingColorSpace(GraphicColorGamut colorGamut);
269 #ifdef RS_ENABLE_VK
GetVkImageManager()270     const std::shared_ptr<RSVkImageManager>& GetVkImageManager() const
271     {
272         return vkImageManager_;
273     }
GetSkContext()274     const std::shared_ptr<Drawing::GPUContext> GetSkContext() const
275     {
276         return skContext_;
277     }
GetCaptureSkContext()278     const std::shared_ptr<Drawing::GPUContext> GetCaptureSkContext() const
279     {
280         return captureSkContext_;
281     }
282 #endif
283 protected:
284     void DrawImage(RSPaintFilterCanvas& canvas, BufferDrawParam& params);
285     static bool CheckIsHdrSurfaceBuffer(const sptr<SurfaceBuffer> surfaceNode);
286 
287     static inline std::mutex colorFilterMutex_;
288     static inline ColorFilterMode colorFilterMode_ = ColorFilterMode::COLOR_FILTER_END;
289     static inline std::atomic_bool isHighContrastEnabled_ = false;
290 
291 private:
292     std::shared_ptr<Drawing::Image> CreateEglImageFromBuffer(RSPaintFilterCanvas& canvas,
293         const sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& acquireFence,
294         const uint32_t threadIndex = UNI_MAIN_THREAD_INDEX,
295         const std::shared_ptr<Drawing::ColorSpace>& drawingColorSpace = nullptr);
296 
297     static void DrawImageRect(RSPaintFilterCanvas& canvas, std::shared_ptr<Drawing::Image> image,
298         BufferDrawParam& params, Drawing::SamplingOptions& samplingOptions);
299 
300 #if defined(NEW_RENDER_CONTEXT)
301     std::shared_ptr<RenderContextBase> renderContext_ = nullptr;
302     std::shared_ptr<DrawingContext> drawingContext_ = nullptr;
303 #else
304 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
305     std::shared_ptr<RenderContext> renderContext_ = nullptr;
306     std::shared_ptr<RenderContext> captureRenderContext_ = nullptr;
307 #endif // RS_ENABLE_GL || RS_ENABLE_VK
308 #endif
309 #ifdef RS_ENABLE_EGLIMAGE
310     std::shared_ptr<RSEglImageManager> eglImageManager_ = nullptr;
311 #endif // RS_ENABLE_EGLIMAGE
312 #ifdef RS_ENABLE_VK
313     std::shared_ptr<Drawing::GPUContext> skContext_ = nullptr;
314     std::shared_ptr<Drawing::GPUContext> captureSkContext_ = nullptr;
315     std::shared_ptr<RSVkImageManager> vkImageManager_ = nullptr;
316 #endif
317     using SurfaceId = uint64_t;
318 #ifdef USE_VIDEO_PROCESSING_ENGINE
319     static bool SetColorSpaceConverterDisplayParameter(
320         const BufferDrawParam& params, Media::VideoProcessingEngine::ColorSpaceConverterDisplayParameter& parameter);
321     static std::shared_ptr<Drawing::ColorSpace> GetCanvasColorSpace(const RSPaintFilterCanvas& canvas);
322     static bool ConvertDrawingColorSpaceToSpaceInfo(const std::shared_ptr<Drawing::ColorSpace>& colorSpace,
323         HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceInfo& colorSpaceInfo);
324     std::shared_ptr<Media::VideoProcessingEngine::ColorSpaceConverterDisplay> colorSpaceConverterDisplay_ = nullptr;
325 #endif
326 };
327 } // namespace Rosen
328 } // namespace OHOS
329 #endif // RS_CORE_PIPELINE_BASE_RENDER_ENGINE_H
330