diff --git a/app/node/node.cpp b/app/node/node.cpp index 6aaea5a81..0223a9ff6 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -150,6 +150,19 @@ void Node::InvalidateCache(const rational &start_range, const rational &end_rang SendInvalidateCache(start_range, end_range); } +void Node::InvalidateVisible(NodeInput *from) +{ + Q_UNUSED(from) + + foreach (NodeParam* param, params_) { + if (param->type() == NodeParam::kOutput) { + foreach (NodeEdgePtr edge, param->edges()) { + edge->input()->parentNode()->InvalidateVisible(edge->input()); + } + } + } +} + TimeRange Node::InputTimeAdjustment(NodeInput *input, const TimeRange &input_time) const { // Default behavior is no time adjustment at all diff --git a/app/node/node.h b/app/node/node.h index 23de64812..f1d5be5d6 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -241,6 +241,11 @@ public: */ virtual void InvalidateCache(const rational& start_range, const rational& end_range, NodeInput* from = nullptr); + /** + * @brief Signal through node graph to only invalidate frames that are currently visible on a ViewerWidget + */ + virtual void InvalidateVisible(NodeInput *from); + virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const; /** diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 44ffbcfc0..7dfecdf55 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -111,6 +111,15 @@ void ViewerOutput::InvalidateCache(const rational &start_range, const rational & SendInvalidateCache(start_range, end_range); } +void ViewerOutput::InvalidateVisible(NodeInput* from) +{ + if (from == texture_input()) { + emit VisibleInvalidated(); + } + + Node::InvalidateVisible(from); +} + const VideoParams &ViewerOutput::video_params() const { return video_params_; diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index e158189f8..12be7a3fc 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -55,6 +55,7 @@ public: NodeInput* length_input(); virtual void InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from = nullptr) override; + virtual void InvalidateVisible(NodeInput *from) override; const VideoParams& video_params() const; const AudioParams& audio_params() const; @@ -87,6 +88,8 @@ signals: void AudioChangedBetween(const rational&, const rational&); + void VisibleInvalidated(); + void VideoGraphChanged(); void AudioGraphChanged(); diff --git a/app/widget/keyframeview/keyframeviewbase.cpp b/app/widget/keyframeview/keyframeviewbase.cpp index bcb8ad30b..5251ac70e 100644 --- a/app/widget/keyframeview/keyframeviewbase.cpp +++ b/app/widget/keyframeview/keyframeviewbase.cpp @@ -124,7 +124,9 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event) false); } else if (!selected_keys_.isEmpty()) { foreach (const KeyframeItemAndTime& keypair, selected_keys_) { - keypair.key->key()->parent()->blockSignals(true); + NodeInput* input_parent = keypair.key->key()->parent(); + + input_parent->blockSignals(true); keypair.key->key()->set_time(CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x())); @@ -134,9 +136,9 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event) // We emit a custom value changed signal while the keyframe is being dragged so only the currently viewed // frame gets rendered in this time - keypair.key->key()->parent()->blockSignals(false); + input_parent->blockSignals(false); - emit keypair.key->key()->parent()->ValueChanged(GetPlayheadTime(), GetPlayheadTime()); + input_parent->parentNode()->InvalidateVisible(input_parent); } } } @@ -281,13 +283,15 @@ void KeyframeViewBase::ProcessBezierDrag(QPointF mouse_diff_scaled, bool include new_opposing_pos = dragging_bezier_point_opposing_start_; } + NodeInput* input_parent = dragging_bezier_point_->key()->parent(); + if (undoable) { QUndoCommand* command = new QUndoCommand(); // Similar to the code in MouseRelease, we manipulated the signalling earlier and need to set the keys back to their // original position to allow the input to signal correctly when the undo command is pushed. - dragging_bezier_point_->key()->parent()->blockSignals(true); + input_parent->blockSignals(true); dragging_bezier_point_->key()->set_bezier_control(dragging_bezier_point_->mode(), dragging_bezier_point_start_); @@ -309,11 +313,11 @@ void KeyframeViewBase::ProcessBezierDrag(QPointF mouse_diff_scaled, bool include command); } - dragging_bezier_point_->key()->parent()->blockSignals(false); + input_parent->blockSignals(false); Core::instance()->undo_stack()->push(command); } else { - dragging_bezier_point_->key()->parent()->blockSignals(true); + input_parent->blockSignals(true); dragging_bezier_point_->key()->set_bezier_control(dragging_bezier_point_->mode(), new_bezier_pos); @@ -321,9 +325,9 @@ void KeyframeViewBase::ProcessBezierDrag(QPointF mouse_diff_scaled, bool include dragging_bezier_point_->key()->set_bezier_control(opposing_type, new_opposing_pos); - dragging_bezier_point_->key()->parent()->blockSignals(false); + input_parent->blockSignals(false); - emit dragging_bezier_point_->key()->parent()->ValueChanged(GetPlayheadTime(), GetPlayheadTime()); + input_parent->parentNode()->InvalidateVisible(input_parent); } } diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index 223dd05f4..e59f71f7f 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -320,7 +320,8 @@ void NodeParamViewWidgetBridge::ProcessSlider(SliderBase *slider, const QVariant } input_->blockSignals(false); - emit input_->ValueChanged(time_, time_); + + input_->parentNode()->InvalidateVisible(input_); } else { if (dragging_) { diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index fed5d6119..bb7296353 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -150,6 +150,7 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man disconnect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase); disconnect(viewer_node_, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot); disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot); + disconnect(viewer_node_, &ViewerOutput::VisibleInvalidated, this, &ViewerWidget::InvalidateVisible); // Effectively disables the viewer and clears the state SizeChangedSlot(0, 0); @@ -171,6 +172,7 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man connect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase); connect(viewer_node_, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot); connect(viewer_node_, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot); + connect(viewer_node_, &ViewerOutput::VisibleInvalidated, this, &ViewerWidget::InvalidateVisible); SizeChangedSlot(viewer_node_->video_params().width(), viewer_node_->video_params().height()); LengthChangedSlot(viewer_node_->Length()); @@ -555,3 +557,8 @@ void ViewerWidget::SetDividerFromMenu(QAction *action) UpdateRendererParameters(); } + +void ViewerWidget::InvalidateVisible() +{ + video_renderer_->InvalidateCache(GetTime(), GetTime()); +} diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index c7a17b3d2..1f030f23b 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -216,6 +216,8 @@ private slots: void SetDividerFromMenu(QAction* action); + void InvalidateVisible(); + }; #endif // VIEWER_WIDGET_H