Draw the editor's dot grid with one shader on the web - #253
Conversation
The web engine redraws every recorded point on every frame: it keeps no pixels between frames the way desktop does. The editor's background grid is about 14,700 points, and while anything was dragged it was most of the frame's raster time. On the web the grid is now one rectangle drawn by a small lattice shader, with the same stretched spacing, dot size and colour and antialiasing one device pixel wide at the editor's zoom. Desktop, and screenshots, keep the points. Dragging a view cone in the signed-in web app went from 96-100 fps with #251 (83-84 before it) to 139 fps, with frames over 16.8 ms falling from hundreds per drag to about ten. At 1:1 and zoomed in, the grid matches the points to within 3/255 per pixel. Found by Astra's raster investigation. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 33 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (3)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (4)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe dot grid now uses a fragment shader for eligible web rendering, with point rendering as a fallback. InteractiveMap enables editor-zoom following, which adjusts the shader’s dot scale. ChangesDot Grid Rendering
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to The web grid can use the shader while retaining point rendering when the asset fails to load. No actionable issue remains before merge. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to This changes how the editor draws its background, not who can access or modify data. No introduced security issue was established. Loading failures retain the existing rendering path; remaining uncertainty concerns browser resource lifetimes and recovery behavior. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
A shader was made for every painter and never disposed, and its uniforms are only freed by dispose: zooming replaced the painter each step, so each step leaked one. The grid's state now owns a single shader and disposes it when the grid goes. Only the web reads the editor's zoom, so desktop records its points once again rather than on every zoom step. Found in review by Astra. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
So a grid that becomes eligible after it mounts still gets the shader, and note why one shader per grid is safe to reuse across its pictures. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A failed load left the loading flag set, so the grid drew points until the page reloaded; the next build now tries again. The shader's dot edge is now a linear ramp of about one device pixel, closer to the points' coverage than smoothstep was. dot_lattice_test paints the grid both ways in the test runner and holds the shader to the same dots in the same places: no pixel more than 48/255 apart away from the edges, total ink within 8% (both found by Greptile). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On the web, dragging anything in the editor dropped frames, even after #251 made the cone math cheap. The cause is the dotted background grid. Flutter's web renderer (CanvasKit) keeps no pixels between frames, so it redraws every recorded point every frame. The editor's grid is about 14,700 points, and while dragging it was most of the frame's raster time. Desktop isn't affected: its engine keeps the grid's pixels.
What changed
DotGridis now drawn with one rectangle and a small shader,shaders/dot_lattice.frag. It keeps the same lattice as before: spacing stretched so the outer dots sit on the edges, same dot size and colour.screenZoomProvider, and the shader repaints when the zoom changes.Measured
This is the real signed-in web app: a local build against production with a test account, a Lotus strategy, dragging a view cone along the same path in headless Edge (RTX 4070), recording requestAnimationFrame gaps. Two runs each.
Astra ran 24 experiments isolating each element of the scene: the grid, the map art, the side panel, and the cone's fill and clip. Hiding the grid cut sampled raster time from 11.75 s to 1.94 s. Caching the map or the panel did nothing measurable. The engine has no picture raster cache on the web (
CkSurface.rasterizeToCanvasreplays every picture each frame), so wrapping things in moreRepaintBoundarys wouldn't help.The drag script waits for the browser to process each mouse move before sending the next, so a slower build also gets a slower drag. Read the table as per-frame responsiveness under the same path, not frames per second of identical input. A rerun after the shader-lifetime fix gave the same numbers: 137–138 fps, 13–15 frames over 16.8 ms.
Look: screenshots of the editor at 1:1 and zoomed in about 8x match main to within 3/255 per pixel, with the dots in the same places.
Testing
kIsWebis false, so the points path is unchanged there, and the grid doesn't watch the editor's zoom.🤖 Generated with Claude Code
Summary by CodeRabbit
No outstanding findings block merging.
Summary
The PR replaces point-by-point rendering of the web editor’s dot grid with a shader while retaining point rendering for desktop, screenshots, and shader loading. The latest changes allow a failed shader load to be retried, adjust dot-edge rendering, and add a shader-versus-points rendering test. No outstanding findings remain.
Reviews (2) · Last reviewed commit: "Retry a failed grid shader load, and tes..."