mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
fix(engine,producer): apply software-GPU screenshot invariant at concrete-resolved point
Addresses Miguel's R1 blockers:
1. `browserGpuMode: "auto"` that runtime-probes to software slipped past the
`resolveConfig` clamp — that clamp only sees the pre-resolve string. Add
`shouldClampToScreenshotForConcreteGpu(resolvedGpuMode, currentForceScreenshot, env)`
in `packages/engine/src/config.ts` and apply it at BOTH concrete-resolution
sites:
- `packages/engine/src/services/frameCapture.ts`: downgrades `preMode`
from "beginframe" to "screenshot" when resolved GPU is software (respects
`PRODUCER_FORCE_SCREENSHOT=false` env opt-out), fixing the routing.
- `packages/producer/src/services/renderOrchestrator.ts`: updates
`captureObservability.forceScreenshot` (and thus `captureMode`) at the
same call site, fixing the observability truth on the auto → software
case.
2. New unit tests in `config.test.ts`:
- Documents the auto-branch gap (resolveConfig leaves auto as
forceScreenshot=false — the runtime companion closes it).
- 5 branch tests on `shouldClampToScreenshotForConcreteGpu` covering
software / hardware / already-forced / env-opt-out / non-"false" env
values.
Full suite: 56/56 pass.
Scope narrowing on Blocker 2: the distributed rendering path at
`packages/producer/src/services/distributed/plan.ts:753-754` and
`renderChunk.ts:462-466` explicitly hardcodes `browserGpuMode:"software",
forceScreenshot:false` post-resolveConfig and stays outside this PR's
invariant boundary. `compileStage` may still flip it to true for alpha
formats, but generic MP4 distributed renders on SwiftShader hosts remain
BeginFrame. That's a separate architectural cleanup (needs its own
behavior-change trace); the PR body now scopes the invariant to the
in-process CLI/orchestrator path.
This commit is contained in:
@@ -70,6 +70,7 @@ import {
|
||||
type SubTimelineWaitOutcome,
|
||||
resolveBrowserGpuMode,
|
||||
resolveHeadlessShellPath,
|
||||
shouldClampToScreenshotForConcreteGpu,
|
||||
scaleProtocolTimeoutForComposition,
|
||||
isMemoryExhaustionError,
|
||||
isTransientBrowserError,
|
||||
@@ -1908,7 +1909,23 @@ export async function executeRenderJob(
|
||||
chromePath: resolveHeadlessShellPath(cfg),
|
||||
browserTimeout: cfg.browserTimeout,
|
||||
});
|
||||
updateCaptureObservability({ browserGpuMode: resolvedBrowserGpuMode });
|
||||
// Mirror the frameCapture.ts routing invariant here so observability
|
||||
// reports the actual capture mode on `browserGpuMode: "auto"` renders
|
||||
// that probe to software: `resolveConfig` couldn't see this at config
|
||||
// time, so `captureObservability.forceScreenshot` was still false,
|
||||
// misreporting `captureMode: "beginframe"` for a session that will
|
||||
// actually take the screenshot path. Env-level opt-out preserved via
|
||||
// the shared helper.
|
||||
const observabilityForceScreenshot =
|
||||
captureObservability.forceScreenshot ||
|
||||
shouldClampToScreenshotForConcreteGpu(
|
||||
resolvedBrowserGpuMode,
|
||||
captureObservability.forceScreenshot,
|
||||
);
|
||||
updateCaptureObservability({
|
||||
browserGpuMode: resolvedBrowserGpuMode,
|
||||
forceScreenshot: observabilityForceScreenshot,
|
||||
});
|
||||
const videoCaptureBeyondViewport = resolveVideoCaptureBeyondViewport(composition.videos.length);
|
||||
|
||||
const captureOptions: CaptureOptions = {
|
||||
|
||||
Reference in New Issue
Block a user