summaryrefslogtreecommitdiffstats
path: root/src/render/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/io')
-rw-r--r--src/render/io/glbuffer.cpp12
-rw-r--r--src/render/io/glbuffer_p.h2
-rw-r--r--src/render/io/qgeometryloaderfactory_p.h1
-rw-r--r--src/render/io/qsceneimporter_p.h3
-rw-r--r--src/render/io/qsceneloader.cpp28
-rw-r--r--src/render/io/qsceneloader.h8
-rw-r--r--src/render/io/qsceneloader_p.h2
-rw-r--r--src/render/io/scene.cpp14
-rw-r--r--src/render/io/scenemanager.cpp65
-rw-r--r--src/render/io/scenemanager_p.h28
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