summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2022-08-25 08:30:55 +0300
committerAntti Määttä <antti.maatta@qt.io>2022-08-29 09:33:59 +0300
commitdf02b3f36cfda76d5b027cd34f42266f16b596c2 (patch)
treed47efcb3c49aa30291b17c27c7074a04be1d1994
parent4563961362c14aceb47a9a416626d54cec10cd5d (diff)
Fix memory leak in Qt3DSRendererImplLayerRenderHelperHEADmaster
Two camera nodes are allocated but never freed. Every frame. This leads to a massive memory consumption. We are changing the memory model for these two nodes from dynamic memory allocation to automatic memory allocation. However, this only works when we keep the SLayerRenderHelper object longer alive. Otherwise we are holding addresses to temp object longer alive than allowed. That why the temporary creation of "thePrepResult" and then copy to the member "m_LayerPrepResult" will be avoided with this patch. Which saves us additional code executions. Change-Id: I564516e20616c2bbb979619cd71f26145e962db7 Reviewed-by: Kaj Grönholm <kaj.gronholm@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Antti Määttä <antti.maatta@qt.io>
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp33
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h4
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp50
3 files changed, 41 insertions, 46 deletions
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp
index b3a190d..5f290fa 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp
@@ -70,8 +70,8 @@ QT3DSVec2 ToRectRelativeCoords(const QT3DSVec2 &inCoords, const NVRenderRectF &i
SLayerRenderHelper::SLayerRenderHelper()
: m_Layer(nullptr)
, m_Camera(nullptr)
- , m_CameraLeftEye(nullptr)
- , m_CameraRightEye(nullptr)
+ , m_CameraLeftEye()
+ , m_CameraRightEye()
, m_Offscreen(false)
{
}
@@ -90,8 +90,8 @@ SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewpo
, m_PresentationDesignDimensions(inPresentationDesignDimensions)
, m_Layer(&inLayer)
, m_Camera(nullptr)
- , m_CameraLeftEye(nullptr)
- , m_CameraRightEye(nullptr)
+ , m_CameraLeftEye()
+ , m_CameraRightEye()
, m_Offscreen(inOffscreen)
, m_ScaleMode(inScaleMode)
, m_StereoMode(inStereoMode)
@@ -272,9 +272,9 @@ QSize SLayerRenderHelper::GetTextureDimensions() const
SCamera *SLayerRenderHelper::GetCamera() {
if (m_StereoView == StereoViews::Left)
- return m_CameraLeftEye;
+ return &m_CameraLeftEye;
if (m_StereoView == StereoViews::Right)
- return m_CameraRightEye;
+ return &m_CameraRightEye;
return m_Camera;
}
@@ -413,25 +413,20 @@ void SLayerRenderHelper::copyCameraProperties(SCamera *sourceCamera,
void SLayerRenderHelper::adjustCameraStereoSeparation()
{
- if (!m_CameraLeftEye)
- m_CameraLeftEye = new SCamera();
- if (!m_CameraRightEye)
- m_CameraRightEye = new SCamera();
-
// Copy m_Camera properties into left & right cameras
- copyCameraProperties(m_Camera, m_CameraLeftEye);
- copyCameraProperties(m_Camera, m_CameraRightEye);
+ copyCameraProperties(m_Camera, &m_CameraLeftEye);
+ copyCameraProperties(m_Camera, &m_CameraRightEye);
// Adjust left & right camera positions by eye separation
QT3DSVec3 eyeMove(m_StereoEyeSeparation, 0, 0);
QT3DSVec3 camMove = m_Camera->m_GlobalTransform.transform(eyeMove)
- m_Camera->m_GlobalTransform.getPosition();
camMove.z *= -1; // Inverse z
- m_CameraLeftEye->m_Position -= camMove;
- m_CameraLeftEye->m_Flags.SetTransformDirty(true);
- m_CameraRightEye->m_Position += camMove;
- m_CameraRightEye->m_Flags.SetTransformDirty(true);
+ m_CameraLeftEye.m_Position -= camMove;
+ m_CameraLeftEye.m_Flags.SetTransformDirty(true);
+ m_CameraRightEye.m_Position += camMove;
+ m_CameraRightEye.m_Flags.SetTransformDirty(true);
- m_CameraLeftEye->MarkDirty();
- m_CameraRightEye->MarkDirty();
+ m_CameraLeftEye.MarkDirty();
+ m_CameraRightEye.MarkDirty();
}
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h
index 7d2254a..078c2ec 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h
@@ -60,8 +60,8 @@ namespace render {
QT3DSVec2 m_PresentationDesignDimensions;
SLayer *m_Layer;
SCamera *m_Camera;
- SCamera *m_CameraLeftEye;
- SCamera *m_CameraRightEye;
+ SCamera m_CameraLeftEye;
+ SCamera m_CameraRightEye;
bool m_Offscreen;
NVRenderRectF m_originalViewport;
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
index c2726ab..0ee8aae 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
@@ -1446,7 +1446,6 @@ namespace render {
// Uncomment the line below to disable all progressive AA.
// maxNumAAPasses = 0;
- SLayerRenderPreparationResult thePrepResult;
bool hasOffscreenRenderer = GetOffscreenRenderer();
bool SSAOEnabled = (m_Layer.m_AoStrength > 0.0f && m_Layer.m_AoDistance > 0.0f
@@ -1506,22 +1505,22 @@ namespace render {
maxNumAAPasses = 0;
}
- thePrepResult = SLayerRenderPreparationResult(SLayerRenderHelper(
+ m_LayerPrepResult = SLayerRenderPreparationResult(SLayerRenderHelper(
theViewport, theScissor, m_Layer.m_Scene->m_Presentation->m_PresentationDimensions,
m_Layer, shouldRenderToTexture, m_Renderer.GetQt3DSContext().GetScaleMode(),
m_Renderer.GetQt3DSContext().GetStereoMode(),
m_Renderer.GetQt3DSContext().GetStereoView(),
m_Renderer.GetQt3DSContext().GetStereoEyeSeparation(),
m_Renderer.GetQt3DSContext().GetPresentationScaleFactor()));
- thePrepResult.m_LastEffect = theLastEffect;
- thePrepResult.m_MaxAAPassIndex = maxNumAAPasses;
- thePrepResult.m_Flags.SetRequiresDepthTexture(requiresDepthPrepass
+ m_LayerPrepResult->m_LastEffect = theLastEffect;
+ m_LayerPrepResult->m_MaxAAPassIndex = maxNumAAPasses;
+ m_LayerPrepResult->m_Flags.SetRequiresDepthTexture(requiresDepthPrepass
|| NeedsWidgetTexture());
- thePrepResult.m_Flags.SetShouldRenderToTexture(shouldRenderToTexture);
+ m_LayerPrepResult->m_Flags.SetShouldRenderToTexture(shouldRenderToTexture);
if (m_Renderer.GetContext().GetRenderContextType() != NVRenderContextValues::GLES2)
- thePrepResult.m_Flags.SetRequiresSsaoPass(SSAOEnabled);
+ m_LayerPrepResult->m_Flags.SetRequiresSsaoPass(SSAOEnabled);
- if (thePrepResult.IsLayerVisible()) {
+ if (m_LayerPrepResult->IsLayerVisible()) {
if (shouldRenderToTexture) {
m_Renderer.GetQt3DSContext().GetRenderList().AddRenderTask(
CreateRenderToTextureRunnable());
@@ -1530,10 +1529,10 @@ namespace render {
m_Renderer.PrepareImageForIbl(*m_Layer.m_LightProbe);
wasDataDirty = true;
}
- if (m_StereoMode != thePrepResult.getStereoMode()) {
+ if (m_StereoMode != m_LayerPrepResult->getStereoMode()) {
// When stereo mode changes we need to mark data dirty
// for e.g. temporalAA to render correctly.
- m_StereoMode = thePrepResult.getStereoMode();
+ m_StereoMode = m_LayerPrepResult->getStereoMode();
wasDataDirty = true;
}
@@ -1583,10 +1582,10 @@ namespace render {
// SetupCameraForRender() sets the camera used for picking and
// updates global state e.g. IsGloballyActive()
SCameraGlobalCalculationResult theResult =
- thePrepResult.SetupCameraForRender(*theCamera);
+ m_LayerPrepResult->SetupCameraForRender(*theCamera);
wasDataDirty = wasDataDirty || theResult.m_WasDirty;
if (theCamera->m_Flags.IsGloballyActive())
- m_Camera = thePrepResult.GetCamera();
+ m_Camera = m_LayerPrepResult->GetCamera();
if (theResult.m_ComputeFrustumSucceeded == false) {
qCCritical(INTERNAL_ERROR, "Failed to calculate camera frustum");
}
@@ -1626,7 +1625,7 @@ namespace render {
m_Lights.size() - 1, mapSize, mapSize,
NVRenderTextureFormats::R16F, 1, mapMode,
ShadowFilterValues::NONE);
- thePrepResult.m_Flags.SetRequiresShadowMapPass(true);
+ m_LayerPrepResult->m_Flags.SetRequiresShadowMapPass(true);
SetShaderFeature("QT3DS_ENABLE_SSM", true);
}
}
@@ -1695,11 +1694,11 @@ namespace render {
m_Camera->CalculateViewProjectionMatrix(m_ViewProjection);
if (m_Layer.m_DynamicResize)
- calculateDynamicLayerSize(thePrepResult);
+ calculateDynamicLayerSize(*m_LayerPrepResult);
theTextScaleFactor = m_Camera->GetTextScaleFactor(
- thePrepResult.GetLayerToPresentationViewport(),
- thePrepResult.GetPresentationDesignDimensions());
+ m_LayerPrepResult->GetLayerToPresentationViewport(),
+ m_LayerPrepResult->GetPresentationDesignDimensions());
if (m_Camera->m_EnableFrustumCulling) {
SClipPlane nearPlane;
QT3DSMat33 theUpper33(m_Camera->m_GlobalTransform.getUpper3x3InverseTranspose());
@@ -1731,16 +1730,16 @@ namespace render {
bool renderablesDirty =
PrepareRenderablesForRender(m_ViewProjection,
m_ClippingFrustum,
- theTextScaleFactor, thePrepResult.m_Flags);
+ theTextScaleFactor, m_LayerPrepResult->m_Flags);
wasDataDirty = wasDataDirty || renderablesDirty;
- if (thePrepResult.m_Flags.RequiresStencilBuffer())
- thePrepResult.m_Flags.SetShouldRenderToTexture(true);
+ if (m_LayerPrepResult->m_Flags.RequiresStencilBuffer())
+ m_LayerPrepResult->m_Flags.SetShouldRenderToTexture(true);
} else {
NVRenderRect theViewport =
- thePrepResult.GetLayerToPresentationViewport().ToIntegerRect();
+ m_LayerPrepResult->GetLayerToPresentationViewport().ToIntegerRect();
bool theScissor = true;
NVRenderRect theScissorRect =
- thePrepResult.GetLayerToPresentationScissorRect().ToIntegerRect();
+ m_LayerPrepResult->GetLayerToPresentationScissorRect().ToIntegerRect();
// This happens here because if there are any fancy render steps
IRenderList &theRenderList(m_Renderer.GetQt3DSContext().GetRenderList());
NVRenderContext &theContext(m_Renderer.GetContext());
@@ -1770,12 +1769,13 @@ namespace render {
wasDataDirty = wasDataDirty || theResult.m_HasChangedSinceLastFrame;
}
}
+ } else {
+ // m_LayerPrepResult must always be set.
+ m_LayerPrepResult = SLayerRenderPreparationResult();
}
wasDirty = wasDirty || wasDataDirty;
- thePrepResult.m_Flags.SetWasDirty(wasDirty);
- thePrepResult.m_Flags.SetLayerDataDirty(wasDataDirty);
-
- m_LayerPrepResult = thePrepResult;
+ m_LayerPrepResult->m_Flags.SetWasDirty(wasDirty);
+ m_LayerPrepResult->m_Flags.SetLayerDataDirty(wasDataDirty);
// Per-frame cache of renderable objects post-sort.
GetOpaqueRenderableObjects();