Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.13.2
-
None
-
-
c0fd354690a6de2923e975bb4586fa5bbf310bb1 (qt/qtdatavis3d/dev) 473e19398649a32b36ead33bb086f38b33edfc08 (qt/tqtc-qtdatavis3d/5.15) 6b627c3e060b83251c30b0adb26bfb8c55120255 (qt/qtdatavis3d/6.1)
Description
When using Scatter3D with optimizationHints set to OptimizationStatic there is a memory leak every time the data is updated.
How it occured:
- I render a Scatter3D-component in QML and use addSeries() to connect it to a QScatter3DSeries in c++.
- I set optimizationHints to OptimizationStatic.
- Then I regurarly update the series with new data using resetArray().
- Every time the data is updated my RAM fills up more. I send around 200 000 points every time.
After some debugging and testing I think the bug is caused by the buffers never being deleted. Here is the lead that I followed:
- When the scatter-data is updated, the updateData()-method of "scatter3drenderer.cpp" is called.
- Then if opimizationHints are OptimizationStatic and mesh is not MeshPoint, the buffers are updated using the fullLoad()-method from "scatterobjectbufferhelper.cpp" shown below.
- As you can see in the first line of the method, m_meshDataLoaded is set to false.
- Then further down, without any changes to m_meshDataLoaded, the buffers are deleted only if m_meshDataLoaded is true. This means that the buffers are never deleted.
- I tested changing the if-statement from checking for true into checking for false and this removed the memory leak, but I am unfamiliar with the meaning behind this if-statement so I don't know what would be a good solution.
- Looking to the equivalent load()-method for MeshPoint in "scatterpointbufferhelper.cpp", it deletes the buffers in a similar fashion, but it doesn't set m_meshDataLoaded to false first.
scatterobjectbufferhelper.cpp:
void ScatterObjectBufferHelper::fullLoad(ScatterSeriesRenderCache *cache, qreal dotScale) { m_meshDataLoaded = false; m_indexCount = 0; ObjectHelper *dotObj = cache->object(); const ScatterRenderItemArray &renderArray = cache->renderArray(); const uint renderArraySize = renderArray.size(); if (renderArraySize == 0) return; // No use to go forward uint itemCount = 0; QQuaternion seriesRotation(cache->meshRotation()); if (m_meshDataLoaded) { // Delete old data glDeleteBuffers(1, &m_vertexbuffer); glDeleteBuffers(1, &m_uvbuffer); glDeleteBuffers(1, &m_normalbuffer); glDeleteBuffers(1, &m_elementbuffer); m_vertexbuffer = 0; m_uvbuffer = 0; m_normalbuffer = 0; m_elementbuffer = 0; } . . .