resize: reads before writes everywhere, and an open album drags like a closed one
This commit is contained in:
1 parent
52f5878297
commit
606250c361
2 files changed
+412
-162
No files matched your search
+19
-3
@@ -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`.
|
||||
|
||||
Reference in new issue
Block a user