Panning the scene view no longer redraws the whole scene
game-maker / gate (push) Successful in 2m22s
game-maker / suite (push) Successful in 8m38s

A middle-mouse pan used to run the full redraw on every frame. It
collected every object from the project, cleared and redrew every
shape, re-sorted all children and made Pixi re-upload every buffer,
although only the camera had moved. The user saw the frame rate drop
while panning.

- WorldViewport gets moveCamera(). When zoom and view size are
  unchanged it only moves the world and redraws the overlays drawn in
  screen pixels. collectFrame, the shape redraw and the re-sort drop
  out of a pan frame.
- Every full redraw remembers the box each object is culled by. A pan
  that moves an object across the edge of the view still takes the
  full redraw, so objects appear and vanish as before.
- Grid, selection outlines, rays and the container origin mark move
  into a shared drawOnScreen hook. It runs after every full redraw and
  after every pan. The parent links stay in afterItems because they
  are drawn in world units.
- Wheel zoom keeps the full redraw, because line widths follow the
  zoom. A cache for collectFrame was left out: it would save about
  1 ms and risk stale data.
- debugInfo() reports redraws and cameraMoves, and __gm gets a hook
  that forces a full redraw, so a check can compare against it.

Findings:
- Chrome already coalesces mouse moves to one per frame (500 moves
  gave 183 redraws in 189 frames). A throttle was tried and removed
  again, because its counter-check did not fail.
- A check in module 03 compared the whole gameInfo() object and broke
  on the new counters. It now compares camera, objects and rendering.
- The stall without ?vsync most likely comes from the desynchronized
  context in src/main.ts. It cannot be reproduced headless.

Tests:
- Measured on Jump and Run, main-thread time per frame, 3 runs of 240
  moves: pan 5.7-7.4 ms before, 3.8-4.8 ms after. Plain mouse moves
  stay at 2.1-2.4 ms. 208 of 240 moves took the fast path.
- ./check.sh: 141 files, 2080 tests, exit 0.
- GM_STEPS=1-16,29,42,43: 535 checks, 1 failed (the module 03 test
  above). After the fix GM_STEPS=1-5: all passed, 130 checks.
- 3 new e2e checks in 5d: 12 pan steps give 12 camera moves and 0
  full redraws, pixel rows after the pan match a fresh redraw, a box
  panned out of view and back is drawn again.
- Counter-checks: overlays not redrawn on pan gives "3 of 3 rows
  differ". Edge test disabled keeps the box visible with 0 redraws.
- Check total 1285 (1282 confirmed by CI task 229, plus 3).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-22 15:38:05 +02:00
1 parent d2d63e1681
commit 28b1afa7af
9 files changed
+136 -25

No files matched your search

+2
View File
@@ -276,6 +276,8 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
return null;
},
viewportInfo: () => viewport.debugInfo(),
/** A full redraw of the Scene tab – what a pan, which only moves the camera, is compared with. */
viewportRedraw: () => viewport.redraw(),
/** Where a dragged asset would land in the Scene tab, and why not when it may not. */
dropPreview: () => viewport.dropInfo(),
/** The panel-to-view drag in flight, if any – a drop that never started looks like a refused one. */