diff options
-rw-r--r-- | src/render/backend/platformsurfacefilter.cpp | 14 | ||||
-rw-r--r-- | src/render/backend/platformsurfacefilter_p.h | 9 | ||||
-rw-r--r-- | src/render/backend/renderer.cpp | 88 | ||||
-rw-r--r-- | src/render/backend/renderer_p.h | 69 | ||||
-rw-r--r-- | src/render/backend/renderview.cpp | 2 | ||||
-rw-r--r-- | src/render/framegraph/framegraphnode.cpp | 3 | ||||
-rw-r--r-- | src/render/framegraph/framegraphnode_p.h | 4 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect.cpp | 191 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect.h | 3 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect_p.h | 12 | ||||
-rw-r--r-- | src/render/jobs/framecleanupjob.cpp | 16 | ||||
-rw-r--r-- | src/render/jobs/framecleanupjob_p.h | 9 | ||||
-rw-r--r-- | src/render/jobs/loadscenejob.cpp | 10 | ||||
-rw-r--r-- | src/render/jobs/loadscenejob_p.h | 10 | ||||
-rw-r--r-- | src/render/jobs/pickboundingvolumejob.cpp | 4 | ||||
-rw-r--r-- | src/render/jobs/renderviewjob.cpp | 2 | ||||
-rw-r--r-- | tests/benchmarks/render/jobs/tst_bench_jobs.cpp | 13 |
17 files changed, 265 insertions, 194 deletions
diff --git a/src/render/backend/platformsurfacefilter.cpp b/src/render/backend/platformsurfacefilter.cpp index 248e54d93..1fe9f11be 100644 --- a/src/render/backend/platformsurfacefilter.cpp +++ b/src/render/backend/platformsurfacefilter.cpp @@ -48,14 +48,12 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -PlatformSurfaceFilter::PlatformSurfaceFilter(Renderer *renderer, - QObject *parent) +PlatformSurfaceFilter::PlatformSurfaceFilter(QObject *parent) : QObject(parent) , m_obj(Q_NULLPTR) , m_surface(Q_NULLPTR) - , m_renderer(renderer) + , m_renderer(Q_NULLPTR) { - Q_ASSERT(m_renderer); qRegisterMetaType<QSurface *>("QSurface*"); } @@ -75,6 +73,11 @@ void PlatformSurfaceFilter::setOffscreenSurface(QOffscreenSurface *offscreen) setSurface(offscreen); } +void PlatformSurfaceFilter::setRenderer(AbstractRenderer *renderer) +{ + m_renderer = renderer; +} + bool PlatformSurfaceFilter::eventFilter(QObject *obj, QEvent *e) { if (obj == m_obj && e->type() == QEvent::PlatformSurface) { @@ -114,7 +117,8 @@ void PlatformSurfaceFilter::setRendererSurface(QSurface *surface) // draw calls. Only when the frame finishes and the mutex is unlocked does // this call to Renderer::setSurface continue. Thereby blocking the main // thread from destroying the platform surface before we are ready. - m_renderer->setSurface(surface); + if (m_renderer != Q_NULLPTR) + m_renderer->setSurface(surface); } } // namespace Render diff --git a/src/render/backend/platformsurfacefilter_p.h b/src/render/backend/platformsurfacefilter_p.h index f0f56d238..24d71ca16 100644 --- a/src/render/backend/platformsurfacefilter_p.h +++ b/src/render/backend/platformsurfacefilter_p.h @@ -59,20 +59,21 @@ class QWindow; namespace Qt3DRender { namespace Render { -class Renderer; +class AbstractRenderer; class PlatformSurfaceFilter : public QObject { Q_OBJECT public: - explicit PlatformSurfaceFilter(Renderer *renderAspect, - QObject *parent = 0); + explicit PlatformSurfaceFilter(QObject *parent = 0); ~PlatformSurfaceFilter(); void setWindow(QWindow *window); void setOffscreenSurface(QOffscreenSurface *offscreen); + void setRenderer(AbstractRenderer *renderer); + bool eventFilter(QObject *obj, QEvent *e) Q_DECL_OVERRIDE; private: @@ -96,7 +97,7 @@ private: QObject *m_obj; QSurface *m_surface; - Renderer *m_renderer; + AbstractRenderer *m_renderer; }; } // namespace Render diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index f00bad24d..61bbc7186 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -70,10 +70,7 @@ #include <Qt3DRender/private/techniquefilternode_p.h> #include <Qt3DRender/private/viewportnode_p.h> #include <Qt3DRender/private/vsyncframeadvanceservice_p.h> -#include <Qt3DRender/private/loadbufferjob_p.h> -#include <Qt3DRender/private/loadgeometryjob_p.h> #include <Qt3DRender/private/pickeventfilter_p.h> -#include <Qt3DRender/private/qsceneparserfactory_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/buffermanager_p.h> #include <Qt3DRender/private/nodemanagers_p.h> @@ -135,7 +132,7 @@ const QString SCENE_PARSERS_PATH = QStringLiteral("/sceneparsers"); Renderer::Renderer(QRenderAspect::RenderType type) : m_rendererAspect(Q_NULLPTR) - , m_nodesManager(new NodeManagers()) + , m_nodesManager(Q_NULLPTR) , m_graphicsContext(Q_NULLPTR) , m_surface(Q_NULLPTR) , m_eventSource(Q_NULLPTR) @@ -145,20 +142,20 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_debugLogger(Q_NULLPTR) , m_pickEventFilter(new PickEventFilter()) , m_exposed(0) + , m_glContext(Q_NULLPTR) + , m_pickBoundingVolumeJob(Q_NULLPTR) { // Set renderer as running - it will wait in the context of the // RenderThread for RenderViews to be submitted m_running.fetchAndStoreOrdered(1); if (m_renderThread) m_renderThread->waitForStart(); - - loadSceneParsers(); } Renderer::~Renderer() { // Clean up the TLS allocators - destroyAllocators(rendererAspect()->jobManager()); + destroyAllocators(m_rendererAspect->jobManager()); } NodeManagers *Renderer::nodeManagers() const @@ -166,6 +163,11 @@ NodeManagers *Renderer::nodeManagers() const return m_nodesManager; } +void Renderer::setOpenGLContext(QOpenGLContext *context) +{ + m_glContext = context; +} + void Renderer::buildDefaultTechnique() { Q_ASSERT(m_graphicsContext); @@ -223,16 +225,6 @@ void Renderer::buildDefaultTechnique() } -void Renderer::loadSceneParsers() -{ - QStringList keys = QSceneParserFactory::keys(); - Q_FOREACH (QString key, keys) { - QAbstractSceneParser *sceneParser = QSceneParserFactory::create(key, QStringList()); - if (sceneParser != Q_NULLPTR) - m_sceneParsers.append(sceneParser); - } -} - void Renderer::buildDefaultMaterial() { m_defaultMaterial = new QMaterial(); @@ -245,7 +237,6 @@ void Renderer::buildDefaultMaterial() QEffect* defEff = new QEffect; defEff->addTechnique(m_defaultTechnique); m_defaultMaterial->setEffect(defEff); - } void Renderer::createAllocators(QAbstractAspectJobManager *jobManager) @@ -319,7 +310,7 @@ void Renderer::destroyThreadLocalAllocator(void *renderer) // Called in RenderThread context by the run method of RenderThread // RenderThread has locked the mutex already and unlocks it when this // method termintates -void Renderer::initialize(QOpenGLContext *context) +void Renderer::initialize() { if (m_renderThread) m_waitForWindowToBeSetCondition.wait(mutex()); @@ -334,8 +325,8 @@ void Renderer::initialize(QOpenGLContext *context) if (enableDebugLogging) sf.setOption(QSurfaceFormat::DebugContext); - QOpenGLContext* ctx = context ? context : new QOpenGLContext; - if (!context) { + QOpenGLContext* ctx = m_glContext ? m_glContext : new QOpenGLContext; + if (!m_glContext) { qCDebug(Backend) << "Creating OpenGL context with format" << sf; ctx->setFormat(sf); if (ctx->create()) @@ -402,9 +393,9 @@ void Renderer::setSurfaceExposed(bool exposed) m_exposed.fetchAndStoreOrdered(exposed); } -void Renderer::setFrameGraphRoot(const Qt3DCore::QNodeId &frameGraphRootUuid) +void Renderer::setFrameGraphRoot(const Qt3DCore::QNodeId fgRootId) { - m_frameGraphRootUuid = frameGraphRootUuid; + m_frameGraphRootUuid = fgRootId; qCDebug(Backend) << Q_FUNC_INFO << m_frameGraphRootUuid; } @@ -423,7 +414,7 @@ Render::FrameGraphNode *Renderer::frameGraphRoot() const // 3) setWindow -> waking Initialize if setSceneGraphRoot was called before // 4) Initialize resuming, performing initialization and waking up setSceneGraphRoot // 5) setSceneGraphRoot called || setSceneGraphRoot resuming if it was waiting -void Renderer::setSceneGraphRoot(Entity *sgRoot) +void Renderer::setSceneRoot(Entity *sgRoot) { Q_ASSERT(sgRoot); QMutexLocker lock(&m_mutex); // This waits until initialize and setSurface have been called @@ -739,7 +730,7 @@ bool Renderer::submitRenderViews() // Waits to be told to create jobs for the next frame // Called by QRenderAspect jobsToExecute context of QAspectThread -QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBinJobs() +QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() { // Traverse the current framegraph. For each leaf node create a // RenderView and set its configuration then create a job to @@ -756,42 +747,14 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBinJobs() return renderBinJobs; } -// 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> Renderer::createRenderBufferJobs() +QAspectJobPtr Renderer::pickBoundingVolumeJob() { - const QVector<QNodeId> dirtyBuffers = nodeManagers()->bufferManager()->dirtyBuffers(); - QVector<QAspectJobPtr> dirtyBuffersJobs; - - Q_FOREACH (const QNodeId &bufId, dirtyBuffers) { - HBuffer bufferHandle = m_nodesManager->lookupHandle<Buffer, BufferManager, HBuffer>(bufId); - if (!bufferHandle.isNull()) { - // Create new buffer job - LoadBufferJobPtr job(new LoadBufferJob(bufferHandle)); - job->setNodeManager(m_nodesManager); - dirtyBuffersJobs.push_back(job); - } - } - - return dirtyBuffersJobs; -} - -QVector<Qt3DCore::QAspectJobPtr> Renderer::createGeometryRendererJobs() -{ - GeometryRendererManager *geomRendererManager = m_nodesManager->geometryRendererManager(); - const QVector<QNodeId> dirtyGeometryRenderers = geomRendererManager->dirtyGeometryRenderers(); - QVector<QAspectJobPtr> dirtyGeometryRendererJobs; - - Q_FOREACH (const QNodeId &geoRendererId, dirtyGeometryRenderers) { - HGeometryRenderer geometryRendererHandle = geomRendererManager->lookupHandle(geoRendererId); - if (!geometryRendererHandle.isNull()) { - LoadGeometryJobPtr job(new LoadGeometryJob(geometryRendererHandle)); - job->setNodeManagers(m_nodesManager); - dirtyGeometryRendererJobs.push_back(job); - } - } - - return dirtyGeometryRendererJobs; + // Clear any previous dependency not valid anymore + if (!m_pickBoundingVolumeJob) + m_pickBoundingVolumeJob.reset(new PickBoundingVolumeJob(this)); + m_pickBoundingVolumeJob->clearNullDependencies(); + m_pickBoundingVolumeJob->setRoot(m_renderSceneRoot); + return m_pickBoundingVolumeJob; } // Called during while traversing the FrameGraph for each leaf node context of QAspectThread @@ -806,6 +769,11 @@ Qt3DCore::QAspectJobPtr Renderer::createRenderViewJob(FrameGraphNode *node, int return job; } +QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const +{ + return static_cast<Qt3DCore::QAbstractFrameAdvanceService *>(m_vsyncFrameAdvanceService.data()); +} + // Called by RenderView->submit() in RenderThread context void Renderer::executeCommands(const QVector<RenderCommand *> &commands) { diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 1e17d5270..05f7faaf2 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -53,8 +53,10 @@ #include <Qt3DRender/qtechnique.h> #include <Qt3DRender/private/quniformvalue_p.h> #include <Qt3DRender/private/handle_types_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DCore/qaspectjob.h> #include <Qt3DRender/private/qt3drender_global_p.h> +#include <Qt3DRender/private/pickboundingvolumejob_p.h> #include <QHash> #include <QMatrix4x4> @@ -113,41 +115,58 @@ class VSyncFrameAdvanceService; class PickEventFilter; class NodeManagers; -class QT3DRENDERSHARED_PRIVATE_EXPORT Renderer +class QT3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer { public: explicit Renderer(QRenderAspect::RenderType type); ~Renderer(); - void setQRenderAspect(QRenderAspect *aspect) { m_rendererAspect = aspect; } - QRenderAspect *rendererAspect() const { return m_rendererAspect; } + API api() const Q_DECL_OVERRIDE { return AbstractRenderer::OpenGL; } - NodeManagers *nodeManagers() const; + void setSurface(QSurface *s) Q_DECL_OVERRIDE; + void setNodeManagers(NodeManagers *managers) Q_DECL_OVERRIDE { m_nodesManager = managers; } + void setQRenderAspect(QRenderAspect *aspect) Q_DECL_OVERRIDE { m_rendererAspect = aspect; } + void setSurfaceExposed(bool exposed) Q_DECL_OVERRIDE; - void createAllocators(Qt3DCore::QAbstractAspectJobManager *jobManager); - void destroyAllocators(Qt3DCore::QAbstractAspectJobManager *jobManager); + QSurface *surface() const Q_DECL_OVERRIDE { return m_surface; } + NodeManagers *nodeManagers() const Q_DECL_OVERRIDE; + QRenderAspect *renderAspect() const Q_DECL_OVERRIDE { return m_rendererAspect; } - Qt3DCore::QFrameAllocator *currentFrameAllocator(); + void initialize() Q_DECL_OVERRIDE; + void shutdown() Q_DECL_OVERRIDE; + void createAllocators(Qt3DCore::QAbstractAspectJobManager *jobManager) Q_DECL_OVERRIDE; - QThreadStorage<Qt3DCore::QFrameAllocator *> *tlsAllocators(); + void render() Q_DECL_OVERRIDE; + void doRender() Q_DECL_OVERRIDE; + + bool isRunning() const Q_DECL_OVERRIDE { return m_running.load(); } - void setFrameGraphRoot(const Qt3DCore::QNodeId &fgRoot); - Render::FrameGraphNode *frameGraphRoot() const; + void setSceneRoot(Entity *sgRoot) Q_DECL_OVERRIDE; + Entity *sceneRoot() const Q_DECL_OVERRIDE { return m_renderSceneRoot; } - void setSceneGraphRoot(Entity *sgRoot); - Entity *renderSceneRoot() const { return m_renderSceneRoot; } + void setFrameGraphRoot(const Qt3DCore::QNodeId fgRootId) Q_DECL_OVERRIDE; + FrameGraphNode *frameGraphRoot() const Q_DECL_OVERRIDE; - void render(); - void doRender(); + QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() Q_DECL_OVERRIDE; + Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() Q_DECL_OVERRIDE; - QVector<Qt3DCore::QAspectJobPtr> createRenderBinJobs(); - QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs(); - QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs(); Qt3DCore::QAspectJobPtr createRenderViewJob(FrameGraphNode *node, int submitOrderIndex); + + Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const Q_DECL_OVERRIDE; + + void registerEventFilter(Qt3DCore::QEventFilterService *service) Q_DECL_OVERRIDE; + void executeCommands(const QVector<RenderCommand *> &commands); Attribute *updateBuffersAndAttributes(Geometry *geometry, RenderCommand *command, GLsizei &count, bool forceUpdate); + + void setOpenGLContext(QOpenGLContext *context); + QGraphicsApiFilter *contextInfo() const; + + void destroyAllocators(Qt3DCore::QAbstractAspectJobManager *jobManager); void addAllocator(Qt3DCore::QFrameAllocator *allocator); + Qt3DCore::QFrameAllocator *currentFrameAllocator(); + QThreadStorage<Qt3DCore::QFrameAllocator *> *tlsAllocators(); inline HMaterial defaultMaterialHandle() const { return m_defaultMaterialHandle; } inline HEffect defaultEffectHandle() const { return m_defaultEffectHandle; } @@ -155,27 +174,15 @@ public: inline HRenderPass defaultRenderPassHandle() const { return m_defaultRenderPassHandle; } inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; } - inline QList<QAbstractSceneParser *> sceneParsers() const { return m_sceneParsers; } - inline VSyncFrameAdvanceService *vsyncFrameAdvanceService() const { return m_vsyncFrameAdvanceService.data(); } QList<QMouseEvent> pendingPickingEvents() const; - QGraphicsApiFilter *contextInfo() const; - - void setSurface(QSurface *s); - inline QSurface *surface() const { return m_surface; } - void registerEventFilter(Qt3DCore::QEventFilterService *service); void enqueueRenderView(RenderView *renderView, int submitOrder); bool submitRenderViews(); - void initialize(QOpenGLContext *context = Q_NULLPTR); - void shutdown(); - QMutex* mutex() { return &m_mutex; } - bool isRunning() const { return m_running.load(); } - void setSurfaceExposed(bool exposed); #ifdef QT3D_RENDER_UNIT_TESTS public: @@ -222,7 +229,6 @@ private: void buildDefaultMaterial(); void buildDefaultTechnique(); - void loadSceneParsers(); QMutex m_mutex; QSemaphore m_submitRenderViewsSemaphore; @@ -237,12 +243,13 @@ private: QScopedPointer<QOpenGLDebugLogger> m_debugLogger; QScopedPointer<PickEventFilter> m_pickEventFilter; - QList<QAbstractSceneParser *> m_sceneParsers; QVector<Qt3DCore::QFrameAllocator *> m_allocators; QVector<Attribute *> m_dirtyAttributes; QVector<Geometry *> m_dirtyGeometry; QAtomicInt m_exposed; + QOpenGLContext *m_glContext; + PickBoundingVolumeJobPtr m_pickBoundingVolumeJob; }; } // namespace Render diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index 22000713a..88e9ecc2f 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -247,7 +247,7 @@ QUniformValue *RenderView::inverseViewportMatrix(const QMatrix4x4 &model) const QUniformValue *RenderView::time(const QMatrix4x4 &model) const { Q_UNUSED(model); - qint64 time = m_renderer->rendererAspect()->time(); + qint64 time = m_renderer->renderAspect()->time(); float t = time / 1000000000.0f; return QUniformValue::fromVariant(QVariant(t), m_allocator); } diff --git a/src/render/framegraph/framegraphnode.cpp b/src/render/framegraph/framegraphnode.cpp index 10629f1d8..d1718b7e5 100644 --- a/src/render/framegraph/framegraphnode.cpp +++ b/src/render/framegraph/framegraphnode.cpp @@ -36,6 +36,7 @@ #include "framegraphnode_p.h" #include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/qframegraph.h> QT_BEGIN_NAMESPACE @@ -146,7 +147,7 @@ QList<FrameGraphNode *> FrameGraphNode::children() const } // TO DO: We need to rework that and probably add a RenderFrameGraph element -FrameGraphComponentFunctor::FrameGraphComponentFunctor(Renderer *renderer) +FrameGraphComponentFunctor::FrameGraphComponentFunctor(AbstractRenderer *renderer) : m_renderer(renderer) { } diff --git a/src/render/framegraph/framegraphnode_p.h b/src/render/framegraph/framegraphnode_p.h index 3e65ca598..707b37ea6 100644 --- a/src/render/framegraph/framegraphnode_p.h +++ b/src/render/framegraph/framegraphnode_p.h @@ -174,13 +174,13 @@ private: class FrameGraphComponentFunctor : public Qt3DCore::QBackendNodeFunctor { public: - explicit FrameGraphComponentFunctor(Renderer *renderer); + explicit FrameGraphComponentFunctor(AbstractRenderer *renderer); Qt3DCore::QBackendNode *create(Qt3DCore::QNode *frontend, const Qt3DCore::QBackendNodeFactory *factory) const Q_DECL_OVERRIDE; Qt3DCore::QBackendNode *get(const Qt3DCore::QNodeId &id) const Q_DECL_OVERRIDE; void destroy(const Qt3DCore::QNodeId &id) const Q_DECL_OVERRIDE; private: - Renderer *m_renderer; + AbstractRenderer *m_renderer; }; } // namespace Render diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index bcfdddde5..46e82a448 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -103,6 +103,12 @@ #include <Qt3DRender/private/boundingvolumedebug_p.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/calcgeometrytrianglevolumes_p.h> +#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 <Qt3DCore/qentity.h> #include <Qt3DCore/qtransform.h> @@ -135,20 +141,23 @@ namespace Qt3DRender { */ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type) : QAbstractAspectPrivate() - , m_renderer(new Render::Renderer(type)) - , m_surfaceEventFilter(new Render::PlatformSurfaceFilter(m_renderer)) + , m_nodeManagers(new Render::NodeManagers()) + , m_renderer(Q_NULLPTR) + , m_surfaceEventFilter(new Render::PlatformSurfaceFilter()) , m_surface(Q_NULLPTR) , m_time(0) , m_initialized(false) - , m_framePreparationJob(new Render::FramePreparationJob(m_renderer->nodeManagers())) - , m_cleanupJob(new Render::FrameCleanupJob(m_renderer)) + , 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_renderer->nodeManagers())) - , m_pickBoundingVolumeJob(new Render::PickBoundingVolumeJob(m_renderer)) + , m_calculateBoundingVolumeJob(new Render::CalculateBoundingVolumeJob(m_nodeManagers)) { 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); @@ -156,7 +165,12 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type) // All world stuff depends on the RenderEntity's localBoundingVolume m_worldTransformJob->addDependency(m_calculateBoundingVolumeJob); - m_pickBoundingVolumeJob->addDependency(m_updateBoundingVolumeJob); + + // 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) @@ -219,50 +233,51 @@ QRenderAspect::QRenderAspect(QRenderAspectPrivate &dd, QObject *parent) void QRenderAspect::registerBackendTypes() { Q_D(QRenderAspect); - Qt3DRender::Render::NodeManagers *nodeManagers = d->m_renderer->nodeManagers(); - - registerBackendType<Qt3DCore::QEntity>(QBackendNodeFunctorPtr(new Render::RenderEntityFunctor(nodeManagers))); - registerBackendType<Qt3DCore::QTransform>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Transform, Render::TransformManager>(nodeManagers->transformManager()))); - registerBackendType<QMaterial>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Material, Render::MaterialManager>(nodeManagers->materialManager()))); - registerBackendType<QTechnique>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Technique, Render::TechniqueManager>(nodeManagers->techniqueManager()))); - registerBackendType<QAbstractTextureProvider>(QBackendNodeFunctorPtr(new Render::TextureFunctor(nodeManagers->textureManager(), nodeManagers->textureImageManager(), nodeManagers->textureDataManager()))); - registerBackendType<QShaderProgram>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Shader, Render::ShaderManager>(nodeManagers->shaderManager()))); - registerBackendType<QEffect>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Effect, Render::EffectManager>(nodeManagers->effectManager()))); - registerBackendType<QAnnotation>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Annotation, Render::CriterionManager>(nodeManagers->criterionManager()))); - registerBackendType<Qt3DCore::QCameraLens>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::CameraLens, Render::CameraManager>(nodeManagers->cameraManager()))); - registerBackendType<QLayer>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Layer, Render::LayerManager>(nodeManagers->layerManager()))); - registerBackendType<QRenderPass>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager>(nodeManagers->renderPassManager()))); - registerBackendType<QAbstractSceneLoader>(QBackendNodeFunctorPtr(new Render::RenderSceneFunctor(nodeManagers->sceneManager()))); - registerBackendType<QRenderTarget>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderTarget, Render::RenderTargetManager>(nodeManagers->renderTargetManager()))); - registerBackendType<QRenderAttachment>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::RenderAttachment, Render::AttachmentManager>(nodeManagers->attachmentManager()))); - registerBackendType<QSortCriterion>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::SortCriterion, Render::SortCriterionManager>(nodeManagers->sortCriterionManager()))); - registerBackendType<QClearBuffer>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::ClearBuffer, QClearBuffer>(nodeManagers->frameGraphManager()))); - registerBackendType<QTechniqueFilter>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::TechniqueFilter, QTechniqueFilter>(nodeManagers->frameGraphManager()))); - registerBackendType<QViewport>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport>(nodeManagers->frameGraphManager()))); - registerBackendType<QRenderPassFilter>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::RenderPassFilter, QRenderPassFilter>(nodeManagers->frameGraphManager()))); - registerBackendType<QCameraSelector>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector>(nodeManagers->frameGraphManager()))); - registerBackendType<QRenderTargetSelector>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::RenderTargetSelector, QRenderTargetSelector>(nodeManagers->frameGraphManager()))); - registerBackendType<QLayerFilter>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::LayerFilterNode, QLayerFilter>(nodeManagers->frameGraphManager()))); - registerBackendType<QSortMethod>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::SortMethod, QSortMethod>(nodeManagers->frameGraphManager()))); - registerBackendType<QFrameGraphSelector>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::FrameGraphSubtreeSelector, QFrameGraphSelector>(nodeManagers->frameGraphManager()))); + + 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>(nodeManagers->parameterManager()))); - registerBackendType<QShaderData>(QBackendNodeFunctorPtr(new Render::RenderShaderDataFunctor(nodeManagers->shaderDataManager()))); - registerBackendType<QAbstractTextureImage>(QBackendNodeFunctorPtr(new Render::TextureImageFunctor(nodeManagers->textureManager(), nodeManagers->textureImageManager(), nodeManagers->textureDataManager()))); - registerBackendType<QStateSet>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::StateSetNode, QStateSet>(nodeManagers->frameGraphManager()))); - registerBackendType<QNoDraw>(QBackendNodeFunctorPtr(new Render::FrameGraphNodeFunctor<Render::NoDraw, QNoDraw>(nodeManagers->frameGraphManager()))); - registerBackendType<QBuffer>(QBackendNodeFunctorPtr(new Render::BufferFunctor(nodeManagers->bufferManager()))); - registerBackendType<QAttribute>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Attribute, Render::AttributeManager>(nodeManagers->attributeManager()))); - registerBackendType<QGeometry>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Geometry, Render::GeometryManager>(nodeManagers->geometryManager()))); - registerBackendType<QGeometryRenderer>(QBackendNodeFunctorPtr(new Render::GeometryRendererFunctor(nodeManagers->geometryRendererManager()))); - registerBackendType<QObjectPicker>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager>(nodeManagers->objectPickerManager()))); - registerBackendType<QBoundingVolumeDebug>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::BoundingVolumeDebug, Render::BoundingVolumeDebugManager>(nodeManagers->boundingVolumeDebugManager()))); + registerBackendType<QParameter>(QBackendNodeFunctorPtr(new Render::NodeFunctor<Render::Parameter, Render::ParameterManager>(d->m_nodeManagers->parameterManager()))); + registerBackendType<QShaderData>(QBackendNodeFunctorPtr(new Render::RenderShaderDataFunctor(d->m_nodeManagers->shaderDataManager()))); + 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()))); } void QRenderAspect::renderInitialize(QOpenGLContext *context) { Q_D(QRenderAspect); - d->m_renderer->initialize(context); + if (d->m_renderer->api() == Render::AbstractRenderer::OpenGL) + static_cast<Render::Renderer *>(d->m_renderer)->setOpenGLContext(context); + d->m_renderer->initialize(); } void QRenderAspect::renderSynchronous() @@ -300,13 +315,14 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time) if (d->m_renderer != Q_NULLPTR && d->m_renderer->isRunning()) { 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->renderSceneRoot()); - d->m_worldTransformJob->setRoot(d->m_renderer->renderSceneRoot()); - d->m_updateBoundingVolumeJob->setRoot(d->m_renderer->renderSceneRoot()); - d->m_calculateBoundingVolumeJob->setRoot(d->m_renderer->renderSceneRoot()); - d->m_pickBoundingVolumeJob->setRoot(d->m_renderer->renderSceneRoot()); + 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) { @@ -319,43 +335,44 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time) // 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) { - job->setRenderer(d->m_renderer); + job->setNodeManagers(d->m_nodeManagers); + job->setSceneParsers(d->m_sceneParsers); jobs.append(job); } // Clear any previous temporary dependency d->m_calculateBoundingVolumeJob->clearNullDependencies(); - const QVector<QAspectJobPtr> bufferJobs = d->m_renderer->createRenderBufferJobs(); + const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs(); Q_FOREACH (const QAspectJobPtr bufferJob, bufferJobs) d->m_calculateBoundingVolumeJob->addDependency(bufferJob); jobs.append(bufferJobs); - const QVector<QAspectJobPtr> geometryJobs = d->m_renderer->createGeometryRendererJobs(); + const QVector<QAspectJobPtr> geometryJobs = createGeometryRendererJobs(); jobs.append(geometryJobs); - // Clear any previous dependency not valid anymore - d->m_pickBoundingVolumeJob->clearNullDependencies(); 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); - d->m_pickBoundingVolumeJob->addDependency(triangleComputeJob); + pickBoundingVolumeJob->addDependency(triangleComputeJob); jobs.append(triangleComputeJob); } + 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); - jobs.append(d->m_pickBoundingVolumeJob); + jobs.append(pickBoundingVolumeJob); // 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->createRenderBinJobs(); + 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); @@ -398,7 +415,7 @@ void QRenderAspect::setRootEntity(Qt3DCore::QEntity *rootObject) Q_D(QRenderAspect); QNodeVisitor visitor; visitor.traverse(rootObject, this, &QRenderAspect::visitNode); - d->m_renderer->setSceneGraphRoot(d->m_renderer->nodeManagers()->lookupResource<Render::Entity, Render::EntityManager>(rootObject->id())); + d->m_renderer->setSceneRoot(d->m_renderer->nodeManagers()->lookupResource<Render::Entity, Render::EntityManager>(rootObject->id())); } void QRenderAspect::onInitialize(const QVariantMap &data) @@ -411,8 +428,10 @@ void QRenderAspect::onInitialize(const QVariantMap &data) // Register the VSyncFrameAdvanceService to drive the aspect manager loop // depending on the vsync if (d->m_aspectManager) { - services()->registerServiceProvider(Qt3DCore::QServiceLocator::FrameAdvanceService, - d->m_renderer->vsyncFrameAdvanceService()); + QAbstractFrameAdvanceService *advanceService = d->m_renderer->frameAdvanceService(); + if (advanceService) + services()->registerServiceProvider(Qt3DCore::QServiceLocator::FrameAdvanceService, + advanceService); } d->m_renderer->setQRenderAspect(this); @@ -452,6 +471,56 @@ void QRenderAspect::visitNode(Qt3DCore::QNode *node) QAbstractAspect::createBackendNode(node); } +// 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() +{ + 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); + } + } + + return dirtyBuffersJobs; +} + +QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::createGeometryRendererJobs() +{ + Q_D(QRenderAspect); + Render::GeometryRendererManager *geomRendererManager = d->m_nodeManagers->geometryRendererManager(); + const QVector<QNodeId> dirtyGeometryRenderers = geomRendererManager->dirtyGeometryRenderers(); + QVector<QAspectJobPtr> dirtyGeometryRendererJobs; + + Q_FOREACH (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); + dirtyGeometryRendererJobs.push_back(job); + } + } + + return dirtyGeometryRendererJobs; +} + +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); + } +} + } // namespace Qt3DRender QT_END_NAMESPACE diff --git a/src/render/frontend/qrenderaspect.h b/src/render/frontend/qrenderaspect.h index 7c1119a32..eb548a917 100644 --- a/src/render/frontend/qrenderaspect.h +++ b/src/render/frontend/qrenderaspect.h @@ -88,6 +88,9 @@ protected: void visitNode(Qt3DCore::QNode *node); + QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs(); + QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs(); + private: friend class Render::Renderer; }; diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h index 418def4cc..b8f103cf0 100644 --- a/src/render/frontend/qrenderaspect_p.h +++ b/src/render/frontend/qrenderaspect_p.h @@ -56,7 +56,6 @@ #include <Qt3DRender/private/framepreparationjob_p.h> #include <Qt3DRender/private/framecleanupjob_p.h> #include <Qt3DRender/private/platformsurfacefilter_p.h> -#include <Qt3DRender/private/pickboundingvolumejob_p.h> QT_BEGIN_NAMESPACE @@ -64,8 +63,11 @@ class QSurface; namespace Qt3DRender { +class QAbstractSceneParser; + namespace Render { -class Renderer; +class AbstractRenderer; +class NodeManagers; } class QRenderAspectPrivate : public Qt3DCore::QAbstractAspectPrivate @@ -76,8 +78,10 @@ public: Q_DECLARE_PUBLIC(QRenderAspect) void setSurface(QSurface *surface); + void loadSceneParsers(); - Render::Renderer *m_renderer; + Render::NodeManagers *m_nodeManagers; + Render::AbstractRenderer *m_renderer; // The filter has affinity with the main thread so we have to delete it there // via QScopedPointerDeleteLater @@ -91,7 +95,7 @@ public: Render::UpdateWorldTransformJobPtr m_worldTransformJob; Render::UpdateBoundingVolumeJobPtr m_updateBoundingVolumeJob; Render::CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob; - Render::PickBoundingVolumeJobPtr m_pickBoundingVolumeJob; + QList<QAbstractSceneParser *> m_sceneParsers; }; } diff --git a/src/render/jobs/framecleanupjob.cpp b/src/render/jobs/framecleanupjob.cpp index 715ad03e6..150626a5b 100644 --- a/src/render/jobs/framecleanupjob.cpp +++ b/src/render/jobs/framecleanupjob.cpp @@ -48,8 +48,9 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -FrameCleanupJob::FrameCleanupJob(Renderer *renderer) - : m_renderer(renderer) +FrameCleanupJob::FrameCleanupJob(NodeManagers *managers) + : m_managers(managers) + , m_root(Q_NULLPTR) { } @@ -57,22 +58,27 @@ FrameCleanupJob::~FrameCleanupJob() { } +void FrameCleanupJob::setRoot(Entity *root) +{ + m_root = root; +} + void FrameCleanupJob::run() { // set each ShaderData to not need an update Q_FOREACH (const Qt3DCore::QNodeId &id, ShaderData::updatedShaderDataList()) { - ShaderData *shaderData = m_renderer->nodeManagers()->shaderDataManager()->lookupResource(id); + ShaderData *shaderData = m_managers->shaderDataManager()->lookupResource(id); if (shaderData != Q_NULLPTR) shaderData->clearUpdate(); } ShaderData::clearShaderDataList(); // Cleanup texture handles - TextureDataManager *textureDataManager = m_renderer->nodeManagers()->textureDataManager(); + TextureDataManager *textureDataManager = m_managers->textureDataManager(); textureDataManager->cleanup(); // Debug bounding volume debug - updateBoundingVolumesDebug(m_renderer->renderSceneRoot()); + updateBoundingVolumesDebug(m_root); } void FrameCleanupJob::updateBoundingVolumesDebug(Entity *node) diff --git a/src/render/jobs/framecleanupjob_p.h b/src/render/jobs/framecleanupjob_p.h index 0f97a0f04..d21718fd5 100644 --- a/src/render/jobs/framecleanupjob_p.h +++ b/src/render/jobs/framecleanupjob_p.h @@ -58,20 +58,23 @@ namespace Qt3DRender { namespace Render { -class Renderer; +class NodeManagers; class Entity; class QT3DRENDERSHARED_PRIVATE_EXPORT FrameCleanupJob : public Qt3DCore::QAspectJob { public: - explicit FrameCleanupJob(Renderer *renderer); + explicit FrameCleanupJob(NodeManagers *managers); ~FrameCleanupJob(); + void setRoot(Entity *root); + protected: void run() Q_DECL_FINAL; private: - Renderer *m_renderer; + NodeManagers *m_managers; + Entity *m_root; void updateBoundingVolumesDebug(Entity *node); }; diff --git a/src/render/jobs/loadscenejob.cpp b/src/render/jobs/loadscenejob.cpp index 4eb857775..cb39f70df 100644 --- a/src/render/jobs/loadscenejob.cpp +++ b/src/render/jobs/loadscenejob.cpp @@ -48,26 +48,26 @@ namespace Render { LoadSceneJob::LoadSceneJob(const QUrl &source, const Qt3DCore::QNodeId &m_sceneComponent) : QAspectJob() - , m_renderer(Q_NULLPTR) , m_source(source) , m_sceneComponent(m_sceneComponent) + , m_managers(Q_NULLPTR) { } void LoadSceneJob::run() { - Qt3DCore::QEntity *sceneTree = m_renderer->nodeManagers()->sceneManager()->sceneTreeFromSource(m_source); + Qt3DCore::QEntity *sceneTree = m_managers->sceneManager()->sceneTreeFromSource(m_source); if (sceneTree == Q_NULLPTR) { - Q_FOREACH (QAbstractSceneParser *parser, m_renderer->sceneParsers()) { + Q_FOREACH (QAbstractSceneParser *parser, m_parsers) { if (parser->isExtensionSupported(m_source)) { parser->setSource(m_source); sceneTree = parser->scene(); - m_renderer->nodeManagers()->sceneManager()->addLoadedSceneTree(m_source, sceneTree); + m_managers->sceneManager()->addLoadedSceneTree(m_source, sceneTree); } } } // set clone of sceneTree in sceneComponent - Scene *scene = m_renderer->nodeManagers()->sceneManager()->lookupResource(m_sceneComponent); + Scene *scene = m_managers->sceneManager()->lookupResource(m_sceneComponent); scene->setSceneSubtree(sceneTree); } diff --git a/src/render/jobs/loadscenejob_p.h b/src/render/jobs/loadscenejob_p.h index b8c4b18ed..a716e8092 100644 --- a/src/render/jobs/loadscenejob_p.h +++ b/src/render/jobs/loadscenejob_p.h @@ -57,23 +57,27 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +class QAbstractSceneParser; + namespace Render { -class Renderer; +class NodeManagers; class LoadSceneJob : public Qt3DCore::QAspectJob { public: explicit LoadSceneJob(const QUrl &source, const Qt3DCore::QNodeId &sceneComponent); - void setRenderer(Renderer *renderer) { m_renderer = renderer; } + void setNodeManagers(NodeManagers *managers) { m_managers = managers; } + void setSceneParsers(const QList<QAbstractSceneParser *> sceneParsers) { m_parsers = sceneParsers; } protected: void run() Q_DECL_OVERRIDE; private: - Renderer *m_renderer; QUrl m_source; Qt3DCore::QNodeId m_sceneComponent; + NodeManagers *m_managers; + QList<QAbstractSceneParser *> m_parsers; }; typedef QSharedPointer<LoadSceneJob> LoadSceneJobPtr; diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 3733cfb56..7fe844fea 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -235,12 +235,12 @@ void PickBoundingVolumeJob::run() if (m_mouseEvents.empty()) return; - Qt3DCore::QAbstractCollisionQueryService *rayCasting = m_renderer->rendererAspect()->services()->service<Qt3DCore::QAbstractCollisionQueryService> + Qt3DCore::QAbstractCollisionQueryService *rayCasting = m_renderer->renderAspect()->services()->service<Qt3DCore::QAbstractCollisionQueryService> (Qt3DCore::QServiceLocator::CollisionService); if (rayCasting == Q_NULLPTR) { Qt3DRender::QRayCastingService *rayCastingService = new QRayCastingService(); - m_renderer->rendererAspect()->services()->registerServiceProvider(Qt3DCore::QServiceLocator::CollisionService, rayCastingService); + m_renderer->renderAspect()->services()->registerServiceProvider(Qt3DCore::QServiceLocator::CollisionService, rayCastingService); rayCasting = rayCastingService; } diff --git a/src/render/jobs/renderviewjob.cpp b/src/render/jobs/renderviewjob.cpp index aa76356b5..890612110 100644 --- a/src/render/jobs/renderviewjob.cpp +++ b/src/render/jobs/renderviewjob.cpp @@ -67,7 +67,7 @@ void RenderViewJob::run() // Build RenderCommand should perform the culling as we have no way to determine // if a child has a mesh in the view frustum while its parent isn't contained in it. if (!renderView->noDraw()) - renderView->buildRenderCommands(m_renderer->renderSceneRoot()); + renderView->buildRenderCommands(m_renderer->sceneRoot()); // Sorts RenderCommand renderView->sort(); diff --git a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp index 2614c4e4c..22340b663 100644 --- a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp +++ b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp @@ -96,36 +96,37 @@ public: QVector<Qt3DCore::QAspectJobPtr> worldTransformJob() { - d_func()->m_worldTransformJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + d_func()->m_worldTransformJob->setRoot(d_func()->m_renderer->sceneRoot()); return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_worldTransformJob; } QVector<Qt3DCore::QAspectJobPtr> updateBoundingJob() { - d_func()->m_updateBoundingVolumeJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + d_func()->m_updateBoundingVolumeJob->setRoot(d_func()->m_renderer->sceneRoot()); return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_updateBoundingVolumeJob; } QVector<Qt3DCore::QAspectJobPtr> calculateBoundingVolumeJob() { - d_func()->m_calculateBoundingVolumeJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + d_func()->m_calculateBoundingVolumeJob->setRoot(d_func()->m_renderer->sceneRoot()); return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_calculateBoundingVolumeJob; } QVector<Qt3DCore::QAspectJobPtr> framePreparationJob() { - d_func()->m_framePreparationJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + d_func()->m_framePreparationJob->setRoot(d_func()->m_renderer->sceneRoot()); return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_framePreparationJob; } QVector<Qt3DCore::QAspectJobPtr> frameCleanupJob() { + d_func()->m_cleanupJob->setRoot(d_func()->m_renderer->sceneRoot()); return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_cleanupJob; } QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() { - return d_func()->m_renderer->createRenderBinJobs(); + return d_func()->m_renderer->renderBinJobs(); } void setRootEntity(Qt3DCore::QEntity *root) @@ -133,7 +134,7 @@ public: if (!m_window) { Qt3DCore::QNodeVisitor visitor; visitor.traverse(root, this, &TestAspect::visitNode); - d_func()->m_renderer->m_renderSceneRoot = + static_cast<Qt3DRender::Render::Renderer *>(d_func()->m_renderer)->m_renderSceneRoot = d_func()->m_renderer->nodeManagers() ->lookupResource<Qt3DRender::Render::Entity, Qt3DRender::Render::EntityManager>(root->id()); } else { |