From: Eunki Hong Date: Fri, 11 Apr 2025 17:09:47 +0000 (+0900) Subject: (GLES) Ensure gles framebuffer bound at shared context X-Git-Tag: dali_2.4.16~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=298317db2d70589c38da8486be1d2e68a28d2ff5;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git (GLES) Ensure gles framebuffer bound at shared context gles-context have framebuffer dependency cache objects. But now, it looks that we only allow to Create/Bind the framebuffers at shared context. Since we cant destroy the framebuffer at another context, we should ensure to remove the cache objects at shared conetext. Change-Id: I4da09e30644488dcb2f217cee1fcf2d7213b1202 Signed-off-by: Eunki Hong --- diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp index ae2d3e61f..222e1c71c 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp @@ -207,8 +207,11 @@ void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstrac mContext = std::make_unique(*this, mGlAbstraction); mCurrentContext = mContext.get(); + // Register shared context for framebuffers + GLES::Framebuffer::SetSharedContext(mCurrentContext); + static auto enableShaderUseProgramBinaryString = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_SHADER_USE_PROGRAM_BINARY); - mUseProgramBinary = enableShaderUseProgramBinaryString ? std::atoi(enableShaderUseProgramBinaryString) : false; + mUseProgramBinary = enableShaderUseProgramBinaryString ? std::atoi(enableShaderUseProgramBinaryString) : false; } void EglGraphicsController::Initialize(Integration::GraphicsSyncAbstraction& syncImplementation, @@ -270,6 +273,9 @@ void EglGraphicsController::Shutdown() // Final flush Flush(); + // Invalidate shared context for framebuffers + GLES::Framebuffer::SetSharedContext(nullptr); + if(mContext) { mContext->GlContextDestroyed(); diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.h b/dali/internal/graphics/gles-impl/egl-graphics-controller.h index 58611c6ed..8f14276c9 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.h +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.h @@ -2,7 +2,7 @@ #define DALI_EGL_GRAPHICS_CONTROLLER_H /* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * Copyright (c) 2025 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -507,6 +507,7 @@ public: !mTextureUpdateRequests.empty() || !mTextureMipmapGenerationRequests.empty()) { + // Must be ResourceContext as current if we have any resource creation. mGraphics->ActivateResourceContext(); } @@ -529,6 +530,7 @@ public: ResetBufferCache(); // Process discards + // Note : we don't need to be ResourceContext when we destroy resources. ProcessDiscardQueues(); // Flush pipeline cache to remove unused pipelines diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index eed36755a..6b766025f 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -823,7 +823,8 @@ void Context::BeginRenderPass(const BeginRenderPassDescriptor& renderPassBegin) if(targetInfo.surface) { // Bind surface FB - BindFrameBuffer(GL_FRAMEBUFFER, 0); + gl->BindFramebuffer(GL_FRAMEBUFFER, 0); + mImpl->mGlStateCache.mFrameBufferStateCache.SetCurrentFrameBuffer(0); } else if(targetInfo.framebuffer) { @@ -1213,47 +1214,6 @@ bool Context::BindBuffer(GLenum target, uint32_t bufferId) return false; } -void Context::DrawBuffers(uint32_t count, const GLenum* buffers) -{ - if(auto* gl = mImpl->GetGL()) - { - mImpl->mGlStateCache.mFrameBufferStateCache.DrawOperation(mImpl->mGlStateCache.mColorMask, - mImpl->mGlStateCache.DepthBufferWriteEnabled(), - mImpl->mGlStateCache.StencilBufferWriteEnabled()); - - gl->DrawBuffers(count, buffers); - } -} - -void Context::BindFrameBuffer(GLenum target, uint32_t bufferId) -{ - if(auto* gl = mImpl->GetGL()) - { - mImpl->mGlStateCache.mFrameBufferStateCache.SetCurrentFrameBuffer(bufferId); - - gl->BindFramebuffer(target, bufferId); - } -} - -void Context::GenFramebuffers(uint32_t count, uint32_t* framebuffers) -{ - if(auto* gl = mImpl->GetGL()) - { - gl->GenFramebuffers(count, framebuffers); - mImpl->mGlStateCache.mFrameBufferStateCache.FrameBuffersCreated(count, framebuffers); - } -} - -void Context::DeleteFramebuffers(uint32_t count, uint32_t* framebuffers) -{ - if(auto* gl = mImpl->GetGL()) - { - mImpl->mGlStateCache.mFrameBufferStateCache.FrameBuffersDeleted(count, framebuffers); - - gl->DeleteFramebuffers(count, framebuffers); - } -} - GLStateCache& Context::GetGLStateCache() { return mImpl->mGlStateCache; diff --git a/dali/internal/graphics/gles-impl/gles-context.h b/dali/internal/graphics/gles-impl/gles-context.h index 753277237..ca63593a0 100644 --- a/dali/internal/graphics/gles-impl/gles-context.h +++ b/dali/internal/graphics/gles-impl/gles-context.h @@ -207,10 +207,6 @@ public: */ bool BindBuffer(GLenum target, uint32_t bufferId); - void DrawBuffers(uint32_t count, const GLenum* buffers); - void BindFrameBuffer(GLenum target, uint32_t bufferId); - void GenFramebuffers(uint32_t count, uint32_t* framebuffers); - void DeleteFramebuffers(uint32_t count, uint32_t* framebuffers); void ColorMask(bool enabled); void ClearStencilBuffer(); void ClearDepthBuffer(); diff --git a/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.cpp b/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.cpp index 2fbb32e72..e545b9af4 100644 --- a/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.cpp +++ b/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2025 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,37 +97,41 @@ GLbitfield FrameBufferStateCache::GetClearMask(GLbitfield mask, bool forceClear, return mask; } -void FrameBufferStateCache::SetCurrentFrameBuffer(GLuint frameBufferId) +void FrameBufferStateCache::SetCurrentFrameBuffer(const GLuint framebufferId) { - mCurrentFrameBufferId = frameBufferId; + mCurrentFrameBufferId = framebufferId; } -void FrameBufferStateCache::FrameBuffersDeleted(GLsizei count, const GLuint* const frameBuffers) +void FrameBufferStateCache::FrameBufferCreated(const GLuint framebufferId) { - for(GLsizei i = 0; i < count; ++i) + // check the frame buffer doesn't exist already + FrameBufferState* state = GetFrameBufferState(framebufferId); + if(state) { - DeleteFrameBuffer(frameBuffers[i]); + DALI_LOG_ERROR("FrameBuffer already exists%d \n", framebufferId); + // reset its state + state->mState = INITIAL_FRAMEBUFFER_STATE; + return; } + + FrameBufferState newFrameBuffer(framebufferId); + mFrameBufferStates.PushBack(newFrameBuffer); } -void FrameBufferStateCache::FrameBuffersCreated(GLsizei count, const GLuint* const frameBuffers) + +void FrameBufferStateCache::FrameBufferDeleted(const GLuint framebufferId) { - for(GLsizei i = 0; i < count; ++i) - { - // check the frame buffer doesn't exist already - GLuint id = frameBuffers[i]; + FrameBufferStateVector::Iterator iter = mFrameBufferStates.Begin(); + FrameBufferStateVector::Iterator endIter = mFrameBufferStates.End(); - FrameBufferState* state = GetFrameBufferState(id); - if(state) + for(; iter != endIter; ++iter) + { + if((*iter).mId == framebufferId) { - DALI_LOG_ERROR("FrameBuffer already exists%d \n", id); - // reset its state - state->mState = INITIAL_FRAMEBUFFER_STATE; - continue; + mFrameBufferStates.Erase(iter); + return; } - - FrameBufferState newFrameBuffer(frameBuffers[i]); - mFrameBufferStates.PushBack(newFrameBuffer); } + DALI_LOG_ERROR("FrameBuffer not found %d \n", framebufferId); } void FrameBufferStateCache::DrawOperation(bool colorBuffer, bool depthBuffer, bool stencilBuffer) @@ -161,8 +165,7 @@ void FrameBufferStateCache::Reset() mFrameBufferStates.Clear(); // create the default frame buffer - GLuint id = 0; // 0 == default frame buffer id - FrameBuffersCreated(1, &id); + FrameBufferCreated(0); } void FrameBufferStateCache::SetClearState(FrameBufferState* state, GLbitfield mask) @@ -184,12 +187,12 @@ void FrameBufferStateCache::SetClearState(FrameBufferState* state, GLbitfield ma } } -FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferState(GLuint frameBufferId) +FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferState(GLuint framebufferId) { for(FrameBufferStateVector::SizeType i = 0; i < mFrameBufferStates.Count(); ++i) { FrameBufferState& state = mFrameBufferStates[i]; - if(state.mId == frameBufferId) + if(state.mId == framebufferId) { return &state; } @@ -197,22 +200,6 @@ FrameBufferStateCache::FrameBufferState* FrameBufferStateCache::GetFrameBufferSt return nullptr; } -void FrameBufferStateCache::DeleteFrameBuffer(GLuint frameBufferId) -{ - FrameBufferStateVector::Iterator iter = mFrameBufferStates.Begin(); - FrameBufferStateVector::Iterator endIter = mFrameBufferStates.End(); - - for(; iter != endIter; ++iter) - { - if((*iter).mId == frameBufferId) - { - mFrameBufferStates.Erase(iter); - return; - } - } - DALI_LOG_ERROR("FrameBuffer not found %d \n", frameBufferId); -} - } // namespace GLES } // namespace Dali::Graphics diff --git a/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.h b/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.h index 02442b85e..4610b43f6 100644 --- a/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.h +++ b/dali/internal/graphics/gles-impl/gles-framebuffer-state-cache.h @@ -2,7 +2,7 @@ #define DALI_GRAPHICS_GLES_CONTEXT_FRAMEBUFFER_STATE_CACHE_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2025 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,23 +56,21 @@ public: /** * @brief Set the current bound frame buffer - * @param[in] frameBufferId frame buffer id + * @param[in] framebufferId frame buffer id */ - void SetCurrentFrameBuffer(GLuint frameBufferId); + void SetCurrentFrameBuffer(const GLuint framebufferId); /** - * @brief Called when frame buffers are deleted - * @param[in] count number of frame buffers - * @param[in] framebuffers array of frame buffer ids + * @brief Called when frame buffer is deleted + * @param[in] framebufferId frame buffer ids */ - void FrameBuffersDeleted(GLsizei count, const GLuint* const frameBuffers); + void FrameBufferDeleted(const GLuint framebufferId); /** - * @brief Called when frame buffers are created - * @param[in] count number of frame buffers - * @param[in] framebuffers array of frame buffer ids + * @brief Called when frame buffer is created + * @param[in] framebufferId frame buffer id */ - void FrameBuffersCreated(GLsizei count, const GLuint* const frameBuffers); + void FrameBufferCreated(const GLuint framebufferId); /** * @brief Draw operation performed on the current frame buffer @@ -126,23 +124,17 @@ private: /** * @brief Helper - * @param[in] frameBufferId frame buffer id + * @param[in] framebufferId frame buffer id * @return pointer to frame buffer state object ( NULL if it doesn't exist) */ - FrameBufferState* GetFrameBufferState(GLuint frameBufferId); - - /** - * @brief Helper to delete a frame buffer state object - * @param[in] frameBufferId frame buffer id - */ - void DeleteFrameBuffer(GLuint frameBufferId); + FrameBufferState* GetFrameBufferState(GLuint framebufferId); FrameBufferStateCache(const FrameBufferStateCache&); ///< undefined copy constructor FrameBufferStateCache& operator=(const FrameBufferStateCache&); ///< undefined assignment operator -private: // data - FrameBufferStateVector mFrameBufferStates{}; ///< state of the frame buffers +private: // data + FrameBufferStateVector mFrameBufferStates{}; ///< state of the frame buffers GLuint mCurrentFrameBufferId{0}; ///< currently bound frame buffer }; diff --git a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp index e7b833138..c1e7e114b 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * Copyright (c) 2025 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ // Internal headers #include #include "egl-graphics-controller.h" +#include "gles-context.h" namespace Dali::Graphics::GLES { @@ -81,6 +82,13 @@ struct DEPTH_STENCIL_ATTACHMENT_TYPE } // anonymous namespace +Context* Framebuffer::mSharedContext = nullptr; + +void Framebuffer::SetSharedContext(Context* context) +{ + mSharedContext = context; +} + Framebuffer::Framebuffer(const Graphics::FramebufferCreateInfo& createInfo, Graphics::EglGraphicsController& controller) : FramebufferResource(createInfo, controller) { @@ -98,14 +106,16 @@ Framebuffer::~Framebuffer() = default; bool Framebuffer::InitializeResource() { - auto context = mController.GetCurrentContext(); - auto gl = mController.GetGL(); - if(gl && context && !mInitialized) + auto gl = mController.GetGL(); + if(gl && mSharedContext && !mInitialized) { + DALI_ASSERT_DEBUG(mSharedContext == mController.GetCurrentContext() && "Framebuffer is create at another context!"); mInitialized = true; - context->GenFramebuffers(1, &mFramebufferId); - context->BindFrameBuffer(GL_FRAMEBUFFER, mFramebufferId); + gl->GenFramebuffers(1, &mFramebufferId); + // @todo: Error check if FramebufferId is 0 + + gl->BindFramebuffer(GL_FRAMEBUFFER, mFramebufferId); for(Graphics::ColorAttachment& attachment : mCreateInfo.colorAttachments) { @@ -113,7 +123,7 @@ bool Framebuffer::InitializeResource() } // @todo is this per framebuffer, or more immediate state that needs setting when framebuffer changed? - context->DrawBuffers(mCreateInfo.colorAttachments.size(), COLOR_ATTACHMENTS); + gl->DrawBuffers(mCreateInfo.colorAttachments.size(), COLOR_ATTACHMENTS); // @todo Currently, we don't assume that GL_EXT_PACKED_DEPTH_STENCIL valid. // We will assume that stencilTexture / stencilBufferId always mean depth-stencil. @@ -171,7 +181,18 @@ bool Framebuffer::InitializeResource() } } - context->BindFrameBuffer(GL_FRAMEBUFFER, 0); + gl->BindFramebuffer(GL_FRAMEBUFFER, 0); + + // Update framebuffer state cache here. + auto& glStateCache = mSharedContext->GetGLStateCache(); + auto& framebufferStateCache = glStateCache.mFrameBufferStateCache; + + framebufferStateCache.FrameBufferCreated(mFramebufferId); + framebufferStateCache.SetCurrentFrameBuffer(mFramebufferId); + framebufferStateCache.DrawOperation(glStateCache.mColorMask, + glStateCache.DepthBufferWriteEnabled(), + glStateCache.StencilBufferWriteEnabled()); + framebufferStateCache.SetCurrentFrameBuffer(0); } return mInitialized; @@ -181,9 +202,8 @@ void Framebuffer::DestroyResource() { if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown())) { - auto context = mController.GetCurrentContext(); - auto gl = mController.GetGL(); - if(gl && context && mInitialized) + auto gl = mController.GetGL(); + if(gl && mInitialized) { if(mDepthBufferId) { @@ -194,7 +214,17 @@ void Framebuffer::DestroyResource() gl->DeleteRenderbuffers(1, &mStencilBufferId); } - context->DeleteFramebuffers(1, &mFramebufferId); + if(mFramebufferId != 0u) + { + gl->DeleteFramebuffers(1, &mFramebufferId); + } + + if(mSharedContext) + { + // Update framebuffer state cache here. + auto& framebufferStateCache = mSharedContext->GetGLStateCache().mFrameBufferStateCache; + framebufferStateCache.FrameBufferDeleted(mFramebufferId); + } mFramebufferId = 0u; mInitialized = false; @@ -209,12 +239,15 @@ void Framebuffer::DiscardResource() void Framebuffer::Bind() const { - auto context = mController.GetCurrentContext(); - auto gl = mController.GetGL(); - - if(gl && context) + auto gl = mController.GetGL(); + if(gl && mSharedContext) { - context->BindFrameBuffer(GL_FRAMEBUFFER, mFramebufferId); + DALI_ASSERT_DEBUG(mSharedContext == mController.GetCurrentContext() && "Framebuffer is bound to another context!"); + gl->BindFramebuffer(GL_FRAMEBUFFER, mFramebufferId); + + // Update framebuffer state cache here. + auto& framebufferStateCache = mSharedContext->GetGLStateCache().mFrameBufferStateCache; + framebufferStateCache.SetCurrentFrameBuffer(mFramebufferId); } } diff --git a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h index 430b395f5..4bcc885b2 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h @@ -2,7 +2,7 @@ #define DALI_GRAPHICS_GLES_FRAMEBUFFER_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2025 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,11 +27,17 @@ namespace Dali::Graphics::GLES { +class Context; using FramebufferResource = Resource; class Framebuffer : public FramebufferResource { public: + /** + * @brief Set the shared context. All GLES::Framebuffer class will use given context. + */ + static void SetSharedContext(Context* context); + /** * @brief Constructor * @param[in] createInfo Valid createInfo structure @@ -83,11 +89,14 @@ private: void AttachTexture(const Graphics::Texture* texture, uint32_t attachmentId, uint32_t layerId, uint32_t levelId); private: + static Context* mSharedContext; ///< The bind available context + uint32_t mFramebufferId{0u}; uint32_t mDepthBufferId{0u}; uint32_t mStencilBufferId{0u}; uint32_t mMultisamples{1u}; - bool mInitialized{false}; + + bool mInitialized{false}; }; } // namespace Dali::Graphics::GLES