summaryrefslogtreecommitdiffstats
path: root/src/plugins/renderers/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/renderers/opengl')
-rw-r--r--src/plugins/renderers/opengl/debug/imguirenderer.cpp10
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp16
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h2
-rw-r--r--src/plugins/renderers/opengl/jobs/materialparametergathererjob.cpp26
-rw-r--r--src/plugins/renderers/opengl/jobs/materialparametergathererjob_p.h3
-rw-r--r--src/plugins/renderers/opengl/jobs/renderviewbuilderjob.cpp86
-rw-r--r--src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp42
-rw-r--r--src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h4
-rw-r--r--src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp7
-rw-r--r--src/plugins/renderers/opengl/jobs/renderviewjobutils.cpp9
-rw-r--r--src/plugins/renderers/opengl/jobs/renderviewjobutils_p.h4
-rw-r--r--src/plugins/renderers/opengl/opengl.pro3
-rw-r--r--src/plugins/renderers/opengl/renderer/gllights.cpp345
-rw-r--r--src/plugins/renderers/opengl/renderer/gllights_p.h (renamed from src/plugins/renderers/opengl/jobs/renderviewbuilderjob_p.h)84
-rw-r--r--src/plugins/renderers/opengl/renderer/glshader.cpp122
-rw-r--r--src/plugins/renderers/opengl/renderer/glshader_p.h53
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer.cpp36
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer.pri2
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer_p.h4
-rw-r--r--src/plugins/renderers/opengl/renderer/renderview.cpp275
-rw-r--r--src/plugins/renderers/opengl/renderer/renderview_p.h16
-rw-r--r--src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp137
-rw-r--r--src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h8
-rw-r--r--src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp10
-rw-r--r--src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h15
25 files changed, 893 insertions, 426 deletions
diff --git a/src/plugins/renderers/opengl/debug/imguirenderer.cpp b/src/plugins/renderers/opengl/debug/imguirenderer.cpp
index 8dd9b98fe..0acee945a 100644
--- a/src/plugins/renderers/opengl/debug/imguirenderer.cpp
+++ b/src/plugins/renderers/opengl/debug/imguirenderer.cpp
@@ -283,13 +283,21 @@ void ImGuiRenderer::renderDebugOverlay(const QVector<RenderView *> &renderViews,
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render framegraph")));
ImGui::SameLine();
- if (ImGui::Button("FrameGraph Paths##1"))
+ if (ImGui::Button("Render Views##1"))
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render framepaths")));
+
+ ImGui::AlignTextToFramePadding();
+ ImGui::Text(" ");
+ ImGui::SameLine();
+ if (ImGui::Button("Filter State##1"))
+ QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
+ Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render filterstates")));
ImGui::SameLine();
if (ImGui::Button("JobsGraph##1"))
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("dump jobs")));
+
ImGui::End();
if (m_showGLInfoWindow)
diff --git a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp
index 519f2ae98..d4d3457ab 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -1166,7 +1166,7 @@ void SubmissionContext::setUpdatedTexture(const Qt3DCore::QNodeIdVector &updated
// It will be easier if the QGraphicContext applies the QUniformPack
// than the other way around
-bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
+bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack, GLShader *shader)
{
static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight.irradiance"));
static const int specularId = StringToInt::lookupId(QLatin1String("envLight.specular"));
@@ -1231,7 +1231,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
}
}
- QOpenGLShaderProgram *shader = activeShader();
+ QOpenGLShaderProgram *glShader = activeShader();
// TO DO: We could cache the binding points somehow and only do the binding when necessary
// for SSBO and UBO
@@ -1245,7 +1245,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// This is currently not required as we are introspecting the bindingIndex
// value from the shaders and not replacing them, making such a call useless
// bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex);
- bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex);
+ bindShaderStorageBlock(glShader->programId(), b.m_blockIndex, b.m_bindingIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
bindGLBuffer(ssbo, GLBuffer::ShaderStorageBuffer);
@@ -1260,7 +1260,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
for (const BlockToUBO &b : blockToUBOs) {
Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer);
- bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex);
+ bindUniformBlock(glShader->programId(), b.m_blockIndex, uboIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
bindGLBuffer(ubo, GLBuffer::UniformBuffer);
@@ -1270,11 +1270,11 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// Update uniforms in the Default Uniform Block
const PackUniformHash values = parameterPack.uniforms();
- const QVector<ShaderUniform> activeUniforms = parameterPack.submissionUniforms();
+ const QVector<int> &activeUniformsIndices = parameterPack.submissionUniformIndices();
+ const QVector<ShaderUniform> &shaderUniforms = shader->uniforms();
- for (const ShaderUniform &uniform : activeUniforms) {
- // We can use [] as we are sure the the uniform wouldn't
- // be un activeUniforms if there wasn't a matching value
+ for (const int shaderUniformIndex : activeUniformsIndices) {
+ const ShaderUniform &uniform = shaderUniforms[shaderUniformIndex];
const UniformValue &v = values.value(uniform.m_nameId);
// skip invalid textures/images
diff --git a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h
index 59b2b78f3..4c895013c 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h
+++ b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h
@@ -137,7 +137,7 @@ public:
GLBuffer *glBufferForRenderBuffer(Buffer *buf);
// Parameters
- bool setParameters(ShaderParameterPack &parameterPack);
+ bool setParameters(ShaderParameterPack &parameterPack, GLShader *shader);
// RenderState
void setCurrentStateSet(RenderStateSet* ss);
diff --git a/src/plugins/renderers/opengl/jobs/materialparametergathererjob.cpp b/src/plugins/renderers/opengl/jobs/materialparametergathererjob.cpp
index 1f51ceba3..1dd26b847 100644
--- a/src/plugins/renderers/opengl/jobs/materialparametergathererjob.cpp
+++ b/src/plugins/renderers/opengl/jobs/materialparametergathererjob.cpp
@@ -59,8 +59,32 @@ const int likelyNumberOfParameters = 24;
} // anonymous
+class MaterialParameterGathererJobPrivate : public Qt3DCore::QAspectJobPrivate
+{
+public:
+ MaterialParameterGathererJobPrivate(MaterialParameterGathererJob *q) : q_ptr(q) { }
+ ~MaterialParameterGathererJobPrivate() override = default;
+
+ bool isRequired() const override;
+ void postFrame(Qt3DCore::QAspectManager *manager) override;
+
+ MaterialParameterGathererJob *q_ptr;
+ Q_DECLARE_PUBLIC(MaterialParameterGathererJob)
+};
+
+bool MaterialParameterGathererJobPrivate::isRequired() const
+{
+ return !q_ptr->m_handles.isEmpty();
+}
+
+void MaterialParameterGathererJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
+{
+ Q_UNUSED(manager)
+ materialParameterGathererCounter = 0;
+}
+
MaterialParameterGathererJob::MaterialParameterGathererJob()
- : Qt3DCore::QAspectJob()
+ : Qt3DCore::QAspectJob(*new MaterialParameterGathererJobPrivate(this))
, m_manager(nullptr)
, m_techniqueFilter(nullptr)
, m_renderPassFilter(nullptr)
diff --git a/src/plugins/renderers/opengl/jobs/materialparametergathererjob_p.h b/src/plugins/renderers/opengl/jobs/materialparametergathererjob_p.h
index cd5af8124..8c9997827 100644
--- a/src/plugins/renderers/opengl/jobs/materialparametergathererjob_p.h
+++ b/src/plugins/renderers/opengl/jobs/materialparametergathererjob_p.h
@@ -71,6 +71,7 @@ namespace OpenGL {
class Renderer;
// TO be executed for each FrameGraph branch with a given RenderPassFilter/TechniqueFilter
+class MaterialParameterGathererJobPrivate;
class Q_AUTOTEST_EXPORT MaterialParameterGathererJob : public Qt3DCore::QAspectJob
{
@@ -96,6 +97,8 @@ private:
// Material id to array of RenderPasse with parameters
MaterialParameterGathererData m_parameters;
QVector<HMaterial> m_handles;
+
+ Q_DECLARE_PRIVATE(MaterialParameterGathererJob)
};
typedef QSharedPointer<MaterialParameterGathererJob> MaterialParameterGathererJobPtr;
diff --git a/src/plugins/renderers/opengl/jobs/renderviewbuilderjob.cpp b/src/plugins/renderers/opengl/jobs/renderviewbuilderjob.cpp
deleted file mode 100644
index 468ab9342..000000000
--- a/src/plugins/renderers/opengl/jobs/renderviewbuilderjob.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Paul Lemire
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "renderviewcommandupdaterjob_p.h"
-#include <Qt3DRender/private/job_common_p.h>
-#include <renderer_p.h>
-#include <renderview_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-namespace OpenGL {
-
-namespace {
-int renderViewInstanceCounter = 0;
-} // anonymous
-
-RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob()
- : Qt3DCore::QAspectJob()
- , m_offset(0)
- , m_count(0)
- , m_renderView(nullptr)
- , m_renderer(nullptr)
- , m_renderables(nullptr)
-{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++);
-}
-
-void RenderViewCommandUpdaterJob::run()
-{
- // Build RenderCommand should perform the culling as we have no way to determine
- // if a child has a mesh in the view frustum while its parent isn't contained in it.
- if (!m_renderView->noDraw()) {
- if (m_count == 0)
- return;
- // Update Render Commands (Uniform Change, Depth Change)
- m_renderView->updateRenderCommand(m_renderables, m_offset, m_count);
- }
-}
-
-} // OpenGL
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp b/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp
index d8a33b693..d5e17e0bf 100644
--- a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp
+++ b/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp
@@ -53,8 +53,32 @@ namespace {
int renderViewInstanceCounter = 0;
} // anonymous
+class RenderViewCommandBuilderJobPrivate : public Qt3DCore::QAspectJobPrivate
+{
+public:
+ RenderViewCommandBuilderJobPrivate(RenderViewCommandBuilderJob *q) : q_ptr(q) { }
+ ~RenderViewCommandBuilderJobPrivate() override = default;
+
+ bool isRequired() const override;
+ void postFrame(Qt3DCore::QAspectManager *manager) override;
+
+ RenderViewCommandBuilderJob *q_ptr;
+ Q_DECLARE_PUBLIC(RenderViewCommandBuilderJob)
+};
+
+bool RenderViewCommandBuilderJobPrivate::isRequired() const
+{
+ return q_ptr->m_renderView && !q_ptr->m_renderView->noDraw() && q_ptr->m_count > 0;
+}
+
+void RenderViewCommandBuilderJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
+{
+ Q_UNUSED(manager)
+ renderViewInstanceCounter = 0;
+}
+
RenderViewCommandBuilderJob::RenderViewCommandBuilderJob()
- : Qt3DCore::QAspectJob()
+ : Qt3DCore::QAspectJob(*new RenderViewCommandBuilderJobPrivate(this))
, m_offset(0)
, m_count(0)
, m_renderView(nullptr)
@@ -64,18 +88,14 @@ RenderViewCommandBuilderJob::RenderViewCommandBuilderJob()
void RenderViewCommandBuilderJob::run()
{
- if (!m_renderView->noDraw()) {
- if (m_count == 0)
- return;
-
- const bool isDraw = !m_renderView->isCompute();
- if (isDraw)
- m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count);
- else
- m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count);
- }
+ const bool isDraw = !m_renderView->isCompute();
+ if (isDraw)
+ m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count);
+ else
+ m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count);
}
+
} // OpenGL
} // Render
diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h b/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h
index e9f8bb10a..52c055285 100644
--- a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h
+++ b/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h
@@ -63,6 +63,8 @@ namespace Render {
namespace OpenGL {
+class RenderViewCommandBuilderJobPrivate;
+
class Q_AUTOTEST_EXPORT RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob
{
public:
@@ -85,6 +87,8 @@ private:
RenderView *m_renderView;
QVector<Entity *> m_entities;
EntityRenderCommandData m_commandData;
+
+ Q_DECLARE_PRIVATE(RenderViewCommandBuilderJob)
};
typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr;
diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp b/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp
index ed0854ecf..9bbdf50fd 100644
--- a/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp
+++ b/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp
@@ -60,17 +60,16 @@ public:
RenderViewCommandUpdaterJobPrivate(RenderViewCommandUpdaterJob *q) : q_ptr(q) { }
~RenderViewCommandUpdaterJobPrivate() override = default;
- bool isRequired() override;
+ bool isRequired() const override;
void postFrame(Qt3DCore::QAspectManager *manager) override;
RenderViewCommandUpdaterJob *q_ptr;
Q_DECLARE_PUBLIC(RenderViewCommandUpdaterJob)
};
-bool RenderViewCommandUpdaterJobPrivate::isRequired()
+bool RenderViewCommandUpdaterJobPrivate::isRequired() const
{
- Q_Q(RenderViewCommandUpdaterJob);
-
+ Q_Q(const RenderViewCommandUpdaterJob);
return q->m_renderView && !q->m_renderView->noDraw() && q->m_count > 0;
}
diff --git a/src/plugins/renderers/opengl/jobs/renderviewjobutils.cpp b/src/plugins/renderers/opengl/jobs/renderviewjobutils.cpp
index d4835054b..8774ac368 100644
--- a/src/plugins/renderers/opengl/jobs/renderviewjobutils.cpp
+++ b/src/plugins/renderers/opengl/jobs/renderviewjobutils.cpp
@@ -473,7 +473,10 @@ UniformBlockValueBuilder::~UniformBlockValueBuilder()
{
}
-void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData, const QString &blockName, const QString &qmlPropertyName, const QVariant &value)
+void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(const ShaderData *currentShaderData,
+ const QString &blockName,
+ const QString &qmlPropertyName,
+ const QVariant &value)
{
// In the end, values are either scalar or a scalar array
// Composed elements (structs, structs array) are simplified into simple scalars
@@ -534,7 +537,9 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *
}
}
-void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(ShaderData *rShaderData, const QString &blockName, const QString &qmlPropertyName)
+void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(const ShaderData *rShaderData,
+ const QString &blockName,
+ const QString &qmlPropertyName)
{
const QHash<QString, ShaderData::PropertyValue> &properties = rShaderData->properties();
auto it = properties.begin();
diff --git a/src/plugins/renderers/opengl/jobs/renderviewjobutils_p.h b/src/plugins/renderers/opengl/jobs/renderviewjobutils_p.h
index 7b5ba2bfd..bc5bfd8aa 100644
--- a/src/plugins/renderers/opengl/jobs/renderviewjobutils_p.h
+++ b/src/plugins/renderers/opengl/jobs/renderviewjobutils_p.h
@@ -162,11 +162,11 @@ struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder
QT3D_ALIGNED_MALLOC_AND_FREE()
- void buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData,
+ void buildActiveUniformNameValueMapHelper(const ShaderData *currentShaderData,
const QString &blockName,
const QString &qmlPropertyName,
const QVariant &value);
- void buildActiveUniformNameValueMapStructHelper(ShaderData *rShaderData,
+ void buildActiveUniformNameValueMapStructHelper(const ShaderData *rShaderData,
const QString &blockName,
const QString &qmlPropertyName = QString());
diff --git a/src/plugins/renderers/opengl/opengl.pro b/src/plugins/renderers/opengl/opengl.pro
index ebd4ff5d1..f098513e8 100644
--- a/src/plugins/renderers/opengl/opengl.pro
+++ b/src/plugins/renderers/opengl/opengl.pro
@@ -1,5 +1,8 @@
TARGET = openglrenderer
+# We use QT_AUTOTEST_EXPORT to test the plug-ins, which needs QT_BUILDING_QT
+DEFINES += QT_BUILDING_QT
+
include(opengl.pri)
SOURCES += \
diff --git a/src/plugins/renderers/opengl/renderer/gllights.cpp b/src/plugins/renderers/opengl/renderer/gllights.cpp
new file mode 100644
index 000000000..c87fd766b
--- /dev/null
+++ b/src/plugins/renderers/opengl/renderer/gllights.cpp
@@ -0,0 +1,345 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <Qt3DRender/private/stringtoint_p.h>
+#include "gllights_p.h"
+
+#define LIGHT_POSITION_NAME QLatin1String(".position")
+#define LIGHT_TYPE_NAME QLatin1String(".type")
+#define LIGHT_COLOR_NAME QLatin1String(".color")
+#define LIGHT_INTENSITY_NAME QLatin1String(".intensity")
+#define LIGHT_DIRECTION_NAME QLatin1String(".direction")
+#define LIGHT_LINEAR_ATTENUATION_NAME QLatin1String(".linearAttenuation")
+#define LIGHT_QUADRATIC_ATTENUATION_NAME QLatin1String(".quadraticAttenuation")
+#define LIGHT_CONSTANT_ATTENUATION_NAME QLatin1String(".constantAttenuation")
+#define LIGHT_CUT_OFF_ANGLE_NAME QLatin1String(".cutOffAngle")
+
+#define DECLARE_LIGHT_STRUCT_NAME(idx)\
+ QLatin1String("lights[") + QLatin1Char(char('0' + idx)) + QLatin1Char(']')
+
+#define DECLARE_LIGHT_POSITION_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_POSITION_NAME)
+
+#define DECLARE_LIGHT_TYPE_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_TYPE_NAME)
+
+#define DECLARE_LIGHT_COLOR_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_COLOR_NAME)
+
+#define DECLARE_LIGHT_INTENSITY_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_INTENSITY_NAME)
+
+#define DECLARE_LIGHT_DIRECTION_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_DIRECTION_NAME)
+
+#define DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_LINEAR_ATTENUATION_NAME)
+
+#define DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_QUADRATIC_ATTENUATION_NAME)
+
+#define DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_CONSTANT_ATTENUATION_NAME)
+
+#define DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_NAMES[idx] + LIGHT_CUT_OFF_ANGLE_NAME)
+
+#define DECLARE_LIGHT_STRUCT_UNROLL_NAME(idx)\
+ QLatin1String("light_") + QLatin1Char(char('0' + idx))
+
+#define DECLARE_LIGHT_POSITION_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_POSITION_NAME)
+
+#define DECLARE_LIGHT_TYPE_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_TYPE_NAME)
+
+#define DECLARE_LIGHT_COLOR_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_COLOR_NAME)
+
+#define DECLARE_LIGHT_INTENSITY_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_INTENSITY_NAME)
+
+#define DECLARE_LIGHT_DIRECTION_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_DIRECTION_NAME)
+
+#define DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_LINEAR_ATTENUATION_NAME)
+
+#define DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_QUADRATIC_ATTENUATION_NAME)
+
+#define DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_CONSTANT_ATTENUATION_NAME)
+
+#define DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(idx)\
+ StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[idx] + LIGHT_CUT_OFF_ANGLE_NAME)
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+namespace OpenGL {
+
+int GLLights::LIGHT_COUNT_NAME_ID = StringToInt::lookupId(QLatin1String("lightCount"));
+
+QString GLLights::LIGHT_STRUCT_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_STRUCT_NAME(0),
+ DECLARE_LIGHT_STRUCT_NAME(1),
+ DECLARE_LIGHT_STRUCT_NAME(2),
+ DECLARE_LIGHT_STRUCT_NAME(3),
+ DECLARE_LIGHT_STRUCT_NAME(4),
+ DECLARE_LIGHT_STRUCT_NAME(5),
+ DECLARE_LIGHT_STRUCT_NAME(6),
+ DECLARE_LIGHT_STRUCT_NAME(7)
+};
+
+int GLLights::LIGHT_POSITION_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_POSITION_NAME(0),
+ DECLARE_LIGHT_POSITION_NAME(1),
+ DECLARE_LIGHT_POSITION_NAME(2),
+ DECLARE_LIGHT_POSITION_NAME(3),
+ DECLARE_LIGHT_POSITION_NAME(4),
+ DECLARE_LIGHT_POSITION_NAME(5),
+ DECLARE_LIGHT_POSITION_NAME(6),
+ DECLARE_LIGHT_POSITION_NAME(7)
+};
+
+int GLLights::LIGHT_TYPE_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_TYPE_NAME(0),
+ DECLARE_LIGHT_TYPE_NAME(1),
+ DECLARE_LIGHT_TYPE_NAME(2),
+ DECLARE_LIGHT_TYPE_NAME(3),
+ DECLARE_LIGHT_TYPE_NAME(4),
+ DECLARE_LIGHT_TYPE_NAME(5),
+ DECLARE_LIGHT_TYPE_NAME(6),
+ DECLARE_LIGHT_TYPE_NAME(7)
+};
+
+int GLLights::LIGHT_COLOR_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_COLOR_NAME(0),
+ DECLARE_LIGHT_COLOR_NAME(1),
+ DECLARE_LIGHT_COLOR_NAME(2),
+ DECLARE_LIGHT_COLOR_NAME(3),
+ DECLARE_LIGHT_COLOR_NAME(4),
+ DECLARE_LIGHT_COLOR_NAME(5),
+ DECLARE_LIGHT_COLOR_NAME(6),
+ DECLARE_LIGHT_COLOR_NAME(7)
+};
+
+int GLLights::LIGHT_INTENSITY_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_INTENSITY_NAME(0),
+ DECLARE_LIGHT_INTENSITY_NAME(1),
+ DECLARE_LIGHT_INTENSITY_NAME(2),
+ DECLARE_LIGHT_INTENSITY_NAME(3),
+ DECLARE_LIGHT_INTENSITY_NAME(4),
+ DECLARE_LIGHT_INTENSITY_NAME(5),
+ DECLARE_LIGHT_INTENSITY_NAME(6),
+ DECLARE_LIGHT_INTENSITY_NAME(7)
+};
+
+int GLLights::LIGHT_DIRECTION_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_DIRECTION_NAME(0),
+ DECLARE_LIGHT_DIRECTION_NAME(1),
+ DECLARE_LIGHT_DIRECTION_NAME(2),
+ DECLARE_LIGHT_DIRECTION_NAME(3),
+ DECLARE_LIGHT_DIRECTION_NAME(4),
+ DECLARE_LIGHT_DIRECTION_NAME(5),
+ DECLARE_LIGHT_DIRECTION_NAME(6),
+ DECLARE_LIGHT_DIRECTION_NAME(7)
+};
+
+int GLLights::LIGHT_LINEAR_ATTENUATION_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(0),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(1),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(2),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(3),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(4),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(5),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(6),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_NAME(7)
+};
+
+int GLLights::LIGHT_QUADRATIC_ATTENUATION_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(0),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(1),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(2),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(3),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(4),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(5),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(6),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_NAME(7)
+};
+
+int GLLights::LIGHT_CONSTANT_ATTENUATION_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(0),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(1),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(2),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(3),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(4),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(5),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(6),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_NAME(7)
+};
+
+int GLLights::LIGHT_CUT_OFF_ANGLE_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(0),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(1),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(2),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(3),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(4),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(5),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(6),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_NAME(7)
+};
+
+QString GLLights::LIGHT_STRUCT_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(0),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(1),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(2),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(3),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(4),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(5),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(6),
+ DECLARE_LIGHT_STRUCT_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_POSITION_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(0),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(1),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(2),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(3),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(4),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(5),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(6),
+ DECLARE_LIGHT_POSITION_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_TYPE_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(0),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(1),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(2),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(3),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(4),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(5),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(6),
+ DECLARE_LIGHT_TYPE_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_COLOR_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(0),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(1),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(2),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(3),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(4),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(5),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(6),
+ DECLARE_LIGHT_COLOR_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_INTENSITY_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(0),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(1),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(2),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(3),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(4),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(5),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(6),
+ DECLARE_LIGHT_INTENSITY_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_DIRECTION_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(0),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(1),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(2),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(3),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(4),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(5),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(6),
+ DECLARE_LIGHT_DIRECTION_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_LINEAR_ATTENUATION_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(0),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(1),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(2),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(3),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(4),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(5),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(6),
+ DECLARE_LIGHT_LINEAR_ATTENUATION_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(0),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(1),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(2),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(3),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(4),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(5),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(6),
+ DECLARE_LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_CONSTANT_ATTENUATION_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(0),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(1),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(2),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(3),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(4),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(5),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(6),
+ DECLARE_LIGHT_CONSTANT_ATTENUATION_UNROLL_NAME(7)
+};
+
+int GLLights::LIGHT_CUT_OFF_ANGLE_UNROLL_NAMES[MAX_LIGHTS] = {
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(0),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(1),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(2),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(3),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(4),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(5),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(6),
+ DECLARE_LIGHT_CUT_OFF_ANGLE_UNROLL_NAME(7)
+};
+
+} // namespace OpenGL
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/plugins/renderers/opengl/jobs/renderviewbuilderjob_p.h b/src/plugins/renderers/opengl/renderer/gllights_p.h
index 13e19daf7..90fa91588 100644
--- a/src/plugins/renderers/opengl/jobs/renderviewbuilderjob_p.h
+++ b/src/plugins/renderers/opengl/renderer/gllights_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -37,66 +37,52 @@
**
****************************************************************************/
-#ifndef QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDBUILDERJOB_P_H
-#define QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDBUILDERJOB_P_H
+#ifndef QT3DRENDER_RENDER_OPENGL_GLLIGHTS_P_H
+#define QT3DRENDER_RENDER_OPENGL_GLLIGHTS_P_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <Qt3DCore/qaspectjob.h>
-#include <Qt3DRender/private/handle_types_p.h>
-#include <rendercommand_p.h>
+#include <QString>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
-
namespace Render {
-
namespace OpenGL {
-class RenderView;
-
-class Q_AUTOTEST_EXPORT RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob
-{
-public:
- RenderViewCommandBuilderJob();
-
- inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; }
- inline void setEntities(const QVector<Entity *> &entities, int offset, int count)
- {
- m_offset = offset;
- m_count = count;
- m_entities = entities;
- }
- inline EntityRenderCommandData &commandData() { return m_commandData; }
+#define MAX_LIGHTS 8
- void run() final;
+static_assert (MAX_LIGHTS < 10, "GL_Lights can't use the QChar trick anymore");
-private:
- int m_offset;
- int m_count;
- RenderView *m_renderView;
- QVector<Entity *> m_entities;
- EntityRenderCommandData m_commandData;
+struct GLLights
+{
+ static int LIGHT_COUNT_NAME_ID;
+
+ static QString LIGHT_STRUCT_NAMES[MAX_LIGHTS];
+ static int LIGHT_POSITION_NAMES[MAX_LIGHTS];
+ static int LIGHT_TYPE_NAMES[MAX_LIGHTS];
+ static int LIGHT_COLOR_NAMES[MAX_LIGHTS];
+ static int LIGHT_INTENSITY_NAMES[MAX_LIGHTS];
+ static int LIGHT_DIRECTION_NAMES[MAX_LIGHTS];
+ static int LIGHT_LINEAR_ATTENUATION_NAMES[MAX_LIGHTS];
+ static int LIGHT_QUADRATIC_ATTENUATION_NAMES[MAX_LIGHTS];
+ static int LIGHT_CONSTANT_ATTENUATION_NAMES[MAX_LIGHTS];
+ static int LIGHT_CUT_OFF_ANGLE_NAMES[MAX_LIGHTS];
+
+ static QString LIGHT_STRUCT_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_POSITION_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_TYPE_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_COLOR_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_INTENSITY_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_DIRECTION_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_LINEAR_ATTENUATION_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_CONSTANT_ATTENUATION_UNROLL_NAMES[MAX_LIGHTS];
+ static int LIGHT_CUT_OFF_ANGLE_UNROLL_NAMES[MAX_LIGHTS];
};
-typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr;
-
-} // OpenGL
-
-} // Render
-
-} // Qt3DRender
+} // namespace OpenGL
+} // namespace Render
+} // namespace Qt3DRender
QT_END_NAMESPACE
-#endif // QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDBUILDERJOB_P_H
+#endif // QT3DRENDER_RENDER_OPENGL_GLLIGHTS_P_H
diff --git a/src/plugins/renderers/opengl/renderer/glshader.cpp b/src/plugins/renderers/opengl/renderer/glshader.cpp
index 5e92d84c2..564e78a8e 100644
--- a/src/plugins/renderers/opengl/renderer/glshader.cpp
+++ b/src/plugins/renderers/opengl/renderer/glshader.cpp
@@ -42,6 +42,7 @@
#include <Qt3DRender/private/stringtoint_p.h>
#include <graphicscontext_p.h>
#include <logging_p.h>
+#include <gllights_p.h>
QT_BEGIN_NAMESPACE
@@ -51,9 +52,51 @@ namespace Render {
namespace OpenGL {
+namespace {
+
+QVector<int> getLightUniformNameIds()
+{
+ QVector<int> names;
+ names.reserve(MAX_LIGHTS * 18 + 1);
+
+ names << GLLights::LIGHT_COUNT_NAME_ID;
+ for (int i = 0; i < MAX_LIGHTS; ++i) {
+ names << GLLights::LIGHT_TYPE_NAMES[i]
+ << GLLights::LIGHT_COLOR_NAMES[i]
+ << GLLights::LIGHT_POSITION_NAMES[i]
+ << GLLights::LIGHT_INTENSITY_NAMES[i]
+ << GLLights::LIGHT_DIRECTION_NAMES[i]
+ << GLLights::LIGHT_LINEAR_ATTENUATION_NAMES[i]
+ << GLLights::LIGHT_QUADRATIC_ATTENUATION_NAMES[i]
+ << GLLights::LIGHT_CONSTANT_ATTENUATION_NAMES[i]
+ << GLLights::LIGHT_CUT_OFF_ANGLE_NAMES[i]
+ << GLLights::LIGHT_TYPE_UNROLL_NAMES[i]
+ << GLLights::LIGHT_COLOR_UNROLL_NAMES[i]
+ << GLLights::LIGHT_POSITION_UNROLL_NAMES[i]
+ << GLLights::LIGHT_INTENSITY_UNROLL_NAMES[i]
+ << GLLights::LIGHT_DIRECTION_UNROLL_NAMES[i]
+ << GLLights::LIGHT_LINEAR_ATTENUATION_UNROLL_NAMES[i]
+ << GLLights::LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAMES[i]
+ << GLLights::LIGHT_CONSTANT_ATTENUATION_UNROLL_NAMES[i]
+ << GLLights::LIGHT_CUT_OFF_ANGLE_UNROLL_NAMES[i];
+ }
+
+ return names;
+}
+
+template<typename Vector>
+bool fastContains(const Vector &v, int value)
+{
+ return std::binary_search(v.cbegin(), v.cend(), value);
+}
+
+}
+
GLShader::GLShader()
: m_isLoaded(false)
, m_graphicsContext(nullptr)
+ , m_parameterPackSize(0)
+ , m_hasActiveVariables(false)
{
m_shaderCode.resize(static_cast<int>(QShaderProgram::Compute) + 1);
}
@@ -106,7 +149,7 @@ QHash<QString, ShaderUniform> GLShader::activeUniformsForUniformBlock(int blockI
return m_uniformBlockIndexToShaderUniforms.value(blockIndex);
}
-ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex)
+ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex) const noexcept
{
for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) {
if (m_uniformBlocks[i].m_index == blockIndex) {
@@ -116,7 +159,7 @@ ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex)
return ShaderUniformBlock();
}
-ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId)
+ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId) const noexcept
{
for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) {
if (m_uniformBlocks[i].m_nameId == blockNameId) {
@@ -126,7 +169,7 @@ ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId)
return ShaderUniformBlock();
}
-ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName)
+ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName) const noexcept
{
for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) {
if (m_uniformBlocks[i].m_name == blockName) {
@@ -136,7 +179,7 @@ ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName)
return ShaderUniformBlock();
}
-ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex)
+ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex) const noexcept
{
for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) {
if (m_shaderStorageBlocks[i].m_index == blockIndex)
@@ -145,7 +188,7 @@ ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex)
return ShaderStorageBlock();
}
-ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId)
+ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId) const noexcept
{
for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) {
if (m_shaderStorageBlocks[i].m_nameId == blockNameId)
@@ -154,7 +197,7 @@ ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId)
return ShaderStorageBlock();
}
-ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName)
+ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName) const noexcept
{
for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) {
if (m_shaderStorageBlocks[i].m_name == blockName)
@@ -163,6 +206,22 @@ ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName)
return ShaderStorageBlock();
}
+GLShader::ParameterKind GLShader::categorizeVariable(int nameId) const noexcept
+{
+ if (fastContains(m_uniformsNamesIds, nameId))
+ return ParameterKind::Uniform;
+ if (fastContains(m_uniformBlockNamesIds, nameId))
+ return ParameterKind::UBO;
+ if (fastContains(m_shaderStorageBlockNamesIds, nameId))
+ return ParameterKind::SSBO;
+ return ParameterKind::Struct;
+}
+
+bool GLShader::hasUniform(int nameId) const noexcept
+{
+ return m_uniformsNamesIds.contains(nameId);
+}
+
void GLShader::prepareUniforms(ShaderParameterPack &pack)
{
const PackUniformHash &values = pack.uniforms();
@@ -170,14 +229,20 @@ void GLShader::prepareUniforms(ShaderParameterPack &pack)
auto it = values.keys.cbegin();
const auto end = values.keys.cend();
+ const int shaderUniformsCount = m_uniforms.size();
+ const auto uIt = m_uniforms.cbegin();
+
while (it != end) {
// Find if there's a uniform with the same name id
- for (const ShaderUniform &uniform : qAsConst(m_uniforms)) {
- if (uniform.m_nameId == *it) {
- pack.setSubmissionUniform(uniform);
- break;
- }
- }
+
+ int i = 0;
+ const int targetNameId = *it;
+ while (i < shaderUniformsCount && (uIt + i)->m_nameId < targetNameId)
+ ++i;
+
+ if (i < shaderUniformsCount && (uIt + i)->m_nameId == targetNameId)
+ pack.setSubmissionUniformIndex(i);
+
++it;
}
}
@@ -188,7 +253,6 @@ void GLShader::setFragOutputs(const QHash<QString, int> &fragOutputs)
QMutexLocker lock(&m_mutex);
m_fragOutputs = fragOutputs;
}
-// updateDNA();
}
const QHash<QString, int> GLShader::fragOutputs() const
@@ -203,6 +267,7 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript
m_uniformsNames.resize(uniformsDescription.size());
m_uniformsNamesIds.reserve(uniformsDescription.size());
m_standardUniformNamesIds.reserve(5);
+ m_lightUniformsNamesIds.reserve(MAX_LIGHTS * 8 + 1);
QHash<QString, ShaderUniform> activeUniformsInDefaultBlock;
static const QVector<int> standardUniformNameIds = {
@@ -231,14 +296,18 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript
Shader::skinningPaletteNameId,
};
+ static const QVector<int> lightUniformNameIds = getLightUniformNameIds();
+
for (int i = 0, m = uniformsDescription.size(); i < m; i++) {
m_uniformsNames[i] = m_uniforms[i].m_name;
const int nameId = StringToInt::lookupId(m_uniformsNames[i]);
m_uniforms[i].m_nameId = nameId;
- // Is the uniform a Qt3D "Standard" uniform or a user defined one?
+ // Is the uniform a Qt3D "Standard" uniform, a light uniform or a user defined one?
if (standardUniformNameIds.contains(nameId))
m_standardUniformNamesIds.push_back(nameId);
+ else if (lightUniformNameIds.contains(nameId))
+ m_lightUniformsNamesIds.push_back(nameId);
else
m_uniformsNamesIds.push_back(nameId);
@@ -248,6 +317,18 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript
}
}
m_uniformBlockIndexToShaderUniforms.insert(-1, activeUniformsInDefaultBlock);
+
+ m_parameterPackSize += m_standardUniformNamesIds.size() + m_lightUniformsNamesIds.size() + m_uniformsNamesIds.size();
+ m_hasActiveVariables |= (m_parameterPackSize > 0);
+
+ // Sort by ascending order to make contains check faster
+ std::sort(m_uniformsNamesIds.begin(), m_uniformsNamesIds.end());
+ std::sort(m_lightUniformsNamesIds.begin(), m_lightUniformsNamesIds.end());
+ std::sort(m_standardUniformNamesIds.begin(), m_standardUniformNamesIds.end());
+ std::sort(m_uniforms.begin(), m_uniforms.end(),
+ [] (const ShaderUniform &a, const ShaderUniform &b) {
+ return a.m_nameId < b.m_nameId;
+ });
}
void GLShader::initializeAttributes(const QVector<ShaderAttribute> &attributesDescription)
@@ -261,6 +342,7 @@ void GLShader::initializeAttributes(const QVector<ShaderAttribute> &attributesDe
m_attributeNamesIds[i] = m_attributes[i].m_nameId;
qCDebug(Shaders) << "Active Attribute " << attributesDescription[i].m_name;
}
+ m_hasActiveVariables |= (m_attributeNamesIds.size() > 0);
}
void GLShader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformBlockDescription)
@@ -296,6 +378,12 @@ void GLShader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &unifor
}
m_uniformBlockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, activeUniformsInBlock);
}
+
+ m_parameterPackSize += m_uniformsNamesIds.size();
+ m_hasActiveVariables |= (m_parameterPackSize > 0);
+
+ // Sort by ascending order to make contains check faster
+ std::sort(m_uniformBlockNamesIds.begin(), m_uniformBlockNamesIds.end());
}
void GLShader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription)
@@ -310,6 +398,12 @@ void GLShader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &
m_shaderStorageBlocks[i].m_nameId =m_shaderStorageBlockNamesIds[i];
qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] << "}";
}
+
+ m_parameterPackSize += m_shaderStorageBlockNamesIds.size();
+ m_hasActiveVariables |= (m_parameterPackSize > 0);
+
+ // Sort by ascending order to make contains check faster
+ std::sort(m_shaderStorageBlockNamesIds.begin(), m_shaderStorageBlockNamesIds.end());
}
} // OpenGL
diff --git a/src/plugins/renderers/opengl/renderer/glshader_p.h b/src/plugins/renderers/opengl/renderer/glshader_p.h
index 6bd5400af..ae447cd18 100644
--- a/src/plugins/renderers/opengl/renderer/glshader_p.h
+++ b/src/plugins/renderers/opengl/renderer/glshader_p.h
@@ -57,6 +57,9 @@
#include <Qt3DRender/qshaderprogram.h>
#include <QMutex>
+#ifdef QT_BUILD_INTERNAL
+ class tst_BenchShaderParameterPack;
+#endif
QT_BEGIN_NAMESPACE
@@ -84,31 +87,44 @@ public:
void setFragOutputs(const QHash<QString, int> &fragOutputs);
const QHash<QString, int> fragOutputs() const;
- inline QVector<int> uniformsNamesIds() const { return m_uniformsNamesIds; }
- inline QVector<int> standardUniformNameIds() const { return m_standardUniformNamesIds; }
- inline QVector<int> uniformBlockNamesIds() const { return m_uniformBlockNamesIds; }
- inline QVector<int> storageBlockNamesIds() const { return m_shaderStorageBlockNamesIds; }
- inline QVector<int> attributeNamesIds() const { return m_attributeNamesIds; }
+ inline const QVector<int> &uniformsNamesIds() const { return m_uniformsNamesIds; }
+ inline const QVector<int> &lightUniformsNamesIds() const { return m_lightUniformsNamesIds; }
+ inline const QVector<int> &standardUniformNameIds() const { return m_standardUniformNamesIds; }
+ inline const QVector<int> &uniformBlockNamesIds() const { return m_uniformBlockNamesIds; }
+ inline const QVector<int> &storageBlockNamesIds() const { return m_shaderStorageBlockNamesIds; }
+ inline const QVector<int> &attributeNamesIds() const { return m_attributeNamesIds; }
QVector<QString> uniformsNames() const;
QVector<QString> attributesNames() const;
QVector<QString> uniformBlockNames() const;
QVector<QString> storageBlockNames() const;
- inline QVector<ShaderUniform> uniforms() const { return m_uniforms; }
- inline QVector<ShaderAttribute> attributes() const { return m_attributes; }
- inline QVector<ShaderUniformBlock> uniformBlocks() const { return m_uniformBlocks; }
- inline QVector<ShaderStorageBlock> storageBlocks() const { return m_shaderStorageBlocks; }
+ inline const QVector<ShaderUniform> &uniforms() const { return m_uniforms; }
+ inline const QVector<ShaderAttribute> &attributes() const { return m_attributes; }
+ inline const QVector<ShaderUniformBlock> &uniformBlocks() const { return m_uniformBlocks; }
+ inline const QVector<ShaderStorageBlock> &storageBlocks() const { return m_shaderStorageBlocks; }
QHash<QString, ShaderUniform> activeUniformsForUniformBlock(int blockIndex) const;
- ShaderUniformBlock uniformBlockForBlockIndex(int blockNameId);
- ShaderUniformBlock uniformBlockForBlockNameId(int blockIndex);
- ShaderUniformBlock uniformBlockForBlockName(const QString &blockName);
+ ShaderUniformBlock uniformBlockForBlockIndex(int blockNameId) const noexcept;
+ ShaderUniformBlock uniformBlockForBlockNameId(int blockIndex) const noexcept;
+ ShaderUniformBlock uniformBlockForBlockName(const QString &blockName) const noexcept;
- ShaderStorageBlock storageBlockForBlockIndex(int blockIndex);
- ShaderStorageBlock storageBlockForBlockNameId(int blockNameId);
- ShaderStorageBlock storageBlockForBlockName(const QString &blockName);
+ ShaderStorageBlock storageBlockForBlockIndex(int blockIndex) const noexcept;
+ ShaderStorageBlock storageBlockForBlockNameId(int blockNameId) const noexcept;
+ ShaderStorageBlock storageBlockForBlockName(const QString &blockName) const noexcept;
+
+ enum ParameterKind {
+ Uniform,
+ UBO,
+ SSBO,
+ Struct
+ };
+ ParameterKind categorizeVariable(int nameId) const noexcept;
+
+ bool hasUniform(int nameId) const noexcept;
+ inline bool hasActiveVariables() const noexcept { return m_hasActiveVariables; }
+ inline int parameterPackSize() const noexcept { return m_parameterPackSize; }
QOpenGLShaderProgram *shaderProgram() { return &m_shader; }
@@ -122,6 +138,7 @@ private:
QVector<QString> m_uniformsNames;
QVector<int> m_uniformsNamesIds;
+ QVector<int> m_lightUniformsNamesIds;
QVector<int> m_standardUniformNamesIds;
QVector<ShaderUniform> m_uniforms;
@@ -141,6 +158,9 @@ private:
QHash<QString, int> m_fragOutputs;
QVector<QByteArray> m_shaderCode;
+ int m_parameterPackSize;
+ int m_hasActiveVariables;
+
// Private so that only GraphicContext can call it
void initializeUniforms(const QVector<ShaderUniform> &uniformsDescription);
void initializeAttributes(const QVector<ShaderAttribute> &attributesDescription);
@@ -148,6 +168,9 @@ private:
void initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription);
friend class GraphicsContext;
+#ifdef QT_BUILD_INTERNAL
+ friend class ::tst_BenchShaderParameterPack;
+#endif
mutable QMutex m_mutex;
QMetaObject::Connection m_contextConnection;
diff --git a/src/plugins/renderers/opengl/renderer/renderer.cpp b/src/plugins/renderers/opengl/renderer/renderer.cpp
index 3ad9c2818..57ee5ec88 100644
--- a/src/plugins/renderers/opengl/renderer/renderer.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderer.cpp
@@ -995,16 +995,9 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
// so we cannot unset its dirtiness at this point
if (rGeometryRenderer->isDirty())
rGeometryRenderer->unsetDirty();
-
- // Prepare the ShaderParameterPack based on the active uniforms of the shader
- shader->prepareUniforms(command.m_parameterPack);
-
} else if (command.m_type == RenderCommand::Compute) {
GLShader *shader = command.m_glShader;
Q_ASSERT(shader);
-
- // Prepare the ShaderParameterPack based on the active uniforms of the shader
- shader->prepareUniforms(command.m_parameterPack);
}
}
}
@@ -1172,6 +1165,10 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager)
Shader *s = m_nodesManager->shaderManager()->data(handle);
if (s->requiresFrontendSync()) {
QShaderProgram *frontend = static_cast<decltype(frontend)>(manager->lookupNode(s->peerId()));
+ // Could happen as a backend shader might live beyong the frontend
+ // the time needed to destroy the GLShader assoicated with it.
+ if (!frontend)
+ continue;
QShaderProgramPrivate *dFrontend = static_cast<decltype(dFrontend)>(QNodePrivate::get(frontend));
s->unsetRequiresFrontendSync();
dFrontend->setStatus(s->status());
@@ -1917,10 +1914,31 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_updatedDisableSubtreeEnablers.push_back(node->peerId());
}
+ int idealThreadCount = QThread::idealThreadCount();
+ const QByteArray maxThreadCount = qgetenv("QT3D_MAX_THREAD_COUNT");
+ if (!maxThreadCount.isEmpty()) {
+ bool conversionOK = false;
+ const int maxThreadCountValue = maxThreadCount.toInt(&conversionOK);
+ if (conversionOK)
+ idealThreadCount = maxThreadCountValue;
+ }
+
const int fgBranchCount = m_frameGraphLeaves.size();
+ if (fgBranchCount > 1) {
+ int workBranches = fgBranchCount;
+ for (auto leaf: qAsConst(m_frameGraphLeaves))
+ if (leaf->nodeType() == FrameGraphNode::NoDraw)
+ --workBranches;
+
+ if (idealThreadCount > 4 && workBranches && maxThreadCount.isEmpty())
+ idealThreadCount = qMax(4, idealThreadCount / workBranches);
+ }
+
for (int i = 0; i < fgBranchCount; ++i) {
FrameGraphNode *leaf = m_frameGraphLeaves.at(i);
RenderViewBuilder builder(leaf, i, this);
+ builder.setOptimalJobCount(leaf->nodeType() == FrameGraphNode::NoDraw ? 1 : idealThreadCount);
+
// If we have a new RV (wasn't in the cache before, then it contains no cached data)
const bool isNewRV = !m_cache.leafNodeCache.contains(leaf);
builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt || isNewRV);
@@ -2046,7 +2064,7 @@ void Renderer::performCompute(const RenderView *, RenderCommand *command)
}
{
Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate, activeProfiler());
- m_submissionContext->setParameters(command->m_parameterPack);
+ m_submissionContext->setParameters(command->m_parameterPack, command->m_glShader);
}
{
Profiling::GLTimeRecorder recorder(Profiling::DispatchCompute, activeProfiler());
@@ -2140,7 +2158,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
{
Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate, activeProfiler());
//// Update program uniforms
- if (!m_submissionContext->setParameters(command.m_parameterPack)) {
+ if (!m_submissionContext->setParameters(command.m_parameterPack, command.m_glShader)) {
allCommandsIssued = false;
// If we have failed to set uniform (e.g unable to bind a texture)
// we won't perform the draw call which could show invalid content
diff --git a/src/plugins/renderers/opengl/renderer/renderer.pri b/src/plugins/renderers/opengl/renderer/renderer.pri
index 3e3f83c86..1a0240e77 100644
--- a/src/plugins/renderers/opengl/renderer/renderer.pri
+++ b/src/plugins/renderers/opengl/renderer/renderer.pri
@@ -1,6 +1,7 @@
INCLUDEPATH += $$PWD
SOURCES += \
+ $$PWD/gllights.cpp \
$$PWD/openglvertexarrayobject.cpp \
$$PWD/rendercommand.cpp \
$$PWD/renderer.cpp \
@@ -13,6 +14,7 @@ SOURCES += \
$$PWD/commandexecuter.cpp
HEADERS += \
+ $$PWD/gllights_p.h \
$$PWD/openglvertexarrayobject_p.h \
$$PWD/renderercache_p.h \
$$PWD/rendercommand_p.h \
diff --git a/src/plugins/renderers/opengl/renderer/renderer_p.h b/src/plugins/renderers/opengl/renderer/renderer_p.h
index 8cf610efb..d4980464a 100644
--- a/src/plugins/renderers/opengl/renderer/renderer_p.h
+++ b/src/plugins/renderers/opengl/renderer/renderer_p.h
@@ -173,7 +173,7 @@ public:
~Renderer();
void dumpInfo() const override;
- API api() const override { return AbstractRenderer::OpenGL; }
+ API api() const override { return Qt3DRender::API::OpenGL; }
qint64 time() const override;
void setTime(qint64 time) override;
@@ -270,7 +270,7 @@ public:
QSharedPointer<RenderBackendResourceAccessor> resourceAccessor() const override;
- const GraphicsApiFilterData *contextInfo() const;
+ const GraphicsApiFilterData *contextInfo() const override;
SubmissionContext *submissionContext() const;
inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; }
diff --git a/src/plugins/renderers/opengl/renderer/renderview.cpp b/src/plugins/renderers/opengl/renderer/renderview.cpp
index 99ac88a94..a3a00782e 100644
--- a/src/plugins/renderers/opengl/renderer/renderview.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderview.cpp
@@ -75,7 +75,8 @@
#include <Qt3DCore/qentity.h>
#include <QtGui/qsurface.h>
#include <algorithm>
-
+#include <atomic>
+#include <gllights_p.h>
#include <QDebug>
#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS)
#include <QElapsedTimer>
@@ -87,33 +88,12 @@ namespace Qt3DRender {
namespace Render {
namespace OpenGL {
-
namespace {
// register our QNodeId's as a metatype during program loading
const int Q_DECL_UNUSED qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>();
-const int MAX_LIGHTS = 8;
-
-#define LIGHT_POSITION_NAME QLatin1String(".position")
-#define LIGHT_TYPE_NAME QLatin1String(".type")
-#define LIGHT_COLOR_NAME QLatin1String(".color")
-#define LIGHT_INTENSITY_NAME QLatin1String(".intensity")
-
-int LIGHT_COUNT_NAME_ID = 0;
-int LIGHT_POSITION_NAMES[MAX_LIGHTS];
-int LIGHT_TYPE_NAMES[MAX_LIGHTS];
-int LIGHT_COLOR_NAMES[MAX_LIGHTS];
-int LIGHT_INTENSITY_NAMES[MAX_LIGHTS];
-QString LIGHT_STRUCT_NAMES[MAX_LIGHTS];
-
-int LIGHT_POSITION_UNROLL_NAMES[MAX_LIGHTS];
-int LIGHT_TYPE_UNROLL_NAMES[MAX_LIGHTS];
-int LIGHT_COLOR_UNROLL_NAMES[MAX_LIGHTS];
-int LIGHT_INTENSITY_UNROLL_NAMES[MAX_LIGHTS];
-QString LIGHT_STRUCT_UNROLL_NAMES[MAX_LIGHTS];
-
-bool wasInitialized = false;
+std::atomic_bool wasInitialized{};
} // anonymous namespace
@@ -168,9 +148,10 @@ static Matrix4x4 getProjectionMatrix(const CameraLens *lens)
}
UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standardUniformType,
- Entity *entity,
- const Matrix4x4 &model) const
+ const Entity *entity) const
{
+ const Matrix4x4 &model = *(entity->worldTransform());
+
switch (standardUniformType) {
case ModelMatrix:
return UniformValue(model);
@@ -263,26 +244,11 @@ RenderView::RenderView()
m_workGroups[1] = 1;
m_workGroups[2] = 1;
- if (Q_UNLIKELY(!wasInitialized)) {
+ if (Q_UNLIKELY(!wasInitialized.exchange(true))) {
// Needed as we can control the init order of static/global variables across compile units
// and this hash relies on the static StringToInt class
- wasInitialized = true;
+
RenderView::ms_standardUniformSetters = RenderView::initializeStandardUniformSetters();
- LIGHT_COUNT_NAME_ID = StringToInt::lookupId(QLatin1String("lightCount"));
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- Q_STATIC_ASSERT_X(MAX_LIGHTS < 10, "can't use the QChar trick anymore");
- LIGHT_STRUCT_NAMES[i] = QLatin1String("lights[") + QLatin1Char(char('0' + i)) + QLatin1Char(']');
- LIGHT_POSITION_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_POSITION_NAME);
- LIGHT_TYPE_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_TYPE_NAME);
- LIGHT_COLOR_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_COLOR_NAME);
- LIGHT_INTENSITY_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_INTENSITY_NAME);
-
- LIGHT_STRUCT_UNROLL_NAMES[i] = QLatin1String("light_") + QLatin1Char(char('0' + i));
- LIGHT_POSITION_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_POSITION_NAME);
- LIGHT_TYPE_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_TYPE_NAME);
- LIGHT_COLOR_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_COLOR_NAME);
- LIGHT_INTENSITY_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_INTENSITY_NAME);
- }
}
}
@@ -437,6 +403,7 @@ struct SubRangeSorter<QSortPolicy::Texture>
{
static void sortSubRange(CommandIt begin, const CommandIt end)
{
+#ifndef Q_OS_WIN
std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) {
QVector<ShaderParameterPack::NamedResource> texturesA = a.m_parameterPack.textures();
QVector<ShaderParameterPack::NamedResource> texturesB = b.m_parameterPack.textures();
@@ -455,6 +422,7 @@ struct SubRangeSorter<QSortPolicy::Texture>
return identicalTextureCount < originalTextureASize;
});
+#endif
}
};
@@ -958,21 +926,16 @@ void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, c
}
void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack,
- int glslNameId,
int nameId,
- Entity *entity,
- const Matrix4x4 &worldTransform) const
+ const Entity *entity) const
{
- uniformPack.setUniform(glslNameId, standardUniformValue(ms_standardUniformSetters[nameId], entity, worldTransform));
+ uniformPack.setUniform(nameId, standardUniformValue(ms_standardUniformSetters[nameId], entity));
}
void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
- GLShader *shader,
const ShaderUniformBlock &block,
const UniformValue &value) const
{
- Q_UNUSED(shader)
-
if (value.valueType() == UniformValue::NodeId) {
Buffer *buffer = nullptr;
@@ -988,11 +951,9 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
}
void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
- GLShader *shader,
const ShaderStorageBlock &block,
const UniformValue &value) const
{
- Q_UNUSED(shader)
if (value.valueType() == UniformValue::NodeId) {
Buffer *buffer = nullptr;
if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) {
@@ -1006,7 +967,10 @@ void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
}
}
-void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, GLShader *shader, ShaderData *shaderData, const QString &structName) const
+void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
+ const GLShader *shader,
+ const ShaderData *shaderData,
+ const QString &structName) const
{
UniformBlockValueBuilder *builder = m_localData.localData();
builder->activeUniformNamesToValue.clear();
@@ -1030,6 +994,42 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
}
}
+void RenderView::applyParameter(const Parameter *param,
+ RenderCommand *command,
+ const GLShader *shader) const noexcept
+{
+ const int nameId = param->nameId();
+ const UniformValue &uniformValue = param->uniformValue();
+ const GLShader::ParameterKind kind = shader->categorizeVariable(nameId);
+
+ switch (kind) {
+ case GLShader::Uniform: {
+ setUniformValue(command->m_parameterPack, nameId, uniformValue);
+ break;
+ }
+ case GLShader::UBO: {
+ setUniformBlockValue(command->m_parameterPack, shader->uniformBlockForBlockNameId(nameId), uniformValue);
+ break;
+ }
+ case GLShader::SSBO: {
+ setShaderStorageValue(command->m_parameterPack, shader->storageBlockForBlockNameId(nameId), uniformValue);
+ break;
+ }
+ case GLShader::Struct: {
+ ShaderData *shaderData = nullptr;
+ if (uniformValue.valueType() == UniformValue::NodeId &&
+ (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) {
+ // Try to check if we have a struct or array matching a QShaderData parameter
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(nameId));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+
void RenderView::setShaderAndUniforms(RenderCommand *command,
ParameterInfoList &parameters,
Entity *entity,
@@ -1052,11 +1052,6 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
// Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings
// If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name
// equals to the parameter name
- const QVector<int> uniformNamesIds = shader->uniformsNamesIds();
- const QVector<int> standardUniformNamesIds = shader->standardUniformNameIds();
- const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds();
- const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds();
- const QVector<int> attributeNamesIds = shader->attributeNamesIds();
// Set fragData Name and index
// Later on we might want to relink the shader if attachments have changed
@@ -1073,113 +1068,95 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
shader->setFragOutputs(fragOutputs);
}
- if (!uniformNamesIds.isEmpty() || !standardUniformNamesIds.isEmpty() ||
- !attributeNamesIds.isEmpty() ||
- !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
+ // Set default attributes
+ command->m_activeAttributes = shader->attributeNamesIds();
- // Set default standard uniforms without bindings
- const Matrix4x4 worldTransform = *(entity->worldTransform());
+ // At this point we know whether the command is a valid draw command or not
+ // We still need to process the uniforms as the command could be a compute command
+ command->m_isValid = !command->m_activeAttributes.empty();
- for (const int uniformNameId : standardUniformNamesIds)
- setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform);
-
- // Set default attributes
- command->m_activeAttributes = attributeNamesIds;
+ if (shader->hasActiveVariables()) {
- // At this point we know whether the command is a valid draw command or not
- // We still need to process the uniforms as the command could be a compute command
- command->m_isValid = !command->m_activeAttributes.empty();
+ // Reserve amount of uniforms we are going to need
+ command->m_parameterPack.reserve(shader->parameterPackSize());
- // Parameters remaining could be
- // -> uniform scalar / vector
- // -> uniform struct / arrays
- // -> uniform block / array (4.3)
- // -> ssbo block / array (4.3)
+ const QVector<int> &standardUniformNamesIds = shader->standardUniformNameIds();
+ for (const int uniformNameId : standardUniformNamesIds)
+ setStandardUniformValue(command->m_parameterPack, uniformNameId, entity);
ParameterInfoList::const_iterator it = parameters.cbegin();
const ParameterInfoList::const_iterator parametersEnd = parameters.cend();
while (it != parametersEnd) {
- Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
- const UniformValue &uniformValue = param->uniformValue();
- if (uniformNamesIds.contains(it->nameId)) { // Parameter is a regular uniform
- setUniformValue(command->m_parameterPack, it->nameId, uniformValue);
- } else if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block
- setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), uniformValue);
- } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO
- setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), uniformValue);
- } else { // Parameter is a struct
- ShaderData *shaderData = nullptr;
- if (uniformValue.valueType() == UniformValue::NodeId &&
- (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) {
- // Try to check if we have a struct or array matching a QShaderData parameter
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId));
- }
- // Otherwise: param unused by current shader
- }
+ const Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
+ applyParameter(param, command, shader);
++it;
}
// Lights
-
- int lightIdx = 0;
- for (const LightSource &lightSource : activeLightSources) {
- if (lightIdx == MAX_LIGHTS)
- break;
- Entity *lightEntity = lightSource.entity;
- const Matrix4x4 lightWorldTransform = *(lightEntity->worldTransform());
- const Vector3D worldPos = lightWorldTransform * Vector3D(0.0f, 0.0f, 0.0f);
- for (Light *light : lightSource.lights) {
- if (!light->isEnabled())
- continue;
-
- ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData());
- if (!shaderData)
- continue;
-
+ const QVector<int> &lightUniformNamesIds = shader->lightUniformsNamesIds();
+ if (!lightUniformNamesIds.empty()) {
+ int lightIdx = 0;
+ for (const LightSource &lightSource : activeLightSources) {
if (lightIdx == MAX_LIGHTS)
break;
+ Entity *lightEntity = lightSource.entity;
+ const Matrix4x4 lightWorldTransform = *(lightEntity->worldTransform());
+ const Vector3D worldPos = lightWorldTransform * Vector3D(0.0f, 0.0f, 0.0f);
+ for (Light *light : lightSource.lights) {
+ if (!light->isEnabled())
+ continue;
+
+ ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData());
+ if (!shaderData)
+ continue;
+
+ if (lightIdx == MAX_LIGHTS)
+ break;
- // Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos);
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
-
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[lightIdx], worldPos);
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[lightIdx], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[lightIdx], 0.5f);
-
-
- // There is no risk in doing that even if multithreaded
- // since we are sure that a shaderData is unique for a given light
- // and won't ever be referenced as a Component either
- Matrix4x4 *worldTransform = lightEntity->worldTransform();
- if (worldTransform)
- shaderData->updateWorldTransform(*worldTransform);
-
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_NAMES[lightIdx]);
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_UNROLL_NAMES[lightIdx]);
- ++lightIdx;
+ // Note: implicit conversion of values to UniformValue
+ if (lightUniformNamesIds.contains(GLLights::LIGHT_TYPE_NAMES[lightIdx])) {
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_POSITION_NAMES[lightIdx], worldPos);
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
+ } else if (lightUniformNamesIds.contains(GLLights::LIGHT_TYPE_UNROLL_NAMES[lightIdx])) {
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_POSITION_UNROLL_NAMES[lightIdx], worldPos);
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_TYPE_UNROLL_NAMES[lightIdx], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_COLOR_UNROLL_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_INTENSITY_UNROLL_NAMES[lightIdx], 0.5f);
+ }
+
+ // There is no risk in doing that even if multithreaded
+ // since we are sure that a shaderData is unique for a given light
+ // and won't ever be referenced as a Component either
+ Matrix4x4 *worldTransform = lightEntity->worldTransform();
+ if (worldTransform)
+ shaderData->updateWorldTransform(*worldTransform);
+
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, GLLights::LIGHT_STRUCT_NAMES[lightIdx]);
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, GLLights::LIGHT_STRUCT_UNROLL_NAMES[lightIdx]);
+ ++lightIdx;
+ }
}
- }
- if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID))
- setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx)));
-
- // If no active light sources and no environment light, add a default light
- if (activeLightSources.isEmpty() && !environmentLight) {
- // Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f);
-
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[0], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[0], 0.5f);
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx)));
+
+ // If no active light sources and no environment light, add a default light
+ if (activeLightSources.isEmpty() && !environmentLight) {
+ // Note: implicit conversion of values to UniformValue
+ if (lightUniformNamesIds.contains(GLLights::LIGHT_TYPE_NAMES[0])) {
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_INTENSITY_NAMES[0], 0.5f);
+ } else if (lightUniformNamesIds.contains(GLLights::LIGHT_TYPE_UNROLL_NAMES[lightIdx])) {
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_POSITION_UNROLL_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_TYPE_UNROLL_NAMES[0], int(QAbstractLight::PointLight));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_COLOR_UNROLL_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, GLLights::LIGHT_INTENSITY_UNROLL_NAMES[0], 0.5f);
+ }
+ }
}
// Environment Light
@@ -1200,6 +1177,9 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
}
setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount);
}
+
+ // Prepare the ShaderParameterPack based on the active uniforms of the shader
+ shader->prepareUniforms(command->m_parameterPack);
}
}
@@ -1233,6 +1213,9 @@ bool RenderView::shouldSkipSubmission() const
if (m_clearBuffer != QClearBuffers::None)
return false;
+ if (!m_renderCaptureNodeId.isNull())
+ return false;
+
return true;
}
diff --git a/src/plugins/renderers/opengl/renderer/renderview_p.h b/src/plugins/renderers/opengl/renderer/renderview_p.h
index adab30f4e..6c41ce500 100644
--- a/src/plugins/renderers/opengl/renderer/renderview_p.h
+++ b/src/plugins/renderers/opengl/renderer/renderview_p.h
@@ -370,27 +370,25 @@ private:
static StandardUniformsNameToTypeHash initializeStandardUniformSetters();
UniformValue standardUniformValue(StandardUniform standardUniformType,
- Entity *entity,
- const Matrix4x4 &model) const;
+ const Entity *entity) const;
void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
void setStandardUniformValue(ShaderParameterPack &uniformPack,
- int glslNameId,
int nameId,
- Entity *entity,
- const Matrix4x4 &worldTransform) const;
+ const Entity *entity) const;
void setUniformBlockValue(ShaderParameterPack &uniformPack,
- GLShader *shader,
const ShaderUniformBlock &block,
const UniformValue &value) const;
void setShaderStorageValue(ShaderParameterPack &uniformPack,
- GLShader *shader,
const ShaderStorageBlock &block,
const UniformValue &value) const;
void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
- GLShader *shader,
- ShaderData *shaderData,
+ const GLShader *shader,
+ const ShaderData *shaderData,
const QString &structName) const;
+ void applyParameter(const Parameter *param,
+ RenderCommand *command,
+ const GLShader *shader) const noexcept;
};
} // namespace OpenGL
diff --git a/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp b/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp
index 8ed32ff10..b0ac76199 100644
--- a/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp
@@ -49,18 +49,13 @@ namespace Qt3DRender {
namespace Render {
namespace OpenGL {
-// In some cases having less jobs is better (especially on fast cpus where
-// splitting just adds more overhead). Ideally, we should try to set the value
-// depending on the platform/CPU/nbr of cores
-const int RenderViewBuilder::m_optimalParallelJobCount = QThread::idealThreadCount();
-
namespace {
-int findIdealNumberOfWorkers(int elementCount, int packetSize = 100)
+int findIdealNumberOfWorkers(int elementCount, int packetSize = 100, int maxJobCount = 1)
{
if (elementCount == 0 || packetSize == 0)
return 0;
- return std::min(std::max(elementCount / packetSize, 1), RenderViewBuilder::optimalJobCount());
+ return std::min(std::max(elementCount / packetSize, 1), maxJobCount);
}
@@ -93,9 +88,10 @@ public:
lock.unlock();
// Split among the ideal number of command builders
- const int idealPacketSize = std::min(std::max(100, entities.size() / RenderViewBuilder::optimalJobCount()), entities.size());
+ const int jobCount = m_renderViewCommandBuilderJobs.size();
+ const int idealPacketSize = std::min(std::max(10, entities.size() / jobCount), entities.size());
// Try to split work into an ideal number of workers
- const int m = findIdealNumberOfWorkers(entities.size(), idealPacketSize);
+ const int m = findIdealNumberOfWorkers(entities.size(), idealPacketSize, jobCount);
for (int i = 0; i < m; ++i) {
const RenderViewCommandBuilderJobPtr renderViewCommandBuilder = m_renderViewCommandBuilderJobs.at(i);
@@ -352,9 +348,9 @@ public:
}
// Split among the number of command builders
- // The idealPacketSize is at least 100 entities per worker
- const int idealPacketSize = std::min(std::max(100, filteredCommandData->size() / RenderViewBuilder::optimalJobCount()), filteredCommandData->size());
- const int m = findIdealNumberOfWorkers(filteredCommandData->size(), idealPacketSize);
+ const int jobCount = m_renderViewCommandUpdaterJobs.size();
+ const int idealPacketSize = std::min(std::max(10, filteredCommandData->size() / jobCount), filteredCommandData->size());
+ const int m = findIdealNumberOfWorkers(filteredCommandData->size(), idealPacketSize, jobCount);
for (int i = 0; i < m; ++i) {
const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = m_renderViewCommandUpdaterJobs.at(i);
@@ -474,6 +470,10 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
, m_syncFilterEntityByLayerJob()
, m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create())
{
+ // In some cases having less jobs is better (especially on fast cpus where
+ // splitting just adds more overhead). Ideally, we should try to set the value
+ // depending on the platform/CPU/nbr of cores
+ m_optimalParallelJobCount = QThread::idealThreadCount();
}
RenderViewInitializerJobPtr RenderViewBuilder::renderViewJob() const
@@ -558,17 +558,16 @@ void RenderViewBuilder::prepareJobs()
m_frustumCullingJob->setRoot(m_renderer->sceneRoot());
if (m_renderCommandCacheNeedsToBeRebuilt) {
-
- m_renderViewCommandBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
- for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
+ m_renderViewCommandBuilderJobs.reserve(m_optimalParallelJobCount);
+ for (auto i = 0; i < m_optimalParallelJobCount; ++i) {
auto renderViewCommandBuilder = Render::OpenGL::RenderViewCommandBuilderJobPtr::create();
m_renderViewCommandBuilderJobs.push_back(renderViewCommandBuilder);
}
m_syncRenderViewPreCommandBuildingJob = CreateSynchronizerJobPtr(SyncPreCommandBuilding(m_renderViewJob,
- m_renderViewCommandBuilderJobs,
- m_renderer,
- m_leafNode),
- JobTypes::SyncRenderViewPreCommandBuilding);
+ m_renderViewCommandBuilderJobs,
+ m_renderer,
+ m_leafNode),
+ JobTypes::SyncRenderViewPreCommandBuilding);
}
m_renderViewJob->setRenderer(m_renderer);
@@ -577,8 +576,8 @@ void RenderViewBuilder::prepareJobs()
// RenderCommand building is the most consuming task -> split it
// Estimate the number of jobs to create based on the number of entities
- m_renderViewCommandUpdaterJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
- for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
+ m_renderViewCommandUpdaterJobs.reserve(m_optimalParallelJobCount);
+ for (auto i = 0; i < m_optimalParallelJobCount; ++i) {
auto renderViewCommandUpdater = Render::OpenGL::RenderViewCommandUpdaterJobPtr::create();
renderViewCommandUpdater->setRenderer(m_renderer);
m_renderViewCommandUpdaterJobs.push_back(renderViewCommandUpdater);
@@ -587,22 +586,23 @@ void RenderViewBuilder::prepareJobs()
if (m_materialGathererCacheNeedsToBeRebuilt) {
// Since Material gathering is an heavy task, we split it
const QVector<HMaterial> materialHandles = m_renderer->nodeManagers()->materialManager()->activeHandles();
- const int elementsPerJob = materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount;
- const int lastRemaingElements = materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount;
- m_materialGathererJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
- for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
- auto materialGatherer = MaterialParameterGathererJobPtr::create();
- materialGatherer->setNodeManagers(m_renderer->nodeManagers());
- if (i == RenderViewBuilder::m_optimalParallelJobCount - 1)
- materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob + lastRemaingElements));
- else
- materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob));
- m_materialGathererJobs.push_back(materialGatherer);
+ if (materialHandles.count()) {
+ const int elementsPerJob = qMax(materialHandles.size() / m_optimalParallelJobCount, 1);
+ m_materialGathererJobs.reserve(m_optimalParallelJobCount);
+ int elementCount = 0;
+ while (elementCount < materialHandles.size()) {
+ auto materialGatherer = MaterialParameterGathererJobPtr::create();
+ materialGatherer->setNodeManagers(m_renderer->nodeManagers());
+ materialGatherer->setHandles(materialHandles.mid(elementCount, elementsPerJob));
+ m_materialGathererJobs.push_back(materialGatherer);
+
+ elementCount += elementsPerJob;
+ }
}
m_syncMaterialGathererJob = CreateSynchronizerJobPtr(SyncMaterialParameterGatherer(m_materialGathererJobs,
- m_renderer,
- m_leafNode),
- JobTypes::SyncMaterialGatherer);
+ m_renderer,
+ m_leafNode),
+ JobTypes::SyncMaterialGatherer);
}
if (m_layerCacheNeedsToBeRebuilt) {
@@ -615,29 +615,29 @@ void RenderViewBuilder::prepareJobs()
}
m_syncRenderViewPreCommandUpdateJob = CreateSynchronizerJobPtr(SyncRenderViewPreCommandUpdate(m_renderViewJob,
- m_frustumCullingJob,
- m_filterProximityJob,
- m_materialGathererJobs,
- m_renderViewCommandUpdaterJobs,
- m_renderViewCommandBuilderJobs,
- m_renderer,
- m_leafNode,
- m_renderCommandCacheNeedsToBeRebuilt),
- JobTypes::SyncRenderViewPreCommandUpdate);
+ m_frustumCullingJob,
+ m_filterProximityJob,
+ m_materialGathererJobs,
+ m_renderViewCommandUpdaterJobs,
+ m_renderViewCommandBuilderJobs,
+ m_renderer,
+ m_leafNode,
+ m_renderCommandCacheNeedsToBeRebuilt),
+ JobTypes::SyncRenderViewPreCommandUpdate);
m_syncRenderViewPostCommandUpdateJob = CreateSynchronizerJobPtr(SyncRenderViewPostCommandUpdate(m_renderViewJob,
- m_renderViewCommandUpdaterJobs,
- m_renderer),
- JobTypes::SyncRenderViewPostCommandUpdate);
+ m_renderViewCommandUpdaterJobs,
+ m_renderer),
+ JobTypes::SyncRenderViewPostCommandUpdate);
m_syncRenderViewPostInitializationJob = CreateSynchronizerJobPtr(SyncRenderViewPostInitialization(m_renderViewJob,
- m_frustumCullingJob,
- m_filterEntityByLayerJob,
- m_filterProximityJob,
- m_materialGathererJobs,
- m_renderViewCommandUpdaterJobs,
- m_renderViewCommandBuilderJobs),
- JobTypes::SyncRenderViewInitialization);
+ m_frustumCullingJob,
+ m_filterEntityByLayerJob,
+ m_filterProximityJob,
+ m_materialGathererJobs,
+ m_renderViewCommandUpdaterJobs,
+ m_renderViewCommandBuilderJobs),
+ JobTypes::SyncRenderViewInitialization);
}
QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
@@ -793,9 +793,34 @@ bool RenderViewBuilder::renderCommandCacheNeedsToBeRebuilt() const
return m_renderCommandCacheNeedsToBeRebuilt;
}
-int RenderViewBuilder::optimalJobCount()
+int RenderViewBuilder::defaultJobCount()
+{
+ static int jobCount = 0;
+ if (jobCount)
+ return jobCount;
+
+ const QByteArray maxThreadCount = qgetenv("QT3D_MAX_THREAD_COUNT");
+ if (!maxThreadCount.isEmpty()) {
+ bool conversionOK = false;
+ const int maxThreadCountValue = maxThreadCount.toInt(&conversionOK);
+ if (conversionOK) {
+ jobCount = maxThreadCountValue;
+ return jobCount;
+ }
+ }
+
+ jobCount = QThread::idealThreadCount();
+ return jobCount;
+}
+
+int RenderViewBuilder::optimalJobCount() const
+{
+ return m_optimalParallelJobCount;
+}
+
+void RenderViewBuilder::setOptimalJobCount(int v)
{
- return RenderViewBuilder::m_optimalParallelJobCount;
+ m_optimalParallelJobCount = v;
}
QVector<Entity *> RenderViewBuilder::entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset)
diff --git a/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h b/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h
index 54fc98352..17e5fa744 100644
--- a/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h
+++ b/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h
@@ -61,7 +61,6 @@
#include <renderviewcommandbuilderjob_p.h>
#include <renderviewcommandupdaterjob_p.h>
#include <materialparametergathererjob_p.h>
-#include <renderviewbuilderjob_p.h>
#include <renderview_p.h>
QT_BEGIN_NAMESPACE
@@ -112,7 +111,10 @@ public:
void setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
bool renderCommandCacheNeedsToBeRebuilt() const;
- static int optimalJobCount();
+ static int defaultJobCount();
+ int optimalJobCount() const;
+ void setOptimalJobCount(int v);
+
static QVector<Entity *> entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset);
private:
@@ -140,7 +142,7 @@ private:
SynchronizerJobPtr m_syncMaterialGathererJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
- static const int m_optimalParallelJobCount;
+ int m_optimalParallelJobCount;
};
} // OpenGL
diff --git a/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp b/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp
index c51595bb7..bc9e9434b 100644
--- a/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp
+++ b/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp
@@ -58,6 +58,12 @@ ShaderParameterPack::~ShaderParameterPack()
{
}
+void ShaderParameterPack::reserve(int uniformCount)
+{
+ m_uniforms.reserve(uniformCount);
+ m_submissionUniformIndices.reserve(uniformCount);
+}
+
void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val)
{
m_uniforms.insert(glslNameId, val);
@@ -100,9 +106,9 @@ void ShaderParameterPack::setShaderStorageBuffer(BlockToSSBO blockToSSBO)
m_shaderStorageBuffers.push_back(std::move(blockToSSBO));
}
-void ShaderParameterPack::setSubmissionUniform(const ShaderUniform &uniform)
+void ShaderParameterPack::setSubmissionUniformIndex(const int uniformIdx)
{
- m_submissionUniforms.push_back(uniform);
+ m_submissionUniformIndices.push_back(uniformIdx);
}
} // namespace OpenGL
diff --git a/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h b/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h
index 31ef4f7ea..bb6bb0dc6 100644
--- a/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h
+++ b/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h
@@ -93,8 +93,12 @@ struct PackUniformHash
PackUniformHash()
{
- keys.reserve(10);
- values.reserve(10);
+ }
+
+ void reserve(int count)
+ {
+ keys.reserve(count);
+ values.reserve(count);
}
void insert(int key, const UniformValue &value)
@@ -142,13 +146,14 @@ class Q_AUTOTEST_EXPORT ShaderParameterPack
public:
~ShaderParameterPack();
+ void reserve(int uniformCount);
void setUniform(const int glslNameId, const UniformValue &val);
void setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
void setImage(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
void setUniformBuffer(BlockToUBO blockToUBO);
void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
- void setSubmissionUniform(const ShaderUniform &uniform);
+ void setSubmissionUniformIndex(const int shaderUniformIndex);
inline PackUniformHash &uniforms() { return m_uniforms; }
inline const PackUniformHash &uniforms() const { return m_uniforms; }
@@ -194,7 +199,7 @@ public:
inline QVector<NamedResource> images() const { return m_images; }
inline QVector<BlockToUBO> uniformBuffers() const { return m_uniformBuffers; }
inline QVector<BlockToSSBO> shaderStorageBuffers() const { return m_shaderStorageBuffers; }
- inline QVector<ShaderUniform> submissionUniforms() const { return m_submissionUniforms; }
+ inline QVector<int> submissionUniformIndices() const { return m_submissionUniformIndices; }
private:
PackUniformHash m_uniforms;
@@ -202,7 +207,7 @@ private:
QVector<NamedResource> m_images;
QVector<BlockToUBO> m_uniformBuffers;
QVector<BlockToSSBO> m_shaderStorageBuffers;
- QVector<ShaderUniform> m_submissionUniforms;
+ QVector<int> m_submissionUniformIndices;
friend class RenderView;
};