copy values whenever the cache is invalidated

Since we're now working with a separate proxy copy of the original node graph,
if the user changes a parameter in one of those nodes (triggering an
InvalidateCache signal), the values in our copied graph need to be updated
with these new values too.
This commit is contained in:
itsmattkc
2019-11-23 17:06:49 +09:00
parent 1bc8a20425
commit 44d649903c
7 changed files with 55 additions and 33 deletions
+4 -9
View File
@@ -83,13 +83,6 @@ void Node::InvalidateCache(const rational &start_range, const rational &end_rang
{ {
Q_UNUSED(from) Q_UNUSED(from)
foreach (NodeParam* param, params_) {
if (param->type() == NodeParam::kOutput) {
NodeOutput* output = static_cast<NodeOutput*>(param);
output->drop_cached_values_overlapping(TimeRange(start_range, end_range));
}
}
SendInvalidateCache(start_range, end_range); SendInvalidateCache(start_range, end_range);
} }
@@ -178,8 +171,10 @@ void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
const QList<NodeParam*>& dst_param = destination->params_; const QList<NodeParam*>& dst_param = destination->params_;
for (int i=0;i<src_param.size();i++) { for (int i=0;i<src_param.size();i++) {
if (src_param.at(i)->type() == NodeParam::kInput) { NodeParam* p = src_param.at(i);
NodeInput* src = static_cast<NodeInput*>(src_param.at(i));
if (p->type() == NodeParam::kInput) {
NodeInput* src = static_cast<NodeInput*>(p);
if (src->dependent()) { if (src->dependent()) {
NodeInput* dst = static_cast<NodeInput*>(dst_param.at(i)); NodeInput* dst = static_cast<NodeInput*>(dst_param.at(i));
@@ -34,6 +34,9 @@ void AudioRenderBackend::InvalidateCache(const rational &start_range, const rati
// Remove any overlaps so we don't render the same thing twice // Remove any overlaps so we don't render the same thing twice
ValidateRanges(); ValidateRanges();
// Queue value update
QueueValueUpdate(TimeRange(start_range, end_range));
// Start caching cycle if it hasn't started already // Start caching cycle if it hasn't started already
CacheNext(); CacheNext();
} }
+35 -6
View File
@@ -10,6 +10,7 @@ RenderBackend::RenderBackend(QObject *parent) :
started_(false), started_(false),
viewer_node_(nullptr), viewer_node_(nullptr),
copied_viewer_node_(nullptr), copied_viewer_node_(nullptr),
value_update_queued_(false),
recompile_queued_(false) recompile_queued_(false)
{ {
} }
@@ -109,12 +110,11 @@ bool RenderBackend::Compile()
} }
// Get dependencies of viewer node // Get dependencies of viewer node
QList<Node*> nodes; source_node_list_.append(viewer_node_);
nodes.append(viewer_node_); source_node_list_.append(viewer_node_->GetDependencies());
nodes.append(viewer_node_->GetDependencies());
// Copy all dependencies into graph // Copy all dependencies into graph
foreach (Node* n, nodes) { foreach (Node* n, source_node_list_) {
Node* copy = n->copy(); Node* copy = n->copy();
// Copy values (but not connections yet) // Copy values (but not connections yet)
@@ -127,7 +127,7 @@ bool RenderBackend::Compile()
copied_viewer_node_ = static_cast<ViewerOutput*>(copied_graph_.nodes().first()); copied_viewer_node_ = static_cast<ViewerOutput*>(copied_graph_.nodes().first());
// Copy connections // Copy connections
Node::DuplicateConnectionsBetweenLists(nodes, copied_graph_.nodes()); Node::DuplicateConnectionsBetweenLists(source_node_list_, copied_graph_.nodes());
compiled_ = CompileInternal(); compiled_ = CompileInternal();
@@ -147,8 +147,8 @@ void RenderBackend::Decompile()
DecompileInternal(); DecompileInternal();
copied_graph_.Clear(); copied_graph_.Clear();
copied_viewer_node_ = nullptr; copied_viewer_node_ = nullptr;
source_node_list_.clear();
compiled_ = false; compiled_ = false;
} }
@@ -203,6 +203,8 @@ void RenderBackend::CacheNext()
return; return;
} }
UpdateNodeInputs();
TimeRange cache_frame = cache_queue_.takeFirst(); TimeRange cache_frame = cache_queue_.takeFirst();
caching_ = GenerateData(cache_frame); caching_ = GenerateData(cache_frame);
@@ -250,6 +252,33 @@ const QString &RenderBackend::cache_id() const
return cache_id_; return cache_id_;
} }
void RenderBackend::QueueValueUpdate(const TimeRange &range)
{
value_update_queued_ = true;
value_update_range_ = range;
}
void RenderBackend::UpdateNodeInputs()
{
if (value_update_queued_) {
for (int i=0;i<source_node_list_.size();i++) {
Node* src = source_node_list_.at(i);
Node* dst = copied_graph_.nodes().at(i);
Node::CopyInputs(src, dst, false);
// Drop values in range
foreach (NodeParam* p, dst->parameters()) {
if (p->type() == NodeParam::kOutput) {
static_cast<NodeOutput*>(p)->drop_cached_values_overlapping(value_update_range_);
}
}
}
value_update_queued_ = false;
}
}
const QVector<QThread *> &RenderBackend::threads() const QVector<QThread *> &RenderBackend::threads()
{ {
return threads_; return threads_;
+8
View File
@@ -85,6 +85,10 @@ protected:
const QString& cache_id() const; const QString& cache_id() const;
void QueueValueUpdate(const TimeRange& range);
void UpdateNodeInputs();
QList<TimeRange> cache_queue_; QList<TimeRange> cache_queue_;
QVector<RenderWorker*> processors_; QVector<RenderWorker*> processors_;
@@ -125,8 +129,12 @@ private:
qint64 cache_time_; qint64 cache_time_;
QString cache_id_; QString cache_id_;
QList<Node*> source_node_list_;
NodeGraph copied_graph_; NodeGraph copied_graph_;
bool value_update_queued_;
TimeRange value_update_range_;
bool recompile_queued_; bool recompile_queued_;
private slots: private slots:
-15
View File
@@ -40,24 +40,9 @@ void RenderWorker::Close()
void RenderWorker::Render(NodeDependency path) void RenderWorker::Render(NodeDependency path)
{ {
NodeOutput* output = path.node();
Node* node = output->parent();
QList<Node*> all_nodes_in_graph = ListNodeAndAllDependencies(node);
// Lock all Nodes to prevent UI changes during this render
foreach (Node* dep, all_nodes_in_graph) {
dep->LockUserInput();
}
RenderInternal(path); RenderInternal(path);
emit CompletedCache(path); emit CompletedCache(path);
// Unlock all Nodes so changes can be made again
foreach (Node* dep, all_nodes_in_graph) {
dep->UnlockUserInput();
}
} }
DecoderCache *RenderWorker::decoder_cache() DecoderCache *RenderWorker::decoder_cache()
+5 -2
View File
@@ -46,10 +46,10 @@ void VideoRenderBackend::InvalidateCache(const rational &start_range, const rati
rational start_range_adj = qMax(rational(0), start_range); rational start_range_adj = qMax(rational(0), start_range);
rational end_range_adj = qMin(SequenceLength(), end_range); rational end_range_adj = qMin(SequenceLength(), end_range);
qDebug() << "Cache invalidated between" /*qDebug() << "Cache invalidated between"
<< start_range_adj.toDouble() << start_range_adj.toDouble()
<< "and" << "and"
<< end_range_adj.toDouble(); << end_range_adj.toDouble();*/
// Snap start_range to timebase // Snap start_range to timebase
double start_range_dbl = start_range_adj.toDouble(); double start_range_dbl = start_range_adj.toDouble();
@@ -98,6 +98,9 @@ void VideoRenderBackend::InvalidateCache(const rational &start_range, const rati
// Remove frames after this time code if it's changed // Remove frames after this time code if it's changed
frame_cache_.Truncate(SequenceLength()); frame_cache_.Truncate(SequenceLength());
// Queue value update
QueueValueUpdate(TimeRange(start_range, end_range));
CacheNext(); CacheNext();
} }
-1
View File
@@ -22,7 +22,6 @@
#include "node/graph.h" #include "node/graph.h"
#include <QDebug>
Block* CreateSplitBlock(Block* block, rational point, QObject* parent = nullptr) Block* CreateSplitBlock(Block* block, rational point, QObject* parent = nullptr)
{ {
Block* copy = static_cast<Block*>(block->copy()); Block* copy = static_cast<Block*>(block->copy());