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