Skip to content

fix(producer): stop clipping the bottom edge of software-GPU video renders#2300

Merged
vanceingalls merged 1 commit into
mainfrom
07-12-fix-software-video-beyond-viewport
Jul 12, 2026
Merged

fix(producer): stop clipping the bottom edge of software-GPU video renders#2300
vanceingalls merged 1 commit into
mainfrom
07-12-fix-software-video-beyond-viewport

Conversation

@vanceingalls

@vanceingalls vanceingalls commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Stack

  1. fix(producer): fall back fast when the parallel DE streaming capture stalls #2298 — DE router stall watchdog
  2. fix(producer): stop clipping the bottom edge of software-GPU video renders #2300 — video bottom-edge clip ← you are here
  3. docs(skills): tell agents to file reproducible render bugs, not paraphrases #2301 — feedback bug-report guidance

Problem

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.

Two cohorts hit this:

  • Software-GPU macOS/Linux hosts.
  • Every distributed chunk renderrenderChunk.ts hardcodes browserGpuMode: "software" (asserted via assertSwiftShader), so the whole distributed fleet shipped video renders with a black bottom band.

Reporter confirmed forcing resolveVideoCaptureBeyondViewport=true fixes 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-vestigial browserGpuMode parameter + ResolvedBrowserGpuMode type 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 → true regardless of arg count; the old software → false assertion (which encoded the bug) is gone.

vanceingalls commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator Author

@vanceingalls vanceingalls changed the base branch from main to graphite-base/2300 July 12, 2026 18:08
@vanceingalls vanceingalls force-pushed the 07-12-fix-software-video-beyond-viewport branch from e817a98 to 18a1d1f Compare July 12, 2026 18:08
@vanceingalls vanceingalls changed the base branch from graphite-base/2300 to 07-12-fix-de-router-stall-watchdog July 12, 2026 18:08

@miga-heygen miga-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 james-russo-rames-d-jusso left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Review by Rames D Jusso

jrusso1020
jrusso1020 previously approved these changes Jul 12, 2026

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
miguel-heygen previously approved these changes Jul 12, 2026

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent current-head review.

Strengths

  • captureBeyondViewport.ts:20-22 reduces 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

@vanceingalls vanceingalls changed the base branch from 07-12-fix-de-router-stall-watchdog to graphite-base/2300 July 12, 2026 18:25
vanceingalls added a commit that referenced this pull request Jul 12, 2026
…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>
@vanceingalls vanceingalls force-pushed the 07-12-fix-software-video-beyond-viewport branch from 18a1d1f to de95daa Compare July 12, 2026 18:29
@vanceingalls vanceingalls changed the base branch from graphite-base/2300 to main July 12, 2026 18:29
@vanceingalls vanceingalls dismissed stale reviews from jrusso1020 and miguel-heygen July 12, 2026 18:29

The base branch was changed.

@vanceingalls vanceingalls merged commit 2a0c603 into main Jul 12, 2026
46 of 52 checks passed
@vanceingalls vanceingalls deleted the 07-12-fix-software-video-beyond-viewport branch July 12, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants