From a0dec75f2b0b4805b169629bf4abde445ebbca79 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 27 May 2020 04:05:01 +1000 Subject: [PATCH] renderer: ensure offscreen surface is created in main thread Fixes render crash on some platforms. --- app/render/backend/opengl/openglbackend.cpp | 24 ++++++++------------- app/render/backend/renderbackend.h | 4 ++-- app/task/render/render.cpp | 21 ++++++++---------- app/task/render/render.h | 3 +++ 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/app/render/backend/opengl/openglbackend.cpp b/app/render/backend/opengl/openglbackend.cpp index bd9095589..a66fa8928 100644 --- a/app/render/backend/opengl/openglbackend.cpp +++ b/app/render/backend/opengl/openglbackend.cpp @@ -25,10 +25,17 @@ OLIVE_NAMESPACE_ENTER OpenGLBackend::OpenGLBackend(QObject* parent) : - RenderBackend(parent), - proxy_(nullptr) + RenderBackend(parent) { + proxy_ = new OpenGLProxy(); + QThread* proxy_thread = new QThread(); + proxy_thread->start(QThread::IdlePriority); + proxy_->moveToThread(proxy_thread); + + if (!proxy_->Init()) { + ClearProxy(); + } } OpenGLBackend::~OpenGLBackend() @@ -40,19 +47,6 @@ OpenGLBackend::~OpenGLBackend() RenderWorker *OpenGLBackend::CreateNewWorker() { - if (!proxy_) { - proxy_ = new OpenGLProxy(); - - QThread* proxy_thread = new QThread(); - proxy_thread->start(QThread::IdlePriority); - proxy_->moveToThread(proxy_thread); - - if (!proxy_->Init()) { - ClearProxy(); - return nullptr; - } - } - return new OpenGLWorker(this, proxy_); } diff --git a/app/render/backend/renderbackend.h b/app/render/backend/renderbackend.h index 7762947f6..e8b1d043d 100644 --- a/app/render/backend/renderbackend.h +++ b/app/render/backend/renderbackend.h @@ -41,6 +41,8 @@ public: virtual ~RenderBackend() override; + void Close(); + void SetViewerNode(ViewerOutput* viewer_node); void SetUpdateWithGraph(bool e); @@ -76,8 +78,6 @@ public slots: protected: virtual RenderWorker* CreateNewWorker() = 0; - void Close(); - private: void CopyNodeInputValue(NodeInput* input); Node *CopyNodeConnections(Node *src_node); diff --git a/app/task/render/render.cpp b/app/task/render/render.cpp index 144ade07d..2b6a50b0c 100644 --- a/app/task/render/render.cpp +++ b/app/task/render/render.cpp @@ -21,7 +21,6 @@ #include "render.h" #include "common/timecodefunctions.h" -#include "render/backend/opengl/openglbackend.h" OLIVE_NAMESPACE_ENTER @@ -62,16 +61,12 @@ void RenderTask::Render(const TimeRangeList& video_range, const QMatrix4x4& mat, bool use_disk_cache) { - OpenGLBackend backend; - - backend.moveToThread(qApp->thread()); - // FIXME: This makes a full copy of the node graph every time it starts, there must be a better // way. - backend.SetViewerNode(viewer_); - backend.SetVideoParams(video_params_); - backend.SetAudioParams(audio_params_); - backend.SetVideoDownloadMatrix(mat); + backend_.SetViewerNode(viewer_); + backend_.SetVideoParams(video_params_); + backend_.SetAudioParams(audio_params_); + backend_.SetVideoDownloadMatrix(mat); std::list audio_lookup_table; if (!audio_range.isEmpty()) { @@ -79,7 +74,7 @@ void RenderTask::Render(const TimeRangeList& video_range, QList ranges = RenderBackend::SplitRangeIntoChunks(r); foreach (const TimeRange& split, ranges) { - audio_lookup_table.push_back({split, backend.RenderAudio(split)}); + audio_lookup_table.push_back({split, backend_.RenderAudio(split)}); } } } @@ -92,7 +87,7 @@ void RenderTask::Render(const TimeRangeList& video_range, { QList times = viewer_->video_frame_cache()->GetFrameListFromTimeRange(video_range); - QFuture > hash_future = backend.Hash(times); + QFuture > hash_future = backend_.Hash(times); QList hashes = hash_future.result(); // Determine any duplicates @@ -139,7 +134,7 @@ void RenderTask::Render(const TimeRangeList& video_range, } foreach (const HashTimePair& p, sorted_times) { - render_lookup_table.push_back({p.hash, backend.RenderFrame(p.time)}); + render_lookup_table.push_back({p.hash, backend_.RenderFrame(p.time)}); } } } @@ -205,6 +200,8 @@ void RenderTask::Render(const TimeRangeList& video_range, } } } + + backend_.Close(); } void RenderTask::SetAnchorPoint(const rational &r) diff --git a/app/task/render/render.h b/app/task/render/render.h index f7cdcc3ed..4389791fa 100644 --- a/app/task/render/render.h +++ b/app/task/render/render.h @@ -24,6 +24,7 @@ #include #include "node/output/viewer/viewer.h" +#include "render/backend/opengl/openglbackend.h" #include "task/task.h" OLIVE_NAMESPACE_ENTER @@ -71,6 +72,8 @@ private: rational anchor_point_; + OpenGLBackend backend_; + }; OLIVE_NAMESPACE_EXIT