QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GstEglHelpers.cc
Go to the documentation of this file.
1#include "GstEglHelpers.h"
2
3#if defined(QGC_HAS_GST_DMABUF_GPU_PATH) || defined(QGC_HAS_GST_AHARDWAREBUFFER_GPU_PATH)
4
5#include <QtCore/QByteArray>
6#include <QtCore/QHash>
7#include <QtCore/QMutex>
8#include <QtCore/QMutexLocker>
9#include <QtGui/QOpenGLContext>
10#include <QtGui/qopenglcontext_platform.h>
11#include <cstring>
12#include <utility>
13
14namespace GstEglHelpers {
15
16EGLDisplay resolveEglDisplay(QOpenGLContext* qtCtx) noexcept
17{
18 if (qtCtx) {
19 if (auto* egl = qtCtx->nativeInterface<QNativeInterface::QEGLContext>()) {
20 const EGLDisplay d = egl->display();
21 if (d != EGL_NO_DISPLAY)
22 return d;
23 }
24 }
25 return eglGetCurrentDisplay();
26}
27
28namespace {
29
30QMutex s_extMutex;
31// Hash key = (display, extension name); names are static literals, copy cost paid once per miss.
32QHash<std::pair<EGLDisplay, QByteArray>, bool> s_extCache;
33
34} // namespace
35
36bool displaySupportsExtension(EGLDisplay display, const char* extension)
37{
38 if (display == EGL_NO_DISPLAY || !extension)
39 return false;
40 // Non-owning lookup key; the owning copy is made once per miss on insert.
41 const QByteArray extKey = QByteArray::fromRawData(extension, static_cast<qsizetype>(std::strlen(extension)));
42 // Lock held across read->query->write to prevent concurrent insertion of a conflicting result for the same key.
43 QMutexLocker lock(&s_extMutex);
44 auto it = s_extCache.constFind(std::make_pair(display, extKey));
45 if (it != s_extCache.constEnd())
46 return it.value();
47 // Must not eglInitialize Qt's display (a stray eglTerminate drops Qt's state); uninitialized returns nullptr.
48 const char* exts = eglQueryString(display, EGL_EXTENSIONS);
49 // Token check required: strstr would falsely match EGL_EXT_image_dma_buf_import inside
50 // EGL_EXT_image_dma_buf_import_modifiers.
51 bool supported = false;
52 if (exts && extension) {
53 const std::size_t extLen = std::strlen(extension);
54 for (const char* p = exts; (p = std::strstr(p, extension)) != nullptr; p += extLen) {
55 const char before = p == exts ? ' ' : *(p - 1);
56 const char after = *(p + extLen);
57 if ((before == ' ' || before == '\0') && (after == ' ' || after == '\0')) {
58 supported = true;
59 break;
60 }
61 }
62 }
63 s_extCache.insert(std::make_pair(display, QByteArray(extension)), supported);
64 return supported;
65}
66
67void resetExtensionCache()
68{
69 QMutexLocker lock(&s_extMutex);
70 s_extCache.clear();
71}
72
73} // namespace GstEglHelpers
74
75#endif // QGC_HAS_GST_DMABUF_GPU_PATH || QGC_HAS_GST_AHARDWAREBUFFER_GPU_PATH