From 33eabfc2ff3fc859f874084ade3861245576d098 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 26 Aug 2026 03:55:31 -0400 Subject: [PATCH] [Perf] (DirectGLES): upload the union dirty box instead of scatter rects when staging through the unpack ring (each PBO-sourced glTexSubImage is a GPU copy job on Mali; ~100 sprite rects per tick cost +6ms/frame of GPU time) --- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index df8f632c..dec11a94 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -4002,6 +4002,15 @@ namespace MobileGL::MG_Backend::DirectGLES { dirtyRectCount = textureMipmapObject->GetStorageDirtyRects( uploadTarget, level, dirtyRects, MG_State::GLState::MipmapStorage::kMaxDirtyRects); + // The scatter refinement pays only on the client-pointer path, + // where fewer bytes mean less driver-side copying. Through the + // unpack ring every glTexSubImage is a GPU copy job (Mali), so + // ~100 sprite rects become ~100 jobs whose fixed cost dwarfs + // the union box's extra bytes - measured +6 ms/frame of GPU + // time in MC's animated-atlas ticks. One box, one job. + if (BufferImpl::UnpackRingAvailable()) { + dirtyRectCount = 0; + } } const auto rectShadowPtr = [&](const MG_State::GLState::MipmapDirtyRegion& rect) { return static_cast(uploadData) +