optional preview frame
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m23s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
2026-05-20 14:37:24 +10:00
parent 1d4eb7a34c
commit bfaa3f5e0e
25 changed files with 700 additions and 2740 deletions

View File

@@ -2,6 +2,7 @@
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iostream>
namespace
@@ -184,6 +185,127 @@ void TestCompletedPollMissIsCounted()
Expect(metrics.completedPollMisses == 1, "completed poll miss is counted");
}
void TestLatestPublishedFrameCanBePreviewedWithoutConsuming()
{
SystemFrameExchange exchange(MakeConfig(2));
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "copy snapshot frame can be acquired");
frame.frameIndex = 77;
const unsigned char marker = 0x42;
std::memset(frame.bytes, marker, static_cast<std::size_t>(frame.rowBytes) * frame.height);
Expect(exchange.PublishCompleted(frame), "copy snapshot frame can be completed");
SystemFrame preview;
Expect(exchange.TryAcquireLatestForPreview(preview), "latest published frame can be acquired for preview");
Expect(preview.frameIndex == 77, "preview frame keeps frame index");
Expect(preview.width == 4 && preview.height == 3, "preview frame keeps frame dimensions");
Expect(preview.bytes != nullptr && static_cast<unsigned char*>(preview.bytes)[0] == marker, "preview frame points at frame bytes");
Expect(exchange.ReleasePreviewFrame(preview), "preview frame can be released");
SystemFrame scheduled;
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "previewing frame does not consume completed frame");
}
void TestLatestPublishedFrameCanPreviewScheduledFrame()
{
SystemFrameExchange exchange(MakeConfig(1));
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "scheduled snapshot frame can be acquired");
frame.frameIndex = 88;
Expect(exchange.PublishCompleted(frame), "scheduled snapshot frame can be completed");
SystemFrame scheduled;
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "snapshot test frame can be scheduled");
SystemFrame preview;
Expect(exchange.TryAcquireLatestForPreview(preview), "latest scheduled frame can be acquired for preview");
Expect(preview.frameIndex == 88, "scheduled preview keeps frame index");
Expect(exchange.ReleasePreviewFrame(preview), "scheduled preview frame can be released");
}
void TestPreviewFramePinsReleasedSlotUntilPreviewRelease()
{
SystemFrameExchange exchange(MakeConfig(1));
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "preview pin frame can be acquired");
frame.frameIndex = 99;
Expect(exchange.PublishCompleted(frame), "preview pin frame can be completed");
SystemFrame preview;
Expect(exchange.TryAcquireLatestForPreview(preview), "preview can acquire frame before schedule");
SystemFrame scheduled;
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "previewed frame can still be scheduled");
Expect(exchange.ReleaseScheduledByBytes(scheduled.bytes), "scheduled frame can be released while preview holds it");
SystemFrame blocked;
Expect(!exchange.AcquireForRender(blocked), "preview reader prevents immediate slot reuse");
Expect(exchange.ReleasePreviewFrame(preview), "preview pin can be released");
Expect(exchange.AcquireForRender(blocked), "slot can be reused after preview release");
}
void TestMultiplePreviewReadersPinReleasedSlotUntilAllRelease()
{
SystemFrameExchange exchange(MakeConfig(1));
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "multi-preview frame can be acquired");
frame.frameIndex = 100;
Expect(exchange.PublishCompleted(frame), "multi-preview frame can be completed");
SystemFrame firstPreview;
SystemFrame secondPreview;
Expect(exchange.TryAcquireLatestForPreview(firstPreview), "first preview reader can acquire");
Expect(exchange.TryAcquireLatestForPreview(secondPreview), "second preview reader can acquire");
SystemFrame scheduled;
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "multi-preview frame can be scheduled");
Expect(exchange.ReleaseScheduledByBytes(scheduled.bytes), "multi-preview scheduled frame can be released");
SystemFrame blocked;
Expect(!exchange.AcquireForRender(blocked), "slot remains pinned while two preview readers exist");
Expect(exchange.ReleasePreviewFrame(firstPreview), "first preview reader can release");
Expect(!exchange.AcquireForRender(blocked), "slot remains pinned until last preview reader releases");
Expect(exchange.ReleasePreviewFrame(secondPreview), "second preview reader can release");
Expect(exchange.AcquireForRender(blocked), "slot is reusable after all preview readers release");
}
void TestInvalidPreviewReleaseIsRejected()
{
SystemFrameExchange exchange(MakeConfig(1));
SystemFrame invalid;
Expect(!exchange.ReleasePreviewFrame(invalid), "empty preview frame release is rejected");
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "invalid release source frame can be acquired");
frame.frameIndex = 101;
Expect(exchange.PublishCompleted(frame), "invalid release source frame can be completed");
SystemFrame preview;
Expect(exchange.TryAcquireLatestForPreview(preview), "preview frame can be acquired for invalid release test");
Expect(exchange.ReleasePreviewFrame(preview), "valid preview release succeeds");
Expect(!exchange.ReleasePreviewFrame(preview), "double preview release is rejected");
}
void TestStalePreviewReleaseIsRejectedAfterReconfigure()
{
SystemFrameExchange exchange(MakeConfig(1));
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "stale preview source frame can be acquired");
frame.frameIndex = 102;
Expect(exchange.PublishCompleted(frame), "stale preview source frame can be completed");
SystemFrame preview;
Expect(exchange.TryAcquireLatestForPreview(preview), "preview frame can be acquired before reconfigure");
exchange.Configure(MakeConfig(1));
Expect(!exchange.ReleasePreviewFrame(preview), "preview release after reconfigure is rejected as stale");
}
void TestStableCompletedDepthCanBeObserved()
{
SystemFrameExchange exchange(MakeConfig(1));
@@ -214,6 +336,12 @@ int main()
TestGenerationValidationRejectsStaleFrames();
TestPixelFormatAwareSizing();
TestCompletedPollMissIsCounted();
TestLatestPublishedFrameCanBePreviewedWithoutConsuming();
TestLatestPublishedFrameCanPreviewScheduledFrame();
TestPreviewFramePinsReleasedSlotUntilPreviewRelease();
TestMultiplePreviewReadersPinReleasedSlotUntilAllRelease();
TestInvalidPreviewReleaseIsRejected();
TestStalePreviewReleaseIsRejectedAfterReconfigure();
TestStableCompletedDepthCanBeObserved();
TestStableCompletedDepthTimesOut();