summaryrefslogtreecommitdiffstats
path: root/src/render/frontend/qrenderaspect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/frontend/qrenderaspect.cpp')
-rw-r--r--src/render/frontend/qrenderaspect.cpp520
1 files changed, 260 insertions, 260 deletions
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 2561a6c60..00dd9c327 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -1,34 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt-project.org/legal
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL3$
+** $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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** 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.LGPLv3 included in the
+** 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.html.
+** 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 later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
+** 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$
**
@@ -43,41 +46,40 @@
#include <Qt3DRender/private/scenemanager_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
-#include <Qt3DRender/qabstractsceneloader.h>
+#include <Qt3DRender/qsceneloader.h>
#include <Qt3DRender/qcameraselector.h>
-#include <Qt3DRender/qframegraph.h>
#include <Qt3DRender/qlayer.h>
#include <Qt3DRender/qlayerfilter.h>
#include <Qt3DRender/qmaterial.h>
#include <Qt3DRender/qmesh.h>
#include <Qt3DRender/qparameter.h>
-#include <Qt3DRender/qparametermapping.h>
#include <Qt3DRender/qrenderpassfilter.h>
#include <Qt3DRender/qrendertargetselector.h>
#include <Qt3DRender/qtechniquefilter.h>
#include <Qt3DRender/qviewport.h>
#include <Qt3DRender/qrendertarget.h>
-#include <Qt3DRender/qclearbuffer.h>
+#include <Qt3DRender/qclearbuffers.h>
#include <Qt3DRender/qtexture.h>
#include <Qt3DRender/qeffect.h>
#include <Qt3DRender/qshaderdata.h>
-#include <Qt3DRender/qstateset.h>
+#include <Qt3DRender/qrenderstateset.h>
#include <Qt3DRender/qnodraw.h>
-#include <Qt3DCore/qcameralens.h>
+#include <Qt3DRender/qcameralens.h>
#include <Qt3DRender/qattribute.h>
#include <Qt3DRender/qbuffer.h>
#include <Qt3DRender/qgeometry.h>
#include <Qt3DRender/qgeometryrenderer.h>
#include <Qt3DRender/qobjectpicker.h>
-#include <Qt3DRender/qboundingvolumedebug.h>
#include <Qt3DRender/qfrustumculling.h>
-#include <Qt3DRender/qlight.h>
-#include <Qt3DRender/qlighting.h>
+#include <Qt3DRender/qabstractlight.h>
#include <Qt3DRender/qdispatchcompute.h>
+#include <Qt3DRender/qcomputecommand.h>
+#include <Qt3DRender/qrendersurfaceselector.h>
+#include <Qt3DRender/qrendersettings.h>
#include <Qt3DRender/private/cameraselectornode_p.h>
#include <Qt3DRender/private/layerfilternode_p.h>
-#include <Qt3DRender/private/annotation_p.h>
+#include <Qt3DRender/private/filterkey_p.h>
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/shaderdata_p.h>
@@ -87,10 +89,8 @@
#include <Qt3DRender/private/viewportnode_p.h>
#include <Qt3DRender/private/rendertarget_p.h>
#include <Qt3DRender/private/scenemanager_p.h>
-#include <Qt3DRender/private/clearbuffer_p.h>
-#include <Qt3DRender/private/sortmethod_p.h>
-#include <Qt3DRender/private/sortcriterion_p.h>
-#include <Qt3DRender/private/framegraphsubtreeselector_p.h>
+#include <Qt3DRender/private/clearbuffers_p.h>
+#include <Qt3DRender/private/sortpolicy_p.h>
#include <Qt3DRender/private/renderlogging_p.h>
#include <Qt3DRender/private/nodefunctor_p.h>
#include <Qt3DRender/private/framegraphnode_p.h>
@@ -110,13 +110,15 @@
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/buffermanager_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
-#include <Qt3DRender/private/loadbufferjob_p.h>
#include <Qt3DRender/private/loadgeometryjob_p.h>
-#include <Qt3DRender/private/qsceneparserfactory_p.h>
+#include <Qt3DRender/private/qsceneiofactory_p.h>
#include <Qt3DRender/private/frustumculling_p.h>
#include <Qt3DRender/private/light_p.h>
-#include <Qt3DRender/private/lighting_p.h>
#include <Qt3DRender/private/dispatchcompute_p.h>
+#include <Qt3DRender/private/computecommand_p.h>
+#include <Qt3DRender/private/rendersurfaceselector_p.h>
+#include <Qt3DRender/private/rendersettings_p.h>
+#include <Qt3DRender/private/backendnode_p.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
@@ -129,174 +131,207 @@
#include <QThread>
#include <QWindow>
-static void initResources()
-{
- Q_INIT_RESOURCE(render);
-}
-
QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
namespace Qt3DRender {
+/*!
+ * \class Qt3DRender::QRenderAspect
+ * \brief The QRenderAspect class
+ * \since 5.7
+ * \inmodule Qt3DRender
+ */
+
+/*! \internal */
QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
: QAbstractAspectPrivate()
, m_nodeManagers(new Render::NodeManagers())
- , m_renderer(Q_NULLPTR)
- , m_surfaceEventFilter(new Render::PlatformSurfaceFilter())
- , m_surface(Q_NULLPTR)
+ , m_renderer(nullptr)
, m_initialized(false)
- , m_framePreparationJob(new Render::FramePreparationJob(m_nodeManagers))
- , m_cleanupJob(new Render::FrameCleanupJob(m_nodeManagers))
- , m_worldTransformJob(new Render::UpdateWorldTransformJob())
- , m_updateBoundingVolumeJob(new Render::UpdateBoundingVolumeJob())
- , m_calculateBoundingVolumeJob(new Render::CalculateBoundingVolumeJob(m_nodeManagers))
+ , m_renderType(type)
{
- initResources();
-
// Load the scene parsers
loadSceneParsers();
-
- // Create jobs to update transforms and bounding volumes
- // We can only update bounding volumes once all world transforms are known
- m_updateBoundingVolumeJob->addDependency(m_worldTransformJob);
- m_framePreparationJob->addDependency(m_worldTransformJob);
-
- // All world stuff depends on the RenderEntity's localBoundingVolume
- m_worldTransformJob->addDependency(m_calculateBoundingVolumeJob);
-
- // Create property renderer implementation given
- // a targeted rendering API -> only OpenGL for now
- m_renderer = new Render::Renderer(type);
- m_renderer->setNodeManagers(m_nodeManagers);
- m_surfaceEventFilter->setRenderer(m_renderer);
}
-void QRenderAspectPrivate::setSurface(QSurface *surface)
+/*! \internal */
+QRenderAspectPrivate::~QRenderAspectPrivate()
{
- if (m_surface == surface)
- return;
-
- m_surface = surface;
-
- // If we have a new surface, install the platform surface event filter onto it
- // so that we get informed when the underlying platform surface is about to be
- // deleted and we can tell the renderer about it before it's too late.
- if (m_surface) {
- bool hasPlatformSurface = false;
- switch (m_surface->surfaceClass()) {
- case QSurface::Window: {
- QWindow *window = static_cast<QWindow *>(m_surface);
- m_surfaceEventFilter->setWindow(window);
- hasPlatformSurface = (window->handle() != Q_NULLPTR);
- break;
- }
-
- case QSurface::Offscreen: {
- QOffscreenSurface *offscreen = static_cast<QOffscreenSurface *>(m_surface);
- m_surfaceEventFilter->setOffscreenSurface(offscreen);
- hasPlatformSurface = (offscreen->handle() != Q_NULLPTR);
- break;
- }
- }
-
- // If the window/offscreen surface has a native surface, tell the renderer
- if (hasPlatformSurface)
- m_renderer->setSurface(surface);
- }
+ // The renderer should have been shutdown as part of onUnregistered().
+ // If it still exists then this aspect is being deleted before the aspect
+ // engine is finished with it.
+ if (m_renderer != nullptr)
+ qWarning() << Q_FUNC_INFO << "The renderer should have been deleted when reaching this point (this warning may be normal when running tests)";
+ delete m_nodeManagers;
}
-QRenderAspect::QRenderAspect(QObject *parent)
- : QAbstractAspect(*new QRenderAspectPrivate(Threaded), parent)
+/*! \internal */
+void QRenderAspectPrivate::registerBackendTypes()
{
- // Won't return until the private RenderThread in Renderer has been created
- // The Renderer is set to wait the surface with a wait condition
- // Threads modifying the Renderer should be synchronized using the Renderer's mutex
- registerBackendTypes();
+ Q_Q(QRenderAspect);
+
+ qRegisterMetaType<Qt3DRender::QBuffer*>();
+ qRegisterMetaType<Qt3DRender::QEffect*>();
+ qRegisterMetaType<Qt3DRender::QFrameGraphNode *>();
+
+ q->registerBackendType<Qt3DCore::QEntity>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<Qt3DCore::QTransform>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer, m_nodeManagers->transformManager()));
+
+ q->registerBackendType<Qt3DRender::QCameraLens>(QSharedPointer<Render::NodeFunctor<Render::CameraLens, Render::CameraManager> >::create(m_renderer, m_nodeManagers->cameraManager()));
+ q->registerBackendType<QLayer>(QSharedPointer<Render::NodeFunctor<Render::Layer, Render::LayerManager> >::create(m_renderer, m_nodeManagers->layerManager()));
+ q->registerBackendType<QSceneLoader>(QSharedPointer<Render::RenderSceneFunctor>::create(m_renderer, m_nodeManagers->sceneManager()));
+ q->registerBackendType<QRenderTarget>(QSharedPointer<Render::NodeFunctor<Render::RenderTarget, Render::RenderTargetManager> >::create(m_renderer, m_nodeManagers->renderTargetManager()));
+ q->registerBackendType<QRenderTargetOutput>(QSharedPointer<Render::NodeFunctor<Render::RenderTargetOutput, Render::AttachmentManager> >::create(m_renderer, m_nodeManagers->attachmentManager()));
+ q->registerBackendType<QRenderSettings>(QSharedPointer<Render::RenderSettingsFunctor>::create(m_renderer));
+ q->registerBackendType<QRenderState>(QSharedPointer<Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager> >::create(m_renderer, m_nodeManagers->renderStateManager()));
+
+ // Geometry + Compute
+ q->registerBackendType<QAttribute>(QSharedPointer<Render::NodeFunctor<Render::Attribute, Render::AttributeManager> >::create(m_renderer, m_nodeManagers->attributeManager()));
+ q->registerBackendType<QBuffer>(QSharedPointer<Render::BufferFunctor>::create(m_renderer, m_nodeManagers->bufferManager()));
+ q->registerBackendType<QComputeCommand>(QSharedPointer<Render::NodeFunctor<Render::ComputeCommand, Render::ComputeCommandManager> >::create(m_renderer, m_nodeManagers->computeJobManager()));
+ q->registerBackendType<QGeometry>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer, m_nodeManagers->geometryManager()));
+ q->registerBackendType<QGeometryRenderer>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager()));
+
+ // Textures
+ q->registerBackendType<QAbstractTexture>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager(), m_nodeManagers->textureImageManager(), m_nodeManagers->textureDataManager()));
+ q->registerBackendType<QAbstractTextureImage>(QSharedPointer<Render::TextureImageFunctor>::create(m_renderer, m_nodeManagers->textureManager(), m_nodeManagers->textureImageManager(), m_nodeManagers->textureDataManager()));
+
+ // Material system
+ q->registerBackendType<QEffect>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer, m_nodeManagers->effectManager()));
+ q->registerBackendType<QFilterKey>(QSharedPointer<Render::NodeFunctor<Render::FilterKey, Render::FilterKeyManager> >::create(m_renderer, m_nodeManagers->filterKeyManager()));
+ q->registerBackendType<QAbstractLight>(QSharedPointer<Render::RenderLightFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<QMaterial>(QSharedPointer<Render::NodeFunctor<Render::Material, Render::MaterialManager> >::create(m_renderer, m_nodeManagers->materialManager()));
+ q->registerBackendType<QParameter>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer, m_nodeManagers->parameterManager()));
+ q->registerBackendType<QRenderPass>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer, m_nodeManagers->renderPassManager()));
+ q->registerBackendType<QShaderData>(QSharedPointer<Render::RenderShaderDataFunctor>::create(m_renderer, m_nodeManagers));
+ q->registerBackendType<QShaderProgram>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer, m_nodeManagers->shaderManager()));
+ q->registerBackendType<QTechnique>(QSharedPointer<Render::NodeFunctor<Render::Technique, Render::TechniqueManager> >::create(m_renderer, m_nodeManagers->techniqueManager()));
+
+ // Framegraph
+ q->registerBackendType<QFrameGraphNode>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrameGraphNode, QFrameGraphNode> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QCameraSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QClearBuffers>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ClearBuffers, QClearBuffers> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QDispatchCompute>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::DispatchCompute, QDispatchCompute> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QFrustumCulling>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrustumCulling, QFrustumCulling> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QLayerFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::LayerFilterNode, QLayerFilter> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QNoDraw>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::NoDraw, QNoDraw> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QRenderPassFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderPassFilter, QRenderPassFilter> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QRenderStateSet>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::StateSetNode, QRenderStateSet> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QRenderSurfaceSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderSurfaceSelector, QRenderSurfaceSelector> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QRenderTargetSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderTargetSelector, QRenderTargetSelector> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QSortPolicy>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SortPolicy, QSortPolicy> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QTechniqueFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::TechniqueFilter, QTechniqueFilter> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+ q->registerBackendType<QViewport>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
+
+ // Picking
+ q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer, m_nodeManagers->objectPickerManager()));
}
-QRenderAspect::QRenderAspect(QRenderAspect::RenderType type, QObject *parent)
- : QAbstractAspect(*new QRenderAspectPrivate(type), parent)
+/*! \internal */
+void QRenderAspectPrivate::unregisterBackendTypes()
{
- registerBackendTypes();
+ unregisterBackendType<Qt3DCore::QEntity>();
+ unregisterBackendType<Qt3DCore::QTransform>();
+
+ unregisterBackendType<Qt3DRender::QCameraLens>();
+ unregisterBackendType<QLayer>();
+ unregisterBackendType<QSceneLoader>();
+ unregisterBackendType<QRenderTarget>();
+ unregisterBackendType<QRenderTargetOutput>();
+ unregisterBackendType<QRenderSettings>();
+ unregisterBackendType<QRenderState>();
+
+ // Geometry + Compute
+ unregisterBackendType<QAttribute>();
+ unregisterBackendType<QBuffer>();
+ unregisterBackendType<QComputeCommand>();
+ unregisterBackendType<QGeometry>();
+ unregisterBackendType<QGeometryRenderer>();
+
+ // Textures
+ unregisterBackendType<QAbstractTexture>();
+ unregisterBackendType<QAbstractTextureImage>();
+
+ // Material system
+ unregisterBackendType<QEffect>();
+ unregisterBackendType<QFilterKey>();
+ unregisterBackendType<QAbstractLight>();
+ unregisterBackendType<QMaterial>();
+ unregisterBackendType<QParameter>();
+ unregisterBackendType<QRenderPass>();
+ unregisterBackendType<QShaderData>();
+ unregisterBackendType<QShaderProgram>();
+ unregisterBackendType<QTechnique>();
+
+ // Framegraph
+ unregisterBackendType<QCameraSelector>();
+ unregisterBackendType<QClearBuffers>();
+ unregisterBackendType<QDispatchCompute>();
+ unregisterBackendType<QFrustumCulling>();
+ unregisterBackendType<QLayerFilter>();
+ unregisterBackendType<QNoDraw>();
+ unregisterBackendType<QRenderPassFilter>();
+ unregisterBackendType<QRenderStateSet>();
+ unregisterBackendType<QRenderSurfaceSelector>();
+ unregisterBackendType<QRenderTargetSelector>();
+ unregisterBackendType<QSortPolicy>();
+ unregisterBackendType<QTechniqueFilter>();
+ unregisterBackendType<QViewport>();
+
+ // Picking
+ unregisterBackendType<QObjectPicker>();
}
+/*!
+ * The constructor creates a new QRenderAspect::QRenderAspect instance with the
+ * specified \a parent.
+ * \param parent
+ */
+QRenderAspect::QRenderAspect(QObject *parent)
+ : QRenderAspect(Threaded, parent) {}
+
+/*!
+ * The constructor creates a new QRenderAspect::QRenderAspect instance with the
+ * specified \a type and \a parent.
+ * \param type
+ * \param parent
+ */
+QRenderAspect::QRenderAspect(QRenderAspect::RenderType type, QObject *parent)
+ : QRenderAspect(*new QRenderAspectPrivate(type), parent) {}
+
/*! \internal */
QRenderAspect::QRenderAspect(QRenderAspectPrivate &dd, QObject *parent)
-
: QAbstractAspect(dd, parent)
{
- registerBackendTypes();
+ setObjectName(QStringLiteral("Render Aspect"));
}
-void QRenderAspect::registerBackendTypes()
+/*! \internal */
+QRenderAspect::~QRenderAspect()
{
- Q_D(QRenderAspect);
-
- registerBackendType<Qt3DCore::QEntity>(QBackendNodeFunctorPtr(new Render::RenderEntityFunctor(d->m_nodeManagers)));
- registerBackendType<Qt3DCore::QTransform>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Transform, Render::TransformManager>(d->m_nodeManagers->transformManager())));
- registerBackendType<QMaterial>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Material, Render::MaterialManager>(d->m_nodeManagers->materialManager())));
- registerBackendType<QTechnique>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Technique, Render::TechniqueManager>(d->m_nodeManagers->techniqueManager())));
- registerBackendType<QAbstractTextureProvider>(QBackendNodeFunctorPtr(new Render::TextureFunctor(d->m_nodeManagers->textureManager(), d->m_nodeManagers->textureImageManager(), d->m_nodeManagers->textureDataManager())));
- registerBackendType<QShaderProgram>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Shader, Render::ShaderManager>(d->m_nodeManagers->shaderManager())));
- registerBackendType<QEffect>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Effect, Render::EffectManager>(d->m_nodeManagers->effectManager())));
- registerBackendType<QAnnotation>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Annotation, Render::CriterionManager>(d->m_nodeManagers->criterionManager())));
- registerBackendType<Qt3DCore::QCameraLens>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::CameraLens, Render::CameraManager>(d->m_nodeManagers->cameraManager())));
- registerBackendType<QLayer>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Layer, Render::LayerManager>(d->m_nodeManagers->layerManager())));
- registerBackendType<QRenderPass>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager>(d->m_nodeManagers->renderPassManager())));
- registerBackendType<QAbstractSceneLoader>(QBackendNodeFunctorPtr(new Render::RenderSceneFunctor(d->m_nodeManagers->sceneManager())));
- registerBackendType<QRenderTarget>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderTarget, Render::RenderTargetManager>(d->m_nodeManagers->renderTargetManager())));
- registerBackendType<QRenderAttachment>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderAttachment, Render::AttachmentManager>(d->m_nodeManagers->attachmentManager())));
- registerBackendType<QSortCriterion>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::SortCriterion, Render::SortCriterionManager>(d->m_nodeManagers->sortCriterionManager())));
- registerBackendType<QClearBuffer>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::ClearBuffer, QClearBuffer>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QTechniqueFilter>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::TechniqueFilter, QTechniqueFilter>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QViewport>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QRenderPassFilter>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::RenderPassFilter, QRenderPassFilter>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QCameraSelector>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QRenderTargetSelector>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::RenderTargetSelector, QRenderTargetSelector>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QLayerFilter>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::LayerFilterNode, QLayerFilter>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QSortMethod>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::SortMethod, QSortMethod>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QFrameGraphSelector>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::FrameGraphSubtreeSelector, QFrameGraphSelector>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QFrameGraph>(QBackendNodeFunctorPtr(new Render::FrameGraphComponentFunctor(d->m_renderer)));
- registerBackendType<QParameter>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Parameter, Render::ParameterManager>(d->m_nodeManagers->parameterManager())));
- registerBackendType<QShaderData>(QBackendNodeFunctorPtr(new Render::RenderShaderDataFunctor(d->m_nodeManagers)));
- registerBackendType<QAbstractTextureImage>(QBackendNodeFunctorPtr(new Render::TextureImageFunctor(d->m_nodeManagers->textureManager(), d->m_nodeManagers->textureImageManager(), d->m_nodeManagers->textureDataManager())));
- registerBackendType<QStateSet>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::StateSetNode, QStateSet>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QNoDraw>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::NoDraw, QNoDraw>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QBuffer>(QBackendNodeFunctorPtr(new Render::BufferFunctor(d->m_nodeManagers->bufferManager())));
- registerBackendType<QAttribute>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Attribute, Render::AttributeManager>(d->m_nodeManagers->attributeManager())));
- registerBackendType<QGeometry>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Geometry, Render::GeometryManager>(d->m_nodeManagers->geometryManager())));
- registerBackendType<QGeometryRenderer>(QBackendNodeFunctorPtr(new Render::GeometryRendererFunctor(d->m_nodeManagers->geometryRendererManager())));
- registerBackendType<QObjectPicker>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager>(d->m_nodeManagers->objectPickerManager())));
- registerBackendType<QBoundingVolumeDebug>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::BoundingVolumeDebug, Render::BoundingVolumeDebugManager>(d->m_nodeManagers->boundingVolumeDebugManager())));
- registerBackendType<QFrustumCulling>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::FrustumCulling, QFrustumCulling>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QLight>(QBackendNodeFunctorPtr(new Render::RenderLightFunctor(d->m_nodeManagers)));
- registerBackendType<QLighting>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::Lighting, QLighting>(d->m_nodeManagers->frameGraphManager())));
- registerBackendType<QDispatchCompute>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::DispatchCompute, QDispatchCompute>(d->m_nodeManagers->frameGraphManager())));
}
-void QRenderAspect::renderInitialize(QOpenGLContext *context)
+void QRenderAspectPrivate::renderInitialize(QOpenGLContext *context)
{
- Q_D(QRenderAspect);
- if (d->m_renderer->api() == Render::AbstractRenderer::OpenGL)
- static_cast<Render::Renderer *>(d->m_renderer)->setOpenGLContext(context);
- d->m_renderer->initialize();
+ if (m_renderer->api() == Render::AbstractRenderer::OpenGL)
+ static_cast<Render::Renderer *>(m_renderer)->setOpenGLContext(context);
+ m_renderer->initialize();
}
-void QRenderAspect::renderSynchronous()
+/*! \internal */
+void QRenderAspectPrivate::renderSynchronous()
{
- Q_D(QRenderAspect);
- d->m_renderer->doRender();
+ m_renderer->doRender();
}
/*!
* Only called when rendering with QtQuick 2 and a Scene3D item
*/
-void QRenderAspect::renderShutdown()
+void QRenderAspectPrivate::renderShutdown()
{
- Q_D(QRenderAspect);
- d->m_renderer->shutdown();
+ m_renderer->shutdown();
}
QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
@@ -304,6 +339,10 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
Q_D(QRenderAspect);
d->m_renderer->setTime(time);
+#if defined(QT3D_RENDER_DUMP_BACKEND_NODES)
+ d->m_renderer->dumpInfo();
+#endif
+
// Create jobs that will get exectued by the threadpool
QVector<QAspectJobPtr> jobs;
@@ -315,98 +354,81 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
// 6 PickBoundingVolumeJob
// 7 Cleanup Job (depends on RV)
- // Create jobs to load in any meshes that are pending
- if (d->m_renderer->isRunning()) {
+ // Ensure we have a settings object. It may get deleted by the call to
+ // QChangeArbiter::syncChanges() that happens just before the render aspect is
+ // asked for jobs to execute (this function). If that is the case, the RenderSettings will
+ // be null and we should not generate any jobs.
+ if (d->m_renderer->isRunning() && d->m_renderer->settings()) {
+ // don't spawn any jobs, if the renderer decides to skip this frame
+ if (!d->m_renderer->shouldRender()) {
+ d->m_renderer->skipNextFrame();
+ return jobs;
+ }
Render::NodeManagers *manager = d->m_renderer->nodeManagers();
- QAspectJobPtr pickBoundingVolumeJob = d->m_renderer->pickBoundingVolumeJob();
-
- // Create the jobs to build the frame
- d->m_framePreparationJob->setRoot(d->m_renderer->sceneRoot());
- d->m_worldTransformJob->setRoot(d->m_renderer->sceneRoot());
- d->m_updateBoundingVolumeJob->setRoot(d->m_renderer->sceneRoot());
- d->m_calculateBoundingVolumeJob->setRoot(d->m_renderer->sceneRoot());
- d->m_cleanupJob->setRoot(d->m_renderer->sceneRoot());
-
- const QVector<QNodeId> texturesPending = manager->textureDataManager()->texturesPending();
- Q_FOREACH (const QNodeId &textureId, texturesPending) {
- Render::LoadTextureDataJobPtr loadTextureJob(new Render::LoadTextureDataJob(textureId));
+
+ const QVector<QNodeId> texturesPending = std::move(manager->textureDataManager()->texturesPending());
+ for (const QNodeId textureId : texturesPending) {
+ auto loadTextureJob = Render::LoadTextureDataJobPtr::create(textureId);
loadTextureJob->setNodeManagers(manager);
jobs.append(loadTextureJob);
}
+
// TO DO: Have 2 jobs queue
// One for urgent jobs that are mandatory for the rendering of a frame
// Another for jobs that can span across multiple frames (Scene/Mesh loading)
const QVector<Render::LoadSceneJobPtr> sceneJobs = manager->sceneManager()->pendingSceneLoaderJobs();
- Q_FOREACH (Render::LoadSceneJobPtr job, sceneJobs) {
+ for (const Render::LoadSceneJobPtr &job : sceneJobs) {
job->setNodeManagers(d->m_nodeManagers);
- job->setSceneParsers(d->m_sceneParsers);
+ job->setSceneIOHandlers(d->m_sceneIOHandler);
jobs.append(job);
}
- // Clear any previous temporary dependency
- d->m_calculateBoundingVolumeJob->removeDependency(QWeakPointer<QAspectJob>());
- const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs();
- Q_FOREACH (const QAspectJobPtr bufferJob, bufferJobs)
- d->m_calculateBoundingVolumeJob->addDependency(bufferJob);
- jobs.append(bufferJobs);
-
- const QVector<QAspectJobPtr> geometryJobs = createGeometryRendererJobs();
+ const QVector<QAspectJobPtr> geometryJobs = d->createGeometryRendererJobs();
jobs.append(geometryJobs);
- const QVector<QNodeId> geometryRendererTriangleUpdates = manager->geometryRendererManager()->geometryRenderersRequiringTriangleDataRefresh();
- Q_FOREACH (const QNodeId geomRendererId, geometryRendererTriangleUpdates) {
- Render::CalcGeometryTriangleVolumesPtr triangleComputeJob(new Render::CalcGeometryTriangleVolumes(geomRendererId, manager));
- triangleComputeJob->addDependency(d->m_framePreparationJob);
- pickBoundingVolumeJob->addDependency(triangleComputeJob);
- jobs.append(triangleComputeJob);
- }
-
- // Only add dependency if not already present
- const QVector<QWeakPointer<QAspectJob> > dependencies = pickBoundingVolumeJob->dependencies();
- if (std::find(dependencies.begin(), dependencies.end(), d->m_updateBoundingVolumeJob) == dependencies.end())
- pickBoundingVolumeJob->addDependency(d->m_updateBoundingVolumeJob);
-
// Add all jobs to queue
- jobs.append(d->m_calculateBoundingVolumeJob);
- jobs.append(d->m_worldTransformJob);
- jobs.append(d->m_updateBoundingVolumeJob);
- jobs.append(d->m_framePreparationJob);
+ const Qt3DCore::QAspectJobPtr pickBoundingVolumeJob = d->m_renderer->pickBoundingVolumeJob();
jobs.append(pickBoundingVolumeJob);
- // Clear any old dependencies from previous frames
- d->m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>());
-
- // Do not create any more RenderView jobs when the platform surface is gone.
- if (d->m_renderer->surface()) {
- // Traverse the current framegraph and create jobs to populate
- // RenderBins with RenderCommands
- QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
- // TODO: Add wrapper around ThreadWeaver::Collection
- for (int i = 0; i < renderBinJobs.size(); ++i) {
- QAspectJobPtr renderBinJob = renderBinJobs.at(i);
- renderBinJob->addDependency(d->m_updateBoundingVolumeJob);
- jobs.append(renderBinJob);
- d->m_cleanupJob->addDependency(renderBinJob);
- }
- }
- jobs.append(d->m_cleanupJob);
+ // Traverse the current framegraph and create jobs to populate
+ // RenderBins with RenderCommands
+ // All jobs needed to create the frame and their dependencies are set by
+ // renderBinJobs()
+ const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
+ jobs.append(renderBinJobs);
}
return jobs;
}
-void QRenderAspect::onRootEntityChanged(Qt3DCore::QEntity *rootEntity)
+QVariant QRenderAspect::executeCommand(const QStringList &args)
+{
+ Q_D(QRenderAspect);
+ return d->m_renderer->executeCommand(args);
+}
+
+void QRenderAspect::onEngineStartup()
{
Q_D(QRenderAspect);
- d->m_renderer->setSceneRoot(d, d->m_renderer->nodeManagers()->lookupResource<Render::Entity, Render::EntityManager>(rootEntity->id()));
+ Render::NodeManagers *managers = d->m_renderer->nodeManagers();
+ Render::Entity *rootEntity = managers->lookupResource<Render::Entity, Render::EntityManager>(rootEntityId());
+ Q_ASSERT(rootEntity);
+ d->m_renderer->setSceneRoot(d, rootEntity);
}
-void QRenderAspect::onInitialize(const QVariantMap &data)
+void QRenderAspect::onRegistered()
{
- // TODO: Remove the m_initialized variable and split out onInitialize()
- // and setting a resource (the QSurface) on the aspects.
+ // Create a renderer each time as this is destroyed in onUnregistered below. If
+ // using a threaded renderer, this blocks until the render thread has been created
+ // and started.
Q_D(QRenderAspect);
+ d->m_renderer = new Render::Renderer(d->m_renderType);
+ d->m_renderer->setNodeManagers(d->m_nodeManagers);
+
+ // Register backend types now that we have a renderer
+ d->registerBackendTypes();
+
if (!d->m_initialized) {
// Register the VSyncFrameAdvanceService to drive the aspect manager loop
@@ -419,64 +441,42 @@ void QRenderAspect::onInitialize(const QVariantMap &data)
}
d->m_renderer->setServices(d->services());
- d->m_renderer->createAllocators(d->jobManager());
d->m_initialized = true;
}
- QSurface *surface = Q_NULLPTR;
- const QVariant &v = data.value(QStringLiteral("surface"));
- if (v.isValid())
- surface = v.value<QSurface *>();
-
- if (surface)
- d->setSurface(surface);
-
if (d->m_aspectManager)
d->m_renderer->registerEventFilter(d->services()->eventFilterService());
}
-void QRenderAspect::onCleanup()
-{
- Q_D(QRenderAspect);
- if (d->m_renderer)
- d->m_renderer->destroyAllocators(d->jobManager());
- delete d->m_renderer;
- d->m_renderer = Q_NULLPTR;
-}
-
-// Returns a vector of jobs to be performed for dirty buffers
-// 1 dirty buffer == 1 job, all job can be performed in parallel
-QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::createRenderBufferJobs()
+void QRenderAspect::onUnregistered()
{
Q_D(QRenderAspect);
- const QVector<QNodeId> dirtyBuffers = d->m_nodeManagers->bufferManager()->dirtyBuffers();
- QVector<QAspectJobPtr> dirtyBuffersJobs;
-
- Q_FOREACH (const QNodeId &bufId, dirtyBuffers) {
- Render::HBuffer bufferHandle = d->m_nodeManagers->lookupHandle<Render::Buffer, Render::BufferManager, Render::HBuffer>(bufId);
- if (!bufferHandle.isNull()) {
- // Create new buffer job
- Render::LoadBufferJobPtr job(new Render::LoadBufferJob(bufferHandle));
- job->setNodeManager(d->m_nodeManagers);
- dirtyBuffersJobs.push_back(job);
- }
+ if (d->m_renderer) {
+ // Request the renderer shuts down. In the threaded renderer case, the
+ // Renderer destructor is the synchronization point where we wait for the
+ // thread to join (see below).
+ d->m_renderer->shutdown();
}
- return dirtyBuffersJobs;
+ d->unregisterBackendTypes();
+
+ // Waits for the render thread to join (if using threaded renderer)
+ delete d->m_renderer;
+ d->m_renderer = nullptr;
}
-QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::createGeometryRendererJobs()
+QVector<Qt3DCore::QAspectJobPtr> QRenderAspectPrivate::createGeometryRendererJobs()
{
- Q_D(QRenderAspect);
- Render::GeometryRendererManager *geomRendererManager = d->m_nodeManagers->geometryRendererManager();
+ Render::GeometryRendererManager *geomRendererManager = m_nodeManagers->geometryRendererManager();
const QVector<QNodeId> dirtyGeometryRenderers = geomRendererManager->dirtyGeometryRenderers();
QVector<QAspectJobPtr> dirtyGeometryRendererJobs;
+ dirtyGeometryRendererJobs.reserve(dirtyGeometryRenderers.size());
- Q_FOREACH (const QNodeId &geoRendererId, dirtyGeometryRenderers) {
+ for (const QNodeId geoRendererId : dirtyGeometryRenderers) {
Render::HGeometryRenderer geometryRendererHandle = geomRendererManager->lookupHandle(geoRendererId);
if (!geometryRendererHandle.isNull()) {
- Render::LoadGeometryJobPtr job(new Render::LoadGeometryJob(geometryRendererHandle));
- job->setNodeManagers(d->m_nodeManagers);
+ auto job = Render::LoadGeometryJobPtr::create(geometryRendererHandle);
+ job->setNodeManagers(m_nodeManagers);
dirtyGeometryRendererJobs.push_back(job);
}
}
@@ -486,11 +486,11 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::createGeometryRendererJobs()
void QRenderAspectPrivate::loadSceneParsers()
{
- QStringList keys = QSceneParserFactory::keys();
- Q_FOREACH (QString key, keys) {
- QAbstractSceneParser *sceneParser = QSceneParserFactory::create(key, QStringList());
- if (sceneParser != Q_NULLPTR)
- m_sceneParsers.append(sceneParser);
+ const QStringList keys = QSceneIOFactory::keys();
+ for (const QString &key : keys) {
+ QSceneIOHandler *sceneIOHandler = QSceneIOFactory::create(key, QStringList());
+ if (sceneIOHandler != nullptr)
+ m_sceneIOHandler.append(sceneIOHandler);
}
}