separated setting time and processing node functions

This commit is contained in:
itsmattkc
2019-08-27 23:38:24 +10:00
parent 35db54075d
commit b9ce02a0ec
29 changed files with 146 additions and 109 deletions
-2
View File
@@ -93,8 +93,6 @@ bool Decoder::ProbeMedia(Footage *f)
if (decoder->Probe(f)) {
// We found a Decoder, so we can set this media as valid
f->set_status(Footage::kReady);
+2 -4
View File
@@ -22,10 +22,8 @@ QString AlphaOverBlend::Description()
return tr("A blending node that composites one texture over another using its alpha channel.");
}
void AlphaOverBlend::Process(const rational &time)
void AlphaOverBlend::Process()
{
Q_UNUSED(time)
// FIXME: Write Alpha Over Formula
// Note that alpha will always be premultiplied by this point
@@ -35,5 +33,5 @@ void AlphaOverBlend::Process(const rational &time)
//GLuint base_tex = base_input_->get_value(time).value<GLuint>();
// FIXME: Does nothing
texture_output()->set_value(QVariant::fromValue(blend_input()->get_value(time).value<RenderTexturePtr>()));
texture_output()->set_value(QVariant::fromValue(blend_input()->get_value().value<RenderTexturePtr>()));
}
+1 -1
View File
@@ -13,7 +13,7 @@ public:
virtual QString Description() override;
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
};
#endif // ALPHAOVER_H
+2 -4
View File
@@ -70,7 +70,7 @@ void Block::set_length(const rational &length)
Block *Block::previous()
{
return ValueToPtr<Block>(previous_input_->get_value(0));
return ValueToPtr<Block>(previous_input_->get_value());
}
Block *Block::next()
@@ -83,10 +83,8 @@ NodeInput *Block::previous_input()
return previous_input_;
}
void Block::Process(const rational &time)
void Block::Process()
{
Q_UNUSED(time)
// Simply set both output values as a pointer to this object
block_output_->set_value(PtrToValue(this));
}
+1 -1
View File
@@ -102,7 +102,7 @@ signals:
void Refreshed();
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
NodeInput* previous_input_;
+23 -7
View File
@@ -20,6 +20,8 @@
#include "clip.h"
#include "node/processor/renderer/renderer.h"
ClipBlock::ClipBlock()
{
texture_input_ = new NodeInput("tex_in");
@@ -65,17 +67,31 @@ NodeInput *ClipBlock::texture_input()
return texture_input_;
}
void ClipBlock::Process(const rational &time)
void ClipBlock::set_time(const rational &time)
{
// Run default node processing
Block::Process(time);
Node::set_time(time);
// If the time retrieved is within this block, get texture information
if (time >= in() && time < out()) {
if (texture_input_->IsConnected()) {
// We convert the time given (timeline time) to media time
rational media_time = time - in() + media_in();
// Retrieve texture
texture_output()->set_value(texture_input_->get_value(media_time));
texture_input_->edges().first()->output()->parent()->set_time(media_time);
}
}
void ClipBlock::Process()
{
// Run default node processing
Block::Process();
// Check if we have a renderer instance
if (RendererProcessor::CurrentInstance() != nullptr) {
// If the time retrieved is within this block, get texture information
if (time() >= in() && time() < out()) {
// Retrieve texture
texture_output()->set_value(texture_input_->get_value());
} else {
texture_output()->set_value(0);
}
}
}
+3 -1
View File
@@ -42,8 +42,10 @@ public:
NodeInput* texture_input();
virtual void set_time(const rational& time) override;
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
NodeInput* texture_input_;
+1 -3
View File
@@ -57,11 +57,9 @@ NodeOutput *SolidGenerator::texture_output()
return texture_output_;
}
void SolidGenerator::Process(const rational &time)
void SolidGenerator::Process()
{
// FIXME: Test code
Q_UNUSED(time)
if (texture_ == nullptr) {
QImage img(1920, 1080, QImage::Format_RGBA8888_Premultiplied);
img.fill(Qt::red);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
NodeOutput* texture_output();
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
NodeInput* color_input_;
+10 -27
View File
@@ -61,39 +61,22 @@ void NodeInput::set_can_accept_multiple_inputs(bool b)
can_accept_multiple_inputs_ = b;
}
QVariant NodeInput::get_value(const rational &time)
QVariant NodeInput::get_value()
{
/// Determine if this input has any connections to it
switch (edges_.size()) {
/// No connections - use the internal value
case 0:
// FIXME: Re-implement keyframing
return keyframes_.first().value();
/// One connection - use the output of the connected Node
case 1:
return edges_.first()->output()->get_value(time);
/// Multiple connections - rare, return a list of the outputs of the connected Nodes
default:
{
QList<QVariant> values;
for (int i=0;i<edges_.size();i++) {
values.append(edges_.at(i)->output()->get_value(time));
}
return values;
}
if (!edges_.isEmpty()) {
// One connection - use the output of the connected Node
return edges_.first()->output()->get_value();
}
// No connections - use the internal value
// FIXME: Re-implement keyframing
return keyframes_.first().value();
}
void NodeInput::set_value(const rational &time, const QVariant &value)
void NodeInput::set_value(const QVariant &value)
{
if (keyframing()) {
// FIXME: Keyframing code
Q_UNUSED(time)
// FIXME: Keyframing code using time()
} else {
keyframes_.first().set_value(value);
+2 -2
View File
@@ -80,14 +80,14 @@ public:
* If no output is connected, this will return a user-defined value, either a static value if this input is not
* keyframed, or an interpolated value between the keyframes at this time.
*/
QVariant get_value(const rational &time);
QVariant get_value();
/**
* @brief Set the value at a given time
*
* This function will only work if there are no outputs connected.
*/
void set_value(const rational& time, const QVariant& value);
void set_value(const QVariant& value);
/**
* @brief Return whether keyframing is enabled on this input or not
+4 -5
View File
@@ -84,11 +84,10 @@ NodeOutput *MediaInput::texture_output()
void MediaInput::SetFootage(Footage *f)
{
// FIXME: Need some protection for Time == 0
footage_input_->set_value(0, PtrToValue(f));
footage_input_->set_value(PtrToValue(f));
}
void MediaInput::Process(const rational &time)
void MediaInput::Process()
{
// Set default texture to no texture
texture_output_->set_value(0);
@@ -102,7 +101,7 @@ void MediaInput::Process(const rational &time)
}
// Get currently selected Footage
Footage* footage = ValueToPtr<Footage>(footage_input_->get_value(time));
Footage* footage = ValueToPtr<Footage>(footage_input_->get_value());
// If no footage is selected, return nothing
if (footage == nullptr) {
@@ -123,7 +122,7 @@ void MediaInput::Process(const rational &time)
}
// Get frame from Decoder
FramePtr frame = decoder_->Retrieve(time);
FramePtr frame = decoder_->Retrieve(time());
if (frame == nullptr) {
return;
+1 -4
View File
@@ -34,9 +34,6 @@
/**
* @brief A node that imports an image
*
* FIXME: This will likely be replaced by the Media node as the Media node will be set up to pull from various decoders
* from the beginning.
*/
class MediaInput : public Node
{
@@ -56,7 +53,7 @@ public:
void SetFootage(Footage* f);
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
NodeInput* footage_input_;
+22 -6
View File
@@ -25,7 +25,7 @@
#include "common/qobjectlistcast.h"
Node::Node() :
last_time_(-1)
last_process_time_(-1)
{
}
@@ -90,18 +90,17 @@ void Node::IgnoreCacheInvalidationFrom(NodeInput *input)
ignore_invalid_cache_inputs_.append(input);
}
void Node::Run(const rational &time)
void Node::Run()
{
lock_.lock();
if (last_time_ != time) {
if (last_process_time_ != time_) {
// The results will be the same, so return here
Process(time);
Process();
last_time_ = time;
last_process_time_ = time_;
}
lock_.unlock();
}
@@ -213,6 +212,23 @@ QList<Node *> Node::GetImmediateDependenciesAt(const rational &time)
return GetImmediateDependencies();
}
const rational &Node::time()
{
return time_;
}
void Node::set_time(const rational &t)
{
time_ = t;
QList<Node*> deps = GetImmediateDependencies();
foreach (Node* d, deps) {
d->set_time(time_);
}
emit TimeChanged(time_);
}
bool Node::OutputsTo(Node *n)
{
QList<NodeParam*> params = parameters();
+12 -3
View File
@@ -134,6 +134,9 @@ public:
*/
virtual QList<Node*> GetImmediateDependenciesAt(const rational& time);
const rational& time();
virtual void set_time(const rational& t);
/**
* @brief Returns whether this Node outputs data to the Node `n` in any way
*/
@@ -196,12 +199,12 @@ protected:
* corresponding output if it's connected to one. If your node doesn't directly deal with time, the default behavior
* of the NodeParam objects will handle everything related to it automatically.
*/
virtual void Process(const rational& time) = 0;
virtual void Process() = 0;
public slots:
void Run(const rational& time);
void Run();
signals:
/**
@@ -222,6 +225,11 @@ signals:
*/
void EdgeRemoved(NodeEdgePtr edge);
/**
* @brief Signal emitted when the time is set through set_time()
*/
void TimeChanged(const rational& t);
private:
/**
* @brief Return whether a parameter with ID `id` has already been added to this Node
@@ -233,7 +241,8 @@ private:
*/
QList<NodeInput*> ignore_invalid_cache_inputs_;
rational last_time_;
rational last_process_time_;
rational time_;
QMutex lock_;
};
+2 -2
View File
@@ -47,10 +47,10 @@ void NodeOutput::set_data_type(const NodeParam::DataType &type)
}
}
const QVariant &NodeOutput::get_value(const rational& time)
const QVariant &NodeOutput::get_value()
{
// Node::Process() should put the correct value in this output
parent()->Run(time);
parent()->Run();
// The value should be have been set by this point
return value_;
+1 -1
View File
@@ -61,7 +61,7 @@ public:
* In many cases for efficiency, the Node can also ignore this request if it knows the output data will not change
* (i.e. if the time has not changed from the last Process()).
*/
virtual const QVariant& get_value(const rational &time);
virtual const QVariant& get_value();
/**
* @brief Set the current value of this output
+5 -6
View File
@@ -96,9 +96,8 @@ NodeInput *TimelineOutput::track_input()
return track_input_;
}
void TimelineOutput::Process(const rational &time)
void TimelineOutput::Process()
{
Q_UNUSED(time)
}
int TimelineOutput::GetTrackIndex(TrackOutput *track)
@@ -119,7 +118,7 @@ rational TimelineOutput::GetSequenceLength()
TrackOutput *TimelineOutput::attached_track()
{
return ValueToPtr<TrackOutput>(track_input_->get_value(0));
return ValueToPtr<TrackOutput>(track_input_->get_value());
}
void TimelineOutput::AttachTrack(TrackOutput *track)
@@ -202,7 +201,7 @@ void TimelineOutput::TrackConnectionRemoved(NodeEdgePtr edge)
return;
}
DetachTrack(ValueToPtr<TrackOutput>(edge->output()->get_value(0)));
DetachTrack(ValueToPtr<TrackOutput>(edge->output()->get_value()));
if (attached_timeline_ != nullptr) {
attached_timeline_->Clear();
@@ -230,7 +229,7 @@ void TimelineOutput::TrackEdgeAdded(NodeEdgePtr edge)
// If this edge pertains to the track's track input, all the tracks just added need attaching
if (edge->input() == track->track_input()) {
TrackOutput* added_track = ValueToPtr<TrackOutput>(edge->output()->get_value(0));
TrackOutput* added_track = ValueToPtr<TrackOutput>(edge->output()->get_value());
AttachTrack(added_track);
}
@@ -243,7 +242,7 @@ void TimelineOutput::TrackEdgeRemoved(NodeEdgePtr edge)
// If this edge pertains to the track's track input, all the tracks just added need attaching
if (edge->input() == track->track_input()) {
TrackOutput* added_track = ValueToPtr<TrackOutput>(edge->output()->get_value(0));
TrackOutput* added_track = ValueToPtr<TrackOutput>(edge->output()->get_value());
DetachTrack(added_track);
}
+1 -1
View File
@@ -46,7 +46,7 @@ public:
NodeInput* track_input();
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
int GetTrackIndex(TrackOutput* track);
+6 -6
View File
@@ -133,7 +133,7 @@ void TrackOutput::DestroyBlockWidgets()
TrackOutput *TrackOutput::next_track()
{
return ValueToPtr<TrackOutput>(track_input_->get_value(0));
return ValueToPtr<TrackOutput>(track_input_->get_value());
}
NodeInput *TrackOutput::track_input()
@@ -146,22 +146,22 @@ NodeOutput* TrackOutput::track_output()
return track_output_;
}
void TrackOutput::Process(const rational &time)
void TrackOutput::Process()
{
// Run default node processing
Block::Process(time);
Block::Process();
// Set track output correctly
track_output_->set_value(PtrToValue(this));
ValidateCurrentBlock(time);
ValidateCurrentBlock(time());
if (current_block_ == this) {
// No texture is valid
texture_output()->set_value(0);
} else {
// At this point, we must have found the correct block so we use its texture output to produce the image
texture_output()->set_value(current_block_->texture_output()->get_value(time));
texture_output()->set_value(current_block_->texture_output()->get_value());
}
}
@@ -181,7 +181,7 @@ void TrackOutput::InsertBlockAfter(Block *block, Block *before)
Block *TrackOutput::attached_block()
{
return ValueToPtr<Block>(previous_input()->get_value(0));
return ValueToPtr<Block>(previous_input()->get_value());
}
void TrackOutput::PrependBlock(Block *block)
+1 -1
View File
@@ -156,7 +156,7 @@ signals:
void BlockRemoved(Block* block);
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
/**
+19 -4
View File
@@ -64,11 +64,11 @@ NodeInput *ViewerOutput::texture_input()
return texture_input_;
}
void ViewerOutput::Process(const rational &time)
void ViewerOutput::Process()
{
if (attached_viewer_ != nullptr) {
// Get the texture from whatever Node is currently connected (usually a Renderer of some kind)
GLuint current_texture = texture_input_->get_value(time).value<GLuint>();
GLuint current_texture = texture_input_->get_value().value<GLuint>();
// Send the texture to the Viewer
attached_viewer_->SetTexture(current_texture);
@@ -79,14 +79,29 @@ void ViewerOutput::AttachViewer(ViewerPanel *viewer)
{
// Disconnect old viewer if there's one attached
if (attached_viewer_ != nullptr) {
disconnect(attached_viewer_, SIGNAL(TimeChanged(const rational&)), this, SLOT(Run(const rational&)));
disconnect(attached_viewer_, SIGNAL(TimeChanged(const rational&)), this, SLOT(ViewerTimeChanged(const rational&)));
}
// FIXME: Currently this attaches to ViewerPanels, but should it attached to Viewers instead?
attached_viewer_ = viewer;
if (attached_viewer_ != nullptr) {
connect(attached_viewer_, SIGNAL(TimeChanged(const rational&)), this, SLOT(Run(const rational&)));
connect(attached_viewer_, SIGNAL(TimeChanged(const rational&)), this, SLOT(ViewerTimeChanged(const rational&)));
SetTimebase(timebase_);
}
}
void ViewerOutput::InvalidateCache(const rational &start_range, const rational &end_range)
{
// Update any attached viewer
Process();
Node::InvalidateCache(start_range, end_range);
}
void ViewerOutput::ViewerTimeChanged(const rational &t)
{
set_time(t);
Run();
}
+7 -1
View File
@@ -46,8 +46,10 @@ public:
void AttachViewer(ViewerPanel* viewer);
virtual void InvalidateCache(const rational &start_range, const rational &end_range) override;
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
NodeInput* texture_input_;
@@ -55,6 +57,10 @@ private:
ViewerPanel* attached_viewer_;
rational timebase_;
private slots:
void ViewerTimeChanged(const rational& t);
};
#endif // VIEWER_H
+14 -3
View File
@@ -20,6 +20,7 @@
#include "renderer.h"
#include <QApplication>
#include <QCryptographicHash>
#include <QDateTime>
#include <QDebug>
@@ -72,10 +73,8 @@ void RendererProcessor::SetCacheName(const QString &s)
GenerateCacheIDInternal();
}
void RendererProcessor::Process(const rational &time)
void RendererProcessor::Process()
{
Q_UNUSED(time)
texture_output_->set_value(0);
if (!texture_input_->IsConnected()) {
@@ -252,6 +251,9 @@ void RendererProcessor::CacheNext()
Node* node_to_cache = texture_input_->edges().first()->output()->parent();
// Set graph time
node_to_cache->set_time(time_to_cache);
// Run this probe in another thread
RenderPath path = RendererProbe::ProbeNode(node_to_cache, threads_.size(), time_to_cache);
@@ -287,6 +289,10 @@ void RendererProcessor::CacheNext()
*/
}
// FIXME: Test code only
#include "node/output/viewer/viewer.h"
// End test code
void RendererProcessor::ThreadCallback()
{
cache_return_count_++;
@@ -295,6 +301,11 @@ void RendererProcessor::ThreadCallback()
// Threads are all done now, time to proceed
caching_ = false;
// FIXME: Test code only
// Signal update to viewer
static_cast<ViewerOutput*>(texture_output()->edges().first()->input()->parent())->InvalidateCache(0, 0);
// End test code
CacheNext();
}
}
+1 -1
View File
@@ -94,7 +94,7 @@ public:
NodeOutput* texture_output();
protected:
virtual void Process(const rational &time) override;
virtual void Process() override;
private:
/**
@@ -95,7 +95,7 @@ void RendererThread::run()
// Process the Node
for (int i=path_.size()-1;i>=0;i--) {
path_.at(i)->Run(time_);
path_.at(i)->Run();
}
emit FinishedPath();
+1 -1
View File
@@ -49,7 +49,7 @@ public:
void Detach();
const GLuint buffer() const;
const GLuint& buffer() const;
private:
QOpenGLContext* context_;
@@ -91,7 +91,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
footage_combobox->SetRoot(pp->project()->root());
// Use multiple values
footage_combobox->SetFootage(Node::ValueToPtr<Footage>(base_input->get_value(Now())));
footage_combobox->SetFootage(Node::ValueToPtr<Footage>(base_input->get_value()));
connect(footage_combobox, SIGNAL(FootageChanged(Footage*)), this, SLOT(WidgetCallback()));
// End test code
@@ -103,12 +103,6 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
}
rational NodeParamViewWidgetBridge::Now()
{
// FIXME: Actually implement this
return 0;
}
void NodeParamViewWidgetBridge::WidgetCallback()
{
foreach (NodeInput* input, inputs_) {
@@ -155,7 +149,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
{
// Widget is a FootageComboBox
FootageComboBox* footage_combobox = static_cast<FootageComboBox*>(sender());
input->set_value(Now(), Node::PtrToValue(footage_combobox->SelectedFootage()));
input->set_value(Node::PtrToValue(footage_combobox->SelectedFootage()));
break;
}
}
@@ -22,8 +22,6 @@ private:
void CreateWidgets();
rational Now();
private slots:
void WidgetCallback();
};