Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
25
27{
28 qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via Vsp2 integration created");
29}
30
31#ifndef EGL_EXT_platform_base
32typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
33typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
34#endif
35
36#ifndef EGL_PLATFORM_GBM_KHR
37#define EGL_PLATFORM_GBM_KHR 0x31D7
38#endif
39
40EGLDisplay QEglFSKmsVsp2Integration::createDisplay(EGLNativeDisplayType nativeDisplay)
41{
42 qCDebug(qLcEglfsKmsDebug, "Querying EGLDisplay");
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{
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
76{
77 gbm_surface *surface = reinterpret_cast<gbm_surface *>(window);
78 //TODO call screen destroysurface instead
79 gbm_surface_destroy(surface);
80}
81
83{
84 QWindow *window = static_cast<QWindow *>(surface->surface());
85 auto *screen = static_cast<QEglFSKmsVsp2Screen *>(window->screen()->handle());
86 screen->flip();
87}
88
90{
92 if (!path.isEmpty()) {
93 qCDebug(qLcEglfsKmsDebug) << "VSP2: Using DRM device" << path << "specified in config file";
94 } else {
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
108}
109
111{
112public:
114 : QEglFSWindow(w)
115 , m_integration(integration)
116 {}
117
119
120 void resetSurface() override;
121 void invalidateSurface() override;
123};
124
126{
127 auto *vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen());
128 EGLDisplay display = vsp2Screen->display();
129 QSurfaceFormat platformFormat = m_integration->surfaceFormatFor(window()->requestedFormat());
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());
154 vsp2Screen->resetSurface();
155}
156
161
static QDeviceDiscovery * create(QDeviceTypes type, QObject *parent=nullptr)
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
QKmsScreenConfig * screenConfig() const
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const override
QKmsDevice * device() 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
const QEglFSKmsVsp2Integration * m_integration
QEglFSKmsVsp2Window(QWindow *w, const QEglFSKmsVsp2Integration *integration)
void invalidateSurface() override
Invalidates the window's surface by releasing its surface buffers.
EGLSurface m_surface
EGLConfig m_config
void invalidateSurface() override
Invalidates the window's surface by releasing its surface buffers.
QSurfaceFormat m_format
EGLNativeWindowType m_window
QEglFSScreen * screen() const override
QString devicePath() const
The QPlatformSurface class provides an abstraction for a surface.
QSurface * surface() const
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
\inmodule QtGui
Definition qwindow.h:63
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
#define Q_UNLIKELY(x)
QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat)
#define EGL_PLATFORM_GBM_KHR
EGLConfig config
EGLConfig void * native_window
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy
void * native_display
void const EGLint * attrib_list
EGLDeviceEXT * devices
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
#define qFatal
Definition qlogging.h:168
#define qCDebug(category,...)
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei GLenum format
GLsizei const GLchar *const * path
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScreen * screen
[1]
Definition main.cpp:29
#define Q_UNUSED(x)
QT_BEGIN_NAMESPACE Platform platform()
EGLDisplay(* PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform, void *native_display, const EGLint *attrib_list)
aWidget window() -> setWindowTitle("New Window Title")
[2]