summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhigles2.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-07-27 19:42:27 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-08-02 14:35:33 +0200
commitb594374ba84da986c5ebc93984961040338465d0 (patch)
tree41880eaf968ce0c5be934612a71edc61b0dbab58 /src/gui/rhi/qrhigles2.cpp
parentee68257b61268ef8f5f4c9b4090d8a1624cd98ce (diff)
rhi: Be more graceful when one destroys a resource after the QRhi
One is a bad application or library in this case, but nonetheless we should handle this more gracefully then just crashing due to the QRhi already having been destroyed. Mainly because in Qt 5 one could get away with the same: releasing OpenGL objects underneath, for example, a QSGPlainTexture with no (or wrong) GL context did not generate any user visible fatal errors. So we should not crash in Qt 6 either with these code bases. In debug builds or when QT_RHI_LEAK_CHECK is set, one will get the unreleased resources warning printed in Qt 6, which is a step forward compared to Qt 5. So there is still some indication that something is badly designed, even if the application survives. Task-number: QTBUG-95394 Pick-to: 6.2 Change-Id: I944f4f425ff126e7363a82aff926b280ccf1dfc3 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhigles2.cpp')
-rw-r--r--src/gui/rhi/qrhigles2.cpp76
1 files changed, 51 insertions, 25 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 05465e40cc..7650e852ff 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -4256,10 +4256,12 @@ void QGles2Buffer::destroy()
buffer = 0;
QRHI_RES_RHI(QRhiGles2);
- rhiD->releaseQueue.append(e);
- QRHI_PROF;
- QRHI_PROF_F(releaseBuffer(this));
- rhiD->unregisterResource(this);
+ if (rhiD) {
+ rhiD->releaseQueue.append(e);
+ QRHI_PROF;
+ QRHI_PROF_F(releaseBuffer(this));
+ rhiD->unregisterResource(this);
+ }
}
bool QGles2Buffer::create()
@@ -4366,11 +4368,13 @@ void QGles2RenderBuffer::destroy()
stencilRenderbuffer = 0;
QRHI_RES_RHI(QRhiGles2);
- if (owns)
- rhiD->releaseQueue.append(e);
- QRHI_PROF;
- QRHI_PROF_F(releaseRenderBuffer(this));
- rhiD->unregisterResource(this);
+ if (rhiD) {
+ if (owns)
+ rhiD->releaseQueue.append(e);
+ QRHI_PROF;
+ QRHI_PROF_F(releaseRenderBuffer(this));
+ rhiD->unregisterResource(this);
+ }
}
bool QGles2RenderBuffer::create()
@@ -4521,11 +4525,13 @@ void QGles2Texture::destroy()
zeroInitialized = false;
QRHI_RES_RHI(QRhiGles2);
- if (owns)
- rhiD->releaseQueue.append(e);
- QRHI_PROF;
- QRHI_PROF_F(releaseTexture(this));
- rhiD->unregisterResource(this);
+ if (rhiD) {
+ if (owns)
+ rhiD->releaseQueue.append(e);
+ QRHI_PROF;
+ QRHI_PROF_F(releaseTexture(this));
+ rhiD->unregisterResource(this);
+ }
}
bool QGles2Texture::prepareCreate(QSize *adjustedSize)
@@ -4803,9 +4809,10 @@ void QGles2TextureRenderTarget::destroy()
framebuffer = 0;
QRHI_RES_RHI(QRhiGles2);
- rhiD->releaseQueue.append(e);
-
- rhiD->unregisterResource(this);
+ if (rhiD) {
+ rhiD->releaseQueue.append(e);
+ rhiD->unregisterResource(this);
+ }
}
QRhiRenderPassDescriptor *QGles2TextureRenderTarget::newCompatibleRenderPassDescriptor()
@@ -4999,9 +5006,10 @@ void QGles2GraphicsPipeline::destroy()
samplers.clear();
QRHI_RES_RHI(QRhiGles2);
- rhiD->releaseQueue.append(e);
-
- rhiD->unregisterResource(this);
+ if (rhiD) {
+ rhiD->releaseQueue.append(e);
+ rhiD->unregisterResource(this);
+ }
}
bool QGles2GraphicsPipeline::create()
@@ -5135,9 +5143,10 @@ void QGles2ComputePipeline::destroy()
samplers.clear();
QRHI_RES_RHI(QRhiGles2);
- rhiD->releaseQueue.append(e);
-
- rhiD->unregisterResource(this);
+ if (rhiD) {
+ rhiD->releaseQueue.append(e);
+ rhiD->unregisterResource(this);
+ }
}
bool QGles2ComputePipeline::create()
@@ -5231,8 +5240,12 @@ QGles2SwapChain::~QGles2SwapChain()
void QGles2SwapChain::destroy()
{
- QRHI_PROF;
- QRHI_PROF_F(releaseSwapChain(this));
+ QRHI_RES_RHI(QRhiGles2);
+ if (rhiD) {
+ QRHI_PROF;
+ QRHI_PROF_F(releaseSwapChain(this));
+ rhiD->unregisterResource(this);
+ }
}
QRhiCommandBuffer *QGles2SwapChain::currentFrameCommandBuffer()
@@ -5258,6 +5271,11 @@ QRhiRenderPassDescriptor *QGles2SwapChain::newCompatibleRenderPassDescriptor()
bool QGles2SwapChain::createOrResize()
{
+ // can be called multiple times due to window resizes
+ const bool needsRegistration = !surface || surface != m_window;
+ if (surface && surface != m_window)
+ destroy();
+
surface = m_window;
m_currentPixelSize = surfacePixelSize();
pixelSize = m_currentPixelSize;
@@ -5283,6 +5301,14 @@ bool QGles2SwapChain::createOrResize()
// make something up
QRHI_PROF_F(resizeSwapChain(this, 2, m_sampleCount > 1 ? 2 : 0, m_sampleCount));
+ // The only reason to register this fairly fake gl swapchain
+ // object with no native resources underneath is to be able to
+ // implement a safe destroy().
+ if (needsRegistration) {
+ QRHI_RES_RHI(QRhiGles2);
+ rhiD->registerResource(this);
+ }
+
return true;
}