diff options
author | Wieland Hagen <wieland.hagen@kdab.com> | 2017-02-01 15:38:38 +0700 |
---|---|---|
committer | Wieland Hagen <wieland.hagen@kdab.com> | 2017-02-01 09:29:11 +0000 |
commit | f1c21aaae49d0a356ecfab268994381932b6d327 (patch) | |
tree | 15b1343e9041723b647b49ff89111274475b5ef6 /src/render/backend/renderer.cpp | |
parent | 0da1d0e6a93e9c1f745f5ff3b8d628a2de9b0fa3 (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.cpp | 46 |
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 |