[Fix] (MG_Backend/DirectGLES): Fix VBO binding state leakage.

This commit is contained in:
BZLZHH
2026-02-03 21:02:54 +08:00
parent d251bd3a91
commit f0ab82ea2a
2 changed files with 70 additions and 88 deletions
+18 -36
View File
@@ -43,7 +43,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
const GLenum TempBufferTarget = GL_ARRAY_BUFFER;
void BackendBufferObject::SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) { void BackendBufferObject::SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
@@ -116,7 +115,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
SizeT size = stateBufferObject->GetSize(); SizeT size = stateBufferObject->GetSize();
GLenum usage = MG_Util::ConvertBufferUsageToGLEnum(stateBufferObject->GetUsage()); GLenum usage = MG_Util::ConvertBufferUsageToGLEnum(stateBufferObject->GetUsage());
MG_External::GLES::glBindBuffer(TempBufferTarget, m_backendBufferId); Bind();
MG_External::GLES::glBufferData(TempBufferTarget, size, data, usage); MG_External::GLES::glBufferData(TempBufferTarget, size, data, usage);
} }
@@ -137,7 +136,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
for (const auto& range : ranges) { for (const auto& range : ranges) {
MG_External::GLES::glBindBuffer(TempBufferTarget, m_backendBufferId); Bind();
MG_External::GLES::glBufferSubData(TempBufferTarget, range.start, range.end - range.start, MG_External::GLES::glBufferSubData(TempBufferTarget, range.start, range.end - range.start,
reinterpret_cast<const char*>(data) + range.start); reinterpret_cast<const char*>(data) + range.start);
} }
@@ -158,7 +157,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
SizeT minStart = ranges.GetOverallMinStart(); SizeT minStart = ranges.GetOverallMinStart();
SizeT maxEnd = ranges.GetOverallMaxEnd(); SizeT maxEnd = ranges.GetOverallMaxEnd();
MG_External::GLES::glBindBuffer(TempBufferTarget, m_backendBufferId); Bind();
void* mappedData = MG_External::GLES::glMapBufferRange( void* mappedData = MG_External::GLES::glMapBufferRange(
TempBufferTarget, minStart, maxEnd - minStart, TempBufferTarget, minStart, maxEnd - minStart,
(invalidate ? GL_MAP_INVALIDATE_RANGE_BIT : 0) | (unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0) | (invalidate ? GL_MAP_INVALIDATE_RANGE_BIT : 0) | (unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0) |
@@ -182,19 +181,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
return shared_from_this(); return shared_from_this();
} }
void BackendBufferObject::Bind() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (TempBufferTarget == GL_ARRAY_BUFFER) {
if (g_boundVertexBufferObject.get() == this) {
return;
}
g_boundVertexBufferObject = GetSharedPtr();
}
MG_External::GLES::glBindBuffer(TempBufferTarget, m_backendBufferId);
}
void BackendBufferObject::Bind(GLenum target) { void BackendBufferObject::Bind(GLenum target) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
@@ -873,25 +859,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
Int frontendAttachmentToSyncCount = 0; Int frontendAttachmentToSyncCount = 0;
switch (asTarget) { switch (asTarget) {
case FramebufferTarget::Draw: { case FramebufferTarget::Draw: {
auto &stateDrawBuffers = stateFBOObject->GetDrawBuffers(); auto& stateDrawBuffers = stateFBOObject->GetDrawBuffers();
// Check if still clean, skip if clean // Check if still clean, skip if clean
if (memcmp(m_frontendDrawBuffers, if (memcmp(m_frontendDrawBuffers, stateDrawBuffers.data(),
stateDrawBuffers.data(),
FramebufferObject::MAX_DRAW_BUFFERS * sizeof(FramebufferAttachmentType)) == 0) { FramebufferObject::MAX_DRAW_BUFFERS * sizeof(FramebufferAttachmentType)) == 0) {
break; break;
} }
// Create mappings for draw buffers // Create mappings for draw buffers
int nBuffers = 0; int nBuffers = 0;
std::fill(m_frontendDrawBuffers, std::fill(m_frontendDrawBuffers, m_frontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
m_frontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
FramebufferAttachmentType::None); FramebufferAttachmentType::None);
std::fill(m_compactedFrontendDrawBuffers, std::fill(m_compactedFrontendDrawBuffers,
m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
FramebufferAttachmentType::None); FramebufferAttachmentType::None);
std::fill(m_backendDrawBuffers, std::fill(m_backendDrawBuffers, m_backendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
m_backendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
for (GLint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS; ++i) { for (GLint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
if (stateDrawBuffers[i] == FramebufferAttachmentType::None) { if (stateDrawBuffers[i] == FramebufferAttachmentType::None) {
m_frontendDrawBuffers[i] = FramebufferAttachmentType::None; m_frontendDrawBuffers[i] = FramebufferAttachmentType::None;
@@ -915,15 +898,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
case FramebufferTarget::Read: { case FramebufferTarget::Read: {
auto frontendReadBuf = stateFBOObject->GetReadBuffer(); auto frontendReadBuf = stateFBOObject->GetReadBuffer();
if (frontendReadBuf == m_frontendReadBuffer) if (frontendReadBuf == m_frontendReadBuffer) break;
break;
m_frontendReadBuffer = frontendReadBuf; m_frontendReadBuffer = frontendReadBuf;
// For consistency, we need to find the compacted attachment index of this read buffer // For consistency, we need to find the compacted attachment index of this read buffer
auto it = std::find( auto it =
m_compactedFrontendDrawBuffers, std::find(m_compactedFrontendDrawBuffers,
m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, frontendReadBuf);
frontendReadBuf);
Bool notFound = (it == m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS); Bool notFound = (it == m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS);
if (notFound) { if (notFound) {
@@ -931,8 +912,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
auto backendReadBuffer = notFound ? frontendReadBuf : *it; auto backendReadBuffer = notFound ? frontendReadBuf : *it;
GLenum glBackendReadBuffer = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(backendReadBuffer); GLenum glBackendReadBuffer = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(backendReadBuffer);
if (m_backendReadBuffer == glBackendReadBuffer) if (m_backendReadBuffer == glBackendReadBuffer) break;
break;
m_backendReadBuffer = glBackendReadBuffer; m_backendReadBuffer = glBackendReadBuffer;
MG_External::GLES::glReadBuffer(glBackendReadBuffer); MG_External::GLES::glReadBuffer(glBackendReadBuffer);
@@ -952,7 +932,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto& attachmentVersions = stateFBOObject->GetAllFramebufferAttachmentVersions(); auto& attachmentVersions = stateFBOObject->GetAllFramebufferAttachmentVersions();
for (Int i = 0; i < frontendAttachmentToSyncCount; ++i) { for (Int i = 0; i < frontendAttachmentToSyncCount; ++i) {
auto frontendAttachment = frontendAttachmentToSync[i]; auto frontendAttachment = frontendAttachmentToSync[i];
if (attachmentVersions[(SizeT)frontendAttachment] == m_syncedAttachmentVersions[(SizeT)frontendAttachment]) { if (attachmentVersions[(SizeT)frontendAttachment] ==
m_syncedAttachmentVersions[(SizeT)frontendAttachment]) {
continue; continue;
} }
m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment]; m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment];
@@ -965,10 +946,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment); SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment);
} }
FramebufferAttachmentType auxAtt[] = { FramebufferAttachmentType::Depth, FramebufferAttachmentType::Stencil }; FramebufferAttachmentType auxAtt[] = {FramebufferAttachmentType::Depth, FramebufferAttachmentType::Stencil};
for (auto & att : auxAtt) { for (auto& att : auxAtt) {
auto frontendAttachment = att; auto frontendAttachment = att;
if (attachmentVersions[(SizeT)frontendAttachment] == m_syncedAttachmentVersions[(SizeT)frontendAttachment]) { if (attachmentVersions[(SizeT)frontendAttachment] ==
m_syncedAttachmentVersions[(SizeT)frontendAttachment]) {
continue; continue;
} }
m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment]; m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment];
+2 -2
View File
@@ -17,13 +17,13 @@
namespace MobileGL::MG_Backend::DirectGLES { namespace MobileGL::MG_Backend::DirectGLES {
namespace BufferImpl { namespace BufferImpl {
const GLenum TempBufferTarget = GL_ARRAY_BUFFER;
class BackendBufferObject : public std::enable_shared_from_this<BackendBufferObject> { class BackendBufferObject : public std::enable_shared_from_this<BackendBufferObject> {
public: public:
BackendBufferObject(); BackendBufferObject();
void SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject); void SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject);
Uint GetBackendBufferId() { return m_backendBufferId; } Uint GetBackendBufferId() { return m_backendBufferId; }
void Bind(); void Bind(GLenum target = TempBufferTarget);
void Bind(GLenum target);
SharedPtr<BackendBufferObject> GetSharedPtr(); SharedPtr<BackendBufferObject> GetSharedPtr();
private: private: