Panning the scene view no longer redraws the whole scene
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:
1 parent
d2d63e1681
commit
28b1afa7af
9 files changed
+136
-25
No files matched your search
@@ -42,19 +42,15 @@ export class ContainerCanvas extends SceneViewport {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override beforeItems(): void {
|
||||
super.beforeItems();
|
||||
this.originMark.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* The origin, marked because it carries meaning here: it is the point the container is held by
|
||||
* when placed, so where the content sits relative to it is the thing being authored.
|
||||
*/
|
||||
protected override afterItems(items: DrawItem[], view: View): void {
|
||||
super.afterItems(items, view);
|
||||
protected override drawOnScreen(items: DrawItem[], view: View): void {
|
||||
super.drawOnScreen(items, view);
|
||||
const at = worldToScreen(view, 0, 0);
|
||||
this.originMark
|
||||
.clear()
|
||||
.moveTo(at.x - ORIGIN_ARM, at.y)
|
||||
.lineTo(at.x + ORIGIN_ARM, at.y)
|
||||
.moveTo(at.x, at.y - ORIGIN_ARM)
|
||||
|
||||
Reference in new issue
Block a user