summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2013-10-08 14:55:28 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-09 13:52:58 +0200
commit80cd06fd9d26aa7df02f71e001b449d65bb5b7a3 (patch)
tree240ef609bab7f481e7b86cd6ad625b457de38c28
parent8d2c6206fdf564aa75680f4fea58e31d26a3d6dd (diff)
eglfs: Separate compositor and improve raster window support
Separating the compositor into a separate source file improves the chances of possible future reuse and paves the way to supporting multiple GL windows. Tooltips are now working too. Implemented a few window functions like raise() and lower(). Fixed the qFatal for multiple GL windows to be raised in non-SDK based Android builds too. Change-Id: Id94d2fb2a4382766f3d130eebe1e6f397a535852 Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pri6
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp177
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.h35
-rw-r--r--src/plugins/platforms/eglfs/qeglfscompositor.cpp198
-rw-r--r--src/plugins/platforms/eglfs/qeglfscompositor.h83
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp27
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp22
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h7
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp87
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h11
10 files changed, 412 insertions, 241 deletions
diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri
index 4c066d6f26..390061c168 100644
--- a/src/plugins/platforms/eglfs/eglfs.pri
+++ b/src/plugins/platforms/eglfs/eglfs.pri
@@ -16,7 +16,8 @@ SOURCES += $$PWD/qeglfsintegration.cpp \
$$PWD/qeglfsscreen.cpp \
$$PWD/qeglfshooks_stub.cpp \
$$PWD/qeglfscursor.cpp \
- $$PWD/qeglfscontext.cpp
+ $$PWD/qeglfscontext.cpp \
+ $$PWD/qeglfscompositor.cpp
HEADERS += $$PWD/qeglfsintegration.h \
$$PWD/qeglfswindow.h \
@@ -24,7 +25,8 @@ HEADERS += $$PWD/qeglfsintegration.h \
$$PWD/qeglfsscreen.h \
$$PWD/qeglfscursor.h \
$$PWD/qeglfshooks.h \
- $$PWD/qeglfscontext.h
+ $$PWD/qeglfscontext.h \
+ $$PWD/qeglfscompositor.h
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
index ec2f4f9d91..8de8268616 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
@@ -40,120 +40,24 @@
****************************************************************************/
#include "qeglfsbackingstore.h"
+#include "qeglfscompositor.h"
#include "qeglfscursor.h"
#include "qeglfswindow.h"
+#include "qeglfscontext.h"
-#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QScreen>
-
QT_BEGIN_NAMESPACE
-QEglFSCompositor::QEglFSCompositor()
- : m_rootWindow(0)
-{
- m_updateTimer.setSingleShot(true);
- m_updateTimer.setInterval(0);
- connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
-}
-
-void QEglFSCompositor::schedule(QEglFSWindow *rootWindow)
-{
- m_rootWindow = rootWindow;
- if (!m_updateTimer.isActive())
- m_updateTimer.start();
-}
-
-void QEglFSCompositor::renderAll()
-{
- Q_ASSERT(m_rootWindow);
- QOpenGLContext *context = QEglFSBackingStore::makeRootCurrent(m_rootWindow);
-
- QEglFSScreen *screen = m_rootWindow->screen();
- QList<QEglFSWindow *> windows = screen->windows();
- for (int i = 0; i < windows.size(); ++i) {
- if (windows.at(i)->backingStore())
- render(windows.at(i), m_rootWindow);
- }
-
- context->swapBuffers(m_rootWindow->window());
- context->doneCurrent();
-}
-
-void QEglFSCompositor::render(QEglFSWindow *window, QEglFSWindow *rootWindow)
-{
- QEglFSBackingStore *rootBackingStore = rootWindow->backingStore();
- rootBackingStore->m_program->bind();
-
- 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;
-
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
-
- glViewport(0, 0, sr.width(), sr.height());
-
- glEnableVertexAttribArray(rootBackingStore->m_vertexCoordEntry);
- glEnableVertexAttribArray(rootBackingStore->m_textureCoordEntry);
-
- glVertexAttribPointer(rootBackingStore->m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(rootBackingStore->m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
-
- glBindTexture(GL_TEXTURE_2D, window->backingStore()->m_texture);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- rootBackingStore->m_program->release();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(rootBackingStore->m_vertexCoordEntry);
- glDisableVertexAttribArray(rootBackingStore->m_textureCoordEntry);
-}
-
-static QEglFSCompositor *compositor = 0;
-
-QEglFSCompositor *QEglFSCompositor::instance()
-{
- if (!compositor)
- compositor = new QEglFSCompositor;
- return compositor;
-}
-
QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
- , m_window(static_cast<QEglFSWindow *>(window->handle()))
- , m_context(0)
- , m_texture(0)
- , m_program(0)
+ : QPlatformBackingStore(window),
+ m_window(static_cast<QEglFSWindow *>(window->handle())),
+ m_texture(0)
{
m_window->setBackingStore(this);
}
-QEglFSBackingStore::~QEglFSBackingStore()
-{
- delete m_program;
- delete m_context;
-}
-
QPaintDevice *QEglFSBackingStore::paintDevice()
{
return &m_image;
@@ -186,7 +90,8 @@ void QEglFSBackingStore::updateTexture()
// 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()));
+ 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());
@@ -207,63 +112,14 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
qWarning("QEglBackingStore::flush %p", window);
#endif
- m_window->create();
QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (rootWin) {
- makeRootCurrent(rootWin);
- updateTexture();
- QEglFSCompositor::instance()->schedule(rootWin);
- }
-}
-
-void QEglFSBackingStore::makeCurrent()
-{
- Q_ASSERT(m_window->hasNativeWindow());
-
- QWindow *wnd = window();
- if (!m_context) {
- m_context = new QOpenGLContext;
- m_context->setFormat(wnd->requestedFormat());
- m_context->setScreen(wnd->screen());
- m_context->create();
- }
+ if (!rootWin)
+ return;
- m_context->makeCurrent(wnd);
-}
-
-QOpenGLContext *QEglFSBackingStore::makeRootCurrent(QEglFSWindow *rootWin)
-{
- Q_ASSERT(rootWin->hasNativeWindow() && rootWin->isRasterRoot());
-
- QEglFSBackingStore *rootBackingStore = rootWin->backingStore();
- rootBackingStore->makeCurrent();
- if (!rootBackingStore->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"
- "void main() {\n"
- " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
- "}\n";
-
- rootBackingStore->m_program = new QOpenGLShaderProgram;
-
- rootBackingStore->m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- rootBackingStore->m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- rootBackingStore->m_program->link();
-
- rootBackingStore->m_vertexCoordEntry = rootBackingStore->m_program->attributeLocation("vertexCoordEntry");
- rootBackingStore->m_textureCoordEntry = rootBackingStore->m_program->attributeLocation("textureCoordEntry");
- }
- return rootBackingStore->m_context;
+ m_window->create();
+ rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
+ updateTexture();
+ QEglFSCompositor::instance()->schedule(rootWin->screen());
}
void QEglFSBackingStore::beginPaint(const QRegion &rgn)
@@ -275,9 +131,14 @@ void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents
{
Q_UNUSED(staticContents);
+ QEglFSWindow *rootWin = m_window->screen()->rootWindow();
+ if (!rootWin)
+ return;
+
m_image = QImage(size, QImage::Format_RGB32);
m_window->create();
- makeRootCurrent(m_window->screen()->rootWindow());
+
+ rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
if (m_texture)
glDeleteTextures(1, &m_texture);
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
index 39bdab1563..535428aac1 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
@@ -46,41 +46,16 @@
#include <QImage>
#include <QRegion>
-#include <QTimer>
QT_BEGIN_NAMESPACE
-class QOpenGLContext;
class QOpenGLPaintDevice;
-class QOpenGLShaderProgram;
class QEglFSWindow;
-class QEglFSCompositor : public QObject
-{
- Q_OBJECT
-
-public:
- QEglFSCompositor();
-
- void schedule(QEglFSWindow *rootWindow);
-
- static QEglFSCompositor *instance();
-
-private slots:
- void renderAll();
-
-private:
- void render(QEglFSWindow *window, QEglFSWindow *rootWindow);
-
- QEglFSWindow *m_rootWindow;
- QTimer m_updateTimer;
-};
-
class QEglFSBackingStore : public QPlatformBackingStore
{
public:
QEglFSBackingStore(QWindow *window);
- ~QEglFSBackingStore();
QPaintDevice *paintDevice();
@@ -89,21 +64,15 @@ public:
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
+ uint texture() const { return m_texture; }
+
private:
- void makeCurrent();
- static QOpenGLContext *makeRootCurrent(QEglFSWindow *rootWin);
void updateTexture();
QEglFSWindow *m_window;
- QOpenGLContext *m_context;
QImage m_image;
uint m_texture;
QRegion m_dirty;
- QOpenGLShaderProgram *m_program;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
-
- friend class QEglFSCompositor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.cpp b/src/plugins/platforms/eglfs/qeglfscompositor.cpp
new file mode 100644
index 0000000000..9db43a57a1
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfscompositor.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** 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 "qeglfscompositor.h"
+#include "qeglfswindow.h"
+#include "qeglfscontext.h"
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLFramebufferObject>
+
+QT_BEGIN_NAMESPACE
+
+static QEglFSCompositor *compositor = 0;
+
+QEglFSCompositor::QEglFSCompositor()
+ : m_screen(0),
+ m_program(0)
+{
+ Q_ASSERT(!compositor);
+ m_updateTimer.setSingleShot(true);
+ m_updateTimer.setInterval(0);
+ connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
+}
+
+QEglFSCompositor::~QEglFSCompositor()
+{
+ Q_ASSERT(compositor == this);
+ delete m_program;
+ compositor = 0;
+}
+
+void QEglFSCompositor::schedule(QEglFSScreen *screen)
+{
+ m_screen = screen;
+ if (!m_updateTimer.isActive())
+ m_updateTimer.start();
+}
+
+void QEglFSCompositor::renderAll()
+{
+ QEglFSWindow *rootWin = m_screen->rootWindow();
+ if (!rootWin)
+ return;
+
+ Q_ASSERT(rootWin->hasNativeWindow());
+ QOpenGLContext *context = m_screen->rootContext();
+ Q_ASSERT(context);
+
+ context->makeCurrent(rootWin->window());
+ ensureProgram();
+ m_program->bind();
+
+ QList<QEglFSWindow *> windows = m_screen->windows();
+ for (int i = 0; i < windows.size(); ++i) {
+ QEglFSWindow *window = windows.at(i);
+ uint texture = window->texture();
+ if (texture)
+ render(window, texture, window->isRaster());
+ }
+
+ m_program->release();
+ context->swapBuffers(rootWin->window());
+}
+
+void QEglFSCompositor::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 QEglFSCompositor::render(QEglFSWindow *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());
+
+ glEnableVertexAttribArray(m_vertexCoordEntry);
+ glEnableVertexAttribArray(m_textureCoordEntry);
+
+ glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
+ glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ m_program->setUniformValue(m_isRasterEntry, raster);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisableVertexAttribArray(m_vertexCoordEntry);
+ glDisableVertexAttribArray(m_textureCoordEntry);
+}
+
+QEglFSCompositor *QEglFSCompositor::instance()
+{
+ if (!compositor)
+ compositor = new QEglFSCompositor;
+ return compositor;
+}
+
+void QEglFSCompositor::destroy()
+{
+ delete compositor;
+ compositor = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.h b/src/plugins/platforms/eglfs/qeglfscompositor.h
new file mode 100644
index 0000000000..ade2e06031
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfscompositor.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 QEGLFSCOMPOSITOR_H
+#define QEGLFSCOMPOSITOR_H
+
+#include <QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSScreen;
+class QEglFSWindow;
+class QOpenGLShaderProgram;
+
+class QEglFSCompositor : public QObject
+{
+ Q_OBJECT
+
+public:
+ void schedule(QEglFSScreen *screen);
+
+ static QEglFSCompositor *instance();
+ static void destroy();
+
+private slots:
+ void renderAll();
+
+private:
+ QEglFSCompositor();
+ ~QEglFSCompositor();
+
+ void render(QEglFSWindow *window, uint texture, bool raster);
+ void ensureProgram();
+
+ QEglFSScreen *m_screen;
+ QTimer m_updateTimer;
+ QOpenGLShaderProgram *m_program;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+ int m_isRasterEntry;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLFSCOMPOSITOR_H
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 45dccfa79f..67f0c35ed7 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -43,6 +43,7 @@
#include "qeglfswindow.h"
#include "qeglfsbackingstore.h"
+#include "qeglfscompositor.h"
#include "qeglfshooks.h"
#include <QtGui/private/qguiapplication_p.h>
@@ -75,8 +76,6 @@
QT_BEGIN_NAMESPACE
-static void *eglContextForContext(QOpenGLContext *context);
-
QEglFSIntegration::QEglFSIntegration()
: mFontDb(new QGenericUnixFontDatabase)
, mServices(new QGenericUnixServices)
@@ -108,8 +107,8 @@ QEglFSIntegration::QEglFSIntegration()
QEglFSIntegration::~QEglFSIntegration()
{
+ QEglFSCompositor::destroy();
delete mScreen;
-
eglTerminate(mDisplay);
QEglFSHooks::hooks()->platformDestroy();
}
@@ -131,9 +130,11 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
{
+ QWindowSystemInterface::flushWindowSystemEvents();
QEglFSWindow *w = new QEglFSWindow(window);
w->create();
- w->requestActivateWindow();
+ if (window->type() != Qt::ToolTip)
+ w->requestActivateWindow();
return w;
}
@@ -263,15 +264,6 @@ void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QO
return result;
}
-QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
-{
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context")
- return NativeResourceForContextFunction(eglContextForContext);
-
- return 0;
-}
-
static void *eglContextForContext(QOpenGLContext *context)
{
Q_ASSERT(context);
@@ -283,6 +275,15 @@ static void *eglContextForContext(QOpenGLContext *context)
return handle->eglContext();
}
+QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "get_egl_context")
+ return NativeResourceForContextFunction(eglContextForContext);
+
+ return 0;
+}
+
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
{
class Chooser : public QEglConfigChooser {
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 62f764b392..bd3601bf06 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -47,9 +47,10 @@
QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
- : m_dpy(dpy)
- , m_surface(EGL_NO_SURFACE)
- , m_cursor(0)
+ : m_dpy(dpy),
+ m_surface(EGL_NO_SURFACE),
+ m_cursor(0),
+ m_rootContext(0)
{
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglScreen %p\n", this);
@@ -121,10 +122,23 @@ void QEglFSScreen::removeWindow(QEglFSWindow *window)
m_windows.removeOne(window);
}
+void QEglFSScreen::moveToTop(QEglFSWindow *window)
+{
+ m_windows.removeOne(window);
+ m_windows.append(window);
+}
+
+void QEglFSScreen::changeWindowIndex(QEglFSWindow *window, int newIdx)
+{
+ int idx = m_windows.indexOf(window);
+ if (idx != -1 && idx != newIdx)
+ m_windows.move(idx, newIdx);
+}
+
QEglFSWindow *QEglFSScreen::rootWindow()
{
Q_FOREACH (QEglFSWindow *window, m_windows) {
- if (window->isRasterRoot())
+ if (window->hasNativeWindow())
return window;
}
return 0;
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index bf7e88bd50..578a6cf20d 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -50,9 +50,9 @@
QT_BEGIN_NAMESPACE
-class QPlatformOpenGLContext;
class QEglFSCursor;
class QEglFSWindow;
+class QOpenGLContext;
class QEglFSScreen : public QPlatformScreen
{
@@ -77,7 +77,11 @@ public:
QList<QEglFSWindow *> windows() const { return m_windows; }
void addWindow(QEglFSWindow *window);
void removeWindow(QEglFSWindow *window);
+ void moveToTop(QEglFSWindow *window);
+ void changeWindowIndex(QEglFSWindow *window, int newIdx);
QEglFSWindow *rootWindow();
+ QOpenGLContext *rootContext() { return m_rootContext; }
+ void setRootContext(QOpenGLContext *context) { m_rootContext = context; }
protected:
void setPrimarySurface(EGLSurface surface);
@@ -89,6 +93,7 @@ private:
EGLSurface m_surface;
QEglFSCursor *m_cursor;
QList<QEglFSWindow *> m_windows;
+ QOpenGLContext *m_rootContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 17ab68f747..70f0e437b2 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -42,9 +42,11 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
#include "qeglfscursor.h"
+#include "qeglfsbackingstore.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
+#include <QtGui/QOpenGLContext>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
@@ -99,18 +101,21 @@ void QEglFSWindow::create()
if (window()->surfaceType() == QSurface::RasterSurface)
m_flags |= IsRaster;
- // Stop if there is already a raster root window backed by a native window and
- // surface. Other raster windows will not have their own native window, surface and
- // context. Instead, they will be composited onto the root window's surface.
- if (screen()->primarySurface() != EGL_NO_SURFACE) {
- if (m_flags.testFlag(IsRaster) && screen()->rootWindow()->m_flags.testFlag(IsRaster))
+ // Stop if there is already a window backed by a native window and surface. Additional
+ // raster windows will not have their own native window, surface and context. Instead,
+ // they will be composited onto the root window's surface.
+ QEglFSScreen *screen = this->screen();
+ if (screen->primarySurface() != EGL_NO_SURFACE) {
+ if (m_flags.testFlag(IsRaster) && screen->rootWindow()->m_flags.testFlag(IsRaster))
return;
-#ifndef Q_OS_ANDROID
+#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)
// We can have either a single OpenGL window or multiple raster windows.
// Other combinations cannot work.
qFatal("EGLFS: OpenGL windows cannot be mixed with others.");
#endif
+
+ return;
}
window()->setSurfaceType(QSurface::OpenGLSurface);
@@ -118,31 +123,40 @@ void QEglFSWindow::create()
setGeometry(QRect()); // will become fullscreen
QWindowSystemInterface::handleExposeEvent(window(), geometry());
- EGLDisplay display = static_cast<QEglFSScreen *>(screen())->display();
+ EGLDisplay display = static_cast<QEglFSScreen *>(screen)->display();
QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat());
m_config = QEglFSIntegration::chooseConfig(display, platformFormat);
m_format = q_glFormatFromConfig(display, m_config);
resetSurface();
- if (screen()->primarySurface() == EGL_NO_SURFACE) {
- screen()->setPrimarySurface(m_surface);
- m_flags |= IsRasterRoot;
+ screen->setPrimarySurface(m_surface);
+
+ if (m_flags.testFlag(IsRaster)) {
+ QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
+ context->setFormat(window()->requestedFormat());
+ context->setScreen(window()->screen());
+ context->create();
+ screen->setRootContext(context);
}
}
void QEglFSWindow::destroy()
{
+ QEglFSScreen *screen = this->screen();
if (m_flags.testFlag(HasNativeWindow)) {
- QEglFSCursor *cursor = static_cast<QEglFSCursor *>(screen()->cursor());
+ QEglFSCursor *cursor = static_cast<QEglFSCursor *>(screen->cursor());
if (cursor)
cursor->resetResources();
- if (screen()->primarySurface() == m_surface)
- screen()->setPrimarySurface(EGL_NO_SURFACE);
+
+ if (screen->primarySurface() == m_surface)
+ screen->setPrimarySurface(EGL_NO_SURFACE);
+
invalidateSurface();
}
+
m_flags = 0;
- screen()->removeWindow(this);
+ screen->removeWindow(this);
}
// The virtual functions resetSurface and invalidateSurface may get overridden
@@ -182,20 +196,15 @@ void QEglFSWindow::setVisible(bool visible)
} else {
screen()->removeWindow(this);
windows = screen()->windows();
- // try activating the window below
if (windows.size())
windows.last()->requestActivateWindow();
}
}
- // trigger an update
- QEglFSWindow *rootWin = screen()->rootWindow();
- if (rootWin) {
- QWindowSystemInterface::handleExposeEvent(rootWin->window(), rootWin->window()->geometry());
- QWindowSystemInterface::flushWindowSystemEvents();
- }
+ QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
- QPlatformWindow::setVisible(visible);
+ if (visible)
+ QWindowSystemInterface::flushWindowSystemEvents();
}
void QEglFSWindow::setGeometry(const QRect &r)
@@ -230,13 +239,31 @@ WId QEglFSWindow::winId() const
void QEglFSWindow::requestActivateWindow()
{
+ if (window()->type() != Qt::Desktop)
+ screen()->moveToTop(this);
+
+ QWindowSystemInterface::handleWindowActivated(window());
+ QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
+}
+
+void QEglFSWindow::raise()
+{
if (window()->type() != Qt::Desktop) {
- // move to the end of the list, to be on top
- screen()->removeWindow(this);
- screen()->addWindow(this);
+ screen()->moveToTop(this);
+ QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
}
+}
- QWindowSystemInterface::handleWindowActivated(window());
+void QEglFSWindow::lower()
+{
+ QList<QEglFSWindow *> windows = screen()->windows();
+ if (window()->type() != Qt::Desktop && windows.count() > 1) {
+ int idx = windows.indexOf(this);
+ if (idx > 0) {
+ screen()->changeWindowIndex(this, idx - 1);
+ QWindowSystemInterface::handleExposeEvent(windows.last()->window(), windows.last()->geometry());
+ }
+ }
}
EGLSurface QEglFSWindow::surface() const
@@ -259,4 +286,12 @@ QEglFSScreen *QEglFSWindow::screen() const
return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
}
+uint QEglFSWindow::texture() const
+{
+ if (m_backingStore)
+ return m_backingStore->texture();
+
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index 71c0ed5c27..ee3c194a7c 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -62,6 +62,8 @@ public:
WId winId() const;
void setVisible(bool visible);
void requestActivateWindow();
+ void raise();
+ void lower();
EGLSurface surface() const;
QSurfaceFormat format() const;
@@ -73,11 +75,13 @@ public:
void destroy();
bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); }
- bool isRasterRoot() const { return m_flags.testFlag(IsRasterRoot); }
+ bool isRaster() const { return m_flags.testFlag(IsRaster); }
QEglFSBackingStore *backingStore() { return m_backingStore; }
void setBackingStore(QEglFSBackingStore *backingStore) { m_backingStore = backingStore; }
+ uint texture() const;
+
virtual void invalidateSurface();
virtual void resetSurface();
@@ -93,9 +97,8 @@ private:
enum Flag {
Created = 0x01,
- HasNativeWindow = 0x02,
- IsRaster = 0x04,
- IsRasterRoot = 0x08
+ IsRaster = 0x02,
+ HasNativeWindow = 0x04
};
Q_DECLARE_FLAGS(Flags, Flag);
Flags m_flags;