From c61adbf2a2cefe8ee44be1b4fc0f9772bb564632 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 7 May 2020 00:56:16 +1000 Subject: [PATCH] videorenderer: if an InvalidateVisible() signal comes through, cancel the queue Optimization that frees up the GPU as quickly as possible when the user starts making changes that may require quick feedback. --- app/render/backend/audiorenderbackend.cpp | 4 +- app/render/backend/audiorenderbackend.h | 2 +- app/render/backend/renderbackend.cpp | 46 ++++++++++++++--------- app/render/backend/renderbackend.h | 6 ++- app/render/backend/videorenderbackend.cpp | 24 ++++++++++-- app/render/backend/videorenderbackend.h | 2 +- app/widget/viewer/viewer.cpp | 2 +- 7 files changed, 59 insertions(+), 27 deletions(-) diff --git a/app/render/backend/audiorenderbackend.cpp b/app/render/backend/audiorenderbackend.cpp index 9e819c0c8..368d70195 100644 --- a/app/render/backend/audiorenderbackend.cpp +++ b/app/render/backend/audiorenderbackend.cpp @@ -124,7 +124,7 @@ TimeRange AudioRenderBackend::PopNextFrameFromQueue() return range; } -void AudioRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range) +void AudioRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) { if (!ic_from_conform_) { // Cancel any ranges waiting on a conform here since obviously the contents have changed @@ -153,7 +153,7 @@ void AudioRenderBackend::InvalidateCacheInternal(const rational &start_range, co } } - RenderBackend::InvalidateCacheInternal(start_range, end_range); + RenderBackend::InvalidateCacheInternal(start_range, end_range, only_visible); } void AudioRenderBackend::ListenForConformSignal(AudioStreamPtr s) diff --git a/app/render/backend/audiorenderbackend.h b/app/render/backend/audiorenderbackend.h index ef6e6a090..6c6dd04f2 100644 --- a/app/render/backend/audiorenderbackend.h +++ b/app/render/backend/audiorenderbackend.h @@ -67,7 +67,7 @@ protected: virtual TimeRange PopNextFrameFromQueue() override; - virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range) override; + virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) override; private: struct ConformWaitInfo { diff --git a/app/render/backend/renderbackend.cpp b/app/render/backend/renderbackend.cpp index 8a4acb21e..cf0e92d87 100644 --- a/app/render/backend/renderbackend.cpp +++ b/app/render/backend/renderbackend.cpp @@ -290,24 +290,14 @@ void RenderBackend::CancelQueue() cancel_dialog_->RunIfWorkersAreBusy(); } +void RenderBackend::InvalidateVisible(const TimeRange &range, NodeInput *from) +{ + InvalidateCacheVeryInternal(range, from, true); +} + void RenderBackend::InvalidateCache(const TimeRange &range, NodeInput *from) { - // Adjust range to min/max values - rational start_range_adj = qMax(rational(0), range.in()); - rational end_range_adj = qMin(GetSequenceLength(), range.out()); - - qDebug() << "Cache invalidated between" - << start_range_adj.toDouble() - << "and" - << end_range_adj.toDouble(); - - if (from) { - // Queue value update - qDebug() << " from" << from->parentNode()->id() << "::" << from->id(); - QueueValueUpdate(from); - } - - InvalidateCacheInternal(start_range_adj, end_range_adj); + InvalidateCacheVeryInternal(range, from, false); } bool RenderBackend::ViewerIsConnected() const @@ -349,6 +339,26 @@ void RenderBackend::SetWorkerBusyState(RenderWorker *worker, bool busy) processor_busy_state_.replace(processors_.indexOf(worker), busy); } +void RenderBackend::InvalidateCacheVeryInternal(const TimeRange &range, NodeInput *from, bool only_visible) +{ + // Adjust range to min/max values + rational start_range_adj = qMax(rational(0), range.in()); + rational end_range_adj = qMin(GetSequenceLength(), range.out()); + + qDebug() << "Cache invalidated between" + << start_range_adj.toDouble() + << "and" + << end_range_adj.toDouble(); + + if (from) { + // Queue value update + qDebug() << " from" << from->parentNode()->id() << "::" << from->id(); + QueueValueUpdate(from); + } + + InvalidateCacheInternal(start_range_adj, end_range_adj, only_visible); +} + void RenderBackend::CopyNodeInputValue(NodeInput *input) { // Find our copy of this parameter @@ -446,8 +456,10 @@ const QVector &RenderBackend::threads() return threads_; } -void RenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range) +void RenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) { + Q_UNUSED(only_visible) + // Add the range to the list cache_queue_.InsertTimeRange(TimeRange(start_range, end_range)); diff --git a/app/render/backend/renderbackend.h b/app/render/backend/renderbackend.h index 1431d00df..90ecd9d6a 100644 --- a/app/render/backend/renderbackend.h +++ b/app/render/backend/renderbackend.h @@ -51,6 +51,8 @@ public: void CancelQueue(); + void InvalidateVisible(const TimeRange &range, NodeInput *from); + public slots: void InvalidateCache(const TimeRange &range, NodeInput *from); @@ -77,7 +79,7 @@ protected: */ virtual bool GenerateCacheIDInternal(QCryptographicHash& hash) = 0; - virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range); + virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible); virtual void CacheIDChangedEvent(const QString& id); @@ -120,6 +122,8 @@ protected: NodeGraph copied_graph_; private: + void InvalidateCacheVeryInternal(const TimeRange &range, NodeInput *from, bool only_visible); + void CopyNodeInputValue(NodeInput* input); Node *CopyNodeConnections(Node *src_node); void CopyNodeMakeConnection(NodeInput *src_input, NodeInput *dst_input); diff --git a/app/render/backend/videorenderbackend.cpp b/app/render/backend/videorenderbackend.cpp index db61fc0da..25ae78ce9 100644 --- a/app/render/backend/videorenderbackend.cpp +++ b/app/render/backend/videorenderbackend.cpp @@ -152,7 +152,7 @@ void VideoRenderBackend::ConnectWorkerToThis(RenderWorker *processor) connect(video_processor, &VideoRenderWorker::GeneratedFrame, this, &VideoRenderBackend::ThreadGeneratedFrame, Qt::QueuedConnection); } -void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range) +void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) { TimeRange invalidated(start_range, end_range); @@ -160,7 +160,21 @@ void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, co emit RangeInvalidated(invalidated); - Requeue(); + if (only_visible) { + + // We're only caching this frame, and for maximum responsiveness, should cancel the rest of the + // queue + cache_queue_.clear(); + cache_queue_.InsertTimeRange(TimeRange(start_range, end_range)); + + CacheNext(); + + } else { + + // Rework the queue + Requeue(); + + } } VideoRenderFrameCache *VideoRenderBackend::frame_cache() @@ -201,9 +215,11 @@ QString VideoRenderBackend::GetCachedFrame(const rational &time) void VideoRenderBackend::UpdateLastRequestedTime(const rational &time) { - last_time_requested_ = time; + if (last_time_requested_ != time) { + last_time_requested_ = time; - Requeue(); + Requeue(); + } } NodeInput *VideoRenderBackend::GetDependentInput() diff --git a/app/render/backend/videorenderbackend.h b/app/render/backend/videorenderbackend.h index fe7bc6f1b..401770ea9 100644 --- a/app/render/backend/videorenderbackend.h +++ b/app/render/backend/videorenderbackend.h @@ -99,7 +99,7 @@ protected: virtual void ConnectWorkerToThis(RenderWorker* processor) override; - virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range) override; + virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range, bool only_visible) override; virtual void ParamsChangedEvent(){} diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 8fd2bab3a..80908f563 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -878,7 +878,7 @@ void ViewerWidget::SetZoomFromMenu(QAction *action) void ViewerWidget::InvalidateVisible(NodeInput* source) { - video_renderer_->InvalidateCache(TimeRange(GetTime(), GetTime()), source); + video_renderer_->InvalidateVisible(TimeRange(GetTime(), GetTime()), source); } OLIVE_NAMESPACE_EXIT