summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl/renderer/renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/renderers/opengl/renderer/renderer.cpp')
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp64
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