summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/eglconvenience
diff options
context:
space:
mode:
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