Changes to constness of command buffer
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / egl-graphics-controller.cpp
index ef507a7..f4f7e60 100644 (file)
 #include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+#include <dali/integration-api/debug.h>
 #include <dali/integration-api/gl-abstraction.h>
 #include <dali/integration-api/gl-defines.h>
 #include <dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h>
 #include <dali/internal/graphics/gles-impl/gles-graphics-pipeline.h>
+#include <dali/internal/graphics/gles-impl/gles-graphics-render-pass.h>
+#include <dali/internal/graphics/gles-impl/gles-graphics-render-target.h>
 #include <dali/internal/graphics/gles-impl/gles-graphics-shader.h>
 #include <dali/internal/graphics/gles-impl/gles-graphics-texture.h>
 #include <dali/internal/graphics/gles-impl/gles-graphics-types.h>
+#include <dali/internal/graphics/gles-impl/gles3-graphics-memory.h>
 #include <dali/public-api/common/dali-common.h>
+#include "gles-graphics-program.h"
 
 namespace Dali::Graphics
 {
@@ -87,17 +93,23 @@ T0* CastObject(T1* apiObject)
 
 } // namespace
 
+EglGraphicsController::~EglGraphicsController() = default;
+
 void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstraction)
 {
+  DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #1\n");
   mGlAbstraction = &glAbstraction;
   mContext       = std::make_unique<GLES::Context>(*this);
 }
 
 void EglGraphicsController::Initialize(Integration::GlSyncAbstraction&          glSyncAbstraction,
-                                       Integration::GlContextHelperAbstraction& glContextHelperAbstraction)
+                                       Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
+                                       Internal::Adaptor::GraphicsInterface&    graphicsInterface)
 {
+  DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #2\n");
   mGlSyncAbstraction          = &glSyncAbstraction;
   mGlContextHelperAbstraction = &glContextHelperAbstraction;
+  mGraphics                   = &graphicsInterface;
 }
 
 void EglGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo)
@@ -115,6 +127,31 @@ void EglGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo)
   }
 }
 
+void EglGraphicsController::PresentRenderTarget(RenderTarget* renderTarget)
+{
+  // Use command buffer to execute presentation (we should pool it)
+  CommandBufferCreateInfo info;
+  info.SetLevel(CommandBufferLevel::PRIMARY);
+  info.fixedCapacity        = 1; // only one command
+  auto presentCommandBuffer = new GLES::CommandBuffer(info, *this);
+  presentCommandBuffer->PresentRenderTarget(static_cast<GLES::RenderTarget*>(renderTarget));
+  SubmitInfo submitInfo;
+  submitInfo.cmdBuffer = {presentCommandBuffer};
+  submitInfo.flags     = 0 | SubmitFlagBits::FLUSH;
+  SubmitCommandBuffers(submitInfo);
+}
+
+void EglGraphicsController::ResolvePresentRenderTarget(GLES::RenderTarget* renderTarget)
+{
+  auto* rt = static_cast<GLES::RenderTarget*>(renderTarget);
+  if(rt->GetCreateInfo().surface)
+  {
+    auto* surfaceInterface = reinterpret_cast<Dali::RenderSurfaceInterface*>(rt->GetCreateInfo().surface);
+    surfaceInterface->MakeContextCurrent();
+    surfaceInterface->PostRender();
+  }
+}
+
 Integration::GlAbstraction& EglGraphicsController::GetGlAbstraction()
 {
   DALI_ASSERT_DEBUG(mGlAbstraction && "Graphics controller not initialized");
@@ -133,31 +170,38 @@ Integration::GlContextHelperAbstraction& EglGraphicsController::GetGlContextHelp
   return *mGlContextHelperAbstraction;
 }
 
-Graphics::UniquePtr<CommandBuffer>
-EglGraphicsController::CreateCommandBuffer(const CommandBufferCreateInfo&       commandBufferCreateInfo,
-                                           Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer)
+Graphics::UniquePtr<CommandBuffer> EglGraphicsController::CreateCommandBuffer(
+  const CommandBufferCreateInfo&       commandBufferCreateInfo,
+  Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer)
 {
   return NewObject<GLES::CommandBuffer>(commandBufferCreateInfo, *this, std::move(oldCommandBuffer));
 }
 
+Graphics::UniquePtr<RenderPass> EglGraphicsController::CreateRenderPass(const RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<RenderPass>&& oldRenderPass)
+{
+  return NewObject<GLES::RenderPass>(renderPassCreateInfo, *this, std::move(oldRenderPass));
+}
+
 Graphics::UniquePtr<Texture>
 EglGraphicsController::CreateTexture(const TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Texture>&& oldTexture)
 {
   return NewObject<GLES::Texture>(textureCreateInfo, *this, std::move(oldTexture));
 }
 
-Graphics::UniquePtr<Buffer>
-EglGraphicsController::CreateBuffer(const BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Buffer>&& oldBuffer)
+Graphics::UniquePtr<Buffer> EglGraphicsController::CreateBuffer(
+  const BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Buffer>&& oldBuffer)
 {
   return NewObject<GLES::Buffer>(bufferCreateInfo, *this, std::move(oldBuffer));
 }
 
-Graphics::UniquePtr<Shader> EglGraphicsController::CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader)
+Graphics::UniquePtr<Framebuffer> EglGraphicsController::CreateFramebuffer(
+  const FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Framebuffer>&& oldFramebuffer)
 {
-  return NewObject<GLES::Shader>(shaderCreateInfo, *this, std::move(oldShader));
+  return NewObject<GLES::Framebuffer>(framebufferCreateInfo, *this, std::move(oldFramebuffer));
 }
 
-Graphics::UniquePtr<Pipeline> EglGraphicsController::CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
+Graphics::UniquePtr<Pipeline> EglGraphicsController::CreatePipeline(
+  const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
 {
   // Create pipeline cache if needed
   if(!mPipelineCache)
@@ -168,6 +212,38 @@ Graphics::UniquePtr<Pipeline> EglGraphicsController::CreatePipeline(const Pipeli
   return mPipelineCache->GetPipeline(pipelineCreateInfo, std::move(oldPipeline));
 }
 
+Graphics::UniquePtr<Program> EglGraphicsController::CreateProgram(
+  const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram)
+{
+  // Create program cache if needed
+  if(!mPipelineCache)
+  {
+    mPipelineCache = std::make_unique<GLES::PipelineCache>(*this);
+  }
+
+  return mPipelineCache->GetProgram(programCreateInfo, std::move(oldProgram));
+}
+
+Graphics::UniquePtr<Shader> EglGraphicsController::CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader)
+{
+  return NewObject<GLES::Shader>(shaderCreateInfo, *this, std::move(oldShader));
+}
+
+Graphics::UniquePtr<Sampler> EglGraphicsController::CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler)
+{
+  return NewObject<GLES::Sampler>(samplerCreateInfo, *this, std::move(oldSampler));
+}
+
+Graphics::UniquePtr<RenderTarget> EglGraphicsController::CreateRenderTarget(const RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<RenderTarget>&& oldRenderTarget)
+{
+  return NewObject<GLES::RenderTarget>(renderTargetCreateInfo, *this, std::move(oldRenderTarget));
+}
+
+const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Graphics::Program& program)
+{
+  return static_cast<const Graphics::GLES::Program*>(&program)->GetReflection();
+}
+
 void EglGraphicsController::AddTexture(GLES::Texture& texture)
 {
   // Assuming we are on the correct context
@@ -180,6 +256,12 @@ void EglGraphicsController::AddBuffer(GLES::Buffer& buffer)
   mCreateBufferQueue.push(&buffer);
 }
 
+void EglGraphicsController::AddFramebuffer(GLES::Framebuffer& framebuffer)
+{
+  // Assuming we are on the correct context
+  mCreateFramebufferQueue.push(&framebuffer);
+}
+
 void EglGraphicsController::ProcessDiscardQueues()
 {
   // Process textures
@@ -187,6 +269,24 @@ void EglGraphicsController::ProcessDiscardQueues()
 
   // Process buffers
   ProcessDiscardQueue<GLES::Buffer>(mDiscardBufferQueue);
+
+  // Process Framebuffers
+  ProcessDiscardQueue<GLES::Framebuffer>(mDiscardFramebufferQueue);
+
+  // Process pipelines
+  ProcessDiscardQueue<GLES::Pipeline>(mDiscardPipelineQueue);
+
+  // Process programs
+  ProcessDiscardQueue<GLES::Program>(mDiscardProgramQueue);
+
+  // Process shaders
+  ProcessDiscardQueue<GLES::Shader>(mDiscardShaderQueue);
+
+  // Process samplers
+  ProcessDiscardQueue<GLES::Sampler>(mDiscardSamplerQueue);
+
+  // Process command buffers
+  ProcessDiscardQueue<GLES::CommandBuffer>(mDiscardCommandBufferQueue);
 }
 
 void EglGraphicsController::ProcessCreateQueues()
@@ -196,73 +296,140 @@ void EglGraphicsController::ProcessCreateQueues()
 
   // Process buffers
   ProcessCreateQueue(mCreateBufferQueue);
+
+  // Process framebuffers
+  ProcessCreateQueue(mCreateFramebufferQueue);
 }
 
-void EglGraphicsController::ProcessCommandQueues()
+void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& commandBuffer)
 {
-  // TODO: command queue per context, sync between queues should be
-  // done externally
-
-  while(!mCommandQueue.empty())
+  for(auto& cmd : commandBuffer.GetCommands())
   {
-    auto cmdBuf = mCommandQueue.front();
-    mCommandQueue.pop();
-
-    for(auto& cmd : cmdBuf->GetCommands())
+    // process command
+    switch(cmd.type)
     {
-      // process command
-      switch(cmd.type)
+      case GLES::CommandType::FLUSH:
       {
-        case GLES::CommandType::FLUSH:
-        {
-          // Nothing to do here
-          break;
-        }
-        case GLES::CommandType::BIND_TEXTURES:
-        {
-          mContext->BindTextures(cmd.bindTextures.textureBindings);
-          break;
-        }
-        case GLES::CommandType::BIND_VERTEX_BUFFERS:
-        {
-          auto& bindings = cmd.bindVertexBuffers.vertexBufferBindings;
-          mContext->BindVertexBuffers(bindings);
-          break;
-        }
-        case GLES::CommandType::BIND_INDEX_BUFFER:
-        {
-          mContext->BindIndexBuffer(cmd.bindIndexBuffer);
-          break;
-        }
-        case GLES::CommandType::BIND_SAMPLERS:
-        {
-          break;
-        }
-        case GLES::CommandType::BIND_PIPELINE:
-        {
-          mContext->BindPipeline(cmd.bindPipeline.pipeline);
-          break;
-        }
-        case GLES::CommandType::DRAW:
+        // Nothing to do here
+        break;
+      }
+      case GLES::CommandType::BIND_TEXTURES:
+      {
+        mContext->BindTextures(cmd.bindTextures.textureBindings);
+        break;
+      }
+      case GLES::CommandType::BIND_VERTEX_BUFFERS:
+      {
+        auto& bindings = cmd.bindVertexBuffers.vertexBufferBindings;
+        mContext->BindVertexBuffers(bindings);
+        break;
+      }
+      case GLES::CommandType::BIND_UNIFORM_BUFFER:
+      {
+        auto& bindings = cmd.bindUniformBuffers;
+        mContext->BindUniformBuffers(bindings.uniformBufferBindings, bindings.standaloneUniformsBufferBinding);
+        break;
+      }
+      case GLES::CommandType::BIND_INDEX_BUFFER:
+      {
+        mContext->BindIndexBuffer(cmd.bindIndexBuffer);
+        break;
+      }
+      case GLES::CommandType::BIND_SAMPLERS:
+      {
+        break;
+      }
+      case GLES::CommandType::BIND_PIPELINE:
+      {
+        auto pipeline = static_cast<const GLES::Pipeline*>(cmd.bindPipeline.pipeline);
+        mContext->BindPipeline(pipeline);
+        break;
+      }
+      case GLES::CommandType::DRAW:
+      {
+        mContext->Flush(false, cmd.draw);
+        break;
+      }
+      case GLES::CommandType::DRAW_INDEXED:
+      {
+        mContext->Flush(false, cmd.draw);
+        break;
+      }
+      case GLES::CommandType::DRAW_INDEXED_INDIRECT:
+      {
+        mContext->Flush(false, cmd.draw);
+        break;
+      }
+      case GLES::CommandType::SET_SCISSOR: // @todo Consider correcting for orientation here?
+      {
+        mGlAbstraction->Scissor(cmd.scissor.region.x, cmd.scissor.region.y, cmd.scissor.region.width, cmd.scissor.region.height);
+        break;
+      }
+      case GLES::CommandType::SET_SCISSOR_TEST:
+      {
+        if(cmd.scissorTest.enable)
         {
-          mContext->Flush(false, cmd.draw);
-          break;
+          mGlAbstraction->Enable(GL_SCISSOR_TEST);
         }
-        case GLES::CommandType::DRAW_INDEXED:
+        else
         {
-          mContext->Flush(false, cmd.draw);
-          break;
+          mGlAbstraction->Disable(GL_SCISSOR_TEST);
         }
-        case GLES::CommandType::DRAW_INDEXED_INDIRECT:
+        break;
+      }
+      case GLES::CommandType::SET_VIEWPORT: // @todo Consider correcting for orientation here?
+      {
+        mGlAbstraction->Viewport(cmd.viewport.region.x, cmd.viewport.region.y, cmd.viewport.region.width, cmd.viewport.region.height);
+        break;
+      }
+      case GLES::CommandType::BEGIN_RENDERPASS:
+      {
+        mContext->BeginRenderPass(cmd.beginRenderPass);
+        break;
+      }
+      case GLES::CommandType::END_RENDERPASS:
+      {
+        mContext->EndRenderPass();
+        break;
+      }
+      case GLES::CommandType::PRESENT_RENDER_TARGET:
+      {
+        ResolvePresentRenderTarget(cmd.presentRenderTarget.targetToPresent);
+
+        // push this command buffer to the discard queue
+        mDiscardCommandBufferQueue.push(const_cast<GLES::CommandBuffer*>(&commandBuffer));
+        break;
+      }
+      case GLES::CommandType::EXECUTE_COMMAND_BUFFERS:
+      {
+        // Process secondary command buffers
+        // todo: check validity of the secondaries
+        //       there are operations which are illigal to be done
+        //       within secondaries.
+        for(auto& buf : cmd.executeCommandBuffers.buffers)
         {
-          mContext->Flush(false, cmd.draw);
-          break;
+          ProcessCommandBuffer(*static_cast<const GLES::CommandBuffer*>(buf));
         }
+        break;
       }
     }
   }
 }
 
+void EglGraphicsController::ProcessCommandQueues()
+{
+  // TODO: command queue per context, sync between queues should be
+  // done externally
+  currentFramebuffer = nullptr;
+
+  while(!mCommandQueue.empty())
+  {
+    auto cmdBuf = mCommandQueue.front();
+    mCommandQueue.pop();
+    ProcessCommandBuffer(*cmdBuf);
+  }
+}
+
 void EglGraphicsController::ProcessTextureUpdateQueue()
 {
   while(!mTextureUpdateRequests.empty())
@@ -347,12 +514,31 @@ void EglGraphicsController::UpdateTextures(const std::vector<TextureUpdateInfo>&
 
 Graphics::UniquePtr<Memory> EglGraphicsController::MapBufferRange(const MapBufferInfo& mapInfo)
 {
+  mGraphics->ActivateResourceContext();
+
   // Mapping buffer requires the object to be created NOW
   // Workaround - flush now, otherwise there will be given a staging buffer
   // in case when the buffer is not there yet
   ProcessCreateQueues();
 
-  return Graphics::UniquePtr<Memory>(new GLES::Memory(mapInfo, *this));
+  if(GetGLESVersion() < GLES::GLESVersion::GLES_30)
+  {
+    return Graphics::UniquePtr<Memory>(new GLES::Memory2(mapInfo, *this));
+  }
+  else
+  {
+    return Graphics::UniquePtr<Memory>(new GLES::Memory3(mapInfo, *this));
+  }
+}
+
+bool EglGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData)
+{
+  return static_cast<GLES::Program*>(&program)->GetImplementation()->GetParameter(parameterId, outData);
+}
+
+GLES::PipelineCache& EglGraphicsController::GetPipelineCache() const
+{
+  return *mPipelineCache;
 }
 
 } // namespace Dali::Graphics