AbstractProtectedconstructorReadonlybuffers— pool-bucketed reusable geometries of this type.
Protected ReadonlyhostPrivate ReadonlylayoutPrivategrowGrow = RELEASE + REACQUIRE — an in-place rebuild strands the old GL/GPU buffer in the renderer caches (hard leak under the WebGPU renderer via the strong Info.memoryMap). Releasing lets the old geometry reach geometry.dispose() through the normal evictor, which frees its buffers (and its texture, via the geometry dispose event) correctly on every backend. The released buffer cannot be re-picked by the best-fit scan (capacity < count); the fall-through best-fit/fresh-alloc paths set _lastAcquireRebuilt and the allocation counters.
PrivateadoptBest-fit adoption from the free buckets, else a fresh allocation. Separate from acquireGeometry so the grow path can wrap it (and the preceding release) in the OOM re-claim try/catch.
PrivateadoptBEST-fit, not first-fit: scan every pooled candidate and claim the smallest adequate one. Map iteration order is bucket-insertion order, so first-fit could pin an arbitrarily oversized buffer (e.g. a 52 MB 1M-capacity buffer) to a small node until release. The fixed texel layout makes capacity the only matching criterion.
PrivateallocateA fresh geometry at the growth-headroom capacity.
PrivatereclaimUndo a failed grow (see the OOM re-claim comment in grow): restore the buffer released at the start of the grow as the node's active entry, so the geometry the mesh still renders is neither adoptable from the free pool nor orphaned.
Two sub-cases:
The shared acquire/release/dispose lifecycle. Subclasses add their own
updateGeometry; the parent pool reads buffers (also exposed under each subclass's historical name) for stats and eviction.