1// Copyright (C) 2016 Paul Lemire
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "materialparametergathererjob_p.h"
5#include <Qt3DRender/private/nodemanagers_p.h>
6#include <Qt3DRender/private/managers_p.h>
7#include <Qt3DRender/private/renderpassfilternode_p.h>
8#include <Qt3DRender/private/techniquefilternode_p.h>
9#include <Qt3DRender/private/job_common_p.h>
10
11QT_BEGIN_NAMESPACE
12
13namespace Qt3DRender {
14
15namespace Render {
16
17namespace {
18
19int materialParameterGathererCounter = 0;
20const int likelyNumberOfParameters = 24;
21
22} // anonymous
23
24class MaterialParameterGathererJobPrivate : public Qt3DCore::QAspectJobPrivate
25{
26public:
27 MaterialParameterGathererJobPrivate(MaterialParameterGathererJob *q) : q_ptr(q) { }
28 ~MaterialParameterGathererJobPrivate() override = default;
29
30 bool isRequired() const override;
31 void postFrame(Qt3DCore::QAspectManager *manager) override;
32
33 MaterialParameterGathererJob *q_ptr;
34 Q_DECLARE_PUBLIC(MaterialParameterGathererJob)
35};
36
37bool MaterialParameterGathererJobPrivate::isRequired() const
38{
39 return !q_ptr->m_handles.empty();
40}
41
42void MaterialParameterGathererJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
43{
44 Q_UNUSED(manager);
45 materialParameterGathererCounter = 0;
46}
47
48MaterialParameterGathererJob::MaterialParameterGathererJob()
49 : Qt3DCore::QAspectJob(*new MaterialParameterGathererJobPrivate(this))
50 , m_manager(nullptr)
51 , m_techniqueFilter(nullptr)
52 , m_renderPassFilter(nullptr)
53{
54 SET_JOB_RUN_STAT_TYPE(this, JobTypes::MaterialParameterGathering, materialParameterGathererCounter++)
55}
56
57// TechniqueFilter / RenderPassFilter
58
59// Parameters from Material/Effect/Technique
60
61// Note: we could maybe improve that by having a smart update when we detect
62// that a parameter value has changed. That might require way more book keeping
63// which might make this solution a bit too complex
64
65// The fact that this can now be performed in parallel should already provide a big
66// improvement
67void MaterialParameterGathererJob::run()
68{
69 for (const HMaterial &materialHandle : std::as_const(t&: m_handles)) {
70 Material *material = m_manager->materialManager()->data(handle: materialHandle);
71
72 if (Q_UNLIKELY(!material->isEnabled()))
73 continue;
74
75 Effect *effect = m_manager->effectManager()->lookupResource(id: material->effect());
76 Technique *technique = findTechniqueForEffect(manager: m_manager, techniqueFilter: m_techniqueFilter, effect);
77
78 if (Q_LIKELY(technique != nullptr)) {
79 RenderPassList passes = findRenderPassesForTechnique(manager: m_manager, passFilter: m_renderPassFilter, technique);
80 if (Q_LIKELY(passes.size() > 0)) {
81 // Order set:
82 // 1 Pass Filter
83 // 2 Technique Filter
84 // 3 Material
85 // 4 Effect
86 // 5 Technique
87 // 6 RenderPass
88
89 // Add Parameters define in techniqueFilter and passFilter
90 // passFilter have priority over techniqueFilter
91
92 ParameterInfoList parameters;
93 // Doing the reserve allows a gain of 0.5ms on some of the demo examples
94 parameters.reserve(asize: likelyNumberOfParameters);
95
96 if (m_renderPassFilter)
97 parametersFromParametersProvider(infoList: &parameters, manager: m_manager->parameterManager(),
98 provider: m_renderPassFilter);
99 if (m_techniqueFilter)
100 parametersFromParametersProvider(infoList: &parameters, manager: m_manager->parameterManager(),
101 provider: m_techniqueFilter);
102 // Get the parameters for our selected rendering setup (override what was defined in the technique/pass filter)
103 parametersFromMaterialEffectTechnique(infoList: &parameters, manager: m_manager->parameterManager(), material, effect, technique);
104
105 for (RenderPass *renderPass : passes) {
106 ParameterInfoList globalParameters = parameters;
107 parametersFromParametersProvider(infoList: &globalParameters, manager: m_manager->parameterManager(), provider: renderPass);
108 auto it = m_parameters.find(key: material->peerId());
109 if (it != m_parameters.end())
110 it->push_back(x: {.pass: renderPass, .parameterInfo: globalParameters});
111 else
112 m_parameters.insert(key: material->peerId(), value: {{.pass: renderPass, .parameterInfo: globalParameters}});
113 }
114 }
115 }
116 }
117}
118
119} // Render
120
121} // Qt3DRender
122
123QT_END_NAMESPACE
124

source code of qt3d/src/render/jobs/materialparametergathererjob.cpp