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:
+4
-9
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_;
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user