[Fix] (Espryt, State): let the last four object classes announce their own death and delete the twin table's garbage collector

- e2 was landed for two of six kinds, so Texture, Framebuffer, SamplerCso and
  VertexElementsCso still discovered death in a sweep and ROADMAP.md:18's "delete the GC"
  was undelivered. TextureObjectBase (the one base every concrete texture derives from),
  FramebufferObject, SamplerObject and VertexArrayObject now raise
  NotifyStateObjectDestroyed from their destructor, on RenderbufferObject's pattern: out of
  line, declared only under MOBILEGL_PIPE_PUSH, so the pull build keeps its implicit
  destructor and its symbol set (G1 still 0 added / 0 removed / 0 renamed and 0 resized
  against p2/contract).
- With all six announcing, BackendSlotTable loses BOTH sweep drivers: no draw tick, no
  creation tick, no kGCInterval / kCreationGCInterval / m_gcTick / m_creationTick.
  CollectGarbageIfNeeded() is empty on this arm; CollectGarbageNow() stays as an EXPLICIT
  collection and is the backstop for a notice that InProcessTeardown() drops.
- The seven CollectGarbageIfNeeded call sites in DirectGLES.cpp keep their spelling because
  they are the legacy registry's driver and that arm is still compiled beside this one; the
  registry's body is now guarded on MOBILEGL_PIPE_LEGACY_MEMOS, so a build without the
  legacy arm has no collector at all. On the handle arm each site is a predicted branch.
- The weak_ptr per entry stays for exactly two jobs it is honest about: ForEachLive()'s
  strong hand-over to ScopedDetachedTextureFramebufferAttachments, and the explicit
  collection. It is never an identity test; Gen is.
- Tests: AProgramAndARenderbufferAnnounceTheirOwnDeath becomes
  EveryReKeyedObjectClassAnnouncesItsOwnDeath and drives all six classes, by membership
  rather than count because every texture owns a private sampler that also announces;
  ObjectChurnAloneDrivesTheSweep becomes
  AnnouncedDeathKeepsObjectChurnFromAccumulatingWithoutASweep and pins that 256 churned
  objects hold one live twin at a time with no CollectGarbage* call anywhere.
This commit is contained in:
2026-09-07 23:18:09 -04:00
parent 7c97fcfee3
commit 6cb7d1b83b
11 changed files with 189 additions and 111 deletions
@@ -116,7 +116,15 @@ namespace MobileGL::MG_State::GLState {
class TextureObjectBase : public ITextureObject {
public:
TextureObjectBase(TextureTarget target, Uint externalIndex);
#if MOBILEGL_PIPE_PUSH
// P2 step e2. Out of line, and declared only where there is a notice to raise: in a
// pull build this stays the implicit `= default` the pre-P2 tree had, which is what
// keeps the pull build's symbol set byte-for-byte the pre-P2 one (G1). Declared on the
// BASE, so every concrete texture class - 2D, 3D, cube, buffer, view - announces once.
virtual ~TextureObjectBase();
#else
virtual ~TextureObjectBase() = default;
#endif
TextureInternalFormat GetFormat() const override;
TextureTarget GetTarget() const override;