summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-01-06 14:51:37 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-17 14:30:48 +0100
commit328f2f9c35f3cc5e7049a060a608c3f72876484a (patch)
tree984f0f52446b95da5d7240122dcfbec02b0933b5
parent93154216ca7c7a46836716150fe70987d28d6f3c (diff)
eglfs: Move reusable functionality to eglconvenience
The cursor implementation is generic GL(ES) code that should be shared by all the present and future egl-based embedded platform plugins. Follow the pattern of QEGLPlatformContext and move this class into eglconvenience as QEGLPlatformCursor. Similarly, the common bits from the context implementation context are moved back to EGLPlatformContext. eglconvenience has now base classes for integration, screen, window, etc. too. By using these, eglfs becomes much smaller and cleaner. This also paves the way for creating new, separate EGL-based platform plugins for Android, embedded Linux, etc. Also added some documentation to each of the base classes. devicediscovery is now fixed to be usable on any platform. The implementation in this case is naturally a dummy one. This finally allows using it from anywhere without myriads of ugly ifdefs. Change-Id: I02946e360c04e02de7fe234a23a08320eff4ccf5 Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
-rw-r--r--src/platformsupport/devicediscovery/devicediscovery.pri13
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp72
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_p.h9
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri20
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor.cpp (renamed from src/plugins/platforms/eglfs/qeglfscompositor.cpp)71
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor_p.h (renamed from src/plugins/platforms/eglfs/qeglfscompositor.h)27
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp108
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience_p.h10
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer.cpp12
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp (renamed from src/plugins/platforms/eglfs/qeglfsbackingstore.cpp)74
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h (renamed from src/plugins/platforms/eglfs/qeglfsbackingstore.h)19
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp30
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h4
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor.cpp (renamed from src/plugins/platforms/eglfs/qeglfscursor.cpp)157
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor_p.h (renamed from src/plugins/platforms/eglfs/qeglfscursor.h)41
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp255
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration_p.h97
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen.cpp110
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen_p.h81
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow.cpp118
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow_p.h76
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pri10
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.cpp15
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.h6
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks.h4
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp129
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp189
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h47
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp68
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h40
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp56
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h41
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglscreen.cpp10
33 files changed, 1288 insertions, 731 deletions
diff --git a/src/platformsupport/devicediscovery/devicediscovery.pri b/src/platformsupport/devicediscovery/devicediscovery.pri
index 9a58eeedfe..9748129225 100644
--- a/src/platformsupport/devicediscovery/devicediscovery.pri
+++ b/src/platformsupport/devicediscovery/devicediscovery.pri
@@ -1,12 +1,17 @@
-linux:contains(QT_CONFIG, evdev) {
- HEADERS += $$PWD/qdevicediscovery_p.h
+HEADERS += $$PWD/qdevicediscovery_p.h
+linux {
contains(QT_CONFIG, libudev) {
SOURCES += $$PWD/qdevicediscovery_udev.cpp
-
INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
- } else {
+ # Use our own define. QT_NO_LIBUDEV may not be set on non-Linux systems.
+ DEFINES += QDEVICEDISCOVERY_UDEV
+ } else: contains(QT_CONFIG, evdev) {
SOURCES += $$PWD/qdevicediscovery_static.cpp
+ } else {
+ SOURCES += $$PWD/qdevicediscovery_dummy.cpp
}
+} else {
+ SOURCES += $$PWD/qdevicediscovery_dummy.cpp
}
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp
new file mode 100644
index 0000000000..53e042272b
--- /dev/null
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdevicediscovery_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent)
+{
+ return new QDeviceDiscovery(types, parent);
+}
+
+QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, QObject *parent)
+ : QObject(parent),
+ m_types(types)
+{
+}
+
+QDeviceDiscovery::~QDeviceDiscovery()
+{
+}
+
+QStringList QDeviceDiscovery::scanConnectedDevices()
+{
+ return QStringList();
+}
+
+bool QDeviceDiscovery::checkDeviceType(const QString &device)
+{
+ Q_UNUSED(device);
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
index 5485b73fd7..0e21118324 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
@@ -44,8 +44,9 @@
#include <QObject>
#include <QSocketNotifier>
+#include <QStringList>
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
#include <libudev.h>
#endif
@@ -88,13 +89,13 @@ signals:
void deviceDetected(const QString &deviceNode);
void deviceRemoved(const QString &deviceNode);
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
private slots:
void handleUDevNotification();
#endif
private:
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
QDeviceDiscovery(QDeviceTypes types, struct udev *udev, QObject *parent = 0);
bool checkDeviceType(struct udev_device *dev);
#else
@@ -104,7 +105,7 @@ private:
QDeviceTypes m_types;
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
void startWatching();
void stopWatching();
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index 506f4ab4ea..4af0df58c7 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -3,11 +3,30 @@ contains(QT_CONFIG,egl) {
$$PWD/qeglconvenience_p.h \
$$PWD/qeglplatformcontext_p.h \
$$PWD/qeglpbuffer_p.h
+
SOURCES += \
$$PWD/qeglconvenience.cpp \
$$PWD/qeglplatformcontext.cpp \
$$PWD/qeglpbuffer.cpp
+ unix {
+ HEADERS += \
+ $$PWD/qeglplatformcursor_p.h \
+ $$PWD/qeglplatformwindow_p.h \
+ $$PWD/qeglplatformscreen_p.h \
+ $$PWD/qeglcompositor_p.h \
+ $$PWD/qeglplatformbackingstore_p.h \
+ $$PWD/qeglplatformintegration_p.h
+
+ SOURCES += \
+ $$PWD/qeglplatformcursor.cpp \
+ $$PWD/qeglplatformwindow.cpp \
+ $$PWD/qeglplatformscreen.cpp \
+ $$PWD/qeglcompositor.cpp \
+ $$PWD/qeglplatformbackingstore.cpp \
+ $$PWD/qeglplatformintegration.cpp
+ }
+
contains(QT_CONFIG,xlib) {
HEADERS += \
$$PWD/qxlibeglintegration_p.h
@@ -16,4 +35,3 @@ contains(QT_CONFIG,egl) {
}
CONFIG += egl
}
-
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp
index 845bb5b3b5..c8b768ae48 100644
--- a/src/plugins/platforms/eglfs/qeglfscompositor.cpp
+++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp
@@ -39,22 +39,22 @@
**
****************************************************************************/
-#include "qeglfscompositor.h"
-#include "qeglfswindow.h"
-#include "qeglfscontext.h"
-
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLFramebufferObject>
+#include "qeglcompositor_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformscreen_p.h"
+
QT_BEGIN_NAMESPACE
-static QEglFSCompositor *compositor = 0;
+static QEGLCompositor *compositor = 0;
-QEglFSCompositor::QEglFSCompositor()
- : m_screen(0),
- m_program(0),
- m_initialized(false)
+QEGLCompositor::QEGLCompositor()
+ : m_context(0),
+ m_window(0),
+ m_program(0)
{
Q_ASSERT(!compositor);
m_updateTimer.setSingleShot(true);
@@ -62,51 +62,42 @@ QEglFSCompositor::QEglFSCompositor()
connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
}
-QEglFSCompositor::~QEglFSCompositor()
+QEGLCompositor::~QEGLCompositor()
{
Q_ASSERT(compositor == this);
delete m_program;
compositor = 0;
}
-void QEglFSCompositor::schedule(QEglFSScreen *screen)
+void QEGLCompositor::schedule(QOpenGLContext *context, QEGLPlatformWindow *window)
{
- m_screen = screen;
+ m_context = context;
+ m_window = window;
if (!m_updateTimer.isActive())
m_updateTimer.start();
}
-void QEglFSCompositor::renderAll()
+void QEGLCompositor::renderAll()
{
- QEglFSWindow *rootWin = m_screen->rootWindow();
- if (!rootWin)
- return;
-
- Q_ASSERT(rootWin->hasNativeWindow());
- QOpenGLContext *context = m_screen->rootContext();
- Q_ASSERT(context);
-
- context->makeCurrent(rootWin->window());
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
+ Q_ASSERT(m_context && m_window);
+ m_context->makeCurrent(m_window->window());
ensureProgram();
m_program->bind();
- QList<QEglFSWindow *> windows = m_screen->windows();
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QList<QEGLPlatformWindow *> windows = screen->windows();
for (int i = 0; i < windows.size(); ++i) {
- QEglFSWindow *window = windows.at(i);
+ QEGLPlatformWindow *window = windows.at(i);
uint texture = window->texture();
if (texture)
render(window, texture, window->isRaster());
}
m_program->release();
- context->swapBuffers(rootWin->window());
+ m_context->swapBuffers(m_window->window());
}
-void QEglFSCompositor::ensureProgram()
+void QEGLCompositor::ensureProgram()
{
if (!m_program) {
static const char *textureVertexProgram =
@@ -139,7 +130,7 @@ void QEglFSCompositor::ensureProgram()
}
}
-void QEglFSCompositor::render(QEglFSWindow *window, uint texture, bool raster)
+void QEGLCompositor::render(QEGLPlatformWindow *window, uint texture, bool raster)
{
const GLfloat textureCoordinates[] = {
0, 0,
@@ -170,11 +161,11 @@ void QEglFSCompositor::render(QEglFSWindow *window, uint texture, bool raster)
glViewport(0, 0, sr.width(), sr.height());
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
+ m_program->enableAttributeArray(m_vertexCoordEntry);
+ m_program->enableAttributeArray(m_textureCoordEntry);
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+ m_program->setAttributeArray(m_vertexCoordEntry, vertexCoordinates, 2);
+ m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
glBindTexture(GL_TEXTURE_2D, texture);
@@ -183,18 +174,18 @@ void QEglFSCompositor::render(QEglFSWindow *window, uint texture, bool raster)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
+ m_program->enableAttributeArray(m_textureCoordEntry);
+ m_program->enableAttributeArray(m_vertexCoordEntry);
}
-QEglFSCompositor *QEglFSCompositor::instance()
+QEGLCompositor *QEGLCompositor::instance()
{
if (!compositor)
- compositor = new QEglFSCompositor;
+ compositor = new QEGLCompositor;
return compositor;
}
-void QEglFSCompositor::destroy()
+void QEGLCompositor::destroy()
{
delete compositor;
compositor = 0;
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.h b/src/platformsupport/eglconvenience/qeglcompositor_p.h
index 0d5daafa2c..28e770e408 100644
--- a/src/plugins/platforms/eglfs/qeglfscompositor.h
+++ b/src/platformsupport/eglconvenience/qeglcompositor_p.h
@@ -39,47 +39,46 @@
**
****************************************************************************/
-#ifndef QEGLFSCOMPOSITOR_H
-#define QEGLFSCOMPOSITOR_H
+#ifndef QEGLCOMPOSITOR_H
+#define QEGLCOMPOSITOR_H
#include <QtCore/QTimer>
-#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE
-class QEglFSScreen;
-class QEglFSWindow;
class QOpenGLShaderProgram;
+class QOpenGLContext;
+class QEGLPlatformWindow;
-class QEglFSCompositor : public QObject, public QOpenGLFunctions
+class QEGLCompositor : public QObject
{
Q_OBJECT
public:
- void schedule(QEglFSScreen *screen);
+ void schedule(QOpenGLContext *context, QEGLPlatformWindow *window);
- static QEglFSCompositor *instance();
+ static QEGLCompositor *instance();
static void destroy();
private slots:
void renderAll();
private:
- QEglFSCompositor();
- ~QEglFSCompositor();
+ QEGLCompositor();
+ ~QEGLCompositor();
- void render(QEglFSWindow *window, uint texture, bool raster);
+ void render(QEGLPlatformWindow *window, uint texture, bool raster);
void ensureProgram();
- QEglFSScreen *m_screen;
+ QOpenGLContext *m_context;
+ QEGLPlatformWindow *m_window;
QTimer m_updateTimer;
QOpenGLShaderProgram *m_program;
int m_vertexCoordEntry;
int m_textureCoordEntry;
int m_isRasterEntry;
- bool m_initialized;
};
QT_END_NAMESPACE
-#endif // QEGLFSCOMPOSITOR_H
+#endif // QEGLCOMPOSITOR_H
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
index fe6ba2b215..6c2cc4a186 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience.cpp
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -41,6 +41,12 @@
#include <QByteArray>
+#ifdef Q_OS_UNIX
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#include <private/qmath_p.h>
+#endif
+
#include "qeglconvenience_p.h"
QT_BEGIN_NAMESPACE
@@ -427,4 +433,106 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config)
qWarning("\n");
}
+#ifdef Q_OS_UNIX
+
+QSizeF q_physicalScreenSizeFromFb(int framebufferDevice)
+{
+ const int defaultPhysicalDpi = 100;
+ static QSizeF size;
+
+ if (size.isEmpty()) {
+ // Note: in millimeters
+ int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt();
+ int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt();
+
+ if (width && height) {
+ size.setWidth(width);
+ size.setHeight(height);
+ return size;
+ }
+
+ struct fb_var_screeninfo vinfo;
+ int w = -1;
+ int h = -1;
+ QSize screenResolution;
+
+ if (framebufferDevice != -1) {
+ if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+ qWarning("eglconvenience: Could not query screen info");
+ } else {
+ w = vinfo.width;
+ h = vinfo.height;
+ screenResolution = QSize(vinfo.xres, vinfo.yres);
+ }
+ } else {
+ screenResolution = q_screenSizeFromFb(framebufferDevice);
+ }
+
+ size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
+ size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));
+ }
+
+ return size;
+}
+
+QSize q_screenSizeFromFb(int framebufferDevice)
+{
+ const int defaultWidth = 800;
+ const int defaultHeight = 600;
+ static QSize size;
+
+ if (size.isEmpty()) {
+ int width = qgetenv("QT_QPA_EGLFS_WIDTH").toInt();
+ int height = qgetenv("QT_QPA_EGLFS_HEIGHT").toInt();
+
+ if (width && height) {
+ size.setWidth(width);
+ size.setHeight(height);
+ return size;
+ }
+
+ struct fb_var_screeninfo vinfo;
+ int xres = -1;
+ int yres = -1;
+
+ if (framebufferDevice != -1) {
+ if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+ qWarning("eglconvenience: Could not read screen info");
+ } else {
+ xres = vinfo.xres;
+ yres = vinfo.yres;
+ }
+ }
+
+ size.setWidth(xres <= 0 ? defaultWidth : xres);
+ size.setHeight(yres <= 0 ? defaultHeight : yres);
+ }
+
+ return size;
+}
+
+int q_screenDepthFromFb(int framebufferDevice)
+{
+ const int defaultDepth = 32;
+ static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();
+
+ if (depth == 0) {
+ struct fb_var_screeninfo vinfo;
+
+ if (framebufferDevice != -1) {
+ if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1)
+ qWarning("eglconvenience: Could not query screen info");
+ else
+ depth = vinfo.bits_per_pixel;
+ }
+
+ if (depth <= 0)
+ depth = defaultDepth;
+ }
+
+ return depth;
+}
+
+#endif // Q_OS_UNIX
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h
index 35c225cc2f..d4ac669906 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience_p.h
+++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h
@@ -42,11 +42,11 @@
#ifndef QEGLCONVENIENCE_H
#define QEGLCONVENIENCE_H
-
#include <QtGui/QSurfaceFormat>
#include <QtCore/QVector>
-
+#include <QtCore/QSizeF>
#include <EGL/egl.h>
+
QT_BEGIN_NAMESPACE
QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format);
@@ -56,6 +56,12 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config,
bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
void q_printEglConfig(EGLDisplay display, EGLConfig config);
+#ifdef Q_OS_UNIX
+QSizeF q_physicalScreenSizeFromFb(int framebufferDevice);
+QSize q_screenSizeFromFb(int framebufferDevice);
+int q_screenDepthFromFb(int framebufferDevice);
+#endif
+
class QEglConfigChooser
{
public:
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
index 919314e9aa..295f8756c4 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp
+++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
@@ -45,6 +45,18 @@
QT_BEGIN_NAMESPACE
+/*!
+ \class QEGLPbuffer
+ \brief A pbuffer-based implementation of QPlatformOffscreenSurface for EGL.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ To use this implementation in the platform plugin simply
+ reimplement QPlatformIntegration::createPlatformOffscreenSurface()
+ and return a new instance of this class.
+*/
+
QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
: QPlatformOffscreenSurface(offscreenSurface)
, m_format(format)
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
index 03531916cf..543cf2a978 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
@@ -39,31 +39,54 @@
**
****************************************************************************/
-#include "qeglfsbackingstore.h"
-#include "qeglfscompositor.h"
-#include "qeglfscursor.h"
-#include "qeglfswindow.h"
-#include "qeglfscontext.h"
-
-#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
+
+#include "qeglplatformbackingstore_p.h"
+#include "qeglcompositor_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformscreen_p.h"
QT_BEGIN_NAMESPACE
-QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
+/*!
+ \class QEGLPlatformBackingStore
+ \brief A backing store implementation for EGL and GLES.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ This implementation uploads raster-rendered widget windows into
+ textures and composites them onto a single native window using
+ QEGLCompositor. This means that multiple top-level widgets are
+ supported without creating actual native windows for each of them.
+
+ The class is ready to be used as-is, the default
+ QEGLPlatformIntegration::createPlatformBackingStore()
+ implementation creates an instance which is ready to be used
+ without further customization.
+
+ If QEGLCompositor is not suitable, this backing store
+ implementation can also be used without it. In this case a
+ subclass must reimplement composite() and schedule an update in
+ its custom compositor when this function is called. The textures
+ are accessible via QEGLPlatformWindow::texture().
+*/
+
+QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window)
: QPlatformBackingStore(window),
- m_window(static_cast<QEglFSWindow *>(window->handle())),
+ m_window(static_cast<QEGLPlatformWindow *>(window->handle())),
m_texture(0)
{
m_window->setBackingStore(this);
}
-QPaintDevice *QEglFSBackingStore::paintDevice()
+QPaintDevice *QEGLPlatformBackingStore::paintDevice()
{
return &m_image;
}
-void QEglFSBackingStore::updateTexture()
+void QEGLPlatformBackingStore::updateTexture()
{
glBindTexture(GL_TEXTURE_2D, m_texture);
@@ -102,7 +125,7 @@ void QEglFSBackingStore::updateTexture()
}
}
-void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(window);
Q_UNUSED(region);
@@ -112,34 +135,41 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
qWarning("QEglBackingStore::flush %p", window);
#endif
- QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (!rootWin || !rootWin->isRaster())
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || !dstWin->isRaster())
return;
m_window->create();
- rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
+ QOpenGLContext *context = screen->compositingContext();
+ context->makeCurrent(dstWin->window());
updateTexture();
- QEglFSCompositor::instance()->schedule(rootWin->screen());
+ composite(context, dstWin);
+}
+
+void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
+{
+ QEGLCompositor::instance()->schedule(context, window);
}
-void QEglFSBackingStore::beginPaint(const QRegion &rgn)
+void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn)
{
m_dirty |= rgn;
}
-void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
+void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(staticContents);
- QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (!rootWin || !rootWin->isRaster())
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || !dstWin->isRaster())
return;
m_image = QImage(size, QImage::Format_RGB32);
m_window->create();
- rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
- initializeOpenGLFunctions();
+ screen->compositingContext()->makeCurrent(dstWin->window());
if (m_texture)
glDeleteTextures(1, &m_texture);
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
index 9af856e8e7..58fc386892 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
@@ -39,24 +39,23 @@
**
****************************************************************************/
-#ifndef QEGLFSBACKINGSTORE_H
-#define QEGLFSBACKINGSTORE_H
+#ifndef QEGLPLATFORMBACKINGSTORE_H
+#define QEGLPLATFORMBACKINGSTORE_H
#include <qpa/qplatformbackingstore.h>
-#include <QtGui/QOpenGLFunctions>
#include <QImage>
#include <QRegion>
QT_BEGIN_NAMESPACE
-class QOpenGLPaintDevice;
-class QEglFSWindow;
+class QOpenGLContext;
+class QEGLPlatformWindow;
-class QEglFSBackingStore : public QPlatformBackingStore, public QOpenGLFunctions
+class QEGLPlatformBackingStore : public QPlatformBackingStore
{
public:
- QEglFSBackingStore(QWindow *window);
+ QEGLPlatformBackingStore(QWindow *window);
QPaintDevice *paintDevice();
@@ -67,10 +66,12 @@ public:
uint texture() const { return m_texture; }
+ virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
+
private:
void updateTexture();
- QEglFSWindow *m_window;
+ QEGLPlatformWindow *m_window;
QImage m_image;
uint m_texture;
QRegion m_dirty;
@@ -78,4 +79,4 @@ private:
QT_END_NAMESPACE
-#endif // QEGLFSBACKINGSTORE_H
+#endif // QEGLPLATFORMBACKINGSTORE_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 1a7eb9d92f..614d086178 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -40,12 +40,27 @@
****************************************************************************/
#include "qeglplatformcontext_p.h"
-
#include "qeglconvenience_p.h"
-
#include <qpa/qplatformwindow.h>
-#include <EGL/egl.h>
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformContext
+ \brief An EGL context implementation.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ Implement QPlatformOpenGLContext using EGL. To use it in platform
+ plugins a subclass must be created since
+ eglSurfaceForPlatformSurface() has to be reimplemented. This
+ function is used for mapping platform surfaces (windows) to EGL
+ surfaces and is necessary since different platform plugins may
+ have different ways of handling native windows (for example, a
+ plugin may choose not to back every platform window by a real EGL
+ surface). Other than that, no further customization is necessary.
+ */
static inline void bindApi(const QSurfaceFormat &format)
{
@@ -84,6 +99,9 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform
EGLConfig config, EGLenum eglApi)
: m_eglDisplay(display)
, m_eglConfig(config)
+ , m_swapInterval(-1)
+ , m_swapIntervalEnvChecked(false)
+ , m_swapIntervalFromEnv(-1)
{
init(format, share);
Q_UNUSED(eglApi);
@@ -152,8 +170,8 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
if (ok) {
if (!m_swapIntervalEnvChecked) {
m_swapIntervalEnvChecked = true;
- if (qEnvironmentVariableIsSet("QT_QPA_EGL_SWAPINTERVAL")) {
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGL_SWAPINTERVAL");
+ if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) {
+ QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
bool ok;
const int swapInterval = swapIntervalString.toInt(&ok);
if (ok)
@@ -234,3 +252,5 @@ EGLConfig QEGLPlatformContext::eglConfig() const
{
return m_eglConfig;
}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
index a976aff271..d62082faa2 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
@@ -46,6 +46,8 @@
#include <qpa/qplatformopenglcontext.h>
#include <EGL/egl.h>
+QT_BEGIN_NAMESPACE
+
class QEGLPlatformContext : public QPlatformOpenGLContext
{
public:
@@ -84,4 +86,6 @@ private:
int m_swapIntervalFromEnv;
};
+QT_END_NAMESPACE
+
#endif //QEGLPLATFORMCONTEXT_H
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
index 0066426769..55590dbc9e 100644
--- a/src/plugins/platforms/eglfs/qeglfscursor.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
@@ -39,19 +39,47 @@
**
****************************************************************************/
-#include "qeglfscursor.h"
+#include "qeglplatformcursor_p.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtDebug>
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
+
QT_BEGIN_NAMESPACE
-QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
- : m_screen(screen), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), m_textureEntry(0)
+/*!
+ \class QEGLPlatformCursor
+ \brief Mouse cursor implementation using OpenGL.
+ \since 5.2
+ \internal
+ \ingroup qpa
+ */
+
+QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen)
+ : m_visible(true),
+ m_screen(screen),
+ m_program(0),
+ m_vertexCoordEntry(0),
+ m_textureCoordEntry(0),
+ m_textureEntry(0)
{
+ QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
+ if (hideCursorVal.isEmpty()) {
+ QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
+ m_visible = !dis->scanConnectedDevices().isEmpty();
+ } else {
+ m_visible = hideCursorVal.toInt() == 0;
+ }
+ if (!m_visible)
+ return;
+
+ // Try to load the cursor atlas. If this fails, m_visible is set to false and
+ // paintOnScreen() and setCurrentCursor() become no-ops.
initCursorAtlas();
// initialize the cursor
@@ -61,15 +89,15 @@ QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
#endif
}
-QEglFSCursor::~QEglFSCursor()
+QEGLPlatformCursor::~QEGLPlatformCursor()
{
resetResources();
}
-void QEglFSCursor::resetResources()
+void QEGLPlatformCursor::resetResources()
{
if (QOpenGLContext::currentContext()) {
- glDeleteProgram(m_program);
+ delete m_program;
glDeleteTextures(1, &m_cursor.customCursorTexture);
glDeleteTextures(1, &m_cursorAtlas.texture);
}
@@ -79,46 +107,7 @@ void QEglFSCursor::resetResources()
m_cursorAtlas.texture = 0;
}
-GLuint QEglFSCursor::createShader(GLenum shaderType, const char *program)
-{
- GLuint shader = glCreateShader(shaderType);
- glShaderSource(shader, 1 /* count */, &program, NULL /* lengths */);
- glCompileShader(shader);
- GLint status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (status == GL_TRUE)
- return shader;
-
- GLint length;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
- char *infoLog = new char[length];
- glGetShaderInfoLog(shader, length, NULL, infoLog);
- qDebug("%s shader compilation error: %s", shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment", infoLog);
- delete [] infoLog;
- return 0;
-}
-
-GLuint QEglFSCursor::createProgram(GLuint vshader, GLuint fshader)
-{
- GLuint program = glCreateProgram();
- glAttachShader(program, vshader);
- glAttachShader(program, fshader);
- glLinkProgram(program);
- GLint status;
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (status == GL_TRUE)
- return program;
-
- GLint length;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
- char *infoLog = new char[length];
- glGetProgramInfoLog(program, length, NULL, infoLog);
- qDebug("program link error: %s", infoLog);
- delete [] infoLog;
- return 0;
-}
-
-void QEglFSCursor::createShaderPrograms()
+void QEGLPlatformCursor::createShaderPrograms()
{
static const char *textureVertexProgram =
"attribute highp vec2 vertexCoordEntry;\n"
@@ -136,18 +125,17 @@ void QEglFSCursor::createShaderPrograms()
" gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
"}\n";
- GLuint vertexShader = createShader(GL_VERTEX_SHADER, textureVertexProgram);
- GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, textureFragmentProgram);
- m_program = createProgram(vertexShader, fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
+ m_program = new QOpenGLShaderProgram;
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_program->link();
- m_vertexCoordEntry = glGetAttribLocation(m_program, "vertexCoordEntry");
- m_textureCoordEntry = glGetAttribLocation(m_program, "textureCoordEntry");
- m_textureEntry = glGetUniformLocation(m_program, "texture");
+ m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
+ m_textureEntry = m_program->attributeLocation("texture");
}
-void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
+void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image)
{
if (!*texture)
glGenTextures(1, texture);
@@ -161,25 +149,29 @@ void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
}
-void QEglFSCursor::initCursorAtlas()
+void QEGLPlatformCursor::initCursorAtlas()
{
static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");
if (json.isEmpty())
json = ":/cursor.json";
- QFile file(json);
- file.open(QFile::ReadOnly);
+ QFile file(QString::fromUtf8(json));
+ if (!file.open(QFile::ReadOnly)) {
+ m_visible = false;
+ return;
+ }
+
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
QJsonObject object = doc.object();
- QString atlas = object.value("image").toString();
+ QString atlas = object.value(QLatin1String("image")).toString();
Q_ASSERT(!atlas.isEmpty());
- const int cursorsPerRow = object.value("cursorsPerRow").toDouble();
+ const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble();
Q_ASSERT(cursorsPerRow);
m_cursorAtlas.cursorsPerRow = cursorsPerRow;
- const QJsonArray hotSpots = object.value("hotSpots").toArray();
+ const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray();
Q_ASSERT(hotSpots.count() == Qt::LastCursor);
for (int i = 0; i < hotSpots.count(); i++) {
QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble());
@@ -195,7 +187,7 @@ void QEglFSCursor::initCursorAtlas()
}
#ifndef QT_NO_CURSOR
-void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
+void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window)
{
Q_UNUSED(window);
const QRect oldCursorRect = cursorRect();
@@ -203,8 +195,11 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
update(oldCursorRect | cursorRect());
}
-bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
+bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor)
{
+ if (!m_visible)
+ return false;
+
const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor)
return false;
@@ -237,30 +232,30 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
}
#endif
-void QEglFSCursor::update(const QRegion &rgn)
+void QEGLPlatformCursor::update(const QRegion &rgn)
{
QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(m_cursor.pos), rgn);
QWindowSystemInterface::flushWindowSystemEvents();
}
-QRect QEglFSCursor::cursorRect() const
+QRect QEGLPlatformCursor::cursorRect() const
{
return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
}
-QPoint QEglFSCursor::pos() const
+QPoint QEGLPlatformCursor::pos() const
{
return m_cursor.pos;
}
-void QEglFSCursor::setPos(const QPoint &pos)
+void QEGLPlatformCursor::setPos(const QPoint &pos)
{
const QRect oldCursorRect = cursorRect();
m_cursor.pos = pos;
update(oldCursorRect | cursorRect());
}
-void QEglFSCursor::pointerEvent(const QMouseEvent &event)
+void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event)
{
if (event.type() != QEvent::MouseMove)
return;
@@ -269,8 +264,11 @@ void QEglFSCursor::pointerEvent(const QMouseEvent &event)
update(oldCursorRect | cursorRect());
}
-void QEglFSCursor::paintOnScreen()
+void QEGLPlatformCursor::paintOnScreen()
{
+ if (!m_visible)
+ return;
+
const QRectF cr = cursorRect();
const QRect screenRect(m_screen->geometry());
const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1;
@@ -282,11 +280,10 @@ void QEglFSCursor::paintOnScreen()
draw(r);
}
-void QEglFSCursor::draw(const QRectF &r)
+void QEGLPlatformCursor::draw(const QRectF &r)
{
if (!m_program) {
// one time initialization
- initializeOpenGLFunctions();
createShaderPrograms();
if (!m_cursorAtlas.texture) {
@@ -306,7 +303,7 @@ void QEglFSCursor::draw(const QRectF &r)
Q_ASSERT(m_cursor.texture);
- glUseProgram(m_program);
+ m_program->bind();
const GLfloat x1 = r.left();
const GLfloat x2 = r.right();
@@ -332,13 +329,13 @@ void QEglFSCursor::draw(const QRectF &r)
glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
+ m_program->enableAttributeArray(m_vertexCoordEntry);
+ m_program->enableAttributeArray(m_textureCoordEntry);
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, cursorCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+ m_program->setAttributeArray(m_vertexCoordEntry, cursorCoordinates, 2);
+ m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
- glUniform1i(m_textureEntry, 0);
+ m_program->setUniformValue(m_textureEntry, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -347,10 +344,10 @@ void QEglFSCursor::draw(const QRectF &r)
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
+ m_program->disableAttributeArray(m_textureCoordEntry);
+ m_program->disableAttributeArray(m_vertexCoordEntry);
- glUseProgram(0);
+ m_program->release();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
index 71ff73b8f3..52359b84cd 100644
--- a/src/plugins/platforms/eglfs/qeglfscursor.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
@@ -39,49 +39,42 @@
**
****************************************************************************/
-#ifndef QEGLFSCURSOR_H
-#define QEGLFSCURSOR_H
+#ifndef QEGLPLATFORMCURSOR_H
+#define QEGLPLATFORMCURSOR_H
#include <qpa/qplatformcursor.h>
-#include <QtGui/QOpenGLFunctions>
-#include "qeglfsscreen.h"
+#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
class QOpenGLShaderProgram;
-class QEglFSScreen;
-class QEglFSCursor : public QPlatformCursor, public QOpenGLFunctions
+class QEGLPlatformCursor : public QPlatformCursor
{
public:
- QEglFSCursor(QEglFSScreen *screen);
- ~QEglFSCursor();
+ QEGLPlatformCursor(QPlatformScreen *screen);
+ ~QEGLPlatformCursor();
#ifndef QT_NO_CURSOR
void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE;
#endif
void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
-
QPoint pos() const Q_DECL_OVERRIDE;
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
QRect cursorRect() const;
-
- virtual void paintOnScreen();
-
+ void paintOnScreen();
void resetResources();
-protected:
+private:
#ifndef QT_NO_CURSOR
bool setCurrentCursor(QCursor *cursor);
#endif
void draw(const QRectF &rect);
void update(const QRegion &region);
-
- GLuint createShader(GLenum shaderType, const char *program);
- GLuint createProgram(GLuint vshader, GLuint fshader);
-
- QEglFSScreen *m_screen;
+ void createShaderPrograms();
+ static void createCursorTexture(uint *texture, const QImage &image);
+ void initCursorAtlas();
// current cursor information
struct Cursor {
@@ -97,11 +90,6 @@ protected:
bool customCursorPending;
} m_cursor;
-private:
- void createShaderPrograms();
- static void createCursorTexture(uint *texture, const QImage &image);
- void initCursorAtlas();
-
// cursor atlas information
struct CursorAtlas {
CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
@@ -113,7 +101,9 @@ private:
QImage image; // valid until it's uploaded
} m_cursorAtlas;
- GLuint m_program;
+ bool m_visible;
+ QPlatformScreen *m_screen;
+ QOpenGLShaderProgram *m_program;
int m_vertexCoordEntry;
int m_textureCoordEntry;
int m_textureEntry;
@@ -121,5 +111,4 @@ private:
QT_END_NAMESPACE
-#endif // QEGLFSCURSOR_H
-
+#endif // QEGLPLATFORMCURSOR_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
new file mode 100644
index 0000000000..28cd1a236f
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixservices_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#include "qeglplatformintegration_p.h"
+#include "qeglplatformcontext_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformbackingstore_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformIntegration
+ \brief Base class for EGL-based QPlatformIntegration implementations.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ This class provides most of the necessary platform integration for
+ an EGL-based Unix system. Platform plugins must subclass this and
+ reimplement the virtuals for creating platform screens and windows
+ since they will most likely wish to use a subclass for these.
+
+ The backing store, native interface accessors, font database,
+ basic capability flags, etc. are provided out of the box, no
+ further customization is needed. Subclasses are still responsible
+ however for context and offscreen surface creation.
+
+ \note It is critical that this class' implementation of
+ initialize() is called. Therefore subclasses should either avoid
+ to reimplement this function or call the base class
+ implementation.
+ */
+
+QEGLPlatformIntegration::QEGLPlatformIntegration()
+ : m_screen(0),
+ m_display(EGL_NO_DISPLAY),
+ m_inputContext(0),
+ mFontDb(new QGenericUnixFontDatabase),
+ mServices(new QGenericUnixServices)
+{
+}
+
+QEGLPlatformIntegration::~QEGLPlatformIntegration()
+{
+ delete m_screen;
+ if (m_display != EGL_NO_DISPLAY)
+ eglTerminate(m_display);
+}
+
+void QEGLPlatformIntegration::initialize()
+{
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ qFatal("Could not bind GL_ES API");
+
+ m_display = eglGetDisplay(nativeDisplay());
+ if (m_display == EGL_NO_DISPLAY)
+ qFatal("Could not open egl display");
+
+ EGLint major, minor;
+ if (!eglInitialize(m_display, &major, &minor))
+ qFatal("Could not initialize egl display");
+
+ m_screen = createScreen();
+ screenAdded(m_screen);
+
+ m_inputContext = QPlatformInputContextFactory::create();
+}
+
+QAbstractEventDispatcher *QEGLPlatformIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
+QPlatformServices *QEGLPlatformIntegration::services() const
+{
+ return mServices.data();
+}
+
+QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const
+{
+ return mFontDb.data();
+}
+
+QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QEGLPlatformBackingStore(window);
+}
+
+QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const
+{
+ QWindowSystemInterface::flushWindowSystemEvents();
+ QEGLPlatformWindow *w = createWindow(window);
+ w->create();
+ if (window->type() != Qt::ToolTip)
+ w->requestActivateWindow();
+ return w;
+}
+
+bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ case WindowManagement: return false;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const
+{
+ return const_cast<QEGLPlatformIntegration *>(this);
+}
+
+enum ResourceType {
+ EglDisplay,
+ EglWindow,
+ EglContext
+};
+
+static int resourceType(const QByteArray &key)
+{
+ static const QByteArray names[] = { // match ResourceType
+ QByteArrayLiteral("egldisplay"),
+ QByteArrayLiteral("eglwindow"),
+ QByteArrayLiteral("eglcontext")
+ };
+ const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
+ const QByteArray *result = std::find(names, end, key);
+ if (result == end)
+ result = std::find(names, end, key.toLower());
+ return int(result - names);
+}
+
+void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &resource)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglDisplay:
+ result = m_screen->display();
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEGLPlatformIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglDisplay:
+ if (window && window->handle())
+ result = static_cast<QEGLPlatformScreen *>(window->handle()->screen())->display();
+ else
+ result = m_screen->display();
+ break;
+ case EglWindow:
+ if (window && window->handle())
+ result = reinterpret_cast<void*>(static_cast<QEGLPlatformWindow *>(window->handle())->eglWindow());
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglContext:
+ if (context->handle())
+ result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static void *eglContextForContext(QOpenGLContext *context)
+{
+ Q_ASSERT(context);
+
+ QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
+ if (!handle)
+ return 0;
+
+ return handle->eglContext();
+}
+
+QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "get_egl_context")
+ return NativeResourceForContextFunction(eglContextForContext);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
new file mode 100644
index 0000000000..ea667e7d6f
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMINTEGRATION_H
+#define QEGLPLATFORMINTEGRATION_H
+
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformnativeinterface.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEGLPlatformScreen;
+class QEGLPlatformWindow;
+
+class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
+{
+public:
+ QEGLPlatformIntegration();
+ ~QEGLPlatformIntegration();
+
+ void initialize() Q_DECL_OVERRIDE;
+
+ QEGLPlatformScreen *screen() const { return m_screen; }
+ EGLDisplay display() const { return m_display; }
+
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QPlatformServices *services() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ // QPlatformNativeInterface
+ void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+
+protected:
+ virtual QEGLPlatformScreen *createScreen() const = 0;
+ virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0;
+ virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; }
+
+private:
+ QEGLPlatformScreen *m_screen;
+ EGLDisplay m_display;
+ QPlatformInputContext *m_inputContext;
+ QScopedPointer<QPlatformFontDatabase> mFontDb;
+ QScopedPointer<QPlatformServices> mServices;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMINTEGRATION_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
new file mode 100644
index 0000000000..72e7f6a6df
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglcompositor_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformScreen
+ \brief Base class for EGL-based platform screen implementations.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ This class provides a lightweight base for QPlatformScreen
+ implementations. It covers basic window stack management which is
+ necessary when compositing multiple raster (widget-based) windows
+ together into one single native surface.
+
+ Reimplementing the virtuals are essential when using
+ QEGLPlatformBackingStore. The context and the window returned from
+ these are the ones that are used when compositing the textures
+ generated from the raster (widget) based windows.
+
+ \note It is up to the QEGLPlatformWindow subclasses to use the
+ functions, like addWindow(), removeWindow(), etc., provided here.
+ */
+
+QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy)
+ : m_dpy(dpy)
+{
+}
+
+QEGLPlatformScreen::~QEGLPlatformScreen()
+{
+ QEGLCompositor::destroy();
+}
+
+void QEGLPlatformScreen::addWindow(QEGLPlatformWindow *window)
+{
+ if (!m_windows.contains(window)) {
+ m_windows.append(window);
+ topWindowChanged(window);
+ }
+}
+
+void QEGLPlatformScreen::removeWindow(QEGLPlatformWindow *window)
+{
+ m_windows.removeOne(window);
+ if (!m_windows.isEmpty())
+ topWindowChanged(m_windows.last());
+}
+
+void QEGLPlatformScreen::moveToTop(QEGLPlatformWindow *window)
+{
+ m_windows.removeOne(window);
+ m_windows.append(window);
+ topWindowChanged(window);
+}
+
+void QEGLPlatformScreen::changeWindowIndex(QEGLPlatformWindow *window, int newIdx)
+{
+ int idx = m_windows.indexOf(window);
+ if (idx != -1 && idx != newIdx) {
+ m_windows.move(idx, newIdx);
+ if (newIdx == m_windows.size() - 1)
+ topWindowChanged(m_windows.last());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
new file mode 100644
index 0000000000..d0d8a52a87
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMSCREEN_H
+#define QEGLPLATFORMSCREEN_H
+
+#include <QtCore/QList>
+#include <qpa/qplatformscreen.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLContext;
+class QEGLPlatformWindow;
+
+class QEGLPlatformScreen : public QPlatformScreen
+{
+public:
+ QEGLPlatformScreen(EGLDisplay dpy);
+ ~QEGLPlatformScreen();
+
+ QList<QEGLPlatformWindow *> windows() const { return m_windows; }
+
+ void addWindow(QEGLPlatformWindow *window);
+ void removeWindow(QEGLPlatformWindow *window);
+ void moveToTop(QEGLPlatformWindow *window);
+ void changeWindowIndex(QEGLPlatformWindow *window, int newIdx);
+
+ virtual void topWindowChanged(QEGLPlatformWindow *window) { Q_UNUSED(window); }
+
+ EGLDisplay display() const { return m_dpy; }
+
+ virtual QEGLPlatformWindow *compositingWindow() = 0;
+ virtual QOpenGLContext *compositingContext() = 0;
+
+private:
+ QList<QEGLPlatformWindow *> m_windows;
+ EGLDisplay m_dpy;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMSCREEN_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
new file mode 100644
index 0000000000..a635bfff29
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformbackingstore_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformWindow
+ \brief Base class for EGL-based platform window implementations.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ Lightweight class providing some basic platform window operations
+ and interfacing with QEGLPlatformBackingStore.
+
+ Almost no QPlatformWindow functions are implemented here. This is
+ intentional because different platform plugins may use different
+ strategies for their window management (some may force fullscreen
+ windows, some may not, some may share the underlying native
+ surface, some may not, etc.) and therefore it is not sensible to
+ enforce anything for these functions.
+
+ \note Subclasses are responsible for invoking this class'
+ implementation of create(). When using QEGLPlatformScreen, the
+ subclasses of this class are expected to utilize the window stack
+ management functions (addWindow() etc.) provided there.
+ */
+
+QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w)
+ : QPlatformWindow(w),
+ m_winId(0)
+{
+}
+
+static WId newWId()
+{
+ static WId id = 0;
+
+ if (id == std::numeric_limits<WId>::max())
+ qWarning("QEGLPlatformWindow: Out of window IDs");
+
+ return ++id;
+}
+
+void QEGLPlatformWindow::create()
+{
+ m_winId = newWId();
+
+ // Save the original surface type before changing to OpenGLSurface.
+ m_raster = (window()->surfaceType() == QSurface::RasterSurface);
+ window()->setSurfaceType(QSurface::OpenGLSurface);
+
+ if (window()->type() == Qt::Desktop) {
+ QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
+ QPlatformWindow::setGeometry(fullscreenRect);
+ QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
+ return;
+ }
+}
+
+uint QEGLPlatformWindow::texture() const
+{
+ if (m_backingStore)
+ return m_backingStore->texture();
+
+ return 0;
+}
+
+WId QEGLPlatformWindow::winId() const
+{
+ return m_winId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
new file mode 100644
index 0000000000..770c741623
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMWINDOW_H
+#define QEGLPLATFORMWINDOW_H
+
+#include <qpa/qplatformwindow.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEGLPlatformBackingStore;
+
+class QEGLPlatformWindow : public QPlatformWindow
+{
+public:
+ QEGLPlatformWindow(QWindow *w);
+
+ virtual void create();
+
+ QEGLPlatformBackingStore *backingStore() { return m_backingStore; }
+ void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; }
+ uint texture() const;
+ bool isRaster() const { return m_raster; }
+
+ WId winId() const Q_DECL_OVERRIDE;
+
+ virtual EGLNativeWindowType eglWindow() const = 0;
+
+private:
+ QEGLPlatformBackingStore *m_backingStore;
+ bool m_raster;
+ WId m_winId;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMWINDOW_H
diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri
index 390061c168..7afa9c9e11 100644
--- a/src/plugins/platforms/eglfs/eglfs.pri
+++ b/src/plugins/platforms/eglfs/eglfs.pri
@@ -12,21 +12,15 @@ DEFINES += MESA_EGL_NO_X11_HEADERS
SOURCES += $$PWD/qeglfsintegration.cpp \
$$PWD/qeglfswindow.cpp \
- $$PWD/qeglfsbackingstore.cpp \
$$PWD/qeglfsscreen.cpp \
$$PWD/qeglfshooks_stub.cpp \
- $$PWD/qeglfscursor.cpp \
- $$PWD/qeglfscontext.cpp \
- $$PWD/qeglfscompositor.cpp
+ $$PWD/qeglfscontext.cpp
HEADERS += $$PWD/qeglfsintegration.h \
$$PWD/qeglfswindow.h \
- $$PWD/qeglfsbackingstore.h \
$$PWD/qeglfsscreen.h \
- $$PWD/qeglfscursor.h \
$$PWD/qeglfshooks.h \
- $$PWD/qeglfscontext.h \
- $$PWD/qeglfscompositor.h
+ $$PWD/qeglfscontext.h
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp
index dd3f272d8b..86ceb0721b 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp
@@ -41,11 +41,12 @@
#include "qeglfscontext.h"
#include "qeglfswindow.h"
-#include "qeglfscursor.h"
#include "qeglfshooks.h"
#include "qeglfsintegration.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtGui/QSurface>
#include <QtDebug>
@@ -58,11 +59,6 @@ QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContex
{
}
-bool QEglFSContext::makeCurrent(QPlatformSurface *surface)
-{
- return QEGLPlatformContext::makeCurrent(surface);
-}
-
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
if (surface->surface()->surfaceClass() == QSurface::Window)
@@ -73,10 +69,10 @@ EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface
void QEglFSContext::swapBuffers(QPlatformSurface *surface)
{
+ // draw the cursor
if (surface->surface()->surfaceClass() == QSurface::Window) {
- QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
- // draw the cursor
- if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(window->screen()->cursor()))
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ if (QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(window->screen()->cursor()))
cursor->paintOnScreen();
}
@@ -85,4 +81,3 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface)
}
QT_END_NAMESPACE
-
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h
index 6caa49ab4f..22a7c67e46 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.h
+++ b/src/plugins/platforms/eglfs/qeglfscontext.h
@@ -42,7 +42,6 @@
#ifndef QEGLFSCONTEXT_H
#define QEGLFSCONTEXT_H
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
@@ -52,9 +51,8 @@ class QEglFSContext : public QEGLPlatformContext
public:
QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLenum eglApi = EGL_OPENGL_ES_API);
- bool makeCurrent(QPlatformSurface *surface);
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
- void swapBuffers(QPlatformSurface *surface);
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h
index 1cd1380994..dfafec73af 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks.h
+++ b/src/plugins/platforms/eglfs/qeglfshooks.h
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-class QEglFSCursor;
+class QEGLPlatformCursor;
class QEglFSScreen;
class QEglFSHooks
@@ -73,7 +73,7 @@ public:
const QSurfaceFormat &format);
virtual void destroyNativeWindow(EGLNativeWindowType window);
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
- virtual QEglFSCursor *createCursor(QEglFSScreen *screen) const;
+ virtual QEGLPlatformCursor *createCursor(QPlatformScreen *screen) const;
virtual bool filterConfig(EGLDisplay display, EGLConfig config) const;
virtual void waitForVSync() const;
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index 4dc0783d43..f5467fd6a4 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -40,14 +40,14 @@
****************************************************************************/
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
-#include <private/qmath_p.h>
#include <private/qcore_unix_p.h>
QT_BEGIN_NAMESPACE
@@ -82,105 +82,12 @@ EGLNativeDisplayType QEglFSHooks::platformDisplay() const
QSizeF QEglFSHooks::physicalScreenSize() const
{
- static QSizeF size;
- if (size.isEmpty()) {
-
- // Note: in millimeters
- int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt();
- int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt();
-
- if (width && height) {
- // no need to read fb0
- size.setWidth(width);
- size.setHeight(height);
- return size;
- }
-
- struct fb_var_screeninfo vinfo;
- int w = -1;
- int h = -1;
- QSize screenResolution;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- qWarning("EGLFS: Could not query variable screen info.");
- } else {
- w = vinfo.width;
- h = vinfo.height;
- screenResolution = QSize(vinfo.xres, vinfo.yres);
- }
- } else {
- screenResolution = screenSize();
- }
-
- const int defaultPhysicalDpi = 100;
- size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
- size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));
-
- if (w <= 0 || h <= 0) {
- qWarning("EGLFS: Unable to query physical screen size, defaulting to %d dpi.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH "
- "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).",
- defaultPhysicalDpi);
- }
-
- // override fb0 from environment var setting
- if (width)
- size.setWidth(width);
- if (height)
- size.setWidth(height);
- }
- return size;
+ return q_physicalScreenSizeFromFb(framebuffer);
}
QSize QEglFSHooks::screenSize() const
{
- static QSize size;
-
- if (size.isEmpty()) {
- int width = qgetenv("QT_QPA_EGLFS_WIDTH").toInt();
- int height = qgetenv("QT_QPA_EGLFS_HEIGHT").toInt();
-
- if (width && height) {
- // no need to read fb0
- size.setWidth(width);
- size.setHeight(height);
- return size;
- }
-
- struct fb_var_screeninfo vinfo;
-
- int xres = -1;
- int yres = -1;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- qWarning("EGLFS: Could not query variable screen info.");
- } else {
- xres = vinfo.xres;
- yres = vinfo.yres;
- }
- }
-
- const int defaultWidth = 800;
- const int defaultHeight = 600;
- size.setWidth(xres <= 0 ? defaultWidth : xres);
- size.setHeight(yres <= 0 ? defaultHeight : yres);
-
- if (xres <= 0 || yres <= 0) {
- qWarning("EGLFS: Unable to query screen resolution, defaulting to %dx%d.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_WIDTH and QT_QPA_EGLFS_HEIGHT.",
- defaultWidth, defaultHeight);
- }
-
- // override fb0 from environment var setting
- if (width)
- size.setWidth(width);
- if (height)
- size.setHeight(height);
- }
-
- return size;
+ return q_screenSizeFromFb(framebuffer);
}
QDpi QEglFSHooks::logicalDpi() const
@@ -204,29 +111,7 @@ Qt::ScreenOrientation QEglFSHooks::orientation() const
int QEglFSHooks::screenDepth() const
{
- static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();
-
- if (depth == 0) {
- struct fb_var_screeninfo vinfo;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1)
- qWarning("EGLFS: Could not query variable screen info.");
- else
- depth = vinfo.bits_per_pixel;
- }
-
- const int defaultDepth = 32;
-
- if (depth <= 0) {
- depth = defaultDepth;
-
- qWarning("EGLFS: Unable to query screen depth, defaulting to %d.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_DEPTH.", defaultDepth);
- }
- }
-
- return depth;
+ return q_screenDepthFromFb(framebuffer);
}
QImage::Format QEglFSHooks::screenFormat() const
@@ -265,9 +150,9 @@ bool QEglFSHooks::hasCapability(QPlatformIntegration::Capability cap) const
return false;
}
-QEglFSCursor *QEglFSHooks::createCursor(QEglFSScreen *screen) const
+QEGLPlatformCursor *QEglFSHooks::createCursor(QPlatformScreen *screen) const
{
- return new QEglFSCursor(screen);
+ return new QEGLPlatformCursor(screen);
}
void QEglFSHooks::waitForVSync() const
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index d6832493f1..dfe240a888 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -42,15 +42,10 @@
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
-#include "qeglfsbackingstore.h"
-#include "qeglfscompositor.h"
#include "qeglfshooks.h"
#include <QtGui/private/qguiapplication_p.h>
-#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
@@ -68,8 +63,6 @@
#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformcursor.h>
-#include <qpa/qplatforminputcontextfactory_p.h>
-
#include "qeglfscontext.h"
#include <EGL/egl.h>
@@ -82,10 +75,6 @@ static void initResources()
QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
- : mFontDb(new QGenericUnixFontDatabase)
- , mServices(new QGenericUnixServices)
- , mScreen(0)
- , mInputContext(0)
{
mDisableInputHandlers = qgetenv("QT_QPA_EGLFS_DISABLE_INPUT").toInt();
@@ -94,9 +83,6 @@ QEglFSIntegration::QEglFSIntegration()
QEglFSIntegration::~QEglFSIntegration()
{
- QEglFSCompositor::destroy();
- delete mScreen;
- eglTerminate(mDisplay);
QEglFSHooks::hooks()->platformDestroy();
}
@@ -106,33 +92,12 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
if (QEglFSHooks::hooks() && QEglFSHooks::hooks()->hasCapability(cap))
return true;
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return true;
- case ThreadedOpenGL: return true;
- case WindowManagement: return false;
- default: return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
-{
- QWindowSystemInterface::flushWindowSystemEvents();
- QEglFSWindow *w = new QEglFSWindow(window);
- w->create();
- if (window->type() != Qt::ToolTip)
- w->requestActivateWindow();
- return w;
-}
-
-QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
-{
- return new QEglFSBackingStore(window);
+ return QEGLPlatformIntegration::hasCapability(cap);
}
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay);
+ return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), display());
}
QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
@@ -141,164 +106,40 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf
return new QEGLPbuffer(screen->display(), QEglFSHooks::hooks()->surfaceFormatFor(surface->requestedFormat()), surface);
}
-QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
-{
- return mFontDb.data();
-}
-
-QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
void QEglFSIntegration::initialize()
{
QEglFSHooks::hooks()->platformInit();
- EGLint major, minor;
-
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- qWarning("Could not bind GL_ES API\n");
- qFatal("EGL error");
- }
-
- mDisplay = eglGetDisplay(QEglFSHooks::hooks() ? QEglFSHooks::hooks()->platformDisplay() : EGL_DEFAULT_DISPLAY);
- if (mDisplay == EGL_NO_DISPLAY) {
- qWarning("Could not open egl display\n");
- qFatal("EGL error");
- }
-
- if (!eglInitialize(mDisplay, &major, &minor)) {
- qWarning("Could not initialize egl display\n");
- qFatal("EGL error");
- }
-
- mScreen = createScreen();
- screenAdded(mScreen);
-
- mInputContext = QPlatformInputContextFactory::create();
+ QEGLPlatformIntegration::initialize();
if (!mDisableInputHandlers)
createInputHandlers();
}
-QEglFSScreen *QEglFSIntegration::createScreen() const
+EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const
{
- return new QEglFSScreen(mDisplay);
+ return QEglFSHooks::hooks()->platformDisplay();
}
-QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
+QEGLPlatformScreen *QEglFSIntegration::createScreen() const
{
- switch (hint)
- {
- case QPlatformIntegration::ShowIsFullScreen:
- return mScreen->rootWindow() == 0;
- default:
- return QPlatformIntegration::styleHint(hint);
- }
-}
-
-QPlatformServices *QEglFSIntegration::services() const
-{
- return mServices.data();
+ return new QEglFSScreen(display());
}
-QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const
+QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
{
- return const_cast<QEglFSIntegration *>(this);
+ return new QEglFSWindow(window);
}
-enum ResourceType {
- EglDisplay,
- EglWindow,
- EglContext
-};
-
-static int resourceType(const QByteArray &key)
-{
- static const QByteArray names[] = { // match ResourceType
- QByteArrayLiteral("egldisplay"),
- QByteArrayLiteral("eglwindow"),
- QByteArrayLiteral("eglcontext")
- };
- const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
- const QByteArray *result = std::find(names, end, key);
- if (result == end)
- result = std::find(names, end, key.toLower());
- return int(result - names);
-}
-
-void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- result = mScreen->display();
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- if (window && window->handle())
- result = static_cast<QEglFSScreen *>(window->handle()->screen())->display();
- else
- result = mScreen->display();
- break;
- case EglWindow:
- if (window && window->handle())
- result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow());
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglContext:
- if (context->handle())
- result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
- break;
+ switch (hint)
+ {
+ case QPlatformIntegration::ShowIsFullScreen:
+ return screen()->compositingWindow() == 0;
default:
- break;
+ return QPlatformIntegration::styleHint(hint);
}
-
- return result;
-}
-
-static void *eglContextForContext(QOpenGLContext *context)
-{
- Q_ASSERT(context);
-
- QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
- if (!handle)
- return 0;
-
- return handle->eglContext();
-}
-
-QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
-{
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context")
- return NativeResourceForContextFunction(eglContextForContext);
-
- return 0;
}
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 12c8158bd1..581b523c76 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -42,61 +42,36 @@
#ifndef QEGLFSINTEGRATION_H
#define QEGLFSINTEGRATION_H
-#include "qeglfsscreen.h"
-
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformnativeinterface.h>
+#include <QtPlatformSupport/private/qeglplatformintegration_p.h>
#include <qpa/qplatformscreen.h>
+#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
-class QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
+class QEglFSIntegration : public QEGLPlatformIntegration
{
public:
QEglFSIntegration();
~QEglFSIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
-
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
- QPlatformNativeInterface *nativeInterface() const;
-
- QPlatformFontDatabase *fontDatabase() const;
- QPlatformServices *services() const;
-
- QAbstractEventDispatcher *createEventDispatcher() const;
- void initialize();
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
- QVariant styleHint(QPlatformIntegration::StyleHint hint) const;
+ void initialize() Q_DECL_OVERRIDE;
- // QPlatformNativeInterface
- void *nativeResourceForIntegration(const QByteArray &resource);
- void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
- void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ QVariant styleHint(QPlatformIntegration::StyleHint hint) const Q_DECL_OVERRIDE;
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
-
- QPlatformScreen *screen() const { return mScreen; }
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
- EGLDisplay display() const { return mDisplay; }
-
- QPlatformInputContext *inputContext() const { return mInputContext; }
-
protected:
- virtual QEglFSScreen *createScreen() const;
+ QEGLPlatformScreen *createScreen() const Q_DECL_OVERRIDE;
+ QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
private:
void createInputHandlers();
- EGLDisplay mDisplay;
- QScopedPointer<QPlatformFontDatabase> mFontDb;
- QScopedPointer<QPlatformServices> mServices;
- QEglFSScreen *mScreen;
- QPlatformInputContext *mInputContext;
bool mDisableInputHandlers;
};
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 758b461b3f..11c1160ce9 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -39,39 +39,25 @@
**
****************************************************************************/
-#include "qeglfscursor.h"
#include "qeglfsscreen.h"
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
-#include <QtPlatformSupport/private/qdevicediscovery_p.h>
-#endif
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
- : m_dpy(dpy),
+ : QEGLPlatformScreen(dpy),
m_surface(EGL_NO_SURFACE),
m_cursor(0),
+ m_rootWindow(0),
m_rootContext(0)
{
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglScreen %p\n", this);
#endif
- QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
- bool hideCursor = false;
- if (hideCursorVal.isEmpty()) {
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
- hideCursor = dis->scanConnectedDevices().isEmpty();
-#endif
- } else {
- hideCursor = hideCursorVal.toInt() != 0;
- }
- if (!hideCursor)
- m_cursor = QEglFSHooks::hooks()->createCursor(this);
+ m_cursor = QEglFSHooks::hooks()->createCursor(this);
}
QEglFSScreen::~QEglFSScreen()
@@ -124,50 +110,4 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface)
m_surface = surface;
}
-void QEglFSScreen::addWindow(QEglFSWindow *window)
-{
- if (!m_windows.contains(window)) {
- m_windows.append(window);
- topWindowChanged(window);
- }
-}
-
-void QEglFSScreen::removeWindow(QEglFSWindow *window)
-{
- m_windows.removeOne(window);
- if (!m_windows.isEmpty())
- topWindowChanged(m_windows.last());
-}
-
-void QEglFSScreen::moveToTop(QEglFSWindow *window)
-{
- m_windows.removeOne(window);
- m_windows.append(window);
- topWindowChanged(window);
-}
-
-void QEglFSScreen::changeWindowIndex(QEglFSWindow *window, int newIdx)
-{
- int idx = m_windows.indexOf(window);
- if (idx != -1 && idx != newIdx) {
- m_windows.move(idx, newIdx);
- if (newIdx == m_windows.size() - 1)
- topWindowChanged(m_windows.last());
- }
-}
-
-QEglFSWindow *QEglFSScreen::rootWindow()
-{
- Q_FOREACH (QEglFSWindow *window, m_windows) {
- if (window->hasNativeWindow())
- return window;
- }
- return 0;
-}
-
-void QEglFSScreen::topWindowChanged(QPlatformWindow *window)
-{
- Q_UNUSED(window);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 11d66b7e0f..13f7cfddd8 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -42,7 +42,7 @@
#ifndef QEGLFSSCREEN_H
#define QEGLFSSCREEN_H
-#include <qpa/qplatformscreen.h>
+#include <QtPlatformSupport/private/qeglplatformscreen_p.h>
#include <QtCore/QTextStream>
@@ -50,52 +50,48 @@
QT_BEGIN_NAMESPACE
-class QEglFSCursor;
+class QEGLPlatformCursor;
class QEglFSWindow;
class QOpenGLContext;
-class QEglFSScreen : public QPlatformScreen
+class QEglFSScreen : public QEGLPlatformScreen
{
public:
QEglFSScreen(EGLDisplay display);
~QEglFSScreen();
- QRect geometry() const;
- int depth() const;
- QImage::Format format() const;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ int depth() const Q_DECL_OVERRIDE;
+ QImage::Format format() const Q_DECL_OVERRIDE;
- QSizeF physicalSize() const;
- QDpi logicalDpi() const;
- Qt::ScreenOrientation nativeOrientation() const;
- Qt::ScreenOrientation orientation() const;
+ QSizeF physicalSize() const Q_DECL_OVERRIDE;
+ QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
- QPlatformCursor *cursor() const;
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
- EGLDisplay display() const { return m_dpy; }
EGLSurface primarySurface() const { return m_surface; }
- QList<QEglFSWindow *> windows() const { return m_windows; }
- void addWindow(QEglFSWindow *window);
- void removeWindow(QEglFSWindow *window);
- void moveToTop(QEglFSWindow *window);
- void changeWindowIndex(QEglFSWindow *window, int newIdx);
- QEglFSWindow *rootWindow();
- QOpenGLContext *rootContext() { return m_rootContext; }
+ QEGLPlatformWindow *compositingWindow() Q_DECL_OVERRIDE { return m_rootWindow; }
+ QOpenGLContext *compositingContext() Q_DECL_OVERRIDE { return m_rootContext; }
+
+ void setRootWindow(QEGLPlatformWindow *window) { m_rootWindow = window; }
void setRootContext(QOpenGLContext *context) { m_rootContext = context; }
protected:
void setPrimarySurface(EGLSurface surface);
- virtual void topWindowChanged(QPlatformWindow *window);
private:
friend class QEglFSWindow;
EGLDisplay m_dpy;
EGLSurface m_surface;
- QEglFSCursor *m_cursor;
- QList<QEglFSWindow *> m_windows;
+ QEGLPlatformCursor *m_cursor;
+ QEGLPlatformWindow *m_rootWindow;
QOpenGLContext *m_rootContext;
};
QT_END_NAMESPACE
+
#endif // QEGLFSSCREEN_H
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index cc0e64a83b..279e7bbc91 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -41,13 +41,11 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
-#include "qeglfsbackingstore.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
#include <QtGui/QOpenGLContext>
-
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtDebug>
@@ -55,11 +53,9 @@
QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
- : QPlatformWindow(w)
+ : QEGLPlatformWindow(w)
, m_surface(0)
, m_window(0)
- , m_wid(0)
- , m_backingStore(0)
, m_flags(0)
{
#ifdef QEGL_EXTRA_DEBUG
@@ -72,41 +68,24 @@ QEglFSWindow::~QEglFSWindow()
destroy();
}
-static WId newWId()
-{
- static WId id = 0;
-
- if (id == std::numeric_limits<WId>::max())
- qWarning("EGLFS: Out of window IDs");
-
- return ++id;
-}
-
void QEglFSWindow::create()
{
if (m_flags.testFlag(Created))
return;
+ QEGLPlatformWindow::create();
+
m_flags = Created;
- m_wid = newWId();
- if (window()->type() == Qt::Desktop) {
- QRect rect(QPoint(), QEglFSHooks::hooks()->screenSize());
- QPlatformWindow::setGeometry(rect);
- QWindowSystemInterface::handleGeometryChange(window(), rect);
+ if (window()->type() == Qt::Desktop)
return;
- }
-
- // Save the original surface type before changing to OpenGLSurface.
- if (window()->surfaceType() == QSurface::RasterSurface)
- m_flags |= IsRaster;
// Stop if there is already a window backed by a native window and surface. Additional
// raster windows will not have their own native window, surface and context. Instead,
// they will be composited onto the root window's surface.
QEglFSScreen *screen = this->screen();
if (screen->primarySurface() != EGL_NO_SURFACE) {
- if (m_flags.testFlag(IsRaster) && screen->rootWindow()->m_flags.testFlag(IsRaster))
+ if (isRaster() && screen->compositingWindow())
return;
#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)
@@ -118,7 +97,6 @@ void QEglFSWindow::create()
return;
}
- window()->setSurfaceType(QSurface::OpenGLSurface);
m_flags |= HasNativeWindow;
setGeometry(QRect()); // will become fullscreen
QWindowSystemInterface::handleExposeEvent(window(), geometry());
@@ -132,12 +110,13 @@ void QEglFSWindow::create()
screen->setPrimarySurface(m_surface);
- if (m_flags.testFlag(IsRaster)) {
+ if (isRaster()) {
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
context->setFormat(window()->requestedFormat());
context->setScreen(window()->screen());
context->create();
screen->setRootContext(context);
+ screen->setRootWindow(this);
}
}
@@ -145,7 +124,7 @@ void QEglFSWindow::destroy()
{
QEglFSScreen *screen = this->screen();
if (m_flags.testFlag(HasNativeWindow)) {
- QEglFSCursor *cursor = static_cast<QEglFSCursor *>(screen->cursor());
+ QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->cursor());
if (cursor)
cursor->resetResources();
@@ -188,7 +167,7 @@ void QEglFSWindow::resetSurface()
void QEglFSWindow::setVisible(bool visible)
{
- QList<QEglFSWindow *> windows = screen()->windows();
+ QList<QEGLPlatformWindow *> windows = screen()->windows();
if (window()->type() != Qt::Desktop) {
if (visible) {
@@ -234,11 +213,6 @@ QRect QEglFSWindow::geometry() const
return QPlatformWindow::geometry();
}
-WId QEglFSWindow::winId() const
-{
- return m_wid;
-}
-
void QEglFSWindow::requestActivateWindow()
{
if (window()->type() != Qt::Desktop)
@@ -258,7 +232,7 @@ void QEglFSWindow::raise()
void QEglFSWindow::lower()
{
- QList<QEglFSWindow *> windows = screen()->windows();
+ QList<QEGLPlatformWindow *> windows = screen()->windows();
if (window()->type() != Qt::Desktop && windows.count() > 1) {
int idx = windows.indexOf(this);
if (idx > 0) {
@@ -288,12 +262,4 @@ QEglFSScreen *QEglFSWindow::screen() const
return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
}
-uint QEglFSWindow::texture() const
-{
- if (m_backingStore)
- return m_backingStore->texture();
-
- return 0;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index ee3c194a7c..f93a9d54bc 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -45,42 +45,32 @@
#include "qeglfsintegration.h"
#include "qeglfsscreen.h"
-#include <qpa/qplatformwindow.h>
+#include <QtPlatformSupport/private/qeglplatformwindow_p.h>
QT_BEGIN_NAMESPACE
-class QEglFSBackingStore;
-
-class QEglFSWindow : public QPlatformWindow
+class QEglFSWindow : public QEGLPlatformWindow
{
public:
QEglFSWindow(QWindow *w);
~QEglFSWindow();
- void setGeometry(const QRect &);
- QRect geometry() const;
- WId winId() const;
- void setVisible(bool visible);
- void requestActivateWindow();
- void raise();
- void lower();
+ void create() Q_DECL_OVERRIDE;
+ void destroy();
+
+ void setGeometry(const QRect &) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ void setVisible(bool visible) Q_DECL_OVERRIDE;
+ void requestActivateWindow() Q_DECL_OVERRIDE;
+ void raise() Q_DECL_OVERRIDE;
+ void lower() Q_DECL_OVERRIDE;
+ QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE;
EGLSurface surface() const;
- QSurfaceFormat format() const;
- EGLNativeWindowType eglWindow() const;
-
QEglFSScreen *screen() const;
- void create();
- void destroy();
-
bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); }
- bool isRaster() const { return m_flags.testFlag(IsRaster); }
-
- QEglFSBackingStore *backingStore() { return m_backingStore; }
- void setBackingStore(QEglFSBackingStore *backingStore) { m_backingStore = backingStore; }
-
- uint texture() const;
virtual void invalidateSurface();
virtual void resetSurface();
@@ -92,13 +82,10 @@ protected:
private:
EGLConfig m_config;
QSurfaceFormat m_format;
- WId m_wid;
- QEglFSBackingStore *m_backingStore;
enum Flag {
Created = 0x01,
- IsRaster = 0x02,
- HasNativeWindow = 0x04
+ HasNativeWindow = 0x02
};
Q_DECLARE_FLAGS(Flags, Flag);
Flags m_flags;
diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
index ebc402550e..d26b20d364 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
@@ -101,16 +101,6 @@ QMinimalEglScreen::QMinimalEglScreen(EGLNativeDisplayType display)
}
qWarning("Initialized display %d %d\n", major, minor);
-
- int swapInterval = 1;
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = 1;
- }
- eglSwapInterval(m_dpy, swapInterval);
}
QMinimalEglScreen::~QMinimalEglScreen()