[Feat] (MG_Backend/DirectGLES): properly implement BlitFramebuffer

This commit is contained in:
2025-10-28 21:48:46 +08:00
parent 0e01a7281e
commit 6927f81754
6 changed files with 52 additions and 25 deletions
+31 -20
View File
@@ -244,6 +244,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} // namespace PrgramImpl } // 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() { void PrepareForDraw() {
BufferImpl::SyncNeccessaryBuffers(); BufferImpl::SyncNeccessaryBuffers();
VertexArrayImpl::SyncCurrentVAO(); VertexArrayImpl::SyncCurrentVAO();
@@ -252,16 +268,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
PrgramImpl::SyncCurrentProgram(); PrgramImpl::SyncCurrentProgram();
RenderStateImpl::SyncRenderState(); RenderStateImpl::SyncRenderState();
const auto& currentFBO = BindCurrentFBO(FramebufferTarget::Draw);
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);
}
const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray(); const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray();
if (currentVAO) { if (currentVAO) {
@@ -342,16 +349,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
RenderStateImpl::SyncRenderState(); RenderStateImpl::SyncRenderState();
const auto& currentFBO = BindCurrentFBO(FramebufferTarget::Draw);
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);
}
MG_External::GLES::glClear(mask); 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]); 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 } // namespace MobileGL::MG_Backend::DirectGLES
@@ -14,4 +14,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
GLsizei drawcount); GLsizei drawcount);
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices,
GLsizei drawcount, const GLint* basevertex); 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 } // namespace MobileGL::MG_Backend::DirectGLES
+8 -3
View File
@@ -343,8 +343,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendFramebufferObject::Bind() { void BackendFramebufferObject::Bind(FramebufferTarget target) {
MG_External::GLES::glBindFramebuffer(GL_FRAMEBUFFER, m_backendFBOId); 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<MG_State::GLState::FramebufferObject>& stateFBOObject) { void BackendFramebufferObject::SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& 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()); MGLOG_D("Syncing FBO object with ID: %u to backend for state: 0x%p", m_backendFBOId, stateFBOObject.get());
BackendFramebufferBindingProtector backendFBOBindingProtector(GL_FRAMEBUFFER); BackendFramebufferBindingProtector backendFBOBindingProtector(GL_FRAMEBUFFER);
Bind(); // TODO: do i really need to bind here?
Bind(FramebufferTarget::Read);
Bind(FramebufferTarget::Draw);
// TODO: add dirty check // TODO: add dirty check
// Sync all attachments // Sync all attachments
+1 -1
View File
@@ -85,7 +85,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
BackendFramebufferObject(); BackendFramebufferObject();
void SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject); void SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject);
Uint GetBackendFramebufferId() { return m_backendFBOId; } Uint GetBackendFramebufferId() { return m_backendFBOId; }
void Bind(); void Bind(FramebufferTarget target);
private: private:
Uint m_backendFBOId = 0; Uint m_backendFBOId = 0;
@@ -1,7 +1,9 @@
#include "GL_Drawing.h" #include "GL_Drawing.h"
#include <Config.h> #include <Config.h>
#include <MG_State/GLState/Core.h> #include <MG_State/GLState/Core.h>
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
#include <MG_Backend/DirectGLES/DirectGLES.h> #include <MG_Backend/DirectGLES/DirectGLES.h>
#endif
#include <MG_Util/BackendLoaders/OpenGL/Loader.h> #include <MG_Util/BackendLoaders/OpenGL/Loader.h>
namespace MobileGL { namespace MobileGL {
@@ -1,14 +1,21 @@
#include "GL_Framebuffer.h" #include "GL_Framebuffer.h"
#include "Validators.h" #include "Validators.h"
#include "Config.h"
#include <MG_Impl/GLImpl/Texture/Validators.h> #include <MG_Impl/GLImpl/Texture/Validators.h>
#include <MG_State/GLState/ErrorState/Error.h> #include <MG_State/GLState/ErrorState/Error.h>
#include <MG_Util/Converters/GLToMG/FramebufferEnumConverter.h> #include <MG_Util/Converters/GLToMG/FramebufferEnumConverter.h>
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
#include <MG_Backend/DirectGLES/DirectGLES.h>
#endif
namespace MobileGL { namespace MobileGL {
namespace MG_Impl::GLImpl { namespace MG_Impl::GLImpl {
void BlitFramebuffer_Backend(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, void BlitFramebuffer_Backend(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0,
GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { 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) { void SampleMaski_State(GLuint maskNumber, GLbitfield mask) {