summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2020-01-17 07:57:05 +0200
committerAntti Määttä <antti.maatta@qt.io>2020-01-22 13:28:49 +0200
commit88849a83a6f9ca3524cf3ba32c3a4ed7e6fabdb9 (patch)
treecbe79006339b63245381cef7e2822cbbf01dcae9
parent7a49e1bdc590f0d3f397dd04355fd165bbd1cb86 (diff)
Don't render when scene is not changing
Reduce CPU and GPU load by checking if the scene has changed and render only if it has. Task-number: QT3DS-4042 Change-Id: I54e447760f04fdad8d64319f326245175b471331 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/api/studio3dqml/q3dsrenderer.cpp13
-rw-r--r--src/api/studio3dqml/q3dsrenderer_p.h2
-rw-r--r--src/engine/Qt3DSRenderRuntimeBinding.cpp4
-rw-r--r--src/engine/Qt3DSRuntimeView.cpp8
-rw-r--r--src/engine/Qt3DSRuntimeView.h2
-rw-r--r--src/runtime/Qt3DSApplication.cpp13
-rw-r--r--src/runtime/Qt3DSApplication.h2
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp5
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp13
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h4
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp5
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h2
-rw-r--r--src/viewer/Qt3DSViewerApp.cpp6
-rw-r--r--src/viewer/Qt3DSViewerApp.h4
14 files changed, 51 insertions, 32 deletions
diff --git a/src/api/studio3dqml/q3dsrenderer.cpp b/src/api/studio3dqml/q3dsrenderer.cpp
index 7d63b30..c902934 100644
--- a/src/api/studio3dqml/q3dsrenderer.cpp
+++ b/src/api/studio3dqml/q3dsrenderer.cpp
@@ -197,27 +197,32 @@ void Q3DSRenderer::render()
// Don't render if the plugin is hidden; however, if hidden, but sure
// to process pending commands so we can be shown again.
if (m_initialized) {
+ bool updateAgain = false;
if (m_visibleFlag)
- draw();
+ updateAgain = draw();
else
processCommands();
- update(); // mark as dirty to ensure update again
+
+ if (updateAgain)
+ update(); // mark as dirty to ensure update again
}
}
/** Cause Qt3DS runtime to render content.
* Initializes GL and the runtime when called the first time.
*/
-void Q3DSRenderer::draw()
+bool Q3DSRenderer::draw()
{
+ bool ret = true;
if (m_runtime && m_runtime->IsInitialised() && m_window) {
if (m_initialized)
m_runtime->RestoreState();
- m_runtime->Render();
+ ret = m_runtime->Render();
m_runtime->SaveState();
m_window->resetOpenGLState();
}
+ return ret;
}
bool Q3DSRenderer::initializeRuntime(QOpenGLFramebufferObject *inFbo)
diff --git a/src/api/studio3dqml/q3dsrenderer_p.h b/src/api/studio3dqml/q3dsrenderer_p.h
index 0817494..dbc85a2 100644
--- a/src/api/studio3dqml/q3dsrenderer_p.h
+++ b/src/api/studio3dqml/q3dsrenderer_p.h
@@ -89,7 +89,7 @@ protected:
static void onInitHandler(void *userData);
static void onUpdateHandler(void *userData);
bool initializeRuntime(QOpenGLFramebufferObject *inFbo);
- void draw();
+ bool draw();
void render() override;
void synchronize(QQuickFramebufferObject *inView) override;
void releaseRuntime();
diff --git a/src/engine/Qt3DSRenderRuntimeBinding.cpp b/src/engine/Qt3DSRenderRuntimeBinding.cpp
index 28c5403..e830e0f 100644
--- a/src/engine/Qt3DSRenderRuntimeBinding.cpp
+++ b/src/engine/Qt3DSRenderRuntimeBinding.cpp
@@ -1505,9 +1505,11 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager,
bool firstFrame) override
{
Qt3DSRenderScene *theFirstScene = nullptr;
- for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end && theFirstScene == nullptr; ++idx)
+ for (QT3DSU32 idx = 0, end = m_Scenes.size(); idx < end; ++idx) {
if (m_Scenes[idx].second->m_RuntimePresentation == inPresentation)
theFirstScene = m_Scenes[idx].second;
+ m_Scenes[idx].second->TransferDirtyProperties();
+ }
if (theFirstScene && theFirstScene->m_Presentation) {
m_LastRenderedScene = theFirstScene;
diff --git a/src/engine/Qt3DSRuntimeView.cpp b/src/engine/Qt3DSRuntimeView.cpp
index fd3be65..2335cf1 100644
--- a/src/engine/Qt3DSRuntimeView.cpp
+++ b/src/engine/Qt3DSRuntimeView.cpp
@@ -179,7 +179,7 @@ public:
void Cleanup() override;
bool CanRender() override;
- void Render() override;
+ bool Render() override;
bool WasLastFrameDirty() override;
bool HandleMessage(const QEvent *inEvent) override;
@@ -394,8 +394,9 @@ bool CRuntimeView::CanRender()
* returns KD_TRUE to call egl_render and swap properly, KD_FALSE if there has been no scene update
*or redraw.
*/
-void CRuntimeView::Render()
+bool CRuntimeView::Render()
{
+ bool ret = true;
if (m_Application.mPtr == nullptr) {
// InitializeGraphics has not been called
QT3DS_ASSERT(false);
@@ -403,7 +404,7 @@ void CRuntimeView::Render()
PerfLogGeneralEvent1(DATALOGGER_FRAME);
- m_Application->UpdateAndRender();
+ ret = m_Application->UpdateAndRender();
if (m_startupTime < 0 && m_startupTimer && m_startupTimer->isValid()) {
@@ -457,6 +458,7 @@ void CRuntimeView::Render()
manager.PopState();
}
+ return ret;
}
bool CRuntimeView::WasLastFrameDirty()
diff --git a/src/engine/Qt3DSRuntimeView.h b/src/engine/Qt3DSRuntimeView.h
index e3f57d1..e0061b0 100644
--- a/src/engine/Qt3DSRuntimeView.h
+++ b/src/engine/Qt3DSRuntimeView.h
@@ -185,7 +185,7 @@ public: // loading
virtual bool CanRender() = 0;
- virtual void Render() = 0;
+ virtual bool Render() = 0;
virtual bool WasLastFrameDirty() = 0;
diff --git a/src/runtime/Qt3DSApplication.cpp b/src/runtime/Qt3DSApplication.cpp
index cb8f732..79866c5 100644
--- a/src/runtime/Qt3DSApplication.cpp
+++ b/src/runtime/Qt3DSApplication.cpp
@@ -1031,7 +1031,7 @@ struct SApp : public IApplication
} // End QT3DS_PERF_SCOPED_TIMER scope
}
- void UpdateScenes() { m_RuntimeFactory->GetSceneManager().Update(); }
+ bool UpdateScenes() { return m_RuntimeFactory->GetSceneManager().Update(); }
bool LazyLoadSubPresentations()
{
@@ -1113,7 +1113,7 @@ struct SApp : public IApplication
void ResetDirtyCounter() { m_DirtyCountdown = 5; }
// Update all the presentations and render them.
- void UpdateAndRender() override
+ bool UpdateAndRender() override
{
QT3DS_ASSERT(m_AppLoadContext.mPtr == NULL);
m_ThisFrameStartTime = qt3ds::foundation::Time::getCurrentCounterValue();
@@ -1147,15 +1147,17 @@ struct SApp : public IApplication
}
UpdatePresentations();
- UpdateScenes();
+ bool dirty = UpdateScenes();
// If subpresentations changed we need to check if any of them needs to be loaded.
if (LazyLoadSubPresentations()) {
// Just redo all
UpdatePresentations();
- UpdateScenes();
+ dirty |= UpdateScenes();
}
-
+ bool renderNextFrame = false;
+ if (m_LastRenderWasDirty || dirty || m_initialFrame)
+ renderNextFrame = true;
Render();
m_InputEnginePtr->ClearInputFrame();
@@ -1185,6 +1187,7 @@ struct SApp : public IApplication
ResetDirtyCounter();
else
m_DirtyCountdown = NVMax(0, m_DirtyCountdown - 1);
+ return renderNextFrame;
}
// hook this up to -layer-caching.
diff --git a/src/runtime/Qt3DSApplication.h b/src/runtime/Qt3DSApplication.h
index 72d88a1..ad447f7 100644
--- a/src/runtime/Qt3DSApplication.h
+++ b/src/runtime/Qt3DSApplication.h
@@ -174,7 +174,7 @@ public:
virtual QList<Q3DStudio::CPresentation *> GetPresentationList() = 0;
// Update all the presentations and render them. Called exactly once per frame.
- virtual void UpdateAndRender() = 0;
+ virtual bool UpdateAndRender() = 0;
virtual bool IsApplicationDirty() = 0;
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp
index 0484390..104bd09 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp
@@ -253,7 +253,7 @@ namespace render {
SLayerRenderData *theRenderData = GetOrCreateLayerRenderDataForNode(*theLayer, id);
if (theRenderData) {
- theRenderData->PrepareForRender();
+ bool needsRender = theRenderData->PrepareForRender();
if (id) {
if (m_initialPrepareData.contains(theLayer)) {
// Copy dirty state from the initial since the graph is
@@ -268,7 +268,8 @@ namespace render {
m_initialPrepareData.insert(theLayer, theRenderData);
}
}
- retval = retval || theRenderData->m_LayerPrepResult->m_Flags.WasDirty();
+ retval = retval || needsRender
+ || theRenderData->m_LayerPrepResult->m_Flags.WasDirty() ;
} else {
QT3DS_ASSERT(false);
}
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
index c43ed1a..e453c91 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
@@ -120,9 +120,9 @@ namespace render {
if (m_AdvancedBlendDrawTexture)
m_AdvancedBlendDrawTexture = NULL;
}
- void SLayerRenderData::PrepareForRender(const QSize &inViewportDimensions)
+ bool SLayerRenderData::PrepareForRender(const QSize &inViewportDimensions)
{
- SLayerRenderPreparationData::PrepareForRender(inViewportDimensions);
+ bool needsRender = SLayerRenderPreparationData::PrepareForRender(inViewportDimensions);
SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult);
IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager());
@@ -182,6 +182,9 @@ namespace render {
m_Renderer.GetQt3DSContext().GetEffectSystem().GetResourceManager()
.DestroyFreeSizedResources();
}
+ bool isProgressiveAABlendPass =
+ m_ProgressiveAAPassIndex && m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex;
+ return needsRender || isProgressiveAABlendPass;
}
NVRenderTextureFormats::Enum SLayerRenderData::GetDepthBufferFormat()
@@ -2328,13 +2331,13 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn,
QSize(theCurrentViewport.m_Width, theCurrentViewport.m_Height));
}
- void SLayerRenderData::PrepareForRender()
+ bool SLayerRenderData::PrepareForRender()
{
// When we render to the scene itself (as opposed to an offscreen buffer somewhere)
// then we use the MVP of the layer somewhat.
NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport();
- PrepareForRender(
- QSize((QT3DSU32)theViewport.m_Width, (QT3DSU32)theViewport.m_Height));
+ return PrepareForRender(
+ QSize((QT3DSU32)theViewport.m_Width, (QT3DSU32)theViewport.m_Height));
}
void SLayerRenderData::ResetForFrame()
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h
index aa4d456..7520edf 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h
@@ -102,10 +102,10 @@ struct AdvancedBlendModes
virtual ~SLayerRenderData();
- void PrepareForRender();
+ bool PrepareForRender();
// Internal Call
- void PrepareForRender(const QSize &inViewportDimensions) override;
+ bool PrepareForRender(const QSize &inViewportDimensions) override;
NVRenderTextureFormats::Enum GetDepthBufferFormat();
NVRenderFrameBufferAttachments::Enum
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
index 1f191b0..821a0b8 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
@@ -1219,12 +1219,12 @@ namespace render {
}
};
- void SLayerRenderPreparationData::PrepareForRender(const QSize &inViewportDimensions)
+ bool SLayerRenderPreparationData::PrepareForRender(const QSize &inViewportDimensions)
{
QT3DS_PERF_SCOPED_TIMER(m_Renderer.GetQt3DSContext().GetPerfTimer(),
"LayerRenderData: PrepareForRender")
if (m_LayerPrepResult.hasValue())
- return;
+ return false;
m_Features.clear();
m_FeatureSetHash = 0;
@@ -1576,6 +1576,7 @@ namespace render {
GetTransparentRenderableObjects();
GetCameraDirection();
+ return wasDirty;
}
void SLayerRenderPreparationData::ResetForFrame()
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h
index 53b60f2..8b1463a 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h
@@ -344,7 +344,7 @@ namespace render {
// returns true if this object will render something different than it rendered the last
// time.
- virtual void PrepareForRender(const QSize &inViewportDimensions);
+ virtual bool PrepareForRender(const QSize &inViewportDimensions);
bool CheckLightProbeDirty(SImage &inLightProbe);
void AddRenderWidget(IRenderWidget &inWidget);
void SetShaderFeature(const char *inName, bool inValue);
diff --git a/src/viewer/Qt3DSViewerApp.cpp b/src/viewer/Qt3DSViewerApp.cpp
index a4cec7f..ce8163f 100644
--- a/src/viewer/Qt3DSViewerApp.cpp
+++ b/src/viewer/Qt3DSViewerApp.cpp
@@ -522,8 +522,9 @@ void Q3DSViewerApp::setupSearchPath(std::vector<std::string> &cmdLineArgs)
//NvFAppendSearchPath(theModuleDirectory.c_str());
}
-void Q3DSViewerApp::Render()
+bool Q3DSViewerApp::Render()
{
+ bool ret = true;
if (m_Impl.m_view && m_Impl.m_view->GetTegraRenderEngine()) {
if (m_Impl.m_appInitSuccessful) {
for (QEvent *e : m_Impl.m_pendingEvents) {
@@ -535,9 +536,10 @@ void Q3DSViewerApp::Render()
HandleController(*m_Impl.m_view);
#endif
- m_Impl.m_view->Render();
+ ret = m_Impl.m_view->Render();
}
}
+ return ret;
}
void Q3DSViewerApp::SaveState()
diff --git a/src/viewer/Qt3DSViewerApp.h b/src/viewer/Qt3DSViewerApp.h
index 25d2ed7..db8ba57 100644
--- a/src/viewer/Qt3DSViewerApp.h
+++ b/src/viewer/Qt3DSViewerApp.h
@@ -257,9 +257,9 @@ public:
/*
* @brief does the actual scene rendering
*
- * @return no return
+ * @return true if the scene needs to be rendered again in next frame
*/
- void Render();
+ bool Render();
/*
* @brief handle keyboard input