minor code cleanup and fixed opengl thread desync issue
This commit is contained in:
@@ -105,7 +105,6 @@ bool OIIODecoder::Open()
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <QFile>
|
||||
FramePtr OIIODecoder::RetrieveVideo(const rational &timecode)
|
||||
{
|
||||
if (!open_ && !Open()) {
|
||||
@@ -114,7 +113,7 @@ FramePtr OIIODecoder::RetrieveVideo(const rational &timecode)
|
||||
|
||||
Q_UNUSED(timecode)
|
||||
|
||||
if (frame_ == nullptr) {
|
||||
if (!frame_) {
|
||||
frame_ = Frame::Create();
|
||||
|
||||
frame_->set_width(width_);
|
||||
|
||||
@@ -135,7 +135,7 @@ void OpenGLBackend::DecompileInternal()
|
||||
shader_cache_.Clear();
|
||||
}
|
||||
|
||||
bool OpenGLBackend::TimeIsCached(const TimeRange &time)
|
||||
bool OpenGLBackend::TimeIsQueued(const TimeRange &time)
|
||||
{
|
||||
return cache_queue_.contains(time);
|
||||
}
|
||||
@@ -164,9 +164,10 @@ void OpenGLBackend::ThreadCompletedFrame(NodeDependency path, QByteArray hash, N
|
||||
last_download_thread_++;
|
||||
}
|
||||
|
||||
// Set as push texture
|
||||
if (!TimeIsCached(TimeRange(path.in(), path.in()))) {
|
||||
emit CachedFrameReady(path.in(), value);
|
||||
// Check if this frame has changed once again, in which case we may not want to draw it (it'll look jittery to the user)
|
||||
if (!TimeIsQueued(TimeRange(path.in(), path.in()))) {
|
||||
// FIXME: This texture is part of the texture cache and therefore volatile, we should probably copy it here instead
|
||||
emit CachedFrameReady(path.in(), QVariant::fromValue(value.value<OpenGLTextureCache::ReferencePtr>()->texture()));
|
||||
}
|
||||
|
||||
// Queue up a new frame for this worker
|
||||
|
||||
@@ -29,7 +29,7 @@ protected:
|
||||
virtual void DecompileInternal() override;
|
||||
|
||||
private:
|
||||
bool TimeIsCached(const TimeRange &time);
|
||||
bool TimeIsQueued(const TimeRange &time);
|
||||
|
||||
OpenGLTexturePtr master_texture_;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
OpenGLTexture::OpenGLTexture() :
|
||||
context_(nullptr),
|
||||
created_ctx_(nullptr),
|
||||
texture_(0),
|
||||
width_(0),
|
||||
height_(0),
|
||||
@@ -41,27 +41,27 @@ OpenGLTexture::~OpenGLTexture()
|
||||
|
||||
bool OpenGLTexture::IsCreated() const
|
||||
{
|
||||
return (texture_ != 0);
|
||||
return (texture_);
|
||||
}
|
||||
|
||||
void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const olive::PixelFormat &format, const void* data)
|
||||
{
|
||||
if (ctx == nullptr) {
|
||||
if (!ctx) {
|
||||
qWarning() << "RenderTexture::Create was passed an invalid context";
|
||||
return;
|
||||
}
|
||||
|
||||
Destroy();
|
||||
|
||||
context_ = ctx;
|
||||
created_ctx_ = ctx;
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
format_ = format;
|
||||
|
||||
connect(context_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Destroy()));
|
||||
connect(created_ctx_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Destroy()));
|
||||
|
||||
// Create main texture
|
||||
CreateInternal(&texture_, data);
|
||||
CreateInternal(created_ctx_, &texture_, data);
|
||||
}
|
||||
|
||||
void OpenGLTexture::Create(QOpenGLContext *ctx, FramePtr frame)
|
||||
@@ -71,34 +71,38 @@ void OpenGLTexture::Create(QOpenGLContext *ctx, FramePtr frame)
|
||||
|
||||
void OpenGLTexture::Destroy()
|
||||
{
|
||||
if (context_ != nullptr) {
|
||||
disconnect(context_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Destroy()));
|
||||
if (created_ctx_) {
|
||||
disconnect(created_ctx_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Destroy()));
|
||||
|
||||
context_->functions()->glDeleteTextures(1, &texture_);
|
||||
created_ctx_->functions()->glDeleteTextures(1, &texture_);
|
||||
texture_ = 0;
|
||||
|
||||
context_ = nullptr;
|
||||
created_ctx_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLTexture::Bind()
|
||||
{
|
||||
if (context_ == nullptr) {
|
||||
QOpenGLContext* context = QOpenGLContext::currentContext();
|
||||
|
||||
if (!context) {
|
||||
qWarning() << "RenderTexture::Bind() called with an invalid context";
|
||||
return;
|
||||
}
|
||||
|
||||
context_->functions()->glBindTexture(GL_TEXTURE_2D, texture_);
|
||||
context->functions()->glBindTexture(GL_TEXTURE_2D, texture_);
|
||||
}
|
||||
|
||||
void OpenGLTexture::Release()
|
||||
{
|
||||
if (context_ == nullptr) {
|
||||
QOpenGLContext* context = QOpenGLContext::currentContext();
|
||||
|
||||
if (!context) {
|
||||
qWarning() << "RenderTexture::Release() called with an invalid context";
|
||||
return;
|
||||
}
|
||||
|
||||
context_->functions()->glBindTexture(GL_TEXTURE_2D, 0);
|
||||
context->functions()->glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
const int &OpenGLTexture::width() const
|
||||
@@ -116,11 +120,6 @@ const olive::PixelFormat &OpenGLTexture::format() const
|
||||
return format_;
|
||||
}
|
||||
|
||||
QOpenGLContext *OpenGLTexture::context() const
|
||||
{
|
||||
return context_;
|
||||
}
|
||||
|
||||
const GLuint &OpenGLTexture::texture() const
|
||||
{
|
||||
return texture_;
|
||||
@@ -133,19 +132,26 @@ void OpenGLTexture::Upload(const void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
QOpenGLContext* context = QOpenGLContext::currentContext();
|
||||
|
||||
if (!context) {
|
||||
qWarning() << "RenderTexture::Release() called with an invalid context";
|
||||
return;
|
||||
}
|
||||
|
||||
Bind();
|
||||
|
||||
PixelFormatInfo info = PixelService::GetPixelFormatInfo(format_);
|
||||
|
||||
context_->functions()->glTexSubImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
width_,
|
||||
height_,
|
||||
info.pixel_format,
|
||||
info.gl_pixel_type,
|
||||
data);
|
||||
context->functions()->glTexSubImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
width_,
|
||||
height_,
|
||||
info.pixel_format,
|
||||
info.gl_pixel_type,
|
||||
data);
|
||||
|
||||
Release();
|
||||
}
|
||||
@@ -157,7 +163,8 @@ uchar *OpenGLTexture::Download() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QOpenGLFunctions* f = context_->functions();
|
||||
QOpenGLContext* context = QOpenGLContext::currentContext();
|
||||
QOpenGLFunctions* f = context->functions();
|
||||
|
||||
GLuint read_fbo;
|
||||
|
||||
@@ -165,7 +172,7 @@ uchar *OpenGLTexture::Download() const
|
||||
|
||||
f->glBindFramebuffer(GL_READ_FRAMEBUFFER, read_fbo);
|
||||
|
||||
context_->extraFunctions()->glFramebufferTexture2D(
|
||||
context->extraFunctions()->glFramebufferTexture2D(
|
||||
GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0
|
||||
);
|
||||
|
||||
@@ -182,9 +189,9 @@ uchar *OpenGLTexture::Download() const
|
||||
return data;
|
||||
}
|
||||
|
||||
void OpenGLTexture::CreateInternal(GLuint* tex, const void *data)
|
||||
void OpenGLTexture::CreateInternal(QOpenGLContext* create_ctx, GLuint* tex, const void *data)
|
||||
{
|
||||
QOpenGLFunctions* f = context_->functions();
|
||||
QOpenGLFunctions* f = create_ctx->functions();
|
||||
|
||||
// Create texture
|
||||
f->glGenTextures(1, tex);
|
||||
|
||||
@@ -55,8 +55,6 @@ public:
|
||||
|
||||
const olive::PixelFormat &format() const;
|
||||
|
||||
QOpenGLContext* context() const;
|
||||
|
||||
const GLuint& texture() const;
|
||||
|
||||
void Upload(const void *data);
|
||||
@@ -67,9 +65,9 @@ public slots:
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
void CreateInternal(GLuint *tex, const void *data = nullptr);
|
||||
void CreateInternal(QOpenGLContext *create_ctx, GLuint *tex, const void *data = nullptr);
|
||||
|
||||
QOpenGLContext* context_;
|
||||
QOpenGLContext* created_ctx_;
|
||||
|
||||
GLuint texture_;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ OpenGLTextureCache::~OpenGLTextureCache()
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(const VideoRenderingParams ¶ms, const void *data)
|
||||
OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, const VideoRenderingParams ¶ms, const void *data)
|
||||
{
|
||||
OpenGLTexturePtr texture = nullptr;
|
||||
|
||||
@@ -28,8 +28,6 @@ OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(const VideoRenderingPar
|
||||
|
||||
lock_.unlock();
|
||||
|
||||
QOpenGLContext* ctx = QOpenGLContext::currentContext();
|
||||
|
||||
// If we didn't find a texture, we'll need to create one
|
||||
if (!texture) {
|
||||
texture = std::make_shared<OpenGLTexture>();
|
||||
@@ -38,15 +36,19 @@ OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(const VideoRenderingPar
|
||||
texture->Upload(data);
|
||||
}
|
||||
|
||||
return std::make_shared<Reference>(this, texture);
|
||||
ReferencePtr ref = std::make_shared<Reference>(this, texture);
|
||||
existing_references_.append(ref.get());
|
||||
return ref;
|
||||
}
|
||||
|
||||
void OpenGLTextureCache::Relinquish(OpenGLTextureCache::Reference *ref)
|
||||
{
|
||||
OpenGLTexturePtr tex = ref->texture();
|
||||
|
||||
lock_.lock();
|
||||
|
||||
existing_references_.removeOne(ref);
|
||||
available_textures_.append(ref->texture());
|
||||
available_textures_.append(tex);
|
||||
|
||||
lock_.unlock();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
|
||||
DISABLE_COPY_MOVE(OpenGLTextureCache)
|
||||
|
||||
ReferencePtr Get(const VideoRenderingParams& params, const void *data = nullptr);
|
||||
ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, const void *data = nullptr);
|
||||
|
||||
private:
|
||||
void Relinquish(Reference* ref);
|
||||
|
||||
@@ -98,7 +98,7 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
||||
|
||||
VideoRenderingParams footage_params(frame->width(), frame->height(), stream->timebase(), frame->format(), video_params().mode());
|
||||
|
||||
OpenGLTextureCache::ReferencePtr footage_tex_ref = texture_cache_->Get(footage_params, frame->data());
|
||||
OpenGLTextureCache::ReferencePtr footage_tex_ref = texture_cache_->Get(ctx_, footage_params, frame->data());
|
||||
|
||||
if (video_params().mode() == olive::kOffline) {
|
||||
if (!color_processor->IsEnabled()) {
|
||||
@@ -106,15 +106,15 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
||||
}
|
||||
|
||||
// Create destination texture
|
||||
OpenGLTextureCache::ReferencePtr associated_tex_ref = texture_cache_->Get(footage_params);
|
||||
|
||||
// Set viewport for texture size
|
||||
functions_->glViewport(0, 0, footage_tex_ref->texture()->width(), footage_tex_ref->texture()->height());
|
||||
OpenGLTextureCache::ReferencePtr associated_tex_ref = texture_cache_->Get(ctx_, footage_params);
|
||||
|
||||
buffer_.Attach(associated_tex_ref->texture(), true);
|
||||
buffer_.Bind();
|
||||
footage_tex_ref->texture()->Bind();
|
||||
|
||||
// Set viewport for texture size
|
||||
functions_->glViewport(0, 0, footage_tex_ref->texture()->width(), footage_tex_ref->texture()->height());
|
||||
|
||||
// Blit old texture to new texture through OCIO shader
|
||||
color_processor->ProcessOpenGL();
|
||||
|
||||
@@ -123,6 +123,8 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
||||
buffer_.Detach();
|
||||
|
||||
footage_tex_ref = associated_tex_ref;
|
||||
|
||||
functions_->glFinish();
|
||||
}
|
||||
|
||||
table->Push(NodeParam::kTexture, QVariant::fromValue(footage_tex_ref));
|
||||
@@ -151,7 +153,7 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const NodeValueDatabase
|
||||
}
|
||||
|
||||
// Create the output texture
|
||||
OpenGLTextureCache::ReferencePtr output_ref = texture_cache_->Get(video_params());
|
||||
OpenGLTextureCache::ReferencePtr output_ref = texture_cache_->Get(ctx_, video_params());
|
||||
|
||||
buffer_.Attach(output_ref->texture(), true);
|
||||
buffer_.Bind();
|
||||
@@ -284,7 +286,6 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const NodeValueDatabase
|
||||
shader->release();
|
||||
|
||||
buffer_.Release();
|
||||
|
||||
buffer_.Detach();
|
||||
|
||||
output_params->Push(NodeParam::kTexture, QVariant::fromValue(output_ref));
|
||||
|
||||
@@ -256,8 +256,6 @@ void RenderBackend::CacheNext()
|
||||
if (!WorkerIsBusy(worker)) {
|
||||
TimeRange cache_frame = cache_queue_.takeFirst();
|
||||
|
||||
qDebug() << "Rendering" << cache_frame.in().toDouble();
|
||||
|
||||
NodeDependency dep = NodeDependency(node_connected_to_viewer, cache_frame.in(), cache_frame.out());
|
||||
|
||||
SetWorkerBusyState(worker, true);
|
||||
|
||||
Reference in New Issue
Block a user