minor render thread refactor
This commit is contained in:
@@ -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 +=
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 "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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user