From b7a88d59ddb87bc10d6cea87edf5538cb83de891 Mon Sep 17 00:00:00 2001 From: Kai Blaschke Date: Mon, 24 Nov 2025 10:58:52 +0100 Subject: [PATCH] Keep references to textures and samplers in descriptors Previously, if the TextureManager was recreated, e.g. when changing the texture paths, all loaded textures were deleted, even if currently in use by a preset. Storing textures and samplers as shared pointers instead of weak pointers will make sure the objects are kept alive until the preset is unloaded. Signed-off-by: Kai Blaschke --- .../Renderer/TextureSamplerDescriptor.cpp | 50 +++++++++---------- .../Renderer/TextureSamplerDescriptor.hpp | 16 ++++-- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/libprojectM/Renderer/TextureSamplerDescriptor.cpp b/src/libprojectM/Renderer/TextureSamplerDescriptor.cpp index b9a7870f9..25efe8e39 100644 --- a/src/libprojectM/Renderer/TextureSamplerDescriptor.cpp +++ b/src/libprojectM/Renderer/TextureSamplerDescriptor.cpp @@ -20,71 +20,71 @@ TextureSamplerDescriptor::TextureSamplerDescriptor(const std::shared_ptr bool { - return m_texture.expired() || m_sampler.expired(); + return m_texture->Empty(); } void TextureSamplerDescriptor::Bind(GLint unit, const Shader& shader) const { - auto texture = m_texture.lock(); - auto sampler = m_sampler.lock(); - if (texture && sampler) + if (m_texture && m_sampler) { - texture->Bind(unit, sampler); + m_texture->Bind(unit, m_sampler); shader.SetUniformInt(std::string("sampler_" + m_samplerName).c_str(), unit); // Might be setting this more than once if the texture is used with different wrap/filter modes, but this rarely happens. - shader.SetUniformFloat4(std::string("texsize_" + m_sizeName).c_str(), {texture->Width(), - texture->Height(), - 1.0f / static_cast(texture->Width()), - 1.0f / static_cast(texture->Height())}); + shader.SetUniformFloat4(std::string("texsize_" + m_sizeName).c_str(), {m_texture->Width(), + m_texture->Height(), + 1.0f / static_cast(m_texture->Width()), + 1.0f / static_cast(m_texture->Height())}); // Bind shorthand random texture size uniform if (m_sizeName.substr(0, 4) == "rand" && m_sizeName.length() > 7 && m_sizeName.at(6) == '_') { - shader.SetUniformFloat4(std::string("texsize_" + m_sizeName.substr(0, 6)).c_str(), {texture->Width(), - texture->Height(), - 1.0f / static_cast(texture->Width()), - 1.0f / static_cast(texture->Height())}); + shader.SetUniformFloat4(std::string("texsize_" + m_sizeName.substr(0, 6)).c_str(), {m_texture->Width(), + m_texture->Height(), + 1.0f / static_cast(m_texture->Width()), + 1.0f / static_cast(m_texture->Height())}); } } } void TextureSamplerDescriptor::Unbind(GLint unit) { - auto texture = m_texture.lock(); - if (texture) + if (m_texture) { - texture->Unbind(unit); + m_texture->Unbind(unit); } Sampler::Unbind(unit); } auto TextureSamplerDescriptor::Texture() const -> std::shared_ptr { - return m_texture.lock(); + return m_texture; } -void TextureSamplerDescriptor::Texture(std::weak_ptr texture) +void TextureSamplerDescriptor::Texture(const std::shared_ptr& texture) { m_texture = texture; } +void TextureSamplerDescriptor::Texture(const std::weak_ptr& texture) +{ + m_texture = texture.lock(); +} + auto TextureSamplerDescriptor::Sampler() const -> std::shared_ptr { - return m_sampler.lock(); + return m_sampler; } auto TextureSamplerDescriptor::SamplerDeclaration() const -> std::string { - auto texture = m_texture.lock(); - auto sampler = m_sampler.lock(); - if (!texture || !sampler) + if (!m_texture || !m_sampler) { return {}; } std::string declaration = "uniform "; - if (texture->Type() == GL_TEXTURE_3D) + if (m_texture->Type() == GL_TEXTURE_3D) { declaration.append("sampler3D sampler_"); } @@ -109,9 +109,7 @@ auto TextureSamplerDescriptor::SamplerDeclaration() const -> std::string auto TextureSamplerDescriptor::TexSizeDeclaration() const -> std::string { - auto texture = m_texture.lock(); - auto sampler = m_sampler.lock(); - if (!texture || !sampler) + if (!m_texture || !m_sampler) { return {}; } diff --git a/src/libprojectM/Renderer/TextureSamplerDescriptor.hpp b/src/libprojectM/Renderer/TextureSamplerDescriptor.hpp index 40deba8ec..0e4d7997c 100644 --- a/src/libprojectM/Renderer/TextureSamplerDescriptor.hpp +++ b/src/libprojectM/Renderer/TextureSamplerDescriptor.hpp @@ -1,6 +1,10 @@ #pragma once +#include "Renderer/Sampler.hpp" #include "Renderer/Shader.hpp" +#include "Renderer/Texture.hpp" + +#include namespace libprojectM { namespace Renderer { @@ -65,11 +69,17 @@ public: */ auto Texture() const -> std::shared_ptr; + /** + * @brief Updates the internal texture with a new one. + * @param texture A shared pointer to the new texture. + */ + void Texture(const std::shared_ptr& texture); + /** * @brief Updates the internal texture with a new one. * @param texture A weak pointer to the new texture. */ - void Texture(std::weak_ptr texture); + void Texture(const std::weak_ptr& texture); /** * @brief Returns a pointer to the stored sampler. @@ -96,8 +106,8 @@ public: void TryUpdate(TextureManager& textureManager); private: - std::weak_ptr m_texture; //!< A weak reference to the texture. - std::weak_ptr m_sampler; //!< A weak reference to the sampler. + std::shared_ptr m_texture; //!< A reference to the texture. + std::shared_ptr m_sampler; //!< A reference to the sampler. std::string m_samplerName; //!< The name of the texture sampler as referenced in the shader. std::string m_sizeName; //!< The name of the "texsize_" uniform as referenced in the shader. bool m_updateFailed{false}; //!< Set to true if the update try failed, e.g. texture could not be loaded.