eglfs: Move reusable functionality to eglconvenience
The cursor implementation is generic GL(ES) code that should be shared by all the present and future egl-based embedded platform plugins. Follow the pattern of QEGLPlatformContext and move this class into eglconvenience as QEGLPlatformCursor. Similarly, the common bits from the context implementation context are moved back to EGLPlatformContext. eglconvenience has now base classes for integration, screen, window, etc. too. By using these, eglfs becomes much smaller and cleaner. This also paves the way for creating new, separate EGL-based platform plugins for Android, embedded Linux, etc. Also added some documentation to each of the base classes. devicediscovery is now fixed to be usable on any platform. The implementation in this case is naturally a dummy one. This finally allows using it from anywhere without myriads of ugly ifdefs. Change-Id: I02946e360c04e02de7fe234a23a08320eff4ccf5 Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
parent
93154216ca
commit
328f2f9c35
@ -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
|
||||
}
|
||||
|
@ -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
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
@ -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
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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 QEglFSBackingStore::beginPaint(const QRegion &rgn)
|
||||
void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
|
||||
{
|
||||
QEGLCompositor::instance()->schedule(context, window);
|
||||
}
|
||||
|
||||
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);
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
255
src/platformsupport/eglconvenience/qeglplatformintegration.cpp
Normal file
255
src/platformsupport/eglconvenience/qeglplatformintegration.cpp
Normal file
@ -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
|
@ -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
|
110
src/platformsupport/eglconvenience/qeglplatformscreen.cpp
Normal file
110
src/platformsupport/eglconvenience/qeglplatformscreen.cpp
Normal file
@ -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
|
81
src/platformsupport/eglconvenience/qeglplatformscreen_p.h
Normal file
81
src/platformsupport/eglconvenience/qeglplatformscreen_p.h
Normal file
@ -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
|
118
src/platformsupport/eglconvenience/qeglplatformwindow.cpp
Normal file
118
src/platformsupport/eglconvenience/qeglplatformwindow.cpp
Normal file
@ -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
|
76
src/platformsupport/eglconvenience/qeglplatformwindow_p.h
Normal file
76
src/platformsupport/eglconvenience/qeglplatformwindow_p.h
Normal file
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,50 +106,29 @@ 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();
|
||||
}
|
||||
|
||||
QEGLPlatformScreen *QEglFSIntegration::createScreen() const
|
||||
{
|
||||
return new QEglFSScreen(display());
|
||||
}
|
||||
|
||||
QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
|
||||
{
|
||||
return new QEglFSWindow(window);
|
||||
}
|
||||
|
||||
QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
|
||||
@ -192,115 +136,12 @@ QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) cons
|
||||
switch (hint)
|
||||
{
|
||||
case QPlatformIntegration::ShowIsFullScreen:
|
||||
return mScreen->rootWindow() == 0;
|
||||
return screen()->compositingWindow() == 0;
|
||||
default:
|
||||
return QPlatformIntegration::styleHint(hint);
|
||||
}
|
||||
}
|
||||
|
||||
QPlatformServices *QEglFSIntegration::services() const
|
||||
{
|
||||
return mServices.data();
|
||||
}
|
||||
|
||||
QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const
|
||||
{
|
||||
return const_cast<QEglFSIntegration *>(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 *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)
|
||||
{
|
||||
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 QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
|
||||
{
|
||||
QByteArray lowerCaseResource = resource.toLower();
|
||||
if (lowerCaseResource == "get_egl_context")
|
||||
return NativeResourceForContextFunction(eglContextForContext);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
|
||||
{
|
||||
class Chooser : public QEglConfigChooser {
|
||||
|
@ -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;
|
||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
|
||||
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
|
||||
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const;
|
||||
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
|
||||
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
|
||||
QPlatformNativeInterface *nativeInterface() const;
|
||||
void initialize() Q_DECL_OVERRIDE;
|
||||
|
||||
QPlatformFontDatabase *fontDatabase() const;
|
||||
QPlatformServices *services() const;
|
||||
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
|
||||
QVariant styleHint(QPlatformIntegration::StyleHint hint) const Q_DECL_OVERRIDE;
|
||||
|
||||
QAbstractEventDispatcher *createEventDispatcher() const;
|
||||
void initialize();
|
||||
|
||||
QVariant styleHint(QPlatformIntegration::StyleHint hint) const;
|
||||
|
||||
// QPlatformNativeInterface
|
||||
void *nativeResourceForIntegration(const QByteArray &resource);
|
||||
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
|
||||
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
EGLSurface surface() const;
|
||||
QSurfaceFormat format() const;
|
||||
EGLNativeWindowType eglWindow() const;
|
||||
|
||||
QEglFSScreen *screen() const;
|
||||
|
||||
void create();
|
||||
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;
|
||||
QEglFSScreen *screen() const;
|
||||
|
||||
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;
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user