eglfs refactor: move window creation into qeglfswindow

This potentially allows the creation of multiple QWindows. The platform
context is now in a seperate file and the integration provides a new
instance of the context allowing creation of multiple contexts.

Change-Id: If2b6fa29b573d87c0a4cd0a8eff1f044bd1ff9b8
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Girish Ramakrishnan 2012-06-06 13:57:09 -07:00 committed by Qt by Nokia
parent 040f30decd
commit e9df01d3db
9 changed files with 212 additions and 106 deletions

View File

@ -20,14 +20,16 @@ SOURCES = main.cpp \
qeglfsbackingstore.cpp \
qeglfsscreen.cpp \
qeglfshooks_stub.cpp \
qeglfscursor.cpp
qeglfscursor.cpp \
qeglfscontext.cpp
HEADERS = qeglfsintegration.h \
qeglfswindow.h \
qeglfsbackingstore.h \
qeglfsscreen.h \
qeglfscursor.h \
qeglfshooks.h
qeglfshooks.h \
qeglfscontext.h
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF

View File

@ -41,6 +41,7 @@
#include "qeglfsbackingstore.h"
#include "qeglfscursor.h"
#include "qeglfswindow.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
@ -56,7 +57,7 @@ QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
, m_texture(0)
, m_program(0)
{
m_context->setFormat(window->requestedFormat());
m_context->setFormat(window->format());
m_context->setScreen(window->screen());
m_context->create();
}
@ -193,7 +194,7 @@ void QEglFSBackingStore::makeCurrent()
{
// needed to prevent QOpenGLContext::makeCurrent() from failing
window()->setSurfaceType(QSurface::OpenGLSurface);
(static_cast<QEglFSWindow *>(window()->handle()))->create();
m_context->makeCurrent(window());
}

View File

@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qeglfscontext.h"
#include "qeglfswindow.h"
#include "qeglfscursor.h"
#include "qeglfshooks.h"
#include <QtDebug>
QT_BEGIN_NAMESPACE
QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
EGLDisplay display, EGLenum eglApi)
: QEGLPlatformContext(format, share, display, eglApi)
{
}
bool QEglFSContext::makeCurrent(QPlatformSurface *surface)
{
// create the native window surface. this makes sure that
// we create surfaces only for painted widgets (unlike QDesktopWidget)
(static_cast<QEglFSWindow *>(surface))->create();
return QEGLPlatformContext::makeCurrent(surface);
}
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
return window->surface();
}
void QEglFSContext::swapBuffers(QPlatformSurface *surface)
{
QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
// draw the cursor
if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(window->screen()->cursor()))
cursor->paintOnScreen();
QEGLPlatformContext::swapBuffers(surface);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QEGLFSCONTEXT_H
#define QEGLFSCONTEXT_H
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
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);
};
QT_END_NAMESPACE
#endif // QEGLFSCONTEXT_H

View File

@ -61,6 +61,8 @@
#include <QtGui/QScreen>
#include <qpa/qplatformcursor.h>
#include "qeglfscontext.h"
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@ -88,15 +90,12 @@ QEglFSIntegration::QEglFSIntegration()
qWarning("Could not open egl display\n");
qFatal("EGL error");
}
qWarning("Opened display %p\n", mDisplay);
if (!eglInitialize(mDisplay, &major, &minor)) {
qWarning("Could not initialize egl display\n");
qFatal("EGL error");
}
qWarning("Initialized display %d %d\n", major, minor);
int swapInterval = 1;
QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
if (!swapIntervalString.isEmpty()) {
@ -109,10 +108,6 @@ QEglFSIntegration::QEglFSIntegration()
mScreen = new QEglFSScreen(mDisplay);
screenAdded(mScreen);
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglFSIntegration\n");
#endif
}
QEglFSIntegration::~QEglFSIntegration()
@ -139,27 +134,19 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
{
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglFSIntegration::createPlatformWindow %p\n",window);
#endif
QPlatformWindow *w = new QEglFSWindow(window);
w->requestActivateWindow();
return w;
}
QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
{
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglFSIntegration::createWindowSurface %p\n", window);
#endif
return new QEglFSBackingStore(window);
}
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
return static_cast<QEglFSScreen *>(context->screen()->handle())->platformContext();
return new QEglFSContext(context->format(), 0 /*share*/, mDisplay);
}
QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const

View File

@ -44,45 +44,10 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
// #define QEGL_EXTRA_DEBUG
class QEglFSContext : public QEGLPlatformContext
{
public:
QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLenum eglApi = EGL_OPENGL_ES_API)
: QEGLPlatformContext(format, share, display, eglApi)
{
}
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
QEglFSScreen *screen = static_cast<QEglFSScreen *>(window->screen());
return screen->surface();
}
void swapBuffers(QPlatformSurface *surface)
{
QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
QEglFSScreen *screen = static_cast<QEglFSScreen *>(window->screen());
if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(screen->cursor()))
cursor->paintOnScreen();
QEGLPlatformContext::swapBuffers(surface);
}
};
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: m_dpy(dpy)
, m_platformContext(0)
, m_surface(0)
, m_window(0)
, m_cursor(0)
{
#ifdef QEGL_EXTRA_DEBUG
@ -101,39 +66,6 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
QEglFSScreen::~QEglFSScreen()
{
delete m_cursor;
if (m_surface)
eglDestroySurface(m_dpy, m_surface);
hooks->destroyNativeWindow(m_window);
}
void QEglFSScreen::createAndSetPlatformContext() const {
const_cast<QEglFSScreen *>(this)->createAndSetPlatformContext();
}
void QEglFSScreen::createAndSetPlatformContext()
{
QSurfaceFormat platformFormat = hooks->defaultSurfaceFormat();
EGLConfig config = q_configFromGLFormat(m_dpy, platformFormat);
m_window = hooks->createNativeWindow(hooks->screenSize());
#ifdef QEGL_EXTRA_DEBUG
q_printEglConfig(m_dpy, config);
#endif
m_surface = eglCreateWindowSurface(m_dpy, config, m_window, NULL);
if (m_surface == EGL_NO_SURFACE) {
qWarning("Could not create the egl surface: error = 0x%x\n", eglGetError());
eglTerminate(m_dpy);
qFatal("EGL error");
}
// qWarning("Created surface %dx%d\n", w, h);
QEGLPlatformContext *platformContext = new QEglFSContext(platformFormat, 0, m_dpy);
m_platformContext = platformContext;
}
QRect QEglFSScreen::geometry() const
@ -156,13 +88,4 @@ QPlatformCursor *QEglFSScreen::cursor() const
return m_cursor;
}
QPlatformOpenGLContext *QEglFSScreen::platformContext() const
{
if (!m_platformContext) {
QEglFSScreen *that = const_cast<QEglFSScreen *>(this);
that->createAndSetPlatformContext();
}
return m_platformContext;
}
QT_END_NAMESPACE

View File

@ -67,17 +67,10 @@ public:
QPlatformOpenGLContext *platformContext() const;
EGLSurface surface() const { return m_surface; }
EGLDisplay display() const { return m_dpy; }
private:
void createAndSetPlatformContext() const;
void createAndSetPlatformContext();
EGLDisplay m_dpy;
QPlatformOpenGLContext *m_platformContext;
EGLSurface m_surface;
EGLNativeWindowType m_window;
QEglFSCursor *m_cursor;
};

View File

@ -40,13 +40,19 @@
****************************************************************************/
#include "qeglfswindow.h"
#include "qeglfshooks.h"
#include <QtGui/QWindowSystemInterface>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtDebug>
QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
: QPlatformWindow(w)
, m_surface(0)
, m_window(0)
{
static int serialNo = 0;
m_winid = ++serialNo;
@ -57,6 +63,43 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
setWindowState(Qt::WindowFullScreen);
}
QEglFSWindow::~QEglFSWindow()
{
destroy();
}
void QEglFSWindow::create()
{
if (m_window) {
return;
}
EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
QSurfaceFormat platformFormat = hooks->defaultSurfaceFormat();
EGLConfig config = q_configFromGLFormat(display, platformFormat);
m_window = hooks->createNativeWindow(hooks->screenSize());
m_surface = eglCreateWindowSurface(display, config, m_window, NULL);
if (m_surface == EGL_NO_SURFACE) {
qWarning("Could not create the egl surface: error = 0x%x\n", eglGetError());
eglTerminate(display);
qFatal("EGL error");
}
}
void QEglFSWindow::destroy()
{
if (m_surface) {
EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
eglDestroySurface(display, m_surface);
m_surface = 0;
}
if (m_window) {
hooks->destroyNativeWindow(m_window);
m_window = 0;
}
}
void QEglFSWindow::setGeometry(const QRect &)
{
// We only support full-screen windows
@ -77,4 +120,9 @@ WId QEglFSWindow::winId() const
return m_winid;
}
QSurfaceFormat QEglFSWindow::format() const
{
return hooks->defaultSurfaceFormat();
}
QT_END_NAMESPACE

View File

@ -46,7 +46,6 @@
#include "qeglfsscreen.h"
#include <qpa/qplatformwindow.h>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
@ -54,13 +53,22 @@ class QEglFSWindow : public QPlatformWindow
{
public:
QEglFSWindow(QWindow *w);
~QEglFSWindow();
void setGeometry(const QRect &);
Qt::WindowState setWindowState(Qt::WindowState state);
WId winId() const;
EGLSurface surface() const { return m_surface; }
QSurfaceFormat format() const;
void create();
void destroy();
private:
WId m_winid;
EGLSurface m_surface;
EGLNativeWindowType m_window;
};
QT_END_NAMESPACE
#endif // QEGLFSWINDOW_H