*/
// EXTERNAL INCLUDES
+#include <dali/graphics-api/graphics-command-buffer-create-info.h>
#include <dali/graphics-api/graphics-command-buffer.h>
+#include <dali/graphics-api/graphics-types.h>
// INTERNAL INCLUDES
-#include "egl-graphics-controller.h"
+#include "gles-graphics-resource.h"
+#include "gles-graphics-types.h"
-namespace Dali
+namespace Dali::Graphics::GLES
{
-namespace Graphics
-{
-namespace GLES
-{
-class EglController;
-class Texture;
-class Buffer;
-class Sampler;
-
+class Pipeline;
+class RenderPass;
+class Framebuffer;
+class CommandBuffer;
enum class CommandType
{
FLUSH,
BIND_TEXTURES,
BIND_SAMPLERS,
BIND_VERTEX_BUFFERS,
- BIND_INDEX_BUFFER
+ BIND_INDEX_BUFFER,
+ BIND_UNIFORM_BUFFER,
+ BIND_PIPELINE,
+ DRAW,
+ DRAW_INDEXED,
+ DRAW_INDEXED_INDIRECT,
+ SET_SCISSOR,
+ SET_SCISSOR_TEST,
+ SET_VIEWPORT,
+ BEGIN_RENDERPASS,
+ END_RENDERPASS,
+ EXECUTE_COMMAND_BUFFERS,
+ PRESENT_RENDER_TARGET,
};
/**
+ * @brief Helper function to invoke destructor on anonymous struct
+ */
+template<class T>
+static void InvokeDestructor(T& object)
+{
+ object.~T();
+}
+
+/**
* Command structure allocates memory to store a single command
*/
struct Command
{
- Command()
+ Command() = delete;
+
+ Command(CommandType commandType)
{
+ type = commandType;
+ switch(type)
+ {
+ case CommandType::BIND_VERTEX_BUFFERS:
+ {
+ new(&bindVertexBuffers) decltype(bindVertexBuffers);
+ break;
+ }
+ case CommandType::BIND_TEXTURES:
+ {
+ new(&bindTextures) decltype(bindTextures);
+ break;
+ }
+ case CommandType::BEGIN_RENDERPASS:
+ {
+ // run destructor
+ new(&beginRenderPass) decltype(beginRenderPass);
+ break;
+ }
+ default:
+ {
+ }
+ }
}
~Command()
{
+ switch(type)
+ {
+ case CommandType::BIND_VERTEX_BUFFERS:
+ {
+ InvokeDestructor(bindVertexBuffers);
+ break;
+ }
+ case CommandType::BIND_TEXTURES:
+ {
+ InvokeDestructor(bindTextures);
+ break;
+ }
+ case CommandType::BEGIN_RENDERPASS:
+ {
+ // run destructor
+ InvokeDestructor(beginRenderPass);
+ break;
+ }
+ default:
+ {
+ }
+ }
}
/**
{
case CommandType::BIND_VERTEX_BUFFERS:
{
+ new(&bindVertexBuffers) decltype(bindVertexBuffers);
bindVertexBuffers = rhs.bindVertexBuffers;
break;
}
}
case CommandType::BIND_TEXTURES:
{
+ new(&bindTextures) decltype(bindTextures);
bindTextures = rhs.bindTextures;
break;
}
+ case CommandType::BIND_PIPELINE:
+ {
+ bindPipeline = rhs.bindPipeline;
+ break;
+ }
+ case CommandType::BIND_UNIFORM_BUFFER:
+ {
+ bindUniformBuffers = rhs.bindUniformBuffers;
+ break;
+ }
+ case CommandType::DRAW:
+ {
+ draw.type = rhs.draw.type;
+ draw.draw = rhs.draw.draw;
+ break;
+ }
+ case CommandType::DRAW_INDEXED:
+ {
+ draw.type = rhs.draw.type;
+ draw.drawIndexed = rhs.draw.drawIndexed;
+ break;
+ }
+ case CommandType::DRAW_INDEXED_INDIRECT:
+ {
+ draw.type = rhs.draw.type;
+ draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
+ break;
+ }
+ case CommandType::BEGIN_RENDERPASS:
+ {
+ new(&beginRenderPass) BeginRenderPassDescriptor(rhs.beginRenderPass);
+ break;
+ }
+ case CommandType::END_RENDERPASS:
+ {
+ break;
+ }
+ case CommandType::EXECUTE_COMMAND_BUFFERS:
+ {
+ executeCommandBuffers = rhs.executeCommandBuffers;
+ break;
+ }
case CommandType::FLUSH:
{
// Nothing to do
break;
}
+ case CommandType::SET_SCISSOR:
+ {
+ scissor.region = rhs.scissor.region;
+ break;
+ }
+ case CommandType::SET_SCISSOR_TEST:
+ {
+ scissorTest.enable = rhs.scissorTest.enable;
+ break;
+ }
+ case CommandType::SET_VIEWPORT:
+ {
+ viewport.region = rhs.viewport.region;
+ break;
+ }
+ case CommandType::PRESENT_RENDER_TARGET:
+ {
+ presentRenderTarget = rhs.presentRenderTarget;
+ break;
+ }
}
type = rhs.type;
}
{
case CommandType::BIND_VERTEX_BUFFERS:
{
+ new(&bindVertexBuffers) decltype(bindVertexBuffers);
bindVertexBuffers = std::move(rhs.bindVertexBuffers);
break;
}
bindIndexBuffer = rhs.bindIndexBuffer;
break;
}
+ case CommandType::BIND_UNIFORM_BUFFER:
+ {
+ bindUniformBuffers = std::move(rhs.bindUniformBuffers);
+ break;
+ }
case CommandType::BIND_SAMPLERS:
{
bindSamplers = std::move(rhs.bindSamplers);
}
case CommandType::BIND_TEXTURES:
{
+ new(&bindTextures) decltype(bindTextures);
bindTextures = std::move(rhs.bindTextures);
break;
}
+ case CommandType::BIND_PIPELINE:
+ {
+ bindPipeline = rhs.bindPipeline;
+ break;
+ }
+ case CommandType::DRAW:
+ {
+ draw.type = rhs.draw.type;
+ draw.draw = rhs.draw.draw;
+ break;
+ }
+ case CommandType::DRAW_INDEXED:
+ {
+ draw.type = rhs.draw.type;
+ draw.drawIndexed = rhs.draw.drawIndexed;
+ break;
+ }
+ case CommandType::DRAW_INDEXED_INDIRECT:
+ {
+ draw.type = rhs.draw.type;
+ draw.drawIndexedIndirect = rhs.draw.drawIndexedIndirect;
+ break;
+ }
+ case CommandType::BEGIN_RENDERPASS:
+ {
+ new(&beginRenderPass) BeginRenderPassDescriptor(std::move(rhs.beginRenderPass));
+ break;
+ }
+ case CommandType::END_RENDERPASS:
+ {
+ break;
+ }
+ case CommandType::EXECUTE_COMMAND_BUFFERS:
+ {
+ executeCommandBuffers = std::move(rhs.executeCommandBuffers);
+ break;
+ }
case CommandType::FLUSH:
{
// Nothing to do
break;
}
+ case CommandType::SET_SCISSOR:
+ {
+ scissor.region = rhs.scissor.region;
+ break;
+ }
+ case CommandType::SET_SCISSOR_TEST:
+ {
+ scissorTest.enable = rhs.scissorTest.enable;
+ break;
+ }
+ case CommandType::SET_VIEWPORT:
+ {
+ viewport.region = rhs.viewport.region;
+ break;
+ }
+ case CommandType::PRESENT_RENDER_TARGET:
+ {
+ presentRenderTarget = rhs.presentRenderTarget;
+ break;
+ }
}
type = rhs.type;
}
- CommandType type{CommandType::FLUSH};
+ CommandType type{CommandType::FLUSH}; ///< Type of command
union
{
struct
{
- struct Binding
- {
- const Graphics::Buffer* buffer{nullptr};
- uint32_t offset{0u};
- };
+ using Binding = GLES::VertexBufferBindingDescriptor;
std::vector<Binding> vertexBufferBindings;
} bindVertexBuffers;
- struct
+ struct : public IndexBufferBindingDescriptor
{
- const Graphics::Buffer* buffer{nullptr};
- uint32_t offset{};
- Graphics::Format format{};
} bindIndexBuffer;
+
+ struct
+ {
+ std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
+ UniformBufferBindingDescriptor standaloneUniformsBufferBinding{};
+ } bindUniformBuffers;
+
+ struct
+ {
+ const GLES::Pipeline* pipeline{nullptr};
+ } bindPipeline;
+
+ struct : public DrawCallDescriptor
+ {
+ } draw;
+
+ struct
+ {
+ Graphics::Rect2D region;
+ } scissor;
+
+ struct
+ {
+ bool enable;
+ } scissorTest;
+
+ struct
+ {
+ Graphics::Viewport region;
+ } viewport;
+
+ struct BeginRenderPassDescriptor
+ beginRenderPass;
+
+ struct
+ {
+ } endRenderPass;
+
+ struct
+ {
+ std::vector<GLES::CommandBuffer*> buffers;
+ } executeCommandBuffers;
+
+ struct
+ {
+ GLES::RenderTarget* targetToPresent;
+ } presentRenderTarget;
};
};
class CommandBuffer : public CommandBufferResource
{
public:
- CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
- : CommandBufferResource(createInfo, controller)
- {
- }
+ CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
+
+ ~CommandBuffer() override;
void BindVertexBuffers(uint32_t firstBinding,
std::vector<const Graphics::Buffer*> buffers,
- std::vector<uint32_t> offsets) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
- auto& bindings = mCommands.back().bindVertexBuffers.vertexBufferBindings;
- if(bindings.size() < firstBinding + buffers.size())
- {
- bindings.resize(firstBinding + buffers.size());
- auto index = firstBinding;
- for(auto& buf : buffers)
- {
- bindings[index].buffer = buf;
- bindings[index].offset = offsets[index - firstBinding];
- index++;
- }
- }
- }
+ std::vector<uint32_t> offsets) override;
- void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
- {
- }
+ void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
- void BindPipeline(const Graphics::Pipeline& pipeline) override
- {
- }
+ void BindPipeline(const Graphics::Pipeline& pipeline) override;
- void BindTextures(std::vector<TextureBinding>& textureBindings) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_TEXTURES;
- mCommands.back().bindTextures.textureBindings = std::move(textureBindings);
- }
+ void BindTextures(std::vector<TextureBinding>& textureBindings) override;
- void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override
- {
- mCommands.emplace_back();
- mCommands.back().bindSamplers.samplerBindings = std::move(samplerBindings);
- }
+ void BindSamplers(std::vector<SamplerBinding>& samplerBindings) override;
void BindPushConstants(void* data,
uint32_t size,
- uint32_t binding) override
- {
- }
+ uint32_t binding) override;
void BindIndexBuffer(const Graphics::Buffer& buffer,
uint32_t offset,
- Format format) override
- {
- mCommands.emplace_back();
- mCommands.back().type = CommandType::BIND_INDEX_BUFFER;
- mCommands.back().bindIndexBuffer.buffer = &buffer;
- mCommands.back().bindIndexBuffer.offset = offset;
- mCommands.back().bindIndexBuffer.format = format;
- }
+ Format format) override;
void BeginRenderPass(
- Graphics::RenderPass& renderPass,
- Graphics::RenderTarget& renderTarget,
- Extent2D renderArea,
- std::vector<ClearValue> clearValues) override
- {
- }
+ Graphics::RenderPass* renderPass,
+ Graphics::RenderTarget* renderTarget,
+ Rect2D renderArea,
+ std::vector<ClearValue> clearValues) override;
/**
* @brief Ends current render pass
* dependencies (for example, to know when target texture is ready
* before passing it to another render pass).
*/
- void EndRenderPass() override
- {
- }
+ void EndRenderPass() override;
+
+ void ExecuteCommandBuffers(std::vector<Graphics::CommandBuffer*>&& commandBuffers) override;
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
- uint32_t firstInstance) override
- {
- }
+ uint32_t firstInstance) override;
void DrawIndexed(
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
- uint32_t firstInstance) override
- {
- }
+ uint32_t firstInstance) override;
void DrawIndexedIndirect(
Graphics::Buffer& buffer,
uint32_t offset,
uint32_t drawCount,
- uint32_t stride) override
- {
- }
+ uint32_t stride) override;
- void Reset(Graphics::CommandBuffer& commandBuffer) override
- {
- mCommands.clear();
- }
+ void Reset() override;
- void SetScissor(Extent2D value) override
- {
- }
+ void SetScissor(Graphics::Rect2D value) override;
- void SetScissorTestEnable(bool value) override
- {
- }
+ void SetScissorTestEnable(bool value) override;
- void SetViewport(Viewport value) override
- {
- }
+ void SetViewport(Viewport value) override;
- void SetViewportEnable(bool value) override
- {
- }
+ void SetViewportEnable(bool value) override;
- [[nodiscard]] const std::vector<Command>& GetCommands() const
- {
- return mCommands;
- }
+ /**
+ * @brief Presents specified render target
+ *
+ * @param[in] renderTarget Valid pointer to a RenderTarget
+ *
+ * It's internal command that schedules presentation of
+ * specified render target.
+ */
+ void PresentRenderTarget(GLES::RenderTarget* renderTarget);
- void DestroyResource() override
- {
- // Nothing to do
- }
+ [[nodiscard]] const std::vector<Command>& GetCommands() const;
- bool InitializeResource() override
- {
- // Nothing to do
- return true;
- }
+ void DestroyResource() override;
+ bool InitializeResource() override;
- void DiscardResource() override
- {
- // Nothing to do
- }
+ void DiscardResource() override;
private:
std::vector<Command> mCommands;
};
-} // Namespace GLES
-} // Namespace Graphics
-} // Namespace Dali
+} // namespace Dali::Graphics::GLES
-#endif
\ No newline at end of file
+#endif