[Refactor] (Espryt): route every frontend read through MGB_CTX - 113 arrow sites sed'd, 9 non-arrow lines converted (the fb-slot cache keys on MGB_CTX_IDENTITY); pull build byte-identical

- P1 package B (BRIEF-P1 C.2): the four DirectGLES TUs include <MG_Pipe/PipeInputsSwitch.h> right after
  their MG_State/GLState/Core.h include (Managers.cpp after its Managers.h include) and spell every
  frontend read MGB_CTX->Accessor(...). In the pull build MGB_CTX is MG_State::pGLContext, so the
  code is the tree before this commit token for token; in the push build it is &gPipeInputs, the block
  the frontend fills at every verb boundary.
- 113 arrow occurrences on 113 lines went through the mechanical sed (DirectGLES.cpp 91, Managers.cpp 15,
  MultiDraw.cpp 5, Utils.cpp 2). The 9 non-arrow lines follow D9: Managers.cpp's five bare/compound
  guards and three ternary conditions become MGB_CTX_LIVE (UniquePtr::operator bool spelled out, so the
  pull build does not move); DirectGLES.cpp's GetFramebufferBindingSlotFast keys its static cache on
  MGB_CTX_IDENTITY (a const void* compare) instead of pGLContext.get().
- The cache refill loop dereferences MGB_CTX once into a local reference and reads the slots through it,
  instead of &MGB_CTX->GetFramebufferBindingSlot(i) per iteration as D9 spells it: a store into
  g_fbSlotCache (a pointer) may alias the unique_ptr's own pointer under clang's TBAA, so the per-iteration
  spelling re-reads pGLContext inside the loop and grows the three functions the loop is inlined into
  (SyncCurrentProgram +16, ForceBindCurrentFBO +9, BlitNamedFramebuffer +1; .text +32). Hoisting the
  dereference restores the single load and a zero .text delta.
- grep -rc pGLContext MobileGL/MG_Backend/DirectGLES reports 0 in every file; symbol_report --threshold 0
  against the 087685d1 baseline: 0 added / 0 removed / 0 resized / 0 renamed, .text +0, nm --defined-only
  set identical. The only bytes that move are __LINE__ immediates in RecordError sites after the inserted
  include line. The 8 SyncPersistentMappedRange and 3 SyncGpuWrites sites and the PipeStats AddCalls
  literals are untouched.
This commit is contained in:
2026-09-06 04:41:28 -04:00
parent 9087f13308
commit d4504e30f8
4 changed files with 129 additions and 124 deletions
+24 -23
View File
@@ -7,6 +7,7 @@
// End of Source File Header
#include "Managers.h"
#include <MG_Pipe/PipeInputsSwitch.h>
#include "Utils.h"
#include "DirectGLES.h"
#include "BackendObject_DirectGLES.h"
@@ -3641,9 +3642,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
// that needs no work costs the same nothing per draw that any other synced texture does.
void BackendTextureObject::StampViewSyncKeys(
const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
if (MG_State::pGLContext) {
m_syncedShapeContextId = MG_State::pGLContext->GetTextureContextId();
m_syncedShapeGeneration = MG_State::pGLContext->GetSamplingResolutionGeneration();
if (MGB_CTX_LIVE) {
m_syncedShapeContextId = MGB_CTX->GetTextureContextId();
m_syncedShapeGeneration = MGB_CTX->GetSamplingResolutionGeneration();
m_syncedShapeParamsVersion = stateTextureObject->GetTextureParamsVersion();
}
m_syncedContentVersion = stateTextureObject->GetContentVersion();
@@ -3770,9 +3771,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
// version - and backend-side storage resets clear m_isInitialized. Restricted to
// Mipmap storage like the probe fast path: a buffer texture's backing store can move
// without any of these keys noticing.
if (m_isInitialized && m_syncedShapeContextId != 0 && MG_State::pGLContext &&
m_syncedShapeContextId == MG_State::pGLContext->GetTextureContextId() &&
m_syncedShapeGeneration == MG_State::pGLContext->GetSamplingResolutionGeneration() &&
if (m_isInitialized && m_syncedShapeContextId != 0 && MGB_CTX_LIVE &&
m_syncedShapeContextId == MGB_CTX->GetTextureContextId() &&
m_syncedShapeGeneration == MGB_CTX->GetSamplingResolutionGeneration() &&
m_syncedContentVersion == stateTextureObject->GetContentVersion() &&
m_syncedShapeParamsVersion == stateTextureObject->GetTextureParamsVersion() &&
stateTextureObject->GetStorageType() == TextureStorageType::Mipmap) {
@@ -3841,9 +3842,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
// The probe just proved "fully synced" from the real state, so the cheap
// gate may be (re)stamped here: the coarse generation only ever goes stale
// from OTHER textures' churn, and this draw re-validated this one.
if (MG_State::pGLContext) {
m_syncedShapeContextId = MG_State::pGLContext->GetTextureContextId();
m_syncedShapeGeneration = MG_State::pGLContext->GetSamplingResolutionGeneration();
if (MGB_CTX_LIVE) {
m_syncedShapeContextId = MGB_CTX->GetTextureContextId();
m_syncedShapeGeneration = MGB_CTX->GetSamplingResolutionGeneration();
m_syncedShapeParamsVersion = stateTextureObject->GetTextureParamsVersion();
}
return;
@@ -4732,9 +4733,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Same instant, so the cheap gate's keys describe exactly this synced state.
// Only Mipmap storage may arm it - the gate refuses other storage types anyway,
// but a stale trio must not linger on an object that later switches type.
if (MG_State::pGLContext && stateTextureObject->GetStorageType() == TextureStorageType::Mipmap) {
m_syncedShapeContextId = MG_State::pGLContext->GetTextureContextId();
m_syncedShapeGeneration = MG_State::pGLContext->GetSamplingResolutionGeneration();
if (MGB_CTX_LIVE && stateTextureObject->GetStorageType() == TextureStorageType::Mipmap) {
m_syncedShapeContextId = MGB_CTX->GetTextureContextId();
m_syncedShapeGeneration = MGB_CTX->GetSamplingResolutionGeneration();
m_syncedShapeParamsVersion = stateTextureObject->GetTextureParamsVersion();
} else {
m_syncedShapeContextId = 0;
@@ -5352,7 +5353,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// read buffer names no colour attachment at all.
static const MG_State::GLState::FramebufferAttachmentObject* GetReadColorAttachment() {
const auto& readFBO =
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
if (!readFBO) {
return nullptr;
}
@@ -5457,7 +5458,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
Bool IsFixedPointFallbackReadAttachment() {
const auto& readFBO =
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
if (!readFBO) {
return false;
}
@@ -6227,7 +6228,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// outside the frontend's array, which cannot be addressed at all.
Uint BoundImageUnitFormat(Int unit) {
if (unit < 0 || unit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) return 0;
return static_cast<Uint>(MG_State::pGLContext->GetImageTextureBinding(unit).Format);
return static_cast<Uint>(MGB_CTX->GetImageTextureBinding(unit).Format);
}
// Combines one (unit, format) pair into a running digest. Commutative, so the order
@@ -7189,19 +7190,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
// patch size - so a program built for one value is stale for another. Recorded here
// and compared on the draw path (SyncCurrentProgram), the same shape as the
// storage-block and image-format signatures next to it.
const Uint patchVertices = MG_State::pGLContext != nullptr
? MG_State::pGLContext->GetPatchVertices()
const Uint patchVertices = MGB_CTX_LIVE
? MGB_CTX->GetPatchVertices()
: 3u;
m_passthroughTessControlPatchVertices = static_cast<Int>(patchVertices);
// PATCH_DEFAULT_{OUTER,INNER}_LEVEL are the same kind of dynamic state and are baked
// into the same stage (ES has no such state and no entry point to forward them to), so
// they are recorded and compared alongside the patch size - the two move together, as
// BuildPassthroughTessControlEssl's contract says.
m_passthroughTessControlOuterLevel = MG_State::pGLContext != nullptr
? MG_State::pGLContext->GetPatchDefaultOuterLevel()
m_passthroughTessControlOuterLevel = MGB_CTX_LIVE
? MGB_CTX->GetPatchDefaultOuterLevel()
: FloatVec4(1.0f, 1.0f, 1.0f, 1.0f);
m_passthroughTessControlInnerLevel = MG_State::pGLContext != nullptr
? MG_State::pGLContext->GetPatchDefaultInnerLevel()
m_passthroughTessControlInnerLevel = MGB_CTX_LIVE
? MGB_CTX->GetPatchDefaultInnerLevel()
: FloatVec2(1.0f, 1.0f);
if (tessEvalShaderIndex < 0 ||
@@ -8747,8 +8748,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_E_ONCE("Renderbuffer %u storage allocation ran out of memory: %dx%d, samples=%d, format=%s",
stateRBOObject->GetExternalIndex(), width, height, samples,
MG_Util::ConvertGLEnumToString(glInternalFormat).c_str());
if (MG_State::pGLContext) {
MG_State::pGLContext->RecordError(
if (MGB_CTX_LIVE) {
MGB_CTX->RecordError(
ErrorCode::OutOfMemory,
MakeUnique<GenericErrorInfo>("DirectGLES", "BackendRenderbufferObject::SyncToBackend",
"The ES driver could not allocate the renderbuffer storage."));