V2 working
This commit is contained in:
176
tests/RenderCadenceCompositorFrameExchangeTests.cpp
Normal file
176
tests/RenderCadenceCompositorFrameExchangeTests.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
#include "SystemFrameExchange.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
int gFailures = 0;
|
||||
|
||||
void Expect(bool condition, const char* message)
|
||||
{
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
std::cerr << "FAIL: " << message << "\n";
|
||||
++gFailures;
|
||||
}
|
||||
|
||||
SystemFrameExchangeConfig MakeConfig(std::size_t capacity = 2)
|
||||
{
|
||||
SystemFrameExchangeConfig config;
|
||||
config.width = 4;
|
||||
config.height = 3;
|
||||
config.pixelFormat = VideoIOPixelFormat::Bgra8;
|
||||
config.capacity = capacity;
|
||||
return config;
|
||||
}
|
||||
|
||||
void TestAcquirePublishesAndSchedules()
|
||||
{
|
||||
SystemFrameExchange exchange(MakeConfig(1));
|
||||
|
||||
SystemFrame frame;
|
||||
Expect(exchange.AcquireForRender(frame), "frame can be acquired for render");
|
||||
Expect(frame.bytes != nullptr, "acquired frame has storage");
|
||||
Expect(frame.width == 4, "frame width is configured");
|
||||
Expect(frame.height == 3, "frame height is configured");
|
||||
Expect(frame.rowBytes == 16, "BGRA8 row bytes are inferred");
|
||||
Expect(frame.pixelFormat == VideoIOPixelFormat::Bgra8, "pixel format is configured");
|
||||
|
||||
frame.frameIndex = 42;
|
||||
Expect(exchange.PublishCompleted(frame), "rendering frame can be completed");
|
||||
Expect(exchange.WaitForCompletedDepth(1, std::chrono::milliseconds(0)), "completed depth can be observed");
|
||||
|
||||
SystemFrame scheduled;
|
||||
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "completed frame can be scheduled");
|
||||
Expect(scheduled.index == frame.index, "scheduled frame uses completed slot");
|
||||
Expect(scheduled.generation == frame.generation, "scheduled frame keeps generation");
|
||||
Expect(scheduled.frameIndex == 42, "frame index is preserved");
|
||||
|
||||
Expect(exchange.ReleaseScheduledByBytes(scheduled.bytes), "scheduled frame can be released by bytes");
|
||||
|
||||
SystemFrameExchangeMetrics metrics = exchange.Metrics();
|
||||
Expect(metrics.freeCount == 1, "released slot returns to free");
|
||||
Expect(metrics.completedFrames == 1, "completed metric is counted");
|
||||
Expect(metrics.scheduledFrames == 1, "scheduled metric is counted");
|
||||
}
|
||||
|
||||
void TestAcquireDropsOldestCompletedUnscheduled()
|
||||
{
|
||||
SystemFrameExchange exchange(MakeConfig(2));
|
||||
|
||||
SystemFrame first;
|
||||
SystemFrame second;
|
||||
SystemFrame third;
|
||||
Expect(exchange.AcquireForRender(first), "first frame can be acquired");
|
||||
first.frameIndex = 1;
|
||||
Expect(exchange.PublishCompleted(first), "first frame can be completed");
|
||||
Expect(exchange.AcquireForRender(second), "second frame can be acquired");
|
||||
second.frameIndex = 2;
|
||||
Expect(exchange.PublishCompleted(second), "second frame can be completed");
|
||||
|
||||
Expect(exchange.AcquireForRender(third), "third acquire drops the oldest completed frame");
|
||||
Expect(third.index == first.index, "oldest completed slot is reused");
|
||||
|
||||
SystemFrame scheduled;
|
||||
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "remaining completed frame can be scheduled");
|
||||
Expect(scheduled.index == second.index, "newer completed frame survives drop");
|
||||
Expect(scheduled.frameIndex == 2, "newer frame index survives drop");
|
||||
|
||||
SystemFrameExchangeMetrics metrics = exchange.Metrics();
|
||||
Expect(metrics.completedDrops == 1, "drop metric is counted");
|
||||
Expect(metrics.renderingCount == 1, "reused slot is rendering");
|
||||
Expect(metrics.scheduledCount == 1, "consumed slot is scheduled");
|
||||
}
|
||||
|
||||
void TestScheduledFramesAreNotDropped()
|
||||
{
|
||||
SystemFrameExchange exchange(MakeConfig(1));
|
||||
|
||||
SystemFrame frame;
|
||||
Expect(exchange.AcquireForRender(frame), "single frame can be acquired");
|
||||
Expect(exchange.PublishCompleted(frame), "single frame can be completed");
|
||||
|
||||
SystemFrame scheduled;
|
||||
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "single frame can be scheduled");
|
||||
|
||||
SystemFrame extra;
|
||||
Expect(!exchange.AcquireForRender(extra), "scheduled frame is not dropped for render acquire");
|
||||
|
||||
SystemFrameExchangeMetrics metrics = exchange.Metrics();
|
||||
Expect(metrics.acquireMisses == 1, "blocked acquire miss is counted");
|
||||
Expect(metrics.completedDrops == 0, "scheduled frame is not counted as a completed drop");
|
||||
}
|
||||
|
||||
void TestGenerationValidationRejectsStaleFrames()
|
||||
{
|
||||
SystemFrameExchange exchange(MakeConfig(1));
|
||||
|
||||
SystemFrame first;
|
||||
Expect(exchange.AcquireForRender(first), "frame can be acquired");
|
||||
Expect(exchange.PublishCompleted(first), "frame can be completed");
|
||||
|
||||
SystemFrame scheduled;
|
||||
Expect(exchange.ConsumeCompletedForSchedule(scheduled), "frame can be scheduled");
|
||||
Expect(exchange.ReleaseScheduledByBytes(scheduled.bytes), "frame can be released");
|
||||
|
||||
SystemFrame second;
|
||||
Expect(exchange.AcquireForRender(second), "slot can be reacquired");
|
||||
Expect(second.index == first.index, "same slot is reused");
|
||||
Expect(second.generation != first.generation, "reacquire invalidates stale generation");
|
||||
Expect(!exchange.PublishCompleted(first), "stale frame cannot be completed");
|
||||
}
|
||||
|
||||
void TestPixelFormatAwareSizing()
|
||||
{
|
||||
SystemFrameExchangeConfig config;
|
||||
config.width = 7;
|
||||
config.height = 2;
|
||||
config.pixelFormat = VideoIOPixelFormat::V210;
|
||||
config.capacity = 1;
|
||||
|
||||
SystemFrameExchange exchange(config);
|
||||
SystemFrame frame;
|
||||
Expect(exchange.AcquireForRender(frame), "v210 frame can be acquired");
|
||||
Expect(frame.pixelFormat == VideoIOPixelFormat::V210, "v210 pixel format is preserved");
|
||||
Expect(frame.rowBytes == static_cast<long>(VideoIORowBytes(VideoIOPixelFormat::V210, 7)), "v210 row bytes are inferred");
|
||||
|
||||
config.pixelFormat = VideoIOPixelFormat::Uyvy8;
|
||||
config.rowBytes = 64;
|
||||
exchange.Configure(config);
|
||||
Expect(exchange.AcquireForRender(frame), "explicit row-byte frame can be acquired");
|
||||
Expect(frame.pixelFormat == VideoIOPixelFormat::Uyvy8, "reconfigured pixel format is preserved");
|
||||
Expect(frame.rowBytes == 64, "explicit row bytes are preserved");
|
||||
}
|
||||
|
||||
void TestCompletedPollMissIsCounted()
|
||||
{
|
||||
SystemFrameExchange exchange(MakeConfig(1));
|
||||
SystemFrame frame;
|
||||
Expect(!exchange.ConsumeCompletedForSchedule(frame), "empty completed queue cannot be consumed");
|
||||
|
||||
SystemFrameExchangeMetrics metrics = exchange.Metrics();
|
||||
Expect(metrics.completedPollMisses == 1, "completed poll miss is counted");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TestAcquirePublishesAndSchedules();
|
||||
TestAcquireDropsOldestCompletedUnscheduled();
|
||||
TestScheduledFramesAreNotDropped();
|
||||
TestGenerationValidationRejectsStaleFrames();
|
||||
TestPixelFormatAwareSizing();
|
||||
TestCompletedPollMissIsCounted();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
std::cerr << gFailures << " frame exchange test failure(s).\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "RenderCadenceCompositor frame exchange tests passed.\n";
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user