further implement colortransformjob

This commit is contained in:
itsmattkc
2022-04-26 13:13:28 -07:00
parent 831fe77275
commit 3c13e32620
10 changed files with 164 additions and 93 deletions
+9 -3
View File
@@ -65,11 +65,16 @@ void ChromaKeyNode::InputValueChangedEvent(const QString &input, int element)
GenerateProcessor();
}
ShaderCode ChromaKeyNode::GetShaderCode(const QString &) const
{
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/chromakey.frag")));
}
void ChromaKeyNode::GenerateProcessor()
{
if (manager()){
ColorTransform transform("cie_xyz_d65_interchange");
set_processor(ColorProcessor::Create(manager(), manager()->GetReferenceColorSpace(), transform));
set_processor(ColorProcessor::Create(manager(), manager()->GetReferenceColorSpace(), transform));
}
}
@@ -78,12 +83,13 @@ void ChromaKeyNode::Value(const NodeValueRow &value, const NodeGlobals &globals,
if (!value[kTextureInput].data().isNull() && processor()) {
ColorTransformJob job;
job.InsertValue(value);
job.SetColorProcessor(processor());
job.SetInputTexture(value[kTextureInput].data().value<TexturePtr>());
job.SetShaderPath(QStringLiteral(":/shaders/chromakey.frag"));
job.SetNeedsCustomShader(this);
table->Push(NodeValue::kColorTransformJob, QVariant::fromValue(job), this);
}
}
} // namespace olive
} // namespace olive
+1
View File
@@ -37,6 +37,7 @@ class ChromaKeyNode : public OCIOBaseNode {
virtual void InputValueChangedEvent(const QString& input, int element) override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals& globals, NodeValueTable* table) const override;
virtual void ConfigChanged() override {};
+34
View File
@@ -0,0 +1,34 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef ALPHAASSOC_H
#define ALPHAASSOC_H
namespace olive {
enum AlphaAssociated {
kAlphaNone,
kAlphaUnassociated,
kAlphaAssociated
};
}
#endif // ALPHAASSOC_H
+39 -4
View File
@@ -21,19 +21,28 @@
#ifndef COLORTRANSFORMJOB_H
#define COLORTRANSFORMJOB_H
#include <QMatrix4x4>
#include <QString>
#include "render/job/acceleratedjob.h"
#include "render/alphaassoc.h"
#include "render/colorprocessor.h"
#include "render/texture.h"
namespace olive {
class ColorTransformJob {
class Node;
class ColorTransformJob : public AcceleratedJob
{
public:
ColorTransformJob()
{
processor_ = nullptr;
input_texture_ = nullptr;
custom_shader_src_ = nullptr;
input_alpha_association_ = kAlphaNone;
clear_destination_ = true;
}
TexturePtr GetInputTexture() const { return input_texture_; }
@@ -42,15 +51,41 @@ public:
ColorProcessorPtr GetColorProcessor() const { return processor_; }
void SetColorProcessor(ColorProcessorPtr p) { processor_ = p; }
QString GetShaderPath() const { return shader_path_; }
void SetShaderPath(const QString shader_path) { shader_path_ = shader_path; }
const AlphaAssociated &GetInputAlphaAssociation() const { return input_alpha_association_; }
void SetInputAlphaAssociation(const AlphaAssociated &e) { input_alpha_association_ = e; }
const Node *CustomShaderSource() const { return custom_shader_src_; }
const QString &CustomShaderID() const { return custom_shader_id_; }
void SetNeedsCustomShader(const Node *node, const QString &id = QString())
{
custom_shader_src_ = node;
custom_shader_id_ = id;
}
bool IsClearDestinationEnabled() const { return clear_destination_; }
void SetClearDestinationEnabled(bool e) { clear_destination_ = e; }
const QMatrix4x4 &GetTransformMatrix() const { return matrix_; }
void SetTransformMatrix(const QMatrix4x4 &m) { matrix_ = m; }
const QMatrix4x4 &GetCropMatrix() const { return crop_matrix_; }
void SetCropMatrix(const QMatrix4x4 &m) { crop_matrix_ = m; }
private:
ColorProcessorPtr processor_;
TexturePtr input_texture_;
QString shader_path_;
const Node *custom_shader_src_;
QString custom_shader_id_;
AlphaAssociated input_alpha_association_;
bool clear_destination_;
QMatrix4x4 matrix_;
QMatrix4x4 crop_matrix_;
};
+25 -46
View File
@@ -52,21 +52,6 @@ TexturePtr Renderer::CreateTexture(const VideoParams &params, const void *data,
return CreateTexture(params, Texture::k2D, data, linesize);
}
void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, AlphaAssociated source_alpha_association, Texture *destination, bool clear_destination, const QMatrix4x4 &matrix, const QMatrix4x4 &crop_matrix)
{
BlitColorManagedInternal(color_processor, source, source_alpha_association, destination, destination->params(), clear_destination, matrix, crop_matrix);
}
void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, AlphaAssociated source_alpha_association, Texture* destination, QString shader_path, bool clear_destination, const QMatrix4x4& matrix, const QMatrix4x4 &crop_matrix)
{
BlitColorManagedInternal(color_processor, source, source_alpha_association, destination, destination->params(), clear_destination, matrix, crop_matrix, shader_path);
}
void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, AlphaAssociated source_alpha_association, VideoParams params, bool clear_destination, const QMatrix4x4& matrix, const QMatrix4x4 &crop_matrix)
{
BlitColorManagedInternal(color_processor, source, source_alpha_association, nullptr, params, clear_destination, matrix, crop_matrix);
}
TexturePtr Renderer::InterlaceTexture(TexturePtr top, TexturePtr bottom, const VideoParams &params)
{
color_cache_mutex_.lock();
@@ -108,14 +93,16 @@ TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v, const Vide
return std::make_shared<Texture>(this, v, params, type);
}
bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::ColorContext *ctx, QString shader_path)
bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::ColorContext *ctx)
{
QMutexLocker locker(&color_cache_mutex_);
ColorContext& color_ctx = *ctx;
if (color_cache_.contains(color_processor->id())) {
color_ctx = color_cache_.value(color_processor->id());
QString proc_id = color_job.GetColorProcessor()->id();
if (color_cache_.contains(proc_id)) {
color_ctx = color_cache_.value(proc_id);
return true;
} else {
// Create shader description
@@ -126,22 +113,21 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo
shader_desc->setResourcePrefix("ocio_");
// Generate shader
color_processor->GetProcessor()->getDefaultGPUProcessor()->extractGpuShaderInfo(shader_desc);
color_job.GetColorProcessor()->GetProcessor()->getDefaultGPUProcessor()->extractGpuShaderInfo(shader_desc);
QString shader_frag;
if (shader_path.isEmpty()) {
// Generate shader code using OCIO stub and our auto-generated name
shader_frag = FileFunctions::ReadFileAsString(QStringLiteral(":shaders/colormanage.frag"))
.arg(shader_desc->getShaderText(), ocio_func_name);
ShaderCode code;
if (const Node *shader_src = color_job.CustomShaderSource()) {
// Use shader code from associated node
code = shader_src->GetShaderCode(color_job.CustomShaderID());
} else {
// FIXME: Currently only supports a single function
shader_frag = FileFunctions::ReadFileAsString(shader_path)
.arg(shader_desc->getShaderText(), ocio_func_name);
// Generate shader code using OCIO stub and our auto-generated name
code = FileFunctions::ReadFileAsString(QStringLiteral(":shaders/colormanage.frag"));
}
code.set_frag_code(code.frag_code().arg(shader_desc->getShaderText(), ocio_func_name));
// Try to compile shader
color_ctx.compiled_shader = CreateNativeShader(ShaderCode(shader_frag,
FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/default.vert"))));
color_ctx.compiled_shader = CreateNativeShader(code);
if (color_ctx.compiled_shader.isNull()) {
return false;
@@ -209,32 +195,25 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo
color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
}
color_cache_.insert(color_processor->id(), color_ctx);
color_cache_.insert(proc_id, color_ctx);
return true;
}
}
void Renderer::BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source,
AlphaAssociated source_alpha_association, Texture *destination,
VideoParams params, bool clear_destination, const QMatrix4x4& matrix,
const QMatrix4x4& crop_matrix, const QString shader_path)
void Renderer::BlitColorManaged(const ColorTransformJob &color_job, Texture *destination, const VideoParams &params)
{
ColorContext color_ctx;
if (!GetColorContext(color_processor, &color_ctx, shader_path)) {
if (!GetColorContext(color_job, &color_ctx)) {
return;
}
ShaderJob job;
if (shader_path.isEmpty()) {
job.InsertValue(QStringLiteral("ove_maintex"), NodeValue(NodeValue::kTexture, QVariant::fromValue(source)));
} else {
// If we are using a custom shader in a node use "tex_in" for consistency
job.InsertValue(QStringLiteral("tex_in"), NodeValue(NodeValue::kTexture, QVariant::fromValue(source)));
}
job.InsertValue(QStringLiteral("ove_mvpmat"), NodeValue(NodeValue::kMatrix, matrix));
job.InsertValue(QStringLiteral("ove_cropmatrix"), NodeValue(NodeValue::kMatrix, crop_matrix.inverted()));
job.InsertValue(QStringLiteral("ove_maintex_alpha"), NodeValue(NodeValue::kInt, source_alpha_association));
job.InsertValue(QStringLiteral("ove_maintex"), NodeValue(NodeValue::kTexture, QVariant::fromValue(color_job.GetInputTexture())));
job.InsertValue(QStringLiteral("ove_mvpmat"), NodeValue(NodeValue::kMatrix, color_job.GetTransformMatrix()));
job.InsertValue(QStringLiteral("ove_cropmatrix"), NodeValue(NodeValue::kMatrix, color_job.GetCropMatrix().inverted()));
job.InsertValue(QStringLiteral("ove_maintex_alpha"), NodeValue(NodeValue::kInt, color_job.GetInputAlphaAssociation()));
job.InsertValue(color_job.GetValues());
foreach (const ColorContext::LUT& l, color_ctx.lut3d_textures) {
job.InsertValue(l.name, NodeValue(NodeValue::kTexture, QVariant::fromValue(l.texture)));
@@ -246,9 +225,9 @@ void Renderer::BlitColorManagedInternal(ColorProcessorPtr color_processor, Textu
}
if (destination) {
BlitToTexture(color_ctx.compiled_shader, job, destination, clear_destination);
BlitToTexture(color_ctx.compiled_shader, job, destination, color_job.IsClearDestinationEnabled());
} else {
Blit(color_ctx.compiled_shader, job, params, clear_destination);
Blit(color_ctx.compiled_shader, job, params, color_job.IsClearDestinationEnabled());
}
}
+11 -15
View File
@@ -29,6 +29,7 @@
#include "common/timerange.h"
#include "node/node.h"
#include "render/colorprocessor.h"
#include "render/job/colortransformjob.h"
#include "render/videoparams.h"
#include "texture.h"
@@ -63,15 +64,15 @@ public:
Blit(shader, job, nullptr, params, clear_destination);
}
enum AlphaAssociated {
kAlphaNone,
kAlphaUnassociated,
kAlphaAssociated
};
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, AlphaAssociated source_alpha_association, Texture* destination, bool clear_destination = true, const QMatrix4x4& matrix = QMatrix4x4(), const QMatrix4x4 &crop_matrix = QMatrix4x4());
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, AlphaAssociated source_alpha_association, Texture* destination, QString shader_path, bool clear_destination = true, const QMatrix4x4& matrix = QMatrix4x4(), const QMatrix4x4 &crop_matrix = QMatrix4x4());
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, AlphaAssociated source_alpha_association, VideoParams params, bool clear_destination = true, const QMatrix4x4& matrix = QMatrix4x4(), const QMatrix4x4 &crop_matrix = QMatrix4x4());
void BlitColorManaged(const ColorTransformJob &color_job, Texture* destination, const VideoParams &params);
void BlitColorManaged(const ColorTransformJob &job, Texture* destination)
{
BlitColorManaged(job, destination, destination->params());
}
void BlitColorManaged(const ColorTransformJob &job, const VideoParams &params)
{
BlitColorManaged(job, nullptr, params);
}
TexturePtr InterlaceTexture(TexturePtr top, TexturePtr bottom, const VideoParams &params);
@@ -127,12 +128,7 @@ private:
};
bool GetColorContext(ColorProcessorPtr color_processor, ColorContext* ctx, const QString shader_path);
void BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source,
AlphaAssociated source_alpha_association,
Texture* destination, VideoParams params, bool clear_destination,
const QMatrix4x4 &matrix, const QMatrix4x4 &crop_matrix, const QString shader_path = QString());
bool GetColorContext(const ColorTransformJob &color_job, ColorContext* ctx);
QHash<QString, ColorContext> color_cache_;
+25 -12
View File
@@ -99,9 +99,14 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture, const rational& time
if (output_color_transform) {
// Yes color transform, blit color managed
render_ctx_->BlitColorManaged(output_color_transform, texture,
Config::Current()[QStringLiteral("ReassocLinToNonLin")].toBool() ? Renderer::kAlphaAssociated : Renderer::kAlphaNone,
blit_tex.get(), true, matrix);
ColorTransformJob job;
job.SetColorProcessor(output_color_transform);
job.SetInputTexture(texture);
job.SetInputAlphaAssociation(Config::Current()[QStringLiteral("ReassocLinToNonLin")].toBool() ? kAlphaAssociated : kAlphaNone);
job.SetTransformMatrix(matrix);
render_ctx_->BlitColorManaged(job, blit_tex.get());
} else {
// No color transform, just blit
ShaderJob job;
@@ -452,19 +457,21 @@ TexturePtr RenderProcessor::ProcessVideoFootage(const FootageJob &stream, const
using_colorspace,
color_manager->GetReferenceColorSpace());
Renderer::AlphaAssociated alpha_assoc;
ColorTransformJob job;
job.SetColorProcessor(processor);
job.SetInputTexture(unmanaged_texture);
if (stream_data.channel_count() != VideoParams::kRGBAChannelCount
|| stream_data.colorspace() == color_manager->GetReferenceColorSpace()) {
alpha_assoc = Renderer::kAlphaNone;
job.SetInputAlphaAssociation(kAlphaNone);
} else if (stream_data.premultiplied_alpha()) {
alpha_assoc = Renderer::kAlphaAssociated;
job.SetInputAlphaAssociation(kAlphaAssociated);
} else {
alpha_assoc = Renderer::kAlphaUnassociated;
job.SetInputAlphaAssociation(kAlphaUnassociated);
}
render_ctx_->BlitColorManaged(processor, unmanaged_texture,
alpha_assoc,
value.get());
render_ctx_->BlitColorManaged(job, value.get());
return value;
}
@@ -571,7 +578,7 @@ TexturePtr RenderProcessor::ProcessColorTransform(const Node *node, const ColorT
TexturePtr src = job.GetInputTexture();
TexturePtr dest = render_ctx_->CreateTexture(src->params());
render_ctx_->BlitColorManaged(job.GetColorProcessor(), src, Renderer::kAlphaAssociated, dest.get(), job.GetShaderPath());
render_ctx_->BlitColorManaged(job, dest.get());
return dest;
}
@@ -600,7 +607,13 @@ TexturePtr RenderProcessor::ProcessFrameGeneration(const Node *node, const Gener
TexturePtr dest = render_ctx_->CreateTexture(GetCacheVideoParams());
ColorManager* color_manager = Node::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
ColorProcessorPtr cp = ColorProcessor::Create(color_manager, job.GetColorspace(), color_manager->GetReferenceColorSpace());
render_ctx_->BlitColorManaged(cp, texture, Renderer::kAlphaAssociated, dest.get());
ColorTransformJob ctj;
ctj.SetColorProcessor(cp);
ctj.SetInputTexture(texture);
ctj.SetInputAlphaAssociation(kAlphaAssociated);
render_ctx_->BlitColorManaged(ctj, dest.get());
texture = dest;
}
+4 -8
View File
@@ -33,15 +33,11 @@ public:
{
}
const QString& frag_code() const
{
return frag_code_;
}
const QString& frag_code() const { return frag_code_; }
void set_frag_code(const QString &f) { frag_code_ = f; }
const QString& vert_code() const
{
return vert_code_;
}
const QString& vert_code() const { return vert_code_; }
void set_vert_code(const QString &v) { vert_code_ = v; }
private:
QString frag_code_;
+7 -1
View File
@@ -74,7 +74,13 @@ void ScopeBase::OnPaint()
if (!managed_tex_ || !managed_tex_up_to_date_
|| managed_tex_->params() != texture_->params()) {
managed_tex_ = renderer()->CreateTexture(texture_->params());
renderer()->BlitColorManaged(color_service(), texture_, Renderer::kAlphaNone, managed_tex_.get());
ColorTransformJob job;
job.SetColorProcessor(color_service());
job.SetInputTexture(texture_);
job.SetInputAlphaAssociation(kAlphaNone);
renderer()->BlitColorManaged(job, managed_tex_.get());
}
DrawScope(managed_tex_, pipeline_);
+9 -4
View File
@@ -485,10 +485,15 @@ void ViewerDisplayWidget::OnPaint()
texture_to_draw = deinterlace_texture_;
}
renderer()->BlitColorManaged(color_service(), texture_to_draw,
Config::Current()[QStringLiteral("ReassocLinToNonLin")].toBool() ? Renderer::kAlphaAssociated : Renderer::kAlphaNone,
device_params, false,
combined_matrix_flipped_, crop_matrix_);
ColorTransformJob ctj;
ctj.SetColorProcessor(color_service());
ctj.SetInputTexture(texture_to_draw);
ctj.SetInputAlphaAssociation(Config::Current()[QStringLiteral("ReassocLinToNonLin")].toBool() ? kAlphaAssociated : kAlphaNone);
ctj.SetClearDestinationEnabled(false);
ctj.SetTransformMatrix(combined_matrix_flipped_);
ctj.SetCropMatrix(crop_matrix_);
renderer()->BlitColorManaged(ctj, device_params);
}
}