From 6927f81754f8e0354e4aca77b4d6ec75a5a8e95a Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 28 Oct 2025 21:48:46 +0800 Subject: [PATCH] [Feat] (MG_Backend/DirectGLES): properly implement BlitFramebuffer --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 51 +++++++++++-------- MobileGL/MG_Backend/DirectGLES/DirectGLES.h | 2 + MobileGL/MG_Backend/DirectGLES/Managers.cpp | 11 ++-- MobileGL/MG_Backend/DirectGLES/Managers.h | 2 +- .../MG_Impl/GLImpl/Drawing/GL_Drawing.cpp | 2 + .../GLImpl/Framebuffer/GL_Framebuffer.cpp | 9 +++- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index ee78cbca..0f1c2b5a 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -244,6 +244,22 @@ namespace MobileGL::MG_Backend::DirectGLES { } } // namespace PrgramImpl + void BindCurrentFBO(FramebufferTarget target) { + const auto& currentFBO = + MG_State::pGLContext->GetFramebufferBindingSlot(target).GetBoundObject(); + if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) { + const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO); + if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) { + backendFBOIt->second->Bind(target); + } + } else { + if (target == FramebufferTarget::Read) + MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + else + MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + } + void PrepareForDraw() { BufferImpl::SyncNeccessaryBuffers(); VertexArrayImpl::SyncCurrentVAO(); @@ -252,16 +268,7 @@ namespace MobileGL::MG_Backend::DirectGLES { PrgramImpl::SyncCurrentProgram(); RenderStateImpl::SyncRenderState(); - const auto& currentFBO = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); - if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) { - const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO); - if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) { - backendFBOIt->second->Bind(); - } - } else { - MG_External::GLES::glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + BindCurrentFBO(FramebufferTarget::Draw); const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray(); if (currentVAO) { @@ -342,16 +349,7 @@ namespace MobileGL::MG_Backend::DirectGLES { FramebufferImpl::SyncCurrentFBO(); RenderStateImpl::SyncRenderState(); - const auto& currentFBO = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); - if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) { - const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO); - if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) { - backendFBOIt->second->Bind(); - } - } else { - MG_External::GLES::glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + BindCurrentFBO(FramebufferTarget::Draw); MG_External::GLES::glClear(mask); } @@ -376,4 +374,17 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_External::GLES::glDrawElementsBaseVertex(mode, counts[i], type, indices[i], baseVertices[i]); } } + + void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + TextureImpl::SyncNeccessaryTextures(); + FramebufferImpl::SyncCurrentFBO(); + RenderStateImpl::SyncRenderState(); + + BindCurrentFBO(FramebufferTarget::Draw); + BindCurrentFBO(FramebufferTarget::Read); + + MG_External::GLES::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, + dstX1, dstY1, mask, filter); + } } // namespace MobileGL::MG_Backend::DirectGLES diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h index e70ab38d..cf75f742 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h @@ -14,4 +14,6 @@ namespace MobileGL::MG_Backend::DirectGLES { GLsizei drawcount); void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, GLsizei drawcount, const GLint* basevertex); + void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); } // namespace MobileGL::MG_Backend::DirectGLES \ No newline at end of file diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index b1f0da68..7d02c43c 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -343,8 +343,11 @@ namespace MobileGL::MG_Backend::DirectGLES { } } - void BackendFramebufferObject::Bind() { - MG_External::GLES::glBindFramebuffer(GL_FRAMEBUFFER, m_backendFBOId); + void BackendFramebufferObject::Bind(FramebufferTarget target) { + if (target == FramebufferTarget::Read) + MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, m_backendFBOId); + else + MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId); } void BackendFramebufferObject::SyncToBackend(SharedPtr& stateFBOObject) { @@ -356,7 +359,9 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("Syncing FBO object with ID: %u to backend for state: 0x%p", m_backendFBOId, stateFBOObject.get()); BackendFramebufferBindingProtector backendFBOBindingProtector(GL_FRAMEBUFFER); - Bind(); + // TODO: do i really need to bind here? + Bind(FramebufferTarget::Read); + Bind(FramebufferTarget::Draw); // TODO: add dirty check // Sync all attachments diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 6540d5aa..036ea31e 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -85,7 +85,7 @@ namespace MobileGL::MG_Backend::DirectGLES { BackendFramebufferObject(); void SyncToBackend(SharedPtr& stateFBOObject); Uint GetBackendFramebufferId() { return m_backendFBOId; } - void Bind(); + void Bind(FramebufferTarget target); private: Uint m_backendFBOId = 0; diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index 6e33643e..dd41e454 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -1,7 +1,9 @@ #include "GL_Drawing.h" #include #include +#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES #include +#endif #include namespace MobileGL { diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index f74e97ed..2001aff4 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -1,14 +1,21 @@ #include "GL_Framebuffer.h" #include "Validators.h" +#include "Config.h" #include #include #include +#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES +#include +#endif namespace MobileGL { namespace MG_Impl::GLImpl { void BlitFramebuffer_Backend(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - // TODO: implement +#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES + MG_Backend::DirectGLES::BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, + dstX1, dstY1, mask, filter); +#endif } void SampleMaski_State(GLuint maskNumber, GLbitfield mask) {