diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2023-04-17 15:44:42 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2023-04-18 14:42:45 +0200 |
commit | 62a4ca773a9e8a2f0c993c159c045f2794078aad (patch) | |
tree | f8b0c594cd526ab40280a1d8268aa123e439c043 /src/gui/rhi/qrhi.cpp | |
parent | e3c9dce0b6e5aa1844f51cf2f3bdc550a5b884ce (diff) |
rhi: Make it safe to always call deleteLater on a resource
...even when the QRhi is already gone. This should not happen in
well-written applications and libraries, but we handle this
gracefully in the regular dtor and destroy() for resources that
register themselves to their creator QRhi, so by registering
everything we can offer this to all QRhiResource subclasses.
We still want to differentiate between native resource owning
QRhiResources and others (that do not create native graphics
objects), so do this via a flag passed to registerResource().
This way the behavior with QT_RHI_LEAK_CHECK=1 does not change.
Pick-to: 6.5
Fixes: QTBUG-112914
Change-Id: I9bafc81ef7a4ae76f356fc5f6248628d1f8791e0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhi.cpp')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index c5fb6afd7c..41b18e643e 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -2119,11 +2119,17 @@ QRhiResource::~QRhiResource() requirement of not altering QRhiResource objects that are referenced by the frame being recorded. + If the QRhi that created this object is already destroyed, the object is + deleted immediately. + \sa destroy() */ void QRhiResource::deleteLater() { - m_rhi->addDeleteLater(this); + if (m_rhi) + m_rhi->addDeleteLater(this); + else + delete this; } /*! @@ -2172,10 +2178,13 @@ quint64 QRhiResource::globalResourceId() const /*! \return the QRhi that created this resource. + + If the QRhi that created this object is already destroyed, the result is + \nullptr. */ QRhi *QRhiResource::rhi() const { - return m_rhi->q; + return m_rhi ? m_rhi->q : nullptr; } /*! @@ -5100,7 +5109,7 @@ QRhiResource::Type QRhiCommandBuffer::resourceType() const return CommandBuffer; } -static const char *resourceTypeStr(QRhiResource *res) +static const char *resourceTypeStr(const QRhiResource *res) { switch (res->resourceType()) { case QRhiResource::Buffer: @@ -5151,8 +5160,10 @@ QRhiImplementation::~QRhiImplementation() qWarning("QRhi %p going down with %d unreleased resources that own native graphics objects. This is not nice.", q, int(resources.size())); } - for (QRhiResource *res : std::as_const(resources)) { - if (leakCheck) + for (auto it = resources.cbegin(), end = resources.cend(); it != end; ++it) { + QRhiResource *res = it.key(); + const bool ownsNativeResources = it.value(); + if (leakCheck && ownsNativeResources) qWarning(" %s resource %p (%s)", resourceTypeStr(res), res, res->m_objectName.constData()); // Null out the resource's rhi pointer. This is why it makes sense to do null |