summaryrefslogtreecommitdiffstats
path: root/src/render/frontend
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2018-02-20 15:21:13 +0100
committerPaul Lemire <paul.lemire@kdab.com>2018-02-28 10:44:49 +0000
commit3dff7c204da1d834629544b54b9f6efaafe165e2 (patch)
treef8529c267fd3a8ffa2f7e293682bdea219fe2897 /src/render/frontend
parenta43cf3726679704cc8c4c5a405c60c6f1c4fcfce (diff)
Revert "Keep rendering in sync with aspect jobs by adding barriers"
This reverts commit 46319648436814afb5a77755dde6681e304befaf. We want to be able to render one set of RenderViews for frame n while concurrently building RenderViews for frame n + 1. The reverted commit removed that behavior which reduced the CPU time available to prepare a frame. This would cause on some scenes a failure to meet the ~10ms budget we have to prepare a frame. This is therefore a regression. The root cause behind this regression is that a job cannot be executed until all the jobs which have been previously launched have completed. The proposed solution would be to instead add an OpenGL command thread that can be used to load graphics resources required for the RenderViews directly when required. This would in turn allow to cache RenderViews and keep the concurrent behavior of RenderView submission and creation. With that goal in mind, the following patches will be rebased and updated https://codereview.qt-project.org/#/c/189309/ https://codereview.qt-project.org/#/c/189310/ Change-Id: I4879047c45986a0e615e3aef7b7352f82a04a9da Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/frontend')
-rw-r--r--src/render/frontend/qrenderaspect.cpp69
-rw-r--r--src/render/frontend/qrenderaspect_p.h4
2 files changed, 34 insertions, 39 deletions
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 5e1fea288..e5cce4c7b 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -153,8 +153,6 @@
#include <private/qrenderpluginfactory_p.h>
#include <private/qrenderplugin_p.h>
-#include <private/framegraphvisitor_p.h>
-#include <private/platformsurfacefilter_p.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
@@ -190,12 +188,7 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
, m_initialized(false)
, m_renderType(type)
, m_offscreenHelper(nullptr)
- , m_blockingRendermode(false)
{
- // The blocking mode can be enabled to make sure we render even while
- // waiting for geometries to load. This is necessary if we want
- // to call doRender for every QtQuick frame when using Scene3D frame.
- m_blockingRendermode = !qgetenv("SCENE3D_BLOCKING_RENDERMODE").isEmpty();
m_instances.append(this);
loadSceneParsers();
}
@@ -381,11 +374,6 @@ void QRenderAspectPrivate::registerBackendType(const QMetaObject &obj,
q->registerBackendType(obj, functor);
}
-void QRenderAspectPrivate::abortRenderJobs()
-{
- m_renderer->abortRenderJobs();
-}
-
/*!
* The constructor creates a new QRenderAspect::QRenderAspect instance with the
* specified \a parent.
@@ -424,17 +412,9 @@ void QRenderAspectPrivate::renderInitialize(QOpenGLContext *context)
}
/*! \internal */
-void QRenderAspectPrivate::tryRenderSynchronous()
+void QRenderAspectPrivate::renderSynchronous(bool blocking)
{
- // If the render aspect is slow for some reason and does not build jobs
- // immediately, we might want to wait for it to make sure we render
- // one Qt3D frame for each QtQuick frame. If blocking mode is enabled,
- // we will wait a short time.
- // TODO By allowing the aspect thread to skip a couple of frames that
- // are not rendered without being in sync with the QtQuick scene graph,
- // we can make this into a blocking call and get rid of the timeout.
- if (m_renderer->tryWaitForRenderJobs(m_blockingRendermode ? 20 : 0))
- m_renderer->lockSurfaceAndRender();
+ m_renderer->doRender(blocking);
}
/*!
@@ -470,16 +450,36 @@ 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 assetLoadingSync = d->m_renderer->syncSkeletonLoadingJob();
- assetLoadingSync->removeDependency(QWeakPointer<QAspectJob>());
- // Launch skeleton loader jobs
+ QAspectJobPtr textureLoadingSync = d->m_renderer->syncTextureLoadingJob();
+ textureLoadingSync->removeDependency(QWeakPointer<QAspectJob>());
+
+ // Launch texture generator jobs
+ const QVector<QTextureImageDataGeneratorPtr> pendingImgGen = manager->textureImageDataManager()->pendingGenerators();
+ for (const QTextureImageDataGeneratorPtr &imgGen : pendingImgGen) {
+ auto loadTextureJob = Render::LoadTextureDataJobPtr::create(imgGen);
+ textureLoadingSync->addDependency(loadTextureJob);
+ loadTextureJob->setNodeManagers(manager);
+ jobs.append(loadTextureJob);
+ }
+ const QVector<QTextureGeneratorPtr> pendingTexGen = manager->textureDataManager()->pendingGenerators();
+ for (const QTextureGeneratorPtr &texGen : pendingTexGen) {
+ auto loadTextureJob = Render::LoadTextureDataJobPtr::create(texGen);
+ textureLoadingSync->addDependency(loadTextureJob);
+ loadTextureJob->setNodeManagers(manager);
+ jobs.append(loadTextureJob);
+ }
+
+ // Launch skeleton loader jobs. We join on the syncTextureLoadingJob for now
+ // which should likely be renamed to something more generic or we introduce
+ // another synchronizing job for skeleton loading
const QVector<Render::HSkeleton> skeletonsToLoad =
manager->skeletonManager()->dirtySkeletons(Render::SkeletonManager::SkeletonDataDirty);
for (const auto &skeletonHandle : skeletonsToLoad) {
auto loadSkeletonJob = Render::LoadSkeletonJobPtr::create(skeletonHandle);
loadSkeletonJob->setNodeManagers(manager);
- assetLoadingSync->addDependency(loadSkeletonJob);
+ textureLoadingSync->addDependency(loadSkeletonJob);
jobs.append(loadSkeletonJob);
}
@@ -496,6 +496,7 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
const QVector<QAspectJobPtr> geometryJobs = d->createGeometryRendererJobs();
jobs.append(geometryJobs);
+
// Add all jobs to queue
// Note: the getter is also responsible for returning a job ready to run
jobs.append(d->m_renderer->pickBoundingVolumeJob());
@@ -510,16 +511,12 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
return jobs;
}
- // Let the rendering thread know that we are ready to spawn jobs if it
- // can promise us that it will in fact call doRender.
- if (d->m_renderer->releaseRendererAndRequestPromiseToRender()) {
- // Traverse the current framegraph and create jobs to populate
- // RenderBins with RenderCommands
- // All jobs needed to create the frame and their dependencies are set by
- // renderBinJobs()
- const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
- jobs.append(renderBinJobs);
- }
+ // Traverse the current framegraph and create jobs to populate
+ // RenderBins with RenderCommands
+ // All jobs needed to create the frame and their dependencies are set by
+ // renderBinJobs()
+ const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
+ jobs.append(renderBinJobs);
}
return jobs;
}
diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h
index d18ce8b4f..26ca091f6 100644
--- a/src/render/frontend/qrenderaspect_p.h
+++ b/src/render/frontend/qrenderaspect_p.h
@@ -90,10 +90,9 @@ public:
void loadSceneParsers();
void loadRenderPlugin(const QString &pluginName);
void renderInitialize(QOpenGLContext *context);
- void tryRenderSynchronous();
+ void renderSynchronous(bool blocking = false);
void renderShutdown();
void registerBackendType(const QMetaObject &, const Qt3DCore::QBackendNodeMapperPtr &functor);
- void abortRenderJobs();
QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs();
Render::NodeManagers *m_nodeManagers;
@@ -105,7 +104,6 @@ public:
QVector<Render::QRenderPlugin *> m_renderPlugins;
QRenderAspect::RenderType m_renderType;
Render::OffscreenSurfaceHelper *m_offscreenHelper;
- bool m_blockingRendermode;
static QMutex m_pluginLock;
static QVector<QString> m_pluginConfig;