mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Perf] (MG_Backend/DirectGLES, MG_Impl): cache link-time lookups, bound unit scans, honor eglSwapInterval
- BackendProgramObjectImpl::CacheResourceLocations resolves every glGetUniformBlockIndex / glGetUniformLocation string query once per link and establishes the block binding points there. Per draw, BindCurrentProgramWithResources now uses the cached indices, re-issues glUniform1i only when a sampler's unit actually changed (program state persists), uploads the global UBO only when its content version moved, and skips redundant glUseProgram binds (guard reset on program-name reuse, MakeCurrent, and every explicit glUseProgram(0)). The caches are invalidated through ProgramObject's link version, which also makes a relinked program finally re-sync its backend program. - Track a texture-unit high-water mark (fed by glBindTexture / glBindTextureUnit / glBindSampler / glBindImageTexture) so the two per-draw unit scans (MAX_TEXTURE_IMAGE_UNITS is 192) and the texture-deletion unbind loop only walk units that were ever touched. - Forward the app's eglSwapInterval to the native EGL surface through a new BackendObject::SetEGLSwapInterval hook (applied immediately when the surface exists, otherwise deferred to surface creation / MakeCurrent). "VSync off" finally reaches the hardware - DirectGLES was hard-locked to the display refresh before. The driver-side cost of the per-draw string lookups was about half of a 30% Adreno driver hotspot; libMobileGL's share of the vanilla render thread fell from 22% to 9% (simpleperf, Adreno 830). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -80,6 +80,8 @@ namespace MobileGL {
|
||||
TextureUnit& GetTextureUnitObject(Int unit);
|
||||
ImageTextureBinding& GetImageTextureBinding(Int unit);
|
||||
const ImageTextureBinding& GetImageTextureBinding(Int unit) const;
|
||||
void NoteTextureUnitTouched(Int unit) { m_textureState.NoteUnitTouched(unit); }
|
||||
Int GetMaxTouchedTextureUnit() const { return m_textureState.GetMaxTouchedUnit(); }
|
||||
Bool ValidateTextureName(Uint index) const;
|
||||
Bool ValidateTextureObject(Uint index) const;
|
||||
Int GetActiveTextureUnit() const;
|
||||
|
||||
@@ -89,20 +89,22 @@ namespace MobileGL::MG_State::GLState {
|
||||
if (m_indexGenerator.IsValid(index)) {
|
||||
auto it = m_textureObjects.find(index);
|
||||
if (it != m_textureObjects.end()) {
|
||||
for (auto& unit : m_textureUnits) {
|
||||
auto& bindingSlots = unit.GetAllBindingSlots();
|
||||
// Units past the touched high-water mark can never reference a texture.
|
||||
for (Int unit = 0; unit <= m_maxTouchedUnit; ++unit) {
|
||||
auto& bindingSlots = m_textureUnits[unit].GetAllBindingSlots();
|
||||
for (auto& bindingSlot : bindingSlots) {
|
||||
if (bindingSlot.GetBoundObject() == it->second) {
|
||||
bindingSlot.Bind(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& imageBinding : m_imageTextureBindings) {
|
||||
for (Int unit = 0; unit <= m_maxTouchedUnit; ++unit) {
|
||||
auto& imageBinding = m_imageTextureBindings[unit];
|
||||
if (imageBinding.Texture == it->second) {
|
||||
imageBinding.Bind(nullptr, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);
|
||||
}
|
||||
}
|
||||
m_textureObjects.erase(it);
|
||||
m_textureObjects.erase(index);
|
||||
}
|
||||
m_indexGenerator.Delete(index);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,16 @@ namespace MobileGL::MG_State::GLState {
|
||||
Bool ValidateName(Uint index) const;
|
||||
Bool ValidateTextureObject(Uint index) const;
|
||||
|
||||
// High-water mark of texture units ever touched by a texture or sampler bind.
|
||||
// Units above it have provably-empty binding slots, so per-draw backend scans
|
||||
// can stop there instead of walking all MAX_TEXTURE_IMAGE_UNITS units.
|
||||
void NoteUnitTouched(Int unit) {
|
||||
if (unit > m_maxTouchedUnit && unit < MAX_TEXTURE_IMAGE_UNITS) m_maxTouchedUnit = unit;
|
||||
}
|
||||
Int GetMaxTouchedUnit() const { return m_maxTouchedUnit; }
|
||||
|
||||
private:
|
||||
Int m_maxTouchedUnit = -1;
|
||||
Int m_activeTextureUnit = 0;
|
||||
Array<TextureUnit, MAX_TEXTURE_IMAGE_UNITS> m_textureUnits;
|
||||
Array<ImageTextureBinding, MAX_TEXTURE_IMAGE_UNITS> m_imageTextureBindings;
|
||||
|
||||
Reference in New Issue
Block a user