fix(web): add CropBounds to PasteKey — stale raster cache was corrupting transparency
This commit is contained in:
@@ -19,11 +19,13 @@ public sealed class SceneCompositor
|
|||||||
// chat/web/image layers are identical frame after frame. Same shape as OBS (the
|
// chat/web/image layers are identical frame after frame. Same shape as OBS (the
|
||||||
// source surface is cached, the compositor blits): a scaled/round-clipped/mirrored
|
// source surface is cached, the compositor blits): a scaled/round-clipped/mirrored
|
||||||
// layer rasterizes once and is pasted (row-copy/blend) on every later tick.
|
// layer rasterizes once and is pasted (row-copy/blend) on every later tick.
|
||||||
// Keyed by the SOURCE FRAME IDENTITY (array + Epoch) — producers hand out fresh
|
// Keyed by the SOURCE FRAME IDENTITY (array + Epoch + CropBounds) — producers hand
|
||||||
// immutable byte[], or recycled-ring arrays whose monotonic Epoch distinguishes
|
// out fresh immutable byte[], or recycled-ring arrays whose monotonic Epoch distinguishes
|
||||||
// each generation (screen capture, take-11 fix), so "same array+epoch + same
|
// each generation (screen capture, take-11 fix). CropBounds must be in the key because
|
||||||
// target rect" ⇒ same raster. Bounds-checked eviction clears wholesale.
|
// the same frame (same Pixels/Epoch/Width/Height) can have different CropBounds as
|
||||||
private sealed record PasteKey(byte[] Pixels, long Epoch, int SrcW, int SrcH, int DstW, int DstH, bool Round, bool Mirror);
|
// the element is resized — a stale cached raster with wrong crop pixels would corrupt
|
||||||
|
// the output. Bounds-checked eviction clears wholesale.
|
||||||
|
private sealed record PasteKey(byte[] Pixels, long Epoch, int SrcW, int SrcH, int DstW, int DstH, bool Round, bool Mirror, (int X, int Y, int W, int H)? CropBounds);
|
||||||
private static readonly Dictionary<PasteKey, VideoFrame> _pasteCache = new();
|
private static readonly Dictionary<PasteKey, VideoFrame> _pasteCache = new();
|
||||||
private static readonly Dictionary<SceneElement, VideoFrame> _elementRasters = new(ReferenceEqualityComparer.Instance);
|
private static readonly Dictionary<SceneElement, VideoFrame> _elementRasters = new(ReferenceEqualityComparer.Instance);
|
||||||
private static readonly object _pasteGate = new();
|
private static readonly object _pasteGate = new();
|
||||||
@@ -286,7 +288,7 @@ public sealed class SceneCompositor
|
|||||||
VideoFrame? raster = null;
|
VideoFrame? raster = null;
|
||||||
lock (_pasteGate)
|
lock (_pasteGate)
|
||||||
{
|
{
|
||||||
key = new PasteKey(frame.BgraPixels, frame.Epoch, frame.Width, frame.Height, dw, dh, isRound, mirror);
|
key = new PasteKey(frame.BgraPixels, frame.Epoch, frame.Width, frame.Height, dw, dh, isRound, mirror, frame.CropBounds);
|
||||||
_pasteCache.TryGetValue(key, out raster);
|
_pasteCache.TryGetValue(key, out raster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user