feat(engine): open drawElement fast capture to Windows hardware GPU

Widen the default-on drawElement clamp from darwin-only to darwin|win32
(still requiring a non-software-GPU browser). The darwin restriction was a
validation envelope, not an architectural limit — the CanvasDrawElement
Chrome flag ships on every platform, and every safety layer that made the
macOS default-on release (v0.7.38) survivable is platform-neutral:
compile-time gates, the SwiftShader init gate, per-render worker-encode
self-verification with screenshot fallback, and the blank guard. Worst case
on an unvalidated D3D11 backend is the same as on Metal: verify catches a
bad frame and the render re-runs on the screenshot baseline.

Why now: 30-day telemetry shows ~206k non-CI hardware-GPU Windows renders
(~78% of the win32 fleet, 18k installs) held on the slow screenshot path by
the clamp — the second-largest perf population after macOS, carrying ~1,550
capture-hours/month in the DE-eligible >=700-frame band alone at a measured
~2x speedup opportunity.

Instrumentation for the new cohort: drawElement session init now records the
raw WebGL UNMASKED_RENDERER_WEBGL string (detectSwiftShader generalized to
detectGpuBackend — same single evaluate, the string was previously read and
discarded) and threads it session -> CapturePerfSummary -> RenderPerfSummary
-> render_complete as `gpu_renderer`. drawElement damage proved
compositor-backend-specific throughout the macOS rollout, so D3D11-cohort
failures must cluster by ANGLE backend + GPU vendor (NVIDIA/AMD/Intel), not
just `os`.

The two DE clamp branches are extracted into a pure, unit-tested
`resolveDefaultDrawElement` (platform + GPU mode + worker-encode + explicit
opt-in), which also drops resolveConfig's cyclomatic complexity. The win32
streaming-encode compound tests collapse onto one shared helper.

Linux stays excluded: that fleet is headless/Docker SwiftShader, where DE
has no speedup and known rendering defects. Kill switches unchanged:
PRODUCER_EXPERIMENTAL_FAST_CAPTURE=false, --experimental-fast-capture=false.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-07-28 00:00:21 -07:00
co-authored by Claude Opus 5
parent 3c857d768b
commit cb30157ebb
10 changed files with 252 additions and 111 deletions
+94 -58
View File
@@ -3,6 +3,7 @@ import { join } from "node:path";
import { tmpdir } from "node:os";
import {
resolveConfig,
resolveDefaultDrawElement,
DEFAULT_CONFIG,
scaleProtocolTimeoutForComposition,
shouldClampToScreenshotForConcreteGpu,
@@ -232,6 +233,40 @@ describe("resolveConfig", () => {
});
});
describe("resolveDefaultDrawElement (pure host clamp)", () => {
const base = {
useDrawElement: true,
explicitOptIn: false,
browserGpuMode: "hardware" as const,
workerEncode: true,
};
it("engages on darwin and win32, not linux", () => {
expect(resolveDefaultDrawElement({ ...base, platform: "darwin" })).toBe(true);
expect(resolveDefaultDrawElement({ ...base, platform: "win32" })).toBe(true);
expect(resolveDefaultDrawElement({ ...base, platform: "linux" })).toBe(false);
});
it("software GPU clamps off even on supported platforms", () => {
expect(
resolveDefaultDrawElement({ ...base, platform: "win32", browserGpuMode: "software" }),
).toBe(false);
});
it("explicit opt-in overrides platform and GPU clamps", () => {
expect(
resolveDefaultDrawElement({
...base,
explicitOptIn: true,
platform: "linux",
browserGpuMode: "software",
}),
).toBe(true);
});
it("no worker-encode (no verify net) clamps the default off", () => {
expect(resolveDefaultDrawElement({ ...base, platform: "darwin", workerEncode: false })).toBe(
false,
);
});
});
describe("useDrawElement (PRODUCER_EXPERIMENTAL_FAST_CAPTURE)", () => {
it("default is clamped off on software-GPU hosts (page-side compositing preserved)", () => {
setEnv("PRODUCER_BROWSER_GPU_MODE", "software");
@@ -242,21 +277,20 @@ describe("resolveConfig", () => {
expect(config.enablePageSideCompositing).toBe(true);
});
it("default engages on macOS with a hardware-GPU browser", () => {
setEnv("PRODUCER_BROWSER_GPU_MODE", "hardware");
unsetEnv("PRODUCER_EXPERIMENTAL_FAST_CAPTURE");
unsetEnv("HF_DE_WORKER_ENCODE");
const config = resolveConfig();
expect(config.useDrawElement).toBe(process.platform === "darwin");
});
it("default engages on macOS with auto GPU mode (the stock CLI path)", () => {
setEnv("PRODUCER_BROWSER_GPU_MODE", "auto");
unsetEnv("PRODUCER_EXPERIMENTAL_FAST_CAPTURE");
unsetEnv("HF_DE_WORKER_ENCODE");
const config = resolveConfig();
expect(config.useDrawElement).toBe(process.platform === "darwin");
});
// win32 opened 2026-07-27 (was darwin-only): ~206k non-CI hardware-GPU
// Windows renders / 30d sat on the screenshot path behind the old clamp.
// "auto" is the stock CLI path; both must pass the platform clamp.
for (const gpuMode of ["hardware", "auto"] as const) {
it(`default engages on macOS/Windows with ${gpuMode} GPU mode`, () => {
setEnv("PRODUCER_BROWSER_GPU_MODE", gpuMode);
unsetEnv("PRODUCER_EXPERIMENTAL_FAST_CAPTURE");
unsetEnv("HF_DE_WORKER_ENCODE");
const config = resolveConfig();
expect(config.useDrawElement).toBe(
process.platform === "darwin" || process.platform === "win32",
);
});
}
it("default requires worker-encode (the verified drain)", () => {
setEnv("PRODUCER_BROWSER_GPU_MODE", "hardware");
@@ -624,40 +658,58 @@ describe("resolveConfig", () => {
Object.defineProperty(process, "platform", { value: originalPlatform, configurable: true });
});
it("auto-disables on win32 + software-GPU + workers=1 + no user opt-in", () => {
setPlatform("win32");
setEnv("PRODUCER_BROWSER_GPU_MODE", "software");
setEnv("PRODUCER_MAX_WORKERS", "1");
/**
* Shared setup/assert for the win32 software-GPU compound: fixed common
* env (low-memory on, no explicit streaming opt-in), variable platform /
* gpu / workers, then assert whether the auto-disable fired.
*/
function expectCompoundOutcome(opts: {
platform: NodeJS.Platform;
gpuMode?: string;
workers?: string;
autoDisabled: boolean;
}): void {
setPlatform(opts.platform);
if (opts.gpuMode === undefined) unsetEnv("PRODUCER_BROWSER_GPU_MODE");
else setEnv("PRODUCER_BROWSER_GPU_MODE", opts.gpuMode);
if (opts.workers === undefined) unsetEnv("PRODUCER_MAX_WORKERS");
else setEnv("PRODUCER_MAX_WORKERS", opts.workers);
setEnv("PRODUCER_LOW_MEMORY_MODE", "true");
unsetEnv("PRODUCER_ENABLE_STREAMING_ENCODE");
const config = resolveConfig();
expect(config.enableStreamingEncode).toBe(false);
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBe(true);
expect(config.enableStreamingEncode).toBe(!opts.autoDisabled);
if (opts.autoDisabled) {
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBe(true);
} else {
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBeUndefined();
}
}
it("auto-disables on win32 + software-GPU + workers=1 + no user opt-in", () => {
expectCompoundOutcome({
platform: "win32",
gpuMode: "software",
workers: "1",
autoDisabled: true,
});
});
it("leaves streaming-encode on when platform is linux", () => {
setPlatform("linux");
setEnv("PRODUCER_BROWSER_GPU_MODE", "software");
setEnv("PRODUCER_MAX_WORKERS", "1");
setEnv("PRODUCER_LOW_MEMORY_MODE", "true");
unsetEnv("PRODUCER_ENABLE_STREAMING_ENCODE");
const config = resolveConfig();
expect(config.enableStreamingEncode).toBe(true);
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBeUndefined();
expectCompoundOutcome({
platform: "linux",
gpuMode: "software",
workers: "1",
autoDisabled: false,
});
});
it("leaves streaming-encode on when workers > 1", () => {
setPlatform("win32");
setEnv("PRODUCER_BROWSER_GPU_MODE", "software");
setEnv("PRODUCER_MAX_WORKERS", "4");
setEnv("PRODUCER_LOW_MEMORY_MODE", "true");
unsetEnv("PRODUCER_ENABLE_STREAMING_ENCODE");
const config = resolveConfig();
expect(config.enableStreamingEncode).toBe(true);
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBeUndefined();
expectCompoundOutcome({
platform: "win32",
gpuMode: "software",
workers: "4",
autoDisabled: false,
});
});
it("respects explicit env opt-in (PRODUCER_ENABLE_STREAMING_ENCODE=true) on the compound", () => {
@@ -703,16 +755,8 @@ describe("resolveConfig", () => {
// --low-memory-mode implies screenshot capture. Compound applies even
// if browserGpuMode is not literal "software" (defense-in-depth: matches
// the OR semantics in `softwareGpuForced`).
setPlatform("win32");
unsetEnv("PRODUCER_BROWSER_GPU_MODE");
unsetEnv("PRODUCER_DISABLE_GPU");
setEnv("PRODUCER_MAX_WORKERS", "1");
setEnv("PRODUCER_LOW_MEMORY_MODE", "true");
unsetEnv("PRODUCER_ENABLE_STREAMING_ENCODE");
const config = resolveConfig();
expect(config.enableStreamingEncode).toBe(false);
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBe(true);
expectCompoundOutcome({ platform: "win32", workers: "1", autoDisabled: true });
});
it("does not trigger when concurrency is 'auto' (workers not explicitly pinned)", () => {
@@ -720,15 +764,7 @@ describe("resolveConfig", () => {
// helper's numeric workers check treats NaN as "unknown, don't trigger".
// Downstream workers may still resolve to 1 via lowMemoryMode, but the
// config-time clamp is deliberately conservative.
setPlatform("win32");
setEnv("PRODUCER_BROWSER_GPU_MODE", "software");
unsetEnv("PRODUCER_MAX_WORKERS");
setEnv("PRODUCER_LOW_MEMORY_MODE", "true");
unsetEnv("PRODUCER_ENABLE_STREAMING_ENCODE");
const config = resolveConfig();
expect(config.enableStreamingEncode).toBe(true);
expect(config.streamingEncodeAutoDisabledOnWin32Compound).toBeUndefined();
expectCompoundOutcome({ platform: "win32", gpuMode: "software", autoDisabled: false });
});
});