fix(producer): stop clipping the bottom edge of software-GPU video renders#2300
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
e817a98 to
18a1d1f
Compare
miga-heygen
left a comment
There was a problem hiding this comment.
Review — fix(producer): stop clipping the bottom edge of software-GPU video renders
SSOT check: clean. resolveVideoCaptureBeyondViewport now has exactly one decision: videoCount > 0 → true, else undefined. No parameters to misconfigure, no GPU-mode branching. Both call sites updated (renderOrchestrator.ts, renderChunk.ts). Dead type ResolvedBrowserGpuMode removed.
Root cause analysis is solid: renderChunk.ts hardcodes browserGpuMode: "software" (via assertSwiftShader), so the old software → false gate affected the entire distributed fleet — every video render shipped with ~87 bottom rows clipped to black. The fix matches the precedent the alpha capture paths already set (captureScreenshotWithAlpha / captureAlphaPng hardcode captureBeyondViewport: true).
Test: the old assertion software → false (which encoded the bug) is gone, replaced with any video count → true. Correct — the test now asserts the invariant, not the accidental behavior.
ponytail: note: acknowledged — if the software re-raster tax matters, a clip predictor is the right narrowing (not a GPU-mode gate). But correct output over perf is the right call for now.
LGTM — no issues found.
— Miga
james-russo-rames-d-jusso
left a comment
There was a problem hiding this comment.
Reviewed at 18a1d1f8.
Right call. Verified against feedback_narrow_titled_bugfix_check_root_cause (title says "bottom edge" — is the fix scoped tighter than the actual bug?): captureBeyondViewport: true is Chrome's mechanism to include content outside the entire viewport rectangle, not just the bottom edge, so the fix is symmetrically broader than the title. That matches the alpha paths' hardcode (captureScreenshotWithAlpha and captureAlphaPng at screenshotService.ts:241,307) — they already carry the same #1094 tall-portrait edge-clipping guard unconditional true. Symmetry per feedback_reimplemented_detection_narrower_than_sibling holds — the non-alpha screenshot path now matches the alpha paths' hardcode.
The two callers that needed updates (renderOrchestrator.ts:1899, renderChunk.ts:484) are both handled; grep confirms no other consumers of resolveVideoCaptureBeyondViewport or the removed ResolvedBrowserGpuMode type. Test rewrite correctly removes the assertion that encoded the bug (software → false) instead of assuming it was the intended contract. And the observability signal at observability.ts:36 (captureBeyondViewport?: boolean) is preserved and now reflects the fix — no metric asymmetry.
Also verified this composes correctly with #2298's screenshot fallback path: when the parallel-DE stall watchdog trips and re-renders via screenshot, the retry passes through resolveVideoCaptureBeyondViewport again — which under this PR returns true for any video, so the fallback picks up the fix automatically without #2298 needing to know about it.
The ponytail: comment about narrowing back with a clip predictor if the software re-raster tax proves significant is the right doc — captures the trade-off explicitly for whoever comes back to it.
LGTM.
jrusso1020
left a comment
There was a problem hiding this comment.
Approving on Rames-D's go. Rames-D LGTM'd at head 18a1d1f, no changes-requested, CI clean so far (some checks still running, no failures). My approve doesn't merge, so the ruleset still gates merge on CI green.
miguel-heygen
left a comment
There was a problem hiding this comment.
Independent current-head review.
Strengths
captureBeyondViewport.ts:20-22reduces the policy to the actual correctness invariant: any native video surface uses beyond-viewport capture.- Both production callers were updated (
renderOrchestrator.ts:1902,distributed/renderChunk.ts:483), and repository-wide symbol audit found no stale signature consumers. - Focused regression passed 2/2 locally. The stack edge is exact/fresh; CI has no failures, with optional render-regression shards still running.
No material blockers found.
Verdict: APPROVE
Reasoning: The change fixes the clipping class at both capture entry points without leaving a software-GPU exception or stale API caller.
— deepwork
…stalls (#2298) ## Stack 1. **#2298 — DE router stall watchdog** ← you are here 2. #2300 — video bottom-edge clip 3. #2301 — feedback bug-report guidance ## Problem The DE parallel router auto-enables the interleaved parallel-**streaming** capture for the ≥24 GB macOS trial cohort. If a worker wedges mid-capture (a hung seek/screenshot at an early frame), the render makes **zero frame progress** yet sits until the per-frame CDP `protocolTimeout` (~5 min) fires before the pinned self-verify fallback can run — a silent multi-minute hang shipped to real users. Reported: stuck at frame 2/2031 for 6+ min, no fallback, until the user manually set `HF_DE_PARALLEL_ROUTER=false` (71 s clean). ## Fix Add a no-frame-progress watchdog to the parallel branch of `runCaptureStreamingStage`: - Ticks off `executeParallelCapture`'s progress callback. If no **new** frame lands within `HF_DE_PARALLEL_STALL_MS` (default **60 s** — well under the 5-min protocol timeout, ≫ the 15–32 ms/frame budget), it fires. - On trip: aborts the **reorder buffer** (so peer workers parked in `waitForFrame` reject instead of deadlocking the `Promise.all` pool) and aborts the pool via a **separate** `AbortController` linked to the parent abort. - The parent `abortSignal` stays un-aborted, so the orchestrator reads the failure as a generic `capture_error` (not a cancellation) and re-renders on the pinned screenshot path — the same fallback a verify failure already uses. ## Test - Watchdog trips on no progress → rethrows a stall error (routes to fallback). - A genuine parent-abort is **not** relabeled as a stall (stays a cancellation).
…nders resolveVideoCaptureBeyondViewport gated Chrome's beyond-viewport screenshot path to hardware-GPU captures, to skip the full-surface software re-rasterization tax. But without beyond-viewport, the viewport-bound capture clips the bottom edge of any frame containing a native video surface (the same #1094 tall-portrait guard the alpha capture paths already hardcode) — leaving ~87 bottom rows black. This hit two cohorts: software-GPU macOS/Linux hosts, and — worse — EVERY distributed chunk render, which hardcodes browserGpuMode "software", so the whole distributed fleet shipped video renders with a black bottom band. Reporter confirmed forcing resolveVideoCaptureBeyondViewport=true fixes it. Correct output wins over the software perf optimization: enable beyond-viewport for any render with a native video surface, regardless of GPU mode. Drops the now-vestigial browserGpuMode parameter (and its type) and updates both call sites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18a1d1f to
de95daa
Compare
The base branch was changed.

Stack
Problem
resolveVideoCaptureBeyondViewportgated Chrome's beyond-viewport screenshot path to hardware-GPU captures, to skip the full-surface software re-rasterization tax. But without beyond-viewport, the viewport-bound capture clips the bottom edge of any frame containing a native video surface (the same #1094 tall-portrait guard the alpha capture paths already hardcode) — leaving ~87 bottom rows black.Two cohorts hit this:
renderChunk.tshardcodesbrowserGpuMode: "software"(asserted viaassertSwiftShader), so the whole distributed fleet shipped video renders with a black bottom band.Reporter confirmed forcing
resolveVideoCaptureBeyondViewport=truefixes it.Fix
Correct output wins over the software perf optimization: enable beyond-viewport for any render with a native video surface, regardless of GPU mode. This matches the precedent the alpha capture paths already set (they hardcode
captureBeyondViewport: true). Drops the now-vestigialbrowserGpuModeparameter +ResolvedBrowserGpuModetype and updates both call sites.ponytail:if the software re-raster tax proves significant on the distributed fleet, narrow it back to comps whose content actually reaches the bottom edge — but that needs a reliable clip predictor, and a black band is unshippable in the meantime.Test
Rewrote the unit test: video →
trueregardless of arg count; the oldsoftware → falseassertion (which encoded the bug) is gone.