Use Pacer to drive all rendering

This commit is contained in:
Cameron Gutman
2018-08-15 23:57:03 -07:00
parent f6a451d6e7
commit 7d61acb2a8
13 changed files with 65 additions and 75 deletions
@@ -10,7 +10,7 @@
#define FRAME_HISTORY_ENTRIES 8
Pacer::Pacer(IVsyncRenderer* renderer) :
Pacer::Pacer(IFFmpegRenderer* renderer) :
m_FrameQueueLock(0),
m_VsyncSource(nullptr),
m_VsyncRenderer(renderer),
@@ -111,10 +111,15 @@ bool Pacer::initialize(SDL_Window* window, int maxVideoFps)
#elif defined(Q_OS_WIN32)
m_VsyncSource = new DxVsyncSource(this);
#else
SDL_assert(false);
// Platforms without a VsyncSource will just render frames
// immediately like they used to.
#endif
return m_VsyncSource->initialize(window);
if (m_VsyncSource != nullptr && !m_VsyncSource->initialize(window)) {
return false;
}
return true;
}
void Pacer::submitFrame(AVFrame* frame)
@@ -122,9 +127,18 @@ void Pacer::submitFrame(AVFrame* frame)
// Make sure initialize() has been called
SDL_assert(m_MaxVideoFps != 0);
SDL_AtomicLock(&m_FrameQueueLock);
m_FrameQueue.enqueue(frame);
SDL_AtomicUnlock(&m_FrameQueueLock);
// Queue the frame until the V-sync callback if
// we have a V-sync source, otherwise deliver it
// immediately and hope for the best.
if (m_VsyncSource != nullptr) {
SDL_AtomicLock(&m_FrameQueueLock);
m_FrameQueue.enqueue(frame);
SDL_AtomicUnlock(&m_FrameQueueLock);
}
else {
m_VsyncRenderer->renderFrameAtVsync(frame);
av_frame_free(&frame);
}
}
void Pacer::drain()
@@ -4,14 +4,6 @@
#include <QQueue>
class Pacer;
class IVsyncRenderer {
public:
virtual ~IVsyncRenderer() {}
virtual void renderFrameAtVsync(AVFrame* frame) = 0;
};
class IVsyncSource {
public:
virtual ~IVsyncSource() {}
@@ -21,7 +13,7 @@ public:
class Pacer
{
public:
Pacer(IVsyncRenderer* renderer);
Pacer(IFFmpegRenderer* renderer);
~Pacer();
@@ -39,7 +31,7 @@ private:
SDL_SpinLock m_FrameQueueLock;
IVsyncSource* m_VsyncSource;
IVsyncRenderer* m_VsyncRenderer;
IFFmpegRenderer* m_VsyncRenderer;
int m_MaxVideoFps;
int m_DisplayFps;
};