diff options
Diffstat (limited to 'src/render/io')
-rw-r--r-- | src/render/io/glbuffer.cpp | 12 | ||||
-rw-r--r-- | src/render/io/glbuffer_p.h | 2 | ||||
-rw-r--r-- | src/render/io/qgeometryloaderfactory_p.h | 1 | ||||
-rw-r--r-- | src/render/io/qsceneimporter_p.h | 3 | ||||
-rw-r--r-- | src/render/io/qsceneloader.cpp | 28 | ||||
-rw-r--r-- | src/render/io/qsceneloader.h | 8 | ||||
-rw-r--r-- | src/render/io/qsceneloader_p.h | 2 | ||||
-rw-r--r-- | src/render/io/scene.cpp | 14 | ||||
-rw-r--r-- | src/render/io/scenemanager.cpp | 65 | ||||
-rw-r--r-- | src/render/io/scenemanager_p.h | 28 |
10 files changed, 136 insertions, 27 deletions
diff --git a/src/render/io/glbuffer.cpp b/src/render/io/glbuffer.cpp index 074868528..4918f9a56 100644 --- a/src/render/io/glbuffer.cpp +++ b/src/render/io/glbuffer.cpp @@ -140,6 +140,18 @@ void GLBuffer::update(GraphicsContext *ctx, const void *data, uint size, int off ctx->openGLContext()->functions()->glBufferSubData(m_lastTarget, offset, size, data); } +QByteArray GLBuffer::download(GraphicsContext *ctx, uint size) +{ + char *gpu_ptr = ctx->mapBuffer(m_lastTarget); + QByteArray data; + if (gpu_ptr != nullptr) { + data.resize(size); + std::copy(gpu_ptr, gpu_ptr+size, data.data()); + } + ctx->unmapBuffer(m_lastTarget); + return data; +} + void GLBuffer::bindBufferBase(GraphicsContext *ctx, int bindingPoint, GLBuffer::Type t) { ctx->bindBufferBase(glBufferTypes[t], bindingPoint, m_bufferId); diff --git a/src/render/io/glbuffer_p.h b/src/render/io/glbuffer_p.h index e800d2bc4..731634b6b 100644 --- a/src/render/io/glbuffer_p.h +++ b/src/render/io/glbuffer_p.h @@ -53,6 +53,7 @@ #include <QOpenGLContext> #include <Qt3DCore/qnodeid.h> +#include <qbytearray.h> QT_BEGIN_NAMESPACE @@ -85,6 +86,7 @@ public: void allocate(GraphicsContext *ctx, uint size, bool dynamic = true); void allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic = true); void update(GraphicsContext *ctx, const void *data, uint size, int offset = 0); + QByteArray download(GraphicsContext *ctx, uint size); void bindBufferBase(GraphicsContext *ctx, int bindingPoint, Type t); void bindBufferBase(GraphicsContext *ctx, int bindingPoint); diff --git a/src/render/io/qgeometryloaderfactory_p.h b/src/render/io/qgeometryloaderfactory_p.h index c6a7344ce..6e0044c4a 100644 --- a/src/render/io/qgeometryloaderfactory_p.h +++ b/src/render/io/qgeometryloaderfactory_p.h @@ -68,6 +68,7 @@ class QGeometryLoaderInterface; class QT3DRENDERSHARED_PRIVATE_EXPORT QGeometryLoaderFactory : public QObject, public QFactoryInterface { Q_OBJECT + Q_INTERFACES(QFactoryInterface) public: explicit QGeometryLoaderFactory(QObject *parent = nullptr); virtual ~QGeometryLoaderFactory(); diff --git a/src/render/io/qsceneimporter_p.h b/src/render/io/qsceneimporter_p.h index e76eb8780..8f83231c3 100644 --- a/src/render/io/qsceneimporter_p.h +++ b/src/render/io/qsceneimporter_p.h @@ -86,7 +86,8 @@ public: virtual ~QSceneImporter(); virtual void setSource(const QUrl &source) = 0; - virtual bool isFileTypeSupported(const QUrl &source) const = 0; + virtual void setData(const QByteArray& data, const QString &basePath) = 0; + virtual bool areFileTypesSupported(const QStringList &extensions) const = 0; virtual Qt3DCore::QEntity *scene(const QString &id = QString()) = 0; virtual Qt3DCore::QEntity *node(const QString &id) = 0; diff --git a/src/render/io/qsceneloader.cpp b/src/render/io/qsceneloader.cpp index b9408298f..3bc842c3d 100644 --- a/src/render/io/qsceneloader.cpp +++ b/src/render/io/qsceneloader.cpp @@ -198,7 +198,8 @@ void QSceneLoaderPrivate::populateEntityMap(QEntity *parentEntity) { // Topmost parent entity is not considered part of the scene as that is typically // an unnamed entity inserted by importer. - for (auto childNode : parentEntity->childNodes()) { + const QNodeVector childNodes = parentEntity->childNodes(); + for (auto childNode : childNodes) { auto childEntity = qobject_cast<QEntity *>(childNode); if (childEntity) { m_entityMap.insert(childEntity->objectName(), childEntity); @@ -207,6 +208,17 @@ void QSceneLoaderPrivate::populateEntityMap(QEntity *parentEntity) } } +void QSceneLoaderPrivate::setStatus(QSceneLoader::Status status) +{ + if (m_status != status) { + Q_Q(QSceneLoader); + m_status = status; + const bool wasBlocked = q->blockNotifications(true); + emit q->statusChanged(status); + q->blockNotifications(wasBlocked); + } +} + /*! The constructor creates an instance with the specified \a parent. */ @@ -253,7 +265,7 @@ void QSceneLoader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) d->populateEntityMap(d->m_subTreeRoot); } } else if (e->propertyName() == QByteArrayLiteral("status")) { - setStatus(e->value().value<QSceneLoader::Status>()); + d->setStatus(e->value().value<QSceneLoader::Status>()); } } } @@ -328,7 +340,7 @@ QStringList QSceneLoader::entityNames() const \sa Qt3DRender::QSceneLoader::ComponentType */ /*! - Returns a component matching \a componentType of a loaded entity with an \a objectName matching + Returns a component matching \a componentType of a loaded entity with an objectName matching the \a entityName. If the entity has multiple matching components, the first match in the component list of the entity is returned. @@ -338,7 +350,8 @@ QComponent *QSceneLoader::component(const QString &entityName, QSceneLoader::ComponentType componentType) const { QEntity *e = entity(entityName); - for (auto component : e->components()) { + const QComponentVector components = e->components(); + for (auto component : components) { switch (componentType) { case GeometryRendererComponent: if (qobject_cast<Qt3DRender::QGeometryRenderer *>(component)) @@ -371,12 +384,7 @@ QComponent *QSceneLoader::component(const QString &entityName, void QSceneLoader::setStatus(QSceneLoader::Status status) { Q_D(QSceneLoader); - if (d->m_status != status) { - d->m_status = status; - const bool wasBlocked = blockNotifications(true); - emit statusChanged(status); - blockNotifications(wasBlocked); - } + d->setStatus(status); } Qt3DCore::QNodeCreatedChangeBasePtr QSceneLoader::createNodeCreationChange() const diff --git a/src/render/io/qsceneloader.h b/src/render/io/qsceneloader.h index 76f8c4d80..31ec47ac0 100644 --- a/src/render/io/qsceneloader.h +++ b/src/render/io/qsceneloader.h @@ -82,10 +82,10 @@ public: QUrl source() const; Status status() const; - Q_INVOKABLE Qt3DCore::QEntity *entity(const QString &entityName) const; - Q_INVOKABLE QStringList entityNames() const; - Q_INVOKABLE Qt3DCore::QComponent *component(const QString &entityName, - ComponentType componentType) const; + Q_REVISION(9) Q_INVOKABLE Qt3DCore::QEntity *entity(const QString &entityName) const; + Q_REVISION(9) Q_INVOKABLE QStringList entityNames() const; + Q_REVISION(9) Q_INVOKABLE Qt3DCore::QComponent *component(const QString &entityName, + ComponentType componentType) const; public Q_SLOTS: void setSource(const QUrl &arg); diff --git a/src/render/io/qsceneloader_p.h b/src/render/io/qsceneloader_p.h index 13569ea70..45a6a1a4e 100644 --- a/src/render/io/qsceneloader_p.h +++ b/src/render/io/qsceneloader_p.h @@ -66,6 +66,8 @@ class QT3DRENDERSHARED_PRIVATE_EXPORT QSceneLoaderPrivate : public Qt3DCore::QCo public: QSceneLoaderPrivate(); + void setStatus(QSceneLoader::Status status); + Q_DECLARE_PUBLIC(QSceneLoader) void populateEntityMap(Qt3DCore::QEntity *parentEntity); diff --git a/src/render/io/scene.cpp b/src/render/io/scene.cpp index 2057ffd3d..7ae6f9473 100644 --- a/src/render/io/scene.cpp +++ b/src/render/io/scene.cpp @@ -42,11 +42,11 @@ #include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/private/qnode_p.h> #include <Qt3DCore/private/qscene_p.h> +#include <Qt3DCore/private/qdownloadhelperservice_p.h> #include <Qt3DRender/qsceneloader.h> #include <Qt3DRender/private/qsceneloader_p.h> #include <Qt3DRender/private/scenemanager_p.h> #include <QtCore/qcoreapplication.h> -#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h> QT_BEGIN_NAMESPACE @@ -73,7 +73,6 @@ void Scene::setStatus(QSceneLoader::Status status) e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); e->setPropertyName("status"); e->setValue(QVariant::fromValue(status)); - Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isFinal = true; notifyObservers(e); } @@ -83,7 +82,10 @@ void Scene::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change const auto &data = typedChange->data; m_source = data.source; Q_ASSERT(m_sceneManager); - m_sceneManager->addSceneData(m_source, peerId()); + if (Qt3DCore::QDownloadHelperService::isLocal(m_source)) + m_sceneManager->addSceneData(m_source, peerId()); + else + m_sceneManager->startSceneDownload(m_source, peerId()); } void Scene::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -92,7 +94,10 @@ void Scene::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e); if (propertyChange->propertyName() == QByteArrayLiteral("source")) { m_source = propertyChange->value().toUrl(); - m_sceneManager->addSceneData(m_source, peerId()); + if (Qt3DCore::QDownloadHelperService::isLocal(m_source)) + m_sceneManager->addSceneData(m_source, peerId()); + else + m_sceneManager->startSceneDownload(m_source, peerId()); } } markDirty(AbstractRenderer::AllDirty); @@ -116,7 +121,6 @@ void Scene::setSceneSubtree(Qt3DCore::QEntity *subTree) e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); e->setPropertyName("scene"); e->setValue(QVariant::fromValue(subTree)); - Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isFinal = true; notifyObservers(e); } diff --git a/src/render/io/scenemanager.cpp b/src/render/io/scenemanager.cpp index d59391a87..b0a595905 100644 --- a/src/render/io/scenemanager.cpp +++ b/src/render/io/scenemanager.cpp @@ -44,18 +44,34 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -SceneManager::SceneManager() : Qt3DCore::QResourceManager<Scene, - Qt3DCore::QNodeId, - 8, - Qt3DCore::ArrayAllocatingPolicy, - Qt3DCore::ObjectLevelLockingPolicy>() +SceneManager::SceneManager() + : Qt3DCore::QResourceManager<Scene, + Qt3DCore::QNodeId, + 8, + Qt3DCore::ArrayAllocatingPolicy, + Qt3DCore::ObjectLevelLockingPolicy>() + , m_service(nullptr) { } -void SceneManager::addSceneData(const QUrl &source, Qt3DCore::QNodeId sceneUuid) +SceneManager::~SceneManager() +{ +} + +void SceneManager::setDownloadService(Qt3DCore::QDownloadHelperService *service) +{ + m_service = service; +} + +void SceneManager::addSceneData(const QUrl &source, + Qt3DCore::QNodeId sceneUuid, + const QByteArray &data) { LoadSceneJobPtr newJob(new LoadSceneJob(source, sceneUuid)); + if (!data.isEmpty()) + newJob->setData(data); + // We cannot run two jobs that use the same scene loader plugin // in two different threads at the same time if (!m_pendingJobs.isEmpty()) @@ -70,6 +86,43 @@ QVector<LoadSceneJobPtr> SceneManager::pendingSceneLoaderJobs() return std::move(m_pendingJobs); } +void SceneManager::startSceneDownload(const QUrl &source, Qt3DCore::QNodeId sceneUuid) +{ + if (!m_service) + return; + SceneDownloaderPtr request = SceneDownloaderPtr::create(source, sceneUuid, this); + m_pendingDownloads << request; + m_service->submitRequest(request); +} + +void SceneManager::clearSceneDownload(SceneDownloader *downloader) +{ + for (auto it = m_pendingDownloads.begin(); it != m_pendingDownloads.end(); ++it) { + if ((*it).data() == downloader) { + m_pendingDownloads.erase(it); + return; + } + } +} + + +SceneDownloader::SceneDownloader(const QUrl &source, Qt3DCore::QNodeId sceneComponent, SceneManager *manager) + : Qt3DCore::QDownloadRequest(source) + , m_sceneComponent(sceneComponent) + , m_manager(manager) +{ + +} + +void SceneDownloader::onCompleted() +{ + if (!m_manager) + return; + if (succeeded()) + m_manager->addSceneData(url(), m_sceneComponent, m_data); + m_manager->clearSceneDownload(this); +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/io/scenemanager_p.h b/src/render/io/scenemanager_p.h index 164f82590..9993c85fc 100644 --- a/src/render/io/scenemanager_p.h +++ b/src/render/io/scenemanager_p.h @@ -52,6 +52,7 @@ // #include <Qt3DCore/private/qresourcemanager_p.h> +#include <Qt3DCore/private/qdownloadhelperservice_p.h> #include <Qt3DRender/private/scene_p.h> #include <Qt3DCore/qnodeid.h> #include <Qt3DRender/private/loadscenejob_p.h> @@ -65,6 +66,22 @@ class QEntity; namespace Qt3DRender { namespace Render { +class SceneManager; + +class SceneDownloader : public Qt3DCore::QDownloadRequest { +public: + SceneDownloader(const QUrl &source, Qt3DCore::QNodeId sceneComponent, SceneManager* manager); + + void onCompleted() Q_DECL_OVERRIDE; + +private: + Qt3DCore::QNodeId m_sceneComponent; + SceneManager* m_manager; +}; + +typedef QSharedPointer<SceneDownloader> SceneDownloaderPtr; + + class Q_AUTOTEST_EXPORT SceneManager : public Qt3DCore::QResourceManager< Scene, Qt3DCore::QNodeId, @@ -74,12 +91,21 @@ class Q_AUTOTEST_EXPORT SceneManager : public Qt3DCore::QResourceManager< { public: SceneManager(); + ~SceneManager(); - void addSceneData(const QUrl &source, Qt3DCore::QNodeId sceneUuid); + void setDownloadService(Qt3DCore::QDownloadHelperService *service); + + void addSceneData(const QUrl &source, Qt3DCore::QNodeId sceneUuid, + const QByteArray &data = QByteArray()); QVector<LoadSceneJobPtr> pendingSceneLoaderJobs(); + void startSceneDownload(const QUrl &source, Qt3DCore::QNodeId sceneUuid); + void clearSceneDownload(SceneDownloader *downloader); + private: + Qt3DCore::QDownloadHelperService *m_service; QVector<LoadSceneJobPtr> m_pendingJobs; + QVector<SceneDownloaderPtr> m_pendingDownloads; }; } // namespace Render |