diff --git a/app/render/backend/opengl/CMakeLists.txt b/app/render/backend/opengl/CMakeLists.txt index 0b292eadd..38148afc4 100644 --- a/app/render/backend/opengl/CMakeLists.txt +++ b/app/render/backend/opengl/CMakeLists.txt @@ -29,6 +29,8 @@ set(OLIVE_SOURCES render/backend/opengl/openglshadercache.h render/backend/opengl/opengltexture.h render/backend/opengl/opengltexture.cpp + render/backend/opengl/opengltexturecache.h + render/backend/opengl/opengltexturecache.cpp render/backend/opengl/openglworker.h render/backend/opengl/openglworker.cpp PARENT_SCOPE diff --git a/app/render/backend/opengl/opengltexturecache.cpp b/app/render/backend/opengl/opengltexturecache.cpp new file mode 100644 index 000000000..a3b1d4600 --- /dev/null +++ b/app/render/backend/opengl/opengltexturecache.cpp @@ -0,0 +1,71 @@ +#include "opengltexturecache.h" + +OpenGLTextureCache::~OpenGLTextureCache() +{ + foreach (Reference* ref, existing_references_) { + ref->ParentKilled(); + } +} + +OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(const VideoRenderingParams ¶ms) +{ + OpenGLTexturePtr texture = nullptr; + + lock_.lock(); + + // Iterate through textures and see if we have one that matches these parameters + for (int i=0;iwidth() == params.effective_width() + && test->height() == params.effective_height() + && test->format() == params.format()) { + texture = test; + available_textures_.removeAt(i); + break; + } + } + + lock_.unlock(); + + // If we didn't find a texture, we'll need to create one + if (!texture) { + texture = std::make_shared(); + texture->Create(QOpenGLContext::currentContext(), params.effective_width(), params.effective_height(), params.format()); + } + + return std::make_shared(this, texture); +} + +void OpenGLTextureCache::Relinquish(OpenGLTextureCache::Reference *ref) +{ + lock_.lock(); + + existing_references_.removeOne(ref); + available_textures_.append(ref->texture()); + + lock_.unlock(); +} + +OpenGLTextureCache::Reference::Reference(OpenGLTextureCache *parent, OpenGLTexturePtr texture) : + parent_(parent), + texture_(texture) +{ +} + +OpenGLTextureCache::Reference::~Reference() +{ + if (parent_) { + parent_->Relinquish(this); + } +} + +OpenGLTexturePtr OpenGLTextureCache::Reference::texture() +{ + return texture_; +} + +void OpenGLTextureCache::Reference::ParentKilled() +{ + parent_ = nullptr; +} diff --git a/app/render/backend/opengl/opengltexturecache.h b/app/render/backend/opengl/opengltexturecache.h new file mode 100644 index 000000000..78092b076 --- /dev/null +++ b/app/render/backend/opengl/opengltexturecache.h @@ -0,0 +1,50 @@ +#ifndef OPENGLTEXTURECACHE_H +#define OPENGLTEXTURECACHE_H + +#include + +#include "opengltexture.h" +#include "render/videoparams.h" + +class OpenGLTextureCache +{ +public: + class Reference { + public: + Reference(OpenGLTextureCache* parent, OpenGLTexturePtr texture); + ~Reference(); + + DISABLE_COPY_MOVE(Reference) + + OpenGLTexturePtr texture(); + + void ParentKilled(); + + private: + OpenGLTextureCache* parent_; + + OpenGLTexturePtr texture_; + }; + + using ReferencePtr = std::shared_ptr; + + OpenGLTextureCache() = default; + + ~OpenGLTextureCache(); + + DISABLE_COPY_MOVE(OpenGLTextureCache) + + ReferencePtr Get(const VideoRenderingParams& params); + +private: + void Relinquish(Reference* ref); + + QMutex lock_; + + QList available_textures_; + + QList existing_references_; + +}; + +#endif // OPENGLTEXTURECACHE_H