mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
[Fix, Test] (MG_Pipe, clientfb, clientsp): retire every emitter's entry at the object's death - the six death helpers freed the slot and told no emitter, so a dead-but-unrecycled texture handle still resolved to the freed ITextureObject* (the allocator's generation moves only at the next hand-out) and the drain list kept the level: glTexImage2D; glDeleteTextures; <any verb> called a virtual on freed memory from the next validate point (final review C-2); the helpers now forward to the texture, renderbuffer, framebuffer, sampler-view and shader-CSO emitters between the wire delete and the free, ResolveTexture refuses a dead slot loudly on IsLive, the sticky-mask producers stamp the generation they write under, and the delete-then-use sequence is pinned for every kind, for a recycled slot, and under MALLOC_PERTURB_ on both backends
This commit is contained in:
@@ -234,7 +234,8 @@ TEST(FramebufferEmit, TheEmitterIsOneNeverDestroyedProcessSingleton) {
|
||||
X(FramebufferEmit, ANamedRecordIsSuppressedPerObjectAndNeverAgainstABoundRecord) \
|
||||
X(FramebufferEmit, ADrawBufferTokenAboveTheWireWidthIsRefusedNotTruncated) \
|
||||
X(FramebufferEmit, ALayeredCubeAttachmentDoesNotAssertAFaceItCannotKnow) \
|
||||
X(FramebufferEmit, EveryNonTexturePointCarriesTheUnknownSentinelsRatherThanZero)
|
||||
X(FramebufferEmit, EveryNonTexturePointCarriesTheUnknownSentinelsRatherThanZero) \
|
||||
X(FramebufferEmit, ADeadFramebuffersNamedRecordLatchIsRetired)
|
||||
|
||||
#define MGL_DECLARE_PULL_SKIP(Suite, Name) \
|
||||
TEST(Suite, Name) { GTEST_SKIP() << "compiled only under MOBILEGL_PIPE_PUSH"; }
|
||||
@@ -772,6 +773,27 @@ TEST(FramebufferEmit, EveryNonTexturePointCarriesTheUnknownSentinelsRatherThanZe
|
||||
"only moved field is the attachment's texture target would be suppressed";
|
||||
(void)probe;
|
||||
}
|
||||
// ============================ final review C-2 ============================
|
||||
//
|
||||
// A framebuffer has no wire lifetime (D-I2), so the only client state under its handle is this
|
||||
// emitter's per-object Named latch - and the death helper retires it before the slot is freed,
|
||||
// the shape every P4a kind takes (ID-8). A recycled handle's Gen already refused the stale
|
||||
// latch, so this pins the hygiene rather than a picture.
|
||||
TEST(FramebufferEmit, ADeadFramebuffersNamedRecordLatchIsRetired) {
|
||||
FramebufferScope scope;
|
||||
MGPipeHandle handle{};
|
||||
{
|
||||
const auto fbo = MakeShared<FramebufferObject>(31);
|
||||
const auto color = MakeColorTexture(32, 8);
|
||||
fbo->AttachTexture(FramebufferAttachmentType::Color0, color, TextureUploadTarget::Texture2D);
|
||||
handle = MGPipeFramebufferEmitter::HandleFor(*fbo);
|
||||
ASSERT_GT(Framebuffers().EmitFramebufferByName(*fbo), 0u) << "the Named record did not go out";
|
||||
ASSERT_TRUE(Framebuffers().NamedRecordIsLatched(handle));
|
||||
}
|
||||
EXPECT_FALSE(MGPipeSlots().IsLive(MGPipeKind::Framebuffer, handle));
|
||||
EXPECT_FALSE(Framebuffers().NamedRecordIsLatched(handle))
|
||||
<< "the dead framebuffer's Named latch survived its death";
|
||||
}
|
||||
#endif // MOBILEGL_PIPE_PUSH
|
||||
|
||||
// =========================================================================================
|
||||
|
||||
Reference in New Issue
Block a user