fix(ui-map): render-on-demand + drop pan inertia to stop the Safari fog freeze
The Phase 29 visibility fog ("visible hyperspace") froze the whole UI on
large reports in Safari while staying smooth in Firefox. Root cause: the
fog is a layered overpaint (torus mode = 9 world-sized rects + 9xN
near-world-sized opaque circles, ~270 fills for KNNTS041) and Pixi's
continuous auto-render loop re-rasterised all of it every frame, even
while idle. Safari's WebGPU backend cannot sustain that fillrate, so the
main thread/compositor starved and the entire UI froze.
Stage 1 (vector-preserving, no rasterisation):
- Stop Pixi's auto-render loop (app.stop()) and paint on demand via a
single Ticker.shared flush gated on viewport.dirty (camera) plus an
internal requestRender() from every content mutation (fog / hide-set /
extras / wrap mode / resize / pick overlay). An idle map now does zero
GPU work per frame; plain hover paints nothing.
- Remove the decelerate (drag-inertia) plugin: a released drag stops
instantly (owner request) and the viewport goes idle immediately.
- Expose RendererHandle.getRenderCount() / getMapRenderCount for
deterministic e2e assertions.
Tests: new map-toggles e2e specs (idle map does not repaint; released
drag does not coast) green on all four Playwright projects incl. WebKit.
Docs: renderer.md (render-on-demand section; fog section corrected to the
current single-fogLayer model; FPS note) and PLAN.md Phase 29 decision 8.
If Safari pan is still heavy after this, stage 2 will cut the overpaint
itself with an inverse stencil mask of the circle union (kept vector).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-2
@@ -3235,8 +3235,9 @@ Targeted tests:
|
||||
- `tests/map-hit-test.test.ts` — `hitTest` honours the
|
||||
`hiddenIds` parameter;
|
||||
- `tests/e2e/map-toggles.spec.ts` — cascade, fog, wrap-mode
|
||||
camera preservation, reload persistence across the four
|
||||
Playwright projects.
|
||||
camera preservation, reload persistence, plus render-on-demand
|
||||
(an idle map does not repaint; a released drag does not coast)
|
||||
across the four Playwright projects.
|
||||
|
||||
Decisions:
|
||||
|
||||
@@ -3278,6 +3279,23 @@ Decisions:
|
||||
`FligthDistance`; the Phase 29 work renamed it to
|
||||
`FlightDistance` (and the only TS call site duplicates the
|
||||
formula directly, awaiting a future race-level WASM bridge).
|
||||
8. **Render-on-demand + no pan inertia (fog perf, stage 1).** The
|
||||
renderer originally kept Pixi's continuous auto-render loop, so
|
||||
the visibility fog's layered overpaint re-rasterised every frame
|
||||
and froze the whole UI on large reports in Safari (Pixi's WebGPU
|
||||
backend) — even while idle. The renderer now stops the auto-render
|
||||
loop (`app.stop()`) and paints on demand: a single `Ticker.shared`
|
||||
flush renders only when `viewport.dirty` (camera moved) or an
|
||||
internal `requestRender()` fires from a content mutation
|
||||
(`setVisibilityFog` / `setHiddenPrimitiveIds` /
|
||||
`setExtraPrimitives` / `applyMode` / `resize` / pick overlay);
|
||||
plain hover paints nothing. The `decelerate` (drag-inertia) plugin
|
||||
is removed so a released drag stops instantly and the viewport
|
||||
goes idle immediately. `RendererHandle.getRenderCount()` (mirrored
|
||||
on `__galaxyDebug` as `getMapRenderCount`) backs the e2e
|
||||
assertions. If Safari pan is still heavy after this, stage 2 cuts
|
||||
the overpaint itself (an inverse stencil mask of the circle union,
|
||||
kept vector so the map stays crisp at any zoom).
|
||||
|
||||
## Phase 30. Calculator Tab
|
||||
|
||||
|
||||
Reference in New Issue
Block a user