From 224f31c0b5ad86b5ea56025ff08faf7e25e1a82d Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Thu, 24 Mar 2016 15:38:05 +0100 Subject: Multi-screen handling for the eglfs_kms_egldevice backend Separates the generic kms classes into a own kms static lib called QtEglFsKmsSupport. The eglfs_kms plugin was changed to use these base classes and got renamed accordingly to QEglFSKmsGbm*. The eglfs_kms_egldevice plugin got extended to also derive from the kms base classed and by this provides multi-screen support Change-Id: I6de6a754e94cb8d52cf8e658b03c6bd6637674a1 Reviewed-by: Laszlo Agocs --- .../eglfs_kms_egldevice/eglfs_kms_egldevice.pro | 21 +- .../eglfs_kms_egldevice/qeglfskmsegldevice.cpp | 79 +++++++ .../eglfs_kms_egldevice/qeglfskmsegldevice.h | 61 ++++++ .../qeglfskmsegldeviceintegration.cpp | 230 +++------------------ .../qeglfskmsegldeviceintegration.h | 46 ++--- .../qeglfskmsegldevicescreen.cpp | 78 +++++++ .../eglfs_kms_egldevice/qeglfskmsegldevicescreen.h | 56 +++++ 7 files changed, 333 insertions(+), 238 deletions(-) create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h (limited to 'src/plugins/platforms/eglfs/deviceintegration/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 index 1932f861b9..3a380b7525 100644 --- 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 @@ -1,23 +1,32 @@ TARGET = qeglfs-kms-egldevice-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfs_device_lib-private eglfs_kms_support-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support DEFINES += MESA_EGL_NO_X11_HEADERS +CONFIG += link_pkgconfig +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += libdrm +} else { + LIBS += -ldrm +} + CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfskmsegldevicemain.cpp \ - $$PWD/qeglfskmsegldeviceintegration.cpp + $$PWD/qeglfskmsegldeviceintegration.cpp \ + qeglfskmsegldevice.cpp \ + qeglfskmsegldevicescreen.cpp -HEADERS += $$PWD/qeglfskmsegldeviceintegration.h +HEADERS += $$PWD/qeglfskmsegldeviceintegration.h \ + qeglfskmsegldevice.h \ + qeglfskmsegldevicescreen.h OTHER_FILES += $$PWD/eglfs_kms_egldevice.json -LIBS += -ldrm - PLUGIN_TYPE = egldeviceintegrations PLUGIN_CLASS_NAME = QEglFSKmsEglDeviceIntegrationPlugin load(qt_plugin) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp new file mode 100644 index 0000000000..e09f2fdb18 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsegldevice.h" +#include "qeglfskmsegldevicescreen.h" + +#include + +QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path) + : QEglFSKmsDevice(integration, path) +{ +} + +bool QEglFSKmsEglDevice::open() +{ + Q_ASSERT(fd() == -1); + + int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); + if (Q_UNLIKELY(fd < 0)) + qFatal("Could not open DRM device"); + + setFd(fd); + + return true; +} + +void QEglFSKmsEglDevice::close() +{ + if (qt_safe_close(fd()) == -1) + qErrnoWarning("Could not close DRM device"); + + setFd(-1); +} + +EGLNativeDisplayType QEglFSKmsEglDevice::device() const +{ + return 0; +} + +QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +{ + return new QEglFSKmsEglDeviceScreen(integration, device, output, position); +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h new file mode 100644 index 0000000000..f85ec27fa2 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSKMSEGLDEVICE_H +#define QEGLFSKMSEGLDEVICE_H + +#include + +class QEglFSKmsEglDevice: public QEglFSKmsDevice +{ +public: + QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path); + + virtual bool open() Q_DECL_OVERRIDE; + virtual void close() Q_DECL_OVERRIDE; + + virtual EGLNativeDisplayType device() const Q_DECL_OVERRIDE; + + virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position) Q_DECL_OVERRIDE; +}; + +#endif // QEGLFSKMSEGLDEVICE_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 201d9d7443..838569d5c6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -38,60 +39,26 @@ ****************************************************************************/ #include "qeglfskmsegldeviceintegration.h" +#include +#include "qeglfswindow.h" +#include "qeglfskmsegldevice.h" +#include "qeglfskmsscreen.h" #include #include QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms") - QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() - : m_dri_fd(-1) + : QEglFSKmsIntegration() , 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) , m_funcs(Q_NULLPTR) { qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); } -void QEglFSKmsEglDeviceIntegration::platformInit() -{ - if (Q_UNLIKELY(!query_egl_device())) - qFatal("Could not set up EGL device!"); - - const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); - if (Q_UNLIKELY(!deviceName)) - qFatal("Failed to query device name from EGLDevice"); - - qCDebug(qLcEglfsKmsDebug, "Opening %s", deviceName); - - m_dri_fd = drmOpen(deviceName, Q_NULLPTR); - if (Q_UNLIKELY(m_dri_fd < 0)) - qFatal("Could not open DRM device"); - - if (Q_UNLIKELY(!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; - - delete m_funcs; - m_funcs = Q_NULLPTR; -} - -EGLNativeDisplayType QEglFSKmsEglDeviceIntegration::platformDisplay() const +EGLint QEglFSKmsEglDeviceIntegration::surfaceType() const { - return static_cast(m_egl_device); + return EGL_STREAM_BIT_KHR; } EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) @@ -120,46 +87,17 @@ EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nat return display; } -QSizeF QEglFSKmsEglDeviceIntegration::physicalScreenSize() const -{ - const int defaultPhysicalDpi = 100; - static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH"); - static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT"); - QSizeF size(width, height); - if (size.isEmpty()) { - size = QSizeF(m_drm_connector->mmWidth, m_drm_connector->mmHeight); - if (size.isEmpty()) { - const float pixelsPerMm = Q_MM_PER_INCH / defaultPhysicalDpi; - size = QSizeF(screenSize().width() * pixelsPerMm, screenSize().height() * pixelsPerMm); - } - } - return size; -} - -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 +bool QEglFSKmsEglDeviceIntegration::supportsSurfacelessContexts() const { - QSurfaceFormat format(inputFormat); - format.setRenderableType(QSurfaceFormat::OpenGLES); - format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - format.setRedBufferSize(8); - format.setGreenBufferSize(8); - format.setBlueBufferSize(8); - return format; + // 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; } -EGLint QEglFSKmsEglDeviceIntegration::surfaceType() const +bool QEglFSKmsEglDeviceIntegration::supportsPBuffers() const { - return EGL_STREAM_BIT_KHR; + return true; } class QEglJetsonTK1Window : public QEglFSWindow @@ -216,11 +154,15 @@ void QEglJetsonTK1Window::resetSurface() return; } + QEglFSKmsScreen *cur_screen = static_cast(screen()); + Q_ASSERT(cur_screen); + qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", cur_screen->output().crtc_id); + for (int i = 0; i < actualCount; ++i) { EGLAttrib id; if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id); - if (id == EGLAttrib(m_integration->m_drm_crtc)) + if (id == EGLAttrib(cur_screen->output().crtc_id)) layer = layers[i]; } else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { // Not used yet, just for debugging. @@ -251,8 +193,8 @@ void QEglJetsonTK1Window::resetSurface() 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(); + const int w = cur_screen->geometry().width(); + const int h = cur_screen->geometry().height(); qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); const EGLint stream_producer_attribs[] = { @@ -280,131 +222,23 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const 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) { - // Maybe detecting the DPMS mode could help here, but there are no properties - // exposed on the connector apparently. So rely on an env var for now. - static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); - if (!alwaysDoSet) { - 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 (Q_UNLIKELY(ret)) - qFatal("drmModeSetCrtc failed"); - } -} - -qreal QEglFSKmsEglDeviceIntegration::refreshRate() const -{ - quint32 refresh = m_drm_mode.vrefresh; - return refresh > 0 ? refresh : 60; -} - -bool QEglFSKmsEglDeviceIntegration::supportsSurfacelessContexts() const +bool QEglFSKmsEglDeviceIntegration::separateScreens() 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; + return true; } -bool QEglFSKmsEglDeviceIntegration::setup_kms() +QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath) { - 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; + Q_UNUSED(devicePath) - 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 (Q_UNLIKELY(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; + if (Q_UNLIKELY(!query_egl_device())) + qFatal("Could not set up EGL device!"); - drmModeFreeResources(resources); + const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); + if (Q_UNLIKELY(!deviceName)) + qFatal("Failed to query device name from EGLDevice"); - return true; + return new QEglFSKmsEglDevice(this, deviceName); } bool QEglFSKmsEglDeviceIntegration::query_egl_device() diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index 3d8f48d63c..43c1945a7f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -40,17 +41,7 @@ #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 @@ -59,41 +50,28 @@ QT_BEGIN_NAMESPACE -class QEglFSKmsEglDeviceIntegration : public QEGLDeviceIntegration +class QEglFSKmsEglDeviceIntegration : public QEglFSKmsIntegration { 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; + EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) Q_DECL_OVERRIDE; bool supportsSurfacelessContexts() const Q_DECL_OVERRIDE; + bool supportsPBuffers() const Q_DECL_OVERRIDE; + QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; + + virtual bool separateScreens() const Q_DECL_OVERRIDE; +protected: + QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; +private: bool setup_kms(); bool query_egl_device(); - // 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; + friend class QEglJetsonTK1Window; // EGLStream infrastructure QEGLStreamConvenience *m_funcs; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp new file mode 100644 index 0000000000..da1b577801 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsegldevicescreen.h" +#include "qeglfskmsegldevice.h" + +QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) + : QEglFSKmsScreen(integration, device, output, position) +{ +} + +void QEglFSKmsEglDeviceScreen::waitForFlip() +{ + if (!output().mode_set) { + output().mode_set = true; + + drmModeCrtcPtr currentMode = drmModeGetCrtc(device()->fd(), output().crtc_id); + const bool alreadySet = currentMode + && currentMode->width == output().modes[output().mode].hdisplay + && currentMode->height == output().modes[output().mode].vdisplay; + if (currentMode) + drmModeFreeCrtc(currentMode); + if (alreadySet) { + // Maybe detecting the DPMS mode could help here, but there are no properties + // exposed on the connector apparently. So rely on an env var for now. + static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); + if (!alwaysDoSet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set"); + return; + } + } + + qCDebug(qLcEglfsKmsDebug, "Setting mode"); + int ret = drmModeSetCrtc(device()->fd(), output().crtc_id, + -1, 0, 0, + &output().connector_id, 1, + &output().modes[output().mode]); + if (ret) + qFatal("drmModeSetCrtc failed"); + } + +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h new file mode 100644 index 0000000000..0cd46e9f9d --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSKMSEGLDEVICESCREEN_H +#define QEGLFSKMSEGLDEVICESCREEN_H + +#include + +class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen +{ +public: + QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, + QEglFSKmsDevice *device, + QEglFSKmsOutput output, + QPoint position); + + void waitForFlip() Q_DECL_OVERRIDE; +}; + +#endif // QEGLFSKMSEGLDEVICESCREEN_H -- cgit v1.2.3