summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2020-03-04 12:59:48 +0000
committerMike Krus <mike.krus@kdab.com>2020-03-06 08:25:31 +0000
commit0d5a9ebc01a584ab4364e825a3d8a5dabd2ffd8b (patch)
tree14c9cf2ec23296160f1cb30ddcd5586e5fca159f
parent76b39dd90f613f340066cc5a4ceed65ff778bdd4 (diff)
Move common job handling out of Renderer
Should be done in aspect as it's independent of the backend. Moved some tests to separate test using an empty renderer as other backends are likely to have different jobs. Change-Id: I2bec0939045acea7b91ecb1622ba18bf9f5db3c6 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer.cpp189
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer_p.h48
-rw-r--r--src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp19
-rw-r--r--src/render/backend/abstractrenderer_p.h11
-rw-r--r--src/render/backend/cameralens.cpp3
-rw-r--r--src/render/backend/transform.cpp3
-rw-r--r--src/render/frontend/qrenderaspect.cpp195
-rw-r--r--src/render/frontend/qrenderaspect_p.h38
-rw-r--r--src/render/picking/objectpicker.cpp5
-rw-r--r--src/render/picking/raycaster.cpp5
-rw-r--r--tests/auto/render/aspect/aspect.pro12
-rw-r--r--tests/auto/render/aspect/tst_aspect.cpp189
-rw-r--r--tests/auto/render/commons/commons.pri2
-rw-r--r--tests/auto/render/commons/testaspect.cpp5
-rw-r--r--tests/auto/render/commons/testaspect.h1
-rw-r--r--tests/auto/render/commons/testrenderer.cpp4
-rw-r--r--tests/auto/render/commons/testrenderer.h20
-rw-r--r--tests/auto/render/opengl/renderer/renderer.pro3
-rw-r--r--tests/auto/render/opengl/renderer/tst_renderer.cpp67
-rw-r--r--tests/auto/render/opengl/renderviewbuilder/tst_renderviewbuilder.cpp24
-rw-r--r--tests/auto/render/render.pro1
-rw-r--r--tests/benchmarks/render/jobs/tst_bench_jobs.cpp18
22 files changed, 535 insertions, 327 deletions
diff --git a/src/plugins/renderers/opengl/renderer/renderer.cpp b/src/plugins/renderers/opengl/renderer/renderer.cpp
index 007bf1be0..9dffba30b 100644
--- a/src/plugins/renderers/opengl/renderer/renderer.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderer.cpp
@@ -67,7 +67,6 @@
#include <Qt3DRender/private/techniquefilternode_p.h>
#include <Qt3DRender/private/viewportnode_p.h>
#include <Qt3DRender/private/vsyncframeadvanceservice_p.h>
-#include <Qt3DRender/private/pickeventfilter_p.h>
#include <Qt3DRender/private/managers_p.h>
#include <Qt3DRender/private/buffermanager_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
@@ -83,12 +82,12 @@
#include <Qt3DRender/private/qshaderprogrambuilder_p.h>
#include <Qt3DRender/private/qshaderprogram_p.h>
#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
+#include <Qt3DRender/private/qrenderaspect_p.h>
#ifndef Q_OS_INTEGRITY
#include <imguirenderer_p.h>
#endif
#include <Qt3DRender/qcameralens.h>
-#include <Qt3DCore/private/qeventfilterservice_p.h>
#include <Qt3DCore/private/qabstractaspectjobmanager_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DCore/private/qsysteminformationservice_p.h>
@@ -121,6 +120,8 @@
#include <QOffscreenSurface>
#include <QWindow>
#include <QThread>
+#include <QKeyEvent>
+#include <QMouseEvent>
#include <QtGui/private/qopenglcontext_p.h>
#include "frameprofiler_p.h"
@@ -232,6 +233,7 @@ private:
Renderer::Renderer(QRenderAspect::RenderType type)
: m_services(nullptr)
+ , m_aspect(nullptr)
, m_nodesManager(nullptr)
, m_renderSceneRoot(nullptr)
, m_defaultRenderStateSet(nullptr)
@@ -241,28 +243,16 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr))
, m_waitForInitializationToBeCompleted(0)
, m_hasBeenInitializedMutex()
- , m_pickEventFilter(new PickEventFilter())
, m_exposed(0)
, m_lastFrameCorrect(0)
, m_glContext(nullptr)
, m_shareContext(nullptr)
- , m_pickBoundingVolumeJob(PickBoundingVolumeJobPtr::create())
- , m_rayCastingJob(RayCastingJobPtr::create())
, m_time(0)
, m_settings(nullptr)
, m_updateShaderDataTransformJob(Render::UpdateShaderDataTransformJobPtr::create())
, m_cleanupJob(Render::FrameCleanupJobPtr::create())
- , m_worldTransformJob(Render::UpdateWorldTransformJobPtr::create())
- , m_expandBoundingVolumeJob(Render::ExpandBoundingVolumeJobPtr::create())
- , m_calculateBoundingVolumeJob(Render::CalculateBoundingVolumeJobPtr::create())
- , m_updateWorldBoundingVolumeJob(Render::UpdateWorldBoundingVolumeJobPtr::create())
- , m_updateTreeEnabledJob(Render::UpdateTreeEnabledJobPtr::create())
, m_sendBufferCaptureJob(Render::SendBufferCaptureJobPtr::create())
- , m_updateSkinningPaletteJob(Render::UpdateSkinningPaletteJobPtr::create())
- , m_updateLevelOfDetailJob(Render::UpdateLevelOfDetailJobPtr::create())
- , m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create())
, m_filterCompatibleTechniqueJob(FilterCompatibleTechniqueJobPtr::create())
- , m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create())
, m_lightGathererJob(Render::LightGathererPtr::create())
, m_renderableEntityFilterJob(Render::RenderableEntityFilterPtr::create())
, m_computableEntityFilterJob(Render::ComputableEntityFilterPtr::create())
@@ -273,7 +263,6 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_introspectShaderJob(CreateSynchronizerPostFramePtr([this] { reloadDirtyShaders(); },
[this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); },
JobTypes::DirtyShaderGathering))
- , m_syncLoadingJobs(CreateSynchronizerJobPtr([] {}, JobTypes::SyncLoadingJobs))
, m_cacheRenderableEntitiesJob(CreateSynchronizerJobPtr(SyncRenderableEntities(m_renderableEntityFilterJob, &m_cache),
JobTypes::EntityComponentTypeFiltering))
, m_cacheComputableEntitiesJob(CreateSynchronizerJobPtr(SyncComputableEntities(m_computableEntityFilterJob, &m_cache),
@@ -294,25 +283,6 @@ Renderer::Renderer(QRenderAspect::RenderType type)
if (m_renderThread)
m_renderThread->waitForStart();
- // Create jobs to update transforms and bounding volumes
- // We can only update bounding volumes once all world transforms are known
- m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob);
- m_updateWorldBoundingVolumeJob->addDependency(m_calculateBoundingVolumeJob);
- m_expandBoundingVolumeJob->addDependency(m_updateWorldBoundingVolumeJob);
- m_updateShaderDataTransformJob->addDependency(m_worldTransformJob);
- m_updateLevelOfDetailJob->addDependency(m_expandBoundingVolumeJob);
- m_pickBoundingVolumeJob->addDependency(m_expandBoundingVolumeJob);
- m_rayCastingJob->addDependency(m_expandBoundingVolumeJob);
- // m_calculateBoundingVolumeJob's dependency on m_updateTreeEnabledJob is set in renderBinJobs
-
- // Ensures all skeletons are loaded before we try to update them
- m_updateSkinningPaletteJob->addDependency(m_syncLoadingJobs);
-
- // All world stuff depends on the RenderEntity's localBoundingVolume
- m_updateLevelOfDetailJob->addDependency(m_updateMeshTriangleListJob);
- m_pickBoundingVolumeJob->addDependency(m_updateMeshTriangleListJob);
- m_rayCastingJob->addDependency(m_updateMeshTriangleListJob);
-
m_introspectShaderJob->addDependency(m_filterCompatibleTechniqueJob);
m_cacheLightsJob->addDependency(m_lightGathererJob);
@@ -377,6 +347,12 @@ void Renderer::setJobsInLastFrame(int jobsInLastFrame)
m_jobsInLastFrame = jobsInLastFrame;
}
+void Renderer::setAspect(QRenderAspect *aspect)
+{
+ m_aspect = aspect;
+ m_updateShaderDataTransformJob->addDependency(QRenderAspectPrivate::get(aspect)->m_worldTransformJob);
+}
+
void Renderer::setNodeManagers(NodeManagers *managers)
{
m_nodesManager = managers;
@@ -385,18 +361,7 @@ void Renderer::setNodeManagers(NodeManagers *managers)
m_updateShaderDataTransformJob->setManagers(m_nodesManager);
m_cleanupJob->setManagers(m_nodesManager);
- m_calculateBoundingVolumeJob->setManagers(m_nodesManager);
- m_expandBoundingVolumeJob->setManagers(m_nodesManager);
- m_worldTransformJob->setManagers(m_nodesManager);
- m_pickBoundingVolumeJob->setManagers(m_nodesManager);
- m_rayCastingJob->setManagers(m_nodesManager);
- m_updateWorldBoundingVolumeJob->setManager(m_nodesManager->renderNodesManager());
- m_updateLevelOfDetailJob->setManagers(m_nodesManager);
- m_updateSkinningPaletteJob->setManagers(m_nodesManager);
- m_updateMeshTriangleListJob->setManagers(m_nodesManager);
m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager());
- m_updateEntityLayersJob->setManager(m_nodesManager);
- m_updateTreeEnabledJob->setManagers(m_nodesManager);
m_sendBufferCaptureJob->setManagers(m_nodesManager);
m_lightGathererJob->setManager(m_nodesManager->renderNodesManager());
m_renderableEntityFilterJob->setManager(m_nodesManager->renderNodesManager());
@@ -410,6 +375,11 @@ void Renderer::setServices(QServiceLocator *services)
m_nodesManager->sceneManager()->setDownloadService(m_services->downloadHelperService());
}
+QRenderAspect *Renderer::aspect() const
+{
+ return m_aspect;
+}
+
NodeManagers *Renderer::nodeManagers() const
{
return m_nodesManager;
@@ -716,26 +686,12 @@ void Renderer::setSceneRoot(Entity *sgRoot)
qCDebug(Backend) << Q_FUNC_INFO << "DUMPING SCENE";
// Set the scene root on the jobs
- m_worldTransformJob->setRoot(m_renderSceneRoot);
- m_expandBoundingVolumeJob->setRoot(m_renderSceneRoot);
- m_calculateBoundingVolumeJob->setRoot(m_renderSceneRoot);
m_cleanupJob->setRoot(m_renderSceneRoot);
- m_pickBoundingVolumeJob->setRoot(m_renderSceneRoot);
- m_rayCastingJob->setRoot(m_renderSceneRoot);
- m_updateLevelOfDetailJob->setRoot(m_renderSceneRoot);
- m_updateSkinningPaletteJob->setRoot(m_renderSceneRoot);
- m_updateTreeEnabledJob->setRoot(m_renderSceneRoot);
// Set all flags to dirty
m_dirtyBits.marked |= AbstractRenderer::AllDirty;
}
-void Renderer::registerEventFilter(QEventFilterService *service)
-{
- qCDebug(Backend) << Q_FUNC_INFO << QThread::currentThread();
- service->registerEventFilter(m_pickEventFilter.data(), 1024);
-}
-
void Renderer::setSettings(RenderSettings *settings)
{
m_settings = settings;
@@ -1877,27 +1833,16 @@ void Renderer::jobsDone(Qt3DCore::QAspectManager *manager)
sendDisablesToFrontend(manager);
}
+void Renderer::setPendingEvents(const QList<QPair<QObject *, QMouseEvent> > &mouseEvents, const QList<QKeyEvent> &keyEvents)
+{
+ QMutexLocker l(&m_frameEventsMutex);
+ m_frameMouseEvents = mouseEvents;
+ m_frameKeyEvents = keyEvents;
+}
+
// Jobs we may have to run even if no rendering will happen
QVector<QAspectJobPtr> Renderer::preRenderingJobs()
{
- {
- QMutexLocker l(&m_frameEventsMutex);
- m_frameMouseEvents = m_pickEventFilter->pendingMouseEvents();
- m_frameKeyEvents = m_pickEventFilter->pendingKeyEvents();
- }
-
- // Set values on picking jobs
- RenderSettings *renderSetting = settings();
- if (renderSetting != nullptr) {
- m_pickBoundingVolumeJob->setRenderSettings(renderSetting);
- m_pickBoundingVolumeJob->setFrameGraphRoot(frameGraphRoot());
- m_pickBoundingVolumeJob->setMouseEvents(m_frameMouseEvents);
- m_pickBoundingVolumeJob->setKeyEvents(m_frameKeyEvents);
-
- m_rayCastingJob->setRenderSettings(renderSetting);
- m_rayCastingJob->setFrameGraphRoot(frameGraphRoot());
- }
-
QVector<QAspectJobPtr> jobs;
// Do we need to notify frontend about fence change?
@@ -1907,9 +1852,6 @@ QVector<QAspectJobPtr> Renderer::preRenderingJobs()
if (m_sendBufferCaptureJob->hasRequests())
jobs.push_back(m_sendBufferCaptureJob);
- jobs.append(pickBoundingVolumeJob());
- jobs.append(rayCastingJob());
-
return jobs;
}
@@ -1920,57 +1862,21 @@ QVector<QAspectJobPtr> Renderer::preRenderingJobs()
QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
{
QVector<QAspectJobPtr> renderBinJobs;
- // Create the jobs to build the frame
- const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs();
// Remove previous dependencies
- m_calculateBoundingVolumeJob->removeDependency(QWeakPointer<QAspectJob>());
m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>());
- // Set dependencies
- for (const QAspectJobPtr &bufferJob : bufferJobs)
- m_calculateBoundingVolumeJob->addDependency(bufferJob);
-
- m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot());
-
const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
m_dirtyBits.marked = {};
m_dirtyBits.remaining = {};
BackendNodeDirtySet notCleared = {};
// Add jobs
- const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
- if (entitiesEnabledDirty) {
- renderBinJobs.push_back(m_updateTreeEnabledJob);
- // This dependency is added here because we clear all dependencies
- // at the start of this function.
- m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
- }
-
- if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
- renderBinJobs.push_back(m_worldTransformJob);
- renderBinJobs.push_back(m_updateWorldBoundingVolumeJob);
+ if (dirtyBitsForFrame & AbstractRenderer::TransformDirty)
renderBinJobs.push_back(m_updateShaderDataTransformJob);
- }
-
- if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
- dirtyBitsForFrame & AbstractRenderer::BuffersDirty) {
- renderBinJobs.push_back(m_calculateBoundingVolumeJob);
- renderBinJobs.push_back(m_updateMeshTriangleListJob);
- }
-
- if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
- dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
- renderBinJobs.push_back(m_expandBoundingVolumeJob);
- }
// TO DO: Conditionally add if skeletons dirty
- renderBinJobs.push_back(m_syncLoadingJobs);
- m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints());
- renderBinJobs.push_back(m_updateSkinningPaletteJob);
- renderBinJobs.push_back(m_updateLevelOfDetailJob);
renderBinJobs.push_back(m_cleanupJob);
- renderBinJobs.append(bufferJobs);
// Jobs to prepare GL Resource upload
renderBinJobs.push_back(m_vaoGathererJob);
@@ -1981,9 +1887,9 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty)
renderBinJobs.push_back(m_textureGathererJob);
-
// Layer cache is dependent on layers, layer filters (hence FG structure
// changes) and the enabled flag on entities
+ const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
const bool frameGraphDirty = dirtyBitsForFrame & AbstractRenderer::FrameGraphDirty;
const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty;
const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty || frameGraphDirty;
@@ -1995,10 +1901,6 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
const bool materialCacheNeedsToBeRebuilt = shadersDirty || materialDirty || frameGraphDirty;
const bool renderCommandsDirty = materialCacheNeedsToBeRebuilt || renderableDirty || computeableDirty;
- // Rebuild Entity Layers list if layers are dirty
- if (layersDirty)
- renderBinJobs.push_back(m_updateEntityLayersJob);
-
if (renderableDirty) {
renderBinJobs.push_back(m_renderableEntityFilterJob);
renderBinJobs.push_back(m_cacheRenderableEntitiesJob);
@@ -2057,8 +1959,8 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// FilterLayerEntityJob is part of the RenderViewBuilder jobs and must be run later
// if none of those jobs are started this frame
notCleared |= AbstractRenderer::EntityEnabledDirty;
- notCleared |= AbstractRenderer::FrameGraphDirty;
notCleared |= AbstractRenderer::LayersDirty;
+ notCleared |= AbstractRenderer::FrameGraphDirty;
}
if (isRunning() && m_submissionContext->isInitialized()) {
@@ -2076,26 +1978,6 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
return renderBinJobs;
}
-QAspectJobPtr Renderer::pickBoundingVolumeJob()
-{
- return m_pickBoundingVolumeJob;
-}
-
-QAspectJobPtr Renderer::rayCastingJob()
-{
- return m_rayCastingJob;
-}
-
-QAspectJobPtr Renderer::syncLoadingJobs()
-{
- return m_syncLoadingJobs;
-}
-
-QAspectJobPtr Renderer::expandBoundingVolumeJob()
-{
- return m_expandBoundingVolumeJob;
-}
-
QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const
{
return static_cast<Qt3DCore::QAbstractFrameAdvanceService *>(m_vsyncFrameAdvanceService.data());
@@ -2454,27 +2336,6 @@ SubmissionContext *Renderer::submissionContext() const
return m_submissionContext.data();
}
-// 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() const
-{
- const QVector<QNodeId> dirtyBuffers = m_nodesManager->bufferManager()->takeDirtyBuffers();
- QVector<QAspectJobPtr> dirtyBuffersJobs;
- dirtyBuffersJobs.reserve(dirtyBuffers.size());
-
- for (const QNodeId bufId : dirtyBuffers) {
- Render::HBuffer bufferHandle = m_nodesManager->lookupHandle<Render::Buffer, Render::BufferManager, Render::HBuffer>(bufId);
- if (!bufferHandle.isNull()) {
- // Create new buffer job
- auto job = Render::LoadBufferJobPtr::create(bufferHandle);
- job->setNodeManager(m_nodesManager);
- dirtyBuffersJobs.push_back(job);
- }
- }
-
- return dirtyBuffersJobs;
-}
-
} // namespace OpenGL
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/plugins/renderers/opengl/renderer/renderer_p.h b/src/plugins/renderers/opengl/renderer/renderer_p.h
index cf76e1b8a..a285659b5 100644
--- a/src/plugins/renderers/opengl/renderer/renderer_p.h
+++ b/src/plugins/renderers/opengl/renderer/renderer_p.h
@@ -58,22 +58,12 @@
#include <Qt3DRender/private/abstractrenderer_p.h>
#include <Qt3DCore/qaspectjob.h>
#include <Qt3DRender/private/qt3drender_global_p.h>
-#include <Qt3DRender/private/pickboundingvolumejob_p.h>
-#include <Qt3DRender/private/raycastingjob_p.h>
#include <Qt3DRender/private/rendersettings_p.h>
-#include <Qt3DRender/private/expandboundingvolumejob_p.h>
-#include <Qt3DRender/private/updateworldtransformjob_p.h>
-#include <Qt3DRender/private/calcboundingvolumejob_p.h>
#include <Qt3DRender/private/updateshaderdatatransformjob_p.h>
#include <Qt3DRender/private/framecleanupjob_p.h>
-#include <Qt3DRender/private/updateworldboundingvolumejob_p.h>
-#include <Qt3DRender/private/updatetreeenabledjob_p.h>
#include <Qt3DRender/private/platformsurfacefilter_p.h>
#include <Qt3DRender/private/sendbuffercapturejob_p.h>
#include <Qt3DRender/private/genericlambdajob_p.h>
-#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h>
-#include <Qt3DRender/private/updateskinningpalettejob_p.h>
-#include <Qt3DRender/private/updateentitylayersjob_p.h>
#include <Qt3DRender/private/shaderbuilder_p.h>
#include <Qt3DRender/private/lightgatherer_p.h>
#include <Qt3DRender/private/texture_p.h>
@@ -149,7 +139,6 @@ class RenderPass;
class RenderThread;
class RenderStateSet;
class VSyncFrameAdvanceService;
-class PickEventFilter;
class NodeManagers;
class ResourceAccessor;
@@ -195,10 +184,12 @@ public:
void setTime(qint64 time) override;
void setJobsInLastFrame(int jobsInLastFrame) override;
+ void setAspect(QRenderAspect *aspect) override;
void setNodeManagers(NodeManagers *managers) override;
void setServices(Qt3DCore::QServiceLocator *services) override;
void setSurfaceExposed(bool exposed) override;
+ QRenderAspect *aspect() const override;
NodeManagers *nodeManagers() const override;
Qt3DCore::QServiceLocator *services() const override { return m_services; }
@@ -228,30 +219,17 @@ public:
void skipNextFrame() override;
void jobsDone(Qt3DCore::QAspectManager *manager) override;
+ void setPendingEvents(const QList<QPair<QObject *, QMouseEvent>> &mouseEvents, const QList<QKeyEvent> &keyEvents) override;
+
QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override;
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override;
- Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override;
- Qt3DCore::QAspectJobPtr rayCastingJob() override;
- Qt3DCore::QAspectJobPtr syncLoadingJobs() override;
- Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override;
-
- QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const;
inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; }
inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; }
- inline CalculateBoundingVolumeJobPtr calculateBoundingVolumeJob() const { return m_calculateBoundingVolumeJob; }
- inline UpdateTreeEnabledJobPtr updateTreeEnabledJob() const { return m_updateTreeEnabledJob; }
- inline UpdateWorldTransformJobPtr updateWorldTransformJob() const { return m_worldTransformJob; }
- inline UpdateWorldBoundingVolumeJobPtr updateWorldBoundingVolumeJob() const { return m_updateWorldBoundingVolumeJob; }
- inline UpdateLevelOfDetailJobPtr updateLevelOfDetailJob() const { return m_updateLevelOfDetailJob; }
- inline UpdateMeshTriangleListJobPtr updateMeshTriangleListJob() const { return m_updateMeshTriangleListJob; }
inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; }
- inline SynchronizerJobPtr syncLoadingJobs() const { return m_syncLoadingJobs; }
- inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; }
inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; }
inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; }
inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; }
- inline UpdateEntityLayersJobPtr updateEntityLayersJob() const { return m_updateEntityLayersJob; }
inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; }
inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; }
inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; }
@@ -261,8 +239,6 @@ public:
Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override;
- void registerEventFilter(Qt3DCore::QEventFilterService *service) override;
-
void setSettings(RenderSettings *settings) override;
RenderSettings *settings() const override;
QOpenGLContext *shareContext() const override;
@@ -331,7 +307,6 @@ public:
RendererCache *cache() { return &m_cache; }
void setScreen(QScreen *scr) override;
QScreen *screen() const override;
- NodeManagers *nodesManager() const { return m_nodesManager; }
#ifdef QT3D_RENDER_UNIT_TESTS
public:
@@ -343,6 +318,7 @@ private:
Profiling::FrameProfiler *activeProfiler() const;
Qt3DCore::QServiceLocator *m_services;
+ QRenderAspect *m_aspect;
NodeManagers *m_nodesManager;
// Frame graph root
@@ -368,8 +344,6 @@ private:
QAtomicInt m_running;
- QScopedPointer<PickEventFilter> m_pickEventFilter;
-
QVector<Attribute *> m_dirtyAttributes;
QVector<Geometry *> m_dirtyGeometry;
QAtomicInt m_exposed;
@@ -384,8 +358,6 @@ private:
QOpenGLContext *m_glContext;
QOpenGLContext *m_shareContext;
mutable QMutex m_shareContextMutex;
- PickBoundingVolumeJobPtr m_pickBoundingVolumeJob;
- RayCastingJobPtr m_rayCastingJob;
qint64 m_time;
@@ -393,17 +365,8 @@ private:
UpdateShaderDataTransformJobPtr m_updateShaderDataTransformJob;
FrameCleanupJobPtr m_cleanupJob;
- UpdateWorldTransformJobPtr m_worldTransformJob;
- ExpandBoundingVolumeJobPtr m_expandBoundingVolumeJob;
- CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob;
- UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob;
- UpdateTreeEnabledJobPtr m_updateTreeEnabledJob;
SendBufferCaptureJobPtr m_sendBufferCaptureJob;
- UpdateSkinningPaletteJobPtr m_updateSkinningPaletteJob;
- UpdateLevelOfDetailJobPtr m_updateLevelOfDetailJob;
- UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob;
FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob;
- UpdateEntityLayersJobPtr m_updateEntityLayersJob;
LightGathererPtr m_lightGathererJob;
RenderableEntityFilterPtr m_renderableEntityFilterJob;
ComputableEntityFilterPtr m_computableEntityFilterJob;
@@ -421,7 +384,6 @@ private:
SynchronizerJobPtr m_textureGathererJob;
SynchronizerJobPtr m_sendSetFenceHandlesToFrontendJob;
SynchronizerPostFramePtr m_introspectShaderJob;
- SynchronizerJobPtr m_syncLoadingJobs;
SynchronizerJobPtr m_cacheRenderableEntitiesJob;
SynchronizerJobPtr m_cacheComputableEntitiesJob;
SynchronizerJobPtr m_cacheLightsJob;
diff --git a/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp b/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp
index a80fbe445..7264064f6 100644
--- a/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "renderviewbuilder_p.h"
+#include <Qt3DRender/private/qrenderaspect_p.h>
#include <QThread>
@@ -637,6 +638,12 @@ void RenderViewBuilder::prepareJobs()
QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
{
QVector<Qt3DCore::QAspectJobPtr> jobs;
+ auto daspect = QRenderAspectPrivate::get(m_renderer->aspect());
+ auto expandBVJob = daspect->m_expandBoundingVolumeJob;
+ auto wordTransformJob = daspect->m_worldTransformJob;
+ auto updateTreeEnabledJob = daspect->m_updateTreeEnabledJob;
+ auto updateSkinningPaletteJob = daspect->m_updateSkinningPaletteJob;
+ auto updateEntityLayersJob = daspect->m_updateEntityLayersJob;
jobs.reserve(m_materialGathererJobs.size() + m_renderViewCommandUpdaterJobs.size() + 11);
@@ -644,20 +651,20 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
// 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_renderViewJob->addDependency(updateSkinningPaletteJob);
- m_syncPreFrustumCullingJob->addDependency(m_renderer->updateWorldTransformJob());
+ m_syncPreFrustumCullingJob->addDependency(wordTransformJob);
m_syncPreFrustumCullingJob->addDependency(m_renderer->updateShaderDataTransformJob());
m_syncPreFrustumCullingJob->addDependency(m_syncRenderViewPostInitializationJob);
- m_frustumCullingJob->addDependency(m_renderer->expandBoundingVolumeJob());
+ m_frustumCullingJob->addDependency(expandBVJob);
m_frustumCullingJob->addDependency(m_syncPreFrustumCullingJob);
m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewPostInitializationJob);
m_syncRenderViewPostInitializationJob->addDependency(m_renderViewJob);
- m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob());
+ m_filterProximityJob->addDependency(expandBVJob);
m_filterProximityJob->addDependency(m_syncRenderViewPostInitializationJob);
m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncRenderViewPostInitializationJob);
@@ -702,9 +709,9 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
}
if (m_layerCacheNeedsToBeRebuilt) {
- m_filterEntityByLayerJob->addDependency(m_renderer->updateEntityLayersJob());
+ m_filterEntityByLayerJob->addDependency(updateEntityLayersJob);
m_filterEntityByLayerJob->addDependency(m_syncRenderViewPostInitializationJob);
- m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob());
+ m_filterEntityByLayerJob->addDependency(updateTreeEnabledJob);
m_syncFilterEntityByLayerJob->addDependency(m_filterEntityByLayerJob);
m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncFilterEntityByLayerJob);
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index 4e25d627f..020aa6c9f 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -66,6 +66,8 @@ class QSurface;
class QSize;
class QScreen;
class QOpenGLTexture;
+class QMouseEvent;
+class QKeyEvent;
namespace Qt3DCore {
class QAbstractFrameAdvanceService;
@@ -130,10 +132,12 @@ public:
virtual void setTime(qint64 time) = 0;
virtual void setJobsInLastFrame(int jobsInLastFrame) = 0;
+ virtual void setAspect(QRenderAspect *aspect) = 0;
virtual void setNodeManagers(NodeManagers *managers) = 0;
virtual void setServices(Qt3DCore::QServiceLocator *services) = 0;
virtual void setSurfaceExposed(bool exposed) = 0;
+ virtual QRenderAspect *aspect() const = 0;
virtual NodeManagers *nodeManagers() const = 0;
virtual Qt3DCore::QServiceLocator *services() const = 0;
@@ -159,12 +163,10 @@ public:
virtual void skipNextFrame() = 0;
virtual void jobsDone(Qt3DCore::QAspectManager *manager) = 0;
+ virtual void setPendingEvents(const QList<QPair<QObject *, QMouseEvent>> &mouseEvents, const QList<QKeyEvent> &keyEvents) = 0;
+
virtual QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() = 0;
virtual QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() = 0;
- virtual Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() = 0;
- virtual Qt3DCore::QAspectJobPtr rayCastingJob() = 0;
- virtual Qt3DCore::QAspectJobPtr syncLoadingJobs() = 0;
- virtual Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() = 0;
virtual void setSceneRoot(Entity *root) = 0;
@@ -172,7 +174,6 @@ public:
virtual FrameGraphNode *frameGraphRoot() const = 0;
virtual Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const = 0;
- virtual void registerEventFilter(Qt3DCore::QEventFilterService *service) = 0;
virtual void setSettings(RenderSettings *settings) = 0;
virtual RenderSettings *settings() const = 0;
diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp
index ab74e8b56..a4a5dfabd 100644
--- a/src/render/backend/cameralens.cpp
+++ b/src/render/backend/cameralens.cpp
@@ -48,6 +48,7 @@
#include <Qt3DRender/private/sphere_p.h>
#include <Qt3DRender/private/computefilteredboundingvolumejob_p.h>
#include <Qt3DRender/private/renderlogging_p.h>
+#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
@@ -167,7 +168,7 @@ void CameraLens::computeSceneBoundingVolume(QNodeId entityId,
Entity *camNode = nodeManagers->renderNodesManager()->lookupResource(cameraId);
ComputeFilteredBoundingVolumeJobPtr job(new GetBoundingVolumeWithoutCameraJob(this, requestId));
- job->addDependency(m_renderer->expandBoundingVolumeJob());
+ job->addDependency(QRenderAspectPrivate::get(m_renderer->aspect())->m_expandBoundingVolumeJob);
job->setRoot(root);
job->setManagers(nodeManagers);
job->ignoreSubTree(camNode);
diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp
index 9e78bc96f..e9e40e34a 100644
--- a/src/render/backend/transform.cpp
+++ b/src/render/backend/transform.cpp
@@ -105,6 +105,9 @@ void Transform::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
markDirty(AbstractRenderer::TransformDirty);
}
+ if (transform->isEnabled() != isEnabled())
+ markDirty(AbstractRenderer::TransformDirty);
+
BackendNode::syncFromFrontEnd(frontEnd, firstTime);
}
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index a06032899..9d5058ec8 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -163,12 +163,15 @@
#include <Qt3DRender/private/waitfence_p.h>
#include <Qt3DRender/private/shaderimage_p.h>
#include <Qt3DRender/private/debugoverlay_p.h>
+#include <Qt3DRender/private/qrendererpluginfactory_p.h>
+#include <Qt3DRender/private/updatelevelofdetailjob_p.h>
+#include <Qt3DRender/private/job_common_p.h>
+#include <Qt3DRender/private/pickeventfilter_p.h>
+#include <Qt3DRender/private/loadbufferjob_p.h>
#include <private/qrenderpluginfactory_p.h>
#include <private/qrenderplugin_p.h>
-#include <Qt3DRender/private/qrendererpluginfactory_p.h>
-
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
@@ -178,6 +181,7 @@
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/private/qentity_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
+#include <Qt3DCore/private/qeventfilterservice_p.h>
#include <QThread>
#include <QOpenGLContext>
@@ -188,6 +192,9 @@ using namespace Qt3DCore;
namespace Qt3DRender {
+#define CreateSynchronizerJobPtr(lambda, type) \
+ Render::SynchronizerJobPtr::create(lambda, type, #type)
+
/*!
* \class Qt3DRender::QRenderAspect
* \inheaderfile Qt3DRender/QRenderAspect
@@ -212,6 +219,18 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
, m_renderAfterJobs(false)
, m_renderType(type)
, m_offscreenHelper(nullptr)
+ , m_updateTreeEnabledJob(Render::UpdateTreeEnabledJobPtr::create())
+ , m_worldTransformJob(Render::UpdateWorldTransformJobPtr::create())
+ , m_expandBoundingVolumeJob(Render::ExpandBoundingVolumeJobPtr::create())
+ , m_calculateBoundingVolumeJob(Render::CalculateBoundingVolumeJobPtr::create())
+ , m_updateWorldBoundingVolumeJob(Render::UpdateWorldBoundingVolumeJobPtr::create())
+ , m_updateSkinningPaletteJob(Render::UpdateSkinningPaletteJobPtr::create())
+ , m_updateLevelOfDetailJob(Render::UpdateLevelOfDetailJobPtr::create())
+ , m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create())
+ , m_syncLoadingJobs(CreateSynchronizerJobPtr([] {}, Render::JobTypes::SyncLoadingJobs))
+ , m_pickBoundingVolumeJob(Render::PickBoundingVolumeJobPtr::create())
+ , m_rayCastingJob(Render::RayCastingJobPtr::create())
+ , m_pickEventFilter(new Render::PickEventFilter())
{
m_instances.append(this);
loadSceneParsers();
@@ -219,6 +238,11 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
m_renderType = QRenderAspect::Synchronous;
m_renderAfterJobs = true;
}
+
+ m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob);
+ m_updateWorldBoundingVolumeJob->addDependency(m_calculateBoundingVolumeJob);
+ m_expandBoundingVolumeJob->addDependency(m_updateWorldBoundingVolumeJob);
+ m_updateLevelOfDetailJob->addDependency(m_expandBoundingVolumeJob);
}
/*! \internal */
@@ -245,6 +269,11 @@ QRenderAspectPrivate *QRenderAspectPrivate::findPrivate(Qt3DCore::QAspectEngine
return nullptr;
}
+QRenderAspectPrivate *QRenderAspectPrivate::get(QRenderAspect *q)
+{
+ return q->d_func();
+}
+
void QRenderAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const
{
Render::BackendNode *renderBackend = static_cast<Render::BackendNode *>(backend);
@@ -263,6 +292,41 @@ void QRenderAspectPrivate::frameDone()
m_renderer->doRender(true);
}
+void QRenderAspectPrivate::createNodeManagers()
+{
+ m_nodeManagers = new Render::NodeManagers();
+
+ m_updateTreeEnabledJob->setManagers(m_nodeManagers);
+ m_worldTransformJob->setManagers(m_nodeManagers);
+ m_expandBoundingVolumeJob->setManagers(m_nodeManagers);
+ m_calculateBoundingVolumeJob->setManagers(m_nodeManagers);
+ m_updateWorldBoundingVolumeJob->setManager(m_nodeManagers->renderNodesManager());
+ m_updateSkinningPaletteJob->setManagers(m_nodeManagers);
+ m_updateLevelOfDetailJob->setManagers(m_nodeManagers);
+ m_updateEntityLayersJob->setManager(m_nodeManagers);
+ m_pickBoundingVolumeJob->setManagers(m_nodeManagers);
+ m_rayCastingJob->setManagers(m_nodeManagers);
+}
+
+void QRenderAspectPrivate::onEngineStartup()
+{
+ Render::Entity *rootEntity = m_nodeManagers->lookupResource<Render::Entity, Render::EntityManager>(m_rootId);
+ Q_ASSERT(rootEntity);
+ m_renderer->setSceneRoot(rootEntity);
+
+ m_worldTransformJob->setRoot(rootEntity);
+ m_expandBoundingVolumeJob->setRoot(rootEntity);
+ m_calculateBoundingVolumeJob->setRoot(rootEntity);
+ m_updateLevelOfDetailJob->setRoot(rootEntity);
+ m_updateSkinningPaletteJob->setRoot(rootEntity);
+ m_updateTreeEnabledJob->setRoot(rootEntity);
+ m_pickBoundingVolumeJob->setRoot(rootEntity);
+ m_rayCastingJob->setRoot(rootEntity);
+
+ // Ensures all skeletons are loaded before we try to update them
+ m_updateSkinningPaletteJob->addDependency(m_syncLoadingJobs);
+}
+
/*! \internal */
void QRenderAspectPrivate::registerBackendTypes()
{
@@ -490,6 +554,8 @@ void QRenderAspectPrivate::renderShutdown()
QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
{
+ using namespace Render;
+
Q_D(QRenderAspect);
d->m_renderer->setTime(time);
@@ -513,10 +579,10 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
// 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()) {
-
- Render::NodeManagers *manager = d->m_renderer->nodeManagers();
- QAspectJobPtr loadingJobSync = d->m_renderer->syncLoadingJobs();
- loadingJobSync->removeDependency(QWeakPointer<QAspectJob>());
+ NodeManagers *manager = d->m_nodeManagers;
+ d->m_syncLoadingJobs->removeDependency(QWeakPointer<QAspectJob>());
+ d->m_calculateBoundingVolumeJob->removeDependency(QWeakPointer<QAspectJob>());
+ d->m_updateLevelOfDetailJob->setFrameGraphRoot(d->m_renderer->frameGraphRoot());
// Launch skeleton loader jobs once all loading jobs have completed.
const QVector<Render::HSkeleton> skeletonsToLoad =
@@ -524,7 +590,7 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
for (const auto &skeletonHandle : skeletonsToLoad) {
auto loadSkeletonJob = Render::LoadSkeletonJobPtr::create(skeletonHandle);
loadSkeletonJob->setNodeManagers(manager);
- loadingJobSync->addDependency(loadSkeletonJob);
+ d->m_syncLoadingJobs->addDependency(loadSkeletonJob);
jobs.append(loadSkeletonJob);
}
@@ -541,9 +607,6 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
const QVector<QAspectJobPtr> geometryJobs = d->createGeometryRendererJobs();
jobs.append(geometryJobs);
- const QVector<QAspectJobPtr> preRenderingJobs = d->m_renderer->preRenderingJobs();
- jobs.append(preRenderingJobs);
-
// Don't spawn any rendering jobs, if the renderer decides to skip this frame
// Note: this only affects rendering jobs (jobs that load buffers,
// perform picking,... must still be run)
@@ -557,9 +620,56 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
// RenderBins with RenderCommands
// All jobs needed to create the frame and their dependencies are set by
// renderBinJobs()
+
+ const AbstractRenderer::BackendNodeDirtySet dirtyBitsForFrame = d->m_renderer->dirtyBits();
+
+ // Create the jobs to build the frame
+ const QVector<QAspectJobPtr> bufferJobs = d->createRenderBufferJobs();
+ for (const QAspectJobPtr &bufferJob : bufferJobs)
+ d->m_calculateBoundingVolumeJob->addDependency(bufferJob);
+ jobs.append(bufferJobs);
+
+ const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
+ if (entitiesEnabledDirty) {
+ jobs.push_back(d->m_updateTreeEnabledJob);
+ // This dependency is added here because we clear all dependencies
+ // at the start of this function.
+ d->m_calculateBoundingVolumeJob->addDependency(d->m_updateTreeEnabledJob);
+ }
+
+ if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
+ jobs.push_back(d->m_worldTransformJob);
+ jobs.push_back(d->m_updateWorldBoundingVolumeJob);
+ }
+
+ if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
+ dirtyBitsForFrame & AbstractRenderer::BuffersDirty) {
+ jobs.push_back(d->m_calculateBoundingVolumeJob);
+ }
+
+ if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
+ dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
+ jobs.push_back(d->m_expandBoundingVolumeJob);
+ }
+
+ // TO DO: Conditionally add if skeletons dirty
+ jobs.push_back(d->m_syncLoadingJobs);
+ d->m_updateSkinningPaletteJob->setDirtyJoints(manager->jointManager()->dirtyJoints());
+ jobs.push_back(d->m_updateSkinningPaletteJob);
+ jobs.push_back(d->m_updateLevelOfDetailJob);
+
+ // Rebuild Entity Layers list if layers are dirty
+ const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty;
+ if (layersDirty)
+ jobs.push_back(d->m_updateEntityLayersJob);
+
+ const QVector<QAspectJobPtr> preRenderingJobs = d->createPreRendererJobs();
+ jobs.append(preRenderingJobs);
+
const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
jobs.append(renderBinJobs);
}
+
return jobs;
}
@@ -589,10 +699,7 @@ void QRenderAspect::onEngineStartup()
Q_D(QRenderAspect);
if (d->m_renderAfterJobs) // synchronous rendering but using QWindow
d->m_renderer->initialize();
- Render::NodeManagers *managers = d->m_renderer->nodeManagers();
- Render::Entity *rootEntity = managers->lookupResource<Render::Entity, Render::EntityManager>(rootEntityId());
- Q_ASSERT(rootEntity);
- d->m_renderer->setSceneRoot(rootEntity);
+ d->onEngineStartup();
}
void QRenderAspect::onRegistered()
@@ -601,12 +708,13 @@ void QRenderAspect::onRegistered()
// using a threaded renderer, this blocks until the render thread has been created
// and started.
Q_D(QRenderAspect);
- d->m_nodeManagers = new Render::NodeManagers();
+ d->createNodeManagers();
// Load proper Renderer class based on Qt configuration preferences
d->m_renderer = d->loadRendererPlugin();
Q_ASSERT(d->m_renderer);
d->m_renderer->setScreen(d->m_screen);
+ d->m_renderer->setAspect(this);
d->m_renderer->setNodeManagers(d->m_nodeManagers);
// Create a helper for deferring creation of an offscreen surface used during cleanup
@@ -619,7 +727,6 @@ void QRenderAspect::onRegistered()
d->registerBackendTypes();
if (!d->m_initialized) {
-
// Register the VSyncFrameAdvanceService to drive the aspect manager loop
// depending on the vsync
if (d->m_aspectManager) {
@@ -635,7 +742,7 @@ void QRenderAspect::onRegistered()
}
if (d->m_aspectManager)
- d->m_renderer->registerEventFilter(d->services()->eventFilterService());
+ d->services()->eventFilterService()->registerEventFilter(d->m_pickEventFilter.data(), 1024);
}
void QRenderAspect::onUnregistered()
@@ -665,14 +772,14 @@ void QRenderAspect::onUnregistered()
d->m_offscreenHelper = nullptr;
}
-QVector<Qt3DCore::QAspectJobPtr> QRenderAspectPrivate::createGeometryRendererJobs()
+QVector<Qt3DCore::QAspectJobPtr> QRenderAspectPrivate::createGeometryRendererJobs() const
{
Render::GeometryRendererManager *geomRendererManager = m_nodeManagers->geometryRendererManager();
const QVector<QNodeId> dirtyGeometryRenderers = geomRendererManager->dirtyGeometryRenderers();
QVector<QAspectJobPtr> dirtyGeometryRendererJobs;
dirtyGeometryRendererJobs.reserve(dirtyGeometryRenderers.size());
- for (const QNodeId geoRendererId : dirtyGeometryRenderers) {
+ for (const QNodeId &geoRendererId : dirtyGeometryRenderers) {
Render::HGeometryRenderer geometryRendererHandle = geomRendererManager->lookupHandle(geoRendererId);
if (!geometryRendererHandle.isNull()) {
auto job = Render::LoadGeometryJobPtr::create(geometryRendererHandle);
@@ -684,6 +791,56 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspectPrivate::createGeometryRendererJob
return dirtyGeometryRendererJobs;
}
+QVector<QAspectJobPtr> QRenderAspectPrivate::createPreRendererJobs() const
+{
+ if (!m_renderer)
+ return {};
+
+ const auto frameMouseEvents = m_pickEventFilter->pendingMouseEvents();
+ const auto frameKeyEvents = m_pickEventFilter->pendingKeyEvents();
+ m_renderer->setPendingEvents(frameMouseEvents, m_pickEventFilter->pendingKeyEvents());
+
+ auto jobs = m_renderer->preRenderingJobs();
+
+ // Set values on picking jobs
+ Render::RenderSettings *renderSetting = m_renderer->settings();
+ if (renderSetting != nullptr) {
+ m_pickBoundingVolumeJob->setRenderSettings(renderSetting);
+ m_pickBoundingVolumeJob->setFrameGraphRoot(m_renderer->frameGraphRoot());
+ m_pickBoundingVolumeJob->setMouseEvents(frameMouseEvents);
+ m_pickBoundingVolumeJob->setKeyEvents(frameKeyEvents);
+
+ m_rayCastingJob->setRenderSettings(renderSetting);
+ m_rayCastingJob->setFrameGraphRoot(m_renderer->frameGraphRoot());
+ }
+
+ jobs.append(m_pickBoundingVolumeJob);
+ jobs.append(m_rayCastingJob);
+
+ return jobs;
+}
+
+// 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> QRenderAspectPrivate::createRenderBufferJobs() const
+{
+ const QVector<QNodeId> dirtyBuffers = m_nodeManagers->bufferManager()->takeDirtyBuffers();
+ QVector<QAspectJobPtr> dirtyBuffersJobs;
+ dirtyBuffersJobs.reserve(dirtyBuffers.size());
+
+ for (const QNodeId &bufId : dirtyBuffers) {
+ Render::HBuffer bufferHandle = m_nodeManagers->lookupHandle<Render::Buffer, Render::BufferManager, Render::HBuffer>(bufId);
+ if (!bufferHandle.isNull()) {
+ // Create new buffer job
+ auto job = Render::LoadBufferJobPtr::create(bufferHandle);
+ job->setNodeManager(m_nodeManagers);
+ dirtyBuffersJobs.push_back(job);
+ }
+ }
+
+ return dirtyBuffersJobs;
+}
+
void QRenderAspectPrivate::loadSceneParsers()
{
const QStringList keys = QSceneImportFactory::keys();
diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h
index 0eb04cee9..830b42305 100644
--- a/src/render/frontend/qrenderaspect_p.h
+++ b/src/render/frontend/qrenderaspect_p.h
@@ -54,6 +54,16 @@
#include <Qt3DRender/qrenderaspect.h>
#include <Qt3DCore/private/qabstractaspect_p.h>
#include <Qt3DRender/private/qt3drender_global_p.h>
+#include <Qt3DRender/private/expandboundingvolumejob_p.h>
+#include <Qt3DRender/private/updateworldtransformjob_p.h>
+#include <Qt3DRender/private/updateworldboundingvolumejob_p.h>
+#include <Qt3DRender/private/calcboundingvolumejob_p.h>
+#include <Qt3DRender/private/updateskinningpalettejob_p.h>
+#include <Qt3DRender/private/updateentitylayersjob_p.h>
+#include <Qt3DRender/private/updatetreeenabledjob_p.h>
+#include <Qt3DRender/private/genericlambdajob_p.h>
+#include <Qt3DRender/private/pickboundingvolumejob_p.h>
+#include <Qt3DRender/private/raycastingjob_p.h>
#include <QtCore/qmutex.h>
@@ -74,6 +84,12 @@ class QRenderPlugin;
namespace Render {
class OffscreenSurfaceHelper;
+class PickEventFilter;
+
+using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
+
+class UpdateLevelOfDetailJob;
+typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr;
}
class Q_3DRENDERSHARED_PRIVATE_EXPORT QRenderAspectPrivate : public Qt3DCore::QAbstractAspectPrivate
@@ -85,11 +101,15 @@ public:
Q_DECLARE_PUBLIC(QRenderAspect)
static QRenderAspectPrivate* findPrivate(Qt3DCore::QAspectEngine *engine);
+ static QRenderAspectPrivate *get(QRenderAspect *q);
void syncDirtyFrontEndNode(Qt3DCore::QNode *node, Qt3DCore::QBackendNode *backend, bool firstTime) const override;
void jobsDone() override;
void frameDone() override;
+ void createNodeManagers();
+ void onEngineStartup();
+
void registerBackendTypes();
void unregisterBackendTypes();
void loadSceneParsers();
@@ -98,7 +118,9 @@ public:
void renderSynchronous(bool swapBuffers = true);
void renderShutdown();
void registerBackendType(const QMetaObject &, const Qt3DCore::QBackendNodeMapperPtr &functor);
- QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs();
+ QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs() const;
+ QVector<Qt3DCore::QAspectJobPtr> createPreRendererJobs() const;
+ QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const;
Render::AbstractRenderer *loadRendererPlugin();
Render::NodeManagers *m_nodeManagers;
@@ -113,6 +135,20 @@ public:
Render::OffscreenSurfaceHelper *m_offscreenHelper;
QScreen *m_screen = nullptr;
+ Render::UpdateTreeEnabledJobPtr m_updateTreeEnabledJob;
+ Render::UpdateWorldTransformJobPtr m_worldTransformJob;
+ Render::ExpandBoundingVolumeJobPtr m_expandBoundingVolumeJob;
+ Render::CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob;
+ Render::UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob;
+ Render::UpdateSkinningPaletteJobPtr m_updateSkinningPaletteJob;
+ Render::UpdateLevelOfDetailJobPtr m_updateLevelOfDetailJob;
+ Render::UpdateEntityLayersJobPtr m_updateEntityLayersJob;
+ Render::SynchronizerJobPtr m_syncLoadingJobs;
+ Render::PickBoundingVolumeJobPtr m_pickBoundingVolumeJob;
+ Render::RayCastingJobPtr m_rayCastingJob;
+
+ QScopedPointer<Render::PickEventFilter> m_pickEventFilter;
+
static QMutex m_pluginLock;
static QVector<QString> m_pluginConfig;
static QVector<QRenderAspectPrivate *> m_instances;
diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp
index 84169586e..2835d1b0e 100644
--- a/src/render/picking/objectpicker.cpp
+++ b/src/render/picking/objectpicker.cpp
@@ -43,6 +43,7 @@
#include <Qt3DRender/private/qobjectpicker_p.h>
#include <Qt3DRender/qattribute.h>
#include <Qt3DRender/private/pickboundingvolumejob_p.h>
+#include <Qt3DRender/private/qrenderaspect_p.h>
QT_BEGIN_NAMESPACE
@@ -103,8 +104,8 @@ void ObjectPicker::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstT
void ObjectPicker::notifyJob()
{
- if (m_renderer && m_renderer->pickBoundingVolumeJob())
- qSharedPointerCast<PickBoundingVolumeJob>(m_renderer->pickBoundingVolumeJob())->markPickersDirty();
+ if (m_renderer && m_renderer->aspect())
+ QRenderAspectPrivate::get(m_renderer->aspect())->m_pickBoundingVolumeJob->markPickersDirty();
}
bool ObjectPicker::isPressed() const
diff --git a/src/render/picking/raycaster.cpp b/src/render/picking/raycaster.cpp
index 8d3456595..b441a5099 100644
--- a/src/render/picking/raycaster.cpp
+++ b/src/render/picking/raycaster.cpp
@@ -44,6 +44,7 @@
#include <Qt3DRender/qlayer.h>
#include <Qt3DRender/private/qabstractraycaster_p.h>
#include <Qt3DRender/private/raycastingjob_p.h>
+#include <Qt3DRender/private/qrenderaspect_p.h>
QT_BEGIN_NAMESPACE
@@ -178,8 +179,8 @@ void RayCaster::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime
void RayCaster::notifyJob()
{
- if (m_renderer && m_renderer->rayCastingJob())
- qSharedPointerCast<RayCastingJob>(m_renderer->rayCastingJob())->markCastersDirty();
+ if (m_renderer && m_renderer->aspect())
+ QRenderAspectPrivate::get(m_renderer->aspect())->m_rayCastingJob->markCastersDirty();
}
} // Render
diff --git a/tests/auto/render/aspect/aspect.pro b/tests/auto/render/aspect/aspect.pro
new file mode 100644
index 000000000..1e8a9c042
--- /dev/null
+++ b/tests/auto/render/aspect/aspect.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_aspect
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_aspect.cpp
+
+CONFIG += useCommonTestAspect
+include(../commons/commons.pri)
diff --git a/tests/auto/render/aspect/tst_aspect.cpp b/tests/auto/render/aspect/tst_aspect.cpp
new file mode 100644
index 000000000..9bd5df698
--- /dev/null
+++ b/tests/auto/render/aspect/tst_aspect.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QMutex>
+#include <QWaitCondition>
+#include <QThread>
+#include <Qt3DRender/qrenderaspect.h>
+#include <Qt3DRender/private/offscreensurfacehelper_p.h>
+#include <Qt3DRender/private/rendersettings_p.h>
+#include <Qt3DRender/private/viewportnode_p.h>
+#include <Qt3DRender/private/job_common_p.h>
+#include <Qt3DRender/private/entity_p.h>
+
+#include "testaspect.h"
+#include "testrenderer.h"
+
+class TestRendererAspect : public Qt3DRender::TestAspect {
+public:
+ TestRendererAspect(Qt3DCore::QEntity *root) : Qt3DRender::TestAspect(root) {
+ auto d = Qt3DCore::QAbstractAspectPrivate::get(this);
+ d->m_rootId = root->id();
+ }
+
+ void replaceWithTestRenderer() {
+ auto daspect = Qt3DRender::QRenderAspectPrivate::get(this);
+
+ auto sceneRoot = daspect->m_renderer->sceneRoot();
+ daspect->m_renderer->shutdown();
+ delete daspect->m_renderer;
+ daspect->m_renderer = new TestRenderer();
+ daspect->m_renderer->setNodeManagers(daspect->m_nodeManagers);
+ daspect->m_renderer->setOffscreenSurfaceHelper(daspect->m_offscreenHelper);
+ sceneRoot->setRenderer(daspect->m_renderer);
+ daspect->m_renderer->setSceneRoot(sceneRoot);
+
+ // Give it a setting instance
+ Qt3DRender::Render::RenderSettings settings;
+ // owned by FG manager
+ Qt3DRender::Render::ViewportNode *fgRoot = new Qt3DRender::Render::ViewportNode();
+ const Qt3DCore::QNodeId fgRootId = Qt3DCore::QNodeId::createId();
+
+ daspect->m_nodeManagers->frameGraphManager()->appendNode(fgRootId, fgRoot);
+ settings.setActiveFrameGraphId(fgRootId);
+
+ daspect->m_renderer->setSettings(&settings);
+ }
+};
+
+class tst_Aspect : public QObject
+{
+ Q_OBJECT
+public :
+ tst_Aspect() = default;
+ ~tst_Aspect() = default;
+
+private Q_SLOTS:
+
+ void checkJobs()
+ {
+ // GIVEN
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ QScopedPointer<TestRendererAspect> aspect(new TestRendererAspect(rootEntity));
+ auto daspect = Qt3DRender::QRenderAspectPrivate::get(aspect.data());
+ daspect->m_renderAfterJobs = true;
+ aspect->onEngineStartup();
+
+ // replace with empty renderer
+ aspect->replaceWithTestRenderer();
+
+ // WHEN
+ daspect->m_renderer->markDirty(Qt3DRender::Render::AbstractRenderer::AllDirty, nullptr);
+
+ auto jobs = daspect->jobsToExecute(1.);
+// qDebug() << jobs.size();
+// for (auto job: jobs)
+// qDebug() << Qt3DCore::QAspectJobPrivate::get(job.data())->m_jobName;
+
+ // THEN -> AllDirty
+ QCOMPARE(jobs.size(),
+ 1 + // UpdateTreeEnabled
+ 1 + // UpdateTransform
+ 1 + // UpdateWorldBoundingVolume
+ 1 + // CalcBoundingVolume
+ 1 + // ExpandBoundingVolume
+ 1 + // SyncLoadingJobs
+ 1 + // UpdateSkinningPalette
+ 1 + // UpdateLevelOfDetail
+ 1 + // UpdateLayerEntity
+ 1 + // PickBoundingVolume
+ 1 + // RayCasting
+ 0 // No skeleton, no scene loading, no geometry, no buffers
+ );
+
+ // WHEN
+ daspect->m_renderer->clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ jobs = daspect->jobsToExecute(1.);
+
+ // THEN -> Nothing dirty
+ QCOMPARE(jobs.size(),
+ 1 + // SyncLoadingJobs
+ 1 + // UpdateSkinningPalette
+ 1 + // UpdateLevelOfDetail
+ 1 + // PickBoundingVolume
+ 1 + // RayCasting
+ 0 // No skeleton, no scene loading, no geometry, no buffers
+ );
+
+ // WHEN
+ daspect->m_renderer->clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ daspect->m_renderer->markDirty(Qt3DRender::Render::AbstractRenderer::EntityEnabledDirty, nullptr);
+ jobs = daspect->jobsToExecute(1.);
+
+ // THEN -> enabled dirty
+ QCOMPARE(jobs.size(),
+ 1 + // UpdateTreeEnabled
+ 1 + // SyncLoadingJobs
+ 1 + // UpdateSkinningPalette
+ 1 + // UpdateLevelOfDetail
+ 1 + // PickBoundingVolume
+ 1 + // RayCasting
+ 0 // No skeleton, no scene loading, no geometry, no buffers
+ );
+
+ // WHEN
+ daspect->m_renderer->clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ daspect->m_renderer->markDirty(Qt3DRender::Render::AbstractRenderer::TransformDirty, nullptr);
+ jobs = daspect->jobsToExecute(1.);
+
+ // THEN -> transform dirty
+ QCOMPARE(jobs.size(),
+ 1 + // UpdateTransform
+ 1 + // UpdateWorldBoundingVolume
+ 1 + // ExpandBoundingVolume
+ 1 + // SyncLoadingJobs
+ 1 + // UpdateSkinningPalette
+ 1 + // UpdateLevelOfDetail
+ 1 + // PickBoundingVolume
+ 1 + // RayCasting
+ 0 // No skeleton, no scene loading, no geometry, no buffers
+ );
+
+ // WHEN
+ daspect->m_renderer->clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ daspect->m_renderer->markDirty(Qt3DRender::Render::AbstractRenderer::GeometryDirty, nullptr);
+ jobs = daspect->jobsToExecute(1.);
+
+ // THEN -> geometry dirty
+ QCOMPARE(jobs.size(),
+ 1 + // CalcBoundingVolume
+ 1 + // ExpandBoundingVolume
+ 1 + // SyncLoadingJobs
+ 1 + // UpdateSkinningPalette
+ 1 + // UpdateLevelOfDetail
+ 1 + // PickBoundingVolume
+ 1 + // RayCasting
+ 0 // No skeleton, no scene loading, no geometry, no buffers
+ );
+ }
+};
+
+QTEST_MAIN(tst_Aspect)
+
+#include "tst_aspect.moc"
diff --git a/tests/auto/render/commons/commons.pri b/tests/auto/render/commons/commons.pri
index 6f4382a0b..1c6645f8d 100644
--- a/tests/auto/render/commons/commons.pri
+++ b/tests/auto/render/commons/commons.pri
@@ -6,7 +6,7 @@ HEADERS += \
useCommonTestAspect {
SOURCES += $$PWD/testaspect.cpp
- SOURCES += $$PWD/testaspect.h
+ HEADERS += $$PWD/testaspect.h
}
INCLUDEPATH += $$PWD
diff --git a/tests/auto/render/commons/testaspect.cpp b/tests/auto/render/commons/testaspect.cpp
index 87ffc56d7..086d79bb6 100644
--- a/tests/auto/render/commons/testaspect.cpp
+++ b/tests/auto/render/commons/testaspect.cpp
@@ -95,6 +95,11 @@ Render::NodeManagers *TestAspect::nodeManagers() const
return d_func()->m_renderer->nodeManagers();
}
+void TestAspect::onEngineStartup()
+{
+ QRenderAspect::onEngineStartup();
+}
+
void TestAspect::onRegistered()
{
QRenderAspect::onRegistered();
diff --git a/tests/auto/render/commons/testaspect.h b/tests/auto/render/commons/testaspect.h
index a0da98721..dfbe78fbd 100644
--- a/tests/auto/render/commons/testaspect.h
+++ b/tests/auto/render/commons/testaspect.h
@@ -56,6 +56,7 @@ public:
Qt3DRender::Render::NodeManagers *nodeManagers() const;
+ void onEngineStartup();
void onRegistered();
void onUnregistered();
diff --git a/tests/auto/render/commons/testrenderer.cpp b/tests/auto/render/commons/testrenderer.cpp
index 5a36fecf2..45713e9b9 100644
--- a/tests/auto/render/commons/testrenderer.cpp
+++ b/tests/auto/render/commons/testrenderer.cpp
@@ -38,7 +38,7 @@ TestRenderer::~TestRenderer()
void TestRenderer::markDirty(Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet changes, Qt3DRender::Render::BackendNode *node)
{
- Q_UNUSED(node);
+ Q_UNUSED(node)
m_changes |= changes;
}
@@ -50,7 +50,7 @@ Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet TestRenderer::dirtyBit
#if defined(QT_BUILD_INTERNAL)
void TestRenderer::clearDirtyBits(Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet changes)
{
- m_changes &= changes;
+ m_changes &= ~changes;
}
#endif
diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h
index 7b3e0a387..8d5d87a98 100644
--- a/tests/auto/render/commons/testrenderer.h
+++ b/tests/auto/render/commons/testrenderer.h
@@ -43,15 +43,17 @@ public:
void dumpInfo() const override {}
API api() const override { return AbstractRenderer::OpenGL; }
qint64 time() const override { return 0; }
- void setTime(qint64 time) override { Q_UNUSED(time); }
+ void setTime(qint64 time) override { Q_UNUSED(time) }
+ void setAspect(Qt3DRender::QRenderAspect *aspect) override { m_aspect = aspect; }
void setNodeManagers(Qt3DRender::Render::NodeManagers *m) override
{
m_managers = m;
m_resourceAccessor.reset(new Qt3DRender::Render::ResourceAccessor(this, m_managers));
}
- void setServices(Qt3DCore::QServiceLocator *services) override { Q_UNUSED(services); }
- void setSurfaceExposed(bool exposed) override { Q_UNUSED(exposed); }
+ void setServices(Qt3DCore::QServiceLocator *services) override { Q_UNUSED(services) }
+ void setSurfaceExposed(bool exposed) override { Q_UNUSED(exposed) }
void setJobsInLastFrame(int jobsInLastFrame) override { Q_UNUSED(jobsInLastFrame) }
+ Qt3DRender::QRenderAspect *aspect() const override { return m_aspect; }
Qt3DRender::Render::NodeManagers *nodeManagers() const override { return m_managers; }
Qt3DCore::QServiceLocator *services() const override { return nullptr; }
void initialize() override {}
@@ -66,17 +68,13 @@ public:
void jobsDone(Qt3DCore::QAspectManager *manager) override { Q_UNUSED(manager) }
QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
- Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); }
- Qt3DCore::QAspectJobPtr rayCastingJob() override { return Qt3DCore::QAspectJobPtr(); }
- Qt3DCore::QAspectJobPtr syncLoadingJobs() override { return Qt3DCore::QAspectJobPtr(); }
- Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); }
void setSceneRoot(Qt3DRender::Render::Entity *root) override { Q_UNUSED(root) }
Qt3DRender::Render::Entity *sceneRoot() const override { return nullptr; }
Qt3DRender::Render::FrameGraphNode *frameGraphRoot() const override { return nullptr; }
Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override { return nullptr; }
- void registerEventFilter(Qt3DCore::QEventFilterService *service) override { Q_UNUSED(service) }
- void setSettings(Qt3DRender::Render::RenderSettings *settings) override { Q_UNUSED(settings) }
- Qt3DRender::Render::RenderSettings *settings() const override { return nullptr; }
+ void setSettings(Qt3DRender::Render::RenderSettings *settings) override { m_settings = settings; }
+ Qt3DRender::Render::RenderSettings *settings() const override { return m_settings; }
+ void setPendingEvents(const QList<QPair<QObject *, QMouseEvent> > &, const QList<QKeyEvent> &) override { }
void markDirty(Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet changes, Qt3DRender::Render::BackendNode *node) override;
Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet dirtyBits() override;
@@ -99,8 +97,10 @@ public:
protected:
Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet m_changes;
+ Qt3DRender::QRenderAspect *m_aspect = nullptr;
Qt3DRender::Render::NodeManagers *m_managers = nullptr;
QSharedPointer<Qt3DRender::Render::ResourceAccessor> m_resourceAccessor;
+ Qt3DRender::Render::RenderSettings *m_settings = nullptr;
};
QT_END_NAMESPACE
diff --git a/tests/auto/render/opengl/renderer/renderer.pro b/tests/auto/render/opengl/renderer/renderer.pro
index d481c7b9e..a4a459655 100644
--- a/tests/auto/render/opengl/renderer/renderer.pro
+++ b/tests/auto/render/opengl/renderer/renderer.pro
@@ -10,3 +10,6 @@ SOURCES += tst_renderer.cpp
# Link Against OpenGL Renderer Plugin
include(../opengl_render_plugin.pri)
+
+CONFIG += useCommonTestAspect
+include(../../commons/commons.pri)
diff --git a/tests/auto/render/opengl/renderer/tst_renderer.cpp b/tests/auto/render/opengl/renderer/tst_renderer.cpp
index db7a37af1..abb1aee86 100644
--- a/tests/auto/render/opengl/renderer/tst_renderer.cpp
+++ b/tests/auto/render/opengl/renderer/tst_renderer.cpp
@@ -30,12 +30,15 @@
#include <QMutex>
#include <QWaitCondition>
#include <QThread>
-#include <Qt3DRender/private/viewportnode_p.h>
#include <renderer_p.h>
#include <renderview_p.h>
#include <renderviewbuilder_p.h>
-#include <Qt3DRender/private/offscreensurfacehelper_p.h>
#include <renderqueue_p.h>
+#include <Qt3DRender/private/viewportnode_p.h>
+#include <Qt3DRender/private/offscreensurfacehelper_p.h>
+#include <Qt3DRender/private/qrenderaspect_p.h>
+
+#include "testaspect.h"
class tst_Renderer : public QObject
{
@@ -72,19 +75,14 @@ private Q_SLOTS:
QVector<Qt3DCore::QAspectJobPtr> jobs = renderer.preRenderingJobs();
// THEN
- QCOMPARE(jobs.size(),
- 1 + // PickBoundingVolumeJob
- 1); // RayCastingJob
+ QCOMPARE(jobs.size(), 0);
// WHEN
renderer.m_sendBufferCaptureJob->addRequest({Qt3DCore::QNodeId(), {}});
jobs = renderer.preRenderingJobs();
// THEN
- QCOMPARE(jobs.size(),
- 1 + // PickBoundingVolumeJob
- 1 + // RayCastingJob
- 1); // SendBufferCaptureJob
+ QCOMPARE(jobs.size(), 1); // SendBufferCaptureJob
// Note: pending render buffer captures are only cleared when the job is run
// WHEN
@@ -93,8 +91,6 @@ private Q_SLOTS:
// THEN
QCOMPARE(jobs.size(),
- 1 + // PickBoundingVolumeJob
- 1 + // RayCastingJob
1 + // SendBufferCaptureJob
1); // SendSetFenceHandlesJob
// Note: pending set fence handles are only cleared when the job is run
@@ -106,8 +102,12 @@ private Q_SLOTS:
void checkRenderBinJobs()
{
// GIVEN
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ QScopedPointer<Qt3DRender::TestAspect> aspect(new Qt3DRender::TestAspect(rootEntity));
+ auto daspect = Qt3DRender::QRenderAspectPrivate::get(aspect.data());
+
Qt3DRender::Render::NodeManagers nodeManagers;
- Qt3DRender::Render::OpenGL::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
+ auto &renderer = *(static_cast<Qt3DRender::Render::OpenGL::Renderer *>(daspect->m_renderer));
Qt3DRender::Render::OpenGL::RenderQueue *renderQueue = renderer.renderQueue();
Qt3DRender::Render::OffscreenSurfaceHelper offscreenHelper(&renderer);
Qt3DRender::Render::RenderSettings settings;
@@ -156,21 +156,11 @@ private Q_SLOTS:
// (Renderer is not initialized so FilterCompatibleTechniqueJob
// and ShaderGathererJob are not added here)
QCOMPARE(jobs.size(),
- 1 + // EntityEnabledDirty
- 1 + // WorldTransformJob
- 1 + // UpdateWorldBoundingVolume
1 + // UpdateShaderDataTransform
- 1 + // ExpandBoundingVolumeJob
- 1 + // CalculateBoundingVolumeJob
- 1 + // UpdateMeshTriangleListJob
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
1 + // BufferGathererJob
1 + // TexturesGathererJob
- 1 + // UpdateEntityLayersJob
1 + // LightGathererJob
1 + // CacheLightJob
1 + // RenderableEntityFilterJob
@@ -191,11 +181,8 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
singleRenderViewJobCount +
singleRenderViewCommandRebuildJobCount +
renderViewBuilderMaterialCacheJobCount +
@@ -211,11 +198,8 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
singleRenderViewJobCount +
singleRenderViewCommandRebuildJobCount +
renderViewBuilderMaterialCacheJobCount +
@@ -230,12 +214,8 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
- 1 + // EntityEnabledDirty
singleRenderViewJobCount +
layerCacheJobCount);
@@ -248,15 +228,9 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // WorldTransformJob
- 1 + // UpdateWorldBoundingVolume
1 + // UpdateShaderDataTransform
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
- 1 + // ExpandBoundingVolumeJob
singleRenderViewJobCount);
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
@@ -268,11 +242,8 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
singleRenderViewJobCount +
singleRenderViewCommandRebuildJobCount +
renderViewBuilderMaterialCacheJobCount);
@@ -286,14 +257,8 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // CalculateBoundingVolumeJob
- 1 + // UpdateMeshTriangleListJob
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
- 1 + // ExpandBoundingVolumeJob
1 + // RenderableEntityFilterPtr
1 + // SyncRenderableEntities
singleRenderViewCommandRebuildJobCount +
@@ -308,13 +273,8 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- 1 + // SyncLoadingJobs
- 1 + // CalculateBoundingVolumeJob
- 1 + // UpdateMeshTriangleListJob
1 + // BufferGathererJob
singleRenderViewJobCount);
@@ -327,12 +287,9 @@ private Q_SLOTS:
// THEN (level
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
1 + // TexturesGathererJob
- 1 + // updateSkinningPaletteJob
- 1 + // SyncTexturesGathererJob
singleRenderViewJobCount);
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
diff --git a/tests/auto/render/opengl/renderviewbuilder/tst_renderviewbuilder.cpp b/tests/auto/render/opengl/renderviewbuilder/tst_renderviewbuilder.cpp
index fe534e243..f0d02d63a 100644
--- a/tests/auto/render/opengl/renderviewbuilder/tst_renderviewbuilder.cpp
+++ b/tests/auto/render/opengl/renderviewbuilder/tst_renderviewbuilder.cpp
@@ -53,6 +53,7 @@
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/managers_p.h>
#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
+#include <Qt3DRender/private/qrenderaspect_p.h>
QT_BEGIN_NAMESPACE
@@ -290,6 +291,11 @@ private Q_SLOTS:
Qt3DRender::QClearBuffers *clearBuffer = new Qt3DRender::QClearBuffers(viewport);
Qt3DRender::TestAspect testAspect(buildSimpleScene(viewport));
+ auto expandBVJob = Qt3DRender::QRenderAspectPrivate::get(&testAspect)->m_expandBoundingVolumeJob;
+ auto wordTransformJob = Qt3DRender::QRenderAspectPrivate::get(&testAspect)->m_worldTransformJob;
+ auto updateTreeEnabledJob = Qt3DRender::QRenderAspectPrivate::get(&testAspect)->m_updateTreeEnabledJob;
+ auto updateEntityLayerJob = Qt3DRender::QRenderAspectPrivate::get(&testAspect)->m_updateEntityLayersJob;
+
// THEN
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id());
QVERIFY(leafNode != nullptr);
@@ -304,7 +310,6 @@ private Q_SLOTS:
// Step 1
QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 1); // Depends upon skinning palette update
-
// Step 2
QCOMPARE(renderViewBuilder.syncRenderViewPostInitializationJob()->dependencies().size(), 1);
QCOMPARE(renderViewBuilder.syncRenderViewPostInitializationJob()->dependencies().constFirst().toStrongRef().data(),
@@ -316,7 +321,7 @@ private Q_SLOTS:
QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2);
QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
- QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+ QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(expandBVJob));
QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1);
QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().constFirst().toStrongRef().data(),
@@ -324,14 +329,13 @@ private Q_SLOTS:
QCOMPARE(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().size(), 3);
QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
- QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob()));
+ QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(wordTransformJob));
QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
// Step 4
QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2);
QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncPreFrustumCullingJob()));
- QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
-
+ QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(expandBVJob));
QCOMPARE(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 7);
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
@@ -374,16 +378,16 @@ private Q_SLOTS:
// Step 3
QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->dependencies().size(), 3);
- QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateEntityLayersJob()));
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(updateEntityLayerJob));
QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
- QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob()));
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(updateTreeEnabledJob));
QCOMPARE(renderViewBuilder.syncFilterEntityByLayerJob()->dependencies().size(), 1);
QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob()->dependencies().contains(renderViewBuilder.filterEntityByLayerJob()));
QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2);
QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
- QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+ QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(expandBVJob));
QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1);
QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().constFirst().toStrongRef().data(),
@@ -391,7 +395,7 @@ private Q_SLOTS:
QCOMPARE(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().size(), 3);
QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
- QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob()));
+ QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(wordTransformJob));
QVERIFY(renderViewBuilder.syncPreFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
for (const auto &materialGatherer : renderViewBuilder.materialGathererJobs()) {
@@ -404,7 +408,7 @@ private Q_SLOTS:
// Step 4
QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2);
QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncPreFrustumCullingJob()));
- QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+ QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(expandBVJob));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(renderViewBuilder.syncRenderViewPostInitializationJob()));
QVERIFY(renderViewBuilder.syncRenderViewPreCommandUpdateJob()->dependencies().contains(renderViewBuilder.syncFilterEntityByLayerJob()));
diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro
index 14fc74883..f8011b2cf 100644
--- a/tests/auto/render/render.pro
+++ b/tests/auto/render/render.pro
@@ -2,6 +2,7 @@ TEMPLATE = subdirs
qtConfig(private_tests) {
SUBDIRS += \
+ aspect \
entity \
renderpass \
shader \
diff --git a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp
index 85b5e8c89..57bd7745d 100644
--- a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp
+++ b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp
@@ -87,20 +87,26 @@ namespace Qt3DRender {
QVector<Qt3DCore::QAspectJobPtr> worldTransformJob()
{
- static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer)->m_worldTransformJob->setRoot(d_func()->m_renderer->sceneRoot());
- return QVector<Qt3DCore::QAspectJobPtr>() << static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer)->m_worldTransformJob;
+ auto renderer = static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer);
+ auto daspect = Qt3DRender::QRenderAspectPrivate::get(renderer->aspect());
+ daspect->m_worldTransformJob->setRoot(d_func()->m_renderer->sceneRoot());
+ return QVector<Qt3DCore::QAspectJobPtr>() << daspect->m_worldTransformJob;
}
QVector<Qt3DCore::QAspectJobPtr> updateBoundingJob()
{
- static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer)->m_updateWorldBoundingVolumeJob->setManager(d_func()->m_renderer->nodeManagers()->renderNodesManager());
- return QVector<Qt3DCore::QAspectJobPtr>() << static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer)->m_updateWorldBoundingVolumeJob;
+ auto renderer = static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer);
+ auto daspect = Qt3DRender::QRenderAspectPrivate::get(renderer->aspect());
+ daspect->m_updateWorldBoundingVolumeJob->setManager(d_func()->m_renderer->nodeManagers()->renderNodesManager());
+ return QVector<Qt3DCore::QAspectJobPtr>() << daspect->m_updateWorldBoundingVolumeJob;
}
QVector<Qt3DCore::QAspectJobPtr> calculateBoundingVolumeJob()
{
- static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer)->m_calculateBoundingVolumeJob->setRoot(d_func()->m_renderer->sceneRoot());
- return QVector<Qt3DCore::QAspectJobPtr>() << static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer)->m_calculateBoundingVolumeJob;
+ auto renderer = static_cast<Render::OpenGL::Renderer *>(d_func()->m_renderer);
+ auto daspect = Qt3DRender::QRenderAspectPrivate::get(renderer->aspect());
+ daspect->m_calculateBoundingVolumeJob->setRoot(d_func()->m_renderer->sceneRoot());
+ return QVector<Qt3DCore::QAspectJobPtr>() << daspect->m_calculateBoundingVolumeJob;
}
QVector<Qt3DCore::QAspectJobPtr> framePreparationJob()