1 /*
2  * Copyright (c) 2024 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 API_RENDER_UTIL_IRENDER_FRAME_UTIL_H
17 #define API_RENDER_UTIL_IRENDER_FRAME_UTIL_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/array_view.h>
22 #include <base/containers/byte_array.h>
23 #include <base/containers/string.h>
24 #include <base/containers/unique_ptr.h>
25 #include <render/namespace.h>
26 #include <render/resource_handle.h>
27 
RENDER_BEGIN_NAMESPACE()28 RENDER_BEGIN_NAMESPACE()
29 /** @ingroup group_util_irenderframeutil */
30 
31 /** Interface for render frame utilities.
32  * CopyToCpu is internally synchronized
33  * SetBackBufferConfiguration is internally synchronized
34  */
35 class IRenderFrameUtil {
36 public:
37     /** Copy flag bits */
38     enum CopyFlagBits {
39         /** Wait for idle is called before copying the data */
40         WAIT_FOR_IDLE = (1 << 0),
41         /** GPU copy to CPU accessable buffer */
42         GPU_BUFFER_ONLY = (1 << 1),
43     };
44     /** Copy flag bits container */
45     using CopyFlags = uint32_t;
46 
47     /** Low level type of the opaque signal resource handle */
48     enum class SignalResourceType : uint32_t {
49         /** Undefined */
50         UNDEFINED,
51         /** GPU semaphore */
52         GPU_SEMAPHORE,
53         /** GPU fence */
54         GPU_FENCE,
55     };
56 
57     /** Frame copy data */
58     struct FrameCopyData {
59         /** handle for reference/check-up */
60         BASE_NS::unique_ptr<BASE_NS::ByteArray> byteBuffer;
61         /** frame index */
62         uint64_t frameIndex { 0 };
63         /** handle for reference/check-up */
64         RenderHandleReference handle {};
65         /** copy flags */
66         CopyFlags copyFlags { 0u };
67         /** additional buffer handle if doing GPU -> GPU readable copy */
68         RenderHandleReference bufferHandle {};
69     };
70     /** Back buffer configuration
71      * Which overwrites NodeGraphBackBufferConfiguration POD
72      */
73     struct BackBufferConfiguration {
74         /** Back buffer type */
75         enum class BackBufferType : uint32_t {
76             /** Undefined */
77             UNDEFINED,
78             /** Swapchain */
79             SWAPCHAIN,
80             /** GPU image */
81             GPU_IMAGE,
82             /** GPU image buffer copy */
83             GPU_IMAGE_BUFFER_COPY,
84         };
85 
86         /** Name of the GpuImage in render node graph json where rendering happens.
87          * Image with this name must have been created by the application (or by the renderer). */
88         BASE_NS::string backBufferName { "CORE_DEFAULT_BACKBUFFER" };
89 
90         /** Back buffer type */
91         BackBufferType backBufferType = { BackBufferType::UNDEFINED };
92 
93         /** Handle to the final target.
94          * If backbufferType is SWAPCHAIN this handle is not used.
95          * If backbufferType is GPU_IMAGE this must point to a valid GpuImage. */
96         RenderHandleReference backBufferHandle;
97         /* If backbufferType is GPU_IMAGE_BUFFER_COPY this must point to a valid GpuBuffer where image data is copied.
98          */
99         RenderHandleReference gpuBufferHandle;
100 
101         /** Present */
102         bool present { false };
103 
104         /** Binary semaphore for signaling end of frame, i.e. when rendered to back buffer */
105         uint64_t gpuSemaphoreHandle { 0 };
106     };
107 
108     /** Signal resource object which can be retrieved after render frame has been processed
109      */
110     struct SignalData {
111         /** Handle if it was attached to some handle */
112         RenderHandleReference handle;
113         /** Quarantee that the semaphore object has been signaled */
114         bool signaled { false };
115         /** Low level signal resource handle (In Vulkan GPU semaphore) */
116         uint64_t gpuSignalResourceHandle { 0 };
117         /** Low level signal resource type */
118         SignalResourceType signalResourceType {};
119     };
120 
121     /** Copy data to CPU the next frame if waiting for idle.
122      * @param handle Render handle reference of the resource.
123      * @param flags Copy flag bits.
124      */
125     virtual void CopyToCpu(const RenderHandleReference& handle, const CopyFlags flags) = 0;
126 
127     /** Get copied frame data. Valid after RenderFrame and stays valid for next RenderFrame call.
128      * NOTE: do not call during RenderFrame() not thread safe during rendering.
129      * @return Array view of copied data.
130      */
131     virtual BASE_NS::array_view<FrameCopyData> GetFrameCopyData() = 0;
132 
133     /** Get const reference to copied frame data by id.
134      * Valid after RenderFrame and stays valid for next RenderFrame call.
135      * NOTE: do not call during RenderFrame() not thread safe during rendering.
136      * @param handle The handle which was used when copy was added.
137      * @return Const reference of copy data.
138      */
139     virtual const FrameCopyData& GetFrameCopyData(const RenderHandleReference& handle) = 0;
140 
141     /** Set backbuffer configuration.
142      * If this is set once, it will update the NodeGraphBackBufferConfiguration POD every frame.
143      * @param backBufferConfiguration which will be hold and updated every frame
144      */
145     virtual void SetBackBufferConfiguration(const BackBufferConfiguration& backBufferConfiguration) = 0;
146 
147     /** Add GPU only signal to be signaled this frame.
148      * Guarantees that the signal will be signaled if anything is processed in the backend.
149      * Does not guarantee that the signal is immediate after the specific handle has been processed on the GPU.
150      * If the signal resource handle is zero rendering side resource is created automatically.
151      * @param signalData All the values are optional.
152      */
153     virtual void AddGpuSignal(const SignalData& signalData) = 0;
154 
155     /** Get GPU frame signal data.
156      * Get all signal data for processed frame.
157      * Be sure to check the boolean flag, and the gpuSemaphoreHandle before casting.
158      * @return array view of frame signal data.
159      */
160     virtual BASE_NS::array_view<SignalData> GetFrameGpuSignalData() = 0;
161 
162     /** Get frame signal data for a specific handle.
163      * Make sure to check the boolean flag every time before using.
164      * Be sure to check the boolean flag, and the gpuSemaphoreHandle before casting
165      * @param handle The handle which was used when signal was added.
166      * @return semaphore data if it was found.
167      */
168     virtual SignalData GetFrameGpuSignalData(const RenderHandleReference& handle) = 0;
169 
170 protected:
171     IRenderFrameUtil() = default;
172     virtual ~IRenderFrameUtil() = default;
173 };
174 RENDER_END_NAMESPACE()
175 
176 #endif // API_RENDER_UTIL_IRENDER_FRAME_UTIL_H
177