Skip to content

Commit

Permalink
gfx: fix memory leak with meshes generated from arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
jcelerier committed Dec 27, 2024
1 parent 040d8a9 commit fc658e2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/plugins/score-plugin-gfx/Gfx/Graph/NodeRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ void GenericNodeRenderer::defaultMeshUpdate(
// Or... just put all of one frame's message in one vector and push that one at the end of the audio frame.
if(node.hasGeometryChanged(geometryChangedIndex) && node.geometry.meshes)
{
std::tie(m_mesh, m_meshbufs) = renderer.acquireMesh(node.geometry, res);
std::tie(m_mesh, m_meshbufs)
= renderer.acquireMesh(node.geometry, res, m_mesh, m_meshbufs);
}
}

Expand Down
33 changes: 32 additions & 1 deletion src/plugins/score-plugin-gfx/Gfx/Graph/RenderList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,10 @@ QImage RenderList::adaptImage(const QImage& frame)
}

RenderList::Buffers RenderList::acquireMesh(
const ossia::geometry_spec& spec, QRhiResourceUpdateBatch& res) noexcept
const ossia::geometry_spec& spec, QRhiResourceUpdateBatch& res, const Mesh* current,
MeshBuffers currentbufs) noexcept
{
// 1. Try to find mesh from the exact same geometry
const auto& [p, f] = spec;
if(auto it = m_customMeshCache.find(spec); it != m_customMeshCache.end())
{
Expand All @@ -214,6 +216,35 @@ RenderList::Buffers RenderList::acquireMesh(
}
}

// 2. If not found try to see if the mesh is already used
for(const auto& [k, v] : m_customMeshCache)
{
if(v == current)
{
auto m = const_cast<CustomMesh*>(safe_cast<const CustomMesh*>(current));

if(m)
{
auto meshbufs_it = this->m_vertexBuffers.find(m);
SCORE_ASSERT(meshbufs_it != this->m_vertexBuffers.end());
SCORE_ASSERT(meshbufs_it->second.index == currentbufs.index);
SCORE_ASSERT(meshbufs_it->second.mesh == currentbufs.mesh);
auto mb = currentbufs;
auto cur_idx = p->dirty_index;

{
m->reload(*p, f);
m->update(mb, res);
// FIXME atomic !!
if(cur_idx > m->dirtyGeometryIndex)
m->dirtyGeometryIndex = cur_idx;
}
return {m, mb};
}
}
}

// 3. Really not found, we allocate a new mesh for good
auto m = new CustomMesh{*p, f};
auto meshbufs = initMeshBuffer(*m, res);

Expand Down
5 changes: 3 additions & 2 deletions src/plugins/score-plugin-gfx/Gfx/Graph/RenderList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ class SCORE_PLUGIN_GFX_EXPORT RenderList
RenderState& state;

using Buffers = std::pair<const Mesh* const, MeshBuffers>;
Buffers
acquireMesh(const ossia::geometry_spec&, QRhiResourceUpdateBatch& res) noexcept;
Buffers acquireMesh(
const ossia::geometry_spec&, QRhiResourceUpdateBatch& res, const Mesh* current,
MeshBuffers currentbufs) noexcept;

/**
* @brief Nodes present in this RenderList, in order
Expand Down

0 comments on commit fc658e2

Please sign in to comment.