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
6#include "qeglfskmsgbmintegration_p.h"
7#include "qeglfskmsgbmdevice_p.h"
8#include "qeglfskmsgbmscreen_p.h"
9#include "qeglfskmsgbmcursor_p.h"
10#include "qeglfskmsgbmwindow_p.h"
11#include "private/qeglfscursor_p.h"
12
13#include <QtCore/QLoggingCategory>
14#include <QtGui/QScreen>
15#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h>
16
17#include <gbm.h>
18
19QT_BEGIN_NAMESPACE
20
21QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
22{
23 qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created");
24}
25
26#ifndef EGL_EXT_platform_base
27typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
28#endif
29
30#ifndef EGL_PLATFORM_GBM_KHR
31#define EGL_PLATFORM_GBM_KHR 0x31D7
32#endif
33
34EGLDisplay QEglFSKmsGbmIntegration::createDisplay(EGLNativeDisplayType nativeDisplay)
35{
36 qCDebug(qLcEglfsKmsDebug, "Querying EGLDisplay");
37 EGLDisplay display;
38
39 PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = nullptr;
40 const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
41 if (extensions && (strstr(haystack: extensions, needle: "EGL_KHR_platform_gbm") || strstr(haystack: extensions, needle: "EGL_MESA_platform_gbm"))) {
42 getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
43 eglGetProcAddress(procname: "eglGetPlatformDisplayEXT"));
44 }
45
46 if (getPlatformDisplay) {
47 display = getPlatformDisplay(EGL_PLATFORM_GBM_KHR, nativeDisplay, nullptr);
48 } else {
49 qCDebug(qLcEglfsKmsDebug, "No eglGetPlatformDisplay for GBM, falling back to eglGetDisplay");
50 display = eglGetDisplay(display_id: nativeDisplay);
51 }
52
53 return display;
54}
55
56EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format)
57{
58 Q_UNUSED(format);
59 Q_ASSERT(device());
60
61 gbm_surface *surface = gbm_surface_create(gbm: static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(),
62 width: 1, height: 1,
63 GBM_FORMAT_XRGB8888,
64 flags: GBM_BO_USE_RENDERING);
65
66 return reinterpret_cast<EGLNativeWindowType>(surface);
67}
68
69void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window)
70{
71 gbm_surface *surface = reinterpret_cast<gbm_surface *>(window);
72 gbm_surface_destroy(surface);
73}
74
75QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const
76{
77#if QT_CONFIG(opengl)
78 if (!screenConfig()->hwCursor()) {
79 qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor");
80 return new QEglFSCursor(screen);
81 }
82#else
83 Q_UNUSED(screen);
84#endif
85 return nullptr;
86}
87
88void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface)
89{
90 QWindow *window = static_cast<QWindow *>(surface->surface());
91 QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(window->screen()->handle());
92 screen->flip();
93}
94
95QKmsDevice *QEglFSKmsGbmIntegration::createDevice()
96{
97 QString path = screenConfig()->devicePath();
98 if (!path.isEmpty()) {
99 qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file";
100 } else {
101 QDeviceDiscovery *d = QDeviceDiscovery::create(type: QDeviceDiscovery::Device_VideoMask);
102 const QStringList devices = d->scanConnectedDevices();
103 qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices;
104 d->deleteLater();
105
106 if (Q_UNLIKELY(devices.isEmpty()))
107 qFatal(msg: "Could not find DRM device!");
108
109 path = devices.first();
110 qCDebug(qLcEglfsKmsDebug) << "Using" << path;
111 }
112
113 return new QEglFSKmsGbmDevice(screenConfig(), path);
114}
115
116QEglFSWindow *QEglFSKmsGbmIntegration::createWindow(QWindow *window) const
117{
118 return new QEglFSKmsGbmWindow(window, this);
119}
120
121QT_END_NAMESPACE
122

source code of qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp