summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2019-05-20 15:34:05 +0300
committerAntti Määttä <antti.maatta@qt.io>2019-05-22 13:32:14 +0300
commita32488dcdcd84eea08b3070395009a8af6caedec (patch)
tree2ff3289f66e80e857748156d57fa158be0592f91
parent5f7a8fba3b56ec0fc44e2cd3ba4fc91195054fed (diff)
Load slide images in background thread
Use the existing batch loading to load images in a slide in the background. Task-number: QT3DS-3385 Change-Id: I68097afb94f643696d0783c9980553c31c80d6cb Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Jari Karppinen <jari.karppinen@qt.io> Reviewed-by: Jere Tuliniemi <jere.tuliniemi@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Authoring/Studio/Render/StudioRendererTranslation.cpp2
-rw-r--r--src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp10
-rw-r--r--src/Runtime/Source/runtime/Qt3DSApplication.cpp89
-rw-r--r--src/Runtime/Source/runtime/Qt3DSIScene.h2
-rw-r--r--src/Runtime/Source/runtime/Qt3DSSceneManager.h2
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp4
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h2
-rw-r--r--src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp11
-rw-r--r--src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h2
-rw-r--r--src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp2
10 files changed, 97 insertions, 29 deletions
diff --git a/src/Authoring/Studio/Render/StudioRendererTranslation.cpp b/src/Authoring/Studio/Render/StudioRendererTranslation.cpp
index d2e92f67..82678986 100644
--- a/src/Authoring/Studio/Render/StudioRendererTranslation.cpp
+++ b/src/Authoring/Studio/Render/StudioRendererTranslation.cpp
@@ -2439,7 +2439,7 @@ void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPa
if (m_Scene) {
// Note that begin frame is called before we allocate the bounding box and axis widgets so
// that we can take advantage of the renderer's per-frame-allocator.
- m_Context.BeginFrame();
+ m_Context.BeginFrame(true);
qt3dsdm::TInstanceHandleList theHandles = m_Doc.GetSelectedValue().GetSelectedInstances();
diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp
index 1ffb7141..2c15e0e5 100644
--- a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp
+++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBinding.cpp
@@ -200,6 +200,11 @@ struct Qt3DSRenderScene : public Q3DStudio::IScene
qt3ds::NVAllocatorCallback &allocator() override { return m_LoadData->m_AutoAllocator; }
Q3DStudio::IPresentation &GetPresentation() override { return *m_RuntimePresentation; }
+ bool preferKtx() const override
+ {
+ return m_Presentation->m_preferKTX;
+ }
+
// Update really just adds objects to the dirty set
bool Update()
{
@@ -1555,7 +1560,8 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager,
return theResult;
}
- Q3DStudio::BOOL RenderPresentation(Q3DStudio::IPresentation *inPresentation) override
+ Q3DStudio::BOOL RenderPresentation(Q3DStudio::IPresentation *inPresentation,
+ bool firstFrame) override
{
Qt3DSRenderScene *theFirstScene = nullptr;
for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end && theFirstScene == nullptr; ++idx)
@@ -1584,7 +1590,7 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager,
(QT3DSU32)theFirstScene->m_Presentation->m_PresentationDimensions.y));
}
- m_Context->m_Context->BeginFrame();
+ m_Context->m_Context->BeginFrame(firstFrame);
m_Context->m_RenderContext->ResetBlendState();
// How exactly does this work, I have no idea.
diff --git a/src/Runtime/Source/runtime/Qt3DSApplication.cpp b/src/Runtime/Source/runtime/Qt3DSApplication.cpp
index 1b518e9f..3549957f 100644
--- a/src/Runtime/Source/runtime/Qt3DSApplication.cpp
+++ b/src/Runtime/Source/runtime/Qt3DSApplication.cpp
@@ -79,6 +79,7 @@
#include "Qt3DSQmlElementHelper.h"
#include "Qt3DSRenderBufferManager.h"
#include "Qt3DSRenderRenderList.h"
+#include "Qt3DSRenderImageBatchLoader.h"
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qpair.h>
#include <QtCore/qdir.h>
@@ -303,40 +304,85 @@ struct SSlideResourceCounter
}
};
-struct STextureUploadRenderTask : public IRenderTask
+struct STextureUploadRenderTask : public IRenderTask, public IImageLoadListener
{
+ IImageBatchLoader &m_batchLoader;
IBufferManager &m_bufferManager;
+ NVRenderContextType m_type;
+ bool m_preferKtx;
QSet<QString> m_uploadSet;
+ QSet<QString> m_uploadWaitSet;
QSet<QString> m_deleteSet;
QMutex m_updateMutex;
+ QHash<QT3DSU32, QSet<QString>> m_batches;
+ volatile QT3DSI32 mRefCount;
- STextureUploadRenderTask(IBufferManager &mgr)
- : m_bufferManager(mgr)
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_bufferManager.GetStringTable()
+ .GetAllocator())
+
+ STextureUploadRenderTask(IImageBatchLoader &loader, IBufferManager &mgr,
+ NVRenderContextType type, bool preferKtx)
+ : m_batchLoader(loader), m_bufferManager(mgr), m_type(type), m_preferKtx(preferKtx),
+ mRefCount(0)
{
}
void Run() override
{
QMutexLocker loc(&m_updateMutex);
- m_bufferManager.loadSet(m_uploadSet);
+ if (!m_uploadSet.isEmpty()) {
+ nvvector<CRegisteredString> sourcePaths(m_bufferManager.GetStringTable().GetAllocator(),
+ "TempSourcePathList");
+ for (auto &s : qAsConst(m_uploadSet))
+ sourcePaths.push_back(m_bufferManager.GetStringTable().RegisterStr(s));
+ QT3DSU32 id = m_batchLoader.LoadImageBatch(sourcePaths, CRegisteredString(),
+ this, m_type, m_preferKtx);
+ if (id)
+ m_batches[id] = m_uploadSet;
+ }
+ if (!m_uploadWaitSet.isEmpty()) {
+ nvvector<CRegisteredString> sourcePaths(m_bufferManager.GetStringTable().GetAllocator(),
+ "TempSourcePathList");
+ for (auto &s : qAsConst(m_uploadWaitSet))
+ sourcePaths.push_back(m_bufferManager.GetStringTable().RegisterStr(s));
+ QT3DSU32 id = m_batchLoader.LoadImageBatch(sourcePaths, CRegisteredString(),
+ this, m_type, m_preferKtx);
+ if (id) {
+ m_batchLoader.BlockUntilLoaded(id);
+ m_bufferManager.loadSet(m_uploadWaitSet);
+ }
+ }
m_bufferManager.unloadSet(m_deleteSet);
}
- void add(const QSet<QString> &set)
+ void add(const QSet<QString> &set, bool wait)
{
QMutexLocker loc(&m_updateMutex);
- m_uploadSet.unite(set);
+ if (wait)
+ m_uploadWaitSet.unite(set);
+ else
+ m_uploadSet.unite(set);
m_deleteSet.subtract(set);
}
void remove(const QSet<QString> &set)
{
QMutexLocker loc(&m_updateMutex);
m_uploadSet.subtract(set);
+ m_uploadWaitSet.subtract(set);
m_deleteSet.unite(set);
}
bool persistent() const override
{
return true;
}
+ void OnImageLoadComplete(CRegisteredString inPath, ImageLoadResult::Enum inResult) override
+ {
+ Q_UNUSED(inPath);
+ Q_UNUSED(inResult);
+ }
+ void OnImageBatchComplete(QT3DSU64 inBatch) override
+ {
+ m_bufferManager.loadSet(m_batches[inBatch]);
+ }
};
struct SApp;
@@ -562,7 +608,7 @@ struct SApp : public IApplication
// the name of the file without extension.
eastl::string m_Filename;
Q3DSVariantConfig m_variantConfig;
- QScopedPointer<STextureUploadRenderTask> m_uploadRenderTask;
+ NVScopedRefCounted<STextureUploadRenderTask> m_uploadRenderTask;
qt3ds::foundation::NVScopedReleasable<IRuntimeMetaData> m_MetaData;
nvvector<eastl::pair<SBehaviorAsset, bool>> m_Behaviors;
@@ -598,6 +644,8 @@ struct SApp : public IApplication
DataInputMap m_dataInputDefs;
+ bool m_initialFrame = true;
+
SSlideResourceCounter m_resourceCounter;
QSet<QString> m_createSet;
@@ -958,8 +1006,11 @@ struct SApp : public IApplication
{
SStackPerfTimer __updateTimer(m_RuntimeFactory->GetPerfTimer(), "Render");
CPresentation *pres = GetPrimaryPresentation();
- if (pres)
- m_LastRenderWasDirty = m_RuntimeFactory->GetSceneManager().RenderPresentation(pres);
+ if (pres) {
+ m_LastRenderWasDirty = m_RuntimeFactory->GetSceneManager()
+ .RenderPresentation(pres, m_initialFrame);
+ m_initialFrame = false;
+ }
}
void ResetDirtyCounter() { m_DirtyCountdown = 5; }
@@ -1049,7 +1100,7 @@ struct SApp : public IApplication
////////////////////////////////////////////////////////////////////////////////
void loadComponentSlideResources(TElement *component, CPresentation *presentation, int index,
- const QString slideName)
+ const QString slideName, bool wait)
{
if (m_RuntimeFactory->GetQt3DSRenderContext().GetBufferManager()
.isReloadableResourcesEnabled()) {
@@ -1063,7 +1114,7 @@ struct SApp : public IApplication
qCInfo(PERF_INFO) << "Load component slide resources: " << completeName;
m_resourceCounter.handleLoadSlide(completeName, key, slidesystem);
if (m_uploadRenderTask)
- m_uploadRenderTask->add(m_resourceCounter.createSet);
+ m_uploadRenderTask->add(m_resourceCounter.createSet, wait);
else
m_createSet.unite(m_resourceCounter.createSet);
}
@@ -1141,7 +1192,7 @@ struct SApp : public IApplication
QVector<TElement *> components;
thePresentation->GetRoot()->findComponents(components);
for (auto &component : qAsConst(components))
- loadComponentSlideResources(component, thePresentation, 0, "Master");
+ loadComponentSlideResources(component, thePresentation, 0, "Master", true);
return true;
}
@@ -1448,7 +1499,7 @@ struct SApp : public IApplication
QString slideName;
int index;
if (presentationComponentSlide(slide, pres, component, slideName, index))
- loadComponentSlideResources(component, pres, index, slideName);
+ loadComponentSlideResources(component, pres, index, slideName, false);
}
void unloadSlide(const QString &slide) override
@@ -1472,7 +1523,7 @@ struct SApp : public IApplication
const QString &elementPath, int slideIndex,
const QString &slideName) override
{
- loadComponentSlideResources(component, presentation, slideIndex, slideName);
+ loadComponentSlideResources(component, presentation, slideIndex, slideName, true);
}
void ComponentSlideExited(Q3DStudio::CPresentation *presentation,
@@ -1556,9 +1607,13 @@ struct SApp : public IApplication
m_AudioPlayer.SetPlayer(inAudioPlayer);
- m_uploadRenderTask.reset(new STextureUploadRenderTask(
- m_RuntimeFactory->GetQt3DSRenderContext().GetBufferManager()));
- m_uploadRenderTask->add(m_createSet);
+ auto &rc = m_RuntimeFactory->GetQt3DSRenderContext();
+ m_uploadRenderTask = QT3DS_NEW(m_CoreFactory->GetFoundation().getAllocator(),
+ STextureUploadRenderTask(rc.GetImageBatchLoader(),
+ rc.GetBufferManager(),
+ rc.GetRenderContext().GetRenderContextType(),
+ GetPrimaryPresentation()->GetScene()->preferKtx()));
+ m_uploadRenderTask->add(m_createSet, true);
m_RuntimeFactory->GetQt3DSRenderContext().GetRenderList()
.AddRenderTask(*m_uploadRenderTask);
m_createSet.clear();
diff --git a/src/Runtime/Source/runtime/Qt3DSIScene.h b/src/Runtime/Source/runtime/Qt3DSIScene.h
index 83347e11..7494ab0f 100644
--- a/src/Runtime/Source/runtime/Qt3DSIScene.h
+++ b/src/Runtime/Source/runtime/Qt3DSIScene.h
@@ -157,6 +157,8 @@ public: // Base Interface
virtual void Release() = 0;
+ virtual bool preferKtx() const = 0;
+
virtual qt3ds::NVAllocatorCallback &allocator() = 0;
};
diff --git a/src/Runtime/Source/runtime/Qt3DSSceneManager.h b/src/Runtime/Source/runtime/Qt3DSSceneManager.h
index 7b8a4aab..7d8297f4 100644
--- a/src/Runtime/Source/runtime/Qt3DSSceneManager.h
+++ b/src/Runtime/Source/runtime/Qt3DSSceneManager.h
@@ -143,7 +143,7 @@ public: // Presentations
public: // Update Cycle
virtual BOOL Update() = 0;
- virtual BOOL RenderPresentation(IPresentation *inPresentation) = 0;
+ virtual BOOL RenderPresentation(IPresentation *inPresentation, bool firstFrame) = 0;
virtual void OnViewResize(INT32 inViewWidth, INT32 inViewHeight) = 0;
virtual void GetViewSize(INT32 &outWidth, INT32 &outHeight) = 0;
diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp
index d41454e6..33e1bf6c 100644
--- a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp
+++ b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.cpp
@@ -623,7 +623,7 @@ struct SRenderContext : public IQt3DSRenderContext
// Trying to avoid duplicate code as much as possible.
SBeginFrameResult m_BeginFrameResult;
- void BeginFrame() override
+ void BeginFrame(bool firstFrame) override
{
m_PreRenderPresentationDimensions = m_PresentationDimensions;
QSize thePresentationDimensions(m_PreRenderPresentationDimensions);
@@ -682,7 +682,7 @@ struct SRenderContext : public IQt3DSRenderContext
m_TextRenderer->BeginFrame();
if (m_TextTextureCache)
m_TextTextureCache->BeginFrame();
- m_ImageBatchLoader->BeginFrame();
+ m_ImageBatchLoader->BeginFrame(firstFrame);
}
QT3DSVec2 GetPresentationScaleFactor() const override { return m_PresentationScale; }
diff --git a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h
index d5e54fb2..302571d2 100644
--- a/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h
+++ b/src/Runtime/Source/runtimerender/Qt3DSRenderContextCore.h
@@ -207,7 +207,7 @@ namespace render {
// and the topmost presentation dimensions. Expects there to be exactly one presentation
// dimension pushed at this point.
// This also starts a render target in the render graph.
- virtual void BeginFrame() = 0;
+ virtual void BeginFrame(bool firstFrame) = 0;
// This runs through the added tasks in reverse order. This is used to render dependencies
// before rendering to the main render target.
diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp
index 8f1cb14f..e2cfbed1 100644
--- a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp
+++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp
@@ -323,7 +323,7 @@ struct SBatchLoader : public IImageBatchLoader
theBatch->m_LoadEvent.wait(200);
theBatch->m_LoadEvent.reset();
}
- BeginFrame();
+ BeginFrame(true);
}
}
void ImageLoaded(SLoadingImage &inImage, SLoadedTexture *inTexture)
@@ -335,7 +335,7 @@ struct SBatchLoader : public IImageBatchLoader
inImage.m_Batch->m_LoadEvent.set();
}
// These are called by the render context, users don't need to call this.
- void BeginFrame() override
+ void BeginFrame(bool firstFrame) override
{
TScopedLock __loaderLock(m_LoaderMutex);
// Pass 1 - send out all image loaded signals
@@ -346,8 +346,13 @@ struct SBatchLoader : public IImageBatchLoader
m_LoadedImages[idx].m_Batch->IncrementFinalizedImageCount();
if (m_LoadedImages[idx].m_Batch->IsFinalizedFinished())
m_FinishedBatches.push_back(m_LoadedImages[idx].m_Batch->m_BatchId);
+ if (!firstFrame)
+ break;
}
- m_LoadedImages.clear();
+ if (firstFrame)
+ m_LoadedImages.clear();
+ else if (m_LoadedImages.size())
+ m_LoadedImages.erase(m_LoadedImages.begin());
// pass 2 - clean up any existing batches.
for (QT3DSU32 idx = 0, end = m_FinishedBatches.size(); idx < end; ++idx) {
TImageLoaderBatchMap::iterator theIter = m_Batches.find(m_FinishedBatches[idx]);
diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h
index d45123f1..bc1773ce 100644
--- a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h
+++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h
@@ -82,7 +82,7 @@ namespace render {
virtual void BlockUntilLoaded(TImageBatchId inId) = 0;
// These are called by the render context, users don't need to call this.
- virtual void BeginFrame() = 0;
+ virtual void BeginFrame(bool firstFrame) = 0;
virtual void EndFrame() = 0;
static IImageBatchLoader &CreateBatchLoader(NVFoundationBase &inFoundation,
diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp
index b1993021..11762733 100644
--- a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp
+++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp
@@ -682,7 +682,7 @@ SLoadedTexture *SLoadedTexture::Load(const QString &inPath, NVFoundationBase &in
NVScopedRefCounted<IRefCountedInputStream> theStream(
inFactory.GetStreamForFile(preferKTX ? ktxSource : inPath, true));
if (!theStream.mPtr) {
- if (!preferKTX)
+ if (preferKTX)
theStream = inFactory.GetStreamForFile(inPath, true);
else
return nullptr;