restored previous renderer iteration for porting
This commit is contained in:
@@ -8,10 +8,7 @@
|
||||
#include "project/item/footage/footage.h"
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
VideoInput::VideoInput() :
|
||||
color_processor_(nullptr),
|
||||
pipeline_(nullptr),
|
||||
ocio_texture_(0)
|
||||
VideoInput::VideoInput()
|
||||
{
|
||||
matrix_input_ = new NodeInput("matrix_in");
|
||||
matrix_input_->set_data_type(NodeInput::kMatrix);
|
||||
@@ -45,14 +42,6 @@ QString VideoInput::Description()
|
||||
void VideoInput::Release()
|
||||
{
|
||||
MediaInput::Release();
|
||||
|
||||
internal_tex_.Destroy();
|
||||
color_processor_ = nullptr;
|
||||
pipeline_ = nullptr;
|
||||
|
||||
if (ocio_texture_ != 0) {
|
||||
ocio_ctx_->functions()->glDeleteTextures(1, &ocio_texture_);
|
||||
}
|
||||
}
|
||||
|
||||
NodeInput *VideoInput::matrix_input()
|
||||
|
||||
@@ -31,5 +31,9 @@ set(OLIVE_SOURCES
|
||||
render/backend/videorendererdownloadthread.cpp
|
||||
render/backend/videorendererprocessthread.h
|
||||
render/backend/videorendererprocessthread.cpp
|
||||
render/backend/videorendererthreadbase.h
|
||||
render/backend/videorendererthreadbase.cpp
|
||||
render/backend/renderinstance.h
|
||||
render/backend/renderinstance.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -4,3 +4,9 @@ AudioRenderBackend::AudioRenderBackend()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AudioRenderBackend::InvalidateCache(const rational &start_range, const rational &end_range)
|
||||
{
|
||||
Q_UNUSED(start_range)
|
||||
Q_UNUSED(end_range)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "openglshader.h"
|
||||
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
OpenGLShader::OpenGLShader()
|
||||
{
|
||||
|
||||
@@ -17,6 +19,117 @@ OpenGLShaderPtr OpenGLShader::CreateDefault(const QString &function_name, const
|
||||
return program;
|
||||
}
|
||||
|
||||
// copied from source code to OCIODisplay
|
||||
const int OCIO_LUT3D_EDGE_SIZE = 32;
|
||||
|
||||
// copied from source code to OCIODisplay, expanded from 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE
|
||||
const int OCIO_NUM_3D_ENTRIES = 98304;
|
||||
|
||||
OpenGLShaderPtr OpenGLShader::CreateOCIO(QOpenGLContext* ctx,
|
||||
GLuint& lut_texture,
|
||||
OCIO::ConstProcessorRcPtr processor,
|
||||
bool alpha_is_associated)
|
||||
{
|
||||
|
||||
QOpenGLExtraFunctions* xf = ctx->extraFunctions();
|
||||
|
||||
// Create LUT texture
|
||||
xf->glGenTextures(1, &lut_texture);
|
||||
|
||||
// Bind LUT
|
||||
xf->glBindTexture(GL_TEXTURE_3D, lut_texture);
|
||||
|
||||
// Set texture parameters
|
||||
xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Allocate storage for texture
|
||||
xf->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
|
||||
OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE,
|
||||
0, GL_RGB,GL_FLOAT, nullptr);
|
||||
|
||||
//
|
||||
// SET UP GLSL SHADER
|
||||
//
|
||||
|
||||
OCIO::GpuShaderDesc shaderDesc;
|
||||
const char* ocio_func_name = "OCIODisplay";
|
||||
shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
|
||||
shaderDesc.setFunctionName(ocio_func_name);
|
||||
shaderDesc.setLut3DEdgeLen(OCIO_LUT3D_EDGE_SIZE);
|
||||
|
||||
//
|
||||
// COMPUTE 3D LUT
|
||||
//
|
||||
|
||||
GLfloat* ocio_lut_data = new GLfloat[OCIO_NUM_3D_ENTRIES];
|
||||
processor->getGpuLut3D(ocio_lut_data, shaderDesc);
|
||||
|
||||
// Upload LUT data to texture
|
||||
xf->glTexSubImage3D(GL_TEXTURE_3D, 0,
|
||||
0, 0, 0,
|
||||
OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE,
|
||||
GL_RGB, GL_FLOAT, ocio_lut_data);
|
||||
|
||||
delete [] ocio_lut_data;
|
||||
|
||||
// Create OCIO shader code
|
||||
QString shader_text(processor->getGpuShaderText(shaderDesc));
|
||||
|
||||
QString shader_call;
|
||||
|
||||
// Enforce alpha association
|
||||
if (alpha_is_associated) {
|
||||
|
||||
// If alpha is already associated, we'll need to disassociate and reassociate
|
||||
shader_text.append("\n");
|
||||
|
||||
QString disassociate_func_name = "disassoc";
|
||||
shader_text.append(CodeAlphaDisassociate(disassociate_func_name));
|
||||
|
||||
QString reassociate_func_name = "reassoc";
|
||||
shader_text.append(CodeAlphaReassociate(reassociate_func_name));
|
||||
|
||||
// Make OCIO call pass through disassociate and reassociate function
|
||||
shader_call = QString("%3(%1(%2(col), tex2));").arg(ocio_func_name,
|
||||
disassociate_func_name,
|
||||
reassociate_func_name);
|
||||
|
||||
} else {
|
||||
|
||||
// If alpha is not already associated, we can just associate after OCIO
|
||||
|
||||
// Add associate function
|
||||
QString associate_func_name = "assoc";
|
||||
shader_text.append(CodeAlphaAssociate(associate_func_name));
|
||||
|
||||
// Make OCIO call pass through associate function
|
||||
shader_call = QString("%2(%1(col, tex2));").arg(ocio_func_name, associate_func_name);
|
||||
|
||||
}
|
||||
|
||||
// Add process() function, which GetPipeline() will call if specified
|
||||
QString process_function_name = "process";
|
||||
shader_text.append(QString("\n"
|
||||
"uniform sampler3D tex2;\n"
|
||||
"\n"
|
||||
"vec4 %2(vec4 col) {\n"
|
||||
" return %1\n"
|
||||
"}\n").arg(shader_call, process_function_name));
|
||||
|
||||
|
||||
// Get pipeline-based shader to inject OCIO shader into
|
||||
OpenGLShaderPtr shader = OpenGLShader::CreateDefault(process_function_name, shader_text);
|
||||
|
||||
// Release LUT
|
||||
xf->glBindTexture(GL_TEXTURE_3D, 0);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
QString OpenGLShader::CodeDefaultFragment(const QString &function_name, const QString &shader_code)
|
||||
{
|
||||
QString frag_code = QStringLiteral("#version 110\n"
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include <memory>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
|
||||
class OpenGLShader;
|
||||
using OpenGLShaderPtr = std::shared_ptr<OpenGLShader>;
|
||||
|
||||
@@ -14,6 +17,11 @@ public:
|
||||
static OpenGLShaderPtr CreateDefault(const QString &function_name = QString(),
|
||||
const QString &shader_code = QString());
|
||||
|
||||
static OpenGLShaderPtr CreateOCIO(QOpenGLContext* ctx,
|
||||
GLuint& lut_texture,
|
||||
OCIO::ConstProcessorRcPtr processor,
|
||||
bool alpha_is_associated);
|
||||
|
||||
static QString CodeDefaultFragment(const QString &function_name = QString(),
|
||||
const QString &shader_code = QString());
|
||||
static QString CodeDefaultVertex();
|
||||
|
||||
@@ -30,74 +30,6 @@ void RenderBackend::SetViewerNode(ViewerOutput *viewer_node)
|
||||
Decompile();
|
||||
}
|
||||
|
||||
void RenderBackend::InvalidateCache(const rational &start_range, const rational &end_range)
|
||||
{
|
||||
if (!params_.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjust range to min/max values
|
||||
rational start_range_adj = qMax(rational(0), start_range);
|
||||
rational end_range_adj = qMin(viewer_node_->Length(), end_range);
|
||||
|
||||
qDebug() << "Cache invalidated between"
|
||||
<< start_range_adj.toDouble()
|
||||
<< "and"
|
||||
<< end_range_adj.toDouble();
|
||||
|
||||
// Snap start_range to timebase
|
||||
double start_range_dbl = start_range_adj.toDouble();
|
||||
double start_range_numf = start_range_dbl * static_cast<double>(params_.time_base().denominator());
|
||||
int64_t start_range_numround = qFloor(start_range_numf/static_cast<double>(params_.time_base().numerator())) * params_.time_base().numerator();
|
||||
rational true_start_range(start_range_numround, params_.time_base().denominator());
|
||||
|
||||
for (rational r=true_start_range;r<=end_range_adj;r+=params_.time_base()) {
|
||||
// Try to order the queue from closest to the playhead to furthest
|
||||
rational last_time = last_time_requested_;
|
||||
|
||||
rational diff = r - last_time;
|
||||
|
||||
if (diff < 0) {
|
||||
// FIXME: Hardcoded number
|
||||
// If the number is before the playhead, we still prioritize its closeness but not nearly as much (5:1 in this
|
||||
// example)
|
||||
diff = qAbs(diff) * 5;
|
||||
}
|
||||
|
||||
bool contains = false;
|
||||
bool added = false;
|
||||
QLinkedList<rational>::iterator insert_iterator;
|
||||
|
||||
for (QLinkedList<rational>::iterator i = cache_queue_.begin();i != cache_queue_.end();i++) {
|
||||
rational compare = *i;
|
||||
|
||||
if (!added) {
|
||||
rational compare_diff = compare - last_time;
|
||||
|
||||
if (compare_diff > diff) {
|
||||
insert_iterator = i;
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (compare == r) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contains) {
|
||||
if (added) {
|
||||
cache_queue_.insert(insert_iterator, r);
|
||||
} else {
|
||||
cache_queue_.append(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CacheNext();
|
||||
}
|
||||
|
||||
void RenderBackend::SetError(const QString &error)
|
||||
{
|
||||
error_ = error;
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "renderinstance.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "opengl/openglshader.h"
|
||||
|
||||
RenderInstance::RenderInstance(const VideoRenderingParams& params) :
|
||||
share_ctx_(nullptr),
|
||||
params_(params)
|
||||
{
|
||||
// Create offscreen surface
|
||||
surface_.create();
|
||||
}
|
||||
|
||||
RenderInstance::~RenderInstance()
|
||||
{
|
||||
// Destroy offscreen surface
|
||||
surface_.destroy();
|
||||
}
|
||||
|
||||
void RenderInstance::SetShareContext(QOpenGLContext *share)
|
||||
{
|
||||
Q_ASSERT(!IsStarted());
|
||||
|
||||
share_ctx_ = share;
|
||||
}
|
||||
|
||||
bool RenderInstance::Start()
|
||||
{
|
||||
if (IsStarted()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create context object
|
||||
ctx_ = new QOpenGLContext();
|
||||
|
||||
// If we're sharing resources, set this up now
|
||||
if (share_ctx_ != nullptr) {
|
||||
ctx_->setShareContext(share_ctx_);
|
||||
}
|
||||
|
||||
// Create OpenGL context (automatically destroys any existing if there is one)
|
||||
if (!ctx_->create()) {
|
||||
qWarning() << tr("Failed to create OpenGL context in thread %1").arg(reinterpret_cast<quintptr>(this));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make context current on that surface
|
||||
if (!ctx_->makeCurrent(&surface_)) {
|
||||
qWarning() << tr("Failed to makeCurrent() on offscreen surface in thread %1").arg(reinterpret_cast<quintptr>(this));
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer_.Create(ctx_);
|
||||
|
||||
// Set viewport to the compositing dimensions
|
||||
ctx_->functions()->glViewport(0, 0, params_.effective_width(), params_.effective_height());
|
||||
ctx_->functions()->glEnable(GL_BLEND);
|
||||
|
||||
// Set up default pipeline
|
||||
default_pipeline_ = OpenGLShader::CreateDefault();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderInstance::Stop()
|
||||
{
|
||||
if (IsStarted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy pipeline
|
||||
default_pipeline_ = nullptr;
|
||||
|
||||
// Destroy buffer
|
||||
buffer_.Destroy();
|
||||
|
||||
// Destroy context
|
||||
delete ctx_;
|
||||
}
|
||||
|
||||
bool RenderInstance::IsStarted()
|
||||
{
|
||||
return buffer_.IsCreated();
|
||||
}
|
||||
|
||||
OpenGLFramebuffer *RenderInstance::buffer()
|
||||
{
|
||||
return &buffer_;
|
||||
}
|
||||
|
||||
QOpenGLContext *RenderInstance::context()
|
||||
{
|
||||
return ctx_;
|
||||
}
|
||||
|
||||
const VideoRenderingParams &RenderInstance::params() const
|
||||
{
|
||||
return params_;
|
||||
}
|
||||
|
||||
OpenGLShaderPtr RenderInstance::default_pipeline() const
|
||||
{
|
||||
return default_pipeline_;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef GLINSTANCE_H
|
||||
#define GLINSTANCE_H
|
||||
|
||||
#include <QMatrix4x4>
|
||||
#include <QOffscreenSurface>
|
||||
#include <QOpenGLContext>
|
||||
|
||||
#include "opengl/openglshader.h"
|
||||
#include "opengl/openglframebuffer.h"
|
||||
#include "render/rendermodes.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
/**
|
||||
* @brief An object containing all resources necessary for each thread to support hardware accelerated rendering
|
||||
*
|
||||
* RenderInstance contains everything that Nodes will need to draw with on a per-thread basis.
|
||||
*
|
||||
* Due to its usage of QOffscreenSurface, a RenderInstance instance must be constructed in the main (GUI) thread. From
|
||||
* there it is safe to call Start() on in another thread.
|
||||
*/
|
||||
class RenderInstance : public QObject
|
||||
{
|
||||
public:
|
||||
RenderInstance(const VideoRenderingParams ¶ms);
|
||||
|
||||
virtual ~RenderInstance() override;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(RenderInstance)
|
||||
|
||||
void SetShareContext(QOpenGLContext* share);
|
||||
|
||||
bool Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
bool IsStarted();
|
||||
|
||||
OpenGLFramebuffer* buffer();
|
||||
|
||||
QOpenGLContext* context();
|
||||
|
||||
const VideoRenderingParams& params() const;
|
||||
|
||||
OpenGLShaderPtr default_pipeline() const;
|
||||
|
||||
private:
|
||||
QOpenGLContext* ctx_;
|
||||
|
||||
QOpenGLContext* share_ctx_;
|
||||
|
||||
QOffscreenSurface surface_;
|
||||
|
||||
OpenGLFramebuffer buffer_;
|
||||
|
||||
VideoRenderingParams params_;
|
||||
|
||||
OpenGLShaderPtr default_pipeline_;
|
||||
};
|
||||
|
||||
#endif // GLINSTANCE_H
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
***/
|
||||
|
||||
#include "videorenderer.h"
|
||||
#include "videorenderbackend.h"
|
||||
|
||||
#include <OpenImageIO/imageio.h>
|
||||
#include <QApplication>
|
||||
@@ -29,8 +29,7 @@
|
||||
#include <QtMath>
|
||||
|
||||
#include "common/filefunctions.h"
|
||||
#include "render/gl/functions.h"
|
||||
#include "render/gl/shadergenerators.h"
|
||||
#include "opengl/functions.h"
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
VideoRendererProcessor::VideoRendererProcessor(QObject *parent) :
|
||||
@@ -200,13 +199,13 @@ void VideoRendererProcessor::Start()
|
||||
ctx->makeCurrent(old_surface);
|
||||
|
||||
// Create master texture (the one sent to the viewer)
|
||||
master_texture_ = std::make_shared<RenderTexture>();
|
||||
master_texture_ = std::make_shared<OpenGLTexture>();
|
||||
master_texture_->Create(ctx, params_.effective_width(), params_.effective_height(), params_.format());
|
||||
|
||||
// Create internal FBO for copying textures
|
||||
copy_buffer_.Create(ctx);
|
||||
copy_buffer_.Attach(master_texture_);
|
||||
copy_pipeline_ = olive::ShaderGenerator::DefaultPipeline();
|
||||
copy_pipeline_ = OpenGLShader::CreateDefault();
|
||||
|
||||
cache_frame_load_buffer_.resize(PixelService::GetBufferSize(params_.format(), params_.effective_width(), params_.effective_height()));
|
||||
|
||||
@@ -420,22 +419,6 @@ void VideoRendererProcessor::DownloadThreadComplete(const QByteArray &hash)
|
||||
}
|
||||
}
|
||||
|
||||
VideoRendererThreadBase* VideoRendererProcessor::CurrentThread()
|
||||
{
|
||||
return dynamic_cast<VideoRendererThreadBase*>(QThread::currentThread());
|
||||
}
|
||||
|
||||
RenderInstance *VideoRendererProcessor::CurrentInstance()
|
||||
{
|
||||
VideoRendererThreadBase* thread = CurrentThread();
|
||||
|
||||
if (thread != nullptr) {
|
||||
return thread->render_instance();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RenderTexturePtr VideoRendererProcessor::GetCachedFrame(const rational &time)
|
||||
{
|
||||
last_time_requested_ = time;
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "render/rendermodes.h"
|
||||
#include "opengl/openglframebuffer.h"
|
||||
#include "opengl/openglshader.h"
|
||||
#include "opengl/opengltexture.h"
|
||||
#include "videorendererdownloadthread.h"
|
||||
#include "videorendererprocessthread.h"
|
||||
|
||||
@@ -84,16 +87,6 @@ public:
|
||||
*/
|
||||
bool TryCache(const QByteArray& hash);
|
||||
|
||||
/**
|
||||
* @brief Return current instance of a RenderThread (or nullptr if there is none)
|
||||
*
|
||||
* This function attempts a dynamic_cast on QThread::currentThread() to RendererThread, which will return nullptr if
|
||||
* the cast fails (e.g. if this function is called from the main thread rather than a RendererThread).
|
||||
*/
|
||||
static VideoRendererThreadBase* CurrentThread();
|
||||
|
||||
static RenderInstance* CurrentInstance();
|
||||
|
||||
RenderTexturePtr GetCachedFrame(const rational& time);
|
||||
|
||||
void SetViewerNode(ViewerOutput* viewer);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "videorendererprocessthread.h"
|
||||
|
||||
#include "videorenderer.h"
|
||||
#include "videorenderbackend.h"
|
||||
|
||||
RendererProcessThread::RendererProcessThread(VideoRendererProcessor* parent,
|
||||
QOpenGLContext *share_ctx,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "videorendererthreadbase.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
VideoRendererThreadBase::VideoRendererThreadBase(QOpenGLContext *share_ctx, const VideoRenderingParams ¶ms) :
|
||||
share_ctx_(share_ctx),
|
||||
render_instance_(params)
|
||||
{
|
||||
connect(share_ctx_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Cancel()));
|
||||
}
|
||||
|
||||
RenderInstance *VideoRendererThreadBase::render_instance()
|
||||
{
|
||||
return &render_instance_;
|
||||
}
|
||||
|
||||
void VideoRendererThreadBase::run()
|
||||
{
|
||||
// Lock mutex for main loop
|
||||
mutex_.lock();
|
||||
|
||||
render_instance_.SetShareContext(share_ctx_);
|
||||
|
||||
// Allocate and create resources
|
||||
bool started = render_instance_.Start();
|
||||
|
||||
// Signal that main thread can continue now
|
||||
WakeCaller();
|
||||
|
||||
if (started) {
|
||||
|
||||
// Main loop (use Cancel() to exit it)
|
||||
ProcessLoop();
|
||||
|
||||
}
|
||||
|
||||
// Free all resources
|
||||
render_instance_.Stop();
|
||||
|
||||
// Unlock mutex before exiting
|
||||
mutex_.unlock();
|
||||
}
|
||||
|
||||
void VideoRendererThreadBase::WakeCaller()
|
||||
{
|
||||
// Signal that main thread can continue now
|
||||
caller_mutex_.lock();
|
||||
wait_cond_.wakeAll();
|
||||
caller_mutex_.unlock();
|
||||
}
|
||||
|
||||
void VideoRendererThreadBase::StartThread(QThread::Priority priority)
|
||||
{
|
||||
caller_mutex_.lock();
|
||||
|
||||
// Start the thread
|
||||
QThread::start(priority);
|
||||
|
||||
// Wait for thread to finish completion
|
||||
wait_cond_.wait(&caller_mutex_);
|
||||
|
||||
caller_mutex_.unlock();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef RENDERTHREAD_H
|
||||
#define RENDERTHREAD_H
|
||||
|
||||
#include <memory>
|
||||
#include <QMutex>
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "node/node.h"
|
||||
#include "render/videoparams.h"
|
||||
#include "renderinstance.h"
|
||||
|
||||
class VideoRendererThreadBase : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VideoRendererThreadBase(QOpenGLContext* share_ctx, const VideoRenderingParams& params);
|
||||
|
||||
RenderInstance* render_instance();
|
||||
|
||||
void StartThread(Priority priority = InheritPriority);
|
||||
|
||||
virtual void run() override;
|
||||
|
||||
public slots:
|
||||
virtual void Cancel() = 0;
|
||||
|
||||
protected:
|
||||
virtual void ProcessLoop() = 0;
|
||||
|
||||
QWaitCondition wait_cond_;
|
||||
|
||||
QMutex mutex_;
|
||||
|
||||
QMutex caller_mutex_;
|
||||
|
||||
private:
|
||||
void WakeCaller();
|
||||
|
||||
QOpenGLContext* share_ctx_;
|
||||
|
||||
RenderInstance render_instance_;
|
||||
|
||||
};
|
||||
|
||||
using RendererThreadPtr = std::shared_ptr<VideoRendererThreadBase>;
|
||||
|
||||
#endif // RENDERTHREAD_H
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
video_renderer_(nullptr),
|
||||
viewer_node_(nullptr),
|
||||
playback_speed_(0)
|
||||
{
|
||||
@@ -161,7 +162,6 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
}
|
||||
|
||||
video_renderer_->SetViewerNode(viewer_node_);
|
||||
opengl_backend_.SetViewerNode(viewer_node_);
|
||||
}
|
||||
|
||||
void ViewerWidget::DisconnectViewerNode()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "render/backend/opengl/openglbackend.h"
|
||||
#include "render/backend/videorenderbackend.h"
|
||||
#include "viewerglwidget.h"
|
||||
#include "viewersizer.h"
|
||||
#include "widget/playbackcontrols/playbackcontrols.h"
|
||||
@@ -111,7 +111,7 @@ private:
|
||||
void PushScrubbedAudio();
|
||||
|
||||
// FIXME: Test code only
|
||||
OpenGLBackend opengl_backend_;
|
||||
VideoRendererProcessor* video_renderer_;
|
||||
// End test code
|
||||
|
||||
ViewerSizer* sizer_;
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
#include "render/gl/functions.h"
|
||||
#include "render/gl/shadergenerators.h"
|
||||
#include "render/backend/opengl/functions.h"
|
||||
#include "render/backend/opengl/openglshader.h"
|
||||
|
||||
ViewerGLWidget::ViewerGLWidget(QWidget *parent) :
|
||||
QOpenGLWidget(parent),
|
||||
@@ -87,7 +87,7 @@ void ViewerGLWidget::paintGL()
|
||||
void ViewerGLWidget::SetupPipeline()
|
||||
{
|
||||
// Re-retrieve pipeline pertaining to this context
|
||||
pipeline_ = olive::ShaderGenerator::OCIOPipeline(context(),
|
||||
pipeline_ = OpenGLShader::CreateOCIO(context(),
|
||||
ocio_lut_,
|
||||
color_service_->GetProcessor(),
|
||||
true);
|
||||
|
||||
Reference in New Issue
Block a user