fix(web): composite consumes the FULL canvas, alpha crop is measure-only — transparent web margins reveal the webcam again

take-19-2/take-20 'webcam black square under the web widget': the capture was
alpha-cropped (FindContentBounds) and that CROP was fed to the compositor, whose
UniformToFill zoomed the opaque content box to cover the whole element rect the
moment the widget drew any content (idle transparent page = full-frame crop = the
correct viewport, hence take-1-good/take-2-bad). OBS model verified: the page is a
fixed 1920x1080 canvas and the element rect is a viewport onto it — measure with the
alpha crop (preview/selection), hand the composite the FULL canvas on an 8-deep ring
+ Epoch (same identity discipline as camera/screen). Regression test:
Composite_FullCanvasWebSource_TransparentMarginsRevealWebcam (the reveal contract:
margin pixel = webcam, badge pixel = widget).
This commit is contained in:
2026-09-05 15:33:56 -07:00
parent d35823a4a9
commit 0f441d825a
4 changed files with 151 additions and 21 deletions
+9
View File
@@ -27,6 +27,15 @@ This project's hard lesson: the web-source bounding saga (2026-08) burned 9
commits rediscovering that a browser source is a *fixed canvas* — OBS keeps it at
a stable page size, crops/hugs content via the box, and clips at the edge. The
apparent "gap" that ended the saga was a widget's own CSS glow effect, not a bug.
Refined 2026-09-05 (take-19-2/take-20 "webcam black square"): **measure with the
alpha crop, but CONSUME the full canvas.** The alpha bounding box (`FindContentBounds`)
is the widget's true extent for the UI/selection box; the frame handed to the
compositor must be the FULL transparent-background canvas, because the element rect
is a viewport onto the page — `UniformToFill` on the CROP zoomed the opaque content
box to cover the whole element rect (a hard box over the webcam) the moment the
widget drew any content. Stateful take-1-good/take-2-bad: an idle transparent page
produces a full-frame crop (≈ the correct full-canvas viewport), any real content
produced a tight crop + zoom.
**Derived-solution rule (2026-08-29, driven by the image-shrink incident):** when
you work out any one-off, reusable solution (recipe / workaround / how-to), write