summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/eglconvenience
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 /src/platformsupport/eglconvenience
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>
Diffstat (limited to 'src/platformsupport/eglconvenience')
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri20
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor.cpp194
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor_p.h84
-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.cpp187
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h82
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp30
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h4
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor.cpp353
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor_p.h114
-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
18 files changed, 1927 insertions, 8 deletions
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/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp
new file mode 100644
index 0000000000..c8b768ae48
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** 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/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLFramebufferObject>
+
+#include "qeglcompositor_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QEGLCompositor *compositor = 0;
+
+QEGLCompositor::QEGLCompositor()
+ : m_context(0),
+ m_window(0),
+ m_program(0)
+{
+ Q_ASSERT(!compositor);
+ m_updateTimer.setSingleShot(true);
+ m_updateTimer.setInterval(0);
+ connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
+}
+
+QEGLCompositor::~QEGLCompositor()
+{
+ Q_ASSERT(compositor == this);
+ delete m_program;
+ compositor = 0;
+}
+
+void QEGLCompositor::schedule(QOpenGLContext *context, QEGLPlatformWindow *window)
+{
+ m_context = context;
+ m_window = window;
+ if (!m_updateTimer.isActive())
+ m_updateTimer.start();
+}
+
+void QEGLCompositor::renderAll()
+{
+ Q_ASSERT(m_context && m_window);
+ m_context->makeCurrent(m_window->window());
+ ensureProgram();
+ m_program->bind();
+
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QList<QEGLPlatformWindow *> windows = screen->windows();
+ for (int i = 0; i < windows.size(); ++i) {
+ QEGLPlatformWindow *window = windows.at(i);
+ uint texture = window->texture();
+ if (texture)
+ render(window, texture, window->isRaster());
+ }
+
+ m_program->release();
+ m_context->swapBuffers(m_window->window());
+}
+
+void QEGLCompositor::ensureProgram()
+{
+ if (!m_program) {
+ static const char *textureVertexProgram =
+ "attribute highp vec2 vertexCoordEntry;\n"
+ "attribute highp vec2 textureCoordEntry;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " textureCoord = textureCoordEntry;\n"
+ " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n"
+ "}\n";
+
+ static const char *textureFragmentProgram =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 textureCoord;\n"
+ "uniform bool isRaster;\n"
+ "void main() {\n"
+ " lowp vec4 c = texture2D(texture, textureCoord);\n"
+ " gl_FragColor = isRaster ? c.bgra : c.rgba;\n"
+ "}\n";
+
+ m_program = new QOpenGLShaderProgram;
+
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_program->link();
+
+ m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
+ m_isRasterEntry = m_program->uniformLocation("isRaster");
+ }
+}
+
+void QEGLCompositor::render(QEGLPlatformWindow *window, uint texture, bool raster)
+{
+ const GLfloat textureCoordinates[] = {
+ 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
+
+ QRectF sr = window->screen()->geometry();
+ QRect r = window->window()->geometry();
+ QPoint tl = r.topLeft();
+ QPoint br = r.bottomRight();
+
+ GLfloat x1 = (tl.x() / sr.width()) * 2 - 1;
+ GLfloat x2 = (br.x() / sr.width()) * 2 - 1;
+ GLfloat y1 = ((sr.height() - tl.y()) / sr.height()) * 2 - 1;
+ GLfloat y2 = ((sr.height() - br.y()) / sr.height()) * 2 - 1;
+
+ if (!raster)
+ qSwap(y1, y2);
+
+ const GLfloat vertexCoordinates[] = {
+ x1, y1,
+ x2, y1,
+ x2, y2,
+ x1, y2
+ };
+
+ glViewport(0, 0, sr.width(), sr.height());
+
+ m_program->enableAttributeArray(m_vertexCoordEntry);
+ m_program->enableAttributeArray(m_textureCoordEntry);
+
+ m_program->setAttributeArray(m_vertexCoordEntry, vertexCoordinates, 2);
+ m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ m_program->setUniformValue(m_isRasterEntry, raster);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ m_program->enableAttributeArray(m_textureCoordEntry);
+ m_program->enableAttributeArray(m_vertexCoordEntry);
+}
+
+QEGLCompositor *QEGLCompositor::instance()
+{
+ if (!compositor)
+ compositor = new QEGLCompositor;
+ return compositor;
+}
+
+void QEGLCompositor::destroy()
+{
+ delete compositor;
+ compositor = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglcompositor_p.h b/src/platformsupport/eglconvenience/qeglcompositor_p.h
new file mode 100644
index 0000000000..28e770e408
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglcompositor_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QEGLCOMPOSITOR_H
+#define QEGLCOMPOSITOR_H
+
+#include <QtCore/QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLShaderProgram;
+class QOpenGLContext;
+class QEGLPlatformWindow;
+
+class QEGLCompositor : public QObject
+{
+ Q_OBJECT
+
+public:
+ void schedule(QOpenGLContext *context, QEGLPlatformWindow *window);
+
+ static QEGLCompositor *instance();
+ static void destroy();
+
+private slots:
+ void renderAll();
+
+private:
+ QEGLCompositor();
+ ~QEGLCompositor();
+
+ void render(QEGLPlatformWindow *window, uint texture, bool raster);
+ void ensureProgram();
+
+ QOpenGLContext *m_context;
+ QEGLPlatformWindow *m_window;
+ QTimer m_updateTimer;
+ QOpenGLShaderProgram *m_program;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+ int m_isRasterEntry;
+};
+
+QT_END_NAMESPACE
+
+#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/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
new file mode 100644
index 0000000000..543cf2a978
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** 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/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
+
+#include "qeglplatformbackingstore_p.h"
+#include "qeglcompositor_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \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<QEGLPlatformWindow *>(window->handle())),
+ m_texture(0)
+{
+ m_window->setBackingStore(this);
+}
+
+QPaintDevice *QEGLPlatformBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QEGLPlatformBackingStore::updateTexture()
+{
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ if (!m_dirty.isNull()) {
+ QRegion fixed;
+ QRect imageRect = m_image.rect();
+ m_dirty |= imageRect;
+
+ foreach (const QRect &rect, m_dirty.rects()) {
+ // intersect with image rect to be sure
+ QRect r = imageRect & rect;
+
+ // if the rect is wide enough it's cheaper to just
+ // extend it instead of doing an image copy
+ if (r.width() >= imageRect.width() / 2) {
+ r.setX(0);
+ r.setWidth(imageRect.width());
+ }
+
+ fixed |= r;
+ }
+
+ foreach (const QRect &rect, fixed.rects()) {
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.copy(rect).constBits());
+ }
+ }
+
+ m_dirty = QRegion();
+ }
+}
+
+void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglBackingStore::flush %p", window);
+#endif
+
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || !dstWin->isRaster())
+ return;
+
+ m_window->create();
+ QOpenGLContext *context = screen->compositingContext();
+ context->makeCurrent(dstWin->window());
+ updateTexture();
+ composite(context, dstWin);
+}
+
+void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
+{
+ QEGLCompositor::instance()->schedule(context, window);
+}
+
+void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn)
+{
+ m_dirty |= rgn;
+}
+
+void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+
+ 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();
+
+ screen->compositingContext()->makeCurrent(dstWin->window());
+
+ if (m_texture)
+ glDeleteTextures(1, &m_texture);
+
+ glGenTextures(1, &m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
new file mode 100644
index 0000000000..58fc386892
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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 QEGLPLATFORMBACKINGSTORE_H
+#define QEGLPLATFORMBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+
+#include <QImage>
+#include <QRegion>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLContext;
+class QEGLPlatformWindow;
+
+class QEGLPlatformBackingStore : public QPlatformBackingStore
+{
+public:
+ QEGLPlatformBackingStore(QWindow *window);
+
+ QPaintDevice *paintDevice();
+
+ void beginPaint(const QRegion &);
+
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+ uint texture() const { return m_texture; }
+
+ virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
+
+private:
+ void updateTexture();
+
+ QEGLPlatformWindow *m_window;
+ QImage m_image;
+ uint m_texture;
+ QRegion m_dirty;
+};
+
+QT_END_NAMESPACE
+
+#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/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
new file mode 100644
index 0000000000..55590dbc9e
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** 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 "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
+
+/*!
+ \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
+#ifndef QT_NO_CURSOR
+ QCursor cursor(Qt::ArrowCursor);
+ setCurrentCursor(&cursor);
+#endif
+}
+
+QEGLPlatformCursor::~QEGLPlatformCursor()
+{
+ resetResources();
+}
+
+void QEGLPlatformCursor::resetResources()
+{
+ if (QOpenGLContext::currentContext()) {
+ delete m_program;
+ glDeleteTextures(1, &m_cursor.customCursorTexture);
+ glDeleteTextures(1, &m_cursorAtlas.texture);
+ }
+ m_program = 0;
+ m_cursor.customCursorTexture = 0;
+ m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();
+ m_cursorAtlas.texture = 0;
+}
+
+void QEGLPlatformCursor::createShaderPrograms()
+{
+ static const char *textureVertexProgram =
+ "attribute highp vec2 vertexCoordEntry;\n"
+ "attribute highp vec2 textureCoordEntry;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " textureCoord = textureCoordEntry;\n"
+ " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n"
+ "}\n";
+
+ static const char *textureFragmentProgram =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
+ "}\n";
+
+ m_program = new QOpenGLShaderProgram;
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_program->link();
+
+ m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
+ m_textureEntry = m_program->attributeLocation("texture");
+}
+
+void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image)
+{
+ if (!*texture)
+ glGenTextures(1, texture);
+ glBindTexture(GL_TEXTURE_2D, *texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */,
+ GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+}
+
+void QEGLPlatformCursor::initCursorAtlas()
+{
+ static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");
+ if (json.isEmpty())
+ json = ":/cursor.json";
+
+ 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(QLatin1String("image")).toString();
+ Q_ASSERT(!atlas.isEmpty());
+
+ const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble();
+ Q_ASSERT(cursorsPerRow);
+ m_cursorAtlas.cursorsPerRow = cursorsPerRow;
+
+ 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());
+ m_cursorAtlas.hotSpots << hotSpot;
+ }
+
+ QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow;
+ m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow - 1) / cursorsPerRow);
+ m_cursorAtlas.width = image.width();
+ m_cursorAtlas.height = image.height();
+ m_cursorAtlas.image = image;
+}
+
+#ifndef QT_NO_CURSOR
+void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window)
+{
+ Q_UNUSED(window);
+ const QRect oldCursorRect = cursorRect();
+ if (setCurrentCursor(cursor))
+ update(oldCursorRect | cursorRect());
+}
+
+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;
+
+ if (m_cursor.shape == Qt::BitmapCursor) {
+ m_cursor.customCursorImage = QImage();
+ m_cursor.customCursorPending = false;
+ }
+ m_cursor.shape = newShape;
+ if (newShape != Qt::BitmapCursor) { // standard cursor
+ const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,
+ hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;
+ m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),
+ hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),
+ ws, hs);
+ m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];
+ m_cursor.texture = m_cursorAtlas.texture;
+ m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);
+ } else {
+ QImage image = cursor->pixmap().toImage();
+ m_cursor.textureRect = QRectF(0, 0, 1, 1);
+ m_cursor.hotSpot = cursor->hotSpot();
+ m_cursor.texture = 0; // will get updated in the next render()
+ m_cursor.size = image.size();
+ m_cursor.customCursorImage = image;
+ m_cursor.customCursorPending = true;
+ }
+
+ return true;
+}
+#endif
+
+void QEGLPlatformCursor::update(const QRegion &rgn)
+{
+ QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(m_cursor.pos), rgn);
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+QRect QEGLPlatformCursor::cursorRect() const
+{
+ return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
+}
+
+QPoint QEGLPlatformCursor::pos() const
+{
+ return m_cursor.pos;
+}
+
+void QEGLPlatformCursor::setPos(const QPoint &pos)
+{
+ const QRect oldCursorRect = cursorRect();
+ m_cursor.pos = pos;
+ update(oldCursorRect | cursorRect());
+}
+
+void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event)
+{
+ if (event.type() != QEvent::MouseMove)
+ return;
+ const QRect oldCursorRect = cursorRect();
+ m_cursor.pos = event.screenPos().toPoint();
+ update(oldCursorRect | cursorRect());
+}
+
+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;
+ const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1;
+ const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2;
+ const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2;
+ QRectF r(QPointF(x1, y1), QPointF(x2, y2));
+
+ draw(r);
+}
+
+void QEGLPlatformCursor::draw(const QRectF &r)
+{
+ if (!m_program) {
+ // one time initialization
+ createShaderPrograms();
+
+ if (!m_cursorAtlas.texture) {
+ createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image);
+
+ if (m_cursor.shape != Qt::BitmapCursor)
+ m_cursor.texture = m_cursorAtlas.texture;
+ }
+ }
+
+ if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) {
+ // upload the custom cursor
+ createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage);
+ m_cursor.texture = m_cursor.customCursorTexture;
+ m_cursor.customCursorPending = false;
+ }
+
+ Q_ASSERT(m_cursor.texture);
+
+ m_program->bind();
+
+ const GLfloat x1 = r.left();
+ const GLfloat x2 = r.right();
+ const GLfloat y1 = r.top();
+ const GLfloat y2 = r.bottom();
+ const GLfloat cursorCoordinates[] = {
+ x1, y2,
+ x2, y2,
+ x1, y1,
+ x2, y1
+ };
+
+ const GLfloat s1 = m_cursor.textureRect.left();
+ const GLfloat s2 = m_cursor.textureRect.right();
+ const GLfloat t1 = m_cursor.textureRect.top();
+ const GLfloat t2 = m_cursor.textureRect.bottom();
+ const GLfloat textureCoordinates[] = {
+ s1, t2,
+ s2, t2,
+ s1, t1,
+ s2, t1
+ };
+
+ glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
+
+ m_program->enableAttributeArray(m_vertexCoordEntry);
+ m_program->enableAttributeArray(m_textureCoordEntry);
+
+ m_program->setAttributeArray(m_vertexCoordEntry, cursorCoordinates, 2);
+ m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
+
+ m_program->setUniformValue(m_textureEntry, 0);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDisable(GL_BLEND);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ m_program->disableAttributeArray(m_textureCoordEntry);
+ m_program->disableAttributeArray(m_vertexCoordEntry);
+
+ m_program->release();
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
new file mode 100644
index 0000000000..52359b84cd
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** 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 QEGLPLATFORMCURSOR_H
+#define QEGLPLATFORMCURSOR_H
+
+#include <qpa/qplatformcursor.h>
+#include <qpa/qplatformscreen.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLShaderProgram;
+
+class QEGLPlatformCursor : public QPlatformCursor
+{
+public:
+ 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;
+ void paintOnScreen();
+ void resetResources();
+
+private:
+#ifndef QT_NO_CURSOR
+ bool setCurrentCursor(QCursor *cursor);
+#endif
+ void draw(const QRectF &rect);
+ void update(const QRegion &region);
+ void createShaderPrograms();
+ static void createCursorTexture(uint *texture, const QImage &image);
+ void initCursorAtlas();
+
+ // current cursor information
+ struct Cursor {
+ Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { }
+ uint texture; // a texture from 'image' or the atlas
+ Qt::CursorShape shape;
+ QRectF textureRect; // normalized rect inside texture
+ QSize size; // size of the cursor
+ QPoint hotSpot;
+ QImage customCursorImage;
+ QPoint pos; // current cursor position
+ uint customCursorTexture;
+ bool customCursorPending;
+ } m_cursor;
+
+ // cursor atlas information
+ struct CursorAtlas {
+ CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
+ int cursorsPerRow;
+ uint texture;
+ int width, height; // width and height of the the atlas
+ int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
+ QList<QPoint> hotSpots;
+ QImage image; // valid until it's uploaded
+ } m_cursorAtlas;
+
+ bool m_visible;
+ QPlatformScreen *m_screen;
+ QOpenGLShaderProgram *m_program;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+ int m_textureEntry;
+};
+
+QT_END_NAMESPACE
+
+#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