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