minor render thread refactor

This commit is contained in:
itsmattkc
2019-03-03 12:17:55 -08:00
parent 2b406d71f2
commit 7af3a0cd6e
6 changed files with 173 additions and 134 deletions
+4 -2
View File
@@ -159,7 +159,8 @@ SOURCES += \
rendering/cacher.cpp \
rendering/clipqueue.cpp \
rendering/audio.cpp \
dialogs/clippropertiesdialog.cpp
dialogs/clippropertiesdialog.cpp \
rendering/framebufferobject.cpp
HEADERS += \
mainwindow.h \
@@ -270,7 +271,8 @@ HEADERS += \
rendering/clipqueue.h \
rendering/cacher.h \
rendering/audio.h \
dialogs/clippropertiesdialog.h
dialogs/clippropertiesdialog.h \
rendering/framebufferobject.h
FORMS +=
+5 -4
View File
@@ -749,10 +749,11 @@ void Cacher::WakeMainThread()
main_thread_lock_.unlock();
}
Cacher::Cacher(Clip* c) : clip(c) {
frame_ = nullptr;
pkt = nullptr;
}
Cacher::Cacher(Clip* c) :
clip(c),
frame_(nullptr),
pkt(nullptr)
{}
void Cacher::OpenWorker() {
qint64 time_start = QDateTime::currentMSecsSinceEpoch();
+81
View File
@@ -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_;
}
+24
View File
@@ -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
View File
@@ -33,25 +33,20 @@ namespace OCIO = OCIO_NAMESPACE;
#include "rendering/renderfunctions.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();
}
@@ -75,44 +70,32 @@ void RenderThread::run() {
if (ctx != nullptr) {
ctx->makeCurrent(&surface);
// gen fbo
if (front_buffer1 == 0) {
// delete any existing framebuffers
delete_fbo();
// if the sequence size has changed, we'll need to reinitialize the textures
if (seq->width != tex_width || seq->height != tex_height) {
delete_buffers();
// create framebuffers
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
// cache sequence values for future checks
tex_width = seq->width;
tex_height = seq->height;
}
// delete any existing textures
delete_texture();
// create texture
glGenTextures(1, &front_texture1);
glGenTextures(1, &front_texture2);
glGenTextures(1, &back_texture_1);
glGenTextures(1, &back_texture_2);
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 };
for (int i=0;i<4;i++) {
allocate_texture(textures[i], fbos[i]);
}
// create any buffers that don't yet exist
if (!front_buffer_1.IsCreated()) {
front_buffer_1.Create(ctx, seq->width, seq->height);
}
if (!front_buffer_2.IsCreated()) {
front_buffer_2.Create(ctx, seq->width, seq->height);
}
if (!back_buffer_1.IsCreated()) {
back_buffer_1.Create(ctx, seq->width, seq->height);
}
if (!back_buffer_2.IsCreated()) {
back_buffer_2.Create(ctx, seq->width, seq->height);
}
if (blend_mode_program == nullptr) {
// create shader program to make blending modes work
delete_shader_program();
delete_shaders();
blend_mode_program = new QOpenGLShaderProgram();
blend_mode_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/internalshaders/common.vert");
@@ -149,36 +132,7 @@ QMutex *RenderThread::get_texture_mutex()
const GLuint &RenderThread::get_texture()
{
// return the opposite texture to the texture being drawn to by the renderer
return front_buffer_switcher ? front_texture2 : front_texture1;
}
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);
return front_buffer_switcher ? front_buffer_2.texture() : front_buffer_1.texture();
}
void RenderThread::set_up_ocio()
@@ -197,12 +151,12 @@ void RenderThread::paint() {
params.playback_speed = 1;
params.blend_mode_program = blend_mode_program;
params.premultiply_program = premultiply_program;
params.backend_buffer1 = back_buffer_1;
params.backend_buffer2 = back_buffer_2;
params.backend_attachment1 = back_texture_1;
params.backend_attachment2 = back_texture_2;
params.main_buffer = front_buffer_switcher ? front_buffer1 : front_buffer2;
params.main_attachment = front_buffer_switcher ? front_texture1 : front_texture2;
params.backend_buffer1 = back_buffer_1.buffer();
params.backend_buffer2 = back_buffer_2.buffer();
params.backend_attachment1 = back_buffer_1.texture();
params.backend_attachment2 = back_buffer_2.texture();
params.main_buffer = front_buffer_switcher ? front_buffer_1.buffer() : front_buffer_2.buffer();
params.main_attachment = front_buffer_switcher ? front_buffer_1.texture() : front_buffer_2.texture();
// get currently selected gizmos
gizmos = seq->GetSelectedGizmo();
@@ -313,44 +267,27 @@ void RenderThread::cancel() {
wait();
}
void RenderThread::delete_texture() {
if (front_texture1 > 0) {
GLuint tex[4] = {front_texture1, front_texture2, back_texture_1, back_texture_2};
glDeleteTextures(3, tex);
}
front_texture1 = 0;
front_texture2 = 0;
back_texture_1 = 0;
back_texture_2 = 0;
void RenderThread::delete_buffers() {
front_buffer_1.Destroy();
front_buffer_2.Destroy();
back_buffer_1.Destroy();
back_buffer_2.Destroy();
}
void RenderThread::delete_fbo() {
if (front_buffer1 > 0) {
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;
}
void RenderThread::delete_shaders() {
delete blend_mode_program;
blend_mode_program = nullptr;
delete premultiply_program;
premultiply_program = nullptr;
}
void RenderThread::delete_ctx() {
if (ctx != nullptr) {
delete_shader_program();
delete_texture();
delete_fbo();
ctx->doneCurrent();
delete ctx;
delete_shaders();
delete_buffers();
}
delete ctx;
ctx = nullptr;
}
+8 -14
View File
@@ -31,6 +31,7 @@
#include "project/sequence.h"
#include "project/effect.h"
#include "rendering/framebufferobject.h"
// copied from source code to OCIODisplay
const int LUT3D_EDGE_SIZE = 32;
@@ -66,22 +67,17 @@ public slots:
signals:
void ready();
private:
void allocate_texture(GLuint tex, GLuint fbo);
// cleanup functions
void delete_buffers();
void delete_shaders();
void set_up_ocio();
void destroy_ocio();
// cleanup functions
void delete_texture();
void delete_fbo();
void delete_shader_program();
GLuint front_buffer1;
GLuint front_texture1;
FramebufferObject front_buffer_1;
QMutex front_mutex1;
GLuint front_buffer2;
GLuint front_texture2;
FramebufferObject front_buffer_2;
QMutex front_mutex2;
bool front_buffer_switcher;
@@ -98,10 +94,8 @@ private:
QOpenGLShaderProgram* blend_mode_program;
QOpenGLShaderProgram* premultiply_program;
GLuint back_buffer_1;
GLuint back_buffer_2;
GLuint back_texture_1;
GLuint back_texture_2;
FramebufferObject back_buffer_1;
FramebufferObject back_buffer_2;
float ocio_lut_data[NUM_3D_ENTRIES];
GLuint ocio_lut_texture;