diff options
author | Antti Määttä <antti.maatta@qt.io> | 2019-04-12 13:54:35 +0300 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2019-05-03 09:34:00 +0000 |
commit | 73ebd0f9cf6376a762c96d37ab6046fefd8d4789 (patch) | |
tree | e415e2af7e30002563422ba9cbec02f3276b013e /src/Runtime/Source/runtimerender | |
parent | ccc70e48e576c0dffc289df4850a909fb6fef83d (diff) |
Implement dynamic loading of slide resources
Implements loading of textures and images during runtime instead of load
time.
- Images which are not part of any slide are loaded at load time
- Master slide images are always loaded at load time
- Images used in a slide are loaded when the slide is entered
- Images are unloaded when slide is exited and any other slide does not
use them
Task-number: QT3DS-3208
Change-Id: I7a827a5e828908efd2b104fe25374c66958319d2
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Runtime/Source/runtimerender')
9 files changed, 300 insertions, 69 deletions
diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp index 3c940805..207059fc 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp @@ -126,7 +126,8 @@ struct SRenderContextCore : public IQt3DSRenderContextCore IRenderPluginManagerCore &GetRenderPluginCore() override { return *m_RenderPluginManagerCore; } IPathManagerCore &GetPathManagerCore() override { return *m_PathManagerCore; } IQt3DSRenderContext &CreateRenderContext(NVRenderContext &inContext, - const char8_t *inPrimitivesDirectory) override; + const char8_t *inPrimitivesDirectory, + bool delayedLoading) override; void SetTextRendererCore(ITextRendererCore &inRenderer) override { m_TextRenderer = inRenderer; } ITextRendererCore *GetTextRendererCore() override { return m_TextRenderer.mPtr; } void setDistanceFieldRenderer(ITextRendererCore &inRenderer) override @@ -263,7 +264,7 @@ struct SRenderContext : public IQt3DSRenderContext bool m_AuthoringMode; SRenderContext(NVRenderContext &ctx, IQt3DSRenderContextCore &inCore, - const char8_t *inApplicationDirectory) + const char8_t *inApplicationDirectory, bool delayedLoading) : m_RenderContext(ctx) , m_CoreContext(inCore) , m_StringTable(ctx.GetStringTable()) @@ -288,6 +289,7 @@ struct SRenderContext : public IQt3DSRenderContext , m_FPS(qMakePair(0.0, 0)) , m_AuthoringMode(false) { + m_BufferManager->enableReloadableResources(delayedLoading); m_OffscreenRenderManager = IOffscreenRenderManager::CreateOffscreenRenderManager( ctx.GetAllocator(), *m_StringTable, *m_ResourceManager, *this); m_Renderer = IQt3DSRenderer::CreateRenderer(*this); @@ -827,10 +829,12 @@ struct SRenderContext : public IQt3DSRenderContext }; IQt3DSRenderContext &SRenderContextCore::CreateRenderContext(NVRenderContext &inContext, - const char8_t *inPrimitivesDirectory) + const char8_t *inPrimitivesDirectory, + bool delayedLoading) { return *QT3DS_NEW(m_Foundation.getAllocator(), SRenderContext)(inContext, *this, - inPrimitivesDirectory); + inPrimitivesDirectory, + delayedLoading); } } diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h index 012864ba..2fcd1e0b 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h @@ -77,7 +77,8 @@ namespace render { virtual ITextRendererCore *GetOnscreenTextRendererCore() = 0; // The render context maintains a reference to this object. virtual IQt3DSRenderContext &CreateRenderContext(NVRenderContext &inContext, - const char8_t *inPrimitivesDirectory) = 0; + const char8_t *inPrimitivesDirectory, + bool delayedLoading) = 0; static IQt3DSRenderContextCore &Create(NVFoundationBase &fnd, IStringTable &strt); }; diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h b/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h index d3698032..aaa73d7e 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h @@ -33,6 +33,9 @@ #include "Qt3DSRender.h" #include "foundation/Qt3DSFlags.h" +#include <QtCore/qsharedpointer.h> +#include <QtCore/qvector.h> + namespace qt3ds { namespace render { @@ -85,9 +88,16 @@ namespace render { Qt3DSRenderPrefilterTexture *m_BSDFMipMap; SImageTextureData() - : m_Texture(NULL) - , m_BSDFMipMap(NULL) + : m_Texture(nullptr) + , m_BSDFMipMap(nullptr) + { + } + + SImageTextureData(const SImageTextureData& data) + : m_Texture(data.m_Texture), m_TextureFlags(data.m_TextureFlags) + , m_BSDFMipMap(data.m_BSDFMipMap) { + } bool operator!=(const SImageTextureData &inOther) @@ -96,7 +106,33 @@ namespace render { || m_BSDFMipMap != inOther.m_BSDFMipMap; } }; + + struct IReloadableCallback + { + virtual ~IReloadableCallback() {} + virtual void onLoad() = 0; + virtual void onUnload() = 0; + }; + + struct SImage; + struct SReloadableImageTextureData : public SImageTextureData + { + QString m_path; + bool m_loaded; + bool m_scanTransparency; + bool m_bsdfMipmap; + bool m_initialized; + QVector<SImage *> m_callbacks; + + SReloadableImageTextureData() + : SImageTextureData() + , m_loaded(false), m_scanTransparency(false), m_bsdfMipmap(false), m_initialized(false) + { + } + }; + + typedef QSharedPointer<SReloadableImageTextureData> ReloadableTexturePtr; } } -#endif
\ No newline at end of file +#endif diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp index 118c855d..05a7b2c4 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp @@ -45,6 +45,7 @@ struct SRenderList : public IRenderList NVFoundationBase &m_Foundation; TTaskList m_Tasks; + TTaskList m_PersistentTasks; QT3DSU32 m_NextTaskId; QT3DSI32 mRefCount; bool m_ScissorEnabled; @@ -54,6 +55,7 @@ struct SRenderList : public IRenderList SRenderList(NVFoundationBase &fnd) : m_Foundation(fnd) , m_Tasks(fnd.getAllocator(), "m_Tasks") + , m_PersistentTasks(fnd.getAllocator(), "m_PersistentTasks") , m_NextTaskId(1) , mRefCount(0) , m_ScissorEnabled(false) @@ -71,8 +73,14 @@ struct SRenderList : public IRenderList QT3DSU32 AddRenderTask(IRenderTask &inTask) override { QT3DSU32 taskId = m_NextTaskId; - ++m_NextTaskId; - m_Tasks.push_back(eastl::make_pair(taskId, &inTask)); + if (inTask.persistent()) { + m_PersistentTasks.push_back(eastl::make_pair(0, &inTask)); + taskId = 0; + } else { + QT3DSU32 taskId = m_NextTaskId; + ++m_NextTaskId; + m_Tasks.push_back(eastl::make_pair(taskId, &inTask)); + } return taskId; } @@ -89,9 +97,15 @@ struct SRenderList : public IRenderList // before rendering to the main render target. void RunRenderTasks() override { + for (TTaskList::reverse_iterator iter = m_PersistentTasks.rbegin(), + end = m_PersistentTasks.rend(); iter != end; + ++iter) { + iter->second->Run(); + } for (TTaskList::reverse_iterator iter = m_Tasks.rbegin(), end = m_Tasks.rend(); iter != end; - ++iter) + ++iter) { iter->second->Run(); + } BeginFrame(); } diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h index c498c7ee..957c3d78 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h +++ b/src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h @@ -42,6 +42,10 @@ namespace render { public: virtual ~IRenderTask() {} virtual void Run() = 0; + virtual bool persistent() const + { + return false; + } }; /** diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp index eaa98c77..1cbd6015 100644 --- a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp @@ -38,9 +38,9 @@ using namespace qt3ds::render; SImage::SImage() : SGraphObject(GraphObjectTypes::Image) - , m_RenderPlugin(NULL) - , m_LastFrameOffscreenRenderer(NULL) - , m_Parent(NULL) + , m_RenderPlugin(nullptr) + , m_LastFrameOffscreenRenderer(nullptr) + , m_Parent(nullptr) , m_Scale(1, 1) , m_Pivot(0, 0) , m_Rotation(0) @@ -84,7 +84,7 @@ bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager } } - if (newImage.m_Texture == NULL) { + if (newImage.m_Texture == nullptr) { if (m_OffscreenRendererId.IsValid()) { SOffscreenRenderResult theResult = inRenderManager.GetRenderedItem(m_OffscreenRendererId); @@ -92,10 +92,26 @@ bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager } } - if (newImage.m_Texture == NULL) { - m_LastFrameOffscreenRenderer = NULL; - newImage = inBufferManager.LoadRenderImage(m_ImagePath, false, forIbl); - replaceTexture = newImage.m_Texture != m_TextureData.m_Texture; + if (newImage.m_Texture == nullptr) { + m_LastFrameOffscreenRenderer = nullptr; + if (m_ImagePath.IsValid()) { + if (!m_LoadedTextureData + || m_LoadedTextureData->m_path != QString::fromUtf8(m_ImagePath.c_str())) { + if (m_LoadedTextureData) + m_LoadedTextureData->m_callbacks.removeOne(this); + m_LoadedTextureData = inBufferManager.CreateReloadableImage(m_ImagePath, false, + forIbl); + m_LoadedTextureData->m_callbacks.push_back(this); + } + if (m_LoadedTextureData) { + if (m_LoadedTextureData->m_loaded) { + newImage.m_Texture = m_LoadedTextureData->m_Texture; + newImage.m_TextureFlags = m_LoadedTextureData->m_TextureFlags; + newImage.m_BSDFMipMap = m_LoadedTextureData->m_BSDFMipMap; + } + replaceTexture = m_TextureData.m_Texture != newImage.m_Texture; + } + } } if (replaceTexture) { diff --git a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h index 47993e73..9b71d3f1 100644 --- a/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h +++ b/src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h @@ -67,6 +67,7 @@ namespace render { SGraphObject *m_Parent; SImageTextureData m_TextureData; + ReloadableTexturePtr m_LoadedTextureData; NodeFlags m_Flags; // only dirty, transform dirty, and active apply diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp index 37ca281f..15cf7323 100644 --- a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp @@ -45,6 +45,7 @@ #include "foundation/Qt3DSFoundation.h" #include "Qt3DSRenderInputStreamFactory.h" #include "Qt3DSRenderImageScaler.h" +#include "Qt3DSRenderImage.h" #include "Qt3DSTextRenderer.h" #include "foundation/Qt3DSPerfTimer.h" #include "foundation/Qt3DSMutex.h" @@ -76,13 +77,13 @@ struct SImageEntry : public SImageTextureData { bool m_Loaded; SImageEntry() - : m_Loaded(false) + : SImageTextureData(), m_Loaded(false) { } - ~SImageEntry() + SImageEntry(const SImageEntry &entry) + : SImageTextureData(entry), m_Loaded(entry.m_Loaded) { - if (m_BSDFMipMap) - m_BSDFMipMap->release(); + } }; @@ -117,6 +118,10 @@ struct SBufferManager : public IBufferManager SPrimitiveEntry m_PrimitiveNames[5]; nvvector<qt3ds::render::NVRenderVertexBufferEntry> m_EntryBuffer; bool m_GPUSupportsDXT; + bool m_reloadableResources; + + QHash<QString, ReloadableTexturePtr> m_reloadableTextures; + static const char8_t *GetPrimitivesDirectory() { return "res//primitives"; } SBufferManager(NVRenderContext &ctx, IStringTable &strTable, @@ -135,6 +140,7 @@ struct SBufferManager : public IBufferManager , m_MeshMap(ctx.GetAllocator(), "SBufferManager::m_MeshMap") , m_EntryBuffer(ctx.GetAllocator(), "SBufferManager::m_EntryBuffer") , m_GPUSupportsDXT(ctx.AreDXTImagesSupported()) + , m_reloadableResources(false) { } virtual ~SBufferManager() { Clear(); } @@ -210,6 +216,15 @@ struct SBufferManager : public IBufferManager return inSourcePath; } + CRegisteredString getImagePath(const QString &path) + { + TAliasImageMap::iterator theAliasIter + = m_AliasImageMap.find(m_StrTable->RegisterStr(qPrintable(path))); + if (theAliasIter != m_AliasImageMap.end()) + return theAliasIter->second; + return m_StrTable->RegisterStr(qPrintable(path)); + } + static inline int wrapMod(int a, int base) { int ret = a % base; @@ -232,6 +247,177 @@ struct SBufferManager : public IBufferManager sY = wrapMod(sY, height); } + template <typename V, typename C> + void iterateAll(const V &vv, C c) + { + for (const auto x : vv) + c(x); + } + + void loadTextureImage(SReloadableImageTextureData &data) + { + CRegisteredString imagePath = getImagePath(data.m_path); + TImageMap::iterator theIter = m_ImageMap.find(imagePath); + if ((theIter == m_ImageMap.end() || theIter->second.m_Loaded == false) + && imagePath.IsValid()) { + NVScopedReleasable<SLoadedTexture> theLoadedImage; + SImageTextureData textureData; + + doImageLoad(imagePath, theLoadedImage); + + if (theLoadedImage) { + textureData = LoadRenderImage(imagePath, *theLoadedImage, data.m_scanTransparency, + data.m_bsdfMipmap); + data.m_Texture = textureData.m_Texture; + data.m_TextureFlags = textureData.m_TextureFlags; + data.m_BSDFMipMap = textureData.m_BSDFMipMap; + data.m_loaded = true; + iterateAll(data.m_callbacks, [](SImage *img){ img->m_Flags.SetDirty(true); }); + } else { + // We want to make sure that bad path fails once and doesn't fail over and over + // again which could slow down the system quite a bit. + pair<TImageMap::iterator, bool> theImage = + m_ImageMap.insert(make_pair(imagePath, SImageEntry())); + theImage.first->second.m_Loaded = true; + qCWarning(WARNING, "Failed to load image: %s", imagePath.c_str()); + theIter = theImage.first; + } + } else { + SImageEntry textureData = theIter->second; + if (textureData.m_Loaded) { + data.m_Texture = textureData.m_Texture; + data.m_TextureFlags = textureData.m_TextureFlags; + data.m_BSDFMipMap = textureData.m_BSDFMipMap; + data.m_loaded = true; + iterateAll(data.m_callbacks, [](SImage *img){ img->m_Flags.SetDirty(true); }); + } + } + } + + void unloadTextureImage(SReloadableImageTextureData &data) + { + CRegisteredString r = m_StrTable->RegisterStr(qPrintable(data.m_path)); + data.m_loaded = false; + data.m_Texture = nullptr; + data.m_BSDFMipMap = nullptr; + data.m_TextureFlags = {}; + iterateAll(data.m_callbacks, [](SImage *img){ img->m_Flags.SetDirty(true); }); + InvalidateBuffer(r); + } + + void loadSet(const QSet<QString> &imageSet) override + { + for (const auto &x : imageSet) { + if (!m_reloadableTextures.contains(x)) { + auto img = CreateReloadableImage(m_StrTable->RegisterStr(qPrintable(x)), false, + false); + img->m_initialized = false; + loadTextureImage(*m_reloadableTextures[x]); + } else if (!m_reloadableTextures[x]->m_loaded) { + loadTextureImage(*m_reloadableTextures[x]); + } + } + } + + void unloadSet(const QSet<QString> &imageSet) override + { + for (const auto &x : imageSet) { + if (m_reloadableTextures.contains(x)) { + if (m_reloadableTextures[x]->m_loaded) + unloadTextureImage(*m_reloadableTextures[x]); + } + } + } + + virtual ReloadableTexturePtr CreateReloadableImage(CRegisteredString inSourcePath, + bool inForceScanForTransparency, + bool inBsdfMipmaps) override + { + QString path = QString::fromLatin1(inSourcePath.c_str()); + const bool inserted = m_reloadableTextures.contains(path); + if (!inserted || (inserted && m_reloadableTextures[path]->m_initialized == false)) { + if (!inserted) + m_reloadableTextures.insert(path, ReloadableTexturePtr::create()); + m_reloadableTextures[path]->m_path = path; + m_reloadableTextures[path]->m_scanTransparency = inForceScanForTransparency; + m_reloadableTextures[path]->m_bsdfMipmap = inBsdfMipmaps; + m_reloadableTextures[path]->m_initialized = true; + + if (!m_reloadableResources) + loadTextureImage(*m_reloadableTextures[path]); + + CRegisteredString imagePath = getImagePath(path); + TImageMap::iterator theIter = m_ImageMap.find(imagePath); + if (theIter != m_ImageMap.end()) { + SImageEntry textureData = theIter->second; + if (textureData.m_Loaded) { + m_reloadableTextures[path]->m_Texture = textureData.m_Texture; + m_reloadableTextures[path]->m_TextureFlags = textureData.m_TextureFlags; + m_reloadableTextures[path]->m_BSDFMipMap = textureData.m_BSDFMipMap; + m_reloadableTextures[path]->m_loaded = true; + } + } + } + return m_reloadableTextures[path]; + } + + void doImageLoad(CRegisteredString inImagePath, + NVScopedReleasable<SLoadedTexture> &theLoadedImage) + { + SStackPerfTimer __perfTimer(m_PerfTimer, "Image Decompression"); + theLoadedImage = SLoadedTexture::Load( + inImagePath.c_str(), m_Context->GetFoundation(), *m_InputStreamFactory, + true, m_Context->GetRenderContextType()); + // Hackish solution to custom materials not finding their textures if they are used + // in sub-presentations. + if (!theLoadedImage) { + if (QDir(inImagePath.c_str()).isRelative()) { + QString searchPath = inImagePath.c_str(); + if (searchPath.startsWith(QLatin1String("./"))) + searchPath.prepend(QLatin1Char('.')); + int loops = 0; + while (!theLoadedImage && ++loops <= 3) { + theLoadedImage = SLoadedTexture::Load( + searchPath.toUtf8(), m_Context->GetFoundation(), + *m_InputStreamFactory, true, + m_Context->GetRenderContextType()); + searchPath.prepend(QLatin1String("../")); + } + } else { + // Some textures, for example environment maps for custom materials, + // have absolute path at this point. It points to the wrong place with + // the new project structure, so we need to split it up and construct + // the new absolute path here. + QString wholePath = inImagePath.c_str(); + QStringList splitPath = wholePath.split(QLatin1String("../")); + if (splitPath.size() > 1) { + QString searchPath = splitPath.at(0) + splitPath.at(1); + int loops = 0; + while (!theLoadedImage && ++loops <= 3) { + theLoadedImage = SLoadedTexture::Load( + searchPath.toUtf8(), m_Context->GetFoundation(), + *m_InputStreamFactory, true, + m_Context->GetRenderContextType()); + searchPath = splitPath.at(0); + for (int i = 0; i < loops; i++) + searchPath.append(QLatin1String("../")); + searchPath.append(splitPath.at(1)); + } + } + } + } + } + + void enableReloadableResources(bool enable) override + { + m_reloadableResources = enable; + } + + bool isReloadableResourcesEnabled() const override + { + return m_reloadableResources; + } + SImageTextureData LoadRenderImage(CRegisteredString inImagePath, SLoadedTexture &inLoadedImage, bool inForceScanForTransparency, bool inBsdfMipmaps) override @@ -336,51 +522,8 @@ struct SBufferManager : public IBufferManager TImageMap::iterator theIter = m_ImageMap.find(inImagePath); if (theIter == m_ImageMap.end() && inImagePath.IsValid()) { NVScopedReleasable<SLoadedTexture> theLoadedImage; - { - SStackPerfTimer __perfTimer(m_PerfTimer, "Image Decompression"); - theLoadedImage = SLoadedTexture::Load( - inImagePath.c_str(), m_Context->GetFoundation(), *m_InputStreamFactory, - true, m_Context->GetRenderContextType()); - // Hackish solution to custom materials not finding their textures if they are used - // in sub-presentations. Note: Runtime 1 is going to be removed in Qt 3D Studio 2.x, - // so this should be ok. - if (!theLoadedImage) { - if (QDir(inImagePath.c_str()).isRelative()) { - QString searchPath = inImagePath.c_str(); - if (searchPath.startsWith(QLatin1String("./"))) - searchPath.prepend(QLatin1String(".")); - int loops = 0; - while (!theLoadedImage && ++loops <= 3) { - theLoadedImage = SLoadedTexture::Load( - searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, - m_Context->GetRenderContextType()); - searchPath.prepend(QLatin1String("../")); - } - } else { - // Some textures, for example environment maps for custom materials, - // have absolute path at this point. It points to the wrong place with - // the new project structure, so we need to split it up and construct - // the new absolute path here. - QString wholePath = inImagePath.c_str(); - QStringList splitPath = wholePath.split(QLatin1String("../")); - if (splitPath.size() > 1) { - QString searchPath = splitPath.at(0) + splitPath.at(1); - int loops = 0; - while (!theLoadedImage && ++loops <= 3) { - theLoadedImage = SLoadedTexture::Load( - searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, - m_Context->GetRenderContextType()); - searchPath = splitPath.at(0); - for (int i = 0; i < loops; i++) - searchPath.append(QLatin1String("../")); - searchPath.append(splitPath.at(1)); - } - } - } - } - } + + doImageLoad(inImagePath, theLoadedImage); if (theLoadedImage) { return LoadRenderImage(inImagePath, *theLoadedImage, inForceScanForTransparency, @@ -862,6 +1005,8 @@ struct SBufferManager : public IBufferManager { if (inEntry.m_Texture) inEntry.m_Texture->release(); + if (inEntry.m_BSDFMipMap) + inEntry.m_BSDFMipMap->release(); } void Clear() override { @@ -916,5 +1061,5 @@ IBufferManager &IBufferManager::Create(NVRenderContext &inRenderContext, IString IInputStreamFactory &inFactory, IPerfTimer &inPerfTimer) { return *QT3DS_NEW(inRenderContext.GetAllocator(), SBufferManager)(inRenderContext, inStrTable, - inFactory, inPerfTimer); + inFactory, inPerfTimer); } diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h index cd9e3d33..d595c902 100644 --- a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h @@ -83,6 +83,16 @@ namespace render { virtual SImageTextureData LoadRenderImage(CRegisteredString inSourcePath, bool inForceScanForTransparency = false, bool inBsdfMipmaps = false) = 0; + + virtual ReloadableTexturePtr CreateReloadableImage(CRegisteredString inSourcePath, + bool inForceScanForTransparency = false, + bool inBsdfMipmaps = false) = 0; + virtual void enableReloadableResources(bool enable) = 0; + virtual bool isReloadableResourcesEnabled() const = 0; + + virtual void loadSet(const QSet<QString> &imageSet) = 0; + virtual void unloadSet(const QSet<QString> &imageSet) = 0; + virtual SRenderMesh *LoadMesh(CRegisteredString inSourcePath) = 0; virtual SRenderMesh *CreateMesh(const char *inSourcePath, QT3DSU8 *inVertData, |