Create GLES::Context per render surface
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-command-buffer.h
index e9ec39f..5996863 100644 (file)
  */
 
 // 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-buffer.h"
-#include "gles-graphics-pipeline.h"
+#include "gles-graphics-resource.h"
 #include "gles-graphics-types.h"
 
 namespace Dali::Graphics::GLES
 {
-class Texture;
 class Pipeline;
-
+class RenderPass;
+class Framebuffer;
+class CommandBuffer;
 enum class CommandType
 {
   FLUSH,
@@ -43,20 +44,83 @@ enum class CommandType
   BIND_PIPELINE,
   DRAW,
   DRAW_INDEXED,
-  DRAW_INDEXED_INDIRECT
+  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:
+      {
+      }
+    }
   }
 
   /**
@@ -69,6 +133,7 @@ struct Command
     {
       case CommandType::BIND_VERTEX_BUFFERS:
       {
+        new(&bindVertexBuffers) decltype(bindVertexBuffers);
         bindVertexBuffers = rhs.bindVertexBuffers;
         break;
       }
@@ -84,6 +149,7 @@ struct Command
       }
       case CommandType::BIND_TEXTURES:
       {
+        new(&bindTextures) decltype(bindTextures);
         bindTextures = rhs.bindTextures;
         break;
       }
@@ -115,11 +181,45 @@ struct Command
         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;
   }
@@ -134,6 +234,7 @@ struct Command
     {
       case CommandType::BIND_VERTEX_BUFFERS:
       {
+        new(&bindVertexBuffers) decltype(bindVertexBuffers);
         bindVertexBuffers = std::move(rhs.bindVertexBuffers);
         break;
       }
@@ -154,6 +255,7 @@ struct Command
       }
       case CommandType::BIND_TEXTURES:
       {
+        new(&bindTextures) decltype(bindTextures);
         bindTextures = std::move(rhs.bindTextures);
         break;
       }
@@ -180,11 +282,45 @@ struct Command
         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;
   }
@@ -228,6 +364,38 @@ struct Command
     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;
   };
 };
 
@@ -236,112 +404,35 @@ using CommandBufferResource = Resource<Graphics::CommandBuffer, Graphics::Comman
 class CommandBuffer : public CommandBufferResource
 {
 public:
-  CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
-  : CommandBufferResource(createInfo, controller)
-  {
-  }
+  CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller);
 
-  ~CommandBuffer() override = default;
+  ~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 = static_cast<const GLES::Buffer*>(buf);
-        bindings[index].offset = offsets[index - firstBinding];
-        index++;
-      }
-    }
-  }
+                         std::vector<uint32_t>                offsets) override;
 
-  void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
-  {
-    mCommands.emplace_back();
-    auto& cmd     = mCommands.back();
-    cmd.type      = CommandType::BIND_UNIFORM_BUFFER;
-    auto& bindCmd = cmd.bindUniformBuffers;
-    for(const auto& binding : bindings)
-    {
-      if(binding.buffer)
-      {
-        auto glesBuffer = static_cast<const GLES::Buffer*>(binding.buffer);
-        if(glesBuffer->IsCPUAllocated()) // standalone uniforms
-        {
-          bindCmd.standaloneUniformsBufferBinding.buffer   = glesBuffer;
-          bindCmd.standaloneUniformsBufferBinding.offset   = binding.offset;
-          bindCmd.standaloneUniformsBufferBinding.binding  = binding.binding;
-          bindCmd.standaloneUniformsBufferBinding.emulated = true;
-        }
-        else // Bind regular UBO
-        {
-          // resize binding slots
-          if(binding.binding >= bindCmd.uniformBufferBindings.size())
-          {
-            bindCmd.uniformBufferBindings.resize(binding.binding + 1);
-          }
-          auto& slot    = bindCmd.uniformBufferBindings[binding.binding];
-          slot.buffer   = glesBuffer;
-          slot.offset   = binding.offset;
-          slot.binding  = binding.binding;
-          slot.emulated = false;
-        }
-      }
-    }
-  }
+  void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override;
 
-  void BindPipeline(const Graphics::Pipeline& pipeline) override
-  {
-    mCommands.emplace_back();
-    mCommands.back().type                  = CommandType::BIND_PIPELINE;
-    mCommands.back().bindPipeline.pipeline = static_cast<const GLES::Pipeline*>(&pipeline);
-  }
+  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 = static_cast<const GLES::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
@@ -352,101 +443,55 @@ public:
    * 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
-  {
-    mCommands.emplace_back();
-    mCommands.back().type  = CommandType::DRAW;
-    auto& cmd              = mCommands.back().draw;
-    cmd.type               = DrawCallDescriptor::Type::DRAW;
-    cmd.draw.vertexCount   = vertexCount;
-    cmd.draw.instanceCount = instanceCount;
-    cmd.draw.firstInstance = firstInstance;
-    cmd.draw.firstVertex   = firstVertex;
-  }
+    uint32_t firstInstance) override;
 
   void DrawIndexed(
     uint32_t indexCount,
     uint32_t instanceCount,
     uint32_t firstIndex,
     int32_t  vertexOffset,
-    uint32_t firstInstance) override
-  {
-    mCommands.emplace_back();
-    mCommands.back().type         = CommandType::DRAW_INDEXED;
-    auto& cmd                     = mCommands.back().draw;
-    cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
-    cmd.drawIndexed.firstIndex    = firstIndex;
-    cmd.drawIndexed.firstInstance = firstInstance;
-    cmd.drawIndexed.indexCount    = indexCount;
-    cmd.drawIndexed.vertexOffset  = vertexOffset;
-    cmd.drawIndexed.instanceCount = instanceCount;
-  }
+    uint32_t firstInstance) override;
 
   void DrawIndexedIndirect(
     Graphics::Buffer& buffer,
     uint32_t          offset,
     uint32_t          drawCount,
-    uint32_t          stride) override
-  {
-    mCommands.emplace_back();
-    mCommands.back().type             = CommandType::DRAW_INDEXED_INDIRECT;
-    auto& cmd                         = mCommands.back().draw;
-    cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
-    cmd.drawIndexedIndirect.buffer    = static_cast<const GLES::Buffer*>(&buffer);
-    cmd.drawIndexedIndirect.offset    = offset;
-    cmd.drawIndexedIndirect.drawCount = drawCount;
-    cmd.drawIndexedIndirect.stride    = stride;
-  }
+    uint32_t          stride) override;
 
-  void Reset() 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;