Merge branch 'devel/master' into devel/graphics
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-command-buffer.h
1 #ifndef DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
2 #define DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/graphics-api/graphics-command-buffer-create-info.h>
23 #include <dali/graphics-api/graphics-command-buffer.h>
24 #include <dali/graphics-api/graphics-types.h>
25
26 // INTERNAL INCLUDES
27 #include "gles-graphics-resource.h"
28 #include "gles-graphics-types.h"
29
30 namespace Dali::Graphics::GLES
31 {
32 class Texture;
33 class Pipeline;
34
35 enum class CommandType
36 {
37   FLUSH,
38   BIND_TEXTURES,
39   BIND_SAMPLERS,
40   BIND_VERTEX_BUFFERS,
41   BIND_INDEX_BUFFER,
42   BIND_UNIFORM_BUFFER,
43   BIND_PIPELINE,
44   DRAW,
45   DRAW_INDEXED,
46   DRAW_INDEXED_INDIRECT,
47   SET_SCISSOR,
48   SET_SCISSOR_TEST,
49   SET_VIEWPORT
50 };
51
52 /**
53  * @brief Helper function to invoke destructor on anonymous struct
54  */
55 template<class T>
56 static void InvokeDestructor(T& object)
57 {
58   object.~T();
59 }
60
61 /**
62  * Command structure allocates memory to store a single command
63  */
64 struct Command
65 {
66   Command() = delete;
67
68   Command(CommandType commandType)
69   {
70     type = commandType;
71     switch(type)
72     {
73       case CommandType::BIND_VERTEX_BUFFERS:
74       {
75         new(&bindVertexBuffers) decltype(bindVertexBuffers);
76         break;
77       }
78       case CommandType::BIND_TEXTURES:
79       {
80         new(&bindTextures) decltype(bindTextures);
81         break;
82       }
83       default:
84       {
85       }
86     }
87   }
88
89   ~Command()
90   {
91     switch(type)
92     {
93       case CommandType::BIND_VERTEX_BUFFERS:
94       {
95         InvokeDestructor(bindVertexBuffers);
96         break;
97       }
98       case CommandType::BIND_TEXTURES:
99       {
100         InvokeDestructor(bindTextures);
101         break;
102       }
103       default:
104       {
105       }
106     }
107   }
108
109   /**
110    * @brief Copy constructor
111    * @param[in] rhs Command
112    */
113   Command(const Command& rhs)
114   {
115     switch(rhs.type)
116     {
117       case CommandType::BIND_VERTEX_BUFFERS:
118       {
119         new(&bindVertexBuffers) decltype(bindVertexBuffers);
120         bindVertexBuffers = rhs.bindVertexBuffers;
121         break;
122       }
123       case CommandType::BIND_INDEX_BUFFER:
124       {
125         bindIndexBuffer = rhs.bindIndexBuffer;
126         break;
127       }
128       case CommandType::BIND_SAMPLERS:
129       {
130         bindSamplers = rhs.bindSamplers;
131         break;
132       }
133       case CommandType::BIND_TEXTURES:
134       {
135         new(&bindTextures) decltype(bindTextures);
136         bindTextures = rhs.bindTextures;
137         break;
138       }
139       case CommandType::BIND_PIPELINE:
140       {
141         bindPipeline = rhs.bindPipeline;
142         break;
143       }
144       case CommandType::BIND_UNIFORM_BUFFER:
145       {
146         bindUniformBuffers = rhs.bindUniformBuffers;
147         break;
148       }
149       case CommandType::DRAW:
150       {
151         draw.type = rhs.draw.type;
152         draw.draw = rhs.draw.draw;
153         break;
154       }
155       case CommandType::DRAW_INDEXED:
156       {
157         draw.type        = rhs.draw.type;
158         draw.drawIndexed = rhs.draw.drawIndexed;
159         break;
160       }
161       case CommandType::DRAW_INDEXED_INDIRECT:
162       {
163         draw.type                = rhs.draw.type;
164         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
165         break;
166       }
167       case CommandType::FLUSH:
168       {
169         // Nothing to do
170         break;
171       }
172       case CommandType::SET_SCISSOR:
173       {
174         scissor.region = rhs.scissor.region;
175         break;
176       }
177       case CommandType::SET_SCISSOR_TEST:
178       {
179         scissorTest.enable = rhs.scissorTest.enable;
180         break;
181       }
182       case CommandType::SET_VIEWPORT:
183       {
184         viewport.region = rhs.viewport.region;
185         break;
186       }
187     }
188     type = rhs.type;
189   }
190
191   /**
192    * @brief Copy constructor
193    * @param[in] rhs Command
194    */
195   Command(Command&& rhs) noexcept
196   {
197     switch(rhs.type)
198     {
199       case CommandType::BIND_VERTEX_BUFFERS:
200       {
201         new(&bindVertexBuffers) decltype(bindVertexBuffers);
202         bindVertexBuffers = std::move(rhs.bindVertexBuffers);
203         break;
204       }
205       case CommandType::BIND_INDEX_BUFFER:
206       {
207         bindIndexBuffer = rhs.bindIndexBuffer;
208         break;
209       }
210       case CommandType::BIND_UNIFORM_BUFFER:
211       {
212         bindUniformBuffers = std::move(rhs.bindUniformBuffers);
213         break;
214       }
215       case CommandType::BIND_SAMPLERS:
216       {
217         bindSamplers = std::move(rhs.bindSamplers);
218         break;
219       }
220       case CommandType::BIND_TEXTURES:
221       {
222         new(&bindTextures) decltype(bindTextures);
223         bindTextures = std::move(rhs.bindTextures);
224         break;
225       }
226       case CommandType::BIND_PIPELINE:
227       {
228         bindPipeline = rhs.bindPipeline;
229         break;
230       }
231       case CommandType::DRAW:
232       {
233         draw.type = rhs.draw.type;
234         draw.draw = rhs.draw.draw;
235         break;
236       }
237       case CommandType::DRAW_INDEXED:
238       {
239         draw.type        = rhs.draw.type;
240         draw.drawIndexed = rhs.draw.drawIndexed;
241         break;
242       }
243       case CommandType::DRAW_INDEXED_INDIRECT:
244       {
245         draw.type                = rhs.draw.type;
246         draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
247         break;
248       }
249       case CommandType::FLUSH:
250       {
251         // Nothing to do
252         break;
253       }
254       case CommandType::SET_SCISSOR:
255       {
256         scissor.region = rhs.scissor.region;
257         break;
258       }
259       case CommandType::SET_SCISSOR_TEST:
260       {
261         scissorTest.enable = rhs.scissorTest.enable;
262         break;
263       }
264       case CommandType::SET_VIEWPORT:
265       {
266         viewport.region = rhs.viewport.region;
267         break;
268       }
269     }
270     type = rhs.type;
271   }
272
273   CommandType type{CommandType::FLUSH}; ///< Type of command
274
275   union
276   {
277     struct
278     {
279       std::vector<Graphics::TextureBinding> textureBindings;
280     } bindTextures{};
281
282     // BindSampler command
283     struct
284     {
285       std::vector<Graphics::SamplerBinding> samplerBindings;
286     } bindSamplers;
287
288     struct
289     {
290       using Binding = GLES::VertexBufferBindingDescriptor;
291       std::vector<Binding> vertexBufferBindings;
292     } bindVertexBuffers;
293
294     struct : public IndexBufferBindingDescriptor
295     {
296     } bindIndexBuffer;
297
298     struct
299     {
300       std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
301       UniformBufferBindingDescriptor              standaloneUniformsBufferBinding{};
302     } bindUniformBuffers;
303
304     struct
305     {
306       const GLES::Pipeline* pipeline{nullptr};
307     } bindPipeline;
308
309     struct : public DrawCallDescriptor
310     {
311     } draw;
312
313     struct
314     {
315       Graphics::Rect2D region;
316     } scissor;
317
318     struct
319     {
320       bool enable;
321     } scissorTest;
322
323     struct
324     {
325       Graphics::Viewport region;
326     } viewport;
327   };
328 };
329
330 using CommandBufferResource = Resource<Graphics::CommandBuffer, Graphics::CommandBufferCreateInfo>;
331
332 class CommandBuffer : public CommandBufferResource
333 {
334 public:
335   CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
336
337   ~CommandBuffer() override;
338
339   void BindVertexBuffers(uint32_t                             firstBinding,
340                          std::vector<const Graphics::Buffer*> buffers,
341                          std::vector<uint32_t>                offsets) override;
342
343   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
344
345   void BindPipeline(const Graphics::Pipeline& pipeline) override;
346
347   void BindTextures(std::vector<TextureBinding>& textureBindings) override;
348
349   void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override;
350
351   void BindPushConstants(void*    data,
352                          uint32_t size,
353                          uint32_t binding) override;
354
355   void BindIndexBuffer(const Graphics::Buffer& buffer,
356                        uint32_t                offset,
357                        Format                  format) override;
358
359   void BeginRenderPass(
360     Graphics::RenderPass&   renderPass,
361     Graphics::RenderTarget& renderTarget,
362     Extent2D                renderArea,
363     std::vector<ClearValue> clearValues) override;
364
365   /**
366    * @brief Ends current render pass
367    *
368    * This command must be issued in order to finalize the render pass.
369    * It's up to the implementation whether anything has to be done but
370    * the Controller may use end RP marker in order to resolve resource
371    * dependencies (for example, to know when target texture is ready
372    * before passing it to another render pass).
373    */
374   void EndRenderPass() override;
375
376   void Draw(
377     uint32_t vertexCount,
378     uint32_t instanceCount,
379     uint32_t firstVertex,
380     uint32_t firstInstance) override;
381
382   void DrawIndexed(
383     uint32_t indexCount,
384     uint32_t instanceCount,
385     uint32_t firstIndex,
386     int32_t  vertexOffset,
387     uint32_t firstInstance) override;
388
389   void DrawIndexedIndirect(
390     Graphics::Buffer& buffer,
391     uint32_t          offset,
392     uint32_t          drawCount,
393     uint32_t          stride) override;
394
395   void Reset() override;
396
397   void SetScissor(Graphics::Rect2D value) override;
398
399   void SetScissorTestEnable(bool value) override;
400
401   void SetViewport(Viewport value) override;
402
403   void SetViewportEnable(bool value) override;
404
405   [[nodiscard]] const std::vector<Command>& GetCommands() const;
406
407   void DestroyResource() override;
408   bool InitializeResource() override;
409
410   void DiscardResource() override;
411
412 private:
413   std::vector<Command> mCommands;
414 };
415 } // namespace Dali::Graphics::GLES
416
417 #endif