diff --git a/HANDOFF.md b/HANDOFF.md index a2b00fa..5e9b1fb 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,29 +1,40 @@ -# HANDOFF — 2026-09-06 +# HANDOFF — 2026-09-08 ## Branch / Commit State -**`main` HEAD = `e002847`** — web transparency fix (take-21): feed full canvas to compositor. +**`main` HEAD = `f6802c7`** — take-23: stride-correct CropBounds Fill rendering. ``` +f6802c7 fix(web): stride-correct CropBounds Fill rendering in compositor (take-23) +84aa70f docs: MyMistakes.md — take-22 full fix for widget scale/position + transparency +ed9d7c1 fix(web): CropBounds metadata + Fill-style scaling in compositor — transparent margins preserved, widget fills element rect (BROKEN — reverted) +5ca9778 docs: update HANDOFF + MyMistakes.md — take-21 web transparency fix landed e002847 fix(web): feed full canvas to compositor — transparent margins reveal layers beneath (take-21) 70db344 perf(camera): MJPEG negotiation before frame reader — camera drives at its best rate -0f059ec docs: HANDOFF — #12 landed (element rasters), MJPEG next, web transparency spin-guarded -6d11e8b perf(compositor): reuse per-element rasters in-place — take-16 GC-churn fix -87509bc (origin/main) docs: restructure TASKS.md into a catalog — one file per task in TASKS/ +87509bc (origin/main) docs: restructure TASKS.md into a catalog ``` -**Pushed to origin: `87509bc`.** 4 unpushed commits after it. +**Pushed to origin: `87509bc`.** 7 unpushed commits after it. -**`today-slices` branch @ `ce87490`** — preserves 17-commit chain. Fallback recovery. +## Web Overlay — Current State + +take-22 (`ed9d7c1`) BROKE the widget — the CropBounds stride was wrong (pixel index used `w = cbW` crop width instead of `src.Width` canvas stride, reading garbage from the full-canvas buffer). REVERTED by the take-23 revert of `ed9d7c1`. + +take-23 (`f6802c7`) is the correct fix: +- `VideoFrame.CropBounds?: (X,Y,W,H)` — metadata on the frame +- `WebView2Manager` sets `CropBounds = (cropX, cropY, cropW, cropH)` on the LatestFrame +- `BlitContentRaw` detects CropBounds and uses Fill-style scaling (stretch to cover, no aspect preservation) using `src.Width` (canvas stride = 1920) for ALL pixel buffer indexing — not the crop width ## Resolved this session -- **Audio regression (TASK 26):** Non-event — external headset volume control was at minimum, not a code bug. -- **Webcam black square / web overlay transparency:** FIXED at `e002847`. Root cause: `bccdb48` introduced alpha cropping; the CROP was fed to the compositor, which `UniformToFill`-zoomed the opaque content to cover the entire element rect. Fix: feed the FULL `1920×1080` canvas to the compositor; transparent margins reveal layers beneath; the alpha crop (`outPixels`) is used only for the preview `WriteableBitmap`. `0f441d8` (take-19) had the right insight but introduced `CanvasRing` alongside the fix — the ring reuse caused additional breakage. Take-21 keeps the single `CanvasScratch` buffer (no ring), feeds full canvas, Epoch increments per frame. +- **Audio regression (TASK 26):** Non-event — external headset volume control was at minimum. +- **Web overlay scale/position + transparency:** take-23 at `f6802c7`. The stride fix was critical — take-22 used crop width (e.g., 800) instead of canvas stride (1920) in pixel indexing, reading garbage from the full-canvas buffer and destroying content. -## MyMistakes.md update needed +## Still open (needs your run + log) -The spin-guard entry for the web overlay needs updating with the take-21 resolution. See that file. +- **Chat overlay missing from recording:** Chat shows in preview but not in recorded output. +- **Audio/sync issues:** unspecified, no log yet. +- **Webcam/capture speed:** unspecified, no log yet. ## Landmines diff --git a/MyMistakes.md b/MyMistakes.md index 03d1244..c465bd3 100644 --- a/MyMistakes.md +++ b/MyMistakes.md @@ -15,31 +15,27 @@ ## 🔬 Recipes registry -### ⚠ SPIN GUARD TRIGGERED → RESOLVED (take-21, 22) — web overlay transparency + scale +### ⚠ SPIN GUARD TRIGGERED → RESOLVED (take-21, 22 broke, 23 fixed) — web overlay transparency + scale **Take-19 (`0f441d8`): FAILED.** Attempted to feed the compositor the FULL canvas instead of the alpha crop. User verdict: "didn't work at all — broke additional crap." Reverted (`1295e0e`). The crop→UniformToFill zoom insight was RIGHT, but the commit ALSO introduced `CanvasRing` (8-deep -full-canvas buffer ring) alongside the fix — the ring reuse poisoned the paste cache (array identity -collisions via the Epoch mechanism), causing additional breakage beyond the transparency issue. +full-canvas buffer ring) alongside the fix — the ring reuse poisoned the paste cache. -**Take-21 (`e002847`): PARTIAL FIX — transparency confirmed, but widget appeared shrunk and offset.** -Root cause of transparency: `bccdb48` introduced `FindContentBounds` alpha cropping; the CROP was -fed to the compositor (`session.LatestFrame = VideoFrame(cropW, cropH, outPixels)`). `UniformToFill` -then zoomed the opaque crop content to cover the whole element rect, covering whatever was beneath -(webcam). Fix: keep the single `CanvasScratch` buffer (no ring), feed the FULL `1920×1080` canvas -to the compositor (`session.LatestFrame = VideoFrame(pixW, pixH, pixels)`), use the alpha crop only -for the preview `WriteableBitmap`. Transparent margins revealed layers beneath — BUT the widget -content appeared at ~1/3 scale and misplaced: the compositor's `UniformToFill` used `src=1920×1080` -for a WebSource element sized 703×389, computing scale=0.366. The preview showed `Stretch="Fill"` with -the CROPPED `PreviewBitmap` — completely different math, hence "looks correct in preview, wrong in -recording." +**Take-21 (`e002847`): PARTIAL FIX.** Feed full canvas, transparent margins revealed — but the +widget appeared shrunk and offset. `UniformToFill` used `src=1920×1080` for a 703×389 element +→ scale=0.366. The preview used `Stretch="Fill"` on the CROPPED bitmap — different math. -**Take-22 (`ed9d7c1`): FULL FIX.** `VideoFrame` gets `CropBounds?: (X,Y,W,H)` metadata. The full -canvas still goes to the compositor, but `BlitContentRaw` detects `CropBounds` and switches from -`UniformToFill` to Fill-style scaling (stretch to cover, no aspect preservation) using the actual -crop dimensions. This matches the preview's `Stretch="Fill"` on the crop. Widget content now fills -the element rect at the correct position; transparent margins still reveal layers beneath. +**Take-22 (`ed9d7c1`): BROKE IT.** Added `CropBounds` metadata but the pixel index in +`BlitContentRaw` used `w = cbW` (crop width, e.g. 800) instead of `src.Width` (canvas stride += 1920) for buffer indexing. Since `s = src.BgraPixels` is the FULL canvas buffer, multiplying +by crop width instead of canvas stride computed completely wrong memory offsets — garbage pixels, +"original content destroyed." Reverted. + +**Take-23 (`f6802c7`): CORRECT FIX.** `BlitContentRaw` CropBounds path now uses `src.Width` +(canvas stride = 1920) for ALL pixel indexing. The Fill-style scale centers the crop content +in the element rect. Transparent margins of the full canvas are preserved and reveal layers +beneath. `srcStride` is explicitly named `srcStride = src.Width` to prevent this mistake recurring. ### Shrink / re-encode an image for the README (screenshots → small hero image)