Enhance frame pacing logic for HDR renderers

This commit is contained in:
Cameron Gutman
2022-04-24 17:43:35 -05:00
parent 5f682bb45f
commit 2bb2745f91
6 changed files with 47 additions and 18 deletions

View File

@@ -208,6 +208,7 @@ bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enablePacing)
{
m_MaxVideoFps = maxVideoFps;
m_DisplayFps = StreamUtils::getDisplayRefreshRate(window);
m_RendererAttributes = m_VsyncRenderer->getRendererAttributes();
if (enablePacing) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
@@ -225,6 +226,8 @@ bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enablePacing)
// immediately like they used to.
#endif
SDL_assert(m_VsyncSource != nullptr || !(m_RendererAttributes & RENDERER_ATTRIBUTE_FORCE_PACING));
if (m_VsyncSource != nullptr && !m_VsyncSource->initialize(window, m_DisplayFps)) {
return false;
}
@@ -259,22 +262,31 @@ void Pacer::renderFrame(AVFrame* frame)
// Drop frames if we have too many queued up for a while
m_FrameQueueLock.lock();
int frameDropTarget = 0;
for (int queueHistoryEntry : m_RenderQueueHistory) {
if (queueHistoryEntry == 0) {
// Be lenient as long as the queue length
// resolves before the end of frame history
frameDropTarget = 2;
break;
int frameDropTarget;
if (m_RendererAttributes & RENDERER_ATTRIBUTE_NO_BUFFERING) {
// Renderers that don't buffer any frames but don't support waitToRender() need us to buffer
// an extra frame to ensure they don't starve while waiting to present.
frameDropTarget = 1;
}
else {
frameDropTarget = 0;
for (int queueHistoryEntry : m_RenderQueueHistory) {
if (queueHistoryEntry == 0) {
// Be lenient as long as the queue length
// resolves before the end of frame history
frameDropTarget = 2;
break;
}
}
}
// Keep a rolling 500 ms window of render queue history
if (m_RenderQueueHistory.count() == m_MaxVideoFps / 2) {
m_RenderQueueHistory.dequeue();
}
// Keep a rolling 500 ms window of render queue history
if (m_RenderQueueHistory.count() == m_MaxVideoFps / 2) {
m_RenderQueueHistory.dequeue();
}
m_RenderQueueHistory.enqueue(m_RenderQueue.count());
m_RenderQueueHistory.enqueue(m_RenderQueue.count());
}
// Catch up if we're several frames ahead
while (m_RenderQueue.count() > frameDropTarget) {