@hyperframes/engine 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,9 +10,47 @@ import { type Page } from "puppeteer-core";
10
10
  import { type FrameLookupTable } from "./videoFrameExtractor.js";
11
11
  import { type BeforeCaptureHook } from "./frameCapture.js";
12
12
  import { type EngineConfig } from "../config.js";
13
- export interface VideoFrameInjectorOptions extends Partial<Pick<EngineConfig, "frameDataUriCacheLimit">> {
13
+ export interface VideoFrameInjectorOptions extends Partial<Pick<EngineConfig, "frameDataUriCacheLimit" | "frameDataUriCacheBytesLimitMb">> {
14
14
  frameSrcResolver?: (framePath: string) => string | null;
15
15
  }
16
+ interface FrameSourceCacheStats {
17
+ entries: number;
18
+ bytes: number;
19
+ /** Total entries evicted since cache creation. A high count vs a small
20
+ * composition signals the byte budget is too tight (cache thrash). */
21
+ evictions: number;
22
+ /** Total inserts rejected because the entry alone exceeds bytesLimit.
23
+ * Non-zero means a single frame is bigger than the configured budget —
24
+ * raise `frameDataUriCacheBytesLimitMb` if it recurs in production. */
25
+ oversizedRejections: number;
26
+ }
27
+ interface FrameSourceCache {
28
+ get: (framePath: string) => Promise<string>;
29
+ /** Exposed for tests + telemetry; reflects current cache occupancy. */
30
+ stats: () => FrameSourceCacheStats;
31
+ }
32
+ /**
33
+ * Two-bound LRU keyed by frame path. Either bound triggers eviction of the
34
+ * oldest entry — entry count protects against pathological many-tiny-frames
35
+ * cases, and the byte budget keeps memory bounded when the per-frame data
36
+ * URI grows (4K PNG frames are ~33 MB once base64-encoded).
37
+ *
38
+ * If a single entry's data URI exceeds `bytesLimit`, we skip caching it
39
+ * (returning the URI directly to the caller). Without this guard, the
40
+ * post-insert eviction loop would drop the entry we just inserted and the
41
+ * cache would degrade into a CPU hot path — every subsequent `get()` would
42
+ * re-read from disk and re-base64 the same frame.
43
+ *
44
+ * **Invariant**: cached values MUST be strings whose `.length` equals the
45
+ * byte count we account for at insertion. We derive size on demand via
46
+ * `cache.get(key)?.length` rather than maintaining a parallel `Map<string, number>`.
47
+ * If you ever wrap the value (e.g. cache a Buffer or an object), the byte
48
+ * accounting silently breaks — switch to a parallel size map first.
49
+ */
50
+ declare function createFrameSourceCache(entryLimit: number, bytesLimit: number, frameSrcResolver?: (framePath: string) => string | null): FrameSourceCache;
51
+ export declare const __testing: {
52
+ createFrameSourceCache: typeof createFrameSourceCache;
53
+ };
16
54
  /**
17
55
  * Creates a BeforeCaptureHook that injects pre-extracted video frames
18
56
  * into the page, replacing native <video> elements with frame images.
@@ -102,4 +140,5 @@ export interface ElementStackingInfo {
102
140
  * @param nativeHdrIds Combined set of HDR-tagged element IDs (videos AND images).
103
141
  */
104
142
  export declare function queryElementStacking(page: Page, nativeHdrIds: Set<string>): Promise<ElementStackingInfo[]>;
143
+ export {};
105
144
  //# sourceMappingURL=videoFrameInjector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"videoFrameInjector.d.ts","sourceRoot":"","sources":["../../src/services/videoFrameInjector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,yBAA0B,SAAQ,OAAO,CACxD,IAAI,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAC7C;IACC,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACzD;AAuDD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,gBAAgB,GAAG,IAAI,EACpC,MAAM,CAAC,EAAE,yBAAyB,GACjC,iBAAiB,GAAG,IAAI,CAgD1B;AAID;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYrF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYrF;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA2C/B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1E;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAiPhC"}
1
+ {"version":3,"file":"videoFrameInjector.d.ts","sourceRoot":"","sources":["../../src/services/videoFrameInjector.ts"],"names":[],"mappings":"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"}
@@ -9,19 +9,63 @@
9
9
  import { promises as fs } from "fs";
10
10
  import { injectVideoFramesBatch, syncVideoFrameVisibility } from "./screenshotService.js";
11
11
  import { DEFAULT_CONFIG } from "../config.js";
12
- function createFrameSourceCache(cacheLimit, frameSrcResolver) {
12
+ /**
13
+ * Two-bound LRU keyed by frame path. Either bound triggers eviction of the
14
+ * oldest entry — entry count protects against pathological many-tiny-frames
15
+ * cases, and the byte budget keeps memory bounded when the per-frame data
16
+ * URI grows (4K PNG frames are ~33 MB once base64-encoded).
17
+ *
18
+ * If a single entry's data URI exceeds `bytesLimit`, we skip caching it
19
+ * (returning the URI directly to the caller). Without this guard, the
20
+ * post-insert eviction loop would drop the entry we just inserted and the
21
+ * cache would degrade into a CPU hot path — every subsequent `get()` would
22
+ * re-read from disk and re-base64 the same frame.
23
+ *
24
+ * **Invariant**: cached values MUST be strings whose `.length` equals the
25
+ * byte count we account for at insertion. We derive size on demand via
26
+ * `cache.get(key)?.length` rather than maintaining a parallel `Map<string, number>`.
27
+ * If you ever wrap the value (e.g. cache a Buffer or an object), the byte
28
+ * accounting silently breaks — switch to a parallel size map first.
29
+ */
30
+ function createFrameSourceCache(entryLimit, bytesLimit, frameSrcResolver) {
13
31
  const cache = new Map();
14
32
  const inFlight = new Map();
33
+ let totalBytes = 0;
34
+ let evictions = 0;
35
+ let oversizedRejections = 0;
36
+ function evictOldest() {
37
+ const oldestKey = cache.keys().next().value;
38
+ if (!oldestKey)
39
+ return;
40
+ // Snapshot the value before deleting so the byte-size derivation can't
41
+ // accidentally read post-delete (a future reorder would silently lose
42
+ // accounting and surface as `totalBytes` drifting out of sync).
43
+ const dropped = cache.get(oldestKey);
44
+ cache.delete(oldestKey);
45
+ totalBytes = Math.max(0, totalBytes - (dropped?.length ?? 0));
46
+ evictions++;
47
+ }
15
48
  function remember(framePath, dataUri) {
49
+ // Skip caching entries that alone exceed the byte budget. Caching them
50
+ // would trigger immediate self-eviction on insert and pollute LRU order
51
+ // by displacing the previous entry's slot.
52
+ if (dataUri.length > bytesLimit) {
53
+ oversizedRejections++;
54
+ // Drop any stale prior version so the caller sees consistent state.
55
+ if (cache.has(framePath)) {
56
+ totalBytes = Math.max(0, totalBytes - (cache.get(framePath)?.length ?? 0));
57
+ cache.delete(framePath);
58
+ }
59
+ return dataUri;
60
+ }
16
61
  if (cache.has(framePath)) {
62
+ totalBytes = Math.max(0, totalBytes - (cache.get(framePath)?.length ?? 0));
17
63
  cache.delete(framePath);
18
64
  }
19
65
  cache.set(framePath, dataUri);
20
- if (cache.size > cacheLimit) {
21
- const oldestKey = cache.keys().next().value;
22
- if (oldestKey) {
23
- cache.delete(oldestKey);
24
- }
66
+ totalBytes += dataUri.length;
67
+ while ((cache.size > entryLimit || totalBytes > bytesLimit) && cache.size > 0) {
68
+ evictOldest();
25
69
  }
26
70
  return dataUri;
27
71
  }
@@ -51,8 +95,17 @@ function createFrameSourceCache(cacheLimit, frameSrcResolver) {
51
95
  inFlight.set(framePath, pending);
52
96
  return pending;
53
97
  }
54
- return { get };
98
+ return {
99
+ get,
100
+ stats: () => ({
101
+ entries: cache.size,
102
+ bytes: totalBytes,
103
+ evictions,
104
+ oversizedRejections,
105
+ }),
106
+ };
55
107
  }
108
+ export const __testing = { createFrameSourceCache };
56
109
  /**
57
110
  * Creates a BeforeCaptureHook that injects pre-extracted video frames
58
111
  * into the page, replacing native <video> elements with frame images.
@@ -60,8 +113,10 @@ function createFrameSourceCache(cacheLimit, frameSrcResolver) {
60
113
  export function createVideoFrameInjector(frameLookup, config) {
61
114
  if (!frameLookup)
62
115
  return null;
63
- const cacheLimit = Math.max(32, config?.frameDataUriCacheLimit ?? DEFAULT_CONFIG.frameDataUriCacheLimit);
64
- const frameCache = createFrameSourceCache(cacheLimit, config?.frameSrcResolver);
116
+ const entryLimit = Math.max(32, config?.frameDataUriCacheLimit ?? DEFAULT_CONFIG.frameDataUriCacheLimit);
117
+ const bytesLimitMb = Math.max(64, config?.frameDataUriCacheBytesLimitMb ?? DEFAULT_CONFIG.frameDataUriCacheBytesLimitMb);
118
+ const bytesLimit = bytesLimitMb * 1024 * 1024;
119
+ const frameCache = createFrameSourceCache(entryLimit, bytesLimit, config?.frameSrcResolver);
65
120
  const lastInjectedFrameByVideo = new Map();
66
121
  return async (page, time) => {
67
122
  const activePayloads = frameLookup.getActiveFramePayloads(time);
@@ -1 +1 @@
1
- {"version":3,"file":"videoFrameInjector.js","sourceRoot":"","sources":["../../src/services/videoFrameInjector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"videoFrameInjector.js","sourceRoot":"","sources":["../../src/services/videoFrameInjector.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/engine",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Seekable web page to video rendering engine (Puppeteer + FFmpeg)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "linkedom": "^0.18.12",
20
20
  "puppeteer": "^24.0.0",
21
21
  "puppeteer-core": "^24.39.1",
22
- "@hyperframes/core": "^0.5.2"
22
+ "@hyperframes/core": "^0.5.4"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^22.10.1",
@@ -97,6 +97,13 @@ describe("resolveConfig", () => {
97
97
  expect(config.browserGpuMode).toBe("hardware");
98
98
  });
99
99
 
100
+ it("accepts 'auto' as a valid browser GPU mode env value", () => {
101
+ setEnv("PRODUCER_BROWSER_GPU_MODE", "auto");
102
+
103
+ const config = resolveConfig();
104
+ expect(config.browserGpuMode).toBe("auto");
105
+ });
106
+
100
107
  it("falls back to software browser GPU mode for invalid env values", () => {
101
108
  setEnv("PRODUCER_BROWSER_GPU_MODE", "native");
102
109
 
package/src/config.ts CHANGED
@@ -32,10 +32,15 @@ export interface EngineConfig {
32
32
  chromePath?: string;
33
33
  disableGpu: boolean;
34
34
  /**
35
- * Chrome/WebGL rendering backend. "software" keeps the existing SwiftShader
36
- * path for reproducible output; "hardware" lets Chrome use the host GPU.
35
+ * Chrome/WebGL rendering backend.
36
+ * - "software": SwiftShader (CPU-only). Always works; ~5-50× slower than GPU.
37
+ * - "hardware": host GPU via platform-native ANGLE backend (Metal/D3D11/EGL).
38
+ * Errors if no usable GPU is reachable from Chrome.
39
+ * - "auto": probe Chrome for WebGL availability on first launch in this
40
+ * process; fall back to software if hardware-mode WebGL is unavailable.
41
+ * Cost: one extra Chrome launch (~1-2 s) per process; result cached.
37
42
  */
38
- browserGpuMode: "software" | "hardware";
43
+ browserGpuMode: "software" | "hardware" | "auto";
39
44
  enableBrowserPool: boolean;
40
45
  browserTimeout: number;
41
46
  protocolTimeout: number;
@@ -71,7 +76,21 @@ export interface EngineConfig {
71
76
 
72
77
  // ── Media ────────────────────────────────────────────────────────────
73
78
  audioGain: number;
79
+ /**
80
+ * Hard upper bound on entries kept in the video frame data URI cache.
81
+ * Acts as a sanity cap; the byte budget below normally fires first on
82
+ * high-resolution renders. At 1080p with ~6 MB per JPEG frame the default
83
+ * 256 entries fit inside ~1.5 GB. At 4K the byte budget evicts long
84
+ * before this cap is reached.
85
+ */
74
86
  frameDataUriCacheLimit: number;
87
+ /**
88
+ * Memory budget for the cache, in megabytes. Eviction kicks in once the
89
+ * sum of cached data-URI string lengths exceeds this. Sized so a worker
90
+ * stays comfortably under a few GB even at 4K (where each PNG frame is
91
+ * ~25 MB and the base64 data URI is ~33 MB).
92
+ */
93
+ frameDataUriCacheBytesLimitMb: number;
75
94
 
76
95
  // ── Timeouts ─────────────────────────────────────────────────────────
77
96
  playerReadyTimeout: number;
@@ -144,6 +163,7 @@ export const DEFAULT_CONFIG: EngineConfig = {
144
163
 
145
164
  audioGain: 1,
146
165
  frameDataUriCacheLimit: 256,
166
+ frameDataUriCacheBytesLimitMb: 1500,
147
167
 
148
168
  playerReadyTimeout: 45_000,
149
169
  renderReadyTimeout: 15_000,
@@ -173,7 +193,7 @@ export function resolveConfig(overrides?: Partial<EngineConfig>): EngineConfig {
173
193
  };
174
194
  const envBrowserGpuMode = (): EngineConfig["browserGpuMode"] => {
175
195
  const raw = env("PRODUCER_BROWSER_GPU_MODE");
176
- if (raw === "hardware" || raw === "software") return raw;
196
+ if (raw === "hardware" || raw === "software" || raw === "auto") return raw;
177
197
  return DEFAULT_CONFIG.browserGpuMode;
178
198
  };
179
199
 
@@ -241,6 +261,13 @@ export function resolveConfig(overrides?: Partial<EngineConfig>): EngineConfig {
241
261
  32,
242
262
  envNum("PRODUCER_FRAME_DATA_URI_CACHE_LIMIT", DEFAULT_CONFIG.frameDataUriCacheLimit),
243
263
  ),
264
+ frameDataUriCacheBytesLimitMb: Math.max(
265
+ 64,
266
+ envNum(
267
+ "PRODUCER_FRAME_DATA_URI_CACHE_BYTES_MB",
268
+ DEFAULT_CONFIG.frameDataUriCacheBytesLimitMb,
269
+ ),
270
+ ),
244
271
 
245
272
  playerReadyTimeout: envNum(
246
273
  "PRODUCER_PLAYER_READY_TIMEOUT_MS",
package/src/index.ts CHANGED
@@ -50,6 +50,7 @@ export {
50
50
  acquireBrowser,
51
51
  releaseBrowser,
52
52
  resolveHeadlessShellPath,
53
+ resolveBrowserGpuMode,
53
54
  buildChromeArgs,
54
55
  ENABLE_BROWSER_POOL,
55
56
  type BuildChromeArgsOptions,
@@ -1,6 +1,11 @@
1
- import { describe, expect, it, vi } from "vitest";
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
2
 
3
- import { buildChromeArgs, forceReleaseBrowser } from "./browserManager.js";
3
+ import {
4
+ _resetAutoBrowserGpuModeCacheForTests,
5
+ buildChromeArgs,
6
+ forceReleaseBrowser,
7
+ resolveBrowserGpuMode,
8
+ } from "./browserManager.js";
4
9
 
5
10
  describe("buildChromeArgs browser GPU mode", () => {
6
11
  const base = { width: 1920, height: 1080 };
@@ -10,6 +15,7 @@ describe("buildChromeArgs browser GPU mode", () => {
10
15
  expect(args).toContain("--enable-features=CanvasDrawElement");
11
16
  expect(args).toContain("--use-gl=angle");
12
17
  expect(args).toContain("--use-angle=swiftshader");
18
+ expect(args).toContain("--enable-unsafe-swiftshader");
13
19
  expect(args).not.toContain("--enable-gpu-rasterization");
14
20
  });
15
21
 
@@ -48,6 +54,80 @@ describe("buildChromeArgs browser GPU mode", () => {
48
54
  });
49
55
  });
50
56
 
57
+ describe("resolveBrowserGpuMode", () => {
58
+ beforeEach(() => {
59
+ _resetAutoBrowserGpuModeCacheForTests();
60
+ });
61
+
62
+ afterEach(() => {
63
+ vi.restoreAllMocks();
64
+ _resetAutoBrowserGpuModeCacheForTests();
65
+ });
66
+
67
+ it("passes 'software' through unchanged without probing", async () => {
68
+ const mode = await resolveBrowserGpuMode("software");
69
+ expect(mode).toBe("software");
70
+ });
71
+
72
+ it("passes 'hardware' through unchanged without probing", async () => {
73
+ const mode = await resolveBrowserGpuMode("hardware");
74
+ expect(mode).toBe("hardware");
75
+ });
76
+
77
+ it("falls back to 'software' when the probe browser cannot launch", async () => {
78
+ // No chromePath, env unset, and (in the test env) no system Chrome to find
79
+ // → puppeteer.launch will throw → caller catches → software fallback.
80
+ // Force a definitely-missing chrome binary so the launch path errors fast.
81
+ const mode = await resolveBrowserGpuMode("auto", {
82
+ chromePath: "/definitely/not/a/real/chrome/binary",
83
+ browserTimeout: 2000,
84
+ });
85
+ expect(mode).toBe("software");
86
+ });
87
+
88
+ it("caches the probe result across calls", async () => {
89
+ const first = await resolveBrowserGpuMode("auto", {
90
+ chromePath: "/definitely/not/a/real/chrome/binary",
91
+ browserTimeout: 2000,
92
+ });
93
+ // Second call uses cache — no new launch. Assert the same answer comes back
94
+ // even with a different chromePath that would have a different probe outcome.
95
+ const second = await resolveBrowserGpuMode("auto", {
96
+ chromePath: "/another/definitely/missing/path",
97
+ browserTimeout: 2000,
98
+ });
99
+ expect(first).toBe("software");
100
+ expect(second).toBe("software");
101
+ // Reset and re-probe to confirm the test-only reset works.
102
+ _resetAutoBrowserGpuModeCacheForTests();
103
+ const third = await resolveBrowserGpuMode("hardware");
104
+ expect(third).toBe("hardware");
105
+ });
106
+
107
+ it("deduplicates concurrent auto-mode probes by caching the in-flight Promise", async () => {
108
+ // Parallel coordinator fires N workers via Promise.all — without Promise-
109
+ // level caching, a `--workers 4` render against a no-GPU host would launch
110
+ // 4 simultaneous probe Chromes. Verify all concurrent callers get the
111
+ // exact same Promise reference (proving the probe runs once, not N times).
112
+ const p1 = resolveBrowserGpuMode("auto", {
113
+ chromePath: "/definitely/not/a/real/chrome/binary",
114
+ browserTimeout: 2000,
115
+ });
116
+ const p2 = resolveBrowserGpuMode("auto", {
117
+ chromePath: "/definitely/not/a/real/chrome/binary",
118
+ browserTimeout: 2000,
119
+ });
120
+ const p3 = resolveBrowserGpuMode("auto", {
121
+ chromePath: "/definitely/not/a/real/chrome/binary",
122
+ browserTimeout: 2000,
123
+ });
124
+ expect(p1).toBe(p2);
125
+ expect(p2).toBe(p3);
126
+ const results = await Promise.all([p1, p2, p3]);
127
+ expect(results).toEqual(["software", "software", "software"]);
128
+ });
129
+ });
130
+
51
131
  describe("forceReleaseBrowser", () => {
52
132
  it("kills the browser process and disconnects", () => {
53
133
  const killFn = vi.fn(() => true);
@@ -136,6 +136,119 @@ async function probeBeginFrameSupport(browser: Browser): Promise<boolean> {
136
136
  }
137
137
  }
138
138
 
139
+ /**
140
+ * Cached *in-flight or resolved* probe Promise for `resolveBrowserGpuMode("auto", ...)`.
141
+ *
142
+ * Caching the Promise (rather than the resolved value) deduplicates concurrent
143
+ * callers — the parallel coordinator runs N workers via `Promise.all`, so a
144
+ * `--workers 4` render against a no-GPU host would otherwise fire 4
145
+ * simultaneous probe Chromes. The first call assigns the Promise and every
146
+ * other concurrent caller awaits the same one, paying the ~240 ms probe cost
147
+ * exactly once per process lifetime.
148
+ *
149
+ * Exported for tests; production callers go through `resolveBrowserGpuMode`.
150
+ */
151
+ export let _autoBrowserGpuModeCache: Promise<"software" | "hardware"> | undefined;
152
+
153
+ /** Test-only: reset the cached probe result. */
154
+ export function _resetAutoBrowserGpuModeCacheForTests(): void {
155
+ _autoBrowserGpuModeCache = undefined;
156
+ }
157
+
158
+ /**
159
+ * Resolve `browserGpuMode` to a concrete `"software" | "hardware"` answer.
160
+ *
161
+ * For `"software"` / `"hardware"` this is a pure pass-through. For `"auto"`
162
+ * it launches a tiny Chrome with the platform's hardware GPU args, runs a
163
+ * one-shot WebGL availability probe, and falls back to `"software"` if
164
+ * hardware-mode WebGL is unavailable. The Promise is cached for the process
165
+ * lifetime, so concurrent callers (parallel workers) share the same probe.
166
+ *
167
+ * Any failure (Chrome launch error, navigation timeout, missing canvas API,
168
+ * etc.) is treated as a `"software"` fallback. The render path with
169
+ * SwiftShader always works, so a misclassification toward software is the
170
+ * safe failure mode; misclassifying toward hardware would error on the real
171
+ * render.
172
+ */
173
+ export function resolveBrowserGpuMode(
174
+ mode: EngineConfig["browserGpuMode"],
175
+ options: {
176
+ chromePath?: string;
177
+ browserTimeout?: number;
178
+ platform?: NodeJS.Platform;
179
+ } = {},
180
+ ): Promise<"software" | "hardware"> {
181
+ if (mode !== "auto") return Promise.resolve(mode);
182
+ if (_autoBrowserGpuModeCache) return _autoBrowserGpuModeCache;
183
+
184
+ _autoBrowserGpuModeCache = (async () => {
185
+ const platform = options.platform ?? process.platform;
186
+ const browserTimeout = options.browserTimeout ?? DEFAULT_CONFIG.browserTimeout;
187
+ const executablePath = options.chromePath ?? resolveHeadlessShellPath({});
188
+
189
+ const probeArgs = [
190
+ "--no-sandbox",
191
+ "--disable-setuid-sandbox",
192
+ "--disable-dev-shm-usage",
193
+ "--enable-webgl",
194
+ "--ignore-gpu-blocklist",
195
+ ...getBrowserGpuArgs("hardware", platform),
196
+ ];
197
+
198
+ const ppt = await getPuppeteer().catch(() => null);
199
+ if (!ppt) {
200
+ logResolvedBrowserGpuMode("software", "puppeteer unavailable");
201
+ return "software" as const;
202
+ }
203
+
204
+ let probeBrowser: Browser | undefined;
205
+ try {
206
+ probeBrowser = await ppt.launch({
207
+ headless: true,
208
+ args: probeArgs,
209
+ defaultViewport: { width: 64, height: 64 },
210
+ executablePath,
211
+ timeout: browserTimeout,
212
+ });
213
+ const page = await probeBrowser.newPage();
214
+ const hasWebGL = await page.evaluate(() => {
215
+ try {
216
+ const c = document.createElement("canvas");
217
+ const gl =
218
+ c.getContext("webgl") ||
219
+ (c.getContext("experimental-webgl") as RenderingContext | null);
220
+ return gl !== null;
221
+ } catch {
222
+ return false;
223
+ }
224
+ });
225
+ const resolved = hasWebGL ? ("hardware" as const) : ("software" as const);
226
+ logResolvedBrowserGpuMode(resolved, hasWebGL ? "WebGL probe succeeded" : "WebGL unavailable");
227
+ return resolved;
228
+ } catch (err) {
229
+ logResolvedBrowserGpuMode(
230
+ "software",
231
+ `probe failed (${err instanceof Error ? err.message : String(err)})`,
232
+ );
233
+ return "software" as const;
234
+ } finally {
235
+ await probeBrowser?.close().catch(() => {});
236
+ }
237
+ })();
238
+
239
+ return _autoBrowserGpuModeCache;
240
+ }
241
+
242
+ /**
243
+ * Single observability surface for the auto-detect outcome. Logged exactly
244
+ * once per process (the probe runs once); without this line, a regression
245
+ * to "always software even with a GPU present" would be invisible in
246
+ * production. Goes to stderr to stay out of stdout pipelines.
247
+ */
248
+ function logResolvedBrowserGpuMode(resolved: "hardware" | "software", reason: string): void {
249
+ console.error(`[hyperframes] browserGpuMode auto → ${resolved} (${reason})`);
250
+ }
251
+
139
252
  export async function acquireBrowser(
140
253
  chromeArgs: string[],
141
254
  config?: Partial<
@@ -344,7 +457,20 @@ function getBrowserGpuArgs(
344
457
  platform: NodeJS.Platform,
345
458
  ): string[] {
346
459
  if (mode === "software") {
347
- return ["--use-gl=angle", "--use-angle=swiftshader"];
460
+ // Chrome 120+ deprecated implicit SwiftShader fallback; the explicit
461
+ // path (--use-angle=swiftshader) keeps working but Chrome emits a
462
+ // deprecation warning unless --enable-unsafe-swiftshader is also set.
463
+ // Despite the name, this is exactly the behaviour Chrome had before;
464
+ // the flag exists to make CPU rasterisation an explicit opt-in rather
465
+ // than an implicit fallback for end users on the open web.
466
+ return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
467
+ }
468
+
469
+ if (mode === "auto") {
470
+ // Should not reach here — `resolveBrowserGpuMode` collapses "auto" to
471
+ // "software" or "hardware" before args are built. Be defensive: software
472
+ // is the always-safe fallback.
473
+ return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
348
474
  }
349
475
 
350
476
  switch (platform) {
@@ -18,6 +18,7 @@ import {
18
18
  releaseBrowser,
19
19
  forceReleaseBrowser,
20
20
  buildChromeArgs,
21
+ resolveBrowserGpuMode,
21
22
  resolveHeadlessShellPath,
22
23
  type CaptureMode,
23
24
  } from "./browserManager.js";
@@ -113,11 +114,22 @@ export async function createCaptureSession(
113
114
  const headlessShell = resolveHeadlessShellPath(config);
114
115
  const isLinux = process.platform === "linux";
115
116
  const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG.forceScreenshot;
117
+ // BeginFrame's screenshot does not honor a viewport `deviceScaleFactor`
118
+ // (the captured surface is sized by the OS window in CSS pixels regardless
119
+ // of `Emulation.setDeviceMetricsOverride`'s DPR). When supersampling we
120
+ // need explicit clip+scale on `Page.captureScreenshot`, so fall back to
121
+ // the screenshot path for any DPR > 1.
122
+ const supersampling = (options.deviceScaleFactor ?? 1) > 1;
116
123
  const preMode: CaptureMode =
117
- headlessShell && isLinux && !forceScreenshot ? "beginframe" : "screenshot";
124
+ headlessShell && isLinux && !forceScreenshot && !supersampling ? "beginframe" : "screenshot";
125
+ const requestedGpuMode = config?.browserGpuMode ?? DEFAULT_CONFIG.browserGpuMode;
126
+ const resolvedGpuMode = await resolveBrowserGpuMode(requestedGpuMode, {
127
+ chromePath: headlessShell ?? undefined,
128
+ browserTimeout: config?.browserTimeout,
129
+ });
118
130
  const chromeArgs = buildChromeArgs(
119
131
  { width: options.width, height: options.height, captureMode: preMode },
120
- config,
132
+ { ...config, browserGpuMode: resolvedGpuMode },
121
133
  );
122
134
 
123
135
  const { browser, captureMode } = await acquireBrowser(chromeArgs, config);