[Optimization] (MG_State/BufferState, VertexArrayState): optimize performance on vao deletion

This commit is contained in:
2025-08-06 10:32:16 +08:00
parent 25fa70ff9d
commit 2c651f2359
4 changed files with 31 additions and 29 deletions
@@ -36,6 +36,7 @@ namespace MobileGL {
return m_bindingSlots[i]; return m_bindingSlots[i];
} }
} }
assert(false);
} }
void BufferState::MarkBufferObjectForDeletion(Uint index) { void BufferState::MarkBufferObjectForDeletion(Uint index) {
+6 -2
View File
@@ -60,8 +60,12 @@ namespace MobileGL {
void GLContext::MarkBufferObjectForDeletion(Uint index) { void GLContext::MarkBufferObjectForDeletion(Uint index) {
if (ValidateBufferObject(index)) { if (ValidateBufferObject(index)) {
auto bufferObject = m_bufferState.GetBufferObject(index); auto bufferObject = m_bufferState.GetBufferObject(index);
for (SizeT i = 0; i < m_vertexArrayState.GetAllVertexArrays().size(); ++i) { auto& vaos = m_vertexArrayState.GetAllVertexArrays();
auto vao = m_vertexArrayState.GetAllVertexArrays()[i]; for (SizeT i = 0; i < vaos.size(); ++i) {
auto vao = vaos[i];
if (vao == nullptr)
continue;
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) { if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
vao->GetIndexBufferBindingSlot().Bind(nullptr); vao->GetIndexBufferBindingSlot().Bind(nullptr);
} }
@@ -8,11 +8,11 @@ namespace MobileGL {
} }
SharedPtr<VertexArrayObject> VertexArrayState::GetVertexArrayObject(Uint index) { SharedPtr<VertexArrayObject> VertexArrayState::GetVertexArrayObject(Uint index) {
auto it = m_vertexArrays.find(index); if (index >= m_vertexArrays.size())
if (it != m_vertexArrays.end()) { // FIXME: report a GL error here
return it->second;
}
return nullptr; return nullptr;
return m_vertexArrays[index];
} }
Vector<Uint> VertexArrayState::GenerateNames(Uint number) { Vector<Uint> VertexArrayState::GenerateNames(Uint number) {
@@ -23,35 +23,37 @@ namespace MobileGL {
void VertexArrayState::Bind(Uint index) { void VertexArrayState::Bind(Uint index) {
if (index == 0) { if (index == 0) {
// FIXME: should we make a dummy VAO at index 0?
m_boundVertexArray = nullptr; m_boundVertexArray = nullptr;
return; return;
} }
auto it = m_vertexArrays.find(index); m_boundVertexArray = GetVertexArrayObject(index);
if (it != m_vertexArrays.end()) {
m_boundVertexArray = it->second;
}
else {
m_boundVertexArray = nullptr;
}
} }
SharedPtr<VertexArrayObject> VertexArrayState::CreateVertexArrayObject(Uint index) { SharedPtr<VertexArrayObject> VertexArrayState::CreateVertexArrayObject(Uint index) {
auto vao = MakeShared<VertexArrayObject>(); if (index >= m_vertexArrays.size()) {
m_vertexArrays[index] = vao; // power-of-2 reallocation
m_vertexArrays.reserve(std::bit_ceil(index + 1));
m_vertexArrays.resize(index + 1, nullptr);
}
auto vao = m_vertexArrays[index] = MakeShared<VertexArrayObject>();
return vao; return vao;
} }
void VertexArrayState::MarkVertexArrayForDeletion(Uint index) { void VertexArrayState::MarkVertexArrayForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) { if (m_indexGenerator.IsValid(index)) {
if (m_boundVertexArray && m_vertexArrays.find(index) != m_vertexArrays.end() && if (m_boundVertexArray) {
m_vertexArrays[index] == m_boundVertexArray) {
m_boundVertexArray = nullptr; m_boundVertexArray = nullptr;
} }
m_vertexArrays.erase(index); if (ValidateVertexArrayObject(index)) {
m_vertexArrays[index] = nullptr;
}
m_indexGenerator.Delete(index); m_indexGenerator.Delete(index);
} }
// FIXME: report GL error here?
} }
bool VertexArrayState::ValidateName(Uint index) const { bool VertexArrayState::ValidateName(Uint index) const {
@@ -59,20 +61,15 @@ namespace MobileGL {
} }
bool VertexArrayState::ValidateVertexArrayObject(Uint index) const { bool VertexArrayState::ValidateVertexArrayObject(Uint index) const {
return m_vertexArrays.find(index) != m_vertexArrays.end(); return index < m_vertexArrays.size() && m_vertexArrays[index] != nullptr;
} }
SharedPtr<VertexArrayObject> VertexArrayState::GetBoundVertexArray() { SharedPtr<VertexArrayObject> VertexArrayState::GetBoundVertexArray() {
return m_boundVertexArray; return m_boundVertexArray;
} }
Vector<SharedPtr<VertexArrayObject>> VertexArrayState::GetAllVertexArrays() { Vector<SharedPtr<VertexArrayObject>>& VertexArrayState::GetAllVertexArrays() {
Vector<SharedPtr<VertexArrayObject>> arrays; return m_vertexArrays;
arrays.reserve(m_vertexArrays.size());
for (const auto& pair : m_vertexArrays) {
arrays.push_back(pair.second);
}
return arrays;
} }
} }
} }
@@ -15,10 +15,10 @@ namespace MobileGL {
bool ValidateName(Uint index) const; bool ValidateName(Uint index) const;
bool ValidateVertexArrayObject(Uint index) const; bool ValidateVertexArrayObject(Uint index) const;
SharedPtr<VertexArrayObject> GetBoundVertexArray(); SharedPtr<VertexArrayObject> GetBoundVertexArray();
Vector<SharedPtr<VertexArrayObject>> GetAllVertexArrays(); Vector<SharedPtr<VertexArrayObject>>& GetAllVertexArrays();
private: private:
UnorderedMap<Uint, SharedPtr<VertexArrayObject>> m_vertexArrays; Vector<SharedPtr<VertexArrayObject>> m_vertexArrays;
IndexGenerator<Uint> m_indexGenerator; IndexGenerator<Uint> m_indexGenerator;
SharedPtr<VertexArrayObject> m_boundVertexArray; SharedPtr<VertexArrayObject> m_boundVertexArray;
}; };