diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2020-07-06 11:07:10 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2020-07-07 12:13:45 +0200 |
commit | db4de3f44a9011ae644c7d2ea10ec2394ff7f6f0 (patch) | |
tree | 3b01abe0ae1e398a1bc3b8b6e9f796e0f5cb80a3 /src/render/jobs/renderviewjobutils.cpp | |
parent | 48d44319b73cb5ef34bfbb3bade6e73c1891c92f (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.cpp | 231 |
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 ¶meterIds) +{ + 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 |