diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2018-03-12 08:32:35 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2020-02-05 11:33:49 +0100 |
commit | 0e115ff000fb294de8519bf5b39beee0d6bfa605 (patch) | |
tree | c66c1f19ad5e4b7fc4f3be7951fa74d1d4df64bb /src/render/renderers/opengl/renderer/renderviewbuilder.cpp | |
parent | f1f387c22dac8748a7edb1f4aa1ea6dac7dfbdfd (diff) |
Make the OpenGL renderer a plugin
By default the QRenderAspect will try to load this plugin
Change-Id: Ie55e207fb8e6d0b64f717bbb99699eb669eaa3f2
Task-number: QTBUG-61151
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl/renderer/renderviewbuilder.cpp')
-rw-r--r-- | src/render/renderers/opengl/renderer/renderviewbuilder.cpp | 803 |
1 files changed, 0 insertions, 803 deletions
diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp deleted file mode 100644 index 4034af146..000000000 --- a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp +++ /dev/null @@ -1,803 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "renderviewbuilder_p.h" - -#include <QThread> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -// 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) -{ - if (elementCount == 0 || packetSize == 0) - return 0; - return std::min(std::max(elementCount / packetSize, 1), RenderViewBuilder::optimalJobCount()); -} - - -class SyncPreCommandBuilding -{ -public: - explicit SyncPreCommandBuilding(RenderViewInitializerJobPtr renderViewInitializerJob, - const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_renderViewInitializer(renderViewInitializerJob) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - { - } - - void operator()() - { - // Split commands to build among jobs - QMutexLocker lock(m_renderer->cache()->mutex()); - // Rebuild RenderCommands for all entities in RV (ignoring filtering) - RendererCache *cache = m_renderer->cache(); - const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode]; - RenderView *rv = m_renderViewInitializer->renderView(); - const auto entities = !rv->isCompute() ? cache->renderableEntities : cache->computeEntities; - - rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer); - - lock.unlock(); - - // Split among the ideal number of command builders - const int idealPacketSize = std::min(std::max(100, entities.size() / RenderViewBuilder::optimalJobCount()), entities.size()); - // Try to split work into an ideal number of workers - const int m = findIdealNumberOfWorkers(entities.size(), idealPacketSize); - - for (int i = 0; i < m; ++i) { - const RenderViewCommandBuilderJobPtr renderViewCommandBuilder = m_renderViewCommandBuilderJobs.at(i); - const int count = (i == m - 1) ? entities.size() - (i * idealPacketSize) : idealPacketSize; - renderViewCommandBuilder->setEntities(entities, i * idealPacketSize, count); - } - } - -private: - RenderViewInitializerJobPtr m_renderViewInitializer; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; -}; - -class SyncRenderViewPostCommandUpdate -{ -public: - explicit SyncRenderViewPostCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob, - const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdateJobs, - Renderer *renderer) - : m_renderViewJob(renderViewJob) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdateJobs) - , m_renderer(renderer) - {} - - void operator()() - { - // Append all the commands and sort them - RenderView *rv = m_renderViewJob->renderView(); - - const EntityRenderCommandDataPtr commandData = m_renderViewCommandUpdaterJobs.first()->renderables(); - - if (commandData) { - const QVector<RenderCommand> commands = std::move(commandData->commands); - rv->setCommands(commands); - - // TO DO: Find way to store commands once or at least only when required - // Sort the commands - rv->sort(); - } - - // Enqueue our fully populated RenderView with the RenderThread - m_renderer->enqueueRenderView(rv, m_renderViewJob->submitOrderIndex()); - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - Renderer *m_renderer; -}; - -class SyncPreFrustumCulling -{ -public: - explicit SyncPreFrustumCulling(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCulling) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCulling) - {} - - void operator()() - { - RenderView *rv = m_renderViewJob->renderView(); - - // Update matrices now that all transforms have been updated - rv->updateMatrices(); - - // Frustum culling - m_frustumCullingJob->setViewProjection(rv->viewProjectionMatrix()); - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - FrustumCullingJobPtr m_frustumCullingJob; -}; - -class SyncRenderViewPostInitialization -{ -public: - explicit SyncRenderViewPostInitialization(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCullingJob, - const FilterLayerEntityJobPtr &filterEntityByLayerJob, - const FilterProximityDistanceJobPtr &filterProximityJob, - const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs, - const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdaterJobs, - const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCullingJob) - , m_filterEntityByLayerJob(filterEntityByLayerJob) - , m_filterProximityJob(filterProximityJob) - , m_materialGathererJobs(materialGathererJobs) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - {} - - void operator()() - { - RenderView *rv = m_renderViewJob->renderView(); - - // Layer filtering - if (!m_filterEntityByLayerJob.isNull()) - m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters()); - - // Proximity filtering - m_filterProximityJob->setProximityFilterIds(rv->proximityFilterIds()); - - // Material Parameter building - for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { - materialGatherer->setRenderPassFilter(const_cast<RenderPassFilter *>(rv->renderPassFilter())); - materialGatherer->setTechniqueFilter(const_cast<TechniqueFilter *>(rv->techniqueFilter())); - } - - // Command builders and updates - for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs)) - renderViewCommandUpdater->setRenderView(rv); - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) - renderViewCommandBuilder->setRenderView(rv); - - // Set whether frustum culling is enabled or not - m_frustumCullingJob->setActive(rv->frustumCulling()); - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - FrustumCullingJobPtr m_frustumCullingJob; - FilterLayerEntityJobPtr m_filterEntityByLayerJob; - FilterProximityDistanceJobPtr m_filterProximityJob; - QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; -}; - -class SyncRenderViewPreCommandUpdate -{ -public: - explicit SyncRenderViewPreCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCullingJob, - const FilterProximityDistanceJobPtr &filterProximityJob, - const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs, - const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdaterJobs, - const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs, - Renderer *renderer, - FrameGraphNode *leafNode, - bool fullCommandRebuild) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCullingJob) - , m_filterProximityJob(filterProximityJob) - , m_materialGathererJobs(materialGathererJobs) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - , m_fullRebuild(fullCommandRebuild) - {} - - void operator()() - { - // Set the result of previous job computations - // for final RenderCommand building - RenderView *rv = m_renderViewJob->renderView(); - - if (!rv->noDraw()) { - ///////// CACHE LOCKED //////////// - // Retrieve Data from Cache - RendererCache *cache = m_renderer->cache(); - QMutexLocker lock(cache->mutex()); - Q_ASSERT(cache->leafNodeCache.contains(m_leafNode)); - - const bool isDraw = !rv->isCompute(); - const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode]; - - // Rebuild RenderCommands if required - // This should happen fairly infrequently (FrameGraph Change, Geometry/Material change) - // and allow to skip that step most of the time - if (m_fullRebuild) { - EntityRenderCommandData commandData; - // Reduction - { - int totalCommandCount = 0; - for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) - totalCommandCount += renderViewCommandBuilder->commandData().size(); - commandData.reserve(totalCommandCount); - for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) - commandData += std::move(renderViewCommandBuilder->commandData()); - } - - - // Store new cache - RendererCache::LeafNodeData &writableCacheForLeaf = cache->leafNodeCache[m_leafNode]; - writableCacheForLeaf.renderCommandData = std::move(commandData); - } - const EntityRenderCommandData commandData = dataCacheForLeaf.renderCommandData; - const QVector<Entity *> filteredEntities = dataCacheForLeaf.filterEntitiesByLayer; - QVector<Entity *> renderableEntities = isDraw ? cache->renderableEntities : cache->computeEntities; - QVector<LightSource> lightSources = cache->gatheredLights; - - rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer); - rv->setEnvironmentLight(cache->environmentLight); - lock.unlock(); - ///////// END OF CACHE LOCKED //////////// - - // Filter out entities that weren't selected by the layer filters - // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, filteredEntities); - - // Set the light sources, with layer filters applied. - for (int i = 0; i < lightSources.count(); ++i) { - if (!filteredEntities.contains(lightSources[i].entity)) - lightSources.removeAt(i--); - } - rv->setLightSources(lightSources); - - if (isDraw) { - // Filter out frustum culled entity for drawable entities - if (rv->frustumCulling()) - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_frustumCullingJob->visibleEntities()); - // Filter out entities which didn't satisfy proximity filtering - if (!rv->proximityFilterIds().empty()) - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities()); - } - - // Early return in case we have nothing to filter - if (renderableEntities.size() == 0) - return; - - // Filter out Render commands for which the Entity wasn't selected because - // of frustum, proximity or layer filtering - EntityRenderCommandDataPtr filteredCommandData = EntityRenderCommandDataPtr::create(); - filteredCommandData->reserve(renderableEntities.size()); - // Because dataCacheForLeaf.renderableEntities or computeEntities are sorted - // What we get out of EntityRenderCommandData is also sorted by Entity - auto eIt = renderableEntities.cbegin(); - const auto eEnd = renderableEntities.cend(); - int cIt = 0; - const int cEnd = commandData.size(); - - while (eIt != eEnd) { - const Entity *targetEntity = *eIt; - // Advance until we have commands whose Entity has a lower address - // than the selected filtered entity - while (cIt != cEnd && commandData.entities.at(cIt) < targetEntity) - ++cIt; - - // Push pointers to command data for all commands that match the - // entity - while (cIt != cEnd && commandData.entities.at(cIt) == targetEntity) { - filteredCommandData->push_back(commandData.entities.at(cIt), - commandData.commands.at(cIt), - commandData.passesData.at(cIt)); - ++cIt; - } - ++eIt; - } - - // 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); - - for (int i = 0; i < m; ++i) { - const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = m_renderViewCommandUpdaterJobs.at(i); - const int count = (i == m - 1) ? filteredCommandData->size() - (i * idealPacketSize) : idealPacketSize; - renderViewCommandBuilder->setRenderables(filteredCommandData, i * idealPacketSize, count); - } - } - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - FrustumCullingJobPtr m_frustumCullingJob; - FilterProximityDistanceJobPtr m_filterProximityJob; - QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; - bool m_fullRebuild; -}; - -class SetClearDrawBufferIndex -{ -public: - explicit SetClearDrawBufferIndex(const RenderViewInitializerJobPtr &renderViewJob) - : m_renderViewJob(renderViewJob) - {} - - void operator()() - { - RenderView *rv = m_renderViewJob->renderView(); - QVector<ClearBufferInfo> &clearBuffersInfo = rv->specificClearColorBufferInfo(); - const AttachmentPack &attachmentPack = rv->attachmentPack(); - for (ClearBufferInfo &clearBufferInfo : clearBuffersInfo) - clearBufferInfo.drawBufferIndex = attachmentPack.getDrawBufferIndex(clearBufferInfo.attchmentPoint); - - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; -}; - -class SyncFilterEntityByLayer -{ -public: - explicit SyncFilterEntityByLayer(const FilterLayerEntityJobPtr &filterEntityByLayerJob, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_filterEntityByLayerJob(filterEntityByLayerJob) - , m_renderer(renderer) - , m_leafNode(leafNode) - { - } - - void operator()() - { - QMutexLocker lock(m_renderer->cache()->mutex()); - // Save the filtered by layer subset into the cache - const QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities(); - RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; - dataCacheForLeaf.filterEntitiesByLayer = filteredEntities; - } - -private: - FilterLayerEntityJobPtr m_filterEntityByLayerJob; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; -}; - -class SyncMaterialParameterGatherer -{ -public: - explicit SyncMaterialParameterGatherer(const QVector<MaterialParameterGathererJobPtr> &materialParameterGathererJobs, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_materialParameterGathererJobs(materialParameterGathererJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - { - } - - void operator()() - { - QMutexLocker lock(m_renderer->cache()->mutex()); - RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; - dataCacheForLeaf.materialParameterGatherer.clear(); - - for (const auto &materialGatherer : qAsConst(m_materialParameterGathererJobs)) - dataCacheForLeaf.materialParameterGatherer.unite(materialGatherer->materialToPassAndParameter()); - } - -private: - QVector<MaterialParameterGathererJobPtr> m_materialParameterGathererJobs; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; -}; - -} // anonymous - -RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer) - : m_leafNode(leafNode) - , m_renderViewIndex(renderViewIndex) - , m_renderer(renderer) - , m_layerCacheNeedsToBeRebuilt(false) - , m_materialGathererCacheNeedsToBeRebuilt(false) - , m_renderCommandCacheNeedsToBeRebuilt(false) - , m_renderViewJob(RenderViewInitializerJobPtr::create()) - , m_filterEntityByLayerJob() - , m_frustumCullingJob(new Render::FrustumCullingJob()) - , m_syncPreFrustumCullingJob(SynchronizerJobPtr::create(SyncPreFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling)) - , m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex)) - , m_syncFilterEntityByLayerJob() - , m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create()) -{ -} - -RenderViewInitializerJobPtr RenderViewBuilder::renderViewJob() const -{ - return m_renderViewJob; -} - -FilterLayerEntityJobPtr RenderViewBuilder::filterEntityByLayerJob() const -{ - return m_filterEntityByLayerJob; -} - -FrustumCullingJobPtr RenderViewBuilder::frustumCullingJob() const -{ - return m_frustumCullingJob; -} - -QVector<RenderViewCommandUpdaterJobPtr> RenderViewBuilder::renderViewCommandUpdaterJobs() const -{ - return m_renderViewCommandUpdaterJobs; -} - -QVector<RenderViewCommandBuilderJobPtr> RenderViewBuilder::renderViewCommandBuilderJobs() const -{ - return m_renderViewCommandBuilderJobs; -} - -QVector<MaterialParameterGathererJobPtr> RenderViewBuilder::materialGathererJobs() const -{ - return m_materialGathererJobs; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPostInitializationJob() const -{ - return m_syncRenderViewPostInitializationJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncPreFrustumCullingJob() const -{ - return m_syncPreFrustumCullingJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPreCommandBuildingJob() const -{ - return m_syncRenderViewPreCommandBuildingJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPreCommandUpdateJob() const -{ - return m_syncRenderViewPreCommandUpdateJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPostCommandUpdateJob() const -{ - return m_syncRenderViewPostCommandUpdateJob; -} - -SynchronizerJobPtr RenderViewBuilder::setClearDrawBufferIndexJob() const -{ - return m_setClearDrawBufferIndexJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncFilterEntityByLayerJob() const -{ - return m_syncFilterEntityByLayerJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncMaterialGathererJob() const -{ - return m_syncMaterialGathererJob; -} - -FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const -{ - return m_filterProximityJob; -} - -void RenderViewBuilder::prepareJobs() -{ - // Init what we can here - m_filterProximityJob->setManager(m_renderer->nodeManagers()); - m_frustumCullingJob->setRoot(m_renderer->sceneRoot()); - - if (m_renderCommandCacheNeedsToBeRebuilt) { - - m_renderViewCommandBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); - for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { - auto renderViewCommandBuilder = Render::RenderViewCommandBuilderJobPtr::create(); - m_renderViewCommandBuilderJobs.push_back(renderViewCommandBuilder); - } - m_syncRenderViewPreCommandBuildingJob = SynchronizerJobPtr::create(SyncPreCommandBuilding(m_renderViewJob, - m_renderViewCommandBuilderJobs, - m_renderer, - m_leafNode), - JobTypes::SyncRenderViewPreCommandBuilding); - } - - m_renderViewJob->setRenderer(m_renderer); - m_renderViewJob->setFrameGraphLeafNode(m_leafNode); - m_renderViewJob->setSubmitOrderIndex(m_renderViewIndex); - - // 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) { - auto renderViewCommandUpdater = Render::RenderViewCommandUpdaterJobPtr::create(); - renderViewCommandUpdater->setRenderer(m_renderer); - m_renderViewCommandUpdaterJobs.push_back(renderViewCommandUpdater); - } - - 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 = Render::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); - } - m_syncMaterialGathererJob = SynchronizerJobPtr::create(SyncMaterialParameterGatherer(m_materialGathererJobs, - m_renderer, - m_leafNode), - JobTypes::SyncMaterialGatherer); - } - - if (m_layerCacheNeedsToBeRebuilt) { - m_filterEntityByLayerJob = Render::FilterLayerEntityJobPtr::create(); - m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers()); - m_syncFilterEntityByLayerJob = SynchronizerJobPtr::create(SyncFilterEntityByLayer(m_filterEntityByLayerJob, - m_renderer, - m_leafNode), - JobTypes::SyncFilterEntityByLayer); - } - - m_syncRenderViewPreCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPreCommandUpdate(m_renderViewJob, - m_frustumCullingJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewCommandUpdaterJobs, - m_renderViewCommandBuilderJobs, - m_renderer, - m_leafNode, - m_renderCommandCacheNeedsToBeRebuilt), - JobTypes::SyncRenderViewPreCommandUpdate); - - m_syncRenderViewPostCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPostCommandUpdate(m_renderViewJob, - m_renderViewCommandUpdaterJobs, - m_renderer), - JobTypes::SyncRenderViewPostCommandUpdate); - - m_syncRenderViewPostInitializationJob = SynchronizerJobPtr::create(SyncRenderViewPostInitialization(m_renderViewJob, - m_frustumCullingJob, - m_filterEntityByLayerJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewCommandUpdaterJobs, - m_renderViewCommandBuilderJobs), - JobTypes::SyncRenderViewInitialization); -} - -QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const -{ - QVector<Qt3DCore::QAspectJobPtr> jobs; - - jobs.reserve(m_materialGathererJobs.size() + m_renderViewCommandUpdaterJobs.size() + 11); - - // Set dependencies - - // Finish the skinning palette job before processing renderviews - // TODO: Maybe only update skinning palettes for non-culled entities - m_renderViewJob->addDependency(m_renderer->updateSkinningPaletteJob()); - - m_syncPreFrustumCullingJob->addDependency(m_renderer->updateWorldTransformJob()); - m_syncPreFrustumCullingJob->addDependency(m_renderer->updateShaderDataTransformJob()); - m_syncPreFrustumCullingJob->addDependency(m_syncRenderViewPostInitializationJob); - - m_frustumCullingJob->addDependency(m_renderer->expandBoundingVolumeJob()); - m_frustumCullingJob->addDependency(m_syncPreFrustumCullingJob); - - m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewPostInitializationJob); - - m_syncRenderViewPostInitializationJob->addDependency(m_renderViewJob); - - m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob()); - m_filterProximityJob->addDependency(m_syncRenderViewPostInitializationJob); - - m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncRenderViewPostInitializationJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_filterProximityJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_frustumCullingJob); - - // Ensure the RenderThread won't be able to process dirtyResources - // before they have been completely gathered - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->introspectShadersJob()); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->bufferGathererJob()); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->textureGathererJob()); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->cacheLightJob()); - - for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs)) { - renderViewCommandUpdater->addDependency(m_syncRenderViewPreCommandUpdateJob); - m_syncRenderViewPostCommandUpdateJob->addDependency(renderViewCommandUpdater); - } - - m_renderer->frameCleanupJob()->addDependency(m_syncRenderViewPostCommandUpdateJob); - m_renderer->frameCleanupJob()->addDependency(m_setClearDrawBufferIndexJob); - - // Add jobs - jobs.push_back(m_renderViewJob); // Step 1 - - jobs.push_back(m_syncRenderViewPostInitializationJob); // Step 2 - - if (m_renderCommandCacheNeedsToBeRebuilt) { // Step 3 - m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheComputableEntitiesJob()); - m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheRenderableEntitiesJob()); - m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncRenderViewPostInitializationJob); - - if (m_materialGathererCacheNeedsToBeRebuilt) - m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncMaterialGathererJob); - - jobs.push_back(m_syncRenderViewPreCommandBuildingJob); - - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) { - renderViewCommandBuilder->addDependency(m_syncRenderViewPreCommandBuildingJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(renderViewCommandBuilder); - jobs.push_back(renderViewCommandBuilder); - } - } - - if (m_layerCacheNeedsToBeRebuilt) { - m_filterEntityByLayerJob->addDependency(m_renderer->updateEntityLayersJob()); - m_filterEntityByLayerJob->addDependency(m_syncRenderViewPostInitializationJob); - m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob()); - - m_syncFilterEntityByLayerJob->addDependency(m_filterEntityByLayerJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncFilterEntityByLayerJob); - - jobs.push_back(m_filterEntityByLayerJob); // Step 3 - jobs.push_back(m_syncFilterEntityByLayerJob); // Step 4 - } - jobs.push_back(m_syncPreFrustumCullingJob); // Step 3 - jobs.push_back(m_filterProximityJob); // Step 3 - jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3 - - if (m_materialGathererCacheNeedsToBeRebuilt) { - for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { - materialGatherer->addDependency(m_syncRenderViewPostInitializationJob); - materialGatherer->addDependency(m_renderer->introspectShadersJob()); - materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob()); - jobs.push_back(materialGatherer); // Step3 - m_syncMaterialGathererJob->addDependency(materialGatherer); - } - m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncMaterialGathererJob); - - jobs.push_back(m_syncMaterialGathererJob); // Step 3 - } - - jobs.push_back(m_frustumCullingJob); // Step 4 - jobs.push_back(m_syncRenderViewPreCommandUpdateJob); // Step 5 - - // Build RenderCommands or Update RenderCommand Uniforms - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandUpdaterJobs)) // Step 6 - jobs.push_back(renderViewCommandBuilder); - - jobs.push_back(m_syncRenderViewPostCommandUpdateJob); // Step 7 - - return jobs; -} - -Renderer *RenderViewBuilder::renderer() const -{ - return m_renderer; -} - -int RenderViewBuilder::renderViewIndex() const -{ - return m_renderViewIndex; -} - -void RenderViewBuilder::setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt) -{ - m_layerCacheNeedsToBeRebuilt = needsToBeRebuilt; -} - -bool RenderViewBuilder::layerCacheNeedsToBeRebuilt() const -{ - return m_layerCacheNeedsToBeRebuilt; -} - -void RenderViewBuilder::setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt) -{ - m_materialGathererCacheNeedsToBeRebuilt = needsToBeRebuilt; -} - -bool RenderViewBuilder::materialGathererCacheNeedsToBeRebuilt() const -{ - return m_materialGathererCacheNeedsToBeRebuilt; -} - -void RenderViewBuilder::setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt) -{ - m_renderCommandCacheNeedsToBeRebuilt = needsToBeRebuilt; -} - -bool RenderViewBuilder::renderCommandCacheNeedsToBeRebuilt() const -{ - return m_renderCommandCacheNeedsToBeRebuilt; -} - -int RenderViewBuilder::optimalJobCount() -{ - return RenderViewBuilder::m_optimalParallelJobCount; -} - -QVector<Entity *> RenderViewBuilder::entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset) -{ - QVector<Entity *> intersection; - intersection.reserve(qMin(entities.size(), subset.size())); - std::set_intersection(entities.begin(), entities.end(), - subset.begin(), subset.end(), - std::back_inserter(intersection)); - - return intersection; -} - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE |