b79607b3a3f2dda47c304f906f993478fba6be1f
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-command-buffer.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "gles-graphics-command-buffer.h"
20
21 // INTERNAL INCLUDES
22 #include "egl-graphics-controller.h"
23 #include "gles-graphics-buffer.h"
24 #include "gles-graphics-framebuffer.h"
25 #include "gles-graphics-pipeline.h"
26 #include "gles-graphics-render-pass.h"
27 #include "gles-graphics-render-target.h"
28 #include "gles-graphics-texture.h"
29
30 namespace Dali::Graphics::GLES
31 {
32 CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
33 : CommandBufferResource(createInfo, controller)
34 {
35 }
36
37 CommandBuffer::~CommandBuffer() = default;
38
39 void CommandBuffer::BindVertexBuffers(uint32_t                             firstBinding,
40                                       std::vector<const Graphics::Buffer*> buffers,
41                                       std::vector<uint32_t>                offsets)
42 {
43   mCommands.emplace_back(CommandType::BIND_VERTEX_BUFFERS);
44   auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
45   if(bindings.size() < firstBinding + buffers.size())
46   {
47     bindings.resize(firstBinding + buffers.size());
48     auto index = firstBinding;
49     for(auto& buf : buffers)
50     {
51       bindings[index].buffer = static_cast<const GLES::Buffer*>(buf);
52       bindings[index].offset = offsets[index - firstBinding];
53       index++;
54     }
55   }
56 }
57
58 void CommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings)
59 {
60   mCommands.emplace_back(CommandType::BIND_UNIFORM_BUFFER);
61   auto& cmd     = mCommands.back();
62   auto& bindCmd = cmd.bindUniformBuffers;
63   for(const auto& binding : bindings)
64   {
65     if(binding.buffer)
66     {
67       auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
68       if(glesBuffer->IsCPUAllocated()) // standalone uniforms
69       {
70         bindCmd.standaloneUniformsBufferBinding.buffer   = glesBuffer;
71         bindCmd.standaloneUniformsBufferBinding.offset   = binding.offset;
72         bindCmd.standaloneUniformsBufferBinding.binding  = binding.binding;
73         bindCmd.standaloneUniformsBufferBinding.emulated = true;
74       }
75       else // Bind regular UBO
76       {
77         // resize binding slots
78         if(binding.binding >= bindCmd.uniformBufferBindings.size())
79         {
80           bindCmd.uniformBufferBindings.resize(binding.binding + 1);
81         }
82         auto& slot    = bindCmd.uniformBufferBindings[binding.binding];
83         slot.buffer   = glesBuffer;
84         slot.offset   = binding.offset;
85         slot.binding  = binding.binding;
86         slot.emulated = false;
87       }
88     }
89   }
90 }
91
92 void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
93 {
94   mCommands.emplace_back(CommandType::BIND_PIPELINE);
95   mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
96 }
97
98 void CommandBuffer::BindTextures(std::vector<TextureBinding>& textureBindings)
99 {
100   mCommands.emplace_back(CommandType::BIND_TEXTURES);
101   mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
102 }
103
104 void CommandBuffer::BindSamplers(std::vector<SamplerBinding>& samplerBindings)
105 {
106   mCommands.emplace_back(CommandType::BIND_SAMPLERS);
107   mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
108 }
109
110 void CommandBuffer::BindPushConstants(void*    data,
111                                       uint32_t size,
112                                       uint32_t binding)
113 {
114 }
115
116 void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
117                                     uint32_t                offset,
118                                     Format                  format)
119 {
120   mCommands.emplace_back(CommandType::BIND_INDEX_BUFFER);
121   mCommands.back().bindIndexBuffer.buffer = static_cast<const GLES::Buffer*>(&buffer);
122   mCommands.back().bindIndexBuffer.offset = offset;
123   mCommands.back().bindIndexBuffer.format = format;
124 }
125
126 void CommandBuffer::BeginRenderPass(
127   Graphics::RenderPass*   renderPass,
128   Graphics::RenderTarget* renderTarget,
129   Rect2D                  renderArea,
130   std::vector<ClearValue> clearValues)
131 {
132   mCommands.emplace_back(CommandType::BEGIN_RENDERPASS);
133   auto& cmd                        = mCommands.back();
134   cmd.beginRenderPass.renderPass   = static_cast<GLES::RenderPass*>(renderPass);
135   cmd.beginRenderPass.renderTarget = static_cast<GLES::RenderTarget*>(renderTarget);
136   cmd.beginRenderPass.renderArea   = renderArea;
137   cmd.beginRenderPass.clearValues  = clearValues;
138 }
139
140 void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
141 {
142   mCommands.emplace_back(CommandType::END_RENDERPASS);
143   auto& cmd = mCommands.back();
144
145   cmd.endRenderPass.syncObject = static_cast<GLES::SyncObject*>(syncObject);
146 }
147
148 void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
149 {
150   mCommands.emplace_back(CommandType::EXECUTE_COMMAND_BUFFERS);
151   auto& cmd = mCommands.back();
152   cmd.executeCommandBuffers.buffers.reserve(commandBuffers.size());
153   for(auto&& item : commandBuffers)
154   {
155     cmd.executeCommandBuffers.buffers.emplace_back(static_cast<const GLES::CommandBuffer*>(item));
156   }
157 }
158
159 void CommandBuffer::Draw(
160   uint32_t vertexCount,
161   uint32_t instanceCount,
162   uint32_t firstVertex,
163   uint32_t firstInstance)
164 {
165   mCommands.emplace_back(CommandType::DRAW);
166   auto& cmd              = mCommands.back().draw;
167   cmd.type               = DrawCallDescriptor::Type::DRAW;
168   cmd.draw.vertexCount   = vertexCount;
169   cmd.draw.instanceCount = instanceCount;
170   cmd.draw.firstInstance = firstInstance;
171   cmd.draw.firstVertex   = firstVertex;
172 }
173
174 void CommandBuffer::DrawIndexed(
175   uint32_t indexCount,
176   uint32_t instanceCount,
177   uint32_t firstIndex,
178   int32_t  vertexOffset,
179   uint32_t firstInstance)
180 {
181   mCommands.emplace_back(CommandType::DRAW_INDEXED);
182   auto& cmd                     = mCommands.back().draw;
183   cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
184   cmd.drawIndexed.firstIndex    = firstIndex;
185   cmd.drawIndexed.firstInstance = firstInstance;
186   cmd.drawIndexed.indexCount    = indexCount;
187   cmd.drawIndexed.vertexOffset  = vertexOffset;
188   cmd.drawIndexed.instanceCount = instanceCount;
189 }
190
191 void CommandBuffer::DrawIndexedIndirect(
192   Graphics::Buffer& buffer,
193   uint32_t          offset,
194   uint32_t          drawCount,
195   uint32_t          stride)
196 {
197   mCommands.emplace_back(CommandType::DRAW_INDEXED_INDIRECT);
198   auto& cmd                         = mCommands.back().draw;
199   cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
200   cmd.drawIndexedIndirect.buffer    = static_cast<const GLES::Buffer*>(&buffer);
201   cmd.drawIndexedIndirect.offset    = offset;
202   cmd.drawIndexedIndirect.drawCount = drawCount;
203   cmd.drawIndexedIndirect.stride    = stride;
204 }
205
206 void CommandBuffer::Reset()
207 {
208   mCommands.clear();
209 }
210
211 void CommandBuffer::SetScissor(Graphics::Rect2D value)
212 {
213   mCommands.emplace_back(CommandType::SET_SCISSOR);
214   mCommands.back().scissor.region = value;
215 }
216
217 void CommandBuffer::SetScissorTestEnable(bool value)
218 {
219   mCommands.emplace_back(CommandType::SET_SCISSOR_TEST);
220   mCommands.back().scissorTest.enable = value;
221 }
222
223 void CommandBuffer::SetViewport(Viewport value)
224 {
225   mCommands.emplace_back(CommandType::SET_VIEWPORT);
226   mCommands.back().viewport.region = value;
227 }
228
229 void CommandBuffer::SetViewportEnable(bool value)
230 {
231   // There is no GL equivalent
232 }
233
234 void CommandBuffer::SetColorMask(bool enabled)
235 {
236   mCommands.emplace_back(CommandType::SET_COLOR_MASK);
237   auto& cmd = mCommands.back().colorMask;
238   ;
239   cmd.enabled = enabled;
240 }
241
242 void CommandBuffer::ClearStencilBuffer()
243 {
244   mCommands.emplace_back(CommandType::CLEAR_STENCIL_BUFFER);
245 }
246
247 void CommandBuffer::SetStencilTestEnable(bool stencilEnable)
248 {
249   mCommands.emplace_back(CommandType::SET_STENCIL_TEST_ENABLE);
250   mCommands.back().stencilTest.enabled = stencilEnable;
251 }
252
253 void CommandBuffer::SetStencilWriteMask(uint32_t writeMask)
254 {
255   mCommands.emplace_back(CommandType::SET_STENCIL_WRITE_MASK);
256   mCommands.back().stencilWriteMask.mask = writeMask;
257 }
258
259 void CommandBuffer::SetStencilOp(Graphics::StencilOp failOp,
260                                  Graphics::StencilOp passOp,
261                                  Graphics::StencilOp depthFailOp)
262 {
263   mCommands.emplace_back(CommandType::SET_STENCIL_OP);
264   auto& cmd       = mCommands.back().stencilOp;
265   cmd.failOp      = failOp;
266   cmd.passOp      = passOp;
267   cmd.depthFailOp = depthFailOp;
268 }
269
270 void CommandBuffer::SetStencilFunc(Graphics::CompareOp compareOp,
271                                    uint32_t            reference,
272                                    uint32_t            compareMask)
273 {
274   mCommands.emplace_back(CommandType::SET_STENCIL_FUNC);
275   auto& cmd       = mCommands.back().stencilFunc;
276   cmd.compareOp   = compareOp;
277   cmd.compareMask = compareMask;
278   cmd.reference   = reference;
279 }
280
281 void CommandBuffer::SetDepthCompareOp(Graphics::CompareOp compareOp)
282 {
283   mCommands.emplace_back(CommandType::SET_DEPTH_COMPARE_OP);
284   mCommands.back().depth.compareOp = compareOp;
285 }
286
287 void CommandBuffer::SetDepthTestEnable(bool depthTestEnable)
288 {
289   mCommands.emplace_back(CommandType::SET_DEPTH_TEST_ENABLE);
290   mCommands.back().depth.testEnabled = depthTestEnable;
291 }
292 void CommandBuffer::SetDepthWriteEnable(bool depthWriteEnable)
293 {
294   mCommands.emplace_back(CommandType::SET_DEPTH_WRITE_ENABLE);
295   mCommands.back().depth.writeEnabled = depthWriteEnable;
296 }
297 void CommandBuffer::ClearDepthBuffer()
298 {
299   mCommands.emplace_back(CommandType::CLEAR_DEPTH_BUFFER);
300 }
301
302 void CommandBuffer::PresentRenderTarget(GLES::RenderTarget* renderTarget)
303 {
304   mCommands.emplace_back(CommandType::PRESENT_RENDER_TARGET);
305   mCommands.back().presentRenderTarget.targetToPresent = renderTarget;
306 }
307
308 [[nodiscard]] const std::vector<Command>& CommandBuffer::GetCommands() const
309 {
310   return mCommands;
311 }
312
313 void CommandBuffer::DestroyResource()
314 {
315   // Nothing to do
316 }
317
318 bool CommandBuffer::InitializeResource()
319 {
320   // Nothing to do
321   return true;
322 }
323
324 void CommandBuffer::DiscardResource()
325 {
326   GetController().DiscardResource(this);
327 }
328
329 } // namespace Dali::Graphics::GLES