diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-10-08 08:08:21 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-10-14 08:04:40 +0200 |
commit | c8134efd470482e2254e7b232deb386828af5610 (patch) | |
tree | dda08eedc773b84b02b40660a61e987126815c7f /src/render/renderers/opengl | |
parent | ca48552bf2c150886fe1b064a061bb77bc76f230 (diff) |
Convert Shader/ShaderBuilder jobs to use direct sync
Change-Id: Ia56ba6176c86e34904611ae57e682ac9d52c79f7
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl')
-rw-r--r-- | src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp | 5 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer.cpp | 90 | ||||
-rw-r--r-- | src/render/renderers/opengl/renderer/renderer_p.h | 22 |
3 files changed, 64 insertions, 53 deletions
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp index f4bd8b871..333453ac7 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp @@ -279,7 +279,7 @@ void GraphicsContext::introspectShaderInterface(Shader *shader, QOpenGLShaderPro } -// Called by GL Command Thread +// Called by Renderer::updateGLResources void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager) { bool wasPresent = false; @@ -317,7 +317,8 @@ void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager) shader->setGraphicsContext(this); shader->setLoaded(true); - shader->markDirty(AbstractRenderer::AllDirty); + // Will force notifications to be sent to frontend at next frame + shader->markDirty(AbstractRenderer::ShadersDirty); } } diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 42af03d11..3da9b6c48 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -91,6 +91,8 @@ #include <Qt3DRender/private/renderviewbuilder_p.h> #include <Qt3DRender/private/setfence_p.h> #include <Qt3DRender/private/subtreeenabler_p.h> +#include <Qt3DRender/private/qshaderprogrambuilder_p.h> +#include <Qt3DRender/private/qshaderprogram_p.h> #include <Qt3DRender/qcameralens.h> #include <Qt3DCore/private/qeventfilterservice_p.h> @@ -191,16 +193,18 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create()) , m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create()) , m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::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_sendTextureChangesToFrontendJob(decltype(m_sendTextureChangesToFrontendJob)::create([] {}, - [this] (Qt3DCore::QAspectManager *m) { sendTextureChangesToFrontend(m); }, - JobTypes::SendTextureChangesToFrontend)) - , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) - , m_sendDisablesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend)) - , m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering)) - , m_syncLoadingJobs(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncLoadingJobs)) + , m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering)) + , m_vaoGathererJob(SynchronizerJobPtr::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering)) + , m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) + , m_sendTextureChangesToFrontendJob(SynchronizerPostFramePtr::create([] {}, + [this] (Qt3DCore::QAspectManager *m) { sendTextureChangesToFrontend(m); }, + JobTypes::SendTextureChangesToFrontend)) + , m_sendSetFenceHandlesToFrontendJob(SynchronizerJobPtr::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) + , m_sendDisablesToFrontendJob(SynchronizerJobPtr::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend)) + , m_introspectShaderJob(SynchronizerPostFramePtr::create([this] { reloadDirtyShaders(); }, + [this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); }, + JobTypes::DirtyShaderGathering)) + , m_syncLoadingJobs(SynchronizerJobPtr::create([] {}, JobTypes::SyncLoadingJobs)) , m_ownedContext(false) , m_offscreenHelper(nullptr) , m_shouldSwapBuffers(true) @@ -1104,45 +1108,22 @@ void Renderer::reloadDirtyShaders() if (shaderBuilder) { shaderBuilder->setGraphicsApi(*technique->graphicsApiFilter()); - for (int i = 0; i <= ShaderBuilder::Compute; i++) { - const auto builderType = static_cast<ShaderBuilder::ShaderType>(i); - if (!shaderBuilder->shaderGraph(builderType).isValid()) + for (int i = 0; i <= QShaderProgram::Compute; i++) { + const auto shaderType = static_cast<QShaderProgram::ShaderType>(i); + if (!shaderBuilder->shaderGraph(shaderType).isValid()) continue; - if (shaderBuilder->isShaderCodeDirty(builderType)) { - shaderBuilder->generateCode(builderType); + if (shaderBuilder->isShaderCodeDirty(shaderType)) { + shaderBuilder->generateCode(shaderType); + m_shaderBuilderUpdates.append(std::move(shaderBuilder->updates())); } - QShaderProgram::ShaderType shaderType = QShaderProgram::Vertex; - switch (builderType) { - case ShaderBuilder::Vertex: - shaderType = QShaderProgram::Vertex; - break; - case ShaderBuilder::TessellationControl: - shaderType = QShaderProgram::TessellationControl; - break; - case ShaderBuilder::TessellationEvaluation: - shaderType = QShaderProgram::TessellationEvaluation; - break; - case ShaderBuilder::Geometry: - shaderType = QShaderProgram::Geometry; - break; - case ShaderBuilder::Fragment: - shaderType = QShaderProgram::Fragment; - break; - case ShaderBuilder::Compute: - shaderType = QShaderProgram::Compute; - break; - } - - const auto code = shaderBuilder->shaderCode(builderType); + const auto code = shaderBuilder->shaderCode(shaderType); shader->setShaderCode(shaderType, code); } } - if (Q_UNLIKELY(shader->hasPendingNotifications())) - shader->submitPendingNotifications(); - // If the shader hasn't be loaded, load it + // If the shader hasn't been loaded, load it if (shader != nullptr && !shader->isLoaded()) loadShader(shader, shaderHandle); } @@ -1150,6 +1131,33 @@ void Renderer::reloadDirtyShaders() } } +// Executed in job postFrame +void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager) +{ + Q_ASSERT(isRunning()); + + // Sync Shader + const QVector<HShader> activeShaders = m_nodesManager->shaderManager()->activeHandles(); + for (const HShader &handle :activeShaders) { + Shader *s = m_nodesManager->shaderManager()->data(handle); + if (s->requiresFrontendSync()) { + QShaderProgram *frontend = static_cast<decltype(frontend)>(manager->lookupNode(s->peerId())); + QShaderProgramPrivate *dFrontend = static_cast<decltype(dFrontend)>(QNodePrivate::get(frontend)); + dFrontend->setStatus(s->status()); + dFrontend->setLog(s->log()); + s->unsetRequiresFrontendSync(); + } + } + + // Sync ShaderBuilder + const QVector<ShaderBuilderUpdate> shaderBuilderUpdates = std::move(m_shaderBuilderUpdates); + for (const ShaderBuilderUpdate &update : shaderBuilderUpdates) { + QShaderProgramBuilder *builder = static_cast<decltype(builder)>(manager->lookupNode(update.builderId)); + QShaderProgramBuilderPrivate *dBuilder = static_cast<decltype(dBuilder)>(QNodePrivate::get(builder)); + dBuilder->setShaderCode(update.shaderCode, update.shaderType); + } +} + // Executed in a job (as postFrame) void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager) { diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 41a071290..29aece008 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -81,6 +81,7 @@ #include <Qt3DRender/private/renderercache_p.h> #include <Qt3DRender/private/texture_p.h> #include <Qt3DRender/private/glfence_p.h> +#include <Qt3DRender/private/shaderbuilder_p.h> #include <QHash> #include <QMatrix4x4> @@ -154,7 +155,7 @@ class UpdateLevelOfDetailJob; typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr; using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; -using IntrospectShadersJobPtr = GenericLambdaJobPtr<std::function<void()>>; +using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>; class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer { @@ -220,7 +221,7 @@ public: inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; } inline SynchronizerJobPtr syncLoadingJobs() const { return m_syncLoadingJobs; } inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; } - inline IntrospectShadersJobPtr introspectShadersJob() const { return m_introspectShaderJob; } + inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; } inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; } inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; } inline Qt3DCore::QAspectJobPtr sendTextureChangesToFrontendJob() const { return m_sendTextureChangesToFrontendJob; } @@ -374,14 +375,13 @@ private: HVao *previousVAOHandle, OpenGLVertexArrayObject **vao); - GenericLambdaJobPtr<std::function<void ()>> m_bufferGathererJob; - GenericLambdaJobPtr<std::function<void ()>> m_vaoGathererJob; - GenericLambdaJobPtr<std::function<void ()>> m_textureGathererJob; - GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>> m_sendTextureChangesToFrontendJob; - GenericLambdaJobPtr<std::function<void ()>> m_sendSetFenceHandlesToFrontendJob; - GenericLambdaJobPtr<std::function<void ()>> m_sendDisablesToFrontendJob; - IntrospectShadersJobPtr m_introspectShaderJob; - + SynchronizerJobPtr m_bufferGathererJob; + SynchronizerJobPtr m_vaoGathererJob; + SynchronizerJobPtr m_textureGathererJob; + SynchronizerPostFramePtr m_sendTextureChangesToFrontendJob; + SynchronizerJobPtr m_sendSetFenceHandlesToFrontendJob; + SynchronizerJobPtr m_sendDisablesToFrontendJob; + SynchronizerPostFramePtr m_introspectShaderJob; SynchronizerJobPtr m_syncLoadingJobs; void lookForAbandonedVaos(); @@ -389,6 +389,7 @@ private: void lookForDownloadableBuffers(); void lookForDirtyTextures(); void reloadDirtyShaders(); + void sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager); void sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager); void sendSetFenceHandlesToFrontend(); void sendDisablesToFrontend(); @@ -404,6 +405,7 @@ private: QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences; QVector<Qt3DCore::QNodeId> m_updatedDisables; Qt3DCore::QNodeIdVector m_textureIdsToCleanup; + QVector<ShaderBuilderUpdate> m_shaderBuilderUpdates; bool m_ownedContext; |