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.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<QThread *> &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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(){}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user