[Perf] (MG_State, MG_Backend/DirectGLES): skip never-touched buffer bind points via high-water mark; SyncNeccessaryBuffers 15.7% -> 4.2%

This commit is contained in:
2026-07-12 04:31:34 -04:00
parent 527e229ac8
commit 340449b77e
5 changed files with 29 additions and 1 deletions
@@ -201,7 +201,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto bindingPointCnt = MG_State::pGLContext->GetBufferBindingPointCount(target);
// Only sync up to the high-water mark of app-touched points; the fixed array is 36
// deep but apps bind a handful, so the never-touched tail is already at GL default 0.
auto bindingPointCnt = MG_State::pGLContext->GetTouchedBufferBindingPointCount(target);
for (SizeT i = 0; i < bindingPointCnt; ++i) {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(target, i);
auto& obj = point.GetBoundObject();
@@ -1310,6 +1310,7 @@ namespace MobileGL::MG_Impl::GLImpl {
BufferTarget bufferTarget = MG_Util::ConvertGLEnumToBufferTarget(target);
if (!BufferImpl::ValidateBufferBindingPointTarget(bufferTarget)) return;
if (!BufferImpl::ValidateBufferBindingPointIndex(bufferTarget, pointIndex)) return;
MG_State::pGLContext->TouchBufferBindingPoint(bufferTarget, pointIndex);
auto& point = MG_State::pGLContext->GetBufferBindingPoint(bufferTarget, pointIndex);
SharedPtr<MG_State::GLState::BufferObject> bufferObject;
@@ -1342,6 +1343,7 @@ namespace MobileGL::MG_Impl::GLImpl {
BufferTarget bufferTarget = MG_Util::ConvertGLEnumToBufferTarget(target);
if (!BufferImpl::ValidateBufferBindingPointTarget(bufferTarget)) return;
if (!BufferImpl::ValidateBufferBindingPointIndex(bufferTarget, index)) return;
MG_State::pGLContext->TouchBufferBindingPoint(bufferTarget, index);
auto& point = MG_State::pGLContext->GetBufferBindingPoint(bufferTarget, index);
SharedPtr<MG_State::GLState::BufferObject> bufferObject;
@@ -13,6 +13,9 @@ namespace MobileGL::MG_State::GLState {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<BufferObject>(GlobalBufferTargets[i]);
}
for (SizeT i = 0; i < m_touchedBindPointCount.size(); ++i) {
m_touchedBindPointCount[i] = 0;
}
}
const SharedPtr<BufferObject>& BufferState::GetBufferObject(Uint index) {
@@ -36,6 +36,20 @@ namespace MobileGL::MG_State::GLState {
auto index = std::distance(BufferBindPointTargets.begin(), it);
return m_bufferBindPointTargets[index].size();
}
// High-water mark of app-touched binding points per target (highest index + 1, 0 if none).
// Lets the backend skip syncing the never-touched tail of the fixed 36-point array each draw.
void TouchBindPoint(const BufferTarget target, Uint index) {
auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target);
if (it == BufferBindPointTargets.end()) return;
auto slot = std::distance(BufferBindPointTargets.begin(), it);
if (static_cast<SizeT>(index) + 1 > m_touchedBindPointCount[slot])
m_touchedBindPointCount[slot] = static_cast<SizeT>(index) + 1;
}
SizeT GetTouchedBindPointCount(const BufferTarget target) const {
auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target);
if (it == BufferBindPointTargets.end()) return 0;
return m_touchedBindPointCount[std::distance(BufferBindPointTargets.begin(), it)];
}
void MarkBufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateBufferObject(Uint index) const;
@@ -48,5 +62,6 @@ namespace MobileGL::MG_State::GLState {
// For glBindBufferBase / glBindBufferRange
Array<Array<BindingSlotRange1D<BufferObject>, BufferBindingPointCount>, BufferBindPointTargets.size()>
m_bufferBindPointTargets;
Array<SizeT, BufferBindPointTargets.size()> m_touchedBindPointCount;
};
} // namespace MobileGL::MG_State::GLState
+6
View File
@@ -67,6 +67,12 @@ namespace MobileGL {
constexpr SizeT GetBufferBindingPointCount(BufferTarget target) const {
return m_bufferState.GetBindingPointCount(target);
}
void TouchBufferBindingPoint(BufferTarget target, Uint index) {
m_bufferState.TouchBindPoint(target, index);
}
SizeT GetTouchedBufferBindingPointCount(BufferTarget target) const {
return m_bufferState.GetTouchedBindPointCount(target);
}
const SharedPtr<BufferObject>& CreateBufferObject(Uint index);
void MarkBufferObjectForDeletion(Uint index);
Bool ValidateBufferName(Uint index) const;