From de230ea9bd9f6c385afb920d8843b086b0290c6d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 19 Jul 2023 11:18:57 +0200 Subject: [PATCH] rhi: Enable registering cleanup callbacks with a key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And the ability to deregister. Going to be required by QRhiWidget. Change-Id: If185cbed2faa042098ac1f6bb1d6daaffd834377 Reviewed-by: Andy Nichols (cherry picked from commit 84873c898cb4cc433f05d3161cad1e458d26c2e9) Reviewed-by: Tor Arne Vestbø --- src/gui/rhi/qrhi.cpp | 32 ++++++++++++++++++++++++++++++++ src/gui/rhi/qrhi.h | 2 ++ src/gui/rhi/qrhi_p.h | 11 +++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 294bcc6966a..7bd47b192eb 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -8272,6 +8272,33 @@ void QRhi::addCleanupCallback(const CleanupCallback &callback) d->addCleanupCallback(callback); } +/*! + \overload + + Registers \a callback to be invoked either when the QRhi is destroyed or + when runCleanup() is called. This overload takes an opaque pointer, \a key, + that is used to ensure that a given callback is registered (and so called) + only once. + + \sa removeCleanupCallback() + */ +void QRhi::addCleanupCallback(const void *key, const CleanupCallback &callback) +{ + d->addCleanupCallback(key, callback); +} + +/*! + Deregisters the callback with \a key. If no cleanup callback was registered + with \a key, the function does nothing. Callbacks registered without a key + cannot be removed. + + \sa addCleanupCallback() + */ +void QRhi::removeCleanupCallback(const void *key) +{ + d->removeCleanupCallback(key); +} + /*! Invokes all registered cleanup functions. The list of cleanup callbacks it then cleared. Normally destroying the QRhi does this automatically, but @@ -8286,6 +8313,11 @@ void QRhi::runCleanup() f(this); d->cleanupCallbacks.clear(); + + for (auto it = d->keyedCleanupCallbacks.cbegin(), end = d->keyedCleanupCallbacks.cend(); it != end; ++it) + it.value()(this); + + d->keyedCleanupCallbacks.clear(); } /*! diff --git a/src/gui/rhi/qrhi.h b/src/gui/rhi/qrhi.h index 43c31e0317d..c96ab7b19c2 100644 --- a/src/gui/rhi/qrhi.h +++ b/src/gui/rhi/qrhi.h @@ -1867,6 +1867,8 @@ public: using CleanupCallback = std::function; void addCleanupCallback(const CleanupCallback &callback); + void addCleanupCallback(const void *key, const CleanupCallback &callback); + void removeCleanupCallback(const void *key); void runCleanup(); QRhiGraphicsPipeline *newGraphicsPipeline(); diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 05df169a35a..d8403af2a22 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -178,6 +178,16 @@ public: cleanupCallbacks.append(callback); } + void addCleanupCallback(const void *key, const QRhi::CleanupCallback &callback) + { + keyedCleanupCallbacks[key] = callback; + } + + void removeCleanupCallback(const void *key) + { + keyedCleanupCallbacks.remove(key); + } + bool sanityCheckGraphicsPipeline(QRhiGraphicsPipeline *ps); bool sanityCheckShaderResourceBindings(QRhiShaderResourceBindings *srb); void updateLayoutDesc(QRhiShaderResourceBindings *srb); @@ -238,6 +248,7 @@ private: QHash resources; QSet pendingDeleteResources; QVarLengthArray cleanupCallbacks; + QHash keyedCleanupCallbacks; QElapsedTimer pipelineCreationTimer; qint64 accumulatedPipelineCreationTime = 0;