diff options
Diffstat (limited to 'src/render/renderers/opengl/renderer/renderer.cpp')
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer.cpp | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 3957894e5..f76673866 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -241,7 +241,6 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_lastFrameCorrect(0) , m_glContext(nullptr) , m_shareContext(nullptr) - , m_shaderCache(new ShaderCache()) , m_pickBoundingVolumeJob(PickBoundingVolumeJobPtr::create()) , m_rayCastingJob(RayCastingJobPtr::create()) , m_time(0) @@ -328,7 +327,6 @@ Renderer::~Renderer() delete m_renderQueue; delete m_defaultRenderStateSet; - delete m_shaderCache; delete m_glResourceManagers; if (!m_ownedContext) @@ -417,8 +415,9 @@ QOpenGLContext *Renderer::shareContext() const // Executed in the reloadDirtyShader job void Renderer::loadShader(Shader *shader, HShader shaderHandle) { - Q_UNUSED(shader) - m_dirtyShaders.push_back(shaderHandle); + Q_UNUSED(shader); + if (!m_dirtyShaders.contains(shaderHandle)) + m_dirtyShaders.push_back(shaderHandle); } void Renderer::setOpenGLContext(QOpenGLContext *context) @@ -491,9 +490,6 @@ void Renderer::initialize() m_shareContext->create(); } - // Set shader cache on submission context and command thread - m_submissionContext->setShaderCache(m_shaderCache); - // Note: we don't have a surface at this point // The context will be made current later on (at render time) m_submissionContext->setOpenGLContext(ctx); @@ -605,6 +601,10 @@ void Renderer::releaseGraphicsResources() buffer->destroy(m_submissionContext.data()); } + // Do the same thing with shaders + const QVector<GLShader *> shaders = m_glResourceManagers->glShaderManager()->takeActiveResources(); + qDeleteAll(shaders); + // Do the same thing with VAOs const QVector<HVao> activeVaos = m_glResourceManagers->vaoManager()->activeHandles(); for (const HVao &vaoHandle : activeVaos) { @@ -770,6 +770,13 @@ void Renderer::doRender(bool swapBuffers) // 2) Update VAO and copy data into commands to allow concurrent submission prepareCommandsSubmission(renderViews); preprocessingComplete = true; + + // Purge shader which aren't used any longer + static int callCount = 0; + ++callCount; + const int shaderPurgePeriod = 600; + if (callCount % shaderPurgePeriod == 0) + m_glResourceManagers->glShaderManager()->purge(); } } } @@ -923,7 +930,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView if (command.m_type == RenderCommand::Draw) { Geometry *rGeometry = m_nodesManager->data<Geometry, GeometryManager>(command.m_geometry); GeometryRenderer *rGeometryRenderer = m_nodesManager->data<GeometryRenderer, GeometryRendererManager>(command.m_geometryRenderer); - Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command.m_shader); + GLShader *shader = command.m_glShader; // We should never have inserted a command for which these are null // in the first place @@ -958,7 +965,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView if (!command.m_activeAttributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) { Profiling::GLTimeRecorder recorder(Profiling::VAOUpload); // Activate shader - m_submissionContext->activateShader(shader->dna()); + m_submissionContext->activateShader(shader); // Bind VAO vao->bind(); // Update or set Attributes and Buffers for the given rGeometry and Command @@ -978,7 +985,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView shader->prepareUniforms(command.m_parameterPack); } else if (command.m_type == RenderCommand::Compute) { - Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command.m_shader); + GLShader *shader = command.m_glShader; Q_ASSERT(shader); // Prepare the ShaderParameterPack based on the active uniforms of the shader @@ -1012,7 +1019,7 @@ void Renderer::lookForAbandonedVaos() // 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 && vao->isAbandoned(m_nodesManager->geometryManager(), m_nodesManager->shaderManager())) { + if (vao && vao->isAbandoned(m_nodesManager->geometryManager(), m_glResourceManagers->glShaderManager())) { m_abandonedVaosMutex.lock(); m_abandonedVaos.push_back(handle); m_abandonedVaosMutex.unlock(); @@ -1128,8 +1135,7 @@ void Renderer::reloadDirtyShaders() } } - // If the shader hasn't been loaded, load it - if (shader != nullptr && !shader->isLoaded()) + if (shader != nullptr && shader->isDirty()) loadShader(shader, shaderHandle); } } @@ -1301,7 +1307,7 @@ void Renderer::updateGLResources() continue; // Compile shader - m_submissionContext->loadShader(shader, shaderManager); + m_submissionContext->loadShader(shader, shaderManager, m_glResourceManagers->glShaderManager()); } } #endif @@ -1433,6 +1439,16 @@ void Renderer::cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId) } } +// Render Thread +void Renderer::cleanupShader(const Shader *shader) +{ + GLShaderManager *glShaderManager = m_glResourceManagers->glShaderManager(); + GLShader *glShader = glShaderManager->lookupResource(shader->peerId()); + + if (glShader != nullptr) + glShaderManager->abandon(glShader, shader); +} + // Called by SubmitRenderView void Renderer::downloadGLBuffers() { @@ -2051,7 +2067,8 @@ void Renderer::performCompute(const RenderView *, RenderCommand *command) { { Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate); - m_submissionContext->activateShader(command->m_shaderDna); + GLShader *shader = m_glResourceManagers->glShaderManager()->lookupResource(command->m_shaderId); + m_submissionContext->activateShader(shader); } { Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate); @@ -2077,7 +2094,7 @@ void Renderer::createOrUpdateVAO(RenderCommand *command, HVao *previousVaoHandle, OpenGLVertexArrayObject **vao) { - const VAOIdentifier vaoKey(command->m_geometry, command->m_shader); + const VAOIdentifier vaoKey(command->m_geometry, command->m_shaderId); VAOManager *vaoManager = m_glResourceManagers->vaoManager(); command->m_vao = vaoManager->lookupHandle(vaoKey); @@ -2133,7 +2150,8 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv) { Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate); //// We activate the shader here - if (!m_submissionContext->activateShader(command.m_shaderDna)) { + GLShader *shader = command.m_glShader; + if (!m_submissionContext->activateShader(shader)) { allCommandsIssued = false; continue; } @@ -2195,7 +2213,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv) bool Renderer::updateVAOWithAttributes(Geometry *geometry, const RenderCommand *command, - Shader *shader, + GLShader *shader, bool forceUpdate) { m_dirtyAttributes.reserve(m_dirtyAttributes.size() + geometry->attributes().size()); @@ -2300,6 +2318,16 @@ void Renderer::cleanGraphicsResources() m_glResourceManagers->vaoManager()->release(vaoHandle); } } + + // Abandon GL shaders when a Shader node is destroyed Note: We are sure + // that when this gets executed, all scene changes have been received and + // shader nodes updated + const QVector<Qt3DCore::QNodeId> cleanedUpShaderIds = m_nodesManager->shaderManager()->takeShaderIdsToCleanup(); + for (const Qt3DCore::QNodeId shaderCleanedUpId: cleanedUpShaderIds) { + cleanupShader(m_nodesManager->shaderManager()->lookupResource(shaderCleanedUpId)); + // We can really release the texture at this point + m_nodesManager->shaderManager()->releaseResource(shaderCleanedUpId); + } } QList<QPair<QObject *, QMouseEvent>> Renderer::pendingPickingEvents() const |