diff --git a/effects/effect.cpp b/effects/effect.cpp index 387a374bb..7648345d3 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -117,7 +117,9 @@ Effect::Effect(Clip* c, const EffectMeta *em) : meta(em), flags_(0), shader_program_(nullptr), - texture(nullptr), + texture(0), + tex_width_(0), + tex_height_(0), isOpen(false), bound(false), iterations(1), @@ -886,24 +888,26 @@ GLuint Effect::process_superimpose(double timecode) { redrew_image = true; } - if (texture == nullptr || texture->width() != img.width() || texture->height() != img.height()) { + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); + + if (texture == 0 || tex_width_ != img.width() || tex_height_ != img.height()) { delete_texture(); - texture = new QOpenGLTexture(QOpenGLTexture::Target2D); - texture->setSize(img.width(), img.height()); - texture->setFormat(QOpenGLTexture::RGBA8_UNorm); - texture->setMipLevels(texture->maximumMipLevels()); - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); + tex_width_ = img.width(); + tex_height_ = img.height(); - redrew_image = true; + f->glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA8, tex_width_, tex_height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.constBits() + ); + + redrew_image = false; } if (redrew_image) { - texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, img.constBits()); + f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex_width_, tex_height_, GL_RGBA, GL_UNSIGNED_BYTE, img.constBits()); } - return texture->textureId(); + return texture; } void Effect::process_audio(double, double, quint8*, int, int) {} @@ -1080,8 +1084,8 @@ bool Effect::valueHasChanged(double timecode) { } void Effect::delete_texture() { - delete texture; - texture = nullptr; + QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &texture); + texture = 0; } const EffectMeta* get_meta_from_name(const QString& input) { diff --git a/effects/effect.h b/effects/effect.h index 89d4809bd..8fc3918cb 100644 --- a/effects/effect.h +++ b/effects/effect.h @@ -229,7 +229,9 @@ protected: // superimpose effect QImage img; - QOpenGLTexture* texture; + GLuint texture; + int tex_width_; + int tex_height_; // enable effect to update constantly virtual bool AlwaysUpdate(); diff --git a/rendering/cacher.cpp b/rendering/cacher.cpp index 784ee3b87..308440b25 100644 --- a/rendering/cacher.cpp +++ b/rendering/cacher.cpp @@ -1124,8 +1124,6 @@ void Cacher::CloseWorker() { avformat_close_input(&formatCtx); } - clip->reset(); - qInfo() << "Clip closed on track" << clip->track(); } diff --git a/rendering/framebufferobject.cpp b/rendering/framebufferobject.cpp index c88ad1406..c69995064 100644 --- a/rendering/framebufferobject.cpp +++ b/rendering/framebufferobject.cpp @@ -66,7 +66,7 @@ void FramebufferObject::Create(QOpenGLContext *ctx, int width, int height) );*/ ctx->functions()->glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr + GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr ); // set texture filtering to bilinear diff --git a/rendering/renderfunctions.cpp b/rendering/renderfunctions.cpp index b7cd99347..2d2d0b1e7 100644 --- a/rendering/renderfunctions.cpp +++ b/rendering/renderfunctions.cpp @@ -468,7 +468,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { params.texture_failed = true; } else { // retrieve ID from c->texture - textureID = c->texture->textureId(); + textureID = c->texture; } if (textureID == 0) { @@ -530,6 +530,13 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { } #ifndef NO_OCIO + + // Convert texture to float + if (textureID != c->fbo.at(0).texture() && textureID != c->fbo.at(1).texture()) { + textureID = draw_clip(params.ctx, params.pipeline, c->fbo.at(fbo_switcher), textureID, true); + fbo_switcher = !fbo_switcher; + } + // Convert frame from source to linear colorspace if (olive::CurrentConfig.enable_color_management) { diff --git a/timeline/clip.cpp b/timeline/clip.cpp index 240830155..99b2612e6 100644 --- a/timeline/clip.cpp +++ b/timeline/clip.cpp @@ -57,8 +57,7 @@ Clip::Clip(Sequence* s) : undeletable = false; replaced = false; open_ = false; - - reset(); + texture = 0; } ClipPtr Clip::copy(Sequence* s) { @@ -196,10 +195,6 @@ void Clip::move(ComboAction* ca, long iin, long iout, long iclip_in, int itrack, } } -void Clip::reset() { - texture = nullptr; -} - void Clip::reset_audio() { if (UsesCacher()) { cacher.ResetAudio(); @@ -503,8 +498,8 @@ void Clip::Close(bool wait) { } // destroy opengl texture in main thread - delete texture; - texture = nullptr; + QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &texture); + texture = 0; // close all effects for (int i=0;icontains(frame)) { + bool allocate_data = false; + // check if the opengl texture exists yet, create it if not - if (texture == nullptr) { - texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + if (texture == 0) { + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); - // the raw frame size may differ from the one we're using (e.g. a lower resolution proxy), so we make sure - // the texture is using the correct dimensions, but then treat it as if it's the original resolution in the - // composition - texture->setSize(cacher.media_width(), cacher.media_height()); + // create texture object + f->glGenTextures(1, &texture); + + f->glBindTexture(GL_TEXTURE_2D, texture); + + // set texture filtering to bilinear + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // queue an allocation ahead + allocate_data = true; - texture->setFormat(QOpenGLTexture::RGBA32F); - texture->setMipLevels(texture->maximumMipLevels()); - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::Float32); } QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/kRGBAComponentCount); - /* - // 2 data buffers to ping-pong between - bool using_db_1 = true; - uint8_t* data_buffer_1 = frame->data[0]; - uint8_t* data_buffer_2 = nullptr; + int video_width = cacher.media_width(); + int video_height = cacher.media_height(); - int frame_size = frame->linesize[0]*frame->height; - - for (int i=0;iFlags() & Effect::ImageFlag) && e->IsEnabled()) { - if (data_buffer_1 == frame->data[0]) { - data_buffer_1 = new uint8_t[frame_size]; - data_buffer_2 = new uint8_t[frame_size]; - - memcpy(data_buffer_1, frame->data[0], frame_size); - } - - e->process_image(get_timecode(this, cacher_frame), - using_db_1 ? data_buffer_1 : data_buffer_2, - using_db_1 ? data_buffer_2 : data_buffer_1, - frame_size - ); - - using_db_1 = !using_db_1; - } + if (allocate_data) { + // the raw frame size may differ from the one we're using (e.g. a lower resolution proxy), so we make sure + // the texture is using the correct dimensions, but then treat it as if it's the original resolution in the + // composition + f->glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA8, video_width, video_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0] + ); + } else { + f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video_width, video_height, GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0]); } - */ - texture->setData(QOpenGLTexture::RGBA, - QOpenGLTexture::UInt8, - const_cast(frame->data[0])); - - /* - if (data_buffer_1 != frame->data[0]) { - delete [] data_buffer_1; - delete [] data_buffer_2; - } - */ + f->glBindTexture(GL_TEXTURE_2D, 0); f->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); diff --git a/timeline/clip.h b/timeline/clip.h index a09eae6c0..ca3f56eb6 100644 --- a/timeline/clip.h +++ b/timeline/clip.h @@ -116,7 +116,6 @@ public: AVRational time_base(); void reset_audio(); - void reset(); void refresh(); long length(); @@ -154,7 +153,7 @@ public: // video playback variables QVector fbo; - QOpenGLTexture* texture; + GLuint texture; long texture_frame; #ifndef NO_OCIO