renderer: attach renderer to single thread

This commit is contained in:
itsmattkc
2022-06-24 09:59:28 -07:00
parent 15d6f407eb
commit ec215f7de6
2 changed files with 143 additions and 25 deletions
+106 -23
View File
@@ -38,21 +38,11 @@ namespace olive {
RenderManager* RenderManager::instance_ = nullptr; RenderManager* RenderManager::instance_ = nullptr;
RenderManager::RenderManager(QObject *parent) : RenderManager::RenderManager(QObject *parent) :
ThreadPool(1, parent),
backend_(kOpenGL), backend_(kOpenGL),
aggressive_gc_(0) aggressive_gc_(0)
{ {
Renderer* graphics_renderer = nullptr;
if (backend_ == kOpenGL) { if (backend_ == kOpenGL) {
graphics_renderer = new OpenGLRenderer(); context_ = new OpenGLRenderer();
}
if (graphics_renderer) {
context_ = new RendererThreadWrapper(graphics_renderer, this);
context_->Init();
context_->PostInit();
decoder_cache_ = new DecoderCache(); decoder_cache_ = new DecoderCache();
shader_cache_ = new ShaderCache(); shader_cache_ = new ShaderCache();
} else { } else {
@@ -61,6 +51,14 @@ RenderManager::RenderManager(QObject *parent) :
decoder_cache_ = nullptr; decoder_cache_ = nullptr;
} }
if (context_) {
video_thread_ = new RenderThread(context_, decoder_cache_, shader_cache_, this);
audio_thread_ = new RenderThread(nullptr, decoder_cache_, shader_cache_, this);
video_thread_->start(QThread::IdlePriority);
audio_thread_->start(QThread::IdlePriority);
}
decoder_clear_timer_ = new QTimer(this); decoder_clear_timer_ = new QTimer(this);
decoder_clear_timer_->setInterval(kDecoderMaximumInactivity); decoder_clear_timer_->setInterval(kDecoderMaximumInactivity);
connect(decoder_clear_timer_, &QTimer::timeout, this, &RenderManager::ClearOldDecoders); connect(decoder_clear_timer_, &QTimer::timeout, this, &RenderManager::ClearOldDecoders);
@@ -73,9 +71,14 @@ RenderManager::~RenderManager()
delete shader_cache_; delete shader_cache_;
delete decoder_cache_; delete decoder_cache_;
context_->Destroy(); video_thread_->quit();
video_thread_->wait();
context_->PostDestroy(); context_->PostDestroy();
delete context_; delete context_;
audio_thread_->quit();
audio_thread_->wait();
} }
} }
@@ -128,7 +131,7 @@ RenderTicketPtr RenderManager::RenderFrame(Node *node, ColorManager* color_manag
ticket->setProperty("cacheuuid", QVariant::fromValue(cache->GetUuid())); ticket->setProperty("cacheuuid", QVariant::fromValue(cache->GetUuid()));
} }
AddTicket(ticket, priority); video_thread_->AddTicket(ticket);
return ticket; return ticket;
} }
@@ -145,22 +148,20 @@ RenderTicketPtr RenderManager::RenderAudio(Node *node, const TimeRange &r, const
ticket->setProperty("enablewaveforms", generate_waveforms); ticket->setProperty("enablewaveforms", generate_waveforms);
ticket->setProperty("aparam", QVariant::fromValue(params)); ticket->setProperty("aparam", QVariant::fromValue(params));
AddTicket(ticket, priority); audio_thread_->AddTicket(ticket);
return ticket; return ticket;
} }
void RenderManager::RunTicket(RenderTicketPtr ticket) const bool RenderManager::RemoveTicket(RenderTicketPtr ticket)
{ {
// Setup the ticket for ::Process if (video_thread_->RemoveTicket(ticket)) {
ticket->Start(); return true;
} else if (audio_thread_->RemoveTicket(ticket)) {
if (ticket->IsCancelled()) { return true;
ticket->Finish(); } else {
return; return false;
} }
RenderProcessor::Process(ticket, context_, decoder_cache_, shader_cache_);
} }
void RenderManager::SetAggressiveGarbageCollection(bool enabled) void RenderManager::SetAggressiveGarbageCollection(bool enabled)
@@ -192,4 +193,86 @@ void RenderManager::ClearOldDecoders()
} }
} }
RenderThread::RenderThread(Renderer *renderer, DecoderCache *decoder_cache, ShaderCache *shader_cache, QObject *parent) :
QThread(parent),
cancelled_(false),
context_(renderer),
decoder_cache_(decoder_cache),
shader_cache_(shader_cache)
{
if (context_) {
context_->Init();
context_->moveToThread(this);
}
}
void RenderThread::AddTicket(RenderTicketPtr ticket)
{
QMutexLocker locker(&mutex_);
queue_.push_back(ticket);
wait_.wakeOne();
}
bool RenderThread::RemoveTicket(RenderTicketPtr ticket)
{
QMutexLocker locker(&mutex_);
auto it = std::find(queue_.begin(), queue_.end(), ticket);
if (it == queue_.end()) {
return false;
}
queue_.erase(it);
return true;
}
void RenderThread::quit()
{
QMutexLocker locker(&mutex_);
cancelled_ = true;
wait_.wakeOne();
}
void RenderThread::run()
{
if (context_) {
context_->PostInit();
}
QMutexLocker locker(&mutex_);
while (!cancelled_) {
if (queue_.empty()) {
wait_.wait(&mutex_);
}
if (cancelled_) {
break;
}
if (!queue_.empty()) {
RenderTicketPtr ticket = queue_.front();
queue_.pop_front();
locker.unlock();
// Setup the ticket for ::Process
ticket->Start();
if (ticket->IsCancelled()) {
ticket->Finish();
} else {
RenderProcessor::Process(ticket, context_, decoder_cache_, shader_cache_);
}
locker.relock();
}
}
if (context_) {
context_->Destroy();
context_->moveToThread(this->thread());
}
}
} }
+37 -2
View File
@@ -35,7 +35,39 @@
namespace olive { namespace olive {
class RenderManager : public ThreadPool class RenderThread : public QThread
{
Q_OBJECT
public:
RenderThread(Renderer *renderer, DecoderCache *decoder_cache, ShaderCache *shader_cache, QObject *parent = nullptr);
void AddTicket(RenderTicketPtr ticket);
bool RemoveTicket(RenderTicketPtr ticket);
void quit();
protected:
virtual void run() override;
private:
QMutex mutex_;
QWaitCondition wait_;
std::list<RenderTicketPtr> queue_;
bool cancelled_;
Renderer *context_;
DecoderCache *decoder_cache_;
ShaderCache *shader_cache_;
};
class RenderManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -96,7 +128,7 @@ public:
*/ */
RenderTicketPtr RenderAudio(Node *viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal); RenderTicketPtr RenderAudio(Node *viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal);
virtual void RunTicket(RenderTicketPtr ticket) const override; bool RemoveTicket(RenderTicketPtr ticket);
enum TicketType { enum TicketType {
kTypeVideo, kTypeVideo,
@@ -135,6 +167,9 @@ private:
QTimer *decoder_clear_timer_; QTimer *decoder_clear_timer_;
RenderThread *video_thread_;
RenderThread *audio_thread_;
private slots: private slots:
void ClearOldDecoders(); void ClearOldDecoders();