Transitions: fade starts from the outgoing picture (was an instant cut)

The transition started with no from-frame, so BlendFrame returned the new scene at once.
Start now requests a capture and the frame pump supplies its last output on the next tick.
Test: TransitionFadeTests. Docs: ai.md, TASKS.md.

Not pushed.
This commit is contained in:
2026-10-27 08:39:49 -07:00
parent 7ae30d4cfc
commit 90cd039d98
5 changed files with 62 additions and 0 deletions
+5
View File
@@ -32,6 +32,7 @@ public sealed class FramePump : IDisposable
private readonly Func<VideoFrame?>? _alertTicker;
private readonly Func<VideoFrame?>? _brandFlash;
private readonly TransitionService? _transition;
private VideoFrame? _lastOutput;
private readonly SceneGraph? _sceneGraph;
private readonly SceneCompositor _compositor = new();
@@ -497,6 +498,9 @@ public sealed class FramePump : IDisposable
socialBarTicks += sw.ElapsedTicks;
VideoFrame frame;
if (_transition is { CaptureRequested: true } capture && _lastOutput != null)
capture.SupplyFromFrame(new VideoFrame(_lastOutput.Width, _lastOutput.Height,
(byte[])_lastOutput.BgraPixels.Clone()));
var scratchSize = compositorOptions.SourceRectWidth
* compositorOptions.SourceRectHeight * 4;
renderSw.Restart();
@@ -567,6 +571,7 @@ public sealed class FramePump : IDisposable
// tick's buffers are recyclable once the enqueue snapshot them.
// The free-list Contains guard keeps the Cut path (BlendFrame
// returns toFrame itself, aliasing scratch) safe.
_lastOutput = frame;
ReleaseScratch(frame.BgraPixels);
ReleaseScratch(scratch);