From 937ace68a692bcdecfd81d92588cfddc29d31567 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Wed, 31 Dec 2025 19:45:49 +0800 Subject: [PATCH] [Feat] (MG_Backend/DirectGLES): Sync RBO in backend. --- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 82 ++++++++++++++++++++- MobileGL/MG_Backend/DirectGLES/Managers.h | 17 +++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 27687303..ba9131c8 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -652,7 +652,21 @@ namespace MobileGL::MG_Backend::DirectGLES { backendTextureObject->GetBackendTextureId(), static_cast(attachment.GetTextureLevel())); } else if (attachment.IsRenderbuffer()) { - // TODO: renderbuffer support + const auto& renderbufferObject = attachment.GetRenderbuffer(); + const auto& backendRenderbufferIt = + RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject); + SharedPtr backendRenderbufferObject; + if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) { + backendRenderbufferObject = MakeShared(); + RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject] = backendRenderbufferObject; + } else { + backendRenderbufferObject = backendRenderbufferIt->second; + } + + backendRenderbufferObject->SyncToBackend(renderbufferObject); + backendRenderbufferObject->Bind(); + MG_External::GLES::glFramebufferRenderbuffer(glFBOTarget, glAttachment, GL_RENDERBUFFER, + backendRenderbufferObject->GetBackendRenderbufferId()); } } // Handle draw buffers for DRAW_FRAMEBUFFER @@ -709,7 +723,21 @@ namespace MobileGL::MG_Backend::DirectGLES { backendTextureObject->GetBackendTextureId(), static_cast(readAttachment.GetTextureLevel())); } else if (readAttachment.IsRenderbuffer()) { - // TODO: renderbuffer support + const auto& renderbufferObject = readAttachment.GetRenderbuffer(); + const auto& backendRenderbufferIt = + RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject); + SharedPtr backendRenderbufferObject; + if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) { + backendRenderbufferObject = MakeShared(); + RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject] = backendRenderbufferObject; + } else { + backendRenderbufferObject = backendRenderbufferIt->second; + } + + backendRenderbufferObject->SyncToBackend(renderbufferObject); + backendRenderbufferObject->Bind(); + MG_External::GLES::glFramebufferRenderbuffer(glFBOTarget, glAttachment, GL_RENDERBUFFER, + backendRenderbufferObject->GetBackendRenderbufferId()); } MG_External::GLES::glReadBuffer(glAttachment); } @@ -988,5 +1016,55 @@ namespace MobileGL::MG_Backend::DirectGLES { g_backendSamplerObjects; } // namespace SamplerImpl + namespace RenderbufferImpl { + BackendRenderbufferObject::BackendRenderbufferObject() { +#ifdef TRACY_ENABLE + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); +#endif + MG_External::GLES::glGenRenderbuffers(1, &m_backendRBOId); + if (m_backendRBOId == 0) { + MGLOG_E("Failed to generate renderbuffer object."); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + } + } + + void BackendRenderbufferObject::Bind() { +#ifdef TRACY_ENABLE + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); +#endif + MG_External::GLES::glBindRenderbuffer(GL_RENDERBUFFER, m_backendRBOId); + } + + void BackendRenderbufferObject::SyncToBackend( + const SharedPtr& stateRBOObject) { +#ifdef TRACY_ENABLE + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); +#endif + if (!stateRBOObject) { + MGLOG_E("State RBO object is null, cannot sync to backend."); + return; + } + + MGLOG_D("Syncing RBO with backend ID %u to backend for state ID %u", m_backendRBOId, + stateRBOObject->GetExternalIndex()); + + Bind(); + + // Allocate storage + GLenum glInternalFormat, glType, glFormat; + TextureImpl::GenerateTextureFormatInfo(stateRBOObject->GetInternalFormat(), &glInternalFormat, &glType, + &glFormat); + + MG_External::GLES::glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, + static_cast(stateRBOObject->GetWidth()), + static_cast(stateRBOObject->GetHeight())); + + m_isInitialized = true; + } + + UnorderedMap, SharedPtr> + g_backendRenderbufferObjects; + } // namespace RenderbufferImpl + namespace Utils {} // namespace Utils } // namespace MobileGL::MG_Backend::DirectGLES diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 0bcb8d7b..97dab147 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -173,4 +173,21 @@ namespace MobileGL::MG_Backend::DirectGLES { extern UnorderedMap, SharedPtr> g_backendSamplerObjects; } // namespace SamplerImpl + + namespace RenderbufferImpl { + class BackendRenderbufferObject { + public: + BackendRenderbufferObject(); + void SyncToBackend(const SharedPtr& stateRBOObject); + Uint GetBackendRenderbufferId() { return m_backendRBOId; } + void Bind(); + + private: + Uint m_backendRBOId = 0; + Bool m_isInitialized = false; + }; + + extern UnorderedMap, SharedPtr> + g_backendRenderbufferObjects; + } // namespace RenderbufferImpl } // namespace MobileGL::MG_Backend::DirectGLES