diff options
Diffstat (limited to 'src/runtime/q3dsimagemanager_p.h')
-rw-r--r-- | src/runtime/q3dsimagemanager_p.h | 117 |
1 files changed, 107 insertions, 10 deletions
diff --git a/src/runtime/q3dsimagemanager_p.h b/src/runtime/q3dsimagemanager_p.h index ac768bc..1c89467 100644 --- a/src/runtime/q3dsimagemanager_p.h +++ b/src/runtime/q3dsimagemanager_p.h @@ -50,6 +50,7 @@ #include <QThreadPool> #include <Qt3DRender/QAbstractTexture> #include <Qt3DRender/QTextureImageData> +#include <Qt3DRender/QParameter> QT_BEGIN_NAMESPACE @@ -59,6 +60,85 @@ namespace Qt3DCore { class QEntity; } +class ReloadableTexture +{ +public: + ReloadableTexture(Qt3DCore::QEntity *parent, bool generateIBL, const QByteArray &id, + const QString &profileInfo, Q3DSProfiler *profiler) + : m_parent(parent), m_id(id), m_profileInfo(profileInfo), m_generateIBL(generateIBL), + m_profiler(profiler) + { + + } + void setSource(const QUrl &source); + + template <typename Caller, typename... Params> + void onLoad(Caller caller, Params... params) + { + m_loadFunc = [this, caller, params...]() { + caller(m_texture, params...); + }; + // onLoad call might provide new parameters when called after loading so call it now + if (m_loaded) + m_loadFunc(); + else + triggerLoading(); + } + + template <typename Caller, typename... Params> + void onUnload(Caller caller, Params... params) + { + m_unloadFunc = [this, caller, params...]() { + caller(m_texture, params...); + }; + triggerLoading(); + } + + void reload(); + void unload(); + + QUrl source() const + { + return m_source; + } + void loaded(Qt3DRender::QAbstractTexture *texture); + bool wasLoaded() const + { + return m_loaded; + } + Qt3DRender::QAbstractTexture *texture() + { + return m_texture; + } + + QString info() + { + return m_profileInfo; + } + + Q3DSProfiler *profiler() + { + return m_profiler; + } + +private: + void triggerLoading(); + + Qt3DCore::QEntity *m_parent = nullptr; + Qt3DRender::QAbstractTexture *m_texture = nullptr; + QByteArray m_id; + QString m_profileInfo; + QUrl m_source; + bool m_generateIBL = false; + bool m_loaded = false; + Q3DSProfiler *m_profiler = nullptr; + + std::function<void()> m_loadFunc = nullptr; + std::function<void()> m_unloadFunc = nullptr; +}; + +typedef QSharedPointer<ReloadableTexture> ReloadableTexturePtr; + class Q3DSImageManager { public: @@ -76,9 +156,13 @@ public: ImageFlags flags, const QByteArray &id, Q3DSProfiler *profiler = nullptr, - const char *profName = nullptr, ...); - void setSource(Qt3DRender::QAbstractTexture *tex, const QUrl &source, bool preferKtx, - bool async = true); + const QString &profilerInfo = {}); + ReloadableTexturePtr newReloadableTextureForImage(Qt3DCore::QEntity *parent, + ImageFlags flags, + const QByteArray &id, + Q3DSProfiler *profiler = nullptr, + const char *profName = nullptr, ...); + void setSource(Qt3DRender::QAbstractTexture *tex, const QImage &image); QSize size(Qt3DRender::QAbstractTexture *tex) const; @@ -88,14 +172,23 @@ public: qint64 ioTimeMsecs() const { return m_ioTime; } qint64 iblTimeMsecs() const { return m_iblTime; } - void finishAsyncLoad(); + void finishAsyncLoad(bool wait = true); + void beginImageLoad(const QSet<QUrl> &imageSet); + void beginUnload(const QSet<QUrl> &imageSet); + bool inResourceSet(const QUrl &url) const; private: - QVector<Qt3DRender::QTextureImageDataPtr> load(const QUrl &source, ImageFlags flags, bool *wasCached); + void loadImageData(const QUrl &source, bool async = true); + void setSource(Qt3DRender::QAbstractTexture *tex, const QUrl &source); + void textureLoaded(Qt3DRender::QAbstractTexture *tex, const QUrl &source); + QVector<Qt3DRender::QTextureImageDataPtr> load(const QUrl &source); int blockSizeForFormat(QOpenGLTexture::TextureFormat format); QByteArray generateIblMip(int w, int h, int prevW, int prevH, QOpenGLTexture::TextureFormat format, int blockSize, const QByteArray &prevLevelData); + QVector<Qt3DRender::QTextureImageDataPtr> generateIblForImageData( + QVector<Qt3DRender::QTextureImageDataPtr> result); + struct TextureInfo { ImageFlags flags; @@ -105,22 +198,26 @@ private: bool wasCached = false; }; - struct TextureImageAsyncLoad + struct LoadImageDataAsync { QFuture<void> future; - Qt3DRender::QAbstractTexture *tex = nullptr; - QUrl source; + QString source; bool preferKtx = false; + bool done = false; }; + QVector<ReloadableTexturePtr> m_reloadableTextures; + QSet<QUrl> m_resourceSet; QHash<Qt3DRender::QAbstractTexture *, TextureInfo> m_metadata; QHash<QString, QVector<Qt3DRender::QTextureImageDataPtr> > m_cache; - QHash<QString, bool> m_loadImageAsync; - QVector<TextureImageAsyncLoad> m_setSourceAsync; + QHash<QString, LoadImageDataAsync> m_loadImageDataAsync; + QHash<QString, QVector<Qt3DRender::QAbstractTexture *> *> m_pendingSetSource; QThreadPool m_threadPool; static QMutex s_loadMutex; qint64 m_ioTime = 0; qint64 m_iblTime = 0; + QMutex m_finishAsyncLoadLock; + friend ReloadableTexture; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Q3DSImageManager::ImageFlags) |