Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qeglfsdeviceintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#ifndef QT_NO_OPENGL
7# include "qeglfscursor_p.h"
8#endif
9#include "qeglfswindow_p.h"
10#include "qeglfsscreen_p.h"
11#include "qeglfshooks_p.h"
12
13#include <QtGui/private/qeglconvenience_p.h>
14#include <QGuiApplication>
15#include <private/qguiapplication_p.h>
16#include <QScreen>
17#include <QDir>
18#if QT_CONFIG(regularexpression)
19# include <QFileInfo>
20# include <QRegularExpression>
21#endif
22#include <QLoggingCategory>
23
24#if defined(Q_OS_LINUX)
25#include <fcntl.h>
26#include <unistd.h>
27#include <linux/fb.h>
28#include <sys/ioctl.h>
29#endif
30
31#include <private/qfactoryloader_p.h>
32#include <private/qcore_unix_p.h>
33
35
36using namespace Qt::StringLiterals;
37
38Q_LOGGING_CATEGORY(qLcEglDevDebug, "qt.qpa.egldeviceintegration")
39
41 (QEglFSDeviceIntegrationFactoryInterface_iid, "/egldeviceintegrations"_L1, Qt::CaseInsensitive))
42
44{
47 qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys:" << list;
48 return list;
49}
50
52{
53 QEglFSDeviceIntegration *integration = nullptr;
54 if (!integration)
55 integration = qLoadPlugin<QEglFSDeviceIntegration, QEglFSDeviceIntegrationPlugin>(loader(), key);
56 if (integration)
57 qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key;
58 else
59 qCWarning(qLcEglDevDebug) << "Failed to load EGL device integration" << key;
60
61 return integration;
62}
63
64static int framebuffer = -1;
65
67{
68#ifdef Q_OS_LINUX
69 QByteArray fbDev = qgetenv("QT_QPA_EGLFS_FB");
70 if (fbDev.isEmpty())
71 fbDev = QByteArrayLiteral("/dev/fb0");
72
73 return fbDev;
74#else
75 return QByteArray();
76#endif
77}
78
80{
81 int fbIndex = 0;
82#if QT_CONFIG(regularexpression)
83 QRegularExpression fbIndexRx("fb(\\d+)"_L1);
86 if (fbinfo.isSymLink())
87 match = fbIndexRx.match(fbinfo.symLinkTarget());
88 else
89 match = fbIndexRx.match(fbinfo.fileName());
90 if (match.hasMatch())
91 fbIndex = match.captured(1).toInt();
92#endif
93 return fbIndex;
94}
95
97{
98#ifdef Q_OS_LINUX
99 QByteArray fbDev = fbDeviceName();
100
101 framebuffer = qt_safe_open(fbDev, O_RDONLY);
102
103 if (Q_UNLIKELY(framebuffer == -1)) {
104 qWarning("EGLFS: Failed to open %s", fbDev.constData());
105 qFatal("EGLFS: Can't continue without a display");
106 }
107
108#ifdef FBIOBLANK
109 ioctl(framebuffer, FBIOBLANK, VESA_NO_BLANKING);
110#endif
111#endif
112}
113
115{
116#ifdef Q_OS_LINUX
117 if (framebuffer != -1)
118 close(framebuffer);
119#endif
120}
121
123{
124 bool displayOk;
125 const int defaultDisplay = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEFAULT_DISPLAY", &displayOk);
126 return displayOk ? EGLNativeDisplayType(quintptr(defaultDisplay)) : EGL_DEFAULT_DISPLAY;
127}
128
129EGLDisplay QEglFSDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay)
130{
131 return eglGetDisplay(nativeDisplay);
132}
133
135{
136 return true;
137}
138
140{
141 // Nothing to do here. Called only when usesDefaultScreen is false.
142}
143
145{
147 while (!app->screens().isEmpty())
149}
150
152{
153 return q_physicalScreenSizeFromFb(framebuffer, screenSize());
154}
155
157{
158 return q_screenSizeFromFb(framebuffer);
159}
160
162{
163 return QDpi(100, 100);
164}
165
167{
168 return QDpi(100, 100);
169}
170
172{
174}
175
177{
179}
180
182{
183 return q_screenDepthFromFb(framebuffer);
184}
185
187{
189}
190
192{
193 return q_refreshRateFromFb(framebuffer);
194}
195
197{
198 return EGL_WINDOW_BIT;
199}
200
202{
203 QSurfaceFormat format = inputFormat;
204
205 static const bool force888 = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCE888");
206 if (force888) {
207 format.setRedBufferSize(8);
208 format.setGreenBufferSize(8);
209 format.setBlueBufferSize(8);
210 }
211
212 return format;
213}
214
216{
217 return true;
218}
219
221{
222 return new QEglFSWindow(window);
223}
224
226 const QSize &size,
227 const QSurfaceFormat &format)
228{
229 Q_UNUSED(platformWindow);
230 Q_UNUSED(size);
232 return 0;
233}
234
236{
238 return 0;
239}
240
242{
244}
245
247{
248 Q_UNUSED(cap);
249 return false;
250}
251
253{
254#ifndef QT_NO_OPENGL
255 return new QEglFSCursor(static_cast<QEglFSScreen *>(screen));
256#else
258 return nullptr;
259#endif
260}
261
263{
264 Q_UNUSED(surface);
265
266#if defined(Q_OS_LINUX) && defined(FBIO_WAITFORVSYNC)
267 static const bool forceSync = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCEVSYNC");
268 if (forceSync && framebuffer != -1) {
269 int arg = 0;
270 if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1)
271 qWarning("Could not wait for vsync.");
272 }
273#endif
274}
275
277{
278 Q_UNUSED(surface);
279}
280
282{
283 return true;
284}
285
287{
288 return true;
289}
290
291QFunctionPointer QEglFSDeviceIntegration::platformFunction(const QByteArray &function) const
292{
294 return nullptr;
295}
296
298{
299 Q_UNUSED(name);
300 return nullptr;
301}
302
304{
305 Q_UNUSED(resource);
307 return nullptr;
308}
309
311{
312 return nullptr;
313}
314
316{
317 class Chooser : public QEglConfigChooser {
318 public:
319 Chooser(EGLDisplay display)
321 bool filterConfig(EGLConfig config) const override {
324 }
325 };
326
327 Chooser chooser(display);
328 chooser.setSurfaceType(qt_egl_device_integration()->surfaceType());
329 chooser.setSurfaceFormat(format);
330 return chooser.chooseConfig();
331}
332
334
335#include "moc_qeglfsdeviceintegration_p.cpp"
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
virtual bool filterConfig(EGLConfig config) const
static QEglFSDeviceIntegration * create(const QString &name)
virtual void presentBuffer(QPlatformSurface *surface)
virtual QSizeF physicalScreenSize() const
virtual bool filterConfig(EGLDisplay display, EGLConfig config) const
virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const
virtual Qt::ScreenOrientation nativeOrientation() const
virtual QImage::Format screenFormat() const
virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format)
virtual void waitForVSync(QPlatformSurface *surface) const
virtual bool supportsPBuffers() const
virtual void * nativeResourceForIntegration(const QByteArray &name)
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
virtual EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format)
virtual QFunctionPointer platformFunction(const QByteArray &function) const
virtual QEglFSWindow * createWindow(QWindow *window) const
virtual QByteArray fbDeviceName() const
virtual EGLint surfaceType() const
virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay)
virtual bool supportsSurfacelessContexts() const
virtual EGLNativeDisplayType platformDisplay() const
virtual QPlatformCursor * createCursor(QPlatformScreen *screen) const
virtual void destroyNativeWindow(EGLNativeWindowType window)
virtual void * nativeResourceForScreen(const QByteArray &resource, QScreen *screen)
virtual Qt::ScreenOrientation orientation() const
virtual bool hasCapability(QPlatformIntegration::Capability cap) const
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
bool isSymLink() const
Returns true if this object points to a symbolic link, shortcut, or alias; otherwise returns false.
QString symLinkTarget() const
QString fileName() const
Returns the name of the file, excluding the path.
\macro qGuiApp
static QList< QScreen * > screens()
Returns a list of all the screens associated with the windowing system the application is connected t...
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ Format_RGB32
Definition qimage.h:46
@ Format_RGB16
Definition qimage.h:49
bool isEmpty() const noexcept
Definition qlist.h:390
const T & constLast() const noexcept
Definition qlist.h:633
void append(parameter_type t)
Definition qlist.h:441
The QPlatformCursor class provides information about pointer device events (movement,...
Capability
Capabilities are used to determine specific features of a platform integration.
The QPlatformScreen class provides an abstraction for visual displays.
The QPlatformSurface class provides an abstraction for a surface.
The QPlatformWindow class provides an abstraction for top-level windows.
\inmodule QtCore \reentrant
\inmodule QtCore \reentrant
QRegularExpressionMatch match(const QString &subject, qsizetype offset=0, MatchType matchType=NormalMatch, MatchOptions matchOptions=NoMatchOption) const
Attempts to match the regular expression against the given subject string, starting at the position o...
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QPlatformScreen * handle() const
Get the platform screen handle.
Definition qscreen.cpp:83
\inmodule QtCore
Definition qsize.h:207
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5788
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
static void handleScreenRemoved(QPlatformScreen *screen)
Should be called by the implementation whenever a screen is removed.
\inmodule QtGui
Definition qwindow.h:63
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
ScreenOrientation
Definition qnamespace.h:270
@ PrimaryOrientation
Definition qnamespace.h:271
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_UNLIKELY(x)
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
#define QEglFSDeviceIntegrationFactoryInterface_iid
QEglFSDeviceIntegration * qt_egl_device_integration()
EGLConfig config
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)
#define qGuiApp
QPair< qreal, qreal > QDpi
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLenum GLsizei GLsizei GLint * values
[15]
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint name
GLint GLsizei GLsizei GLenum format
GLuint framebuffer
GLenum cap
SSL_CTX int(*) void arg)
QScreen * screen
[1]
Definition main.cpp:29
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define Q_UNUSED(x)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
size_t quintptr
Definition qtypes.h:72
double qreal
Definition qtypes.h:92
static const struct @437 keyMap[]
QList< int > list
[14]
QStringList keys
QApplication app(argc, argv)
[0]
aWidget window() -> setWindowTitle("New Window Title")
[2]