From 58bed4cda98e8e25db8adc61c7db73b6853077dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Nystr=C3=B6m?= Date: Wed, 16 Sep 2015 11:32:57 +0200 Subject: eglfs: Support for alternative Mali driver packages In addition to the proprietary Mali Linux driver bundle from ARM, there are a couple of semi open source alternative bundles out in the wild, which are mostly derivatives from the sunxi-mali bundle. The non-ARM bundles lacks the proprietary header file fbdev_window.h which defines the fbdev_window struct. Instead, it has an equivalent mali_native_window struct in the EGL/eglplatform.h (which in turn is included by EGL/egl.h). This change adds an alternative configure test which detects the non-ARM bundles are used. It also removes the dependency on fbdev_window.h by defining the structure ourselves, which actually makes the plugin potentially compilable with *any* EGL SDK. Change-Id: I78ab4b618e8e9c774c889fe9896105cf2cf4228e Reviewed-by: Oswald Buddenhagen Reviewed-by: Laszlo Agocs --- .../eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp index 455d78035a..43decdf849 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include "qeglfsmaliintegration.h" -#include #include #include @@ -43,6 +42,11 @@ QT_BEGIN_NAMESPACE +struct fbdev_window { + unsigned short width; + unsigned short height; +}; + void QEglFSMaliIntegration::platformInit() { // Keep the non-overridden base class functions based on fb0 working. -- cgit v1.2.3 From 0ea56cc075a9217314be69d1056d9a2abcd921c5 Mon Sep 17 00:00:00 2001 From: Pier Luigi Fiorini Date: Sat, 1 Aug 2015 07:00:22 +0200 Subject: eglfs_kms: Subpixel antialiasing type [ChangeLog][QPA][eglfs][kms] Provide subpixel antialiasing type. Change-Id: I1eed487cea675d988a128f63a9d5c2c0ddeae21f Reviewed-by: Laszlo Agocs --- .../deviceintegration/eglfs_kms/qeglfskmsdevice.cpp | 1 + .../deviceintegration/eglfs_kms/qeglfskmsscreen.cpp | 18 ++++++++++++++++++ .../deviceintegration/eglfs_kms/qeglfskmsscreen.h | 3 +++ 3 files changed, 22 insertions(+) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index f3df1f8445..7528d9fe2e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -284,6 +284,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr false, drmModeGetCrtc(m_dri_fd, crtc_id), modes, + connector->subpixel, connectorProperty(connector, QByteArrayLiteral("DPMS")) }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index 227c8f9a62..d2a86c1e25 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -321,6 +321,24 @@ qreal QEglFSKmsScreen::refreshRate() const return refresh > 0 ? refresh : 60; } +QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const +{ + switch (m_output.subpixel) { + default: + case DRM_MODE_SUBPIXEL_UNKNOWN: + case DRM_MODE_SUBPIXEL_NONE: + return Subpixel_None; + case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB: + return Subpixel_RGB; + case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR: + return Subpixel_BGR; + case DRM_MODE_SUBPIXEL_VERTICAL_RGB: + return Subpixel_VRGB; + case DRM_MODE_SUBPIXEL_VERTICAL_BGR: + return Subpixel_VBGR; + } +} + QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const { return m_powerState; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index 2ce8700478..7fd6ccaa31 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -60,6 +60,7 @@ struct QEglFSKmsOutput bool mode_set; drmModeCrtcPtr saved_crtc; QList modes; + int subpixel; drmModePropertyPtr dpms_prop; }; @@ -104,6 +105,8 @@ public: QEglFSKmsOutput &output() { return m_output; } void restoreMode(); + SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE; + QPlatformScreen::PowerState powerState() const Q_DECL_OVERRIDE; void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE; -- cgit v1.2.3 From dceb424fe81ae29dde8e49a6dad300c547c8be26 Mon Sep 17 00:00:00 2001 From: Pier Luigi Fiorini Date: Sat, 11 Jul 2015 22:32:46 +0200 Subject: eglfs_kms: Skip disconnected outputs For some reason VMware reports 8 outputs, 7 of them are disconnected and so they cause several errors. Skip disconnected outputs to avoid those errors. Change-Id: I5f9fa2ef38b916af9f9ae8b50fce9fc40c18bff3 Reviewed-by: Laszlo Agocs --- .../platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index 7528d9fe2e..40cd8b8763 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -191,6 +191,12 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr return Q_NULLPTR; } + // Skip disconnected output + if (configuration == OutputConfigPreferred && connector->connection == DRM_MODE_DISCONNECTED) { + qCDebug(qLcEglfsKmsDebug) << "Skipping disconnected output" << connectorName; + return Q_NULLPTR; + } + // Get the current mode on the current crtc drmModeModeInfo crtc_mode; memset(&crtc_mode, 0, sizeof crtc_mode); -- cgit v1.2.3 From f191ba9d71bd910f205a2f41c5ac6c0d959439ed Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 28 Sep 2015 17:37:55 +0200 Subject: Revamp signal handling in eglfs/linuxfb Go back to the pipe-based signal handling. signalfd() introduces more harm than good and is a regression for applications that install their own signal handlers. Simplify the somewhat overcomplicated suspend (Ctrl+Z) logic too. There is no need for requiring a callback. Just enable/disable the keyboard and cursor on suspend and resume and emit the signals. Backends (like kms) may then perform additional steps, if they choose to do so. Task-number: QTBUG-48384 Change-Id: Ifd52de89c59915a2e0be6bf5ebc6f2ff1728eb50 Reviewed-by: Louai Al-Khanji --- .../platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index d2a86c1e25..60586f98a7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -52,15 +52,11 @@ public: QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) { m_vtHandler = static_cast(QGuiApplicationPrivate::platformIntegration())->vtHandler(); connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode); - connect(m_vtHandler, &QFbVtHandler::suspendRequested, this, &QEglFSKmsInterruptHandler::handleSuspendRequest); + connect(m_vtHandler, &QFbVtHandler::aboutToSuspend, this, &QEglFSKmsInterruptHandler::restoreVideoMode); } public slots: void restoreVideoMode() { m_screen->restoreMode(); } - void handleSuspendRequest() { - m_screen->restoreMode(); - m_vtHandler->suspend(); - } private: QFbVtHandler *m_vtHandler; -- cgit v1.2.3 From bba86a01c9828d03b1564984a08561d62686d329 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 13 Oct 2015 09:26:59 +0200 Subject: Libraries: Fix single-character string literals. Use character literals where applicable. Change-Id: I8e198774c2247c1cc1d852a41b59b301199b7878 Reviewed-by: Marc Mutz --- .../platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index 40cd8b8763..c29d64c06d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -219,7 +219,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr for (int i = 0; i < connector->count_modes; i++) { const drmModeModeInfo &mode = connector->modes[i]; qCDebug(qLcEglfsKmsDebug) << "mode" << i << mode.hdisplay << "x" << mode.vdisplay - << "@" << mode.vrefresh << "hz"; + << '@' << mode.vrefresh << "hz"; modes << connector->modes[i]; } @@ -278,7 +278,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr int height = modes[selected_mode].vdisplay; int refresh = modes[selected_mode].vrefresh; qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height - << "@" << refresh << "hz for output" << connectorName; + << '@' << refresh << "hz for output" << connectorName; } QEglFSKmsOutput output = { -- cgit v1.2.3 From 6046458dee115841c6f01b2a2e01b41be1bfbdc9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 13 Oct 2015 15:54:18 +0200 Subject: eglfs: Handle custom platform window implementations better Backends may want to subclass QEglFSWindow and reimplement resetSurface() and similar. Make it possible to do this by moving window creation to the device integration interface, similarly to screens. In addition to customizing the windows, some backends may want to disable the dependency on surfaceless contexts when using offscreen windows (i.e. pbuffer surfaces). Make this possible too. Change-Id: Ic5a426e07f821c7a800217b8799f91770ba6a6d8 Reviewed-by: Oswald Buddenhagen Reviewed-by: Louai Al-Khanji --- src/plugins/platforms/eglfs/qeglfscontext.cpp | 3 +- .../platforms/eglfs/qeglfsdeviceintegration.cpp | 21 +++++++++++++ .../platforms/eglfs/qeglfsdeviceintegration.h | 5 ++++ src/plugins/platforms/eglfs/qeglfsintegration.cpp | 15 ++++++---- src/plugins/platforms/eglfs/qeglfswindow.cpp | 34 +++++++++------------- src/plugins/platforms/eglfs/qeglfswindow.h | 2 +- 6 files changed, 53 insertions(+), 27 deletions(-) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index e2223aba43..6fcdae7ad2 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -44,7 +44,8 @@ QT_BEGIN_NAMESPACE QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLConfig *config, const QVariant &nativeHandle) - : QEGLPlatformContext(format, share, display, config, nativeHandle), + : QEGLPlatformContext(format, share, display, config, nativeHandle, + qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags(0) : QEGLPlatformContext::NoSurfaceless), m_tempWindow(0) { } diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index d27c949c8d..0c2aa7ad61 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -34,6 +34,7 @@ #include "qeglfsdeviceintegration.h" #include "qeglfsintegration.h" #include "qeglfscursor.h" +#include "qeglfswindow.h" #include #include #include @@ -175,6 +176,11 @@ EGLNativeDisplayType QEGLDeviceIntegration::platformDisplay() const return EGL_DEFAULT_DISPLAY; } +EGLDisplay QEGLDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) +{ + return eglGetDisplay(nativeDisplay); +} + bool QEGLDeviceIntegration::usesDefaultScreen() { return true; @@ -238,6 +244,11 @@ qreal QEGLDeviceIntegration::refreshRate() const return q_refreshRateFromFb(framebuffer); } +EGLint QEGLDeviceIntegration::surfaceType() const +{ + return EGL_WINDOW_BIT; +} + QSurfaceFormat QEGLDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const { QSurfaceFormat format = inputFormat; @@ -257,6 +268,11 @@ bool QEGLDeviceIntegration::filterConfig(EGLDisplay, EGLConfig) const return true; } +QEglFSWindow *QEGLDeviceIntegration::createWindow(QWindow *window) const +{ + return new QEglFSWindow(window); +} + EGLNativeWindowType QEGLDeviceIntegration::createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format) @@ -313,4 +329,9 @@ bool QEGLDeviceIntegration::supportsPBuffers() const return true; } +bool QEGLDeviceIntegration::supportsSurfacelessContexts() const +{ + return true; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index 260fc313f7..d91d67de16 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE class QPlatformSurface; +class QEglFSWindow; #define QEGLDeviceIntegrationFactoryInterface_iid "org.qt-project.qt.qpa.egl.QEGLDeviceIntegrationFactoryInterface.5.5" @@ -67,6 +68,7 @@ public: virtual void platformInit(); virtual void platformDestroy(); virtual EGLNativeDisplayType platformDisplay() const; + virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay); virtual bool usesDefaultScreen(); virtual void screenInit(); virtual void screenDestroy(); @@ -79,6 +81,8 @@ public: virtual QImage::Format screenFormat() const; virtual qreal refreshRate() const; virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; + virtual EGLint surfaceType() const; + virtual QEglFSWindow *createWindow(QWindow *window) const; virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format); @@ -92,6 +96,7 @@ public: virtual QByteArray fbDeviceName() const; virtual int framebufferIndex() const; virtual bool supportsPBuffers() const; + virtual bool supportsSurfacelessContexts() const; }; class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index f0946b9b64..2df06caa6b 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -117,7 +117,7 @@ void QEglFSIntegration::initialize() { qt_egl_device_integration()->platformInit(); - m_display = eglGetDisplay(nativeDisplay()); + m_display = qt_egl_device_integration()->createDisplay(nativeDisplay()); if (m_display == EGL_NO_DISPLAY) qFatal("Could not open egl display"); @@ -179,7 +179,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const { QWindowSystemInterface::flushWindowSystemEvents(); - QEglFSWindow *w = new QEglFSWindow(window); + QEglFSWindow *w = qt_egl_device_integration()->createWindow(window); w->create(); if (window->type() != Qt::ToolTip) w->requestActivateWindow(); @@ -213,10 +213,14 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf { EGLDisplay dpy = surface->screen() ? static_cast(surface->screen()->handle())->display() : display(); QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat()); - if (qt_egl_device_integration()->supportsPBuffers()) - return new QEGLPbuffer(dpy, fmt, surface); - else + if (qt_egl_device_integration()->supportsPBuffers()) { + QEGLPlatformContext::Flags flags = 0; + if (!qt_egl_device_integration()->supportsSurfacelessContexts()) + flags |= QEGLPlatformContext::NoSurfaceless; + return new QEGLPbuffer(dpy, fmt, surface, flags); + } else { return new QEglFSOffscreenWindow(dpy, fmt, surface); + } // Never return null. Multiple QWindows are not supported by this plugin. } @@ -433,6 +437,7 @@ EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceForm }; Chooser chooser(display); + chooser.setSurfaceType(qt_egl_device_integration()->surfaceType()); chooser.setSurfaceFormat(format); return chooser.chooseConfig(); } diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index c3b9dd6ef0..8301be8c17 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -51,7 +51,7 @@ QEglFSWindow::QEglFSWindow(QWindow *w) m_backingStore(0), m_raster(false), m_winId(0), - m_surface(0), + m_surface(EGL_NO_SURFACE), m_window(0), m_flags(0) { @@ -120,13 +120,14 @@ void QEglFSWindow::create() setGeometry(QRect()); // will become fullscreen QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); - EGLDisplay display = static_cast(screen)->display(); - QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); - m_config = QEglFSIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - resetSurface(); + if (m_surface == EGL_NO_SURFACE) { + EGLint error = eglGetError(); + eglTerminate(screen->display()); + qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); + } + screen->setPrimarySurface(m_surface); if (isRaster()) { @@ -158,15 +159,10 @@ void QEglFSWindow::destroy() QOpenGLCompositor::instance()->removeWindow(this); } -// The virtual functions resetSurface and invalidateSurface may get overridden -// in derived classes, for example in the Android port, to perform the native -// window and surface creation differently. - void QEglFSWindow::invalidateSurface() { if (m_surface != EGL_NO_SURFACE) { - EGLDisplay display = static_cast(screen())->display(); - eglDestroySurface(display, m_surface); + eglDestroySurface(screen()->display(), m_surface); m_surface = EGL_NO_SURFACE; } qt_egl_device_integration()->destroyNativeWindow(m_window); @@ -175,15 +171,13 @@ void QEglFSWindow::invalidateSurface() void QEglFSWindow::resetSurface() { - QEglFSScreen *nativeScreen = static_cast(screen()); - EGLDisplay display = nativeScreen->display(); - m_window = qt_egl_device_integration()->createNativeWindow(this, nativeScreen->geometry().size(), m_format); + EGLDisplay display = screen()->display(); + QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); + + m_config = QEglFSIntegration::chooseConfig(display, platformFormat); + m_format = q_glFormatFromConfig(display, m_config, platformFormat); + m_window = qt_egl_device_integration()->createNativeWindow(this, screen()->geometry().size(), m_format); m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL); - if (m_surface == EGL_NO_SURFACE) { - EGLint error = eglGetError(); - eglTerminate(display); - qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); - } } void QEglFSWindow::setVisible(bool visible) diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 53b9e18dc1..806b21de0a 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -89,7 +89,7 @@ public: const QPlatformTextureList *textures() const Q_DECL_OVERRIDE; void endCompositing() Q_DECL_OVERRIDE; -private: +protected: QOpenGLCompositorBackingStore *m_backingStore; bool m_raster; WId m_winId; -- cgit v1.2.3 From f0d21f6921275032edfc35bf36f71807b90fdfa2 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 13 Oct 2015 16:07:19 +0200 Subject: Add support for the Jetson TK1 Pro using EGLDevice For now we pick one crtc and find the corresponding layer. If this is not desired, set QT_QPA_EGLFS_LAYER_INDEX to override the layer to be used. Enable qt.qpa.eglfs.kms to get logs about the available layers. Change-Id: I762783f960739e32966c8cde17d8f55fbe40091f Done-with: Louai Al-Khanji Reviewed-by: Oswald Buddenhagen Reviewed-by: Louai Al-Khanji --- .../eglfs/deviceintegration/deviceintegration.pro | 1 + .../eglfs_kms_egldevice/eglfs_kms_egldevice.json | 3 + .../eglfs_kms_egldevice/eglfs_kms_egldevice.pro | 21 + .../qeglfskmsegldeviceintegration.cpp | 464 +++++++++++++++++++++ .../qeglfskmsegldeviceintegration.h | 137 ++++++ .../eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp | 49 +++ 6 files changed, 675 insertions(+) create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 0adbb0d49f..f8bb854f1c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -2,6 +2,7 @@ TEMPLATE = subdirs contains(QT_CONFIG, egl_x11): SUBDIRS += eglfs_x11 contains(QT_CONFIG, kms): SUBDIRS += eglfs_kms +contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_egldevice contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json new file mode 100644 index 0000000000..169ba1eb02 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_kms_egldevice" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro new file mode 100644 index 0000000000..2274c5b228 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -0,0 +1,21 @@ +TARGET = qeglfs-kms-egldevice-integration + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSKmsEglDeviceIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. + +CONFIG += egl +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfskmsegldevicemain.cpp \ + $$PWD/qeglfskmsegldeviceintegration.cpp + +HEADERS += $$PWD/qeglfskmsegldeviceintegration.h + +OTHER_FILES += $$PWD/eglfs_kms_egldevice.json + +LIBS += -ldrm diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp new file mode 100644 index 0000000000..2f32bd73a3 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -0,0 +1,464 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsegldeviceintegration.h" +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms") + +QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() + : m_dri_fd(-1) + , m_egl_device(EGL_NO_DEVICE_EXT) + , m_egl_display(EGL_NO_DISPLAY) + , m_drm_connector(Q_NULLPTR) + , m_drm_encoder(Q_NULLPTR) + , m_drm_crtc(0) +{ + qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); +} + +void QEglFSKmsEglDeviceIntegration::platformInit() +{ + if (!query_egl_device()) + qFatal("Could not set up EGL device!"); + + const char *deviceName = m_query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); + if (!deviceName) + qFatal("Failed to query device name from EGLDevice"); + + qCDebug(qLcEglfsKmsDebug, "Opening %s", deviceName); + + m_dri_fd = drmOpen(deviceName, Q_NULLPTR); + if (m_dri_fd < 0) + qFatal("Could not open DRM device"); + + if (!setup_kms()) + qFatal("Could not set up KMS on device %s!", m_device.constData()); + + qCDebug(qLcEglfsKmsDebug, "DRM/KMS initialized"); +} + +void QEglFSKmsEglDeviceIntegration::platformDestroy() +{ + if (qt_safe_close(m_dri_fd) == -1) + qErrnoWarning("Could not close DRM device"); + + m_dri_fd = -1; +} + +EGLNativeDisplayType QEglFSKmsEglDeviceIntegration::platformDisplay() const +{ + return static_cast(m_egl_device); +} + +EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) +{ + qCDebug(qLcEglfsKmsDebug, "Creating display"); + + const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + + m_get_platform_display = reinterpret_cast(eglGetProcAddress("eglGetPlatformDisplayEXT")); + m_has_egl_platform_device = extensions && strstr(extensions, "EGL_EXT_platform_device"); + + EGLDisplay display; + + if (!m_has_egl_platform_device) { + qWarning("EGL_EXT_platform_device not available, falling back to legacy path!"); + display = eglGetDisplay(nativeDisplay); + } else { + display = m_get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, Q_NULLPTR); + } + + if (display == EGL_NO_DISPLAY) + qFatal("Could not get EGL display"); + + EGLint major, minor; + if (!eglInitialize(display, &major, &minor)) + qFatal("Could not initialize egl display"); + + if (!eglBindAPI(EGL_OPENGL_ES_API)) + qFatal("Failed to bind EGL_OPENGL_ES_API\n"); + + return display; +} + +QSizeF QEglFSKmsEglDeviceIntegration::physicalScreenSize() const +{ + return QSizeF(m_drm_connector->mmWidth, m_drm_connector->mmHeight); +} + +QSize QEglFSKmsEglDeviceIntegration::screenSize() const +{ + return QSize(m_drm_mode.hdisplay, m_drm_mode.vdisplay); +} + +int QEglFSKmsEglDeviceIntegration::screenDepth() const +{ + return 32; +} + +QSurfaceFormat QEglFSKmsEglDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const +{ + QSurfaceFormat format(inputFormat); + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + format.setRedBufferSize(8); + format.setGreenBufferSize(8); + format.setBlueBufferSize(8); + return format; +} + +EGLint QEglFSKmsEglDeviceIntegration::surfaceType() const +{ + return EGL_STREAM_BIT_KHR; +} + +class QEglJetsonTK1Window : public QEglFSWindow +{ +public: + QEglJetsonTK1Window(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration) + : QEglFSWindow(w) + , m_integration(integration) + , m_egl_stream(EGL_NO_STREAM_KHR) + { } + + void invalidateSurface() Q_DECL_OVERRIDE; + void resetSurface() Q_DECL_OVERRIDE; + + const QEglFSKmsEglDeviceIntegration *m_integration; + EGLStreamKHR m_egl_stream; + EGLint m_latency; +}; + +void QEglJetsonTK1Window::invalidateSurface() +{ + QEglFSWindow::invalidateSurface(); + m_integration->m_destroy_stream(screen()->display(), m_egl_stream); +} + +void QEglJetsonTK1Window::resetSurface() +{ + qCDebug(qLcEglfsKmsDebug, "Creating stream"); + + EGLDisplay display = screen()->display(); + EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT; + EGLint count; + + m_egl_stream = m_integration->m_create_stream(display, Q_NULLPTR); + if (m_egl_stream == EGL_NO_STREAM_KHR) { + qWarning("resetSurface: Couldn't create EGLStream for native window"); + return; + } + + qCDebug(qLcEglfsKmsDebug, "Created stream %p on display %p", m_egl_stream, display); + + if (!m_integration->m_get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) { + qWarning("No output layers found"); + return; + } + + qCDebug(qLcEglfsKmsDebug, "Output has %d layers", count); + + QVector layers; + layers.resize(count); + EGLint actualCount; + if (!m_integration->m_get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) { + qWarning("Failed to get layers"); + return; + } + + for (int i = 0; i < actualCount; ++i) { + EGLAttrib id; + if (m_integration->m_query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { + qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], id); + if (id == EGLAttrib(m_integration->m_drm_crtc)) + layer = layers[i]; + } else if (m_integration->m_query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { + // Not used yet, just for debugging. + qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], id); + } else { + qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - unknown", i, layers[i]); + } + } + + QByteArray reqLayerIndex = qgetenv("QT_QPA_EGLFS_LAYER_INDEX"); + if (!reqLayerIndex.isEmpty()) { + int idx = reqLayerIndex.toInt(); + if (idx >= 0 && idx < layers.count()) + layer = layers[idx]; + } + + if (layer == EGL_NO_OUTPUT_LAYER_EXT) { + qWarning("resetSurface: Couldn't get EGLOutputLayer for native window"); + return; + } + + qCDebug(qLcEglfsKmsDebug, "Using layer %p", layer); + + if (!m_integration->m_stream_consumer_output(display, m_egl_stream, layer)) + qWarning("resetSurface: Unable to connect stream"); + + m_config = QEglFSIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat())); + m_format = q_glFormatFromConfig(display, m_config); + qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; + + const int w = m_integration->screenSize().width(); + const int h = m_integration->screenSize().height(); + qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); + + const EGLint stream_producer_attribs[] = { + EGL_WIDTH, w, + EGL_HEIGHT, h, + EGL_NONE + }; + + m_surface = m_integration->m_create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs); + if (m_surface == EGL_NO_SURFACE) + return; + + qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface); +} + +QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const +{ + QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this); + + if (!const_cast(this)->query_egl_extensions(eglWindow->screen()->display())) + qFatal("Required extensions missing!"); + + return eglWindow; +} + +bool QEglFSKmsEglDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case QPlatformIntegration::ThreadedPixmaps: + case QPlatformIntegration::OpenGL: + case QPlatformIntegration::ThreadedOpenGL: + case QPlatformIntegration::BufferQueueingOpenGL: + return true; + default: + return false; + } +} + +void QEglFSKmsEglDeviceIntegration::waitForVSync(QPlatformSurface *) const +{ + static bool mode_set = false; + + if (!mode_set) { + mode_set = true; + + drmModeCrtcPtr currentMode = drmModeGetCrtc(m_dri_fd, m_drm_crtc); + const bool alreadySet = currentMode + && currentMode->width == m_drm_mode.hdisplay + && currentMode->height == m_drm_mode.vdisplay; + if (currentMode) + drmModeFreeCrtc(currentMode); + if (alreadySet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set"); + return; + } + + qCDebug(qLcEglfsKmsDebug, "Setting mode"); + int ret = drmModeSetCrtc(m_dri_fd, m_drm_crtc, + -1, 0, 0, + &m_drm_connector->connector_id, 1, + const_cast(&m_drm_mode)); + if (ret) + qFatal("drmModeSetCrtc failed"); + } +} + +qreal QEglFSKmsEglDeviceIntegration::refreshRate() const +{ + quint32 refresh = m_drm_mode.vrefresh; + return refresh > 0 ? refresh : 60; +} + +bool QEglFSKmsEglDeviceIntegration::supportsSurfacelessContexts() const +{ + // Returning false disables the usage of EGL_KHR_surfaceless_context even when the + // extension is available. This is just what we need since, at least with NVIDIA + // 352.00 making a null surface current with a context breaks. + return false; +} + +bool QEglFSKmsEglDeviceIntegration::setup_kms() +{ + drmModeRes *resources; + drmModeConnector *connector; + drmModeEncoder *encoder; + quint32 crtc = 0; + int i; + + resources = drmModeGetResources(m_dri_fd); + if (!resources) { + qWarning("drmModeGetResources failed"); + return false; + } + + for (i = 0; i < resources->count_connectors; i++) { + connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); + if (!connector) + continue; + + if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) + break; + + drmModeFreeConnector(connector); + } + + if (i == resources->count_connectors) { + qWarning("No currently active connector found."); + return false; + } + + qCDebug(qLcEglfsKmsDebug, "Using connector with type %d", connector->connector_type); + + for (i = 0; i < resources->count_encoders; i++) { + encoder = drmModeGetEncoder(m_dri_fd, resources->encoders[i]); + if (!encoder) + continue; + + if (encoder->encoder_id == connector->encoder_id) + break; + + drmModeFreeEncoder(encoder); + } + + for (int j = 0; j < resources->count_crtcs; j++) { + if ((encoder->possible_crtcs & (1 << j))) { + crtc = resources->crtcs[j]; + break; + } + } + + if (crtc == 0) + qFatal("No suitable CRTC available"); + + m_drm_connector = connector; + m_drm_encoder = encoder; + m_drm_mode = connector->modes[0]; + m_drm_crtc = crtc; + + qCDebug(qLcEglfsKmsDebug).noquote() << "Using crtc" << m_drm_crtc + << "with mode" << m_drm_mode.hdisplay << "x" << m_drm_mode.vdisplay + << "@" << m_drm_mode.vrefresh; + + drmModeFreeResources(resources); + + return true; +} + +bool QEglFSKmsEglDeviceIntegration::query_egl_device() +{ + const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (!extensions) { + qWarning("eglQueryString failed"); + return false; + } + + m_has_egl_device_base = strstr(extensions, "EGL_EXT_device_base"); + m_query_devices = reinterpret_cast(eglGetProcAddress("eglQueryDevicesEXT")); + m_query_device_string = reinterpret_cast(eglGetProcAddress("eglQueryDeviceStringEXT")); + + if (!m_has_egl_device_base || !m_query_devices || !m_query_device_string) + qFatal("EGL_EXT_device_base missing"); + + EGLint num_devices = 0; + if (m_query_devices(1, &m_egl_device, &num_devices) != EGL_TRUE) { + qWarning("eglQueryDevicesEXT failed: eglError: %x", eglGetError()); + return false; + } + + qCDebug(qLcEglfsKmsDebug, "Found %d EGL devices", num_devices); + + if (num_devices < 1 || m_egl_device == EGL_NO_DEVICE_EXT) { + qWarning("eglQueryDevicesEXT could not find any EGL devices"); + return false; + } + + return true; +} + +bool QEglFSKmsEglDeviceIntegration::query_egl_extensions(EGLDisplay display) +{ + if (!eglBindAPI(EGL_OPENGL_ES_API)) { + qWarning() << Q_FUNC_INFO << "failed to bind EGL_OPENGL_ES_API"; + return false; + } + + m_create_stream = reinterpret_cast(eglGetProcAddress("eglCreateStreamKHR")); + m_destroy_stream = reinterpret_cast(eglGetProcAddress("eglDestroyStreamKHR")); + m_stream_attrib = reinterpret_cast(eglGetProcAddress("eglStreamAttribKHR")); + m_query_stream = reinterpret_cast(eglGetProcAddress("eglQueryStreamKHR")); + m_query_stream_u64 = reinterpret_cast(eglGetProcAddress("eglQueryStreamu64KHR")); + m_create_stream_producer_surface = reinterpret_cast(eglGetProcAddress("eglCreateStreamProducerSurfaceKHR")); + m_stream_consumer_output = reinterpret_cast(eglGetProcAddress("eglStreamConsumerOutputEXT")); + m_get_output_layers = reinterpret_cast(eglGetProcAddress("eglGetOutputLayersEXT")); + m_get_output_ports = reinterpret_cast(eglGetProcAddress("eglGetOutputPortsEXT")); + m_output_layer_attrib = reinterpret_cast(eglGetProcAddress("eglOutputLayerAttribEXT")); + m_query_output_layer_attrib = reinterpret_cast(eglGetProcAddress("eglQueryOutputLayerAttribEXT")); + m_query_output_layer_string = reinterpret_cast(eglGetProcAddress("eglQueryOutputLayerStringEXT")); + m_query_output_port_attrib = reinterpret_cast(eglGetProcAddress("eglQueryOutputPortAttribEXT")); + m_query_output_port_string = reinterpret_cast(eglGetProcAddress("eglQueryOutputPortStringEXT")); + m_get_stream_file_descriptor = reinterpret_cast(eglGetProcAddress("eglGetStreamFileDescriptorKHR")); + m_create_stream_from_file_descriptor = reinterpret_cast(eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR")); + m_stream_consumer_gltexture = reinterpret_cast(eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR")); + m_stream_consumer_acquire = reinterpret_cast(eglGetProcAddress("eglStreamConsumerAcquireKHR")); + + const char *extensions = eglQueryString(display, EGL_EXTENSIONS); + if (!extensions) { + qWarning() << Q_FUNC_INFO << "eglQueryString failed"; + return false; + } + + m_has_egl_stream = strstr(extensions, "EGL_KHR_stream"); + m_has_egl_stream_producer_eglsurface = strstr(extensions, "EGL_KHR_stream_producer_eglsurface"); + m_has_egl_stream_consumer_egloutput = strstr(extensions, "EGL_EXT_stream_consumer_egloutput"); + m_has_egl_output_drm = strstr(extensions, "EGL_EXT_output_drm"); + m_has_egl_output_base = strstr(extensions, "EGL_EXT_output_base"); + m_has_egl_stream_cross_process_fd = strstr(extensions, "EGL_KHR_stream_cross_process_fd"); + m_has_egl_stream_consumer_gltexture = strstr(extensions, "EGL_KHR_stream_consumer_gltexture"); + + return m_has_egl_output_base && + m_has_egl_output_drm && + m_has_egl_stream && + m_has_egl_stream_producer_eglsurface && + m_has_egl_stream_consumer_egloutput; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h new file mode 100644 index 0000000000..c6132354a8 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSKMSEGLDEVICEINTEGRATION_H +#define QEGLFSKMSEGLDEVICEINTEGRATION_H + +#include "qeglfsdeviceintegration.h" +#include "qeglfswindow.h" +#include "qeglfsintegration.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QEglFSKmsEglDeviceIntegration : public QEGLDeviceIntegration +{ +public: + QEglFSKmsEglDeviceIntegration(); + + void platformInit() Q_DECL_OVERRIDE; + void platformDestroy() Q_DECL_OVERRIDE; + EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; + EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) Q_DECL_OVERRIDE; + QSizeF physicalScreenSize() const Q_DECL_OVERRIDE; + QSize screenSize() const Q_DECL_OVERRIDE; + int screenDepth() const Q_DECL_OVERRIDE; + qreal refreshRate() const Q_DECL_OVERRIDE; + QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const Q_DECL_OVERRIDE; + EGLint surfaceType() const Q_DECL_OVERRIDE; + QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + void waitForVSync(QPlatformSurface *surface) const Q_DECL_OVERRIDE; + bool supportsSurfacelessContexts() const Q_DECL_OVERRIDE; + + bool setup_kms(); + + bool query_egl_device(); + bool query_egl_extensions(EGLDisplay display); + + // device bits + QByteArray m_device; + int m_dri_fd; + EGLDeviceEXT m_egl_device; + EGLDisplay m_egl_display; + + // KMS bits + drmModeConnector *m_drm_connector; + drmModeEncoder *m_drm_encoder; + drmModeModeInfo m_drm_mode; + quint32 m_drm_crtc; + + // EGLStream infrastructure + PFNEGLGETPLATFORMDISPLAYEXTPROC m_get_platform_display; + bool m_has_egl_platform_device; + + PFNEGLQUERYDEVICESEXTPROC m_query_devices; + PFNEGLQUERYDEVICESTRINGEXTPROC m_query_device_string; + bool m_has_egl_device_base; + + PFNEGLCREATESTREAMKHRPROC m_create_stream; + PFNEGLDESTROYSTREAMKHRPROC m_destroy_stream; + PFNEGLSTREAMATTRIBKHRPROC m_stream_attrib; + PFNEGLQUERYSTREAMKHRPROC m_query_stream; + PFNEGLQUERYSTREAMU64KHRPROC m_query_stream_u64; + bool m_has_egl_stream; + + PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC m_create_stream_producer_surface; + bool m_has_egl_stream_producer_eglsurface; + + PFNEGLSTREAMCONSUMEROUTPUTEXTPROC m_stream_consumer_output; + bool m_has_egl_stream_consumer_egloutput; + + bool m_has_egl_output_drm; + + PFNEGLGETOUTPUTLAYERSEXTPROC m_get_output_layers; + PFNEGLGETOUTPUTPORTSEXTPROC m_get_output_ports; + PFNEGLOUTPUTLAYERATTRIBEXTPROC m_output_layer_attrib; + PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC m_query_output_layer_attrib; + PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC m_query_output_layer_string; + PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC m_query_output_port_attrib; + PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC m_query_output_port_string; + bool m_has_egl_output_base; + + PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC m_get_stream_file_descriptor; + PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC m_create_stream_from_file_descriptor; + bool m_has_egl_stream_cross_process_fd; + + PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC m_stream_consumer_gltexture; + PFNEGLSTREAMCONSUMERACQUIREKHRPROC m_stream_consumer_acquire; + bool m_has_egl_stream_consumer_gltexture; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp new file mode 100644 index 0000000000..f987ae38a6 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsegldeviceintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSKmsEglDeviceIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms_egldevice.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsEglDeviceIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfskmsegldevicemain.moc" -- cgit v1.2.3 From 0a203bf753f2dc40257f1fcde20607e8f9853780 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 13 Oct 2015 16:09:51 +0200 Subject: Separate KMS and GBM tests KMS is no longer a platform plugin so the relevant leftover bits are now removed. As the introduction of the EGLDevice-based backend for eglfs shows, using DRM/KMS is not tied to GBM, separate buffer management approaches, like EGLStreams, work fine as well. Therefore separate KMS from GBM and remove the EGL and GLES dependency in the tests - this way there is nothing preventing us from using GBM without GL for example. Change-Id: Id7ebe172b44b315f9a637892237d2bb62d99aed2 Reviewed-by: Oswald Buddenhagen Reviewed-by: Louai Al-Khanji --- src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms/eglfs') diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index f8bb854f1c..cf367d930f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs contains(QT_CONFIG, egl_x11): SUBDIRS += eglfs_x11 -contains(QT_CONFIG, kms): SUBDIRS += eglfs_kms +contains(QT_CONFIG, eglfs_gbm): SUBDIRS += eglfs_kms contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_egldevice contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali -- cgit v1.2.3