summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/runtimerender
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2019-04-12 13:54:35 +0300
committerAntti Määttä <antti.maatta@qt.io>2019-05-03 09:34:00 +0000
commit73ebd0f9cf6376a762c96d37ab6046fefd8d4789 (patch)
treee415e2af7e30002563422ba9cbec02f3276b013e /src/Runtime/Source/runtimerender
parentccc70e48e576c0dffc289df4850a909fb6fef83d (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')
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp12
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h3
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderImageTextureData.h42
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.cpp20
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderRenderList.h4
-rw-r--r--src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.cpp32
-rw-r--r--src/Runtime/Source/runtimerender/graphobjects/Qt3DSRenderImage.h1
-rw-r--r--src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp245
-rw-r--r--src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h10
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,