Merge branch 'master' into pr/1875
This commit is contained in:
@@ -95,11 +95,7 @@ void PanNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeV
|
||||
}
|
||||
}
|
||||
|
||||
if (push_job) {
|
||||
table->Push(NodeValue::kSampleJob, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
table->Push(NodeValue::kSamples, QVariant::fromValue(job.samples()), this);
|
||||
}
|
||||
table->Push(NodeValue::kSamples, push_job ? QVariant::fromValue(job) : QVariant::fromValue(job.samples()), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ ClipBlock::ClipBlock() :
|
||||
AddInput(kMaintainAudioPitchInput, NodeValue::kBoolean, false, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
|
||||
|
||||
PrependInput(kBufferIn, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable));
|
||||
SetValueHintForInput(kBufferIn, ValueHint(NodeValue::kBuffer));
|
||||
//SetValueHintForInput(kBufferIn, ValueHint(NodeValue::kBuffer));
|
||||
|
||||
SetEffectInput(kBufferIn);
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ void TransitionBlock::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
|
||||
ShaderJobEvent(value, job);
|
||||
|
||||
job_type = NodeValue::kShaderJob;
|
||||
job_type = NodeValue::kTexture;
|
||||
push_job = QVariant::fromValue(job);
|
||||
} else if (data_type == NodeValue::kSamples) {
|
||||
// This must be an audio transition
|
||||
|
||||
@@ -101,7 +101,7 @@ void CornerPinDistortNode::Value(const NodeValueRow &value, const NodeGlobals &g
|
||||
&& job.GetValue(kTopRightInput).data().value<QVector2D>().isNull() &&
|
||||
job.GetValue(kBottomRightInput).data().value<QVector2D>().isNull() &&
|
||||
job.GetValue(kBottomLeftInput).data().value<QVector2D>().isNull())) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
table->Push(NodeValue::kTexture, job.GetValue(kTextureInput).data(), this);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ void CropDistortNode::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
|| !qIsNull(job.GetValue(kRightInput).data().toDouble())
|
||||
|| !qIsNull(job.GetValue(kTopInput).data().toDouble())
|
||||
|| !qIsNull(job.GetValue(kBottomInput).data().toDouble())) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
table->Push(NodeValue::kTexture, job.GetValue(kTextureInput).data(), this);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ void FlipDistortNode::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
if (!job.GetValue(kTextureInput).data().isNull()) {
|
||||
// Only run shader if at least one of flip or flop are selected
|
||||
if (job.GetValue(kHorizontalInput).data().toBool() || job.GetValue(kVerticalInput).data().toBool()) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
// If we're not flipping or flopping just push the texture
|
||||
table->Push(job.GetValue(kTextureInput));
|
||||
|
||||
@@ -107,7 +107,7 @@ void TransformDistortNode::Value(const NodeValueRow &value, const NodeGlobals &g
|
||||
// end up with gaps in the screen that will require an alpha channel.
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
|
||||
pushed_job = true;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void OpacityEffect::Value(const NodeValueRow &value, const NodeGlobals &globals,
|
||||
if (!job.GetValue(kTextureInput).data().isNull()) {
|
||||
if (!qFuzzyCompare(job.GetValue(kValueInput).data().toDouble(), 1.0)) {
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
// 1.0 float is a no-op, so just push the texture
|
||||
table->Push(job.GetValue(kTextureInput));
|
||||
|
||||
@@ -35,7 +35,7 @@ BlurFilterNode::BlurFilterNode()
|
||||
{
|
||||
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
|
||||
|
||||
AddInput(kMethodInput, NodeValue::kCombo, 0);
|
||||
AddInput(kMethodInput, NodeValue::kCombo, 1); // Default to gaussian
|
||||
|
||||
AddInput(kRadiusInput, NodeValue::kFloat, 10.0);
|
||||
SetInputProperty(kRadiusInput, QStringLiteral("min"), 0.0);
|
||||
@@ -118,7 +118,7 @@ void BlurFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
}
|
||||
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
|
||||
} else {
|
||||
// If we're not performing the blur job, just push the texture
|
||||
|
||||
@@ -66,7 +66,7 @@ void MosaicFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globa
|
||||
if (texture
|
||||
&& job.GetValue(kHorizInput).data().toInt() != texture->width()
|
||||
&& job.GetValue(kVertInput).data().toInt() != texture->height()) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
table->Push(job.GetValue(kTextureInput));
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ void StrokeFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globa
|
||||
if (!job.GetValue(kTextureInput).data().isNull()) {
|
||||
if (job.GetValue(kRadiusInput).data().toDouble() > 0.0
|
||||
&& job.GetValue(kOpacityInput).data().toDouble() > 0.0) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
} else {
|
||||
table->Push(job.GetValue(kTextureInput));
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void NoiseGeneratorNode::Value(const NodeValueRow &value, const NodeGlobals &glo
|
||||
job.InsertValue(QStringLiteral("time_in"), NodeValue(NodeValue::kFloat, globals.time().in().toDouble(), this));
|
||||
|
||||
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ void PolygonGenerator::Value(const NodeValueRow &value, const NodeGlobals &globa
|
||||
job.SetRequestedFormat(VideoParams::kFormatFloat32);
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
|
||||
table->Push(NodeValue::kGenerateJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
|
||||
void PolygonGenerator::GenerateFrame(FramePtr frame, const GenerateJob &job) const
|
||||
|
||||
@@ -63,9 +63,11 @@ void ShapeNode::Retranslate()
|
||||
|
||||
ShaderCode ShapeNode::GetShaderCode(const QString &shader_id) const
|
||||
{
|
||||
Q_UNUSED(shader_id)
|
||||
|
||||
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/shape.frag")));
|
||||
if (shader_id == QStringLiteral("shape")) {
|
||||
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/shape.frag")));
|
||||
} else {
|
||||
return super::GetShaderCode(shader_id);
|
||||
}
|
||||
}
|
||||
|
||||
void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
@@ -75,8 +77,22 @@ void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod
|
||||
job.InsertValue(value);
|
||||
job.InsertValue(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this));
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
job.SetShaderID(QStringLiteral("shape"));
|
||||
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
if (!value[kBaseInput].data().isNull()) {
|
||||
// Push as merge node
|
||||
ShaderJob merge;
|
||||
|
||||
merge.SetShaderID(QStringLiteral("mrg"));
|
||||
merge.InsertValue(MergeNode::kBaseIn, value[kBaseInput]);
|
||||
merge.InsertValue(MergeNode::kBlendIn, NodeValue(NodeValue::kTexture, QVariant::fromValue(job), this));
|
||||
merge.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(merge), this);
|
||||
} else {
|
||||
// Just push generate job
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,12 +30,14 @@ namespace olive {
|
||||
|
||||
#define super Node
|
||||
|
||||
QString ShapeNodeBase::kPositionInput = QStringLiteral("pos_in");
|
||||
QString ShapeNodeBase::kSizeInput = QStringLiteral("size_in");
|
||||
QString ShapeNodeBase::kColorInput = QStringLiteral("color_in");
|
||||
const QString ShapeNodeBase::kBaseInput = QStringLiteral("base_in");
|
||||
const QString ShapeNodeBase::kPositionInput = QStringLiteral("pos_in");
|
||||
const QString ShapeNodeBase::kSizeInput = QStringLiteral("size_in");
|
||||
const QString ShapeNodeBase::kColorInput = QStringLiteral("color_in");
|
||||
|
||||
ShapeNodeBase::ShapeNodeBase(bool create_color_input)
|
||||
{
|
||||
AddInput(kBaseInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
|
||||
AddInput(kPositionInput, NodeValue::kVec2, QVector2D(0, 0));
|
||||
AddInput(kSizeInput, NodeValue::kVec2, QVector2D(100, 100));
|
||||
SetInputProperty(kSizeInput, QStringLiteral("min"), QVector2D(0, 0));
|
||||
@@ -58,6 +60,9 @@ ShapeNodeBase::ShapeNodeBase(bool create_color_input)
|
||||
for (int i=0; i<kGizmoScaleCount; i++) {
|
||||
point_gizmo_[i] = AddDraggableGizmo<PointGizmo>(pos_n_sz, PointGizmo::kAbsolute);
|
||||
}
|
||||
|
||||
SetEffectInput(kBaseInput);
|
||||
SetFlags(kVideoEffect);
|
||||
}
|
||||
|
||||
void ShapeNodeBase::Retranslate()
|
||||
@@ -102,6 +107,15 @@ void ShapeNodeBase::UpdateGizmoPositions(const NodeValueRow &row, const NodeGlob
|
||||
poly_gizmo_->SetPolygon(QRectF(left_pt, top_pt, right_pt - left_pt, bottom_pt - top_pt));
|
||||
}
|
||||
|
||||
ShaderCode ShapeNodeBase::GetShaderCode(const QString &shader_id) const
|
||||
{
|
||||
if (shader_id == QStringLiteral("mrg")) {
|
||||
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/alphaover.frag"));
|
||||
}
|
||||
|
||||
return ShaderCode();
|
||||
}
|
||||
|
||||
void ShapeNodeBase::GizmoDragMove(double x, double y, const Qt::KeyboardModifiers &modifiers)
|
||||
{
|
||||
DraggableGizmo *gizmo = static_cast<DraggableGizmo*>(sender());
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "node/gizmo/point.h"
|
||||
#include "node/gizmo/polygon.h"
|
||||
#include "node/inputdragger.h"
|
||||
#include "node/math/merge/merge.h"
|
||||
#include "node/node.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -40,9 +41,12 @@ public:
|
||||
|
||||
virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override;
|
||||
|
||||
static QString kPositionInput;
|
||||
static QString kSizeInput;
|
||||
static QString kColorInput;
|
||||
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
|
||||
|
||||
static const QString kBaseInput;
|
||||
static const QString kPositionInput;
|
||||
static const QString kSizeInput;
|
||||
static const QString kColorInput;
|
||||
|
||||
protected:
|
||||
PolygonGizmo *poly_gizmo() const
|
||||
|
||||
@@ -70,7 +70,7 @@ void SolidGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals
|
||||
{
|
||||
ShaderJob job;
|
||||
job.InsertValue(value);
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
|
||||
ShaderCode SolidGenerator::GetShaderCode(const QString &shader_id) const
|
||||
|
||||
@@ -95,7 +95,7 @@ void TextGeneratorV1::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
|
||||
if (!job.GetValue(kTextInput).data().toString().isEmpty()) {
|
||||
table->Push(NodeValue::kGenerateJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ void TextGeneratorV2::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
job.SetRequestedFormat(VideoParams::kFormatFloat32);
|
||||
|
||||
if (!job.GetValue(kTextInput).data().toString().isEmpty()) {
|
||||
table->Push(NodeValue::kGenerateJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ void TextGeneratorV3::Retranslate()
|
||||
super::Retranslate();
|
||||
|
||||
SetInputName(kTextInput, tr("Text"));
|
||||
SetInputName(kBaseInput, tr("Base"));
|
||||
}
|
||||
|
||||
void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
@@ -89,7 +90,22 @@ void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
job.SetColorspace(project()->color_manager()->GetDefaultInputColorSpace());
|
||||
|
||||
if (!job.GetValue(kTextInput).data().toString().isEmpty()) {
|
||||
table->Push(NodeValue::kGenerateJob, QVariant::fromValue(job), this);
|
||||
if (!value[kBaseInput].data().isNull()) {
|
||||
// Push as merge node
|
||||
ShaderJob merge;
|
||||
|
||||
merge.SetShaderID(QStringLiteral("mrg"));
|
||||
merge.InsertValue(MergeNode::kBaseIn, value[kBaseInput]);
|
||||
merge.InsertValue(MergeNode::kBlendIn, NodeValue(NodeValue::kTexture, QVariant::fromValue(job), this));
|
||||
merge.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(merge), this);
|
||||
} else {
|
||||
// Just push generate job
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
} else if (!value[kBaseInput].data().isNull()) {
|
||||
table->Push(value[kBaseInput]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-24
@@ -58,7 +58,7 @@ QByteArray HashTraverser::GetHash(const Node *node, const Node::ValueHint &hint,
|
||||
return hash_.result();
|
||||
}
|
||||
|
||||
TexturePtr HashTraverser::ProcessVideoFootage(const FootageJob &stream, const rational &input_time)
|
||||
void HashTraverser::ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time)
|
||||
{
|
||||
Hash(FileFunctions::GetUniqueFileIdentifier(stream.filename()));
|
||||
Hash(stream.loop_mode());
|
||||
@@ -69,24 +69,20 @@ TexturePtr HashTraverser::ProcessVideoFootage(const FootageJob &stream, const ra
|
||||
Hash(stream.video_params().video_type() == VideoParams::kVideoTypeStill ? 0 : input_time);
|
||||
Hash(stream.video_params().video_type());
|
||||
|
||||
TexturePtr texture = super::ProcessVideoFootage(stream, input_time);
|
||||
texture_ids_.insert(texture.get(), hash_.result());
|
||||
return texture;
|
||||
texture_ids_.insert(destination.get(), hash_.result());
|
||||
}
|
||||
|
||||
SampleBufferPtr HashTraverser::ProcessAudioFootage(const FootageJob &stream, const TimeRange &input_time)
|
||||
void HashTraverser::ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time)
|
||||
{
|
||||
Hash(FileFunctions::GetUniqueFileIdentifier(stream.filename()));
|
||||
Hash(stream.loop_mode());
|
||||
Hash(stream.audio_params().stream_index());
|
||||
Hash(input_time);
|
||||
|
||||
SampleBufferPtr buf = super::ProcessAudioFootage(stream, input_time);
|
||||
texture_ids_.insert(buf.get(), hash_.result());
|
||||
return buf;
|
||||
texture_ids_.insert(destination.get(), hash_.result());
|
||||
}
|
||||
|
||||
TexturePtr HashTraverser::ProcessShader(const Node *node, const TimeRange &range, const ShaderJob &job)
|
||||
void HashTraverser::ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob &job)
|
||||
{
|
||||
HashGenerateJob(node, &job);
|
||||
|
||||
@@ -99,33 +95,25 @@ TexturePtr HashTraverser::ProcessShader(const Node *node, const TimeRange &range
|
||||
Hash(it.value());
|
||||
}
|
||||
|
||||
TexturePtr texture = super::ProcessShader(node, range, job);
|
||||
texture_ids_.insert(texture.get(), hash_.result());
|
||||
return texture;
|
||||
texture_ids_.insert(destination.get(), hash_.result());
|
||||
}
|
||||
|
||||
TexturePtr HashTraverser::ProcessColorTransform(const Node *node, const ColorTransformJob &job)
|
||||
void HashTraverser::ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob &job)
|
||||
{
|
||||
Hash(job.GetColorProcessor()->id());
|
||||
TexturePtr texture = super::ProcessColorTransform(node, job);
|
||||
texture_ids_.insert(texture.get(), hash_.result());
|
||||
return texture;
|
||||
texture_ids_.insert(destination.get(), hash_.result());
|
||||
}
|
||||
|
||||
SampleBufferPtr HashTraverser::ProcessSamples(const Node *node, const TimeRange &range, const SampleJob &job)
|
||||
void HashTraverser::ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job)
|
||||
{
|
||||
SampleBufferPtr buf = super::ProcessSamples(node, range, job);
|
||||
texture_ids_.insert(buf.get(), hash_.result());
|
||||
return buf;
|
||||
texture_ids_.insert(destination.get(), hash_.result());
|
||||
}
|
||||
|
||||
TexturePtr HashTraverser::ProcessFrameGeneration(const Node *node, const GenerateJob &job)
|
||||
void HashTraverser::ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob &job)
|
||||
{
|
||||
HashGenerateJob(node, &job);
|
||||
|
||||
TexturePtr texture = super::ProcessFrameGeneration(node, job);
|
||||
texture_ids_.insert(texture.get(), hash_.result());
|
||||
return texture;
|
||||
texture_ids_.insert(destination.get(), hash_.result());
|
||||
}
|
||||
|
||||
void HashTraverser::HashGenerateJob(const Node *node, const GenerateJob *job)
|
||||
|
||||
@@ -33,17 +33,17 @@ public:
|
||||
QByteArray GetHash(const Node *node, const Node::ValueHint &hint, const VideoParams ¶ms, const TimeRange &range);
|
||||
|
||||
protected:
|
||||
virtual TexturePtr ProcessVideoFootage(const FootageJob &stream, const rational &input_time) override;
|
||||
virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time) override;
|
||||
|
||||
virtual SampleBufferPtr ProcessAudioFootage(const FootageJob &stream, const TimeRange &input_time) override;
|
||||
virtual void ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time) override;
|
||||
|
||||
virtual TexturePtr ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job) override;
|
||||
virtual void ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob& job) override;
|
||||
|
||||
virtual TexturePtr ProcessColorTransform(const Node *node, const ColorTransformJob& job) override;
|
||||
virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob& job) override;
|
||||
|
||||
virtual SampleBufferPtr ProcessSamples(const Node *node, const TimeRange &range, const SampleJob &job) override;
|
||||
virtual void ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job) override;
|
||||
|
||||
virtual TexturePtr ProcessFrameGeneration(const Node *node, const GenerateJob& job) override;
|
||||
virtual void ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob& job) override;
|
||||
|
||||
private:
|
||||
void HashGenerateJob(const Node *node, const GenerateJob *job);
|
||||
|
||||
@@ -102,7 +102,7 @@ void ColorDifferenceKeyNode::Value(const NodeValueRow &value, const NodeGlobals
|
||||
|
||||
// If there's no texture, no need to run an operation
|
||||
if (!job.GetValue(kTextureInput).data().isNull()) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ void DespillNode::Value(const NodeValueRow &value, const NodeGlobals &globals, N
|
||||
|
||||
// If there's no texture, no need to run an operation
|
||||
if (!job.GetValue(kTextureInput).data().isNull()) {
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -382,7 +382,7 @@ void MathNodeBase::ValueInternal(Operation operation, Pairing pairing, const QSt
|
||||
output->Push(texture_val);
|
||||
} else {
|
||||
// Push shader job
|
||||
output->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
output->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -413,10 +413,10 @@ void MathNodeBase::ValueInternal(Operation operation, Pairing pairing, const QSt
|
||||
|
||||
output->Push(NodeValue::kSamples, QVariant::fromValue(job.samples()), this);
|
||||
} else {
|
||||
output->Push(NodeValue::kSampleJob, QVariant::fromValue(job), this);
|
||||
output->Push(NodeValue::kSamples, QVariant::fromValue(job), this);
|
||||
}
|
||||
} else {
|
||||
output->Push(NodeValue::kSampleJob, QVariant::fromValue(job), this);
|
||||
output->Push(NodeValue::kSamples, QVariant::fromValue(job), this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ void MergeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOff);
|
||||
}
|
||||
|
||||
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +341,8 @@ void Footage::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeV
|
||||
Track::Reference ref = GetReferenceFromRealIndex(i);
|
||||
FootageJob job(decoder_, filename(), ref.type(), GetLength(), loop_mode);
|
||||
|
||||
NodeValue::Type type;
|
||||
|
||||
if (ref.type() == Track::kVideo) {
|
||||
VideoParams vp = GetVideoParams(ref.index());
|
||||
|
||||
@@ -348,13 +350,17 @@ void Footage::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeV
|
||||
vp.set_colorspace(GetColorspaceToUse(vp));
|
||||
|
||||
job.set_video_params(vp);
|
||||
|
||||
type = NodeValue::kTexture;
|
||||
} else {
|
||||
AudioParams ap = GetAudioParams(ref.index());
|
||||
job.set_audio_params(ap);
|
||||
job.set_cache_path(project()->cache_path());
|
||||
|
||||
type = NodeValue::kSamples;
|
||||
}
|
||||
|
||||
table->Push(NodeValue::kFootageJob, QVariant::fromValue(job), this, false, ref.ToString());
|
||||
table->Push(type, QVariant::fromValue(job), this, false, ref.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+78
-147
@@ -52,6 +52,8 @@ NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node
|
||||
row.insert(it.key(), value);
|
||||
}
|
||||
|
||||
PreProcessRow(range, row);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -258,7 +260,6 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const Node::ValueHint
|
||||
|
||||
if (is_enabled) {
|
||||
NodeValueRow row = GenerateRow(&database, n, range);
|
||||
//qDebug() << "FIXME: Implement pre-process of row";
|
||||
|
||||
// Generate output table
|
||||
NodeValueTable table = database.Merge();
|
||||
@@ -266,9 +267,6 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const Node::ValueHint
|
||||
// By this point, the node should have all the inputs it needs to render correctly
|
||||
n->Value(row, GenerateGlobals(video_params_, range), &table);
|
||||
|
||||
// Post-process table
|
||||
PostProcessTable(n, hint, range, table);
|
||||
|
||||
return table;
|
||||
} else {
|
||||
return database.Merge();
|
||||
@@ -289,179 +287,112 @@ NodeValueTable NodeTraverser::GenerateBlockTable(const Track *track, const TimeR
|
||||
return table;
|
||||
}
|
||||
|
||||
TexturePtr NodeTraverser::ProcessVideoFootage(const FootageJob &stream, const rational &input_time)
|
||||
{
|
||||
Q_UNUSED(input_time)
|
||||
|
||||
// Create dummy texture with footage params
|
||||
return CreateDummyTexture(stream.video_params());
|
||||
}
|
||||
|
||||
SampleBufferPtr NodeTraverser::ProcessAudioFootage(const FootageJob& stream, const TimeRange &input_time)
|
||||
{
|
||||
Q_UNUSED(stream)
|
||||
Q_UNUSED(input_time)
|
||||
|
||||
return SampleBuffer::Create();
|
||||
}
|
||||
|
||||
TexturePtr NodeTraverser::ProcessShader(const Node *node, const TimeRange &range, const ShaderJob &job)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
Q_UNUSED(range)
|
||||
Q_UNUSED(job)
|
||||
|
||||
// Create dummy texture with sequence params
|
||||
VideoParams tex_params = video_params_;
|
||||
tex_params.set_channel_count(GetChannelCountFromJob(job));
|
||||
return CreateDummyTexture(tex_params);
|
||||
}
|
||||
|
||||
TexturePtr NodeTraverser::ProcessColorTransform(const Node *node, const ColorTransformJob &job)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
|
||||
return CreateDummyTexture(job.GetInputTexture()->params());
|
||||
}
|
||||
|
||||
SampleBufferPtr NodeTraverser::ProcessSamples(const Node *node, const TimeRange &range, const SampleJob &job)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
Q_UNUSED(range)
|
||||
Q_UNUSED(job)
|
||||
|
||||
return SampleBuffer::Create();
|
||||
}
|
||||
|
||||
TexturePtr NodeTraverser::ProcessFrameGeneration(const Node *node, const GenerateJob &job)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
Q_UNUSED(job)
|
||||
|
||||
// Create dummy texture with sequence params
|
||||
VideoParams tex_params = video_params_;
|
||||
tex_params.set_channel_count(GetChannelCountFromJob(job));
|
||||
return CreateDummyTexture(tex_params);
|
||||
}
|
||||
|
||||
void NodeTraverser::SaveCachedTexture(const QByteArray &hash, TexturePtr texture)
|
||||
{
|
||||
Q_UNUSED(hash)
|
||||
Q_UNUSED(texture)
|
||||
}
|
||||
|
||||
TexturePtr NodeTraverser::GetCachedTexture(const QByteArray& hash)
|
||||
{
|
||||
Q_UNUSED(hash)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QVector2D NodeTraverser::GenerateResolution() const
|
||||
{
|
||||
return QVector2D(video_params_.square_pixel_width(), video_params_.height());
|
||||
}
|
||||
|
||||
void NodeTraverser::PostProcessTable(const Node *node, const Node::ValueHint &hint, const TimeRange &range, NodeValueTable &output_params)
|
||||
void NodeTraverser::ResolveJobs(NodeValue &val, const TimeRange &range)
|
||||
{
|
||||
bool got_cached_frame = false;
|
||||
QByteArray cached_node_hash;
|
||||
if (val.type() == NodeValue::kTexture || val.type() == NodeValue::kSamples) {
|
||||
const QVariant &v = val.data();
|
||||
|
||||
// Convert footage to image/sample buffers
|
||||
/*if (CanCacheFrames() && node->GetCacheTextures()) {
|
||||
// This node is set to cache the result, see if we can retrieved a previously cached version
|
||||
cached_node_hash = RenderManager::Hash(node, hint, GetCacheVideoParams(), range.in());
|
||||
if (v.canConvert<ShaderJob>()) {
|
||||
|
||||
TexturePtr cached_frame = GetCachedTexture(cached_node_hash);
|
||||
if (cached_frame) {
|
||||
output_params.Push(NodeValue::kTexture, QVariant::fromValue(cached_frame), node);
|
||||
ShaderJob job = v.value<ShaderJob>();
|
||||
|
||||
// No more to do here
|
||||
got_cached_frame = true;
|
||||
}
|
||||
}*/
|
||||
VideoParams tex_params = GetCacheVideoParams();
|
||||
tex_params.set_channel_count(GetChannelCountFromJob(job));
|
||||
|
||||
// Strip out any jobs or footage
|
||||
QList<NodeValue> footage_jobs_to_run;
|
||||
QList<NodeValue> shader_jobs_to_run;
|
||||
QList<NodeValue> sample_jobs_to_run;
|
||||
QList<NodeValue> generate_jobs_to_run;
|
||||
QList<NodeValue> color_transform_jobs_to_run;
|
||||
TexturePtr tex = CreateTexture(tex_params);
|
||||
|
||||
for (int i=0; i<output_params.Count(); i++) {
|
||||
const NodeValue& v = output_params.at(i);
|
||||
QList<NodeValue>* take_this_value_list = nullptr;
|
||||
ProcessShader(tex, val.source(), range, job);
|
||||
|
||||
if (v.type() == NodeValue::kFootageJob) {
|
||||
take_this_value_list = &footage_jobs_to_run;
|
||||
} else if (v.type() == NodeValue::kShaderJob) {
|
||||
take_this_value_list = &shader_jobs_to_run;
|
||||
} else if (v.type() == NodeValue::kSampleJob) {
|
||||
take_this_value_list = &sample_jobs_to_run;
|
||||
} else if (v.type() == NodeValue::kGenerateJob) {
|
||||
take_this_value_list = &generate_jobs_to_run;
|
||||
} else if (v.type() == NodeValue::kColorTransformJob) {
|
||||
take_this_value_list = &color_transform_jobs_to_run;
|
||||
}
|
||||
val.set_data(QVariant::fromValue(tex));
|
||||
|
||||
if (take_this_value_list) {
|
||||
take_this_value_list->append(output_params.TakeAt(i));
|
||||
i--;
|
||||
}
|
||||
}
|
||||
} else if (v.canConvert<GenerateJob>()) {
|
||||
|
||||
if (!got_cached_frame) {
|
||||
// Retrieve video frames
|
||||
foreach (const NodeValue& v, footage_jobs_to_run) {
|
||||
// Assume this is a VideoStream, we did a type check earlier in the function
|
||||
FootageJob job = v.data().value<FootageJob>();
|
||||
GenerateJob job = v.value<GenerateJob>();
|
||||
|
||||
VideoParams tex_params = GetCacheVideoParams();
|
||||
tex_params.set_channel_count(GetChannelCountFromJob(job));
|
||||
if (job.GetRequestedFormat() != VideoParams::kFormatInvalid) {
|
||||
tex_params.set_format(job.GetRequestedFormat());
|
||||
}
|
||||
|
||||
TexturePtr tex = CreateTexture(tex_params);
|
||||
|
||||
ProcessFrameGeneration(tex, val.source(), job);
|
||||
|
||||
val.set_data(QVariant::fromValue(tex));
|
||||
|
||||
} else if (v.canConvert<ColorTransformJob>()) {
|
||||
|
||||
ColorTransformJob job = v.value<ColorTransformJob>();
|
||||
|
||||
VideoParams src_params = job.GetInputTexture()->params();
|
||||
src_params.set_channel_count(GetChannelCountFromJob(job));
|
||||
|
||||
TexturePtr dest = CreateTexture(src_params);
|
||||
|
||||
ProcessColorTransform(dest, val.source(), job);
|
||||
|
||||
val.set_data(QVariant::fromValue(dest));
|
||||
|
||||
} else if (v.canConvert<FootageJob>()) {
|
||||
|
||||
FootageJob job = v.value<FootageJob>();
|
||||
|
||||
if (job.type() == Track::kVideo) {
|
||||
|
||||
rational footage_time = Footage::AdjustTimeByLoopMode(range.in(), job.loop_mode(), job.length(), job.video_params().video_type(), job.video_params().frame_rate_as_time_base());
|
||||
|
||||
TexturePtr tex;
|
||||
|
||||
if (footage_time.isNaN()) {
|
||||
// Push dummy texture
|
||||
output_params.Push(NodeValue::kTexture, QVariant::fromValue(CreateDummyTexture(job.video_params())), node, v.array(), v.tag());
|
||||
tex = CreateDummyTexture(job.video_params());
|
||||
} else {
|
||||
output_params.Push(NodeValue::kTexture, QVariant::fromValue(ProcessVideoFootage(job, footage_time)), node, v.array(), v.tag());
|
||||
VideoParams managed_params = job.video_params();
|
||||
managed_params.set_format(GetCacheVideoParams().format());
|
||||
|
||||
tex = CreateTexture(job.video_params());
|
||||
ProcessVideoFootage(tex, job, footage_time);
|
||||
}
|
||||
|
||||
val.set_data(QVariant::fromValue(tex));
|
||||
|
||||
} else if (job.type() == Track::kAudio) {
|
||||
|
||||
SampleBufferPtr buffer = CreateSampleBuffer(GetCacheAudioParams(), range.length());
|
||||
ProcessAudioFootage(buffer, job, range);
|
||||
val.set_data(QVariant::fromValue(buffer));
|
||||
|
||||
}
|
||||
|
||||
} else if (v.canConvert<SampleJob>()) {
|
||||
|
||||
SampleJob job = v.value<SampleJob>();
|
||||
SampleBufferPtr output_buffer = CreateSampleBuffer(job.samples()->audio_params(), job.samples()->sample_count());
|
||||
ProcessSamples(output_buffer, val.source(), range, job);
|
||||
val.set_data(QVariant::fromValue(output_buffer));
|
||||
|
||||
}
|
||||
|
||||
// Run shaders
|
||||
foreach (const NodeValue& v, shader_jobs_to_run) {
|
||||
output_params.Push(NodeValue::kTexture, QVariant::fromValue(ProcessShader(node, range, v.data().value<ShaderJob>())), node, v.array(), v.tag());
|
||||
}
|
||||
|
||||
// Run color transforms
|
||||
foreach (const NodeValue& v, color_transform_jobs_to_run) {
|
||||
output_params.Push(NodeValue::kTexture, QVariant::fromValue(ProcessColorTransform(node, v.data().value<ColorTransformJob>())), node, v.array(), v.tag());
|
||||
}
|
||||
|
||||
// Run generate jobs
|
||||
foreach (const NodeValue& v, generate_jobs_to_run) {
|
||||
output_params.Push(NodeValue::kTexture, QVariant::fromValue(ProcessFrameGeneration(node, v.data().value<GenerateJob>())), node, v.array(), v.tag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve audio samples
|
||||
foreach (const NodeValue& v, footage_jobs_to_run) {
|
||||
// Assume this is an AudioStream, we did a type check earlier in the function
|
||||
FootageJob job = v.data().value<FootageJob>();
|
||||
void NodeTraverser::PreProcessRow(const TimeRange &range, NodeValueRow &row)
|
||||
{
|
||||
QByteArray cached_node_hash;
|
||||
|
||||
if (job.type() == Track::kAudio) {
|
||||
output_params.Push(NodeValue::kSamples, QVariant::fromValue(ProcessAudioFootage(job, range)), node, v.array(), v.tag());
|
||||
}
|
||||
}
|
||||
// Resolve any jobs
|
||||
for (auto it=row.begin(); it!=row.end(); it++) {
|
||||
// Jobs will almost always be submitted with one of these types
|
||||
NodeValue &val = it.value();
|
||||
|
||||
// Run any accelerated shader jobs
|
||||
foreach (const NodeValue& v, sample_jobs_to_run) {
|
||||
output_params.Push(NodeValue::kSamples, QVariant::fromValue(ProcessSamples(node, range, v.data().value<SampleJob>())), node, v.array(), v.tag());
|
||||
}
|
||||
|
||||
if (CanCacheFrames() && node->GetCacheTextures() && !got_cached_frame) {
|
||||
// Save cached texture
|
||||
SaveCachedTexture(cached_node_hash, output_params.Get(NodeValue::kTexture).value<TexturePtr>());
|
||||
ResolveJobs(val, range);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+35
-9
@@ -66,6 +66,16 @@ public:
|
||||
video_params_ = params;
|
||||
}
|
||||
|
||||
const AudioParams& GetCacheAudioParams() const
|
||||
{
|
||||
return audio_params_;
|
||||
}
|
||||
|
||||
void SetCacheAudioParams(const AudioParams& params)
|
||||
{
|
||||
audio_params_ = params;
|
||||
}
|
||||
|
||||
static int GetChannelCountFromJob(const GenerateJob& job);
|
||||
|
||||
protected:
|
||||
@@ -73,21 +83,33 @@ protected:
|
||||
|
||||
virtual NodeValueTable GenerateBlockTable(const Track *track, const TimeRange& range);
|
||||
|
||||
virtual TexturePtr ProcessVideoFootage(const FootageJob &stream, const rational &input_time);
|
||||
virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time){}
|
||||
|
||||
virtual SampleBufferPtr ProcessAudioFootage(const FootageJob &stream, const TimeRange &input_time);
|
||||
virtual void ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time){}
|
||||
|
||||
virtual TexturePtr ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job);
|
||||
virtual void ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob& job){}
|
||||
|
||||
virtual TexturePtr ProcessColorTransform(const Node *node, const ColorTransformJob& job);
|
||||
virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob& job){}
|
||||
|
||||
virtual SampleBufferPtr ProcessSamples(const Node *node, const TimeRange &range, const SampleJob &job);
|
||||
virtual void ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job){}
|
||||
|
||||
virtual TexturePtr ProcessFrameGeneration(const Node *node, const GenerateJob& job);
|
||||
virtual void ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob& job){}
|
||||
|
||||
virtual TexturePtr GetCachedTexture(const QByteArray& hash);
|
||||
virtual TexturePtr CreateTexture(const VideoParams &p)
|
||||
{
|
||||
return CreateDummyTexture(p);
|
||||
}
|
||||
|
||||
virtual void SaveCachedTexture(const QByteArray& hash, TexturePtr texture);
|
||||
virtual SampleBufferPtr CreateSampleBuffer(const AudioParams ¶ms, int sample_count)
|
||||
{
|
||||
// Return dummy by default
|
||||
return SampleBuffer::Create();
|
||||
}
|
||||
|
||||
SampleBufferPtr CreateSampleBuffer(const AudioParams ¶ms, const rational &length)
|
||||
{
|
||||
return CreateSampleBuffer(params, params.time_to_samples(length));
|
||||
}
|
||||
|
||||
virtual bool CanCacheFrames()
|
||||
{
|
||||
@@ -111,13 +133,17 @@ protected:
|
||||
cancel_ = cancel;
|
||||
}
|
||||
|
||||
void ResolveJobs(NodeValue &value, const TimeRange &range);
|
||||
|
||||
private:
|
||||
void PostProcessTable(const Node *node, const Node::ValueHint &hint, const TimeRange &range, NodeValueTable &output_params);
|
||||
void PreProcessRow(const TimeRange &range, NodeValueRow &row);
|
||||
|
||||
TexturePtr CreateDummyTexture(const VideoParams &p);
|
||||
|
||||
VideoParams video_params_;
|
||||
|
||||
AudioParams audio_params_;
|
||||
|
||||
const QAtomicInt *cancel_;
|
||||
|
||||
};
|
||||
|
||||
@@ -135,13 +135,8 @@ QByteArray NodeValue::ValueToBytes(NodeValue::Type type, const QVariant &value)
|
||||
|
||||
// These types have no persistent input
|
||||
case kNone:
|
||||
case kFootageJob:
|
||||
case kTexture:
|
||||
case kSamples:
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kColorTransformJob:
|
||||
case kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
@@ -355,11 +350,6 @@ QString NodeValue::GetPrettyDataTypeName(Type type)
|
||||
case kAudioParams:
|
||||
return QCoreApplication::translate("NodeValue", "Audio Parameters");
|
||||
|
||||
case kFootageJob:
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kColorTransformJob:
|
||||
case kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
@@ -408,11 +398,6 @@ QString NodeValue::GetDataTypeName(Type type)
|
||||
return QStringLiteral("vparam");
|
||||
case kAudioParams:
|
||||
return QStringLiteral("aparam");
|
||||
case kFootageJob:
|
||||
case kShaderJob:
|
||||
case kSampleJob:
|
||||
case kGenerateJob:
|
||||
case kColorTransformJob:
|
||||
case kDataTypeCount:
|
||||
break;
|
||||
}
|
||||
|
||||
+5
-45
@@ -172,51 +172,6 @@ public:
|
||||
*/
|
||||
kAudioParams,
|
||||
|
||||
/**
|
||||
* Job type
|
||||
*
|
||||
* An internal type used to indicate to the renderer that a footage job needs to
|
||||
* run. This value will usually be taken from a table and a kTexture or kSamples value will be
|
||||
* pushed to take its place.
|
||||
*/
|
||||
kFootageJob,
|
||||
|
||||
/**
|
||||
* Job type
|
||||
*
|
||||
* An internal type used to indicate to the renderer that an accelerated shader job needs to
|
||||
* run. This value will usually be taken from a table and a kTexture value will be pushed to
|
||||
* take its place.
|
||||
*/
|
||||
kShaderJob,
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
kSampleJob,
|
||||
|
||||
/**
|
||||
* 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,
|
||||
|
||||
/**
|
||||
* Job type
|
||||
*
|
||||
* An internal type used to indicate to the renderer that an accelerated color transform job
|
||||
* needs to take place. This value will usually be taken from a table and a kTexture value will
|
||||
* be pushed to take its place.
|
||||
*/
|
||||
kColorTransformJob,
|
||||
|
||||
/**
|
||||
* End of list
|
||||
*/
|
||||
@@ -253,6 +208,11 @@ public:
|
||||
return data_;
|
||||
}
|
||||
|
||||
void set_data(const QVariant& data)
|
||||
{
|
||||
data_ = data;
|
||||
}
|
||||
|
||||
const QString& tag() const
|
||||
{
|
||||
return tag_;
|
||||
|
||||
Reference in New Issue
Block a user