renderer: added generate job
For nodes that produce an image on the CPU before sending it to the GPU.
This commit is contained in:
@@ -557,6 +557,7 @@ void Core::DeclareTypesForQt()
|
||||
qRegisterMetaType<OLIVE_NAMESPACE::AudioVisualWaveform>();
|
||||
qRegisterMetaType<OLIVE_NAMESPACE::SampleJob>();
|
||||
qRegisterMetaType<OLIVE_NAMESPACE::ShaderJob>();
|
||||
qRegisterMetaType<OLIVE_NAMESPACE::GenerateJob>();
|
||||
}
|
||||
|
||||
void Core::StartGUI(bool full_screen)
|
||||
|
||||
@@ -468,6 +468,12 @@ void Node::ProcessSamples(NodeValueDatabase &, const SampleBufferPtr, SampleBuff
|
||||
{
|
||||
}
|
||||
|
||||
void Node::GenerateFrame(FramePtr frame, const GenerateJob &job) const
|
||||
{
|
||||
Q_UNUSED(frame)
|
||||
Q_UNUSED(job)
|
||||
}
|
||||
|
||||
NodeInput *Node::GetInputWithID(const QString &id) const
|
||||
{
|
||||
QList<NodeInput*> inputs = GetInputsIncludingArrays();
|
||||
|
||||
+11
-1
@@ -27,6 +27,7 @@
|
||||
#include <QPointF>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include "codec/frame.h"
|
||||
#include "codec/samplebuffer.h"
|
||||
#include "common/rational.h"
|
||||
#include "common/xmlutils.h"
|
||||
@@ -177,10 +178,19 @@ public:
|
||||
virtual ShaderCode GetShaderCode(const QString& shader_id) const;
|
||||
|
||||
/**
|
||||
* @brief If ProcessesSamples() is true, this is the function that will process them.
|
||||
* @brief If Value() pushes a ShaderJob, this is the function that will process them.
|
||||
*/
|
||||
virtual void ProcessSamples(NodeValueDatabase &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const;
|
||||
|
||||
/**
|
||||
* @brief If Value() pushes a GenerateJob, override this function for the image to create
|
||||
*
|
||||
* @param frame
|
||||
*
|
||||
* The destination buffer. It will already be allocated and ready for writing to.
|
||||
*/
|
||||
virtual void GenerateFrame(FramePtr frame, const GenerateJob &job) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the input with the specified ID (or nullptr if it doesn't exist)
|
||||
*/
|
||||
|
||||
@@ -214,6 +214,7 @@ QByteArray NodeParam::ValueToBytes(const NodeParam::DataType &type, const QVaria
|
||||
case kVector:
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kAny:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -196,6 +196,15 @@ public:
|
||||
*/
|
||||
kSampleJob = 0x20000,
|
||||
|
||||
/**
|
||||
* Job type
|
||||
*
|
||||
* An internal type used to indicate to the renderer that an accelerated sample job needs to
|
||||
* take place. This value will usually be taken from a table and a kSamples value will be
|
||||
* pushed to take its place.
|
||||
*/
|
||||
kGenerateJob = 0x40000,
|
||||
|
||||
/**
|
||||
****************************** BROAD IDENTIFIERS ******************************
|
||||
*/
|
||||
|
||||
+22
-1
@@ -140,6 +140,14 @@ QVariant NodeTraverser::ProcessSamples(const Node *node, const TimeRange &range,
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant NodeTraverser::ProcessFrameGeneration(const Node *node, const GenerateJob &job)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
Q_UNUSED(job)
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant NodeTraverser::GetCachedFrame(const Node *node, const rational &time)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
@@ -166,8 +174,9 @@ void NodeTraverser::PostProcessTable(const Node *node, const TimeRange &range, N
|
||||
QList<NodeValue> audio_footage_to_retrieve;
|
||||
QList<NodeValue> shader_jobs_to_run;
|
||||
QList<NodeValue> sample_jobs_to_run;
|
||||
QList<NodeValue> generate_jobs_to_run;
|
||||
|
||||
for (int i=output_params.Count()-1; i>=0; i--) {
|
||||
for (int i=0; i<output_params.Count(); i++) {
|
||||
const NodeValue& v = output_params.at(i);
|
||||
QList<NodeValue>* take_this_value_list = nullptr;
|
||||
|
||||
@@ -186,10 +195,13 @@ void NodeTraverser::PostProcessTable(const Node *node, const TimeRange &range, N
|
||||
take_this_value_list = &shader_jobs_to_run;
|
||||
} else if (v.type() == NodeParam::kSampleJob) {
|
||||
take_this_value_list = &sample_jobs_to_run;
|
||||
} else if (v.type() == NodeParam::kGenerateJob) {
|
||||
take_this_value_list = &generate_jobs_to_run;
|
||||
}
|
||||
|
||||
if (take_this_value_list) {
|
||||
take_this_value_list->append(output_params.TakeAt(i));
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +223,15 @@ void NodeTraverser::PostProcessTable(const Node *node, const TimeRange &range, N
|
||||
output_params.Push(NodeParam::kTexture, value, node);
|
||||
}
|
||||
}
|
||||
|
||||
// Run generate jobs
|
||||
foreach (const NodeValue& v, generate_jobs_to_run) {
|
||||
QVariant value = ProcessFrameGeneration(node, v.data().value<GenerateJob>());
|
||||
|
||||
if (!value.isNull()) {
|
||||
output_params.Push(NodeParam::kTexture, value, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve audio samples
|
||||
|
||||
@@ -52,6 +52,8 @@ protected:
|
||||
|
||||
virtual QVariant ProcessSamples(const Node *node, const TimeRange &range, const SampleJob &job);
|
||||
|
||||
virtual QVariant ProcessFrameGeneration(const Node *node, const GenerateJob& job);
|
||||
|
||||
virtual QVariant GetCachedFrame(const Node *node, const rational &time);
|
||||
|
||||
private:
|
||||
|
||||
@@ -364,6 +364,7 @@ QVariant OpenGLProxy::RunNodeAccelerated(const Node *node,
|
||||
case NodeInput::kVector:
|
||||
case NodeInput::kShaderJob:
|
||||
case NodeInput::kSampleJob:
|
||||
case NodeInput::kGenerateJob:
|
||||
case NodeInput::kFootage:
|
||||
case NodeInput::kBuffer:
|
||||
case NodeInput::kNone:
|
||||
|
||||
@@ -211,6 +211,29 @@ QVariant RenderWorker::ProcessSamples(const Node *node, const TimeRange &range,
|
||||
return QVariant::fromValue(output_buffer);
|
||||
}
|
||||
|
||||
QVariant RenderWorker::ProcessFrameGeneration(const Node* node, const GenerateJob &job)
|
||||
{
|
||||
FramePtr frame = Frame::Create();
|
||||
|
||||
PixelFormat::Format output_fmt;
|
||||
if (job.GetAlphaChannelRequired()) {
|
||||
output_fmt = PixelFormat::GetFormatWithAlphaChannel(video_params_.format());
|
||||
} else {
|
||||
output_fmt = PixelFormat::GetFormatWithoutAlphaChannel(video_params_.format());
|
||||
}
|
||||
|
||||
frame->set_video_params(VideoParams(video_params_.width(),
|
||||
video_params_.height(),
|
||||
video_params_.time_base(),
|
||||
output_fmt,
|
||||
video_params_.divider()));
|
||||
frame->allocate();
|
||||
|
||||
node->GenerateFrame(frame, job);
|
||||
|
||||
return CachedFrameToTexture(frame);
|
||||
}
|
||||
|
||||
QVariant RenderWorker::GetCachedFrame(const Node* node, const rational& time)
|
||||
{
|
||||
if (node->id() == QStringLiteral("org.olivevideoeditor.Olive.videoinput")) {
|
||||
|
||||
@@ -126,6 +126,8 @@ protected:
|
||||
|
||||
virtual QVariant ProcessSamples(const Node *node, const TimeRange &range, const SampleJob &job) override;
|
||||
|
||||
virtual QVariant ProcessFrameGeneration(const Node *node, const GenerateJob& job) override;
|
||||
|
||||
virtual QVariant GetCachedFrame(const Node *node, const rational &time) override;
|
||||
|
||||
virtual bool TextureHasAlpha(const QVariant& v) const = 0;
|
||||
|
||||
+24
-14
@@ -84,13 +84,34 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class ShaderJob : public AcceleratedJob {
|
||||
class GenerateJob : public AcceleratedJob {
|
||||
public:
|
||||
GenerateJob()
|
||||
{
|
||||
alpha_channel_required_ = false;
|
||||
}
|
||||
|
||||
bool GetAlphaChannelRequired() const
|
||||
{
|
||||
return alpha_channel_required_;
|
||||
}
|
||||
|
||||
void SetAlphaChannelRequired(bool e)
|
||||
{
|
||||
alpha_channel_required_ = e;
|
||||
}
|
||||
|
||||
private:
|
||||
bool alpha_channel_required_;
|
||||
|
||||
};
|
||||
|
||||
class ShaderJob : public GenerateJob {
|
||||
public:
|
||||
ShaderJob()
|
||||
{
|
||||
iterations_ = 1;
|
||||
iterative_input_ = nullptr;
|
||||
alpha_channel_required_ = false;
|
||||
}
|
||||
|
||||
const QString& GetShaderID() const
|
||||
@@ -119,16 +140,6 @@ public:
|
||||
return iterative_input_;
|
||||
}
|
||||
|
||||
bool GetAlphaChannelRequired() const
|
||||
{
|
||||
return alpha_channel_required_;
|
||||
}
|
||||
|
||||
void SetAlphaChannelRequired(bool e)
|
||||
{
|
||||
alpha_channel_required_ = e;
|
||||
}
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
|
||||
@@ -136,8 +147,6 @@ private:
|
||||
|
||||
NodeInput* iterative_input_;
|
||||
|
||||
bool alpha_channel_required_;
|
||||
|
||||
};
|
||||
|
||||
class ShaderCode {
|
||||
@@ -169,5 +178,6 @@ OLIVE_NAMESPACE_EXIT
|
||||
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::ShaderJob)
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::SampleJob)
|
||||
Q_DECLARE_METATYPE(OLIVE_NAMESPACE::GenerateJob)
|
||||
|
||||
#endif // SHADERINFO_H
|
||||
|
||||
@@ -90,6 +90,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
|
||||
case NodeParam::kVector:
|
||||
case NodeParam::kShaderJob:
|
||||
case NodeParam::kSampleJob:
|
||||
case NodeParam::kGenerateJob:
|
||||
break;
|
||||
case NodeParam::kInt:
|
||||
{
|
||||
@@ -266,6 +267,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
|
||||
case NodeParam::kBuffer:
|
||||
case NodeParam::kShaderJob:
|
||||
case NodeParam::kSampleJob:
|
||||
case NodeParam::kGenerateJob:
|
||||
break;
|
||||
case NodeParam::kInt:
|
||||
{
|
||||
@@ -398,6 +400,7 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
|
||||
case NodeParam::kBuffer:
|
||||
case NodeParam::kShaderJob:
|
||||
case NodeParam::kSampleJob:
|
||||
case NodeParam::kGenerateJob:
|
||||
case NodeParam::kVector:
|
||||
break;
|
||||
case NodeParam::kInt:
|
||||
@@ -453,7 +456,10 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
|
||||
}
|
||||
case NodeParam::kText:
|
||||
{
|
||||
static_cast<QLineEdit*>(widgets_.first())->setText(input_->get_value_at_time(node_time).toString());
|
||||
QLineEdit* e = static_cast<QLineEdit*>(widgets_.first());
|
||||
int pos = e->cursorPosition();
|
||||
e->setText(input_->get_value_at_time(node_time).toString());
|
||||
e->setCursorPosition(pos);
|
||||
break;
|
||||
}
|
||||
case NodeParam::kBoolean:
|
||||
|
||||
Reference in New Issue
Block a user