renderer: unqueue deleted node inputs

Fixes segfault when renderer tries to update from a since deleted node
input.
This commit is contained in:
itsmattkc
2020-09-05 19:49:34 +10:00
parent 58d33db34f
commit 43d0129004
3 changed files with 23 additions and 102 deletions
-92
View File
@@ -549,68 +549,6 @@ void TrackOutput::BlockConnected(NodeEdgePtr edge)
UpdateInOutFrom(new_index);
InputConnectionChanged(edge);
/*
// Determine what node was just connected
Node* connected_node = edge->output()->parentNode();
// If this node is a block, we can do something with it
if (connected_node->IsBlock()) {
Block* connected_block = static_cast<Block*>(connected_node);
// See where this input falls in our internal "block cache"
Block* next = nullptr;
for (int i=block_input_->IndexOfSubParameter(edge->input())+1; i<block_input_->GetSize(); i++) {
Node* that_node = block_input_->At(i)->get_connected_node();
// If we find a block, this is the block that will follow the one just connected
if (that_node && that_node->IsBlock()) {
next = static_cast<Block*>(that_node);
break;
}
}
int real_block_index;
// Either insert or append depending on if we found a "next" block
if (next) {
// Insert block before this next block
real_block_index = block_cache_.indexOf(next);
block_cache_.insert(real_block_index, connected_block);
// Update values with next
next->set_previous(connected_block);
connected_block->set_next(next);
} else {
// No "next", this block must come at the end
real_block_index = block_cache_.size();
block_cache_.append(connected_block);
// Update next value
connected_block->set_next(nullptr);
}
// For all blocks after the block we inserted (including it), update the "previous" and "next"
// fields as well as the in/out values
if (real_block_index == 0) {
connected_block->set_previous(nullptr);
} else {
Block* prev = block_cache_.at(real_block_index - 1);
connected_block->set_previous(prev);
prev->set_next(connected_block);
}
UpdateInOutFrom(real_block_index);
// Make connections to this block
connect(connected_block, &Block::LengthChanged, this, &TrackOutput::BlockLengthChanged);
emit BlockAdded(connected_block);
}
InputConnectionChanged(edge);
*/
}
void TrackOutput::BlockDisconnected(NodeEdgePtr edge)
@@ -647,36 +585,6 @@ void TrackOutput::BlockDisconnected(NodeEdgePtr edge)
emit BlockRemoved(b);
}
/*
// See what kind of node was just connected
Node* connected_node = edge->output()->parentNode();
// If this was a block, we would have put it in our block cache in BlockConnected()
int index_of_block = block_cache_.indexOf(static_cast<Block*>(connected_node));
if (index_of_block > -1) {
Block* connected_block = static_cast<Block*>(connected_node);
// Determine what index this block was in our cache and remove it
block_cache_.removeAt(index_of_block);
// If there were blocks following this one, update their ins/outs
UpdateInOutFrom(index_of_block);
// Join the previous and next blocks together
if (connected_block->previous()) {
connected_block->previous()->set_next(connected_block->next());
}
if (connected_block->next()) {
connected_block->next()->set_previous(connected_block->previous());
}
disconnect(connected_block, &Block::LengthChanged, this, &TrackOutput::BlockLengthChanged);
emit BlockRemoved(connected_block);
}
*/
InputConnectionChanged(edge);
}
+21 -10
View File
@@ -324,10 +324,13 @@ void RenderBackend::NodeGraphChanged(NodeInput *source)
return;
}
// Check if this dependency graph is already queued
if (source->parentNode()->OutputsTo(queued_input, true, true)) {
// In which case, no further copy is necessary
return;
// Check if this input supersedes an already queued input
if ((source->IsArray() && static_cast<NodeInputArray*>(source)->sub_params().contains(queued_input))
|| queued_input->parentNode()->OutputsTo(source, true, true)) {
// In which case, we don't need to queue it and can queue our own
graph_update_queue_.removeAt(i);
disconnect(queued_input, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
i--;
}
// Check if the source is a member of this array, in which case it'll be copied eventually anyway
@@ -336,16 +339,15 @@ void RenderBackend::NodeGraphChanged(NodeInput *source)
return;
}
// Check if this input supersedes an already queued input
if (queued_input->parentNode()->OutputsTo(source, true, true)
|| (source->IsArray() && static_cast<NodeInputArray*>(source)->sub_params().contains(queued_input))) {
// In which case, we don't need to queue it and can queue our own
graph_update_queue_.removeAt(i);
i--;
// Check if this dependency graph is already queued
if (source->parentNode()->OutputsTo(queued_input, true, true)) {
// In which case, no further copy is necessary
return;
}
}
graph_update_queue_.append(source);
connect(source, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
}
void RenderBackend::Close()
@@ -668,6 +670,13 @@ void RenderBackend::AutoCacheVideoDownloaded()
delete watcher;
}
void RenderBackend::QueuedInputRemoved()
{
NodeInput* i = static_cast<NodeInput*>(sender());
disconnect(i, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
graph_update_queue_.removeOne(i);
}
//#define PRINT_UPDATE_QUEUE_INFO
void RenderBackend::ProcessUpdateQueue()
{
@@ -681,6 +690,8 @@ void RenderBackend::ProcessUpdateQueue()
#ifdef PRINT_UPDATE_QUEUE_INFO
qDebug() << " " << i->parentNode()->id() << i->id();
#endif
disconnect(i, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
CopyNodeInputValue(i);
}
+2
View File
@@ -246,6 +246,8 @@ private slots:
void AutoCacheVideoDownloaded();
void QueuedInputRemoved();
};
OLIVE_NAMESPACE_EXIT