renderer: attach renderer to single thread
This commit is contained in:
+106
-23
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user