Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qeglfskmsgbmintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// Copyright (C) 2016 The Qt Company Ltd.
3// Copyright (C) 2016 Pelagicore AG
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5// Qt-Security score:significant reason:default
6
12#include "private/qeglfscursor_p.h"
13
14#include <QtCore/QLoggingCategory>
15#include <QtGui/QScreen>
16#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h>
17
18#if QT_CONFIG(filesystemwatcher)
19#include <QtCore/QFileSystemWatcher>
20#endif
21
22#include <gbm.h>
23
25
26QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
27{
28 qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created");
29}
30
31QEglFSKmsGbmIntegration::~QEglFSKmsGbmIntegration()
32{
33}
34
35#ifndef EGL_EXT_platform_base
37#endif
38
39#ifndef EGL_PLATFORM_GBM_KHR
40#define EGL_PLATFORM_GBM_KHR 0x31D7
41#endif
42
43EGLDisplay QEglFSKmsGbmIntegration::createDisplay(EGLNativeDisplayType nativeDisplay)
44{
45 qCDebug(qLcEglfsKmsDebug, "Querying EGLDisplay");
46 EGLDisplay display;
47
48 PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = nullptr;
49 const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
50 if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) {
51 getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
52 eglGetProcAddress("eglGetPlatformDisplayEXT"));
53 }
54
55 if (getPlatformDisplay) {
56 display = getPlatformDisplay(EGL_PLATFORM_GBM_KHR, nativeDisplay, nullptr);
57 } else {
58 qCDebug(qLcEglfsKmsDebug, "No eglGetPlatformDisplay for GBM, falling back to eglGetDisplay");
59 display = eglGetDisplay(nativeDisplay);
60 }
61
62 return display;
63}
64
65EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format)
66{
67 Q_UNUSED(format);
68 Q_ASSERT(device());
69
70 gbm_surface *surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(),
71 1, 1,
72 GBM_FORMAT_XRGB8888,
73 GBM_BO_USE_RENDERING);
74
75 return reinterpret_cast<EGLNativeWindowType>(surface);
76}
77
78void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window)
79{
80 gbm_surface *surface = reinterpret_cast<gbm_surface *>(window);
81 gbm_surface_destroy(surface);
82}
83
84QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const
85{
86#if QT_CONFIG(opengl)
87 if (!screenConfig()->hwCursor()) {
88 qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor");
89 return new QEglFSCursor(screen);
90 }
91#else
92 Q_UNUSED(screen);
93#endif
94 return nullptr;
95}
96
97void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface)
98{
99 QWindow *window = static_cast<QWindow *>(surface->surface());
100 QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(window->screen()->handle());
101 screen->flip();
102}
103
104QKmsDevice *QEglFSKmsGbmIntegration::createDevice()
105{
106
107 m_deviceDiscovery = std::unique_ptr<QDeviceDiscovery>(QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask));
108#if QT_CONFIG(filesystemwatcher)
109 m_kmsConfigWatcher = std::unique_ptr<QFileSystemWatcher>(new QFileSystemWatcher());
110#endif
111
112 QString path = screenConfig()->devicePath();
113 if (!path.isEmpty()) {
114 qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file";
115 } else {
116 const QStringList devices = m_deviceDiscovery->scanConnectedDevices();
117 qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices;
118
119 if (Q_UNLIKELY(devices.isEmpty()))
120 qFatal("Could not find DRM device!");
121
122 path = devices.first();
123 qCDebug(qLcEglfsKmsDebug) << "Using" << path;
124 }
125
126 bool hotreload = !qEnvironmentVariable("QT_QPA_EGLFS_HOTPLUG_ENABLED").isEmpty();
127 if (hotreload) {
128 qCWarning(qLcEglfsKmsDebug) << "EGLFS/KMS: Hot-Reload on KMS-events enabled, be aware that"
129 << "this requires actions in UI code for proper functionallity"
130 << "(e.g. close/open windows on screen's disconnect/connect)";
131 QObject::connect(m_deviceDiscovery.get(), &QDeviceDiscovery::deviceChanged,
132 m_deviceDiscovery.get(), [this](const QString &deviceNode) {
133 qCDebug(qLcEglfsKmsDebug) << "KMS device changed:" << deviceNode;
134 m_device->checkConnectedScreens();
135 });
136 }
137
138 QString json = qEnvironmentVariable("QT_QPA_EGLFS_KMS_CONFIG");
139 if (json.isEmpty())
140 json = qEnvironmentVariable("QT_QPA_KMS_CONFIG");
141
142 if (!json.isEmpty()) {
143#if QT_CONFIG(filesystemwatcher)
144 m_kmsConfigWatcher->addPath(json);
145 QObject::connect(m_kmsConfigWatcher.get(), &QFileSystemWatcher::fileChanged,
146 m_kmsConfigWatcher.get(), [this, json]() {
147 qCDebug(qLcEglfsKmsDebug) << "KMS config-file has changed! path:"
148 << json;
149 m_screenConfig->refreshConfig();
150 m_device->updateScreens();
151 m_kmsConfigWatcher->addPath(json); // as per QFileSystemWatcher doc we have to re-add
152 // the path in case it's a new file
153 });
154#endif
155 }
156
157 return new QEglFSKmsGbmDevice(screenConfig(), path);
158}
159
160QEglFSWindow *QEglFSKmsGbmIntegration::createWindow(QWindow *window) const
161{
162 return new QEglFSKmsGbmWindow(window, this);
163}
164
165QT_END_NAMESPACE
Combined button and popup list for selecting options.
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
void * native_display
void const EGLint * attrib_list
#define EGL_PLATFORM_GBM_KHR