Create GLES::Context per render surface 33/256833/2
authorRichard Huang <r.huang@samsung.com>
Tue, 13 Apr 2021 15:35:27 +0000 (16:35 +0100)
committerRichard Huang <r.huang@samsung.com>
Wed, 14 Apr 2021 14:27:12 +0000 (14:27 +0000)
Change-Id: Id25ef7ab659e9b5b9d94be9df7e67a91797152fa

dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.h
dali/internal/graphics/gles-impl/gles-context.cpp
dali/internal/graphics/gles-impl/gles-graphics-render-target.cpp
dali/internal/graphics/gles-impl/gles-graphics-render-target.h
dali/internal/graphics/gles-impl/gles2-graphics-memory.cpp
dali/internal/graphics/gles-impl/gles3-graphics-memory.cpp
dali/internal/graphics/gles/egl-graphics.cpp
dali/internal/graphics/gles/egl-graphics.h
dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp

index d2a65fe..e766561 100644 (file)
@@ -98,8 +98,9 @@ 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);
+  mGlAbstraction  = &glAbstraction;
+  mContext        = std::make_unique<GLES::Context>(*this);
+  mCurrentContext = mContext.get();
 }
 
 void EglGraphicsController::Initialize(Integration::GlSyncAbstraction&          glSyncAbstraction,
@@ -244,6 +245,39 @@ const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Gr
   return static_cast<const Graphics::GLES::Program*>(&program)->GetReflection();
 }
 
+void EglGraphicsController::CreateSurfaceContext(Dali::RenderSurfaceInterface* surface)
+{
+  std::unique_ptr<GLES::Context> context = std::make_unique<GLES::Context>(*this);
+  mSurfaceContexts.push_back(std::move(std::make_pair(surface, std::move(context))));
+}
+
+void EglGraphicsController::DeleteSurfaceContext(Dali::RenderSurfaceInterface* surface)
+{
+  mSurfaceContexts.erase(std::remove_if(
+                           mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) { return surface == iter.first; }),
+                         mSurfaceContexts.end());
+}
+
+void EglGraphicsController::ActivateResourceContext()
+{
+  mCurrentContext = mContext.get();
+}
+
+void EglGraphicsController::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
+{
+  if(surface && mGraphics->IsResourceContextSupported())
+  {
+    auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) {
+      return (iter.first == surface);
+    });
+
+    if(iter != mSurfaceContexts.end())
+    {
+      mCurrentContext = iter->second.get();
+    }
+  }
+}
+
 void EglGraphicsController::AddTexture(GLES::Texture& texture)
 {
   // Assuming we are on the correct context
@@ -315,24 +349,24 @@ void EglGraphicsController::ProcessCommandBuffer(GLES::CommandBuffer& commandBuf
       }
       case GLES::CommandType::BIND_TEXTURES:
       {
-        mContext->BindTextures(cmd.bindTextures.textureBindings);
+        mCurrentContext->BindTextures(cmd.bindTextures.textureBindings);
         break;
       }
       case GLES::CommandType::BIND_VERTEX_BUFFERS:
       {
         auto& bindings = cmd.bindVertexBuffers.vertexBufferBindings;
-        mContext->BindVertexBuffers(bindings);
+        mCurrentContext->BindVertexBuffers(bindings);
         break;
       }
       case GLES::CommandType::BIND_UNIFORM_BUFFER:
       {
         auto& bindings = cmd.bindUniformBuffers;
-        mContext->BindUniformBuffers(bindings.uniformBufferBindings, bindings.standaloneUniformsBufferBinding);
+        mCurrentContext->BindUniformBuffers(bindings.uniformBufferBindings, bindings.standaloneUniformsBufferBinding);
         break;
       }
       case GLES::CommandType::BIND_INDEX_BUFFER:
       {
-        mContext->BindIndexBuffer(cmd.bindIndexBuffer);
+        mCurrentContext->BindIndexBuffer(cmd.bindIndexBuffer);
         break;
       }
       case GLES::CommandType::BIND_SAMPLERS:
@@ -342,22 +376,22 @@ void EglGraphicsController::ProcessCommandBuffer(GLES::CommandBuffer& commandBuf
       case GLES::CommandType::BIND_PIPELINE:
       {
         auto pipeline = static_cast<const GLES::Pipeline*>(cmd.bindPipeline.pipeline);
-        mContext->BindPipeline(pipeline);
+        mCurrentContext->BindPipeline(pipeline);
         break;
       }
       case GLES::CommandType::DRAW:
       {
-        mContext->Flush(false, cmd.draw);
+        mCurrentContext->Flush(false, cmd.draw);
         break;
       }
       case GLES::CommandType::DRAW_INDEXED:
       {
-        mContext->Flush(false, cmd.draw);
+        mCurrentContext->Flush(false, cmd.draw);
         break;
       }
       case GLES::CommandType::DRAW_INDEXED_INDIRECT:
       {
-        mContext->Flush(false, cmd.draw);
+        mCurrentContext->Flush(false, cmd.draw);
         break;
       }
       case GLES::CommandType::SET_SCISSOR: // @todo Consider correcting for orientation here?
@@ -384,12 +418,26 @@ void EglGraphicsController::ProcessCommandBuffer(GLES::CommandBuffer& commandBuf
       }
       case GLES::CommandType::BEGIN_RENDERPASS:
       {
-        mContext->BeginRenderPass(cmd.beginRenderPass);
+        auto&       renderTarget = *cmd.beginRenderPass.renderTarget;
+        const auto& targetInfo   = renderTarget.GetCreateInfo();
+
+        if(targetInfo.surface)
+        {
+          // switch to surface context
+          mGraphics->ActivateSurfaceContext(static_cast<Dali::RenderSurfaceInterface*>(targetInfo.surface));
+        }
+        else if(targetInfo.framebuffer)
+        {
+          // switch to resource context
+          mGraphics->ActivateResourceContext();
+        }
+
+        mCurrentContext->BeginRenderPass(cmd.beginRenderPass);
         break;
       }
       case GLES::CommandType::END_RENDERPASS:
       {
-        mContext->EndRenderPass();
+        mCurrentContext->EndRenderPass();
         break;
       }
       case GLES::CommandType::PRESENT_RENDER_TARGET:
index 702b028..18ea218 100644 (file)
@@ -558,6 +558,32 @@ public:
   // Resolves presentation
   void ResolvePresentRenderTarget(GLES::RenderTarget* renderTarget);
 
+  /**
+   * Creates a GLES context for the given render surface
+   *
+   * @param[in] surface The surface whose GLES context to be created.
+   */
+  void CreateSurfaceContext(Dali::RenderSurfaceInterface* surface);
+
+  /**
+   * Deletes a GLES context
+   *
+   * @param[in] surface The surface whose GLES context to be deleted.
+   */
+  void DeleteSurfaceContext(Dali::RenderSurfaceInterface* surface);
+
+  /**
+   * Activate the resource context (shared surfaceless context)
+   */
+  void ActivateResourceContext();
+
+  /**
+   * Activate the surface context
+   *
+   * @param[in] surface The surface whose context to be switched to.
+   */
+  void ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface);
+
 private:
   Integration::GlAbstraction*              mGlAbstraction{nullptr};
   Integration::GlSyncAbstraction*          mGlSyncAbstraction{nullptr};
@@ -584,7 +610,10 @@ private:
   using TextureUpdateRequest = std::pair<TextureUpdateInfo, TextureUpdateSourceInfo>;
   std::queue<TextureUpdateRequest> mTextureUpdateRequests;
 
-  std::unique_ptr<GLES::Context> mContext{nullptr}; ///< Context object handling command buffers execution
+  GLES::Context*                 mCurrentContext{nullptr}; ///< The current context
+  std::unique_ptr<GLES::Context> mContext{nullptr};        ///< Context object handling command buffers execution
+  using SurfaceContextPair = std::pair<Dali::RenderSurfaceInterface*, std::unique_ptr<GLES::Context>>;
+  std::vector<SurfaceContextPair> mSurfaceContexts; ///< Vector of surface context objects handling command buffers execution
 
   std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
 
index 00978ce..95b69c9 100644 (file)
@@ -417,7 +417,6 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin)
   auto& renderPass   = *renderPassBegin.renderPass;
   auto& renderTarget = *renderPassBegin.renderTarget;
 
-  const auto& passInfo   = renderPass.GetCreateInfo();
   const auto& targetInfo = renderTarget.GetCreateInfo();
 
   auto& gl       = *mImpl->mController.GetGL();
@@ -425,17 +424,11 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin)
 
   if(targetInfo.surface)
   {
-    // switch context to surface bound
-    graphics.ActivateSurfaceContext(static_cast<Dali::RenderSurfaceInterface*>(targetInfo.surface));
-
     // Bind surface FB
     gl.BindFramebuffer(GL_FRAMEBUFFER, 0);
   }
   else if(targetInfo.framebuffer)
   {
-    // if needed, switch to shared context.
-    graphics.ActivateResourceContext();
-
     // bind framebuffer and swap.
     renderTarget.GetFramebuffer()->Bind();
   }
index df9c4dd..efdaeb2 100644 (file)
 
 // CLASS HEADER
 #include "gles-graphics-render-target.h"
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+#include "egl-graphics-controller.h"
 #include "gles-graphics-framebuffer.h"
 
 namespace Dali::Graphics::GLES
 {
+struct RenderTarget::Impl
+{
+  Impl(EglGraphicsController& controller)
+  : controller(controller){};
+
+  ~Impl() = default;
+
+  EglGraphicsController& controller;
+};
+
 RenderTarget::RenderTarget(const Graphics::RenderTargetCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
 : RenderTargetResource(createInfo, controller)
 {
+  mImpl = std::make_unique<Impl>(controller);
+
+  if(createInfo.surface)
+  {
+    controller.CreateSurfaceContext(static_cast<Dali::RenderSurfaceInterface*>(createInfo.surface));
+  }
+}
+
+RenderTarget::~RenderTarget()
+{
+  if(mCreateInfo.surface)
+  {
+    mImpl->controller.DeleteSurfaceContext(static_cast<Dali::RenderSurfaceInterface*>(mCreateInfo.surface));
+  }
 }
 
 GLES::Framebuffer* RenderTarget::GetFramebuffer() const
index 532427f..6a9fcab 100644 (file)
@@ -43,7 +43,7 @@ public:
   /**
    * @brief Destructor
    */
-  ~RenderTarget() override = default;
+  ~RenderTarget() override;
 
   /**
    * @brief Called when GL resources are destroyed
@@ -81,6 +81,10 @@ public:
    * @brief Returns surface associated with the render target
    */
   Surface* GetSurface() const;
+
+private:
+  struct Impl;
+  std::unique_ptr<Impl> mImpl{nullptr};
 };
 
 } // namespace Dali::Graphics::GLES
index 9330c8c..a514a34 100644 (file)
@@ -82,9 +82,6 @@ void Memory2::Unlock(bool flush)
     auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
     if(!buffer->IsCPUAllocated())
     {
-      // switch to the shared context if necessary
-      auto graphics = mController.GetGraphicsInterface();
-      graphics->ActivateResourceContext();
 
       buffer->Bind(BufferUsage::VERTEX_BUFFER);
       gl->BufferSubData(GL_ARRAY_BUFFER, mMapBufferInfo.offset, mMapBufferInfo.size, mMappedPointer);
index b876cc6..3fb5da4 100644 (file)
@@ -62,10 +62,6 @@ void* Memory3::LockRegion(uint32_t offset, uint32_t size)
     }
     else
     {
-      // switch to the shared context if necessary
-      auto graphics = mController.GetGraphicsInterface();
-      graphics->ActivateResourceContext();
-
       // @TODO: trashing vertex binding, better find target that is rarely used
       buffer->Bind(Graphics::BufferUsage::VERTEX_BUFFER);
       void* ptr      = nullptr;
@@ -87,10 +83,6 @@ void Memory3::Unlock(bool flush)
     auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
     if(!buffer->IsCPUAllocated())
     {
-      // switch to the shared context if necessary
-      auto graphics = mController.GetGraphicsInterface();
-      graphics->ActivateResourceContext();
-
       buffer->Bind(Graphics::BufferUsage::VERTEX_BUFFER);
       gl->UnmapBuffer(GL_ARRAY_BUFFER);
     }
index 943312b..c0eafdb 100644 (file)
@@ -71,6 +71,8 @@ void EglGraphics::SetIsSurfacelessContextSupported(const bool isSupported)
 
 void EglGraphics::ActivateResourceContext()
 {
+  mGraphicsController.ActivateResourceContext();
+
   if(mEglImplementation && mEglImplementation->IsSurfacelessContextSupported())
   {
     // Make the shared surfaceless context as current before rendering
@@ -80,6 +82,8 @@ void EglGraphics::ActivateResourceContext()
 
 void EglGraphics::ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface)
 {
+  mGraphicsController.ActivateSurfaceContext(surface);
+
   if(surface)
   {
     surface->InitializeGraphics();
index 3f81bb9..5a5e78d 100644 (file)
@@ -84,7 +84,7 @@ public:
   void ActivateResourceContext() override;
 
   /**
-   * Activate the resource context
+   * Activate the surface context
    *
    * @param[in] surface The surface whose context to be switched to.
    */
index 083b4e4..52a11b9 100644 (file)
@@ -245,9 +245,6 @@ bool NativeRenderSurfaceEcoreWl::PreRender(bool resizingSurface, const std::vect
 
 void NativeRenderSurfaceEcoreWl::PostRender()
 {
-  // @todo: Check why did we always pass false into here previously?
-  bool replacingSurface = false;
-
   auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics*>(mGraphics);
   if(eglGraphics)
   {