mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 13:48:30 +09:00
[Perf] (MG_State/FastSTL): make object deletion cheap again
- GLContext::MarkBufferObjectForDeletion now detaches the deleted buffer only from the currently bound VAO (GL 4.6 5.1.2 semantics; other VAOs keep their shared_ptr attachments alive). The old every-VAO scan was O(VAOs) per delete - with one VAO per chunk section, vanilla chunk churn made it dominate the render thread and FPS decay over minutes. - Bump FastSTL: erase(key) destroys in place instead of building the discarded successor iterator (a linear bucket-array scan), and switch the buffer/framebuffer/renderbuffer deletion paths to the key overload. Together these removed the 34% render-thread deletion overhead measured in aged vanilla sessions (simpleperf, Adreno 830 / DirectVulkan). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,7 +64,9 @@ namespace MobileGL::MG_State::GLState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_bufferObjects.erase(it);
|
// Key-based erase skips FastSTL's successor-iterator scan, which is
|
||||||
|
// pure overhead here and dominates delete-heavy frames.
|
||||||
|
m_bufferObjects.erase(index);
|
||||||
}
|
}
|
||||||
m_indexGenerator.Delete(index);
|
m_indexGenerator.Delete(index);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,11 +80,16 @@ namespace MobileGL::MG_State {
|
|||||||
|
|
||||||
void GLContext::MarkBufferObjectForDeletion(Uint index) {
|
void GLContext::MarkBufferObjectForDeletion(Uint index) {
|
||||||
if (ValidateBufferObject(index)) {
|
if (ValidateBufferObject(index)) {
|
||||||
|
// GL semantics: deleting a buffer detaches it only from the CURRENT
|
||||||
|
// context's bindings, including the currently bound VAO's attachment
|
||||||
|
// points; attachments in other VAOs must survive (the shared_ptr keeps
|
||||||
|
// the data object alive, matching the spec's deferred deletion). The
|
||||||
|
// previous every-VAO scan was wrong per spec and O(VAOs) per delete —
|
||||||
|
// with one VAO per chunk section, vanilla's steady buffer churn made it
|
||||||
|
// dominate the render thread and FPS decay over session time.
|
||||||
auto bufferObject = m_bufferState.GetBufferObject(index);
|
auto bufferObject = m_bufferState.GetBufferObject(index);
|
||||||
auto& vaos = m_vertexArrayState.GetAllVertexArrays();
|
const auto& vao = m_vertexArrayState.GetBoundVertexArray();
|
||||||
for (auto& vao : vaos) {
|
if (vao != nullptr) {
|
||||||
if (vao == nullptr) continue;
|
|
||||||
|
|
||||||
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
|
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
|
||||||
vao->GetIndexBufferBindingSlot().Bind(nullptr);
|
vao->GetIndexBufferBindingSlot().Bind(nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace MobileGL::MG_State::GLState {
|
|||||||
bindingSlot.Bind(GetFramebufferObject(0));
|
bindingSlot.Bind(GetFramebufferObject(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_framebufferObjects.erase(it);
|
m_framebufferObjects.erase(index);
|
||||||
}
|
}
|
||||||
m_indexGenerator.Delete(index);
|
m_indexGenerator.Delete(index);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace MobileGL::MG_State::GLState {
|
|||||||
bindingSlot.Bind(nullptr);
|
bindingSlot.Bind(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_renderbufferObjects.erase(it);
|
m_renderbufferObjects.erase(index);
|
||||||
}
|
}
|
||||||
m_indexGenerator.Delete(index);
|
m_indexGenerator.Delete(index);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
Submodule include/FastSTL updated: 644b3b01e6...34f55f9df2
Reference in New Issue
Block a user