summaryrefslogtreecommitdiffstats
path: root/src/render/jobs/renderviewjobutils.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2020-07-06 11:07:10 +0200
committerPaul Lemire <paul.lemire@kdab.com>2020-07-07 12:13:45 +0200
commitdb4de3f44a9011ae644c7d2ea10ec2394ff7f6f0 (patch)
tree3b01abe0ae1e398a1bc3b8b6e9f796e0f5cb80a3 /src/render/jobs/renderviewjobutils.cpp
parent48d44319b73cb5ef34bfbb3bade6e73c1891c92f (diff)
Share code between renderer plugins
- MaterialParameterGatherer is common to both - FilterCompatibleTechniqueJob is common to both - RenderViewJobUtils refactor to only contain code common to both - UniformBlockValueBuilder moved to dedicated file, shared with both Change-Id: I634e6d60eb9a213dd6a0d5abd8ac53710bff1417 Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/render/jobs/renderviewjobutils.cpp')
-rw-r--r--src/render/jobs/renderviewjobutils.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp
new file mode 100644
index 000000000..4e0556a8b
--- /dev/null
+++ b/src/render/jobs/renderviewjobutils.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "renderviewjobutils_p.h"
+#include <Qt3DRender/private/renderlogging_p.h>
+
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <Qt3DRender/private/sphere_p.h>
+#include <Qt3DRender/qshaderdata.h>
+
+#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/effect_p.h>
+#include <Qt3DRender/private/renderpassfilternode_p.h>
+#include <Qt3DRender/private/techniquemanager_p.h>
+#include <Qt3DRender/private/techniquefilternode_p.h>
+#include <Qt3DRender/private/renderstatenode_p.h>
+#include <Qt3DRender/private/renderstates_p.h>
+#include <Qt3DRender/private/renderstateset_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DCore;
+
+namespace Qt3DRender {
+namespace Render {
+
+/*!
+ \internal
+ Searches the best matching Technique from \a effect specified.
+*/
+Technique *findTechniqueForEffect(NodeManagers *manager,
+ const TechniqueFilter *techniqueFilter,
+ Effect *effect)
+{
+ if (!effect)
+ return nullptr;
+
+ std::vector<Technique*> matchingTechniques;
+ const bool hasInvalidTechniqueFilter = (techniqueFilter == nullptr || techniqueFilter->filters().isEmpty());
+
+ // Iterate through the techniques in the effect
+ const auto techniqueIds = effect->techniques();
+ for (const QNodeId techniqueId : techniqueIds) {
+ Technique *technique = manager->techniqueManager()->lookupResource(techniqueId);
+
+ // Should be valid, if not there likely a problem with node addition/destruction changes
+ Q_ASSERT(technique);
+
+ // Check if the technique is compatible with the rendering API
+ // If no techniqueFilter is present, we return the technique as it satisfies OpenGL version
+ if (technique->isCompatibleWithRenderer() && (hasInvalidTechniqueFilter || technique->isCompatibleWithFilters(techniqueFilter->filters())))
+ matchingTechniques.push_back(technique);
+ }
+
+ if (matchingTechniques.size() == 0) // We failed to find a suitable technique to use :(
+ return nullptr;
+
+ if (matchingTechniques.size() == 1)
+ return matchingTechniques.front();
+
+ // Several compatible techniques, return technique with highest major and minor version
+ Technique* highest = matchingTechniques.front();
+ GraphicsApiFilterData filter = *highest->graphicsApiFilter();
+ for (auto it = matchingTechniques.cbegin() + 1; it < matchingTechniques.cend(); ++it) {
+ if (filter < *(*it)->graphicsApiFilter()) {
+ filter = *(*it)->graphicsApiFilter();
+ highest = *it;
+ }
+ }
+ return highest;
+}
+
+
+RenderPassList findRenderPassesForTechnique(NodeManagers *manager,
+ const RenderPassFilter *passFilter,
+ Technique *technique)
+{
+ Q_ASSERT(manager);
+ Q_ASSERT(technique);
+
+ RenderPassList passes;
+ const auto passIds = technique->renderPasses();
+ for (const QNodeId passId : passIds) {
+ RenderPass *renderPass = manager->renderPassManager()->lookupResource(passId);
+
+ if (renderPass && renderPass->isEnabled()) {
+ bool foundMatch = (!passFilter || passFilter->filters().size() == 0);
+
+ // A pass filter is present so we need to check for matching criteria
+ if (!foundMatch && renderPass->filterKeys().size() >= passFilter->filters().size()) {
+
+ // Iterate through the filter criteria and look for render passes with criteria that satisfy them
+ const auto filterKeyIds = passFilter->filters();
+ for (const QNodeId filterKeyId : filterKeyIds) {
+ foundMatch = false;
+ FilterKey *filterFilterKey = manager->filterKeyManager()->lookupResource(filterKeyId);
+
+ const auto passFilterKeyIds = renderPass->filterKeys();
+ for (const QNodeId passFilterKeyId : passFilterKeyIds) {
+ FilterKey *passFilterKey = manager->filterKeyManager()->lookupResource(passFilterKeyId);
+ if ((foundMatch = (*passFilterKey == *filterFilterKey)))
+ break;
+ }
+
+ if (!foundMatch) {
+ // No match for criterion in any of the render pass' criteria
+ break;
+ }
+ }
+ }
+
+ if (foundMatch) {
+ // Found a renderpass that satisfies our needs. Add it in order
+ passes << renderPass;
+ }
+ }
+ }
+
+ return passes;
+}
+
+
+ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *params, const int nameId)
+{
+ const ParameterInfoList::const_iterator end = params->cend();
+ ParameterInfoList::const_iterator it = std::lower_bound(params->cbegin(), end, nameId);
+ if (it != end && it->nameId != nameId)
+ return end;
+ return it;
+}
+
+void addParametersForIds(ParameterInfoList *params, ParameterManager *manager,
+ const Qt3DCore::QNodeIdVector &parameterIds)
+{
+ for (const QNodeId paramId : parameterIds) {
+ const HParameter parameterHandle = manager->lookupHandle(paramId);
+ const Parameter *param = manager->data(parameterHandle);
+ ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->nameId());
+ if (it == params->end() || it->nameId != param->nameId())
+ params->insert(it, ParameterInfo(param->nameId(), parameterHandle));
+ }
+}
+
+void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList,
+ ParameterManager *manager,
+ Material *material,
+ Effect *effect,
+ Technique *technique)
+{
+ // The parameters are taken in the following priority order:
+ //
+ // 1) Material
+ // 2) Effect
+ // 3) Technique
+ //
+ // That way a user can override defaults in Effect's and Techniques on a
+ // object manner and a Technique can override global defaults from the Effect.
+ parametersFromParametersProvider(infoList, manager, material);
+ parametersFromParametersProvider(infoList, manager, effect);
+ parametersFromParametersProvider(infoList, manager, technique);
+}
+
+// Only add states with types we don't already have
+void addStatesToRenderStateSet(RenderStateSet *stateSet,
+ const QVector<Qt3DCore::QNodeId> stateIds,
+ RenderStateManager *manager)
+{
+ for (const Qt3DCore::QNodeId &stateId : stateIds) {
+ RenderStateNode *node = manager->lookupResource(stateId);
+ if (node->isEnabled() && stateSet->canAddStateOfType(node->type())) {
+ stateSet->addState(node->impl());
+ }
+ }
+}
+
+ParameterInfo::ParameterInfo(const int nameId, const HParameter &handle)
+ : nameId(nameId)
+ , handle(handle)
+{}
+
+bool ParameterInfo::operator<(const ParameterInfo &other) const Q_DECL_NOEXCEPT
+{
+ return nameId < other.nameId;
+}
+
+bool ParameterInfo::operator<(const int otherNameId) const Q_DECL_NOEXCEPT
+{
+ return nameId < otherNameId;
+}
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE