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
qeglfskmsvsp2integration.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// Copyright (C) 2017 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
9#include "private/qeglfswindow_p.h"
10
11#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h>
12#include <QtGui/private/qeglconvenience_p.h>
13#include <QtCore/QLoggingCategory>
14#include <QtCore/QJsonDocument>
15#include <QtCore/QJsonObject>
16#include <QtCore/QJsonArray>
17#include <QtGui/qpa/qplatformwindow.h>
18#include <QtGui/QScreen>
19
20#include <xf86drm.h>
21#include <xf86drmMode.h>
22#include <gbm.h>
23
24QT_BEGIN_NAMESPACE
25
26QEglFSKmsVsp2Integration::QEglFSKmsVsp2Integration()
27{
28 qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via Vsp2 integration created");
29}
30
31#ifndef EGL_EXT_platform_base
34#endif
35
36#ifndef EGL_PLATFORM_GBM_KHR
37#define EGL_PLATFORM_GBM_KHR 0x31D7
38#endif
39
41{
42 qCDebug(qLcEglfsKmsDebug, "Querying EGLDisplay");
43 EGLDisplay display;
44
45 PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = nullptr;
46 const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
47 if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) {
48 getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
49 eglGetProcAddress("eglGetPlatformDisplayEXT"));
50 }
51
52 if (getPlatformDisplay) {
53 display = getPlatformDisplay(EGL_PLATFORM_GBM_KHR, nativeDisplay, nullptr);
54 } else {
55 qCDebug(qLcEglfsKmsDebug, "No eglGetPlatformDisplay for GBM, falling back to eglGetDisplay");
56 display = eglGetDisplay(nativeDisplay);
57 }
58
59 return display;
60}
61
63{
64 Q_UNUSED(format);
65 Q_ASSERT(device());
66
67 gbm_surface *surface = gbm_surface_create(static_cast<QEglFSKmsVsp2Device *>(device())->gbmDevice(),
68 1, 1,
69 GBM_FORMAT_XRGB8888,
70 GBM_BO_USE_RENDERING);
71
72 return reinterpret_cast<EGLNativeWindowType>(surface);
73}
74
75void QEglFSKmsVsp2Integration::destroyNativeWindow(EGLNativeWindowType window)
76{
77 gbm_surface *surface = reinterpret_cast<gbm_surface *>(window);
78 //TODO call screen destroysurface instead
79 gbm_surface_destroy(surface);
80}
81
82void QEglFSKmsVsp2Integration::presentBuffer(QPlatformSurface *surface)
83{
84 QWindow *window = static_cast<QWindow *>(surface->surface());
85 auto *screen = static_cast<QEglFSKmsVsp2Screen *>(window->screen()->handle());
86 screen->flip();
87}
88
90{
91 QString path = screenConfig()->devicePath();
92 if (!path.isEmpty()) {
93 qCDebug(qLcEglfsKmsDebug) << "VSP2: Using DRM device" << path << "specified in config file";
94 } else {
95 QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask);
96 const QStringList devices = d->scanConnectedDevices();
97 qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices;
98 d->deleteLater();
99
100 if (Q_UNLIKELY(devices.isEmpty()))
101 qFatal("Could not find DRM device!");
102
103 path = devices.first();
104 qCDebug(qLcEglfsKmsDebug) << "Using" << path;
105 }
106
107 return new QEglFSKmsVsp2Device(screenConfig(), path);
108}
109
111{
112public:
113 QEglFSKmsVsp2Window(QWindow *w, const QEglFSKmsVsp2Integration *integration)
114 : QEglFSWindow(w)
115 , m_integration(integration)
116 {}
117
118 ~QEglFSKmsVsp2Window() { destroy(); }
119
123};
124
126{
127 auto *vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen());
128 EGLDisplay display = vsp2Screen->display();
129 QSurfaceFormat platformFormat = m_integration->surfaceFormatFor(window()->requestedFormat());
130 m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat);
131 m_format = q_glFormatFromConfig(display, m_config, platformFormat);
132 // One fullscreen window per screen -> the native window is simply the gbm_surface the screen created.
133 m_window = reinterpret_cast<EGLNativeWindowType>(vsp2Screen->createSurface());
134
135 PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurface = nullptr;
136 const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
137 if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) {
138 createPlatformWindowSurface = reinterpret_cast<PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>(
139 eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"));
140 }
141
142 if (createPlatformWindowSurface) {
143 m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast<void *>(m_window), nullptr);
144 } else {
145 qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface");
146 m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr);
147 }
148}
149
151{
152 auto *vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen());
153 QEglFSWindow::invalidateSurface();
154 vsp2Screen->resetSurface();
155}
156
158{
159 return new QEglFSKmsVsp2Window(window, this);
160}
161
162QT_END_NAMESPACE
gbm_device * gbmDevice() const
QEglFSWindow * createWindow(QWindow *window) const override
QKmsDevice * createDevice() override
void presentBuffer(QPlatformSurface *surface) override
void destroyNativeWindow(EGLNativeWindowType window) override
EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) override
EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override
QEglFSKmsVsp2Window(QWindow *w, const QEglFSKmsVsp2Integration *integration)
const QEglFSKmsVsp2Integration * m_integration
void invalidateSurface() override
Invalidates the window's surface by releasing its surface buffers.
#define EGL_PLATFORM_GBM_KHR
EGLConfig void * native_window
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy
void * native_display
void const EGLint * attrib_list