perf(distributed): skip eager probe session when chunkWorkerCount > 1 (#916)

This commit is contained in:
James Russo
2026-05-17 04:18:47 -04:00
committed by GitHub
parent 34d1f0e1d0
commit f01fccb0ea
4 changed files with 113 additions and 76 deletions
+2
View File
@@ -165,6 +165,8 @@ export {
BROWSER_GPU_NOT_SOFTWARE,
} from "./utils/assertSwiftShader.js";
export { readWebGlVendorInfoFromCanvas } from "./utils/readWebGlVendorInfoFromCanvas.js";
export {
extractMediaMetadata,
extractVideoMetadata,
@@ -23,6 +23,8 @@ import {
type BeforeCaptureHook,
} from "./frameCapture.js";
import { DEFAULT_CONFIG, type EngineConfig } from "../config.js";
import { assertSwiftShader } from "../utils/assertSwiftShader.js";
import { readWebGlVendorInfoFromCanvas } from "../utils/readWebGlVendorInfoFromCanvas.js";
export interface WorkerTask {
workerId: number;
@@ -205,6 +207,19 @@ async function executeWorkerTask(
createBeforeCaptureHook(),
config,
);
// Per-worker SwiftShader assertion: when the caller declares
// `browserGpuMode: "software"`, every worker session must verify Chrome's
// WebGL backend is actually SwiftShader before the first frame. Hosts
// that fall back to a hardware GL backend (or silently fail to load
// SwiftShader) would otherwise produce non-deterministic pixels and
// break the distributed byte-identical-retry contract — the parallel
// branch wouldn't catch it via the pre-warmup probe (renderChunk now
// skips that when chunkWorkerCount > 1). The canvas-based reader works
// on both regular Chrome and chrome-headless-shell (which serves
// `chrome://gpu` as an empty document).
if (config?.browserGpuMode === "software") {
await assertSwiftShader(session.page, readWebGlVendorInfoFromCanvas);
}
await initializeSession(session);
const outputOffset = task.outputFrameOffset ?? 0;
@@ -0,0 +1,52 @@
/**
* Read SwiftShader vendor/renderer via a 1×1 WebGL canvas + the
* `WEBGL_debug_renderer_info` extension. Used as the `readInfo` override
* for {@link assertSwiftShader} when the worker is running on
* `chrome-headless-shell` — that build serves `chrome://gpu` as an empty
* document so the default `chrome://gpu`-based info reader trips
* `net::ERR_FAILED` even when the GL backend is in fact SwiftShader.
*
* The canvas-based probe runs against whatever page the caller hands in
* (we use a fresh `about:blank` so it doesn't depend on the composition
* URL being navigated yet). The renderer string returned matches the
* format `assertSwiftShader` expects (substring match against
* `"swiftshader"`).
*/
import type { Page } from "puppeteer-core";
export async function readWebGlVendorInfoFromCanvas(
page: Page,
): Promise<{ vendor: string; renderer: string }> {
await page.goto("about:blank", { waitUntil: "domcontentloaded", timeout: 30_000 });
return page.evaluate((): { vendor: string; renderer: string } => {
try {
const canvas = document.createElement("canvas");
const gl =
(canvas.getContext("webgl") as WebGLRenderingContext | null) ??
(canvas.getContext("experimental-webgl") as WebGLRenderingContext | null);
if (!gl) {
return { vendor: "", renderer: "" };
}
const ext = gl.getExtension("WEBGL_debug_renderer_info") as {
UNMASKED_VENDOR_WEBGL: number;
UNMASKED_RENDERER_WEBGL: number;
} | null;
if (!ext) {
return {
vendor: String(gl.getParameter(gl.VENDOR) ?? ""),
renderer: String(gl.getParameter(gl.RENDERER) ?? ""),
};
}
// Older Chrome builds expose the unmasked strings under the literal
// numeric constants 0x9245 / 0x9246. The extension surface above is
// identical across builds — read through it.
return {
vendor: String(gl.getParameter(ext.UNMASKED_VENDOR_WEBGL) ?? ""),
renderer: String(gl.getParameter(ext.UNMASKED_RENDERER_WEBGL) ?? ""),
};
} catch {
return { vendor: "", renderer: "" };
}
});
}