Bound resident LOD geometry to the GPU-pool byte budget. Runs once per
frame after all entries are evaluated. This is pure policy: it does not
track bytes itself — it asks the pool for the live resident total
(getResidentBytes, the single accounting truth) and, while over the
budget ceiling (getResidentByteBudget), demotes evictable levels
(loaded, has a release thunk, not the visible child, shown at least
once).
Eviction order prioritises what is furthest from the visible: levels
under a hidden layer (effectively invisible ⇒ undrawable, so the coldest
data of all) first, then levels whose group is entirely outside the camera
frustum, then by descending camera distance, then coldest-last-visible-tick
as the final tiebreak (preserving the previous time-LRU behaviour when
spatial keys tie). Making hidden the PRIMARY key keeps a hidden layer that
happens to sit in-frustum near the camera from ranking behind a visible
layer's off-screen fine levels — undrawable geometry is always reclaimed
before anything the viewer can still draw. This pairs with the off-screen
selector gate: groups the camera turned away from drop to coarsest and are
the first to give back VRAM, keeping the on-screen working set resident.
Each release() moves that level's buffer active→pooled and
synchronously triggers the pool's byte-eviction pass, which disposes
pooled buffers (largest-first) until total resident is back under
budget — so the loop typically demotes one level then exits. The
EFFECTIVELY-visible level of each group (visible flag set and no hidden
ancestor) and eager fallback levels (no release) are never demoted; a
level whose layer is hidden is an ordinary cold candidate, including the
group's nominal displayedChildIndex — nothing of that group is on screen
to protect. Eviction is rare (only under genuine VRAM pressure),
preserving the no-churn retention property — the per-entry world-box /
frustum / distance math here only runs on that rare over-budget frame.
computeWorldBox is the registry's raw per-entry world-box fold, matching
the auto selector's frustum gate rather than its optional robust metric bounds.
Bound resident LOD geometry to the GPU-pool byte budget. Runs once per frame after all entries are evaluated. This is pure policy: it does not track bytes itself — it asks the pool for the live resident total (
getResidentBytes, the single accounting truth) and, while over the budget ceiling (getResidentByteBudget), demotes evictable levels (loaded, has areleasethunk, not the visible child, shown at least once).Eviction order prioritises what is furthest from the visible: levels under a hidden layer (effectively invisible ⇒ undrawable, so the coldest data of all) first, then levels whose group is entirely outside the camera frustum, then by descending camera distance, then coldest-last-visible-tick as the final tiebreak (preserving the previous time-LRU behaviour when spatial keys tie). Making hidden the PRIMARY key keeps a hidden layer that happens to sit in-frustum near the camera from ranking behind a visible layer's off-screen fine levels — undrawable geometry is always reclaimed before anything the viewer can still draw. This pairs with the off-screen selector gate: groups the camera turned away from drop to coarsest and are the first to give back VRAM, keeping the on-screen working set resident.
Each
release()moves that level's buffer active→pooled and synchronously triggers the pool's byte-eviction pass, which disposes pooled buffers (largest-first) until total resident is back under budget — so the loop typically demotes one level then exits. The EFFECTIVELY-visible level of each group (visible flag set and no hidden ancestor) and eager fallback levels (norelease) are never demoted; a level whose layer is hidden is an ordinary cold candidate, including the group's nominaldisplayedChildIndex— nothing of that group is on screen to protect. Eviction is rare (only under genuine VRAM pressure), preserving the no-churn retention property — the per-entry world-box / frustum / distance math here only runs on that rare over-budget frame.computeWorldBoxis the registry's raw per-entry world-box fold, matching the auto selector's frustum gate rather than its optional robust metric bounds.