[Refactoring] Let perspective-enabled grids take the render early-out (track FOV/perspective_map changes in content-generation) #352
Labels
No labels
Alpha Release Requirement
Bugfix
Demo Target
Documentation
Major Feature
Minor Feature
priority:tier1-active
priority:tier2-foundation
priority:tier3-future
priority:tier4-deferred
Refactoring & Cleanup
system:animation
system:documentation
system:grid
system:input
system:performance
system:procgen
system:python-binding
system:rendering
system:ui-hierarchy
Tiny Feature
workflow:blocked
workflow:needs-benchmark
workflow:needs-documentation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
john/McRogueFace#352
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #351.
#351 adds a clean-state render early-out to
UIGridView::render()(skip the full re-rasterization when the grid's content-generation and the camera parameters are unchanged). To keep that first cut provably correct, perspective-enabled grids are carved out — they always re-render — because the perspective overlay depends on the watched entity'sperspective_map, whose values change duringUIEntity::updateVisibility()(promote/demote) without going through any tracked mutation choke point.Why this matters
grid.perspectiveis not a debug overlay — it's the core feature that binds a grid's rendered visibility to a player entity's FOV, which is the single most common "hero grid" configuration. So the #351 carve-out means the one grid a game most wants to be cheap is the one that never benefits, while secondary grids (minimaps, static UI grids, additional views of the same data) do get the early-out. That's a fine starting split, but the hero grid should eventually benefit too — e.g. a player standing still has a static FOV and should not force a full grid re-raster every frame.Proposed systemic fix
Tie perspective/FOV changes into the same content-generation signal #351 introduces:
perspective_generation) whenperspective_mapactually changes — i.e. insideUIEntity::updateVisibility()where cells are promoted/demoted (and onperspective_entityreassignment / enable-disable).UIGridView::render()can drop the "always redraw when perspective_enabled" carve-out and early-out whenever the FOV genuinely didn't change frame-to-frame.Acceptance
References
UIGridView::render()early-out)src/UIEntity.cppupdateVisibility()(perspective_map promote/demote, #294/#316),src/UIGridView.cpp:237-279(perspective overlay)The children half of this carve-out is now cheap to remove (2026-07-13)
#364 moved grid children from
GridDatatoUIGridView, so a child'sparentis now the view itself. Two consequences for this issue:The view has a precise per-child dirty signal. Any child mutation (move, recolor, add, remove) reaches the view as
render_dirtyvia the ordinary parent-chain push, andUIGridView::rendernow consultsrender_dirtyincan_skipand callsclearDirty()after rasterizing.So the
&& (!children || children->empty())carve-out incan_skipis now redundant and can be deleted -- restoring the #351 early-out for grids that have children. Today any grid with even one child pays a permanent full re-render every frame, which is the cost noted in the #364 thread. Left in place deliberately (conservative = always correct) rather than removed on a bugfix branch.Removing it needs one thing verified first: that every mutation path on a child drawable actually calls
markContentDirty()/markCompositeDirty(). If any setter is missing it, dropping the carve-out shows a stale child -- the dangerous direction. Note that #368 (thewas_dirtylatch inmarkContentDirtythat silently swallows every invalidation after the first) must be fixed before this is safe, or the propagation this relies on is not trustworthy in the first place. #368 blocks the children half of this issue.The perspective/FOV half of the carve-out is untouched and still needs its own tracking.