🐛 Fix playground rendering at non-unit device pixel ratio

The playground called _init and _set_render_options with the DPR,
which sets the ratio but leaves the Skia target, backbuffer and
UI surfaces at CSS resolution. The canvas drawing buffer is
physical (CSS x DPR), so at DPR > 1 the smaller surface anchored
to the bottom-left of the framebuffer and left the top and right
edges unpainted.

Call _resize_viewbox after setting the DPR, the same sequence the
application uses in resize-canvas!, so the renderer surfaces
match the physical drawing buffer.

Cover DPR 1, 1.25 and 2 in the adapter test.

AI-assisted-by: deepseek-flash
This commit is contained in:
Miguel de Benito Delgado 2026-09-19 20:30:18 +02:00
parent 34e4dc1674
commit 23109b71fe
2 changed files with 41 additions and 4 deletions

View File

@ -37,13 +37,14 @@ export function createRendererAdapter(module, scheduler = globalThis) {
handle = module.GL.registerContext(context, { majorVersion: 2 });
module.GL.makeContextCurrent(handle);
context.getExtension("WEBGL_debug_renderer_info");
module._init(
Math.round(canvas.width / dpr),
Math.round(canvas.height / dpr),
);
const width = Math.round(canvas.width / dpr);
const height = Math.round(canvas.height / dpr);
module._init(width, height);
module._set_render_options(0, dpr);
// RawBrowser::Chrome = 1; use the same default browser as the benchmark.
module._set_browser?.(1);
// Setting DPR does not resize the renderer's surfaces or framebuffer.
module._resize_viewbox(width, height);
}
function renderFull(flags = 4) {

View File

@ -47,6 +47,7 @@ function fixture() {
},
_init() {},
_set_render_options() {},
_resize_viewbox() {},
_set_browser() {},
_set_view_start() {
calls.start++;
@ -74,6 +75,41 @@ function fixture() {
return { adapter, state, calls, canvas, frames, timers, module };
}
for (const dpr of [1, 1.25, 2]) {
test(`adapter initializes the full drawing buffer at DPR ${dpr}`, () => {
const size = { width: 0, height: 0 };
let rendererDpr = 1;
const module = {
GL: {
registerContext: () => 1,
makeContextCurrent() {},
},
_init(width, height) {
Object.assign(size, { width, height });
},
_set_render_options(_flags, value) {
rendererDpr = value;
},
_resize_viewbox(width, height) {
// The renderer applies DPR when resizing, not when setting options.
Object.assign(size, {
width: width * rendererDpr,
height: height * rendererDpr,
});
},
};
const canvas = {
width: 1920 * dpr,
height: 1080 * dpr,
getContext: () => ({ getExtension() {} }),
};
createRendererAdapter(module).assignCanvas(canvas, dpr);
assert.deepEqual(size, { width: canvas.width, height: canvas.height });
});
}
test("wheel zoom flushes once per animation frame", () => {
const f = fixture();
const wheel = (deltaY, offsetX, offsetY) =>