summaryrefslogtreecommitdiffstats
path: root/src/render/backend/renderer.cpp
diff options
context:
space:
mode:
authorWieland Hagen <wieland.hagen@kdab.com>2017-02-01 15:38:38 +0700
committerWieland Hagen <wieland.hagen@kdab.com>2017-02-01 09:29:11 +0000
commitf1c21aaae49d0a356ecfab268994381932b6d327 (patch)
tree15b1343e9041723b647b49ff89111274475b5ef6 /src/render/backend/renderer.cpp
parent0da1d0e6a93e9c1f745f5ff3b8d628a2de9b0fa3 (diff)
Delete abandoned VAOs after each frame
Use a job to traverse all active VAO handles to check if the geometry and shader objects used to identify the VAO do stil exist. If not, let the renderer dispose the VAOs. Make sure to synchronize access to VAO state and hide state changes behind member functions. Change-Id: Ib77be67d55daa61885cd914af8d9cfc622cae940 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/backend/renderer.cpp')
-rw-r--r--src/render/backend/renderer.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index d38df13e2..100c4a33d 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -170,6 +170,7 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create())
, m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create())
, m_bufferGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering))
+ , m_vaoGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
, m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
, m_shaderGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyShaders(); }, JobTypes::DirtyShaderGathering))
, m_syncTextureLoadingJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncTextureLoading))
@@ -831,6 +832,23 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
}
// Executed in a job
+void Renderer::lookForAbandonedVaos()
+{
+ const QVector<HVao> activeVaos = m_nodesManager->vaoManager()->activeHandles();
+ for (HVao handle : activeVaos) {
+ OpenGLVertexArrayObject *vao = m_nodesManager->vaoManager()->data(handle);
+
+ // Make sure to only mark VAOs for deletion that were already created
+ // (ignore those that might be currently under construction in the render thread)
+ if (vao->isAbandoned(m_nodesManager->geometryManager(), m_nodesManager->shaderManager())) {
+ m_abandonedVaosMutex.lock();
+ m_abandonedVaos.push_back(handle);
+ m_abandonedVaosMutex.unlock();
+ }
+ }
+}
+
+// Executed in a job
void Renderer::lookForDirtyBuffers()
{
const QVector<HBuffer> activeBufferHandles = m_nodesManager->bufferManager()->activeHandles();
@@ -923,8 +941,6 @@ void Renderer::updateGLResources()
// We can really release the texture at this point
m_nodesManager->textureManager()->releaseResource(textureCleanedUpId);
}
-
-
}
// Render Thread
@@ -1267,6 +1283,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Jobs to prepare GL Resource upload
renderBinJobs.push_back(m_syncTextureLoadingJob);
+ renderBinJobs.push_back(m_vaoGathererJob);
renderBinJobs.push_back(m_bufferGathererJob);
renderBinJobs.push_back(m_textureGathererJob);
renderBinJobs.push_back(m_shaderGathererJob);
@@ -1368,16 +1385,15 @@ void Renderer::createOrUpdateVAO(RenderCommand *command,
HVao *previousVaoHandle,
OpenGLVertexArrayObject **vao)
{
+ const VAOIdentifier vaoKey(command->m_geometry, command->m_shader);
+
VAOManager *vaoManager = m_nodesManager->vaoManager();
- command->m_vao = vaoManager->lookupHandle(QPair<HGeometry, HShader>(command->m_geometry, command->m_shader));
+ command->m_vao = vaoManager->lookupHandle(vaoKey);
if (command->m_vao.isNull()) {
qCDebug(Rendering) << Q_FUNC_INFO << "Allocating new VAO";
- command->m_vao = vaoManager->getOrAcquireHandle(QPair<HGeometry, HShader>(command->m_geometry, command->m_shader));
- vaoManager->data(command->m_vao)->setGraphicsContext(m_graphicsContext.data());
- if (m_graphicsContext->supportsVAO())
- vaoManager->data(command->m_vao)->setVao(new QOpenGLVertexArrayObject());
- vaoManager->data(command->m_vao)->create();
+ command->m_vao = vaoManager->getOrAcquireHandle(vaoKey);
+ vaoManager->data(command->m_vao)->create(m_graphicsContext.data(), vaoKey);
}
if (*previousVaoHandle != command->m_vao) {
@@ -1573,6 +1589,20 @@ void Renderer::cleanGraphicsResources()
tex->destroyGLTexture();
delete tex;
}
+
+ // Delete abandoned VAOs
+ m_abandonedVaosMutex.lock();
+ const QVector<HVao> abandonedVaos = std::move(m_abandonedVaos);
+ m_abandonedVaosMutex.unlock();
+ for (HVao vaoHandle : abandonedVaos) {
+ // might have already been destroyed last frame, but added by the cleanup job before, so
+ // check if the VAO is really still existent
+ OpenGLVertexArrayObject *vao = m_nodesManager->vaoManager()->data(vaoHandle);
+ if (vao) {
+ vao->destroy();
+ m_nodesManager->vaoManager()->release(vaoHandle);
+ }
+ }
}
QList<QMouseEvent> Renderer::pendingPickingEvents() const