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