QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
QGCRhiCapture.cc
Go to the documentation of this file.
1#include "QGCRhiCapture.h"
2
3#include "QGCApplication.h"
4
5#if defined(QGC_HAS_GST_GLMEMORY_GPU_PATH) || defined(QGC_HAS_GST_D3D11_GPU_PATH) || defined(QGC_HAS_GST_D3D12_GPU_PATH)
7#endif
8
9#include <QtCore/QPointer>
10#include <QtQuick/QQuickWindow>
11
12#include <array>
13#include <atomic>
14
15namespace QGCRhiCapture {
16
17namespace {
18std::atomic<QRhi*> s_cachedRhi{nullptr};
19QPointer<QQuickWindow> s_connectedWindow;
20// Stored per connection so a window swap (e.g. popout video) can disconnect the prior window's
21// lambdas before they fire and clobber the new window's cached RHI.
22std::array<QMetaObject::Connection, 3> s_connections;
23} // namespace
24
25QRhi *qrhi()
26{
27 QGCApplication *app = qgcApp();
28 if (!app) return nullptr;
29 QQuickWindow *win = app->mainRootWindow();
30 if (!win) return nullptr;
31 return win->rhi();
32}
33
34QRhi *cachedRhi() noexcept
35{
36 return s_cachedRhi.load(std::memory_order_acquire);
37}
38
39void connectWindow(QQuickWindow *window)
40{
41 if (!window) return;
42 if (s_connectedWindow == window) return; // idempotent — avoid duplicate connections
43
44 // Detach prior window's signals before binding the new one — otherwise the old window's
45 // destroyed/invalidated lambdas would later wipe cachedRhi() and reset bridges that the
46 // new window is actively using.
47 for (auto &conn : s_connections) {
48 QObject::disconnect(conn);
49 conn = QMetaObject::Connection();
50 }
51
52 s_connectedWindow = window;
53 s_connections[0] = QObject::connect(window, &QQuickWindow::sceneGraphInitialized, window, [window]() {
54 s_cachedRhi.store(window->rhi(), std::memory_order_release);
55 }, Qt::DirectConnection);
56 s_connections[1] = QObject::connect(window, &QQuickWindow::sceneGraphInvalidated, window, []() {
57 s_cachedRhi.store(nullptr, std::memory_order_release);
58#if defined(QGC_HAS_GST_GLMEMORY_GPU_PATH) || defined(QGC_HAS_GST_D3D11_GPU_PATH) || defined(QGC_HAS_GST_D3D12_GPU_PATH)
59 // Drop bridge-cached GPU devices that wrap the now-defunct QRhi-owned device.
60 GstContextBridgeRegistry::resetAllBridges();
61#endif
62 }, Qt::DirectConnection);
63 // Clear cache when window is destroyed so a stale QRhi* is never returned.
64 s_connections[2] = QObject::connect(window, &QQuickWindow::destroyed, window, [](QObject *) {
65 s_cachedRhi.store(nullptr, std::memory_order_release);
66#if defined(QGC_HAS_GST_GLMEMORY_GPU_PATH) || defined(QGC_HAS_GST_D3D11_GPU_PATH) || defined(QGC_HAS_GST_D3D12_GPU_PATH)
67 GstContextBridgeRegistry::resetAllBridges();
68#endif
69 }, Qt::DirectConnection);
70}
71
72} // namespace QGCRhiCapture
#define qgcApp()
The main application and management class.
QQuickWindow * mainRootWindow()
QRhi * cachedRhi() noexcept
void connectWindow(QQuickWindow *window)