minor render thread refactor
This commit is contained in:
@@ -159,7 +159,8 @@ SOURCES += \
|
|||||||
rendering/cacher.cpp \
|
rendering/cacher.cpp \
|
||||||
rendering/clipqueue.cpp \
|
rendering/clipqueue.cpp \
|
||||||
rendering/audio.cpp \
|
rendering/audio.cpp \
|
||||||
dialogs/clippropertiesdialog.cpp
|
dialogs/clippropertiesdialog.cpp \
|
||||||
|
rendering/framebufferobject.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
@@ -270,7 +271,8 @@ HEADERS += \
|
|||||||
rendering/clipqueue.h \
|
rendering/clipqueue.h \
|
||||||
rendering/cacher.h \
|
rendering/cacher.h \
|
||||||
rendering/audio.h \
|
rendering/audio.h \
|
||||||
dialogs/clippropertiesdialog.h
|
dialogs/clippropertiesdialog.h \
|
||||||
|
rendering/framebufferobject.h
|
||||||
|
|
||||||
FORMS +=
|
FORMS +=
|
||||||
|
|
||||||
|
|||||||
@@ -749,10 +749,11 @@ void Cacher::WakeMainThread()
|
|||||||
main_thread_lock_.unlock();
|
main_thread_lock_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Cacher::Cacher(Clip* c) : clip(c) {
|
Cacher::Cacher(Clip* c) :
|
||||||
frame_ = nullptr;
|
clip(c),
|
||||||
pkt = nullptr;
|
frame_(nullptr),
|
||||||
}
|
pkt(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
void Cacher::OpenWorker() {
|
void Cacher::OpenWorker() {
|
||||||
qint64 time_start = QDateTime::currentMSecsSinceEpoch();
|
qint64 time_start = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#include "framebufferobject.h"
|
||||||
|
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
|
|
||||||
|
FramebufferObject::FramebufferObject() :
|
||||||
|
buffer_(0),
|
||||||
|
texture_(0),
|
||||||
|
ctx_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
FramebufferObject::~FramebufferObject()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FramebufferObject::IsCreated()
|
||||||
|
{
|
||||||
|
return ctx_ != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramebufferObject::Create(QOpenGLContext *ctx, int width, int height)
|
||||||
|
{
|
||||||
|
// free any previous textures
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
// set context to new context provided
|
||||||
|
ctx_ = ctx;
|
||||||
|
|
||||||
|
// create framebuffer object
|
||||||
|
ctx->functions()->glGenFramebuffers(1, &buffer_);
|
||||||
|
|
||||||
|
// create texture
|
||||||
|
ctx->functions()->glGenTextures(1, &texture_);
|
||||||
|
|
||||||
|
// bind framebuffer for attaching
|
||||||
|
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_);
|
||||||
|
|
||||||
|
// bind texture
|
||||||
|
ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_);
|
||||||
|
|
||||||
|
// allocate storage for texture
|
||||||
|
ctx->functions()->glTexImage2D(
|
||||||
|
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
// set texture filtering to bilinear
|
||||||
|
ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
// attach texture to framebuffer
|
||||||
|
ctx->functions()->glFramebufferTexture2D(
|
||||||
|
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
// release texture
|
||||||
|
ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
// release framebuffer
|
||||||
|
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramebufferObject::Destroy()
|
||||||
|
{
|
||||||
|
if (ctx_ != nullptr) {
|
||||||
|
ctx_->functions()->glDeleteFramebuffers(1, &buffer_);
|
||||||
|
|
||||||
|
ctx_->functions()->glDeleteTextures(1, &texture_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLuint &FramebufferObject::buffer()
|
||||||
|
{
|
||||||
|
return buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLuint &FramebufferObject::texture()
|
||||||
|
{
|
||||||
|
return texture_;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef FRAMEBUFFEROBJECT_H
|
||||||
|
#define FRAMEBUFFEROBJECT_H
|
||||||
|
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
|
||||||
|
class FramebufferObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FramebufferObject();
|
||||||
|
~FramebufferObject();
|
||||||
|
|
||||||
|
bool IsCreated();
|
||||||
|
void Create(QOpenGLContext* ctx, int width, int height);
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
const GLuint& buffer();
|
||||||
|
const GLuint& texture();
|
||||||
|
private:
|
||||||
|
QOpenGLContext* ctx_;
|
||||||
|
GLuint buffer_;
|
||||||
|
GLuint texture_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FRAMEBUFFEROBJECT_H
|
||||||
+51
-114
@@ -33,25 +33,20 @@ namespace OCIO = OCIO_NAMESPACE;
|
|||||||
#include "rendering/renderfunctions.h"
|
#include "rendering/renderfunctions.h"
|
||||||
#include "project/sequence.h"
|
#include "project/sequence.h"
|
||||||
|
|
||||||
RenderThread::RenderThread()
|
RenderThread::RenderThread() :
|
||||||
|
gizmos(nullptr),
|
||||||
|
share_ctx(nullptr),
|
||||||
|
ctx(nullptr),
|
||||||
|
blend_mode_program(nullptr),
|
||||||
|
premultiply_program(nullptr),
|
||||||
|
seq(nullptr),
|
||||||
|
tex_width(-1),
|
||||||
|
tex_height(-1),
|
||||||
|
queued(false),
|
||||||
|
texture_failed(false),
|
||||||
|
running(true),
|
||||||
|
front_buffer_switcher(false)
|
||||||
{
|
{
|
||||||
front_buffer1 = 0;
|
|
||||||
front_buffer2 = 0;
|
|
||||||
front_texture1 = 0;
|
|
||||||
front_texture2 = 0;
|
|
||||||
gizmos = nullptr;
|
|
||||||
share_ctx = nullptr;
|
|
||||||
ctx = nullptr;
|
|
||||||
blend_mode_program = nullptr;
|
|
||||||
premultiply_program = nullptr;
|
|
||||||
seq = nullptr;
|
|
||||||
tex_width = -1;
|
|
||||||
tex_height = -1;
|
|
||||||
queued = false;
|
|
||||||
texture_failed = false;
|
|
||||||
running = true;
|
|
||||||
front_buffer_switcher = false;
|
|
||||||
|
|
||||||
surface.create();
|
surface.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,44 +70,32 @@ void RenderThread::run() {
|
|||||||
if (ctx != nullptr) {
|
if (ctx != nullptr) {
|
||||||
ctx->makeCurrent(&surface);
|
ctx->makeCurrent(&surface);
|
||||||
|
|
||||||
// gen fbo
|
// if the sequence size has changed, we'll need to reinitialize the textures
|
||||||
if (front_buffer1 == 0) {
|
if (seq->width != tex_width || seq->height != tex_height) {
|
||||||
// delete any existing framebuffers
|
delete_buffers();
|
||||||
delete_fbo();
|
|
||||||
|
|
||||||
// create framebuffers
|
// cache sequence values for future checks
|
||||||
ctx->functions()->glGenFramebuffers(1, &front_buffer1);
|
|
||||||
ctx->functions()->glGenFramebuffers(1, &front_buffer2);
|
|
||||||
ctx->functions()->glGenFramebuffers(1, &back_buffer_1);
|
|
||||||
ctx->functions()->glGenFramebuffers(1, &back_buffer_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen texture
|
|
||||||
if (front_texture1 == 0 || tex_width != seq->width || tex_height != seq->height) {
|
|
||||||
// cache texture size
|
|
||||||
tex_width = seq->width;
|
tex_width = seq->width;
|
||||||
tex_height = seq->height;
|
tex_height = seq->height;
|
||||||
|
}
|
||||||
|
|
||||||
// delete any existing textures
|
// create any buffers that don't yet exist
|
||||||
delete_texture();
|
if (!front_buffer_1.IsCreated()) {
|
||||||
|
front_buffer_1.Create(ctx, seq->width, seq->height);
|
||||||
// create texture
|
}
|
||||||
glGenTextures(1, &front_texture1);
|
if (!front_buffer_2.IsCreated()) {
|
||||||
glGenTextures(1, &front_texture2);
|
front_buffer_2.Create(ctx, seq->width, seq->height);
|
||||||
glGenTextures(1, &back_texture_1);
|
}
|
||||||
glGenTextures(1, &back_texture_2);
|
if (!back_buffer_1.IsCreated()) {
|
||||||
|
back_buffer_1.Create(ctx, seq->width, seq->height);
|
||||||
GLuint textures[4] = { front_texture1, front_texture2, back_texture_1, back_texture_2 };
|
}
|
||||||
GLuint fbos[4] = { front_buffer1, front_buffer2, back_buffer_1, back_buffer_2 };
|
if (!back_buffer_2.IsCreated()) {
|
||||||
|
back_buffer_2.Create(ctx, seq->width, seq->height);
|
||||||
for (int i=0;i<4;i++) {
|
|
||||||
allocate_texture(textures[i], fbos[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blend_mode_program == nullptr) {
|
if (blend_mode_program == nullptr) {
|
||||||
// create shader program to make blending modes work
|
// create shader program to make blending modes work
|
||||||
delete_shader_program();
|
delete_shaders();
|
||||||
|
|
||||||
blend_mode_program = new QOpenGLShaderProgram();
|
blend_mode_program = new QOpenGLShaderProgram();
|
||||||
blend_mode_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/internalshaders/common.vert");
|
blend_mode_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/internalshaders/common.vert");
|
||||||
@@ -149,36 +132,7 @@ QMutex *RenderThread::get_texture_mutex()
|
|||||||
const GLuint &RenderThread::get_texture()
|
const GLuint &RenderThread::get_texture()
|
||||||
{
|
{
|
||||||
// return the opposite texture to the texture being drawn to by the renderer
|
// return the opposite texture to the texture being drawn to by the renderer
|
||||||
return front_buffer_switcher ? front_texture2 : front_texture1;
|
return front_buffer_switcher ? front_buffer_2.texture() : front_buffer_1.texture();
|
||||||
}
|
|
||||||
|
|
||||||
void RenderThread::allocate_texture(GLuint tex, GLuint fbo)
|
|
||||||
{
|
|
||||||
// bind framebuffer for attaching
|
|
||||||
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
|
||||||
|
|
||||||
// bind texture
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
|
|
||||||
// allocate storage for texture
|
|
||||||
glTexImage2D(
|
|
||||||
GL_TEXTURE_2D, 0, GL_RGBA, seq->width, seq->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
// set texture filtering to bilinear
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
|
|
||||||
// attach texture to framebuffer
|
|
||||||
ctx->functions()->glFramebufferTexture2D(
|
|
||||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
// release texture
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
// release framebuffer
|
|
||||||
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderThread::set_up_ocio()
|
void RenderThread::set_up_ocio()
|
||||||
@@ -197,12 +151,12 @@ void RenderThread::paint() {
|
|||||||
params.playback_speed = 1;
|
params.playback_speed = 1;
|
||||||
params.blend_mode_program = blend_mode_program;
|
params.blend_mode_program = blend_mode_program;
|
||||||
params.premultiply_program = premultiply_program;
|
params.premultiply_program = premultiply_program;
|
||||||
params.backend_buffer1 = back_buffer_1;
|
params.backend_buffer1 = back_buffer_1.buffer();
|
||||||
params.backend_buffer2 = back_buffer_2;
|
params.backend_buffer2 = back_buffer_2.buffer();
|
||||||
params.backend_attachment1 = back_texture_1;
|
params.backend_attachment1 = back_buffer_1.texture();
|
||||||
params.backend_attachment2 = back_texture_2;
|
params.backend_attachment2 = back_buffer_2.texture();
|
||||||
params.main_buffer = front_buffer_switcher ? front_buffer1 : front_buffer2;
|
params.main_buffer = front_buffer_switcher ? front_buffer_1.buffer() : front_buffer_2.buffer();
|
||||||
params.main_attachment = front_buffer_switcher ? front_texture1 : front_texture2;
|
params.main_attachment = front_buffer_switcher ? front_buffer_1.texture() : front_buffer_2.texture();
|
||||||
|
|
||||||
// get currently selected gizmos
|
// get currently selected gizmos
|
||||||
gizmos = seq->GetSelectedGizmo();
|
gizmos = seq->GetSelectedGizmo();
|
||||||
@@ -313,44 +267,27 @@ void RenderThread::cancel() {
|
|||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderThread::delete_texture() {
|
void RenderThread::delete_buffers() {
|
||||||
if (front_texture1 > 0) {
|
front_buffer_1.Destroy();
|
||||||
GLuint tex[4] = {front_texture1, front_texture2, back_texture_1, back_texture_2};
|
front_buffer_2.Destroy();
|
||||||
glDeleteTextures(3, tex);
|
back_buffer_1.Destroy();
|
||||||
}
|
back_buffer_2.Destroy();
|
||||||
front_texture1 = 0;
|
|
||||||
front_texture2 = 0;
|
|
||||||
back_texture_1 = 0;
|
|
||||||
back_texture_2 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderThread::delete_fbo() {
|
void RenderThread::delete_shaders() {
|
||||||
if (front_buffer1 > 0) {
|
delete blend_mode_program;
|
||||||
GLuint fbos[4] = {front_buffer1, front_buffer2, back_buffer_1, back_buffer_2};
|
|
||||||
ctx->functions()->glDeleteFramebuffers(3, fbos);
|
|
||||||
}
|
|
||||||
front_buffer1 = 0;
|
|
||||||
front_buffer2 = 0;
|
|
||||||
back_buffer_1 = 0;
|
|
||||||
back_buffer_2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderThread::delete_shader_program() {
|
|
||||||
if (blend_mode_program != nullptr) {
|
|
||||||
delete blend_mode_program;
|
|
||||||
delete premultiply_program;
|
|
||||||
}
|
|
||||||
blend_mode_program = nullptr;
|
blend_mode_program = nullptr;
|
||||||
|
|
||||||
|
delete premultiply_program;
|
||||||
premultiply_program = nullptr;
|
premultiply_program = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderThread::delete_ctx() {
|
void RenderThread::delete_ctx() {
|
||||||
if (ctx != nullptr) {
|
if (ctx != nullptr) {
|
||||||
delete_shader_program();
|
delete_shaders();
|
||||||
delete_texture();
|
delete_buffers();
|
||||||
delete_fbo();
|
|
||||||
ctx->doneCurrent();
|
|
||||||
delete ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete ctx;
|
||||||
ctx = nullptr;
|
ctx = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "project/sequence.h"
|
#include "project/sequence.h"
|
||||||
#include "project/effect.h"
|
#include "project/effect.h"
|
||||||
|
#include "rendering/framebufferobject.h"
|
||||||
|
|
||||||
// copied from source code to OCIODisplay
|
// copied from source code to OCIODisplay
|
||||||
const int LUT3D_EDGE_SIZE = 32;
|
const int LUT3D_EDGE_SIZE = 32;
|
||||||
@@ -66,22 +67,17 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void ready();
|
void ready();
|
||||||
private:
|
private:
|
||||||
void allocate_texture(GLuint tex, GLuint fbo);
|
// cleanup functions
|
||||||
|
void delete_buffers();
|
||||||
|
void delete_shaders();
|
||||||
|
|
||||||
void set_up_ocio();
|
void set_up_ocio();
|
||||||
void destroy_ocio();
|
void destroy_ocio();
|
||||||
|
|
||||||
// cleanup functions
|
FramebufferObject front_buffer_1;
|
||||||
void delete_texture();
|
|
||||||
void delete_fbo();
|
|
||||||
void delete_shader_program();
|
|
||||||
|
|
||||||
GLuint front_buffer1;
|
|
||||||
GLuint front_texture1;
|
|
||||||
QMutex front_mutex1;
|
QMutex front_mutex1;
|
||||||
|
|
||||||
GLuint front_buffer2;
|
FramebufferObject front_buffer_2;
|
||||||
GLuint front_texture2;
|
|
||||||
QMutex front_mutex2;
|
QMutex front_mutex2;
|
||||||
|
|
||||||
bool front_buffer_switcher;
|
bool front_buffer_switcher;
|
||||||
@@ -98,10 +94,8 @@ private:
|
|||||||
QOpenGLShaderProgram* blend_mode_program;
|
QOpenGLShaderProgram* blend_mode_program;
|
||||||
QOpenGLShaderProgram* premultiply_program;
|
QOpenGLShaderProgram* premultiply_program;
|
||||||
|
|
||||||
GLuint back_buffer_1;
|
FramebufferObject back_buffer_1;
|
||||||
GLuint back_buffer_2;
|
FramebufferObject back_buffer_2;
|
||||||
GLuint back_texture_1;
|
|
||||||
GLuint back_texture_2;
|
|
||||||
|
|
||||||
float ocio_lut_data[NUM_3D_ENTRIES];
|
float ocio_lut_data[NUM_3D_ENTRIES];
|
||||||
GLuint ocio_lut_texture;
|
GLuint ocio_lut_texture;
|
||||||
|
|||||||
Reference in New Issue
Block a user