resize: reads before writes everywhere, and an open album drags like a closed one

This commit is contained in:
KeelrLeek committed 2026-07-31 16:58:48 -05:00
1 parent 52f5878297
commit 606250c361
2 files changed
+412 -162

No files matched your search

+19 -3
View File
@@ -535,10 +535,26 @@ export function createHeroGpuRenderer(canvas, bloomCanvas, previousCanvas, previ
);
const width = Math.max(1, Math.round(rect.width * scale));
const height = Math.max(1, Math.round(rect.height * scale));
if (canvas.width !== width) canvas.width = width;
if (canvas.height !== height) canvas.height = height;
// A store within a couple of percent of the box is not visibly softer —
// that is the same argument reflow() already makes for every
// intermediate frame of a drag, and it holds just as well for the final
// one. Without the tolerance, ANY change reallocates: measured two
// ~52ms hitches landing at 1827ms and 1909ms against a drag that ended
// at 1823ms, i.e. the whole cost of a resize arriving after the user
// had stopped. paint() below is geometrically exact at any store size,
// so skipping the realloc costs nothing but sharpness we cannot see.
const REALLOC_TOLERANCE = 0.02;
const off = (a, b) => Math.abs(a - b) / Math.max(1, b) > REALLOC_TOLERANCE;
if (off(canvas.width, width) || off(canvas.height, height)) {
if (canvas.width !== width) canvas.width = width;
if (canvas.height !== height) canvas.height = height;
}
paint(rect);
gl.finish();
// gl.finish() blocks the main thread until the GPU has drained, and it
// stalls hardest exactly when the GPU is busy — which, 140ms after a
// drag, it still is. Nothing here reads back, so there is nothing to
// synchronise with; the compositor will show the frame when it is done.
gl.flush();
}
/** The ResizeObserver's path, and the reason it is not `resize`.