From 8a37cc494c13b721a5d8c42fde7edaf7f44f2845 Mon Sep 17 00:00:00 2001 From: meleki Date: Tue, 29 Sep 2026 22:08:03 +0200 Subject: [PATCH] Explain reading many pixels and the remaining WSL gap (#283) --- Development.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Development.md b/Development.md index 66f008e..755e109 100644 --- a/Development.md +++ b/Development.md @@ -138,6 +138,15 @@ A menu's tick boxes are read through `t.menuTicked()` as `{ label, ticked }`. Th `tests/ui/fonts.test.ts` reads the character map straight out of the font files and fails on any character in `src/` that one of the shipped faces lacks. +**Many pixels are one read, not many.** Every `__gm.pixelAt` renders the stage into a render +texture of its own and waits for the GPU to hand the pixel back: about 2 ms here, about 7 ms +behind the WSL runner's d3d12 driver. A step that samples a grid or a strip asks +`__gm.pixels([{ x, y }, …])` (or `__gm.pixelRow(x, y, count)`) instead, which renders once around all +the points and answers each exactly as `pixelAt` would. Measured on both runners: the same colour +at all 10,680 points of six screen rows, three columns and 600 scattered points, and a row of 1280 +in 4 to 18 ms instead of 2.4 to 9.9 s. Only whole pixels at a resolution of 1 share the frame; +anything else falls back to one read a point. + **What no colour check can see: whether anything was drawn at all.** `__gm.pixelAt` re-renders the stage on demand, so it answers correctly on a screen that has been frozen for a minute — which is exactly the failure mode of drawing on change instead of every frame (see *Architecture*). The @@ -305,8 +314,12 @@ The **GPU is not in this repo**. It comes from `container.options` in each runne the GPU through Mesa's d3d12 driver: `ANGLE (Microsoft Corporation, D3D12 (NVIDIA GeForce RTX 4070), OpenGL 4.2)`, WebGL 2.0, 60 frames a second. A Wayland chromium reached the GPU as well, but let the editor's clock stall in long runs. - The suite takes about 40% longer there than here, almost all of it in the modules that read - back many pixels (drawing, tilemaps, shaders). + Every GL call there passes through ANGLE, Mesa's d3d12 driver and the Windows driver, and that + costs chromium's GPU process far more CPU than Vulkan does here: in a `perf` sample three + quarters of its time sat in the driver stack. Reading pixels back cost three times as much, + which the steps now avoid (see *Many pixels are one read* above). Frames with real work in them + (tilemaps, the graph) still take longer than here, and no chromium or Mesa switch changed that: + `mesa_glthread`, `--in-process-gpu`, software compositing and EGL were each tried and measured. Without these options chromium falls back to software rendering, and the harness stops at the renderer check.