Files
video-shader-toys/tests/RenderOutputQueueTests.cpp
Aiden 9e3412712c
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m52s
CI / Windows Release Package (push) Successful in 3m0s
Improvement
2026-05-12 00:00:23 +10:00

186 lines
4.8 KiB
C++

#include "RenderOutputQueue.h"
#include <iostream>
namespace
{
int gFailures = 0;
int gReleasedFrames = 0;
void Expect(bool condition, const char* message)
{
if (condition)
return;
std::cerr << "FAIL: " << message << "\n";
++gFailures;
}
RenderOutputFrame MakeFrame(uint64_t index)
{
RenderOutputFrame frame;
frame.frameIndex = index;
frame.frame.nativeFrame = reinterpret_cast<void*>(static_cast<uintptr_t>(index + 1));
return frame;
}
void CountReleasedFrame(VideoIOOutputFrame& frame)
{
if (frame.nativeFrame != nullptr)
{
++gReleasedFrames;
frame.nativeFrame = nullptr;
}
}
RenderOutputFrame MakeOwnedFrame(uint64_t index)
{
RenderOutputFrame frame = MakeFrame(index);
frame.releaseFrame = CountReleasedFrame;
return frame;
}
void TestQueuePreservesOrdering()
{
VideoPlayoutPolicy policy;
policy.maxReadyFrames = 3;
RenderOutputQueue queue(policy);
Expect(queue.Push(MakeFrame(1)), "first ready frame pushes");
Expect(queue.Push(MakeFrame(2)), "second ready frame pushes");
RenderOutputFrame frame;
Expect(queue.TryPop(frame), "first ready frame pops");
Expect(frame.frameIndex == 1, "queue pops first frame first");
Expect(queue.TryPop(frame), "second ready frame pops");
Expect(frame.frameIndex == 2, "queue pops second frame second");
}
void TestBoundedQueueDropsOldestFrame()
{
VideoPlayoutPolicy policy;
policy.maxReadyFrames = 2;
RenderOutputQueue queue(policy);
queue.Push(MakeFrame(1));
queue.Push(MakeFrame(2));
queue.Push(MakeFrame(3));
RenderOutputQueueMetrics metrics = queue.GetMetrics();
Expect(metrics.depth == 2, "bounded queue depth stays at capacity");
Expect(metrics.droppedCount == 1, "bounded queue counts dropped oldest frame");
RenderOutputFrame frame;
Expect(queue.TryPop(frame), "bounded queue pops after drop");
Expect(frame.frameIndex == 2, "oldest frame was dropped when queue overflowed");
}
void TestOverflowReleasesDroppedFrame()
{
gReleasedFrames = 0;
VideoPlayoutPolicy policy;
policy.targetReadyFrames = 1;
policy.maxReadyFrames = 1;
RenderOutputQueue queue(policy);
queue.Push(MakeOwnedFrame(1));
queue.Push(MakeOwnedFrame(2));
Expect(gReleasedFrames == 1, "overflow releases dropped ready frame");
RenderOutputFrame frame;
Expect(queue.TryPop(frame), "newest owned frame remains queued");
Expect(frame.frameIndex == 2, "overflow keeps newest owned frame");
Expect(gReleasedFrames == 1, "pop transfers ownership without releasing");
}
void TestUnderrunIsCounted()
{
RenderOutputQueue queue;
RenderOutputFrame frame;
Expect(!queue.TryPop(frame), "empty queue reports underrun");
RenderOutputQueueMetrics metrics = queue.GetMetrics();
Expect(metrics.underrunCount == 1, "empty pop increments underrun count");
}
void TestConfigureShrinksDepthToNewCapacity()
{
VideoPlayoutPolicy policy;
policy.maxReadyFrames = 4;
RenderOutputQueue queue(policy);
queue.Push(MakeFrame(1));
queue.Push(MakeFrame(2));
queue.Push(MakeFrame(3));
VideoPlayoutPolicy smallerPolicy;
smallerPolicy.targetReadyFrames = 1;
smallerPolicy.maxReadyFrames = 1;
queue.Configure(smallerPolicy);
RenderOutputQueueMetrics metrics = queue.GetMetrics();
Expect(metrics.depth == 1, "configure trims queue to new capacity");
Expect(metrics.droppedCount == 2, "configure counts trimmed frames as drops");
RenderOutputFrame frame;
Expect(queue.TryPop(frame), "trimmed queue still has newest frame");
Expect(frame.frameIndex == 3, "configure keeps newest ready frame");
}
void TestConfigureReleasesTrimmedFrames()
{
gReleasedFrames = 0;
VideoPlayoutPolicy policy;
policy.maxReadyFrames = 3;
RenderOutputQueue queue(policy);
queue.Push(MakeOwnedFrame(1));
queue.Push(MakeOwnedFrame(2));
queue.Push(MakeOwnedFrame(3));
VideoPlayoutPolicy smallerPolicy;
smallerPolicy.targetReadyFrames = 1;
smallerPolicy.maxReadyFrames = 1;
queue.Configure(smallerPolicy);
Expect(gReleasedFrames == 2, "configure releases trimmed ready frames");
RenderOutputFrame frame;
Expect(queue.TryPop(frame), "trimmed owned queue still has newest frame");
Expect(frame.frameIndex == 3, "configure keeps newest owned frame after release");
}
void TestClearReleasesQueuedFrames()
{
gReleasedFrames = 0;
RenderOutputQueue queue;
queue.Push(MakeOwnedFrame(1));
queue.Push(MakeOwnedFrame(2));
queue.Clear();
RenderOutputQueueMetrics metrics = queue.GetMetrics();
Expect(metrics.depth == 0, "clear empties ready queue");
Expect(gReleasedFrames == 2, "clear releases queued ready frames");
}
}
int main()
{
TestQueuePreservesOrdering();
TestBoundedQueueDropsOldestFrame();
TestOverflowReleasesDroppedFrame();
TestUnderrunIsCounted();
TestConfigureShrinksDepthToNewCapacity();
TestConfigureReleasesTrimmedFrames();
TestClearReleasesQueuedFrames();
if (gFailures != 0)
{
std::cerr << gFailures << " render output queue test failure(s).\n";
return 1;
}
std::cout << "RenderOutputQueue tests passed.\n";
return 0;
}