diff options
Diffstat (limited to 'src/platformsupport/eglconvenience')
18 files changed, 1927 insertions, 8 deletions
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri index 506f4ab4ea..4af0df58c7 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pri +++ b/src/platformsupport/eglconvenience/eglconvenience.pri @@ -3,11 +3,30 @@ contains(QT_CONFIG,egl) { $$PWD/qeglconvenience_p.h \ $$PWD/qeglplatformcontext_p.h \ $$PWD/qeglpbuffer_p.h + SOURCES += \ $$PWD/qeglconvenience.cpp \ $$PWD/qeglplatformcontext.cpp \ $$PWD/qeglpbuffer.cpp + unix { + HEADERS += \ + $$PWD/qeglplatformcursor_p.h \ + $$PWD/qeglplatformwindow_p.h \ + $$PWD/qeglplatformscreen_p.h \ + $$PWD/qeglcompositor_p.h \ + $$PWD/qeglplatformbackingstore_p.h \ + $$PWD/qeglplatformintegration_p.h + + SOURCES += \ + $$PWD/qeglplatformcursor.cpp \ + $$PWD/qeglplatformwindow.cpp \ + $$PWD/qeglplatformscreen.cpp \ + $$PWD/qeglcompositor.cpp \ + $$PWD/qeglplatformbackingstore.cpp \ + $$PWD/qeglplatformintegration.cpp + } + contains(QT_CONFIG,xlib) { HEADERS += \ $$PWD/qxlibeglintegration_p.h @@ -16,4 +35,3 @@ contains(QT_CONFIG,egl) { } CONFIG += egl } - diff --git a/src/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp new file mode 100644 index 0000000000..c8b768ae48 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLShaderProgram> +#include <QtGui/QOpenGLFramebufferObject> + +#include "qeglcompositor_p.h" +#include "qeglplatformwindow_p.h" +#include "qeglplatformscreen_p.h" + +QT_BEGIN_NAMESPACE + +static QEGLCompositor *compositor = 0; + +QEGLCompositor::QEGLCompositor() + : m_context(0), + m_window(0), + m_program(0) +{ + Q_ASSERT(!compositor); + m_updateTimer.setSingleShot(true); + m_updateTimer.setInterval(0); + connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll())); +} + +QEGLCompositor::~QEGLCompositor() +{ + Q_ASSERT(compositor == this); + delete m_program; + compositor = 0; +} + +void QEGLCompositor::schedule(QOpenGLContext *context, QEGLPlatformWindow *window) +{ + m_context = context; + m_window = window; + if (!m_updateTimer.isActive()) + m_updateTimer.start(); +} + +void QEGLCompositor::renderAll() +{ + Q_ASSERT(m_context && m_window); + m_context->makeCurrent(m_window->window()); + ensureProgram(); + m_program->bind(); + + QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen()); + QList<QEGLPlatformWindow *> windows = screen->windows(); + for (int i = 0; i < windows.size(); ++i) { + QEGLPlatformWindow *window = windows.at(i); + uint texture = window->texture(); + if (texture) + render(window, texture, window->isRaster()); + } + + m_program->release(); + m_context->swapBuffers(m_window->window()); +} + +void QEGLCompositor::ensureProgram() +{ + if (!m_program) { + static const char *textureVertexProgram = + "attribute highp vec2 vertexCoordEntry;\n" + "attribute highp vec2 textureCoordEntry;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " textureCoord = textureCoordEntry;\n" + " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n" + "}\n"; + + static const char *textureFragmentProgram = + "uniform sampler2D texture;\n" + "varying highp vec2 textureCoord;\n" + "uniform bool isRaster;\n" + "void main() {\n" + " lowp vec4 c = texture2D(texture, textureCoord);\n" + " gl_FragColor = isRaster ? c.bgra : c.rgba;\n" + "}\n"; + + m_program = new QOpenGLShaderProgram; + + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); + m_program->link(); + + m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry"); + m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry"); + m_isRasterEntry = m_program->uniformLocation("isRaster"); + } +} + +void QEGLCompositor::render(QEGLPlatformWindow *window, uint texture, bool raster) +{ + const GLfloat textureCoordinates[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 + }; + + QRectF sr = window->screen()->geometry(); + QRect r = window->window()->geometry(); + QPoint tl = r.topLeft(); + QPoint br = r.bottomRight(); + + GLfloat x1 = (tl.x() / sr.width()) * 2 - 1; + GLfloat x2 = (br.x() / sr.width()) * 2 - 1; + GLfloat y1 = ((sr.height() - tl.y()) / sr.height()) * 2 - 1; + GLfloat y2 = ((sr.height() - br.y()) / sr.height()) * 2 - 1; + + if (!raster) + qSwap(y1, y2); + + const GLfloat vertexCoordinates[] = { + x1, y1, + x2, y1, + x2, y2, + x1, y2 + }; + + glViewport(0, 0, sr.width(), sr.height()); + + m_program->enableAttributeArray(m_vertexCoordEntry); + m_program->enableAttributeArray(m_textureCoordEntry); + + m_program->setAttributeArray(m_vertexCoordEntry, vertexCoordinates, 2); + m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2); + + glBindTexture(GL_TEXTURE_2D, texture); + + m_program->setUniformValue(m_isRasterEntry, raster); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glBindTexture(GL_TEXTURE_2D, 0); + m_program->enableAttributeArray(m_textureCoordEntry); + m_program->enableAttributeArray(m_vertexCoordEntry); +} + +QEGLCompositor *QEGLCompositor::instance() +{ + if (!compositor) + compositor = new QEGLCompositor; + return compositor; +} + +void QEGLCompositor::destroy() +{ + delete compositor; + compositor = 0; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglcompositor_p.h b/src/platformsupport/eglconvenience/qeglcompositor_p.h new file mode 100644 index 0000000000..28e770e408 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglcompositor_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLCOMPOSITOR_H +#define QEGLCOMPOSITOR_H + +#include <QtCore/QTimer> + +QT_BEGIN_NAMESPACE + +class QOpenGLShaderProgram; +class QOpenGLContext; +class QEGLPlatformWindow; + +class QEGLCompositor : public QObject +{ + Q_OBJECT + +public: + void schedule(QOpenGLContext *context, QEGLPlatformWindow *window); + + static QEGLCompositor *instance(); + static void destroy(); + +private slots: + void renderAll(); + +private: + QEGLCompositor(); + ~QEGLCompositor(); + + void render(QEGLPlatformWindow *window, uint texture, bool raster); + void ensureProgram(); + + QOpenGLContext *m_context; + QEGLPlatformWindow *m_window; + QTimer m_updateTimer; + QOpenGLShaderProgram *m_program; + int m_vertexCoordEntry; + int m_textureCoordEntry; + int m_isRasterEntry; +}; + +QT_END_NAMESPACE + +#endif // QEGLCOMPOSITOR_H diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index fe6ba2b215..6c2cc4a186 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -41,6 +41,12 @@ #include <QByteArray> +#ifdef Q_OS_UNIX +#include <sys/ioctl.h> +#include <linux/fb.h> +#include <private/qmath_p.h> +#endif + #include "qeglconvenience_p.h" QT_BEGIN_NAMESPACE @@ -427,4 +433,106 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config) qWarning("\n"); } +#ifdef Q_OS_UNIX + +QSizeF q_physicalScreenSizeFromFb(int framebufferDevice) +{ + const int defaultPhysicalDpi = 100; + static QSizeF size; + + if (size.isEmpty()) { + // Note: in millimeters + int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt(); + int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt(); + + if (width && height) { + size.setWidth(width); + size.setHeight(height); + return size; + } + + struct fb_var_screeninfo vinfo; + int w = -1; + int h = -1; + QSize screenResolution; + + if (framebufferDevice != -1) { + if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) { + qWarning("eglconvenience: Could not query screen info"); + } else { + w = vinfo.width; + h = vinfo.height; + screenResolution = QSize(vinfo.xres, vinfo.yres); + } + } else { + screenResolution = q_screenSizeFromFb(framebufferDevice); + } + + size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w)); + size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h)); + } + + return size; +} + +QSize q_screenSizeFromFb(int framebufferDevice) +{ + const int defaultWidth = 800; + const int defaultHeight = 600; + static QSize size; + + if (size.isEmpty()) { + int width = qgetenv("QT_QPA_EGLFS_WIDTH").toInt(); + int height = qgetenv("QT_QPA_EGLFS_HEIGHT").toInt(); + + if (width && height) { + size.setWidth(width); + size.setHeight(height); + return size; + } + + struct fb_var_screeninfo vinfo; + int xres = -1; + int yres = -1; + + if (framebufferDevice != -1) { + if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) { + qWarning("eglconvenience: Could not read screen info"); + } else { + xres = vinfo.xres; + yres = vinfo.yres; + } + } + + size.setWidth(xres <= 0 ? defaultWidth : xres); + size.setHeight(yres <= 0 ? defaultHeight : yres); + } + + return size; +} + +int q_screenDepthFromFb(int framebufferDevice) +{ + const int defaultDepth = 32; + static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt(); + + if (depth == 0) { + struct fb_var_screeninfo vinfo; + + if (framebufferDevice != -1) { + if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) + qWarning("eglconvenience: Could not query screen info"); + else + depth = vinfo.bits_per_pixel; + } + + if (depth <= 0) + depth = defaultDepth; + } + + return depth; +} + +#endif // Q_OS_UNIX + QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h index 35c225cc2f..d4ac669906 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h @@ -42,11 +42,11 @@ #ifndef QEGLCONVENIENCE_H #define QEGLCONVENIENCE_H - #include <QtGui/QSurfaceFormat> #include <QtCore/QVector> - +#include <QtCore/QSizeF> #include <EGL/egl.h> + QT_BEGIN_NAMESPACE QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format); @@ -56,6 +56,12 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, bool q_hasEglExtension(EGLDisplay display,const char* extensionName); void q_printEglConfig(EGLDisplay display, EGLConfig config); +#ifdef Q_OS_UNIX +QSizeF q_physicalScreenSizeFromFb(int framebufferDevice); +QSize q_screenSizeFromFb(int framebufferDevice); +int q_screenDepthFromFb(int framebufferDevice); +#endif + class QEglConfigChooser { public: diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp index 919314e9aa..295f8756c4 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp +++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp @@ -45,6 +45,18 @@ QT_BEGIN_NAMESPACE +/*! + \class QEGLPbuffer + \brief A pbuffer-based implementation of QPlatformOffscreenSurface for EGL. + \since 5.2 + \internal + \ingroup qpa + + To use this implementation in the platform plugin simply + reimplement QPlatformIntegration::createPlatformOffscreenSurface() + and return a new instance of this class. +*/ + QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) , m_format(format) diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp new file mode 100644 index 0000000000..543cf2a978 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QOpenGLShaderProgram> +#include <QtGui/QOpenGLContext> + +#include "qeglplatformbackingstore_p.h" +#include "qeglcompositor_p.h" +#include "qeglplatformwindow_p.h" +#include "qeglplatformscreen_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QEGLPlatformBackingStore + \brief A backing store implementation for EGL and GLES. + \since 5.2 + \internal + \ingroup qpa + + This implementation uploads raster-rendered widget windows into + textures and composites them onto a single native window using + QEGLCompositor. This means that multiple top-level widgets are + supported without creating actual native windows for each of them. + + The class is ready to be used as-is, the default + QEGLPlatformIntegration::createPlatformBackingStore() + implementation creates an instance which is ready to be used + without further customization. + + If QEGLCompositor is not suitable, this backing store + implementation can also be used without it. In this case a + subclass must reimplement composite() and schedule an update in + its custom compositor when this function is called. The textures + are accessible via QEGLPlatformWindow::texture(). +*/ + +QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window) + : QPlatformBackingStore(window), + m_window(static_cast<QEGLPlatformWindow *>(window->handle())), + m_texture(0) +{ + m_window->setBackingStore(this); +} + +QPaintDevice *QEGLPlatformBackingStore::paintDevice() +{ + return &m_image; +} + +void QEGLPlatformBackingStore::updateTexture() +{ + glBindTexture(GL_TEXTURE_2D, m_texture); + + if (!m_dirty.isNull()) { + QRegion fixed; + QRect imageRect = m_image.rect(); + m_dirty |= imageRect; + + foreach (const QRect &rect, m_dirty.rects()) { + // intersect with image rect to be sure + QRect r = imageRect & rect; + + // if the rect is wide enough it's cheaper to just + // extend it instead of doing an image copy + if (r.width() >= imageRect.width() / 2) { + r.setX(0); + r.setWidth(imageRect.width()); + } + + fixed |= r; + } + + foreach (const QRect &rect, fixed.rects()) { + // if the sub-rect is full-width we can pass the image data directly to + // OpenGL instead of copying, since there's no gap between scanlines + if (rect.width() == imageRect.width()) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + m_image.constScanLine(rect.y())); + } else { + glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + m_image.copy(rect).constBits()); + } + } + + m_dirty = QRegion(); + } +} + +void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(window); + Q_UNUSED(region); + Q_UNUSED(offset); + +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglBackingStore::flush %p", window); +#endif + + QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen()); + QEGLPlatformWindow *dstWin = screen->compositingWindow(); + if (!dstWin || !dstWin->isRaster()) + return; + + m_window->create(); + QOpenGLContext *context = screen->compositingContext(); + context->makeCurrent(dstWin->window()); + updateTexture(); + composite(context, dstWin); +} + +void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window) +{ + QEGLCompositor::instance()->schedule(context, window); +} + +void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn) +{ + m_dirty |= rgn; +} + +void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(staticContents); + + QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen()); + QEGLPlatformWindow *dstWin = screen->compositingWindow(); + if (!dstWin || !dstWin->isRaster()) + return; + + m_image = QImage(size, QImage::Format_RGB32); + m_window->create(); + + screen->compositingContext()->makeCurrent(dstWin->window()); + + if (m_texture) + glDeleteTextures(1, &m_texture); + + glGenTextures(1, &m_texture); + glBindTexture(GL_TEXTURE_2D, m_texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h new file mode 100644 index 0000000000..58fc386892 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLPLATFORMBACKINGSTORE_H +#define QEGLPLATFORMBACKINGSTORE_H + +#include <qpa/qplatformbackingstore.h> + +#include <QImage> +#include <QRegion> + +QT_BEGIN_NAMESPACE + +class QOpenGLContext; +class QEGLPlatformWindow; + +class QEGLPlatformBackingStore : public QPlatformBackingStore +{ +public: + QEGLPlatformBackingStore(QWindow *window); + + QPaintDevice *paintDevice(); + + void beginPaint(const QRegion &); + + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + + uint texture() const { return m_texture; } + + virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window); + +private: + void updateTexture(); + + QEGLPlatformWindow *m_window; + QImage m_image; + uint m_texture; + QRegion m_dirty; +}; + +QT_END_NAMESPACE + +#endif // QEGLPLATFORMBACKINGSTORE_H diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index 1a7eb9d92f..614d086178 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -40,12 +40,27 @@ ****************************************************************************/ #include "qeglplatformcontext_p.h" - #include "qeglconvenience_p.h" - #include <qpa/qplatformwindow.h> -#include <EGL/egl.h> +QT_BEGIN_NAMESPACE + +/*! + \class QEGLPlatformContext + \brief An EGL context implementation. + \since 5.2 + \internal + \ingroup qpa + + Implement QPlatformOpenGLContext using EGL. To use it in platform + plugins a subclass must be created since + eglSurfaceForPlatformSurface() has to be reimplemented. This + function is used for mapping platform surfaces (windows) to EGL + surfaces and is necessary since different platform plugins may + have different ways of handling native windows (for example, a + plugin may choose not to back every platform window by a real EGL + surface). Other than that, no further customization is necessary. + */ static inline void bindApi(const QSurfaceFormat &format) { @@ -84,6 +99,9 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform EGLConfig config, EGLenum eglApi) : m_eglDisplay(display) , m_eglConfig(config) + , m_swapInterval(-1) + , m_swapIntervalEnvChecked(false) + , m_swapIntervalFromEnv(-1) { init(format, share); Q_UNUSED(eglApi); @@ -152,8 +170,8 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface) if (ok) { if (!m_swapIntervalEnvChecked) { m_swapIntervalEnvChecked = true; - if (qEnvironmentVariableIsSet("QT_QPA_EGL_SWAPINTERVAL")) { - QByteArray swapIntervalString = qgetenv("QT_QPA_EGL_SWAPINTERVAL"); + if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) { + QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); bool ok; const int swapInterval = swapIntervalString.toInt(&ok); if (ok) @@ -234,3 +252,5 @@ EGLConfig QEGLPlatformContext::eglConfig() const { return m_eglConfig; } + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index a976aff271..d62082faa2 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -46,6 +46,8 @@ #include <qpa/qplatformopenglcontext.h> #include <EGL/egl.h> +QT_BEGIN_NAMESPACE + class QEGLPlatformContext : public QPlatformOpenGLContext { public: @@ -84,4 +86,6 @@ private: int m_swapIntervalFromEnv; }; +QT_END_NAMESPACE + #endif //QEGLPLATFORMCONTEXT_H diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp new file mode 100644 index 0000000000..55590dbc9e --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -0,0 +1,353 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglplatformcursor_p.h" +#include <qpa/qwindowsysteminterface.h> +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLShaderProgram> +#include <QtCore/QJsonDocument> +#include <QtCore/QJsonArray> +#include <QtCore/QJsonObject> +#include <QtDebug> + +#include <QtPlatformSupport/private/qdevicediscovery_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QEGLPlatformCursor + \brief Mouse cursor implementation using OpenGL. + \since 5.2 + \internal + \ingroup qpa + */ + +QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) + : m_visible(true), + m_screen(screen), + m_program(0), + m_vertexCoordEntry(0), + m_textureCoordEntry(0), + m_textureEntry(0) +{ + QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); + if (hideCursorVal.isEmpty()) { + QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse)); + m_visible = !dis->scanConnectedDevices().isEmpty(); + } else { + m_visible = hideCursorVal.toInt() == 0; + } + if (!m_visible) + return; + + // Try to load the cursor atlas. If this fails, m_visible is set to false and + // paintOnScreen() and setCurrentCursor() become no-ops. + initCursorAtlas(); + + // initialize the cursor +#ifndef QT_NO_CURSOR + QCursor cursor(Qt::ArrowCursor); + setCurrentCursor(&cursor); +#endif +} + +QEGLPlatformCursor::~QEGLPlatformCursor() +{ + resetResources(); +} + +void QEGLPlatformCursor::resetResources() +{ + if (QOpenGLContext::currentContext()) { + delete m_program; + glDeleteTextures(1, &m_cursor.customCursorTexture); + glDeleteTextures(1, &m_cursorAtlas.texture); + } + m_program = 0; + m_cursor.customCursorTexture = 0; + m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull(); + m_cursorAtlas.texture = 0; +} + +void QEGLPlatformCursor::createShaderPrograms() +{ + static const char *textureVertexProgram = + "attribute highp vec2 vertexCoordEntry;\n" + "attribute highp vec2 textureCoordEntry;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " textureCoord = textureCoordEntry;\n" + " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n" + "}\n"; + + static const char *textureFragmentProgram = + "uniform sampler2D texture;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" + "}\n"; + + m_program = new QOpenGLShaderProgram; + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); + m_program->link(); + + m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry"); + m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry"); + m_textureEntry = m_program->attributeLocation("texture"); +} + +void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) +{ + if (!*texture) + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */, + GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); +} + +void QEGLPlatformCursor::initCursorAtlas() +{ + static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); + if (json.isEmpty()) + json = ":/cursor.json"; + + QFile file(QString::fromUtf8(json)); + if (!file.open(QFile::ReadOnly)) { + m_visible = false; + return; + } + + QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); + QJsonObject object = doc.object(); + + QString atlas = object.value(QLatin1String("image")).toString(); + Q_ASSERT(!atlas.isEmpty()); + + const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble(); + Q_ASSERT(cursorsPerRow); + m_cursorAtlas.cursorsPerRow = cursorsPerRow; + + const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray(); + Q_ASSERT(hotSpots.count() == Qt::LastCursor); + for (int i = 0; i < hotSpots.count(); i++) { + QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble()); + m_cursorAtlas.hotSpots << hotSpot; + } + + QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied); + m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow; + m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow - 1) / cursorsPerRow); + m_cursorAtlas.width = image.width(); + m_cursorAtlas.height = image.height(); + m_cursorAtlas.image = image; +} + +#ifndef QT_NO_CURSOR +void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window) +{ + Q_UNUSED(window); + const QRect oldCursorRect = cursorRect(); + if (setCurrentCursor(cursor)) + update(oldCursorRect | cursorRect()); +} + +bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor) +{ + if (!m_visible) + return false; + + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor) + return false; + + if (m_cursor.shape == Qt::BitmapCursor) { + m_cursor.customCursorImage = QImage(); + m_cursor.customCursorPending = false; + } + m_cursor.shape = newShape; + if (newShape != Qt::BitmapCursor) { // standard cursor + const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width, + hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height; + m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow), + hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow), + ws, hs); + m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape]; + m_cursor.texture = m_cursorAtlas.texture; + m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight); + } else { + QImage image = cursor->pixmap().toImage(); + m_cursor.textureRect = QRectF(0, 0, 1, 1); + m_cursor.hotSpot = cursor->hotSpot(); + m_cursor.texture = 0; // will get updated in the next render() + m_cursor.size = image.size(); + m_cursor.customCursorImage = image; + m_cursor.customCursorPending = true; + } + + return true; +} +#endif + +void QEGLPlatformCursor::update(const QRegion &rgn) +{ + QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(m_cursor.pos), rgn); + QWindowSystemInterface::flushWindowSystemEvents(); +} + +QRect QEGLPlatformCursor::cursorRect() const +{ + return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size); +} + +QPoint QEGLPlatformCursor::pos() const +{ + return m_cursor.pos; +} + +void QEGLPlatformCursor::setPos(const QPoint &pos) +{ + const QRect oldCursorRect = cursorRect(); + m_cursor.pos = pos; + update(oldCursorRect | cursorRect()); +} + +void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) +{ + if (event.type() != QEvent::MouseMove) + return; + const QRect oldCursorRect = cursorRect(); + m_cursor.pos = event.screenPos().toPoint(); + update(oldCursorRect | cursorRect()); +} + +void QEGLPlatformCursor::paintOnScreen() +{ + if (!m_visible) + return; + + const QRectF cr = cursorRect(); + const QRect screenRect(m_screen->geometry()); + const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1; + const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1; + const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2; + const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2; + QRectF r(QPointF(x1, y1), QPointF(x2, y2)); + + draw(r); +} + +void QEGLPlatformCursor::draw(const QRectF &r) +{ + if (!m_program) { + // one time initialization + createShaderPrograms(); + + if (!m_cursorAtlas.texture) { + createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); + + if (m_cursor.shape != Qt::BitmapCursor) + m_cursor.texture = m_cursorAtlas.texture; + } + } + + if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) { + // upload the custom cursor + createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); + m_cursor.texture = m_cursor.customCursorTexture; + m_cursor.customCursorPending = false; + } + + Q_ASSERT(m_cursor.texture); + + m_program->bind(); + + const GLfloat x1 = r.left(); + const GLfloat x2 = r.right(); + const GLfloat y1 = r.top(); + const GLfloat y2 = r.bottom(); + const GLfloat cursorCoordinates[] = { + x1, y2, + x2, y2, + x1, y1, + x2, y1 + }; + + const GLfloat s1 = m_cursor.textureRect.left(); + const GLfloat s2 = m_cursor.textureRect.right(); + const GLfloat t1 = m_cursor.textureRect.top(); + const GLfloat t2 = m_cursor.textureRect.bottom(); + const GLfloat textureCoordinates[] = { + s1, t2, + s2, t2, + s1, t1, + s2, t1 + }; + + glBindTexture(GL_TEXTURE_2D, m_cursor.texture); + + m_program->enableAttributeArray(m_vertexCoordEntry); + m_program->enableAttributeArray(m_textureCoordEntry); + + m_program->setAttributeArray(m_vertexCoordEntry, cursorCoordinates, 2); + m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2); + + m_program->setUniformValue(m_textureEntry, 0); + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisable(GL_BLEND); + + glBindTexture(GL_TEXTURE_2D, 0); + m_program->disableAttributeArray(m_textureCoordEntry); + m_program->disableAttributeArray(m_vertexCoordEntry); + + m_program->release(); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h new file mode 100644 index 0000000000..52359b84cd --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLPLATFORMCURSOR_H +#define QEGLPLATFORMCURSOR_H + +#include <qpa/qplatformcursor.h> +#include <qpa/qplatformscreen.h> + +QT_BEGIN_NAMESPACE + +class QOpenGLShaderProgram; + +class QEGLPlatformCursor : public QPlatformCursor +{ +public: + QEGLPlatformCursor(QPlatformScreen *screen); + ~QEGLPlatformCursor(); + +#ifndef QT_NO_CURSOR + void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE; +#endif + void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; + QPoint pos() const Q_DECL_OVERRIDE; + void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + + QRect cursorRect() const; + void paintOnScreen(); + void resetResources(); + +private: +#ifndef QT_NO_CURSOR + bool setCurrentCursor(QCursor *cursor); +#endif + void draw(const QRectF &rect); + void update(const QRegion ®ion); + void createShaderPrograms(); + static void createCursorTexture(uint *texture, const QImage &image); + void initCursorAtlas(); + + // current cursor information + struct Cursor { + Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { } + uint texture; // a texture from 'image' or the atlas + Qt::CursorShape shape; + QRectF textureRect; // normalized rect inside texture + QSize size; // size of the cursor + QPoint hotSpot; + QImage customCursorImage; + QPoint pos; // current cursor position + uint customCursorTexture; + bool customCursorPending; + } m_cursor; + + // cursor atlas information + struct CursorAtlas { + CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { } + int cursorsPerRow; + uint texture; + int width, height; // width and height of the the atlas + int cursorWidth, cursorHeight; // width and height of cursors inside the atlas + QList<QPoint> hotSpots; + QImage image; // valid until it's uploaded + } m_cursorAtlas; + + bool m_visible; + QPlatformScreen *m_screen; + QOpenGLShaderProgram *m_program; + int m_vertexCoordEntry; + int m_textureCoordEntry; + int m_textureEntry; +}; + +QT_END_NAMESPACE + +#endif // QEGLPLATFORMCURSOR_H diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp new file mode 100644 index 0000000000..28cd1a236f --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QWindow> +#include <QtGui/QOpenGLContext> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatforminputcontextfactory_p.h> +#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> +#include <QtPlatformSupport/private/qgenericunixservices_p.h> +#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> + +#include "qeglplatformintegration_p.h" +#include "qeglplatformcontext_p.h" +#include "qeglplatformwindow_p.h" +#include "qeglplatformbackingstore_p.h" +#include "qeglplatformscreen_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QEGLPlatformIntegration + \brief Base class for EGL-based QPlatformIntegration implementations. + \since 5.2 + \internal + \ingroup qpa + + This class provides most of the necessary platform integration for + an EGL-based Unix system. Platform plugins must subclass this and + reimplement the virtuals for creating platform screens and windows + since they will most likely wish to use a subclass for these. + + The backing store, native interface accessors, font database, + basic capability flags, etc. are provided out of the box, no + further customization is needed. Subclasses are still responsible + however for context and offscreen surface creation. + + \note It is critical that this class' implementation of + initialize() is called. Therefore subclasses should either avoid + to reimplement this function or call the base class + implementation. + */ + +QEGLPlatformIntegration::QEGLPlatformIntegration() + : m_screen(0), + m_display(EGL_NO_DISPLAY), + m_inputContext(0), + mFontDb(new QGenericUnixFontDatabase), + mServices(new QGenericUnixServices) +{ +} + +QEGLPlatformIntegration::~QEGLPlatformIntegration() +{ + delete m_screen; + if (m_display != EGL_NO_DISPLAY) + eglTerminate(m_display); +} + +void QEGLPlatformIntegration::initialize() +{ + if (!eglBindAPI(EGL_OPENGL_ES_API)) + qFatal("Could not bind GL_ES API"); + + m_display = eglGetDisplay(nativeDisplay()); + if (m_display == EGL_NO_DISPLAY) + qFatal("Could not open egl display"); + + EGLint major, minor; + if (!eglInitialize(m_display, &major, &minor)) + qFatal("Could not initialize egl display"); + + m_screen = createScreen(); + screenAdded(m_screen); + + m_inputContext = QPlatformInputContextFactory::create(); +} + +QAbstractEventDispatcher *QEGLPlatformIntegration::createEventDispatcher() const +{ + return createUnixEventDispatcher(); +} + +QPlatformServices *QEGLPlatformIntegration::services() const +{ + return mServices.data(); +} + +QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const +{ + return mFontDb.data(); +} + +QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QEGLPlatformBackingStore(window); +} + +QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const +{ + QWindowSystemInterface::flushWindowSystemEvents(); + QEGLPlatformWindow *w = createWindow(window); + w->create(); + if (window->type() != Qt::ToolTip) + w->requestActivateWindow(); + return w; +} + +bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case ThreadedPixmaps: return true; + case OpenGL: return true; + case ThreadedOpenGL: return true; + case WindowManagement: return false; + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const +{ + return const_cast<QEGLPlatformIntegration *>(this); +} + +enum ResourceType { + EglDisplay, + EglWindow, + EglContext +}; + +static int resourceType(const QByteArray &key) +{ + static const QByteArray names[] = { // match ResourceType + QByteArrayLiteral("egldisplay"), + QByteArrayLiteral("eglwindow"), + QByteArrayLiteral("eglcontext") + }; + const QByteArray *end = names + sizeof(names) / sizeof(names[0]); + const QByteArray *result = std::find(names, end, key); + if (result == end) + result = std::find(names, end, key.toLower()); + return int(result - names); +} + +void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &resource) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglDisplay: + result = m_screen->display(); + break; + default: + break; + } + + return result; +} + +void *QEGLPlatformIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglDisplay: + if (window && window->handle()) + result = static_cast<QEGLPlatformScreen *>(window->handle()->screen())->display(); + else + result = m_screen->display(); + break; + case EglWindow: + if (window && window->handle()) + result = reinterpret_cast<void*>(static_cast<QEGLPlatformWindow *>(window->handle())->eglWindow()); + break; + default: + break; + } + + return result; +} + +void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglContext: + if (context->handle()) + result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext(); + break; + default: + break; + } + + return result; +} + +static void *eglContextForContext(QOpenGLContext *context) +{ + Q_ASSERT(context); + + QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle()); + if (!handle) + return 0; + + return handle->eglContext(); +} + +QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegration::nativeResourceFunctionForContext(const QByteArray &resource) +{ + QByteArray lowerCaseResource = resource.toLower(); + if (lowerCaseResource == "get_egl_context") + return NativeResourceForContextFunction(eglContextForContext); + + return 0; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h new file mode 100644 index 0000000000..ea667e7d6f --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLPLATFORMINTEGRATION_H +#define QEGLPLATFORMINTEGRATION_H + +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformnativeinterface.h> +#include <EGL/egl.h> + +QT_BEGIN_NAMESPACE + +class QEGLPlatformScreen; +class QEGLPlatformWindow; + +class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface +{ +public: + QEGLPlatformIntegration(); + ~QEGLPlatformIntegration(); + + void initialize() Q_DECL_OVERRIDE; + + QEGLPlatformScreen *screen() const { return m_screen; } + EGLDisplay display() const { return m_display; } + + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + + QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + // QPlatformNativeInterface + void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; + void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; + NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE; + +protected: + virtual QEGLPlatformScreen *createScreen() const = 0; + virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0; + virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; } + +private: + QEGLPlatformScreen *m_screen; + EGLDisplay m_display; + QPlatformInputContext *m_inputContext; + QScopedPointer<QPlatformFontDatabase> mFontDb; + QScopedPointer<QPlatformServices> mServices; +}; + +QT_END_NAMESPACE + +#endif // QEGLPLATFORMINTEGRATION_H diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp new file mode 100644 index 0000000000..72e7f6a6df --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglcompositor_p.h" +#include "qeglplatformscreen_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QEGLPlatformScreen + \brief Base class for EGL-based platform screen implementations. + \since 5.2 + \internal + \ingroup qpa + + This class provides a lightweight base for QPlatformScreen + implementations. It covers basic window stack management which is + necessary when compositing multiple raster (widget-based) windows + together into one single native surface. + + Reimplementing the virtuals are essential when using + QEGLPlatformBackingStore. The context and the window returned from + these are the ones that are used when compositing the textures + generated from the raster (widget) based windows. + + \note It is up to the QEGLPlatformWindow subclasses to use the + functions, like addWindow(), removeWindow(), etc., provided here. + */ + +QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy) + : m_dpy(dpy) +{ +} + +QEGLPlatformScreen::~QEGLPlatformScreen() +{ + QEGLCompositor::destroy(); +} + +void QEGLPlatformScreen::addWindow(QEGLPlatformWindow *window) +{ + if (!m_windows.contains(window)) { + m_windows.append(window); + topWindowChanged(window); + } +} + +void QEGLPlatformScreen::removeWindow(QEGLPlatformWindow *window) +{ + m_windows.removeOne(window); + if (!m_windows.isEmpty()) + topWindowChanged(m_windows.last()); +} + +void QEGLPlatformScreen::moveToTop(QEGLPlatformWindow *window) +{ + m_windows.removeOne(window); + m_windows.append(window); + topWindowChanged(window); +} + +void QEGLPlatformScreen::changeWindowIndex(QEGLPlatformWindow *window, int newIdx) +{ + int idx = m_windows.indexOf(window); + if (idx != -1 && idx != newIdx) { + m_windows.move(idx, newIdx); + if (newIdx == m_windows.size() - 1) + topWindowChanged(m_windows.last()); + } +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h new file mode 100644 index 0000000000..d0d8a52a87 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLPLATFORMSCREEN_H +#define QEGLPLATFORMSCREEN_H + +#include <QtCore/QList> +#include <qpa/qplatformscreen.h> +#include <EGL/egl.h> + +QT_BEGIN_NAMESPACE + +class QOpenGLContext; +class QEGLPlatformWindow; + +class QEGLPlatformScreen : public QPlatformScreen +{ +public: + QEGLPlatformScreen(EGLDisplay dpy); + ~QEGLPlatformScreen(); + + QList<QEGLPlatformWindow *> windows() const { return m_windows; } + + void addWindow(QEGLPlatformWindow *window); + void removeWindow(QEGLPlatformWindow *window); + void moveToTop(QEGLPlatformWindow *window); + void changeWindowIndex(QEGLPlatformWindow *window, int newIdx); + + virtual void topWindowChanged(QEGLPlatformWindow *window) { Q_UNUSED(window); } + + EGLDisplay display() const { return m_dpy; } + + virtual QEGLPlatformWindow *compositingWindow() = 0; + virtual QOpenGLContext *compositingContext() = 0; + +private: + QList<QEGLPlatformWindow *> m_windows; + EGLDisplay m_dpy; +}; + +QT_END_NAMESPACE + +#endif // QEGLPLATFORMSCREEN_H diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp new file mode 100644 index 0000000000..a635bfff29 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qpa/qwindowsysteminterface.h> + +#include "qeglplatformwindow_p.h" +#include "qeglplatformbackingstore_p.h" +#include "qeglplatformscreen_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QEGLPlatformWindow + \brief Base class for EGL-based platform window implementations. + \since 5.2 + \internal + \ingroup qpa + + Lightweight class providing some basic platform window operations + and interfacing with QEGLPlatformBackingStore. + + Almost no QPlatformWindow functions are implemented here. This is + intentional because different platform plugins may use different + strategies for their window management (some may force fullscreen + windows, some may not, some may share the underlying native + surface, some may not, etc.) and therefore it is not sensible to + enforce anything for these functions. + + \note Subclasses are responsible for invoking this class' + implementation of create(). When using QEGLPlatformScreen, the + subclasses of this class are expected to utilize the window stack + management functions (addWindow() etc.) provided there. + */ + +QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w) + : QPlatformWindow(w), + m_winId(0) +{ +} + +static WId newWId() +{ + static WId id = 0; + + if (id == std::numeric_limits<WId>::max()) + qWarning("QEGLPlatformWindow: Out of window IDs"); + + return ++id; +} + +void QEGLPlatformWindow::create() +{ + m_winId = newWId(); + + // Save the original surface type before changing to OpenGLSurface. + m_raster = (window()->surfaceType() == QSurface::RasterSurface); + window()->setSurfaceType(QSurface::OpenGLSurface); + + if (window()->type() == Qt::Desktop) { + QRect fullscreenRect(QPoint(), screen()->availableGeometry().size()); + QPlatformWindow::setGeometry(fullscreenRect); + QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect); + return; + } +} + +uint QEGLPlatformWindow::texture() const +{ + if (m_backingStore) + return m_backingStore->texture(); + + return 0; +} + +WId QEGLPlatformWindow::winId() const +{ + return m_winId; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h new file mode 100644 index 0000000000..770c741623 --- /dev/null +++ b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLPLATFORMWINDOW_H +#define QEGLPLATFORMWINDOW_H + +#include <qpa/qplatformwindow.h> +#include <EGL/egl.h> + +QT_BEGIN_NAMESPACE + +class QEGLPlatformBackingStore; + +class QEGLPlatformWindow : public QPlatformWindow +{ +public: + QEGLPlatformWindow(QWindow *w); + + virtual void create(); + + QEGLPlatformBackingStore *backingStore() { return m_backingStore; } + void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; } + uint texture() const; + bool isRaster() const { return m_raster; } + + WId winId() const Q_DECL_OVERRIDE; + + virtual EGLNativeWindowType eglWindow() const = 0; + +private: + QEGLPlatformBackingStore *m_backingStore; + bool m_raster; + WId m_winId; +}; + +QT_END_NAMESPACE + +#endif // QEGLPLATFORMWINDOW_H |