[Refactor] (P13 W5 S7): the record arm's remaining transport-guarded blocks (XFB capture landing, staged-texture follows, view-window mips, tracker membership, unit-window checks) follow the record-arm guard.

This commit is contained in:
2026-10-06 13:42:45 -04:00
parent 4ec65e801a
commit 956e3847cd
8 changed files with 24 additions and 26 deletions
@@ -1691,7 +1691,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (!MG_Config::DataArmIsRecord())
#endif
if (!target.buffer) continue;
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5c: under an active transport the frontend object is client
// memory (rule E), so the persistence question is the server
// resource's and the captured bytes go back as a writeback EVENT -
@@ -11422,7 +11422,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return true;
}
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5e (tx2): the inverse of MG_Pipe::MGPipeResourceTargetForTextureTarget, for the two
// descriptor reads this file makes (Managers.cpp has the same inverse beside the storage
// sync; it is file-local there, and a header for eleven cases would be the wrong trade).
@@ -12074,7 +12074,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glBindTexture(dstTarget, cachedBound ? cachedBound->GetBackendTextureId() : 0);
}
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// WHICH LAYERS A VIEW'S MIP CHAIN MAY WRITE. A generation through a view has two coordinate
// systems in it - the view's own level/layer window (the sampler view CSO) and its storage
// owner's - and the native arm below carries only part of the first one: BASE_LEVEL and
@@ -12632,7 +12632,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return true;
}
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P8-B2: RGB16F / RGB32F MIP GENERATION ON THE SERVER, FROM THE SERVER'S OWN LEVEL.
//
// ES generates a chain only for a colour-renderable, filterable format, and whether the
@@ -12907,7 +12907,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
DebugImpl::OpenGLScopeMarker marker(__func__);
#endif
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5e (tx2), CONTRACT-P5E §5.2 / ruling 14 (ID-92's neighbour): GENERATE_MIPMAP RESOLVES
// ITS TEXTURE FROM VerbMipRes, NEVER FROM THE ACTIVE UNIT.
//
+5 -5
View File
@@ -2235,7 +2235,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
#endif
if (!resource) return;
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P11 B2: A T0 STORE TAKES A SERVER-ORIGINATED WRITE GPU-ORDERED. Its pages are the
// client's AHardwareBuffer, so there is no staged copy to refresh and the adopted
// early return below ("the coherent map already has the bytes") is false for bytes
@@ -8280,7 +8280,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
(pushedStorage != nullptr ? static_cast<TextureStorageType>(pushedStorage->Desc.StorageKind) \
: (obj)->GetStorageType())
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// SHARED IMAGES (docs/Disaggregated/notes/anland/plan-ahb-dmabuf.md). The client defined
// level 0 as WxH RGBA8 with no data and then attached the image; the record's descriptor
// still says so, but the texels are the image's, so nothing below may allocate or upload.
@@ -8480,7 +8480,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return;
}
}
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// SHARED IMAGES: ahead of the view test and of the staged-store and serial gates below,
// none of which knows the texels belong to an image - the staged store holds none of
// them, and the storage path would allocate fresh, empty storage over the image.
@@ -8636,7 +8636,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// left the backend name with no levels whatsoever, so the level that WAS defined could
// never be sampled or read back. Sync whenever some level holds an image; the per-level
// loops below skip the degenerate ones individually.
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5c (gt, CONTRACT-P5C §6 layer 1): on the staged arm the same question is answered
// out of the SERVER's staged-texture store, never out of the frontend object - the
// store's Defined-ness (fed by the respecify hook and the sub-data adoption) IS "some
@@ -9261,7 +9261,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
: nullptr;
const auto dirtyRegion = [&]() -> MG_State::GLState::MipmapDirtyRegion {
if (pendingUpload == nullptr) {
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5c (tx): a level this arm owes with NO pending upload behind it
// was dirtied by the GPU (T5), and the dirty answer is the
// server's own mark on the staged shadow - the whole level,
@@ -281,7 +281,7 @@
return true;
}
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P9 W2-a. The store's Defined-ness follows the client's respecifies; the driver's follows the
// twin's last sync. A re-mint asks this before reading a level back, because a level defined
// after that sync (null data, or null data plus a partial upload) is not on the driver yet and
@@ -535,7 +535,7 @@ namespace MobileGL::MG_Record {
// with a span (our client stages client indices into an owned element buffer and never sets
// kDrawHasUserIndices) and a multi-draw that claims instancing (no GL entry point produces
// one; the client never sends it). Only a foreign peer reaches either.
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
namespace {
// P5e (tx2), CONTRACT-P5E §5.3 / ruling 19 (ID-95, A8 closed). THE TWO UNIT WINDOWS MUST
// COVER [0, MaxTouchedTextureUnit], AND THIS IS WHERE THAT PROMISE IS CHECKED.
+2 -2
View File
@@ -2010,7 +2010,7 @@ namespace MobileGL::MG_Pipe {
}
void MGPipeApplierReleaseObjectRecords() {
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
if (MG_Config::DataArmIsRecord() &&
(g_resourceOps == nullptr || g_resourceOps->TextureDestroy == nullptr)) {
MG_Record::ServerStagedTexture().DropAll();
@@ -2780,7 +2780,7 @@ namespace MobileGL::MG_Pipe {
// AND ONLY A BUFFER IS HANDED ON, for resource_create's reason: the op table is the
// buffer family's, its Destroy takes a handle whose kind that backend registered for,
// and a texture's death is read out of the record at the sync that would have used it.
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5c (tx): with ONE exception - the staged-texture store is keyed by the handle, so
// the death must reach it or a recycled slot's stale levels would answer for the
// successor. This does not hand the texture to the buffer family's Destroy.
@@ -32,7 +32,7 @@ namespace MobileGL::MG_State::GLState {
// Starts at 1 so a zero-initialized cache slot can never carry a live buffer's id.
std::atomic<Uint64> g_nextBufferLifetimeId{1};
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5c (hd, CONTRACT-P5C §3.8 / §6 layer 1): the frontend BufferObject's legacy
// accessors are a layer-1 surface. With an active transport, the pre-handle buffer
// arm that reads them (Managers.cpp's RespecifyStorageNow / UploadRangeNow /
@@ -67,7 +67,7 @@ namespace MobileGL::MG_State::GLState {
FatalLegacyBufferArmFromApplyThread(accessor);
}
#else
// P13 W5: no transport, no apply thread to refuse.
// No record arm, no apply thread to refuse.
inline void RefuseLegacyBufferArmFromApplyThread(const char*) {}
#endif
}
@@ -97,7 +97,7 @@ namespace MobileGL::MG_State::GLState {
}
BufferObject::~BufferObject() {
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// Unconditional, not behind PushIsArmed(): the transport mode cannot change, but the
// tracker is a leaked singleton whose entries are raw pointers, and an entry that
// outlives its object is the one failure this set must not have. Forget is a no-op
@@ -406,7 +406,7 @@ namespace MobileGL::MG_State::GLState {
}
void BufferObject::SyncPersistentMappedRange() {
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P5c (hd): the named refusal comes FIRST - a silent return here used to let a
// server-side caller slip through with one MGLOG_D's worth of evidence (B3).
//
@@ -931,7 +931,7 @@ namespace MobileGL::MG_State::GLState {
!(access & BufferMappingAccessBit::FlushExplicit) &&
MG_Pipe::MGPipeResourceSubsystemEnabled()) {
if (void* pushedBase = MG_Pipe::MGPipeEmitMapPersistent(*this)) {
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P11 B2 made this reachable (a T0 adoption), so the tracker lets go of the
// shadow range WHILE THE SHADOW IS STILL OURS: AdoptPersistentMap frees it, and
// an untrack after that would mprotect pages the buffer no longer owns.
@@ -529,10 +529,9 @@ TEST(ProgramArtifactsCodec, AVersionMismatchIsRefused) {
// TProgram, which is null for every archived instance by construction and points into an arena
// no archive owns. A codec arm for it would be a use-after-free waiting for a cache hit.
TEST(ProgramArtifactsCodec, TheTablesVisitEveryMemberExceptTheLiveProgram) {
#if MOBILEGL_BUILD_DISAGGREGATED
#if MOBILEGL_BUILD_RECORD_ARM
// P7 OQ-8: 59 members, 58 visited. The 59th is still the live TProgram; the 58th is
// storageBlocks, which exists only in this build (ProgramArtifacts.h guards it so the pull
// build's LinkArtifacts keeps its size, its destructor and its .text).
// storageBlocks, which follows the record arm's guard (ProgramArtifacts.h).
EXPECT_EQ(ProgramArtifactsVisitedFieldCount<LinkArtifacts>(), 58u);
EXPECT_EQ(ProgramArtifactsVisitedFieldCount<StorageBlockReflection>(), 3u);
#else
@@ -81,10 +81,9 @@ namespace {
EXPECT_EQ(CountFields<TypeFacts>(), 20u);
EXPECT_EQ(CountFields<ResourceReflection>(), 14u);
EXPECT_EQ(CountFields<XfbVarying>(), 11u);
#if MOBILEGL_BUILD_DISAGGREGATED
// P7 OQ-8 added LinkArtifacts::storageBlocks and its own three-field table, in the
// disaggregated build only. The pull/monolith number below is the one G1 measures and
// it has not moved - which is the whole reason the member is guarded.
#if MOBILEGL_BUILD_RECORD_ARM
// P7 OQ-8 added LinkArtifacts::storageBlocks and its own three-field table; since P13 W5
// the member follows the record arm (ProgramArtifacts.h), which every library builds.
EXPECT_EQ(CountFields<StorageBlockReflection>(), 3u);
EXPECT_EQ(CountFields<LinkArtifacts>(), 58u);
#else