Convert LoadGeometryJob to use direct sync

Change-Id: Id744de2f10e7744ad5a9d4f425ae534153ed7446
Reviewed-by: Mike Krus <mike.krus@kdab.com>
This commit is contained in:
Paul Lemire 2019-10-10 14:39:43 +02:00
parent 5eff77db3a
commit c731ef9f45
9 changed files with 51 additions and 66 deletions

View File

@ -146,7 +146,7 @@ void GeometryRenderer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
markDirty(AbstractRenderer::GeometryDirty);
}
void GeometryRenderer::executeFunctor()
GeometryFunctorResult GeometryRenderer::executeFunctor()
{
Q_ASSERT(m_geometryFactory);
@ -167,7 +167,8 @@ void GeometryRenderer::executeFunctor()
}
// Load geometry
std::unique_ptr<QGeometry> geometry((*m_geometryFactory)());
QGeometry *geometry = (*m_geometryFactory)();
QMesh::Status meshLoaderStatus = QMesh::None;
// If the geometry is null, then we were either unable to load it (Error)
// or the mesh is located at a remote url and needs to be downloaded first (Loading)
@ -176,24 +177,15 @@ void GeometryRenderer::executeFunctor()
// corresponding QGeometryRenderer
const auto appThread = QCoreApplication::instance()->thread();
geometry->moveToThread(appThread);
auto e = QGeometryChangePtr::create(peerId());
e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
e->setPropertyName("geometry");
e->data = std::move(geometry);
notifyObservers(e);
}
// Send Status
if (isQMeshFunctor) {
QSharedPointer<MeshLoaderFunctor> meshLoader = qSharedPointerCast<MeshLoaderFunctor>(m_geometryFactory);
auto e = QPropertyUpdatedChangePtr::create(peerId());
e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
e->setPropertyName("status");
e->setValue(meshLoader->status());
notifyObservers(e);
meshLoaderStatus = meshLoader->status();
}
return { geometry, meshLoaderStatus };
}
void GeometryRenderer::unsetDirty()

View File

@ -54,6 +54,7 @@
#include <Qt3DRender/private/backendnode_p.h>
#include <Qt3DRender/qgeometryrenderer.h>
#include <Qt3DRender/qgeometryfactory.h>
#include <Qt3DRender/qmesh.h>
QT_BEGIN_NAMESPACE
@ -66,6 +67,12 @@ namespace Render {
class GeometryRendererManager;
struct GeometryFunctorResult
{
QGeometry *geometry;
QMesh::Status status;
};
class Q_AUTOTEST_EXPORT GeometryRenderer : public BackendNode
{
public:
@ -75,7 +82,7 @@ public:
void cleanup();
void setManager(GeometryRendererManager *manager);
void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void executeFunctor();
GeometryFunctorResult executeFunctor();
inline Qt3DCore::QNodeId geometryId() const { return m_geometryId; }
inline int instanceCount() const { return m_instanceCount; }

View File

@ -480,19 +480,6 @@ void QGeometryRenderer::setGeometryFactory(const QGeometryFactoryPtr &factory)
d->update();
}
/*!
\internal
*/
void QGeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
auto change = qSharedPointerCast<QStaticPropertyUpdatedChangeBase>(e);
if (change->type() == PropertyUpdated && change->propertyName() == QByteArrayLiteral("geometry")) {
auto typedChange = qSharedPointerCast<QGeometryChange>(e);
auto geometry = std::move(typedChange->data);
setGeometry(geometry.release());
}
}
Qt3DCore::QNodeCreatedChangeBasePtr QGeometryRenderer::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QGeometryRendererData>::create(this);

View File

@ -134,7 +134,6 @@ Q_SIGNALS:
protected:
explicit QGeometryRenderer(QGeometryRendererPrivate &dd, Qt3DCore::QNode *parent = nullptr);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QGeometryRenderer)

View File

@ -215,18 +215,6 @@ QMesh::QMesh(QMeshPrivate &dd, QNode *parent)
{
}
/*! \internal */
void QMesh::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
{
Q_D(QMesh);
if (change->type() == Qt3DCore::PropertyUpdated) {
const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
if (e->propertyName() == QByteArrayLiteral("status"))
d->setStatus(e->value().value<QMesh::Status>());
}
Qt3DRender::QGeometryRenderer::sceneChangeEvent(change);
}
void QMesh::setSource(const QUrl& source)
{
Q_D(QMesh);

View File

@ -88,7 +88,6 @@ Q_SIGNALS:
protected:
explicit QMesh(QMeshPrivate &dd, Qt3DCore::QNode *parent = nullptr);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override;
private:
Q_DECLARE_PRIVATE(QMesh)

View File

@ -41,6 +41,8 @@
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
#include <Qt3DRender/private/job_common_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DRender/private/qmesh_p.h>
QT_BEGIN_NAMESPACE
@ -48,8 +50,19 @@ namespace Qt3DRender {
namespace Render {
class LoadGeometryJobPrivate : public Qt3DCore::QAspectJobPrivate
{
public:
LoadGeometryJobPrivate() {}
~LoadGeometryJobPrivate() {}
void postFrame(Qt3DCore::QAspectManager *manager) override;
QVector<std::pair<Qt3DCore::QNodeId, GeometryFunctorResult>> m_updates;
};
LoadGeometryJob::LoadGeometryJob(const HGeometryRenderer &handle)
: QAspectJob()
: QAspectJob(*new LoadGeometryJobPrivate)
, m_handle(handle)
, m_nodeManagers(nullptr)
{
@ -62,9 +75,27 @@ LoadGeometryJob::~LoadGeometryJob()
void LoadGeometryJob::run()
{
Q_D(LoadGeometryJob);
GeometryRenderer *geometryRenderer = m_nodeManagers->geometryRendererManager()->data(m_handle);
if (geometryRenderer != nullptr)
geometryRenderer->executeFunctor();
d->m_updates.push_back({ geometryRenderer->peerId(), geometryRenderer->executeFunctor() });
}
void LoadGeometryJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
{
const auto updates = std::move(m_updates);
for (const auto &update : updates) {
QGeometryRenderer *gR = static_cast<decltype(gR)>(manager->lookupNode(update.first));
const GeometryFunctorResult &result = update.second;
gR->setGeometry(result.geometry);
// Set status if gR is a QMesh instance
QMesh *mesh = qobject_cast<QMesh *>(gR);
if (mesh) {
QMeshPrivate *dMesh = static_cast<decltype(dMesh)>(Qt3DCore::QNodePrivate::get(mesh));
dMesh->setStatus(result.status);
}
}
}
} // namespace Render

View File

@ -62,6 +62,7 @@ namespace Qt3DRender {
namespace Render {
class NodeManagers;
class LoadGeometryJobPrivate;
class Q_AUTOTEST_EXPORT LoadGeometryJob : public Qt3DCore::QAspectJob
{
@ -75,6 +76,9 @@ protected:
void run() override;
HGeometryRenderer m_handle;
NodeManagers *m_nodeManagers;
private:
Q_DECLARE_PRIVATE(LoadGeometryJob)
};
typedef QSharedPointer<LoadGeometryJob> LoadGeometryJobPtr;

View File

@ -240,28 +240,6 @@ private Q_SLOTS:
}
void checkStatusUpdate()
{
// GIVEN
qRegisterMetaType<Qt3DRender::QMesh::Status>("Status");
MyQMesh mesh;
QSignalSpy spy(&mesh, SIGNAL(statusChanged(Status)));
// THEN
QCOMPARE(mesh.status(), Qt3DRender::QMesh::None);
// WHEN
const Qt3DRender::QMesh::Status newStatus = Qt3DRender::QMesh::Error;
Qt3DCore::QPropertyUpdatedChangePtr e(new Qt3DCore::QPropertyUpdatedChange(mesh.id()));
e->setPropertyName("status");
e->setValue(QVariant::fromValue(newStatus));
mesh.sceneChangeEvent(e);
// THEN
QCOMPARE(mesh.status(), newStatus);
QCOMPARE(spy.count(), 1);
}
void checkGeometryFactoryIsAccessibleEvenWithNoScene() // QTBUG-65506
{
// GIVEN