summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs/qeglfshooks.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-10-10 16:03:36 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2014-12-08 14:16:41 +0100
commitb7f0583f3157da5cb8a6d86af5a4b4f410847556 (patch)
treed99b9b8924d771a82f73d95ad0e86e52ca57f271 /src/plugins/platforms/eglfs/qeglfshooks.cpp
parentfec53bf5edb3ac8b847a52c486eae4ea166b09bd (diff)
Pluginize the eglfs hooks
Following the principle of device integrations in QtWayland and soon xcb, a plugin interface is being introduced to gradually replace the statically compiled-in hooks. The interface is same as before for the time being, for compatibility with the existing device-specific hooks. QEglFSHooks is now just a dummy subclass for QEGLDeviceIntegration to support the legacy, compiled-in, device-specific hooks. When -device is not used with configure and so there is no hook active, the new plugin-based approach kicks in. The environment variable QT_QPA_EGLFS_INTEGRATION can be set to indicate the preferred integration name (e.g. eglfs_x11, eglfs_kms). It can also be set to "none", indicating that no plugins should be considered and the default, non-specialized integration is to be used. (this is for devices, like Beagleboard|bone, that do not need any special code to set up EGL) Device makespecs can set EGLFS_DEVICE_INTEGRATION. The value is then used as the default, preferred plugin name when QT_QPA_EGLFS_INTEGRATION is not set. In the future device makespecs are expected to set a plugin name instead of relying on the traditional EGLFS_PLATFORM_HOOKS_*. When neither the QT_QPA_EGLFS_INTEGRATION nor EGLFS_DEVICE_INTEGRATION are set, all plugins will be tried in an unspecified order. The first one that succeeds to load is used. If all fails or there are no plugins, the built-in, non-specialized integration is used. To debug what integration is being used, enable the logging category qt.qpa.egldeviceintegration. There is some built-in logic for desktop/Mesa based systems: Under X, eglfs_x11 is preferred, otherwise eglfs_kms is prioritized. This, assuming sufficient permissions to video and input devices, allows simply launching apps with -platform eglfs. No more editing of eglfs.pri. [ChangeLog][QtGui] Added support for device-specific backend plugins in eglfs. Change-Id: Ia2ddcddac014c25817171dc140cd8cf913784ac6 Reviewed-by: Louai Al-Khanji <louai.al-khanji@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms/eglfs/qeglfshooks.cpp')
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/plugins/platforms/eglfs/qeglfshooks.cpp b/src/plugins/platforms/eglfs/qeglfshooks.cpp
new file mode 100644
index 0000000000..2f12c61f99
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfshooks.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfshooks.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug)
+
+#ifdef EGLFS_PLATFORM_HOOKS
+
+QEGLDeviceIntegration *qt_egl_device_integration()
+{
+ extern QEglFSHooks *platformHooks;
+ return platformHooks;
+}
+
+#else
+
+class DeviceIntegration
+{
+public:
+ DeviceIntegration();
+ ~DeviceIntegration() { delete m_integration; }
+ QEGLDeviceIntegration *integration() { return m_integration; }
+private:
+ QEGLDeviceIntegration *m_integration;
+};
+
+Q_GLOBAL_STATIC(DeviceIntegration, deviceIntegration)
+
+DeviceIntegration::DeviceIntegration()
+{
+ QStringList pluginKeys = QEGLDeviceIntegrationFactory::keys();
+ if (!pluginKeys.isEmpty()) {
+ // Some built-in logic: Prioritize either X11 or KMS/DRM.
+ if (qEnvironmentVariableIsSet("DISPLAY")) {
+ const QString x11key = QStringLiteral("eglfs_x11");
+ if (pluginKeys.contains(x11key)) {
+ pluginKeys.removeOne(x11key);
+ pluginKeys.prepend(x11key);
+ }
+ } else {
+ const QString kmskey = QStringLiteral("eglfs_kms");
+ if (pluginKeys.contains(kmskey)) {
+ pluginKeys.removeOne(kmskey);
+ pluginKeys.prepend(kmskey);
+ }
+ }
+
+ QByteArray requested;
+
+ // The environment variable can override everything.
+ if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_INTEGRATION")) {
+ requested = qgetenv("QT_QPA_EGLFS_INTEGRATION");
+ } else {
+ // Device-specific makespecs may define a preferred plugin.
+#ifdef EGLFS_PREFERRED_PLUGIN
+#define DEFAULT_PLUGIN EGLFS_PREFERRED_PLUGIN
+#define STR(s) #s
+#define STRQ(s) STR(s)
+ requested = STRQ(DEFAULT_PLUGIN);
+#endif
+ }
+
+ // Treat "none" as special. There has to be a way to indicate
+ // that plugins must be ignored when the device is known to be
+ // functional with the default, non-specialized integration.
+ if (requested != QByteArrayLiteral("none")) {
+ if (!requested.isEmpty()) {
+ QString reqStr = QString::fromLocal8Bit(requested);
+ pluginKeys.removeOne(reqStr);
+ pluginKeys.prepend(reqStr);
+ }
+ qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys (sorted):" << pluginKeys;
+ while (!m_integration && !pluginKeys.isEmpty()) {
+ QString key = pluginKeys.takeFirst();
+ qCDebug(qLcEglDevDebug) << "Trying to load device EGL integration" << key;
+ m_integration = QEGLDeviceIntegrationFactory::create(key);
+ }
+ }
+ }
+
+ if (!m_integration) {
+ // Use a default, non-specialized device integration when no plugin is available.
+ // For some systems this is sufficient.
+ qCDebug(qLcEglDevDebug) << "Using base device integration";
+ m_integration = new QEGLDeviceIntegration;
+ }
+}
+
+QEGLDeviceIntegration *qt_egl_device_integration()
+{
+ return deviceIntegration()->integration();
+}
+
+#endif // EGLFS_PLATFORM_HOOKS
+
+QT_END_NAMESPACE