From 0469fac4a9c973b98110124ba952071f368d020d Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 26 Jan 2020 14:16:22 +1100 Subject: [PATCH] node: send invalidatevisible signal through graph When dragging a value in the UI, we use a "single frame update" because we want to prioritize the currently visible frame to give visual feedback as soon as possible. Previously, we generated a single frame InvalidateCache() signal from the widgets themselves, but this had the major downside of not necessarily emitting the time that the viewer was actually showing (due to either node time transformations or times differing between the effects panels and the viewer panels). Now, we send a different signal that viewers can handle themselves to update the time that they're currently showing. This means the fast updating will work no matter how many viewers are connected at whatever time each viewer is set to. --- app/node/node.cpp | 13 ++++++++++++ app/node/node.h | 5 +++++ app/node/output/viewer/viewer.cpp | 9 +++++++++ app/node/output/viewer/viewer.h | 3 +++ app/widget/keyframeview/keyframeviewbase.cpp | 20 +++++++++++-------- .../nodeparamviewwidgetbridge.cpp | 3 ++- app/widget/viewer/viewer.cpp | 7 +++++++ app/widget/viewer/viewer.h | 2 ++ 8 files changed, 53 insertions(+), 9 deletions(-) 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