copy node graph before rendering

Previous iterations would use mutexes to prevent changing of the graph
mid-render, however several user actions would need to capture these mutexes
causing the main thread to hang until the current render job (frame/range of
samples) was complete. We now copy the nodes necessary as part of the "compile"
process so that the main thread shouldn't need nearly as much blocking while
caching occurs.
This commit is contained in:
itsmattkc
2019-11-23 08:53:52 +09:00
parent b233aa5319
commit 2cfccbfbef
7 changed files with 87 additions and 23 deletions
+55 -4
View File
@@ -8,7 +8,9 @@ RenderBackend::RenderBackend(QObject *parent) :
compiled_(false),
caching_(false),
started_(false),
viewer_node_(nullptr)
viewer_node_(nullptr),
copied_viewer_node_(nullptr),
recompile_queued_(false)
{
}
@@ -99,10 +101,34 @@ bool RenderBackend::IsInitiated()
bool RenderBackend::Compile()
{
if (compiled_) {
if (recompile_queued_) {
Decompile();
recompile_queued_ = false;
} else if (compiled_) {
return true;
}
// Get dependencies of viewer node
QList<Node*> nodes;
nodes.append(viewer_node_);
nodes.append(viewer_node_->GetDependencies());
// Copy all dependencies into graph
foreach (Node* n, nodes) {
Node* copy = n->copy();
// Copy values (but not connections yet)
Node::CopyInputs(n, copy, false);
copied_graph_.AddNode(copy);
}
// We know that the first node will be the viewer node since we appended that first in the copy
copied_viewer_node_ = static_cast<ViewerOutput*>(copied_graph_.nodes().first());
// Copy connections
Node::DuplicateConnectionsBetweenLists(nodes, copied_graph_.nodes());
compiled_ = CompileInternal();
if (!compiled_) {
@@ -119,6 +145,12 @@ void RenderBackend::Decompile()
}
DecompileInternal();
copied_graph_.Clear();
copied_viewer_node_ = nullptr;
compiled_ = false;
}
void RenderBackend::RegenerateCacheID()
@@ -141,6 +173,15 @@ void RenderBackend::RegenerateCacheID()
CacheIDChangedEvent(cache_id_);
}
rational RenderBackend::SequenceLength()
{
if (viewer_node_ == nullptr) {
return 0;
}
return viewer_node_->Length();
}
void RenderBackend::SetError(const QString &error)
{
error_ = error;
@@ -158,7 +199,7 @@ void RenderBackend::DisconnectViewer(ViewerOutput *node)
void RenderBackend::CacheNext()
{
if (!Init() || cache_queue_.isEmpty() || viewer_node() == nullptr || caching_) {
if (!Init() || cache_queue_.isEmpty() || !ViewerIsConnected() || caching_) {
return;
}
@@ -191,7 +232,12 @@ bool RenderBackend::GenerateData(const TimeRange &range)
ViewerOutput *RenderBackend::viewer_node() const
{
return viewer_node_;
return copied_viewer_node_;
}
bool RenderBackend::ViewerIsConnected() const
{
return viewer_node_ != nullptr;
}
DecoderCache *RenderBackend::decoder_cache()
@@ -245,3 +291,8 @@ void RenderBackend::ThreadRequestedSibling(NodeDependency dep)
}
}
}
void RenderBackend::QueueRecompile()
{
recompile_queued_ = true;
}