From 0d3a914f93e9882af182a36ba5cfdde3b1d954b4 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 13 Apr 2021 16:35:27 +0100 Subject: [PATCH] Create GLES::Context per render surface Change-Id: Id25ef7ab659e9b5b9d94be9df7e67a91797152fa --- .../graphics/gles-impl/egl-graphics-controller.cpp | 72 ++++++++++++++++++---- .../graphics/gles-impl/egl-graphics-controller.h | 31 +++++++++- dali/internal/graphics/gles-impl/gles-context.cpp | 7 --- .../gles-impl/gles-graphics-render-target.cpp | 28 +++++++++ .../gles-impl/gles-graphics-render-target.h | 6 +- .../graphics/gles-impl/gles2-graphics-memory.cpp | 3 - .../graphics/gles-impl/gles3-graphics-memory.cpp | 8 --- dali/internal/graphics/gles/egl-graphics.cpp | 4 ++ dali/internal/graphics/gles/egl-graphics.h | 2 +- .../native-render-surface-ecore-wl.cpp | 3 - 10 files changed, 128 insertions(+), 36 deletions(-) diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp index d2a65fe..e766561 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp @@ -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(*this); + mGlAbstraction = &glAbstraction; + mContext = std::make_unique(*this); + mCurrentContext = mContext.get(); } void EglGraphicsController::Initialize(Integration::GlSyncAbstraction& glSyncAbstraction, @@ -244,6 +245,39 @@ const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Gr return static_cast(&program)->GetReflection(); } +void EglGraphicsController::CreateSurfaceContext(Dali::RenderSurfaceInterface* surface) +{ + std::unique_ptr context = std::make_unique(*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(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(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: diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.h b/dali/internal/graphics/gles-impl/egl-graphics-controller.h index 702b028..18ea218 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.h +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.h @@ -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; std::queue mTextureUpdateRequests; - std::unique_ptr mContext{nullptr}; ///< Context object handling command buffers execution + GLES::Context* mCurrentContext{nullptr}; ///< The current context + std::unique_ptr mContext{nullptr}; ///< Context object handling command buffers execution + using SurfaceContextPair = std::pair>; + std::vector mSurfaceContexts; ///< Vector of surface context objects handling command buffers execution std::unique_ptr mPipelineCache{nullptr}; ///< Internal pipeline cache diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index 00978ce..95b69c9 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -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(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(); } diff --git a/dali/internal/graphics/gles-impl/gles-graphics-render-target.cpp b/dali/internal/graphics/gles-impl/gles-graphics-render-target.cpp index df9c4dd..efdaeb2 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-render-target.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-render-target.cpp @@ -17,13 +17,41 @@ // CLASS HEADER #include "gles-graphics-render-target.h" + +// INTERNAL INCLUDES +#include +#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(controller); + + if(createInfo.surface) + { + controller.CreateSurfaceContext(static_cast(createInfo.surface)); + } +} + +RenderTarget::~RenderTarget() +{ + if(mCreateInfo.surface) + { + mImpl->controller.DeleteSurfaceContext(static_cast(mCreateInfo.surface)); + } } GLES::Framebuffer* RenderTarget::GetFramebuffer() const diff --git a/dali/internal/graphics/gles-impl/gles-graphics-render-target.h b/dali/internal/graphics/gles-impl/gles-graphics-render-target.h index 532427f..6a9fcab 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-render-target.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-render-target.h @@ -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 mImpl{nullptr}; }; } // namespace Dali::Graphics::GLES diff --git a/dali/internal/graphics/gles-impl/gles2-graphics-memory.cpp b/dali/internal/graphics/gles-impl/gles2-graphics-memory.cpp index 9330c8c..a514a34 100644 --- a/dali/internal/graphics/gles-impl/gles2-graphics-memory.cpp +++ b/dali/internal/graphics/gles-impl/gles2-graphics-memory.cpp @@ -82,9 +82,6 @@ void Memory2::Unlock(bool flush) auto buffer = static_cast(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); diff --git a/dali/internal/graphics/gles-impl/gles3-graphics-memory.cpp b/dali/internal/graphics/gles-impl/gles3-graphics-memory.cpp index b876cc6..3fb5da4 100644 --- a/dali/internal/graphics/gles-impl/gles3-graphics-memory.cpp +++ b/dali/internal/graphics/gles-impl/gles3-graphics-memory.cpp @@ -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(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); } diff --git a/dali/internal/graphics/gles/egl-graphics.cpp b/dali/internal/graphics/gles/egl-graphics.cpp index 943312b..c0eafdb 100644 --- a/dali/internal/graphics/gles/egl-graphics.cpp +++ b/dali/internal/graphics/gles/egl-graphics.cpp @@ -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(); diff --git a/dali/internal/graphics/gles/egl-graphics.h b/dali/internal/graphics/gles/egl-graphics.h index 3f81bb9..5a5e78d 100644 --- a/dali/internal/graphics/gles/egl-graphics.h +++ b/dali/internal/graphics/gles/egl-graphics.h @@ -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. */ diff --git a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp index 083b4e4..52a11b9 100644 --- a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp @@ -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(mGraphics); if(eglGraphics) { -- 2.7.4