diff --git a/app/codec/oiio/oiiodecoder.cpp b/app/codec/oiio/oiiodecoder.cpp
index 632220189..1728c04d2 100644
--- a/app/codec/oiio/oiiodecoder.cpp
+++ b/app/codec/oiio/oiiodecoder.cpp
@@ -215,8 +215,9 @@ bool OIIODecoder::OpenImageHandler(const QString &fn)
// Check if we can work with this pixel format
const OIIO::ImageSpec& spec = image_->spec();
- is_rgba_ = (spec.nchannels == kRGBAChannels);
+ //is_rgba_ = (spec.nchannels == kRGBAChannels);
+ // We use RGBA frames because that tends to be the native format of GPUs
pix_fmt_ = OIIOCommon::GetFormatFromOIIOBasetype(spec);
if (pix_fmt_ == PixelFormat::PIX_FMT_INVALID) {
diff --git a/app/codec/oiio/oiiodecoder.h b/app/codec/oiio/oiiodecoder.h
index 328b54a30..820057d3e 100644
--- a/app/codec/oiio/oiiodecoder.h
+++ b/app/codec/oiio/oiiodecoder.h
@@ -65,7 +65,7 @@ private:
PixelFormat::Format pix_fmt_;
- bool is_rgba_;
+ //bool is_rgba_;
OIIO::ImageBuf* buffer_;
diff --git a/app/config/config.cpp b/app/config/config.cpp
index a40718a8d..40f53240f 100644
--- a/app/config/config.cpp
+++ b/app/config/config.cpp
@@ -231,10 +231,10 @@ void Config::Save()
QString value = NodeInput::ValueToString(iterator.value().type, iterator.value().data, false);
- writer.writeTextElement(iterator.key(), value);
-
if (iterator.value().type == NodeParam::kNone) {
- qWarning() << "Config key" << iterator.key() << "had null type";
+ qWarning() << "Config key" << iterator.key() << "had null type and was discarded";
+ } else {
+ writer.writeTextElement(iterator.key(), value);
}
}
diff --git a/app/core.cpp b/app/core.cpp
index 608b79da7..b60591b88 100644
--- a/app/core.cpp
+++ b/app/core.cpp
@@ -53,7 +53,6 @@
#include "render/diskmanager.h"
#include "render/pixelformat.h"
#include "render/rendermanager.h"
-#include "render/shaderinfo.h"
#ifdef USE_OTIO
#include "task/project/loadotio/loadotio.h"
#include "task/project/saveotio/saveotio.h"
diff --git a/app/node/node.h b/app/node/node.h
index bcc168c15..6da128f51 100644
--- a/app/node/node.h
+++ b/app/node/node.h
@@ -36,7 +36,10 @@
#include "node/output.h"
#include "node/value.h"
#include "render/audioparams.h"
-#include "render/shaderinfo.h"
+#include "render/job/generatejob.h"
+#include "render/job/samplejob.h"
+#include "render/job/shaderjob.h"
+#include "render/shadercode.h"
OLIVE_NAMESPACE_ENTER
diff --git a/app/render/CMakeLists.txt b/app/render/CMakeLists.txt
index 6e8f1e43d..abb4bda59 100644
--- a/app/render/CMakeLists.txt
+++ b/app/render/CMakeLists.txt
@@ -14,45 +14,52 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-add_subdirectory(backend)
+add_subdirectory(job)
add_subdirectory(ocioconf)
+add_subdirectory(opengl)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
- render/audioparams.h
render/audioparams.cpp
- render/audioplaybackcache.h
+ render/audioparams.h
render/audioplaybackcache.cpp
- render/color.h
+ render/audioplaybackcache.h
render/color.cpp
- render/colormanager.h
+ render/color.h
render/colormanager.cpp
+ render/colormanager.h
+ render/colorprocessor.cpp
render/colorprocessor.h
render/colorprocessorcache.h
- render/colorprocessor.cpp
- render/diskmanager.h
render/diskmanager.cpp
- render/framehashcache.h
+ render/diskmanager.h
render/framehashcache.cpp
- render/managedcolor.h
+ render/framehashcache.h
render/managedcolor.cpp
- render/pixelformat.h
+ render/managedcolor.h
render/pixelformat.cpp
- render/playbackcache.h
+ render/pixelformat.h
render/playbackcache.cpp
- render/previewautocacher.h
+ render/playbackcache.h
render/previewautocacher.cpp
+ render/previewautocacher.h
+ render/renderer.cpp
+ render/renderer.h
render/rendercache.h
- render/rendermanager.h
+ render/rendererthreadwrapper.cpp
+ render/rendererthreadwrapper.h
render/rendermanager.cpp
+ render/rendermanager.h
render/rendermodes.h
- render/renderprocessor.h
render/renderprocessor.cpp
- render/shaderinfo.h
+ render/renderprocessor.h
+ render/shadercode.h
render/shadervalue.h
render/stillimagecache.h
- render/videoparams.h
+ render/texture.cpp
+ render/texture.h
render/videoparams.cpp
+ render/videoparams.h
PARENT_SCOPE
)
diff --git a/app/render/backend/renderer.cpp b/app/render/backend/renderer.cpp
deleted file mode 100644
index b2bf0ee04..000000000
--- a/app/render/backend/renderer.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/***
-
- Olive - Non-Linear Video Editor
- Copyright (C) 2019 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 .
-
-***/
-
-#include "renderer.h"
-
-#include
-
-#include "common/ocioutils.h"
-#include "render/colormanager.h"
-
-OLIVE_NAMESPACE_ENTER
-
-Renderer::Renderer(QObject *parent) :
- QObject(parent)
-{
-
-}
-
-Renderer::TexturePtr Renderer::CreateTexture(const VideoParams ¶m, void *data, int linesize)
-{
- QVariant v = CreateNativeTexture(param, data, linesize);
-
- if (v.isNull()) {
- return nullptr;
- }
-
- return std::make_shared(this, v, param);
-}
-
-// copied from source code to OCIODisplay
-/*const int OCIO_LUT3D_EDGE_SIZE = 64;
-
-const int OCIO_LUT3D_PIXEL_COUNT = OCIO_LUT3D_EDGE_SIZE*OCIO_LUT3D_EDGE_SIZE*OCIO_LUT3D_EDGE_SIZE;
-const int OCIO_LUT3D_ENTRY_COUNT = 3 * OCIO_LUT3D_PIXEL_COUNT;
-const int OCIO_LUT3D_ENTRY_COUNT_WITH_ALPHA = 4 * OCIO_LUT3D_PIXEL_COUNT;
-const int OCIO_LUT2D_EDGE_SIZE = 512;*/
-
-void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination, bool flipped)
-{
- qDebug() << "BlitColorManaged is a partial stub";
-
- QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert")));
-
- ShaderJob job;
- job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture));
-
- if (flipped) {
- QMatrix4x4 mat;
- mat.scale(1, -1, 1);
- job.SetMatrix(mat);
- }
-
- BlitToTexture(shader, job, destination);
-
- DestroyNativeShader(shader);
-}
-
-void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, bool flipped)
-{
- qDebug() << "BlitColorManaged is a partial stub";
-
- /*ColorContext color_ctx;
-
- if (color_cache_.contains(color_processor->id())) {
- color_ctx = color_cache_.value(color_processor->id());
- } else {
- // Create shader description
- const char* ocio_func_name = "OCIODisplay";
- OCIO::GpuShaderDescRcPtr shader_desc = OCIO::GpuShaderDesc::CreateShaderDesc();
- shader_desc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2);
- shader_desc->setFunctionName(ocio_func_name);
- shader_desc->setResourcePrefix("ocio_");
-
- // Generate shader
- color_processor->GetProcessor()->getDefaultGPUProcessor()->extractGpuShaderInfo(shader_desc);
-
- qDebug() << "Shader:" << shader_desc->getShaderText();
- }*/
-
- QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert")));
-
- ShaderJob job;
- job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture));
-
- if (flipped) {
- QMatrix4x4 mat;
- mat.scale(1, -1, 1);
- job.SetMatrix(mat);
- }
-
- Blit(shader, job, params);
-
- DestroyNativeShader(shader);
-}
-
-OLIVE_NAMESPACE_EXIT
diff --git a/app/render/backend/CMakeLists.txt b/app/render/job/CMakeLists.txt
similarity index 81%
rename from app/render/backend/CMakeLists.txt
rename to app/render/job/CMakeLists.txt
index de34bd6b3..d71defccf 100644
--- a/app/render/backend/CMakeLists.txt
+++ b/app/render/job/CMakeLists.txt
@@ -14,13 +14,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-add_subdirectory(opengl)
-
set(OLIVE_SOURCES
${OLIVE_SOURCES}
- render/backend/renderer.cpp
- render/backend/renderer.h
- render/backend/rendererthreadwrapper.cpp
- render/backend/rendererthreadwrapper.h
+ render/job/acceleratedjob.h
+ render/job/generatejob.h
+ render/job/samplejob.h
+ render/job/shaderjob.h
PARENT_SCOPE
)
diff --git a/app/render/job/acceleratedjob.h b/app/render/job/acceleratedjob.h
new file mode 100644
index 000000000..71fb1a838
--- /dev/null
+++ b/app/render/job/acceleratedjob.h
@@ -0,0 +1,101 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#ifndef ACCELERATEDJOB_H
+#define ACCELERATEDJOB_H
+
+#include "node/input.h"
+#include "node/inputarray.h"
+#include "render/shadervalue.h"
+#include "node/value.h"
+
+OLIVE_NAMESPACE_ENTER
+
+class AcceleratedJob {
+public:
+ AcceleratedJob() = default;
+
+ ShaderValue GetValue(NodeInput* input) const
+ {
+ return value_map_.value(input->id());
+ }
+
+ ShaderValue GetValue(const QString& input) const
+ {
+ return value_map_.value(input);
+ }
+
+ void InsertValue(NodeInput* input, NodeValueDatabase& value)
+ {
+ ShaderValue shader_val;
+
+ shader_val.type = input->data_type();
+ shader_val.array = input->IsArray();
+
+ if (input->IsArray()) {
+ NodeInputArray* array = static_cast(input);
+ QVector values(array->GetSize());
+
+ for (int j=0;jGetSize();j++) {
+ NodeInput* subparam = array->At(j);
+
+ values[j] = value[subparam].Take(subparam->data_type());
+ }
+
+ shader_val.data = QVariant::fromValue(values);
+ } else {
+ NodeValue node_val = value[input].TakeWithMeta(input->data_type());
+ shader_val.data = node_val.data();
+ shader_val.tag = node_val.tag();
+ }
+
+ InsertValue(input->id(), shader_val);
+ }
+
+ void InsertValue(const QString& input, const ShaderValue& value)
+ {
+ value_map_.insert(input, value);
+ }
+
+ void InsertValue(NodeInput* input, const ShaderValue& value)
+ {
+ value_map_.insert(input->id(), value);
+ }
+
+ void InsertValue(NodeInput* input, const NodeValue& value)
+ {
+ ShaderValue s(value.data(), value.type());
+ s.tag = value.tag();
+ value_map_.insert(input->id(), s);
+ }
+
+ const NodeValueMap &GetValues() const
+ {
+ return value_map_;
+ }
+
+private:
+ NodeValueMap value_map_;
+
+};
+
+OLIVE_NAMESPACE_EXIT
+
+#endif // ACCELERATEDJOB_H
diff --git a/app/render/job/generatejob.h b/app/render/job/generatejob.h
new file mode 100644
index 000000000..e2ab45c72
--- /dev/null
+++ b/app/render/job/generatejob.h
@@ -0,0 +1,54 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#ifndef GENERATEJOB_H
+#define GENERATEJOB_H
+
+#include "acceleratedjob.h"
+
+OLIVE_NAMESPACE_ENTER
+
+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_;
+
+};
+
+OLIVE_NAMESPACE_EXIT
+
+Q_DECLARE_METATYPE(OLIVE_NAMESPACE::GenerateJob)
+
+#endif // GENERATEJOB_H
diff --git a/app/render/job/samplejob.h b/app/render/job/samplejob.h
new file mode 100644
index 000000000..f46e6a3eb
--- /dev/null
+++ b/app/render/job/samplejob.h
@@ -0,0 +1,65 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#ifndef SAMPLEJOB_H
+#define SAMPLEJOB_H
+
+#include "acceleratedjob.h"
+#include "codec/samplebuffer.h"
+
+OLIVE_NAMESPACE_ENTER
+
+class SampleJob : public AcceleratedJob {
+public:
+ SampleJob()
+ {
+ samples_ = nullptr;
+ }
+
+ SampleJob(const NodeValue& value)
+ {
+ samples_ = value.data().value();
+ }
+
+ SampleJob(NodeInput* from, NodeValueDatabase& db)
+ {
+ samples_ = db[from].Take(NodeParam::kSamples).value();
+ }
+
+ SampleBufferPtr samples() const
+ {
+ return samples_;
+ }
+
+ bool HasSamples() const
+ {
+ return samples_ && samples_->is_allocated();
+ }
+
+private:
+ SampleBufferPtr samples_;
+
+};
+
+OLIVE_NAMESPACE_EXIT
+
+Q_DECLARE_METATYPE(OLIVE_NAMESPACE::SampleJob)
+
+#endif // SAMPLEJOB_H
diff --git a/app/render/job/shaderjob.h b/app/render/job/shaderjob.h
new file mode 100644
index 000000000..c6fc66cd9
--- /dev/null
+++ b/app/render/job/shaderjob.h
@@ -0,0 +1,112 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#ifndef SHADERJOB_H
+#define SHADERJOB_H
+
+#include
+
+#include "generatejob.h"
+#include "render/texture.h"
+
+OLIVE_NAMESPACE_ENTER
+
+class ShaderJob : public GenerateJob {
+public:
+ ShaderJob()
+ {
+ iterations_ = 1;
+ iterative_input_ = nullptr;
+ }
+
+ const QMatrix4x4& GetMatrix() const
+ {
+ return matrix_;
+ }
+
+ void SetMatrix(const QMatrix4x4& matrix)
+ {
+ matrix_ = matrix;
+ }
+
+ const QString& GetShaderID() const
+ {
+ return shader_id_;
+ }
+
+ void SetShaderID(const QString& id)
+ {
+ shader_id_ = id;
+ }
+
+ void SetIterations(int iterations, NodeInput* iterative_input)
+ {
+ SetIterations(iterations, iterative_input->id());
+ }
+
+ void SetIterations(int iterations, const QString& iterative_input)
+ {
+ iterations_ = iterations;
+ iterative_input_ = iterative_input;
+ }
+
+ int GetIterationCount() const
+ {
+ return iterations_;
+ }
+
+ const QString& GetIterativeInput() const
+ {
+ return iterative_input_;
+ }
+
+ Texture::Interpolation GetInterpolation(const QString& id)
+ {
+ return interpolation_.value(id, Texture::kDefaultInterpolation);
+ }
+
+ void SetInterpolation(NodeInput* input, Texture::Interpolation interp)
+ {
+ interpolation_.insert(input->id(), interp);
+ }
+
+ void SetInterpolation(const QString& id, Texture::Interpolation interp)
+ {
+ interpolation_.insert(id, interp);
+ }
+
+private:
+ QString shader_id_;
+
+ int iterations_;
+
+ QString iterative_input_;
+
+ QHash interpolation_;
+
+ QMatrix4x4 matrix_;
+
+};
+
+OLIVE_NAMESPACE_EXIT
+
+Q_DECLARE_METATYPE(OLIVE_NAMESPACE::ShaderJob)
+
+#endif // SHADERJOB_H
diff --git a/app/render/backend/opengl/CMakeLists.txt b/app/render/opengl/CMakeLists.txt
similarity index 90%
rename from app/render/backend/opengl/CMakeLists.txt
rename to app/render/opengl/CMakeLists.txt
index e2df52f90..72662cb31 100644
--- a/app/render/backend/opengl/CMakeLists.txt
+++ b/app/render/opengl/CMakeLists.txt
@@ -16,7 +16,7 @@
set(OLIVE_SOURCES
${OLIVE_SOURCES}
- render/backend/opengl/openglrenderer.cpp
- render/backend/opengl/openglrenderer.h
+ render/opengl/openglrenderer.cpp
+ render/opengl/openglrenderer.h
PARENT_SCOPE
)
diff --git a/app/render/backend/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp
similarity index 80%
rename from app/render/backend/opengl/openglrenderer.cpp
rename to app/render/opengl/openglrenderer.cpp
index a435bfd75..25a1c9fb0 100644
--- a/app/render/backend/opengl/openglrenderer.cpp
+++ b/app/render/opengl/openglrenderer.cpp
@@ -103,7 +103,7 @@ void OpenGLRenderer::PostInit()
functions_->glGenFramebuffers(1, &framebuffer_);
}
-void OpenGLRenderer::Destroy()
+void OpenGLRenderer::DestroyInternal()
{
if (context_) {
// Delete framebuffer
@@ -128,7 +128,53 @@ void OpenGLRenderer::ClearDestination(double r, double g, double b, double a)
functions_->glClear(GL_COLOR_BUFFER_BIT);
}
-void OpenGLRenderer::AttachTextureAsDestination(Renderer::Texture* texture)
+QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, PixelFormat::Format format, Texture::ChannelFormat channel_format, const void *data, int linesize)
+{
+ GLuint texture;
+ functions_->glGenTextures(1, &texture);
+
+ functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize);
+
+ GLint current_tex;
+ functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex);
+
+ functions_->glBindTexture(GL_TEXTURE_2D, texture);
+
+ functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(format, channel_format),
+ width, height, 0, GetPixelFormat(channel_format),
+ GetPixelType(format), data);
+
+ functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ functions_->glBindTexture(GL_TEXTURE_2D, current_tex);
+
+ return texture;
+}
+
+QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth, PixelFormat::Format format, Texture::ChannelFormat channel_format, const void *data, int linesize)
+{
+ GLuint texture;
+ functions_->glGenTextures(1, &texture);
+
+ functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize);
+
+ GLint current_tex;
+ functions_->glGetIntegerv(GL_TEXTURE_BINDING_3D, ¤t_tex);
+
+ functions_->glBindTexture(GL_TEXTURE_3D, texture);
+
+ context_->extraFunctions()->glTexImage3D(GL_TEXTURE_3D, 0, GetInternalFormat(format, channel_format),
+ width, height, depth, 0, GetPixelFormat(channel_format),
+ GetPixelType(format), data);
+
+ functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ functions_->glBindTexture(GL_TEXTURE_3D, current_tex);
+
+ return texture;
+}
+
+void OpenGLRenderer::AttachTextureAsDestination(Texture* texture)
{
functions_->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
functions_->glFramebufferTexture2D(GL_FRAMEBUFFER,
@@ -143,29 +189,6 @@ void OpenGLRenderer::DetachTextureAsDestination()
functions_->glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
-QVariant OpenGLRenderer::CreateNativeTexture(VideoParams p, void *data, int linesize)
-{
- GLuint texture;
- functions_->glGenTextures(1, &texture);
-
- functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize);
-
- GLint current_tex;
- functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex);
-
- functions_->glBindTexture(GL_TEXTURE_2D, texture);
-
- functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(p.format()),
- p.effective_width(), p.effective_height(), 0, GL_RGBA,
- GetPixelType(p.format()), data);
-
- functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- functions_->glBindTexture(GL_TEXTURE_2D, current_tex);
-
- return texture;
-}
-
void OpenGLRenderer::DestroyNativeTexture(QVariant texture)
{
GLuint t = texture.value();
@@ -203,7 +226,7 @@ void OpenGLRenderer::DestroyNativeShader(QVariant shader)
delete Node::ValueToPtr(shader);
}
-void OpenGLRenderer::UploadToTexture(Texture *texture, void *data, int linesize)
+void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int linesize)
{
GLuint t = texture->id().value();
const VideoParams& p = texture->params();
@@ -252,11 +275,17 @@ void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int lines
functions_->glBindTexture(GL_TEXTURE_2D, current_tex);
}
-void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destination, VideoParams destination_params)
+struct TextureToBind {
+ TexturePtr texture;
+ Texture::Interpolation interpolation;
+};
+
+void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, VideoParams destination_params)
{
// If this node is iterative, we'll pick up which input here
+ QString iterative_name;
GLuint iterative_input = 0;
- QList textures_to_bind;
+ QVector textures_to_bind;
bool input_textures_have_alpha = false;
QOpenGLShaderProgram* shader = Node::ValueToPtr(s);
@@ -325,10 +354,11 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat
// If this texture binding is the iterative input, set it here
if (it.key() == job.GetIterativeInput()) {
iterative_input = textures_to_bind.size();
+ iterative_name = it.key();
}
GLuint tex_id = texture ? texture->id().value() : 0;
- textures_to_bind.append(tex_id);
+ textures_to_bind.append({texture, job.GetInterpolation(it.key())});
if (texture && texture->has_meaningful_alpha()) {
input_textures_have_alpha = true;
@@ -383,9 +413,17 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat
// Bind all textures
for (int i=0; iid().value() : 0;
+
functions_->glActiveTexture(GL_TEXTURE0 + i);
- functions_->glBindTexture(GL_TEXTURE_2D, textures_to_bind.at(i));
- PrepareInputTexture(job.GetBilinearFiltering());
+
+ GLenum target = (texture->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D;
+ functions_->glBindTexture(target, tex_id);
+
+ PrepareInputTexture(target, t.interpolation);
}
// Set ove_resolution to the destination to the "logical" resolution of the destination
@@ -479,7 +517,9 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat
// last drew
functions_->glActiveTexture(GL_TEXTURE0 + iterative_input);
functions_->glBindTexture(GL_TEXTURE_2D, input_tex->id().value());
- PrepareInputTexture(job.GetBilinearFiltering());
+
+ // At this time, we only support iterating 2D textures
+ PrepareInputTexture(GL_TEXTURE_2D, job.GetInterpolation(iterative_name));
}
// Swap so that the next iteration, the texture we draw now will be the input texture next
@@ -499,8 +539,9 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat
// Release any textures we bound before
for (int i=textures_to_bind.size()-1; i>=0; i--) {
+ GLenum target = (textures_to_bind.at(i).texture->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D;
functions_->glActiveTexture(GL_TEXTURE0 + i);
- functions_->glBindTexture(GL_TEXTURE_2D, 0);
+ functions_->glBindTexture(target, 0);
}
// Release shader
@@ -513,17 +554,17 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat
vao_.destroy();
}
-GLint OpenGLRenderer::GetInternalFormat(PixelFormat::Format format)
+GLint OpenGLRenderer::GetInternalFormat(PixelFormat::Format format, bool with_alpha)
{
switch (format) {
case PixelFormat::PIX_FMT_RGBA8:
- return GL_RGBA8;
+ return with_alpha ? GL_RGBA8 : GL_RGB8;
case PixelFormat::PIX_FMT_RGBA16U:
- return GL_RGBA16;
+ return with_alpha ? GL_RGBA16 : GL_RGB16;
case PixelFormat::PIX_FMT_RGBA16F:
- return GL_RGBA16F;
+ return with_alpha ? GL_RGBA16F : GL_RGB16F;
case PixelFormat::PIX_FMT_RGBA32F:
- return GL_RGBA32F;
+ return with_alpha ? GL_RGBA32F : GL_RGB32F;
case PixelFormat::PIX_FMT_INVALID:
case PixelFormat::PIX_FMT_COUNT:
@@ -553,21 +594,40 @@ GLenum OpenGLRenderer::GetPixelType(PixelFormat::Format format)
return GL_INVALID_VALUE;
}
-void OpenGLRenderer::PrepareInputTexture(bool bilinear)
+GLenum OpenGLRenderer::GetPixelFormat(Texture::ChannelFormat format)
{
- if (bilinear) {
- // Use mipmapped bilinear
- functions_->glGenerateMipmap(GL_TEXTURE_2D);
- functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- } else {
- // Use nearest
- functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ switch (format) {
+ case Texture::kRGBA:
+ return GL_RGBA;
+ case Texture::kRGB:
+ return GL_RGB;
+ case Texture::kRedOnly:
+ return GL_RED;
}
- functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ return GL_INVALID_ENUM;
+}
+
+void OpenGLRenderer::PrepareInputTexture(GLenum target, Texture::Interpolation interp)
+{
+ switch (interp) {
+ case Texture::kNearest:
+ functions_->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ functions_->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ break;
+ case Texture::kLinear:
+ functions_->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ functions_->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ case Texture::kMipmappedLinear:
+ functions_->glGenerateMipmap(target);
+ functions_->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ functions_->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ }
+
+ functions_->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ functions_->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
OLIVE_NAMESPACE_EXIT
diff --git a/app/render/backend/opengl/openglrenderer.h b/app/render/opengl/openglrenderer.h
similarity index 64%
rename from app/render/backend/opengl/openglrenderer.h
rename to app/render/opengl/openglrenderer.h
index 12b6e2a40..ce1f5d795 100644
--- a/app/render/backend/opengl/openglrenderer.h
+++ b/app/render/opengl/openglrenderer.h
@@ -28,7 +28,7 @@
#include
#include
-#include "render/backend/renderer.h"
+#include "render/renderer.h"
OLIVE_NAMESPACE_ENTER
@@ -47,11 +47,12 @@ public:
public slots:
virtual void PostInit() override;
- virtual void Destroy() override;
+ virtual void DestroyInternal() override;
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
- virtual QVariant CreateNativeTexture(OLIVE_NAMESPACE::VideoParams param, void* data = nullptr, int linesize = 0) override;
+ virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
+ virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
virtual void DestroyNativeTexture(QVariant texture) override;
@@ -59,26 +60,28 @@ public slots:
virtual void DestroyNativeShader(QVariant shader) override;
- virtual void UploadToTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) override;
+ virtual void UploadToTexture(OLIVE_NAMESPACE::Texture* texture, const void* data, int linesize) override;
- virtual void DownloadFromTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) override;
+ virtual void DownloadFromTexture(OLIVE_NAMESPACE::Texture* texture, void* data, int linesize) override;
protected slots:
virtual void Blit(QVariant shader,
OLIVE_NAMESPACE::ShaderJob job,
- OLIVE_NAMESPACE::Renderer::Texture* destination,
+ OLIVE_NAMESPACE::Texture* destination,
OLIVE_NAMESPACE::VideoParams destination_params) override;
private:
- static GLint GetInternalFormat(PixelFormat::Format format);
+ static GLint GetInternalFormat(PixelFormat::Format format, bool with_alpha);
static GLenum GetPixelType(PixelFormat::Format format);
- void AttachTextureAsDestination(OLIVE_NAMESPACE::Renderer::Texture* texture);
+ static GLenum GetPixelFormat(Texture::ChannelFormat format);
+
+ void AttachTextureAsDestination(OLIVE_NAMESPACE::Texture* texture);
void DetachTextureAsDestination();
- void PrepareInputTexture(bool bilinear);
+ void PrepareInputTexture(GLenum target, Texture::Interpolation interp);
QOpenGLContext* context_;
diff --git a/app/render/renderer.cpp b/app/render/renderer.cpp
new file mode 100644
index 000000000..ffebfa072
--- /dev/null
+++ b/app/render/renderer.cpp
@@ -0,0 +1,229 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#include "renderer.h"
+
+#include
+
+#include "common/ocioutils.h"
+#include "render/colormanager.h"
+
+OLIVE_NAMESPACE_ENTER
+
+Renderer::Renderer(QObject *parent) :
+ QObject(parent)
+{
+
+}
+
+TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, Texture::Type type, Texture::ChannelFormat channel_format, const void *data, int linesize)
+{
+ QVariant v;
+
+ if (type == Texture::k3D) {
+ v = CreateNativeTexture3D(params.effective_width(), params.effective_height(),
+ params.effective_depth(), params.format(), channel_format, data, linesize);
+ } else {
+ v = CreateNativeTexture2D(params.effective_width(), params.effective_height(), params.format(),
+ channel_format, data, linesize);
+ }
+
+ if (v.isNull()) {
+ return nullptr;
+ }
+
+ return std::make_shared(this, v, params, type);
+}
+
+TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, const void *data, int linesize)
+{
+ return CreateTexture(params, Texture::k2D, Texture::kRGBA, data, linesize);
+}
+
+void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination, bool flipped)
+{
+ BlitColorManagedInternal(color_processor, source, destination, destination->params(), flipped);
+}
+
+void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, bool flipped)
+{
+ BlitColorManagedInternal(color_processor, source, nullptr, params, flipped);
+}
+
+void Renderer::Destroy()
+{
+ color_cache_.clear();
+
+ DestroyInternal();
+}
+
+bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::ColorContext *ctx)
+{
+ ColorContext& color_ctx = *ctx;
+
+ if (color_cache_.contains(color_processor->id())) {
+ color_ctx = color_cache_.value(color_processor->id());
+ return true;
+ } else {
+ // Create shader description
+ const char* ocio_func_name = "OCIODisplay";
+ auto shader_desc = OCIO::GpuShaderDesc::CreateShaderDesc();
+ shader_desc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3);
+ shader_desc->setFunctionName(ocio_func_name);
+ shader_desc->setResourcePrefix("ocio_");
+
+ // Generate shader
+ color_processor->GetProcessor()->getDefaultGPUProcessor()->extractGpuShaderInfo(shader_desc);
+
+ QString shader_frag;
+ shader_frag.append(QStringLiteral("#version 150\n"
+ "\n"
+ "#ifdef GL_ES\n"
+ "precision highp int;\n"
+ "precision highp float;\n"
+ "#endif\n"
+ "\n"
+ "// Main texture input\n"
+ "uniform sampler2D ove_maintex;\n"
+ "\n"
+ "// Macros so OCIO's shaders work on this GLSL version\n"
+ "#define texture2D texture\n"
+ "#define texture3D texture\n"
+ "\n"
+ "// Main texture coordinate\n"
+ "in vec2 ove_texcoord;\n"
+ "\n"
+ "// Texture output\n"
+ "out vec4 fragColor;\n"));
+ shader_frag.append(shader_desc->getShaderText());
+ shader_frag.append(QStringLiteral("\n"
+ "void main() {\n"
+ " fragColor = %1(texture(ove_maintex, ove_texcoord));\n"
+ "}\n").arg(ocio_func_name));
+
+ // Try to compile shader
+ color_ctx.compiled_shader = CreateNativeShader(ShaderCode(shader_frag,
+ FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/default.vert"))));
+
+ if (color_ctx.compiled_shader.isNull()) {
+ return false;
+ }
+
+ color_ctx.lut3d_textures.resize(shader_desc->getNum3DTextures());
+ for (unsigned int i=0; igetNum3DTextures(); i++) {
+ const char* tex_name = nullptr;
+ const char* sampler_name = nullptr;
+ unsigned int edge_len = 0;
+ OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
+
+ shader_desc->get3DTexture(i, tex_name, sampler_name, edge_len, interpolation);
+
+ if (!tex_name || !*tex_name
+ || !sampler_name || !*sampler_name
+ || !edge_len) {
+ qCritical() << "3D LUT texture data is corrupted";
+ return false;
+ }
+
+ const float* values = nullptr;
+ shader_desc->get3DTextureValues(i, values);
+ if (!values) {
+ qCritical() << "3D LUT texture values are missing";
+ return false;
+ }
+
+ // Allocate 3D LUT
+ color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, PixelFormat::PIX_FMT_RGBA32F),
+ Texture::k3D, Texture::kRGB, values);
+ color_ctx.lut3d_textures[i].name = sampler_name;
+ color_ctx.lut3d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
+ }
+
+ color_ctx.lut1d_textures.resize(shader_desc->getNumTextures());
+ for (unsigned int i=0; igetNumTextures(); i++) {
+ const char* tex_name = nullptr;
+ const char* sampler_name = nullptr;
+ unsigned int width = 0, height = 0;
+ OCIO::GpuShaderDesc::TextureType channel = OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL;
+ OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
+
+ shader_desc->getTexture(i, tex_name, sampler_name, width, height, channel, interpolation);
+
+ if (!tex_name || !*tex_name
+ || !sampler_name || !*sampler_name
+ || !width) {
+ qCritical() << "1D LUT texture data is corrupted";
+ return false;
+ }
+
+ const float* values = nullptr;
+ shader_desc->getTextureValues(i, values);
+ if (!values) {
+ qCritical() << "1D LUT texture values are missing";
+ return false;
+ }
+
+ // Allocate 1D LUT
+ color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, PixelFormat::PIX_FMT_RGBA32F),
+ Texture::k2D,
+ (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? Texture::kRedOnly : Texture::kRGB,
+ values);
+ color_ctx.lut1d_textures[i].name = sampler_name;
+ color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
+ }
+
+ color_cache_.insert(color_processor->id(), color_ctx);
+
+ return true;
+ }
+}
+
+void Renderer::BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination, VideoParams params, bool flipped)
+{
+ ColorContext color_ctx;
+ if (!GetColorContext(color_processor, &color_ctx)) {
+ return;
+ }
+
+ ShaderJob job;
+ job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture));
+ foreach (const ColorContext::LUT& l, color_ctx.lut3d_textures) {
+ job.InsertValue(l.name, ShaderValue(QVariant::fromValue(l.texture), NodeParam::kTexture));
+ job.SetInterpolation(l.name, l.interpolation);
+ }
+ foreach (const ColorContext::LUT& l, color_ctx.lut1d_textures) {
+ job.InsertValue(l.name, ShaderValue(QVariant::fromValue(l.texture), NodeParam::kTexture));
+ job.SetInterpolation(l.name, l.interpolation);
+ }
+
+ if (flipped) {
+ QMatrix4x4 mat;
+ mat.scale(1, -1, 1);
+ job.SetMatrix(mat);
+ }
+
+ if (destination) {
+ BlitToTexture(color_ctx.compiled_shader, job, destination);
+ } else {
+ Blit(color_ctx.compiled_shader, job, params);
+ }
+}
+
+OLIVE_NAMESPACE_EXIT
diff --git a/app/render/backend/renderer.h b/app/render/renderer.h
similarity index 54%
rename from app/render/backend/renderer.h
rename to app/render/renderer.h
index 356299fcb..2da550fa1 100644
--- a/app/render/backend/renderer.h
+++ b/app/render/renderer.h
@@ -29,9 +29,12 @@
#include "node/node.h"
#include "render/colorprocessor.h"
#include "render/videoparams.h"
+#include "texture.h"
OLIVE_NAMESPACE_ENTER
+class ShaderJob;
+
class Renderer : public QObject
{
Q_OBJECT
@@ -40,90 +43,12 @@ public:
virtual bool Init() = 0;
- class Texture
- {
- public:
- Texture(Renderer* renderer, const QVariant& native, const VideoParams& param) :
- renderer_(renderer),
- params_(param),
- id_(native),
- meaningful_alpha_(true)
- {
- }
-
- ~Texture()
- {
- renderer_->DestroyNativeTexture(id_);
- }
-
- QVariant id() const
- {
- return id_;
- }
-
- const VideoParams& params() const
- {
- return params_;
- }
-
- void Upload(void* data, int linesize)
- {
- renderer_->UploadToTexture(this, data, linesize);
- }
-
- int width() const
- {
- return params_.width();
- }
-
- int height() const
- {
- return params_.height();
- }
-
- PixelFormat::Format format() const
- {
- return params_.format();
- }
-
- int divider() const
- {
- return params_.divider();
- }
-
- const rational& pixel_aspect_ratio() const
- {
- return params_.pixel_aspect_ratio();
- }
-
- bool has_meaningful_alpha() const
- {
- return meaningful_alpha_;
- }
-
- void set_has_meaningful_alpha(bool e)
- {
- meaningful_alpha_ = e;
- }
-
- private:
- Renderer* renderer_;
-
- VideoParams params_;
-
- QVariant id_;
-
- bool meaningful_alpha_;
-
- };
-
- using TexturePtr = std::shared_ptr;
-
- TexturePtr CreateTexture(const VideoParams& param, void* data = nullptr, int linesize = 0);
+ TexturePtr CreateTexture(const VideoParams& params, Texture::Type type, Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0);
+ TexturePtr CreateTexture(const VideoParams& params, const void *data = nullptr, int linesize = 0);
void BlitToTexture(QVariant shader,
OLIVE_NAMESPACE::ShaderJob job,
- OLIVE_NAMESPACE::Renderer::Texture* destination)
+ OLIVE_NAMESPACE::Texture* destination)
{
Blit(shader, job, destination, destination->params());
}
@@ -138,14 +63,17 @@ public:
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture* destination, bool flipped = false);
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, bool flipped = false);
+ void Destroy();
+
public slots:
virtual void PostInit() = 0;
- virtual void Destroy() = 0;
+ virtual void DestroyInternal() = 0;
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) = 0;
- virtual QVariant CreateNativeTexture(OLIVE_NAMESPACE::VideoParams param, void* data = nullptr, int linesize = 0) = 0;
+ virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) = 0;
+ virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) = 0;
virtual void DestroyNativeTexture(QVariant texture) = 0;
@@ -153,28 +81,39 @@ public slots:
virtual void DestroyNativeShader(QVariant shader) = 0;
- virtual void UploadToTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) = 0;
+ virtual void UploadToTexture(OLIVE_NAMESPACE::Texture* texture, const void* data, int linesize) = 0;
- virtual void DownloadFromTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) = 0;
+ virtual void DownloadFromTexture(OLIVE_NAMESPACE::Texture* texture, void* data, int linesize) = 0;
protected slots:
virtual void Blit(QVariant shader,
OLIVE_NAMESPACE::ShaderJob job,
- OLIVE_NAMESPACE::Renderer::Texture* destination,
+ OLIVE_NAMESPACE::Texture* destination,
OLIVE_NAMESPACE::VideoParams destination_params) = 0;
private:
struct ColorContext {
- QVariant shader;
- TexturePtr lut;
+ struct LUT {
+ TexturePtr texture;
+ Texture::Interpolation interpolation;
+ QString name;
+ };
+
+ QVariant compiled_shader;
+ QVector lut3d_textures;
+ QVector lut1d_textures;
+
};
+ bool GetColorContext(ColorProcessorPtr color_processor, ColorContext* ctx);
+
+ void BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source,
+ Texture* destination, VideoParams params, bool flipped);
+
QHash color_cache_;
};
OLIVE_NAMESPACE_EXIT
-Q_DECLARE_METATYPE(OLIVE_NAMESPACE::Renderer::TexturePtr);
-
#endif // RENDERCONTEXT_H
diff --git a/app/render/backend/rendererthreadwrapper.cpp b/app/render/rendererthreadwrapper.cpp
similarity index 63%
rename from app/render/backend/rendererthreadwrapper.cpp
rename to app/render/rendererthreadwrapper.cpp
index 8b024054e..2024fd377 100644
--- a/app/render/backend/rendererthreadwrapper.cpp
+++ b/app/render/rendererthreadwrapper.cpp
@@ -54,10 +54,10 @@ void RendererThreadWrapper::PostInit()
// Do nothing
}
-void RendererThreadWrapper::Destroy()
+void RendererThreadWrapper::DestroyInternal()
{
if (thread_) {
- QMetaObject::invokeMethod(inner_, "Destroy", Qt::BlockingQueuedConnection);
+ QMetaObject::invokeMethod(inner_, "DestroyInternal", Qt::BlockingQueuedConnection);
inner_ = nullptr;
thread_->quit();
@@ -76,14 +76,34 @@ void RendererThreadWrapper::ClearDestination(double r, double g, double b, doubl
Q_ARG(double, a));
}
-QVariant RendererThreadWrapper::CreateNativeTexture(VideoParams param, void *data, int linesize)
+QVariant RendererThreadWrapper::CreateNativeTexture2D(int width, int height, PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void *data, int linesize)
{
QVariant v;
- QMetaObject::invokeMethod(inner_, "CreateNativeTexture", Qt::BlockingQueuedConnection,
+ QMetaObject::invokeMethod(inner_, "CreateNativeTexture2D", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QVariant, v),
- OLIVE_NS_ARG(VideoParams, param),
- Q_ARG(void*, data),
+ Q_ARG(int, width),
+ Q_ARG(int, height),
+ OLIVE_NS_ARG(PixelFormat::Format, format),
+ OLIVE_NS_ARG(Texture::ChannelFormat, channel_format),
+ Q_ARG(const void*, data),
+ Q_ARG(int, linesize));
+
+ return v;
+}
+
+QVariant RendererThreadWrapper::CreateNativeTexture3D(int width, int height, int depth, PixelFormat::Format format, Texture::ChannelFormat channel_format, const void *data, int linesize)
+{
+ QVariant v;
+
+ QMetaObject::invokeMethod(inner_, "CreateNativeTexture3D", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(QVariant, v),
+ Q_ARG(int, width),
+ Q_ARG(int, height),
+ Q_ARG(int, depth),
+ OLIVE_NS_ARG(PixelFormat::Format, format),
+ OLIVE_NS_ARG(Texture::ChannelFormat, channel_format),
+ Q_ARG(const void*, data),
Q_ARG(int, linesize));
return v;
@@ -112,30 +132,28 @@ void RendererThreadWrapper::DestroyNativeShader(QVariant shader)
Q_ARG(QVariant, shader));
}
-void RendererThreadWrapper::UploadToTexture(Renderer::Texture *texture, void *data, int linesize)
+void RendererThreadWrapper::UploadToTexture(Texture *texture, const void *data, int linesize)
{
QMetaObject::invokeMethod(inner_, "UploadToTexture", Qt::BlockingQueuedConnection,
- OLIVE_NS_ARG(Renderer::Texture*, texture),
- Q_ARG(void*, data),
+ OLIVE_NS_ARG(Texture*, texture),
+ Q_ARG(const void*, data),
Q_ARG(int, linesize));
}
-void RendererThreadWrapper::DownloadFromTexture(Renderer::Texture *texture, void *data, int linesize)
+void RendererThreadWrapper::DownloadFromTexture(Texture *texture, void *data, int linesize)
{
QMetaObject::invokeMethod(inner_, "DownloadFromTexture", Qt::BlockingQueuedConnection,
- OLIVE_NS_ARG(Renderer::Texture*, texture),
+ OLIVE_NS_ARG(Texture*, texture),
Q_ARG(void*, data),
Q_ARG(int, linesize));
}
-void RendererThreadWrapper::Blit(QVariant shader, ShaderJob job, Renderer::Texture *destination, VideoParams destination_params)
+void RendererThreadWrapper::Blit(QVariant shader, ShaderJob job, Texture *destination, VideoParams destination_params)
{
- Renderer::TexturePtr tex;
-
QMetaObject::invokeMethod(inner_, "Blit", Qt::BlockingQueuedConnection,
Q_ARG(QVariant, shader),
OLIVE_NS_ARG(ShaderJob, job),
- OLIVE_NS_ARG(Renderer::Texture*, destination),
+ OLIVE_NS_ARG(Texture*, destination),
OLIVE_NS_ARG(VideoParams, destination_params));
}
diff --git a/app/render/backend/rendererthreadwrapper.h b/app/render/rendererthreadwrapper.h
similarity index 69%
rename from app/render/backend/rendererthreadwrapper.h
rename to app/render/rendererthreadwrapper.h
index 95445bc25..a3b9e5cda 100644
--- a/app/render/backend/rendererthreadwrapper.h
+++ b/app/render/rendererthreadwrapper.h
@@ -43,11 +43,12 @@ public:
public slots:
virtual void PostInit() override;
- virtual void Destroy() override;
+ virtual void DestroyInternal() override;
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
- virtual QVariant CreateNativeTexture(OLIVE_NAMESPACE::VideoParams param, void* data = nullptr, int linesize = 0) override;
+ virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
+ virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
virtual void DestroyNativeTexture(QVariant texture) override;
@@ -55,14 +56,14 @@ public slots:
virtual void DestroyNativeShader(QVariant shader) override;
- virtual void UploadToTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) override;
+ virtual void UploadToTexture(OLIVE_NAMESPACE::Texture* texture, const void* data, int linesize) override;
- virtual void DownloadFromTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) override;
+ virtual void DownloadFromTexture(OLIVE_NAMESPACE::Texture* texture, void* data, int linesize) override;
protected slots:
virtual void Blit(QVariant shader,
OLIVE_NAMESPACE::ShaderJob job,
- OLIVE_NAMESPACE::Renderer::Texture* destination,
+ OLIVE_NAMESPACE::Texture* destination,
OLIVE_NAMESPACE::VideoParams destination_params) override;
private:
diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp
index 2aa648fd5..de9b4b408 100644
--- a/app/render/rendermanager.cpp
+++ b/app/render/rendermanager.cpp
@@ -27,8 +27,8 @@
#include "config/config.h"
#include "core.h"
-#include "render/backend/opengl/openglrenderer.h"
-#include "render/backend/rendererthreadwrapper.h"
+#include "render/opengl/openglrenderer.h"
+#include "render/rendererthreadwrapper.h"
#include "renderprocessor.h"
#include "task/conform/conform.h"
#include "task/taskmanager.h"
diff --git a/app/render/rendermanager.h b/app/render/rendermanager.h
index f170e2aa2..0f73ca53d 100644
--- a/app/render/rendermanager.h
+++ b/app/render/rendermanager.h
@@ -29,7 +29,7 @@
#include "node/graph.h"
#include "node/output/viewer/viewer.h"
#include "node/traverser.h"
-#include "render/backend/renderer.h"
+#include "render/renderer.h"
#include "rendercache.h"
#include "stillimagecache.h"
#include "threading/threadpool.h"
diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp
index 34b612ec6..6587c6d0c 100644
--- a/app/render/renderprocessor.cpp
+++ b/app/render/renderprocessor.cpp
@@ -54,7 +54,7 @@ void RenderProcessor::Run()
NodeValueTable table = ProcessInput(viewer->texture_input(),
TimeRange(time, time + viewer->video_params().time_base()));
- Renderer::TexturePtr texture = table.Get(NodeParam::kTexture).value();
+ TexturePtr texture = table.Get(NodeParam::kTexture).value();
VideoParams frame_params = viewer->video_params();
@@ -222,7 +222,7 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const TrackOutput *track, con
QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &input_time)
{
- Renderer::TexturePtr value = nullptr;
+ TexturePtr value = nullptr;
// Check the still frame cache. On large frames such as high resolution still images, uploading
// and color managing them for every frame is a waste of time, so we implement a small cache here
@@ -285,9 +285,9 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
if (frame) {
// Return a texture from the derived class
- Renderer::TexturePtr unmanaged_texture = render_ctx_->CreateTexture(frame->video_params(),
- frame->data(),
- frame->linesize_pixels());
+ TexturePtr unmanaged_texture = render_ctx_->CreateTexture(frame->video_params(),
+ frame->data(),
+ frame->linesize_pixels());
// We convert to our rendering pixel format, since that will always be float-based which
// is necessary for correct color conversion
@@ -361,7 +361,7 @@ QVariant RenderProcessor::ProcessShader(const Node *node, const TimeRange &range
const VideoParams& video_params = Node::ValueToPtr(ticket_->property("viewer"))->video_params();
- Renderer::TexturePtr destination = render_ctx_->CreateTexture(video_params);
+ TexturePtr destination = render_ctx_->CreateTexture(video_params);
// Run shader
render_ctx_->BlitToTexture(shader, job, destination.get());
@@ -423,9 +423,9 @@ QVariant RenderProcessor::ProcessFrameGeneration(const Node *node, const Generat
node->GenerateFrame(frame, job);
- Renderer::TexturePtr texture = render_ctx_->CreateTexture(frame->video_params(),
- frame->data(),
- frame->linesize_pixels());
+ TexturePtr texture = render_ctx_->CreateTexture(frame->video_params(),
+ frame->data(),
+ frame->linesize_pixels());
texture->set_has_meaningful_alpha(job.GetAlphaChannelRequired());
@@ -456,7 +456,7 @@ QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time)
qDebug() << "Using cached frame!";
- Renderer::TexturePtr texture = render_ctx_->CreateTexture(f->video_params(), f->data(), f->linesize_pixels());
+ TexturePtr texture = render_ctx_->CreateTexture(f->video_params(), f->data(), f->linesize_pixels());
return QVariant::fromValue(texture);
} else {
qDebug() << "Not using cached frame because frame is null";
diff --git a/app/render/renderprocessor.h b/app/render/renderprocessor.h
index e2be6eb61..ed5bf38ae 100644
--- a/app/render/renderprocessor.h
+++ b/app/render/renderprocessor.h
@@ -22,7 +22,7 @@
#define RENDERPROCESSOR_H
#include "node/traverser.h"
-#include "render/backend/renderer.h"
+#include "render/renderer.h"
#include "rendercache.h"
#include "stillimagecache.h"
#include "threading/threadticket.h"
diff --git a/app/render/shadercode.h b/app/render/shadercode.h
new file mode 100644
index 000000000..59d5a59de
--- /dev/null
+++ b/app/render/shadercode.h
@@ -0,0 +1,62 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#ifndef SHADERCODE_H
+#define SHADERCODE_H
+
+#include "common/filefunctions.h"
+
+OLIVE_NAMESPACE_ENTER
+
+class ShaderCode {
+public:
+ ShaderCode(const QString& frag_code, const QString& vert_code) :
+ frag_code_(frag_code),
+ vert_code_(vert_code)
+ {
+ if (frag_code_.isEmpty()) {
+ frag_code_ = FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/default.frag"));
+ }
+
+ if (vert_code_.isEmpty()) {
+ vert_code_ = FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/default.vert"));
+ }
+ }
+
+ const QString& frag_code() const
+ {
+ return frag_code_;
+ }
+
+ const QString& vert_code() const
+ {
+ return vert_code_;
+ }
+
+private:
+ QString frag_code_;
+
+ QString vert_code_;
+
+};
+
+OLIVE_NAMESPACE_EXIT
+
+#endif // SHADERCODE_H
diff --git a/app/render/shaderinfo.h b/app/render/shaderinfo.h
deleted file mode 100644
index 3dc69f681..000000000
--- a/app/render/shaderinfo.h
+++ /dev/null
@@ -1,249 +0,0 @@
-#ifndef SHADERINFO_H
-#define SHADERINFO_H
-
-#include
-
-#include "codec/samplebuffer.h"
-#include "common/filefunctions.h"
-#include "node/input.h"
-#include "node/inputarray.h"
-#include "node/value.h"
-
-OLIVE_NAMESPACE_ENTER
-
-using NodeValueMap = QHash;
-
-class AcceleratedJob {
-public:
- AcceleratedJob() = default;
-
- ShaderValue GetValue(NodeInput* input) const
- {
- return value_map_.value(input->id());
- }
-
- ShaderValue GetValue(const QString& input) const
- {
- return value_map_.value(input);
- }
-
- void InsertValue(NodeInput* input, NodeValueDatabase& value)
- {
- ShaderValue shader_val;
-
- shader_val.type = input->data_type();
- shader_val.array = input->IsArray();
-
- if (input->IsArray()) {
- NodeInputArray* array = static_cast(input);
- QVector values(array->GetSize());
-
- for (int j=0;jGetSize();j++) {
- NodeInput* subparam = array->At(j);
-
- values[j] = value[subparam].Take(subparam->data_type());
- }
-
- shader_val.data = QVariant::fromValue(values);
- } else {
- NodeValue node_val = value[input].TakeWithMeta(input->data_type());
- shader_val.data = node_val.data();
- shader_val.tag = node_val.tag();
- }
-
- InsertValue(input->id(), shader_val);
- }
-
- void InsertValue(const QString& input, const ShaderValue& value)
- {
- value_map_.insert(input, value);
- }
-
- void InsertValue(NodeInput* input, const ShaderValue& value)
- {
- value_map_.insert(input->id(), value);
- }
-
- void InsertValue(NodeInput* input, const NodeValue& value)
- {
- ShaderValue s(value.data(), value.type());
- s.tag = value.tag();
- value_map_.insert(input->id(), s);
- }
-
- const NodeValueMap &GetValues() const
- {
- return value_map_;
- }
-
-private:
- NodeValueMap value_map_;
-
-};
-
-class SampleJob : public AcceleratedJob {
-public:
- SampleJob()
- {
- samples_ = nullptr;
- }
-
- SampleJob(const NodeValue& value)
- {
- samples_ = value.data().value();
- }
-
- SampleJob(NodeInput* from, NodeValueDatabase& db)
- {
- samples_ = db[from].Take(NodeParam::kSamples).value();
- }
-
- SampleBufferPtr samples() const
- {
- return samples_;
- }
-
- bool HasSamples() const
- {
- return samples_ && samples_->is_allocated();
- }
-
-private:
- SampleBufferPtr samples_;
-
-};
-
-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;
- bilinear_ = true;
- }
-
- const QMatrix4x4& GetMatrix() const
- {
- return matrix_;
- }
-
- void SetMatrix(const QMatrix4x4& matrix)
- {
- matrix_ = matrix;
- }
-
- const QString& GetShaderID() const
- {
- return shader_id_;
- }
-
- void SetShaderID(const QString& id)
- {
- shader_id_ = id;
- }
-
- void SetIterations(int iterations, NodeInput* iterative_input)
- {
- SetIterations(iterations, iterative_input->id());
- }
-
- void SetIterations(int iterations, const QString& iterative_input)
- {
- iterations_ = iterations;
- iterative_input_ = iterative_input;
- }
-
- int GetIterationCount() const
- {
- return iterations_;
- }
-
- const QString& GetIterativeInput() const
- {
- return iterative_input_;
- }
-
- bool GetBilinearFiltering() const
- {
- return bilinear_;
- }
-
- void SetBilinearFiltering(bool e)
- {
- bilinear_ = e;
- }
-
-private:
- QString shader_id_;
-
- int iterations_;
-
- QString iterative_input_;
-
- bool bilinear_;
-
- QMatrix4x4 matrix_;
-
-};
-
-class ShaderCode {
-public:
- ShaderCode(const QString& frag_code, const QString& vert_code) :
- frag_code_(frag_code),
- vert_code_(vert_code)
- {
- if (frag_code_.isEmpty()) {
- frag_code_ = FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/default.frag"));
- }
-
- if (vert_code_.isEmpty()) {
- vert_code_ = FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/default.vert"));
- }
- }
-
- const QString& frag_code() const
- {
- return frag_code_;
- }
-
- const QString& vert_code() const
- {
- return vert_code_;
- }
-
-private:
- QString frag_code_;
-
- QString vert_code_;
-
-};
-
-OLIVE_NAMESPACE_EXIT
-
-Q_DECLARE_METATYPE(OLIVE_NAMESPACE::ShaderJob)
-Q_DECLARE_METATYPE(OLIVE_NAMESPACE::SampleJob)
-Q_DECLARE_METATYPE(OLIVE_NAMESPACE::GenerateJob)
-
-#endif // SHADERINFO_H
diff --git a/app/render/shadervalue.h b/app/render/shadervalue.h
index 5d4e8dbfb..dd8412b30 100644
--- a/app/render/shadervalue.h
+++ b/app/render/shadervalue.h
@@ -48,6 +48,8 @@ struct ShaderValue
};
+using NodeValueMap = QHash;
+
OLIVE_NAMESPACE_EXIT
#endif // SHADERVALUE_H
diff --git a/app/render/stillimagecache.h b/app/render/stillimagecache.h
index 9a0b17cb7..efd7ac515 100644
--- a/app/render/stillimagecache.h
+++ b/app/render/stillimagecache.h
@@ -5,7 +5,7 @@
#include "common/rational.h"
#include "project/item/footage/stream.h"
-#include "render/backend/renderer.h"
+#include "render/texture.h"
OLIVE_NAMESPACE_ENTER
@@ -13,7 +13,7 @@ class StillImageCache
{
public:
struct Entry {
- Renderer::TexturePtr texture;
+ TexturePtr texture;
StreamPtr stream;
QString colorspace;
bool alpha_is_associated;
diff --git a/app/render/texture.cpp b/app/render/texture.cpp
new file mode 100644
index 000000000..66bd9dc77
--- /dev/null
+++ b/app/render/texture.cpp
@@ -0,0 +1,39 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#include "texture.h"
+
+#include "renderer.h"
+
+OLIVE_NAMESPACE_ENTER
+
+const Texture::Interpolation Texture::kDefaultInterpolation = Texture::kMipmappedLinear;
+
+Texture::~Texture()
+{
+ renderer_->DestroyNativeTexture(id_);
+}
+
+void Texture::Upload(void *data, int linesize)
+{
+ renderer_->UploadToTexture(this, data, linesize);
+}
+
+OLIVE_NAMESPACE_EXIT
diff --git a/app/render/texture.h b/app/render/texture.h
new file mode 100644
index 000000000..abf4e7e2e
--- /dev/null
+++ b/app/render/texture.h
@@ -0,0 +1,134 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 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 .
+
+***/
+
+#ifndef RENDERTEXTURE_H
+#define RENDERTEXTURE_H
+
+#include "render/videoparams.h"
+
+OLIVE_NAMESPACE_ENTER
+
+class Renderer;
+
+class Texture
+{
+public:
+ enum Type {
+ k2D,
+ k3D
+ };
+
+ enum Interpolation {
+ kNearest,
+ kLinear,
+ kMipmappedLinear
+ };
+
+ enum ChannelFormat {
+ kRGBA,
+ kRGB,
+ kRedOnly
+ };
+
+ static const Interpolation kDefaultInterpolation;
+
+ Texture(Renderer* renderer, const QVariant& native, const VideoParams& param, Type type) :
+ renderer_(renderer),
+ params_(param),
+ id_(native),
+ meaningful_alpha_(true),
+ type_(type)
+ {
+ }
+
+ ~Texture();
+
+ QVariant id() const
+ {
+ return id_;
+ }
+
+ const VideoParams& params() const
+ {
+ return params_;
+ }
+
+ void Upload(void* data, int linesize);
+
+ int width() const
+ {
+ return params_.width();
+ }
+
+ int height() const
+ {
+ return params_.height();
+ }
+
+ PixelFormat::Format format() const
+ {
+ return params_.format();
+ }
+
+ int divider() const
+ {
+ return params_.divider();
+ }
+
+ const rational& pixel_aspect_ratio() const
+ {
+ return params_.pixel_aspect_ratio();
+ }
+
+ bool has_meaningful_alpha() const
+ {
+ return meaningful_alpha_;
+ }
+
+ void set_has_meaningful_alpha(bool e)
+ {
+ meaningful_alpha_ = e;
+ }
+
+ Type type() const
+ {
+ return type_;
+ }
+
+private:
+ Renderer* renderer_;
+
+ VideoParams params_;
+
+ QVariant id_;
+
+ bool meaningful_alpha_;
+
+ Type type_;
+
+};
+
+using TexturePtr = std::shared_ptr;
+
+OLIVE_NAMESPACE_EXIT
+
+Q_DECLARE_METATYPE(OLIVE_NAMESPACE::TexturePtr);
+
+#endif // RENDERTEXTURE_H
diff --git a/app/render/videoparams.cpp b/app/render/videoparams.cpp
index 00167c63a..c9609701e 100644
--- a/app/render/videoparams.cpp
+++ b/app/render/videoparams.cpp
@@ -62,6 +62,7 @@ const QVector VideoParams::kStandardPixelAspects = {
VideoParams::VideoParams() :
width_(0),
height_(0),
+ depth_(0),
format_(PixelFormat::PIX_FMT_INVALID),
interlacing_(Interlacing::kInterlaceNone)
{
@@ -70,6 +71,20 @@ VideoParams::VideoParams() :
VideoParams::VideoParams(const int &width, const int &height, const PixelFormat::Format &format, const rational& pixel_aspect_ratio, const Interlacing &interlacing, const int& divider) :
width_(width),
height_(height),
+ depth_(0),
+ format_(format),
+ pixel_aspect_ratio_(pixel_aspect_ratio),
+ interlacing_(interlacing),
+ divider_(divider)
+{
+ calculate_effective_size();
+ validate_pixel_aspect_ratio();
+}
+
+VideoParams::VideoParams(const int &width, const int &height, const int &depth, const PixelFormat::Format &format, const rational &pixel_aspect_ratio, const VideoParams::Interlacing &interlacing, const int ÷r) :
+ width_(width),
+ height_(height),
+ depth_(depth),
format_(format),
pixel_aspect_ratio_(pixel_aspect_ratio),
interlacing_(interlacing),
@@ -82,6 +97,7 @@ VideoParams::VideoParams(const int &width, const int &height, const PixelFormat:
VideoParams::VideoParams(const int &width, const int &height, const rational &time_base, const PixelFormat::Format &format, const rational& pixel_aspect_ratio, const Interlacing &interlacing, const int ÷r) :
width_(width),
height_(height),
+ depth_(0),
time_base_(time_base),
format_(format),
pixel_aspect_ratio_(pixel_aspect_ratio),
@@ -147,6 +163,7 @@ void VideoParams::calculate_effective_size()
{
effective_width_ = GetScaledDimension(width(), divider_);
effective_height_ = GetScaledDimension(height(), divider_);
+ effective_depth_ = GetScaledDimension(depth(), divider_);
}
void VideoParams::validate_pixel_aspect_ratio()
@@ -196,7 +213,7 @@ QString VideoParams::FormatPixelAspectRatioString(const QString &format, const r
int VideoParams::GetScaledDimension(int dim, int divider)
{
- return qCeil(dim / divider * 0.5) * 2;
+ return dim / divider;
}
OLIVE_NAMESPACE_EXIT
diff --git a/app/render/videoparams.h b/app/render/videoparams.h
index dab019254..3d7102e9f 100644
--- a/app/render/videoparams.h
+++ b/app/render/videoparams.h
@@ -39,6 +39,10 @@ public:
VideoParams(const int& width, const int& height, const PixelFormat::Format& format,
const rational& pixel_aspect_ratio = 1,
const Interlacing& interlacing = kInterlaceNone, const int& divider = 1);
+ VideoParams(const int& width, const int& height, const int& depth,
+ const PixelFormat::Format& format,
+ const rational& pixel_aspect_ratio = 1,
+ const Interlacing& interlacing = kInterlaceNone, const int& divider = 1);
VideoParams(const int& width, const int& height, const rational& time_base,
const PixelFormat::Format& format, const rational& pixel_aspect_ratio = 1,
const Interlacing& interlacing = kInterlaceNone, const int& divider = 1);
@@ -65,6 +69,17 @@ public:
calculate_effective_size();
}
+ int depth() const
+ {
+ return depth_;
+ }
+
+ void set_depth(int depth)
+ {
+ depth_ = depth;
+ calculate_effective_size();
+ }
+
const rational& time_base() const
{
return time_base_;
@@ -96,6 +111,11 @@ public:
return effective_height_;
}
+ int effective_depth() const
+ {
+ return effective_depth_;
+ }
+
PixelFormat::Format format() const
{
return format_;
@@ -162,6 +182,7 @@ private:
int width_;
int height_;
+ int depth_;
rational time_base_;
PixelFormat::Format format_;
@@ -173,6 +194,7 @@ private:
int divider_;
int effective_width_;
int effective_height_;
+ int effective_depth_;
};
OLIVE_NAMESPACE_EXIT
diff --git a/app/widget/manageddisplay/manageddisplay.cpp b/app/widget/manageddisplay/manageddisplay.cpp
index cd0636b6d..ce1528f7b 100644
--- a/app/widget/manageddisplay/manageddisplay.cpp
+++ b/app/widget/manageddisplay/manageddisplay.cpp
@@ -23,7 +23,7 @@
#include
#include
-#include "render/backend/opengl/openglrenderer.h"
+#include "render/opengl/openglrenderer.h"
#include "render/rendermanager.h"
OLIVE_NAMESPACE_ENTER
diff --git a/app/widget/manageddisplay/manageddisplay.h b/app/widget/manageddisplay/manageddisplay.h
index 55da88103..86f82113a 100644
--- a/app/widget/manageddisplay/manageddisplay.h
+++ b/app/widget/manageddisplay/manageddisplay.h
@@ -23,8 +23,8 @@
#include
-#include "render/backend/renderer.h"
#include "render/colormanager.h"
+#include "render/renderer.h"
#include "widget/menu/menu.h"
OLIVE_NAMESPACE_ENTER
diff --git a/app/widget/scope/histogram/histogram.cpp b/app/widget/scope/histogram/histogram.cpp
index aed0d6988..87def5cc3 100644
--- a/app/widget/scope/histogram/histogram.cpp
+++ b/app/widget/scope/histogram/histogram.cpp
@@ -62,7 +62,7 @@ ShaderCode HistogramScope::GenerateShaderCode()
FileFunctions::ReadFileAsString(":/shaders/default.vert"));
}
-void HistogramScope::DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeline)
+void HistogramScope::DrawScope(TexturePtr managed_tex, QVariant pipeline)
{
float histogram_scale = 0.80f;
// This value is eyeballed for usefulness. Until we have a geometry
diff --git a/app/widget/scope/histogram/histogram.h b/app/widget/scope/histogram/histogram.h
index d0ab83958..30895f93d 100644
--- a/app/widget/scope/histogram/histogram.h
+++ b/app/widget/scope/histogram/histogram.h
@@ -42,11 +42,11 @@ protected:
virtual ShaderCode GenerateShaderCode() override;
QVariant CreateSecondaryShader();
- virtual void DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeline) override;
+ virtual void DrawScope(TexturePtr managed_tex, QVariant pipeline) override;
private:
QVariant pipeline_secondary_;
- Renderer::TexturePtr texture_row_sums_;
+ TexturePtr texture_row_sums_;
};
diff --git a/app/widget/scope/scopebase/scopebase.cpp b/app/widget/scope/scopebase/scopebase.cpp
index 89644e589..76a717112 100644
--- a/app/widget/scope/scopebase/scopebase.cpp
+++ b/app/widget/scope/scopebase/scopebase.cpp
@@ -48,7 +48,7 @@ void ScopeBase::showEvent(QShowEvent* e)
UploadTextureFromBuffer();
}
-void ScopeBase::DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeline)
+void ScopeBase::DrawScope(TexturePtr managed_tex, QVariant pipeline)
{
ShaderJob job;
diff --git a/app/widget/scope/scopebase/scopebase.h b/app/widget/scope/scopebase/scopebase.h
index 8cde613f8..2bcd415c5 100644
--- a/app/widget/scope/scopebase/scopebase.h
+++ b/app/widget/scope/scopebase/scopebase.h
@@ -54,16 +54,16 @@ protected:
*
* Override this if your sub-class scope needs extra drawing.
*/
- virtual void DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeline);
+ virtual void DrawScope(TexturePtr managed_tex, QVariant pipeline);
private:
void UploadTextureFromBuffer();
QVariant pipeline_;
- Renderer::TexturePtr texture_;
+ TexturePtr texture_;
- Renderer::TexturePtr managed_tex_;
+ TexturePtr managed_tex_;
Frame* buffer_;
diff --git a/app/widget/scope/waveform/waveform.cpp b/app/widget/scope/waveform/waveform.cpp
index 3f9f85afc..9abd47458 100644
--- a/app/widget/scope/waveform/waveform.cpp
+++ b/app/widget/scope/waveform/waveform.cpp
@@ -48,7 +48,7 @@ ShaderCode WaveformScope::GenerateShaderCode()
FileFunctions::ReadFileAsString(":/shaders/rgbwaveform.vert"));
}
-void WaveformScope::DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeline)
+void WaveformScope::DrawScope(TexturePtr managed_tex, QVariant pipeline)
{
float waveform_scale = 0.80f;
diff --git a/app/widget/scope/waveform/waveform.h b/app/widget/scope/waveform/waveform.h
index 2640f9cf3..687d5b038 100644
--- a/app/widget/scope/waveform/waveform.h
+++ b/app/widget/scope/waveform/waveform.h
@@ -36,7 +36,7 @@ public:
protected:
virtual ShaderCode GenerateShaderCode() override;
- virtual void DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeline) override;
+ virtual void DrawScope(TexturePtr managed_tex, QVariant pipeline) override;
};
diff --git a/app/widget/viewer/viewerdisplay.h b/app/widget/viewer/viewerdisplay.h
index d61d16c20..a8d8b3ade 100644
--- a/app/widget/viewer/viewerdisplay.h
+++ b/app/widget/viewer/viewerdisplay.h
@@ -211,7 +211,7 @@ private:
/**
* @brief Internal reference to the OpenGL texture to draw. Set in SetTexture() and used in paintGL().
*/
- Renderer::TexturePtr texture_;
+ TexturePtr texture_;
/**
* @brief Translation only matrix (defaults to identity).