From 07f63ddc17cf2128658385932b523cbf82b6e057 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:12:19 -0700 Subject: [PATCH] renderer: reinstated new and improved texture cache --- app/codec/ffmpeg/ffmpegdecoder.cpp | 33 +++------------- app/codec/ffmpeg/ffmpegdecoder.h | 4 -- app/render/opengl/openglrenderer.cpp | 25 ++++++------ app/render/opengl/openglrenderer.h | 6 +-- app/render/renderer.cpp | 57 ++++++++++++++++------------ app/render/renderer.h | 12 +++--- app/render/texture.cpp | 4 +- 7 files changed, 60 insertions(+), 81 deletions(-) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 9f66a9e3e..c2dbe2488 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -61,9 +61,6 @@ FFmpegDecoder::FFmpegDecoder() : input_fmt_(AV_PIX_FMT_NONE), native_internal_pix_fmt_(VideoParams::kFormatInvalid), native_output_pix_fmt_(VideoParams::kFormatInvalid), - y_tex_(nullptr), - u_tex_(nullptr), - v_tex_(nullptr), working_frame_(nullptr), working_packet_(nullptr), cache_at_zero_(false), @@ -219,12 +216,7 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration plane_params.set_channel_count(1); plane_params.set_divider(1); plane_params.set_format(native_internal_pix_fmt_); - - if (!y_tex_) { - y_tex_ = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size); - } else { - y_tex_->Upload(f->data[0], f->linesize[0] / px_size); - } + TexturePtr y_plane = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size); if (src_fmt == AV_PIX_FMT_YUV420P || src_fmt == AV_PIX_FMT_YUV422P @@ -244,22 +236,13 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration plane_params.set_height(plane_params.height()/2); } - if (!u_tex_) { - u_tex_ = renderer->CreateTexture(plane_params, f->data[1], f->linesize[1] / px_size); - } else { - u_tex_->Upload(f->data[1], f->linesize[1] / px_size); - } - - if (!v_tex_) { - v_tex_ = renderer->CreateTexture(plane_params, f->data[2], f->linesize[2] / px_size); - } else { - v_tex_->Upload(f->data[2], f->linesize[2] / px_size); - } + TexturePtr u_plane = renderer->CreateTexture(plane_params, f->data[1], f->linesize[1] / px_size); + TexturePtr v_plane = renderer->CreateTexture(plane_params, f->data[2], f->linesize[2] / px_size); ShaderJob job; - job.Insert(QStringLiteral("y_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(y_tex_))); - job.Insert(QStringLiteral("u_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(u_tex_))); - job.Insert(QStringLiteral("v_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(v_tex_))); + job.Insert(QStringLiteral("y_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(y_plane))); + job.Insert(QStringLiteral("u_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(u_plane))); + job.Insert(QStringLiteral("v_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(v_plane))); job.Insert(QStringLiteral("bits_per_pixel"), NodeValue(NodeValue::kInt, bits_per_pixel)); job.Insert(QStringLiteral("jpeg_range"), NodeValue(NodeValue::kBoolean, jpeg_range)); @@ -313,10 +296,6 @@ void FFmpegDecoder::CloseInternal() input_fmt_ = AV_PIX_FMT_NONE; native_internal_pix_fmt_ = VideoParams::kFormatInvalid; native_output_pix_fmt_ = VideoParams::kFormatInvalid; - - y_tex_ = nullptr; - u_tex_ = nullptr; - v_tex_ = nullptr; } QString FFmpegDecoder::id() const diff --git a/app/codec/ffmpeg/ffmpegdecoder.h b/app/codec/ffmpeg/ffmpegdecoder.h index 837d5e04c..1c0d25bb8 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.h +++ b/app/codec/ffmpeg/ffmpegdecoder.h @@ -165,10 +165,6 @@ private: VideoParams::Format native_output_pix_fmt_; int native_channel_count_; - TexturePtr y_tex_; - TexturePtr u_tex_; - TexturePtr v_tex_; - AVFrame *working_frame_; AVPacket *working_packet_; diff --git a/app/render/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp index a06c44ffd..014c124bc 100644 --- a/app/render/opengl/openglrenderer.cpp +++ b/app/render/opengl/openglrenderer.cpp @@ -177,7 +177,7 @@ void OpenGLRenderer::ClearDestination(Texture *texture, double r, double g, doub GL_PREAMBLE; if (texture) { - AttachTextureAsDestination(texture); + AttachTextureAsDestination(texture->id()); } ClearDestinationInternal(r, g, b, a); @@ -225,7 +225,7 @@ QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth, V return texture; } -void OpenGLRenderer::AttachTextureAsDestination(Texture* texture) +void OpenGLRenderer::AttachTextureAsDestination(const QVariant &texture) { PRINT_GL_ERRORS; @@ -233,7 +233,7 @@ void OpenGLRenderer::AttachTextureAsDestination(Texture* texture) functions_->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - texture->id().value(), + texture.value(), 0); } @@ -291,14 +291,13 @@ void OpenGLRenderer::DestroyNativeShader(QVariant shader) functions_->glDeleteProgram(program); } -void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int linesize) +void OpenGLRenderer::UploadToTexture(const QVariant &handle, const VideoParams &p, const void *data, int linesize) { GL_PREAMBLE; - GLuint t = texture->id().value(); - const VideoParams& p = texture->params(); + GLuint t = handle.value(); - bool is_3d = texture->params().is_3d(); + bool is_3d = p.is_3d(); GLenum tex_type = !is_3d ? GL_TEXTURE_2D : GL_TEXTURE_3D; GLenum tex_binding = !is_3d ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D; @@ -332,16 +331,14 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin functions_->glBindTexture(tex_type, current_tex); } -void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int linesize) +void OpenGLRenderer::DownloadFromTexture(const QVariant &id, const VideoParams &p, void *data, int linesize) { GL_PREAMBLE; - const VideoParams& p = texture->params(); - GLint current_tex; functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex); - AttachTextureAsDestination(texture); + AttachTextureAsDestination(id); functions_->glPixelStorei(GL_PACK_ROW_LENGTH, linesize); @@ -372,7 +369,7 @@ void OpenGLRenderer::Flush() Color OpenGLRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt) { - AttachTextureAsDestination(texture); + AttachTextureAsDestination(texture->id()); QByteArray data(VideoParams::GetBytesPerPixel(texture->format(), texture->channel_count()), Qt::Uninitialized); @@ -610,7 +607,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video // This is the last iteration, draw to the destination if (destination) { // If we have a destination texture, draw to it - AttachTextureAsDestination(destination); + AttachTextureAsDestination(destination->id()); } else if (iteration > 0) { // Otherwise, if we were iterating before, detach texture now DetachTextureAsDestination(); @@ -622,7 +619,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video } } else { // Always draw to output_tex, which gets swapped with input_tex every iteration - AttachTextureAsDestination(output_tex.get()); + AttachTextureAsDestination(output_tex->id()); } if (iteration > 0) { diff --git a/app/render/opengl/openglrenderer.h b/app/render/opengl/openglrenderer.h index 1377e475c..fe7f0098a 100644 --- a/app/render/opengl/openglrenderer.h +++ b/app/render/opengl/openglrenderer.h @@ -55,9 +55,9 @@ public: virtual void DestroyNativeShader(QVariant shader) override; - virtual void UploadToTexture(olive::Texture* texture, const void* data, int linesize) override; + virtual void UploadToTexture(const QVariant &handle, const VideoParams ¶ms, const void* data, int linesize) override; - virtual void DownloadFromTexture(olive::Texture* texture, void* data, int linesize) override; + virtual void DownloadFromTexture(const QVariant &handle, const VideoParams ¶ms, void* data, int linesize) override; virtual void Flush() override; @@ -83,7 +83,7 @@ private: static GLenum GetPixelFormat(int channel_count); - void AttachTextureAsDestination(olive::Texture* texture); + void AttachTextureAsDestination(const QVariant &texture); void DetachTextureAsDestination(); diff --git a/app/render/renderer.cpp b/app/render/renderer.cpp index 39a0aaff0..98566a244 100644 --- a/app/render/renderer.cpp +++ b/app/render/renderer.cpp @@ -29,45 +29,52 @@ namespace olive { Renderer::Renderer(QObject *parent) : QObject(parent) { - QTimer *texture_garbage_collector = new QTimer(this); - texture_garbage_collector->setInterval(MAX_TEXTURE_LIFE); - connect(texture_garbage_collector, &QTimer::timeout, this, &Renderer::ClearOldTextures); - texture_garbage_collector->start(); } TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, const void *data, int linesize) { QVariant v; - /*for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); it++) { - if (it->width == params.effective_width() - && it->height == params.effective_height() - && it->depth == params.effective_depth() - && it->format == params.format() - && it->channel_count == params.channel_count()) { - this->Flush(); - v = it->handle; - texture_cache_.erase(it); - break; + if (USE_TEXTURE_CACHE) { + for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); it++) { + if (it->width == params.effective_width() + && it->height == params.effective_height() + && it->depth == params.effective_depth() + && it->format == params.format() + && it->channel_count == params.channel_count()) { + this->Flush(); + v = it->handle; + texture_cache_.erase(it); + break; + } } - }*/ + } - v = CreateNativeTexture(params.effective_width(), params.effective_height(), params.effective_depth(), - params.format(), params.channel_count(), data, linesize); + if (v.isNull()) { + v = CreateNativeTexture(params.effective_width(), params.effective_height(), params.effective_depth(), + params.format(), params.channel_count(), data, linesize); + } else { + UploadToTexture(v, params, data, linesize); + } return CreateTextureFromNativeHandle(v, params); } void Renderer::DestroyTexture(Texture *texture) { - /*texture_cache_.push_back({texture->params().effective_width(), - texture->params().effective_height(), - texture->params().effective_depth(), - texture->params().format(), - texture->params().channel_count(), - texture->id(), - QDateTime::currentMSecsSinceEpoch()});*/ - DestroyNativeTexture(texture->id()); + if (USE_TEXTURE_CACHE) { + texture_cache_.push_back({texture->params().effective_width(), + texture->params().effective_height(), + texture->params().effective_depth(), + texture->params().format(), + texture->params().channel_count(), + texture->id(), + QDateTime::currentMSecsSinceEpoch()}); + + ClearOldTextures(); + } else { + DestroyNativeTexture(texture->id()); + } } TexturePtr Renderer::InterlaceTexture(TexturePtr top, TexturePtr bottom, const VideoParams ¶ms) diff --git a/app/render/renderer.h b/app/render/renderer.h index dc1fb19a0..96141df4e 100644 --- a/app/render/renderer.h +++ b/app/render/renderer.h @@ -91,9 +91,9 @@ public: virtual void DestroyNativeShader(QVariant shader) = 0; - virtual void UploadToTexture(olive::Texture* texture, const void* data, int linesize) = 0; + virtual void UploadToTexture(const QVariant &handle, const VideoParams ¶ms, const void* data, int linesize) = 0; - virtual void DownloadFromTexture(olive::Texture* texture, void* data, int linesize) = 0; + virtual void DownloadFromTexture(const QVariant &handle, const VideoParams ¶ms, void* data, int linesize) = 0; virtual void Flush() = 0; @@ -130,6 +130,8 @@ private: bool GetColorContext(const ColorTransformJob &color_job, ColorContext* ctx); + void ClearOldTextures(); + QHash color_cache_; struct CachedTexture @@ -143,7 +145,8 @@ private: qint64 accessed; }; - const int MAX_TEXTURE_LIFE = 10000; + static const int MAX_TEXTURE_LIFE = 5000; + static const bool USE_TEXTURE_CACHE = true; std::list texture_cache_; QMutex color_cache_mutex_; @@ -152,9 +155,6 @@ private: QVariant interlace_texture_; -private slots: - void ClearOldTextures(); - }; } diff --git a/app/render/texture.cpp b/app/render/texture.cpp index f3b5fb9d0..2c5c9fdea 100644 --- a/app/render/texture.cpp +++ b/app/render/texture.cpp @@ -36,14 +36,14 @@ Texture::~Texture() void Texture::Upload(void *data, int linesize) { if (renderer_) { - renderer_->UploadToTexture(this, data, linesize); + renderer_->UploadToTexture(this->id(), this->params(), data, linesize); } } void Texture::Download(void *data, int linesize) { if (renderer_) { - renderer_->DownloadFromTexture(this, data, linesize); + renderer_->DownloadFromTexture(this->id(), this->params(), data, linesize); } }