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 \ qeglfsbackingstore.cpp \
qeglfsscreen.cpp \ qeglfsscreen.cpp \
qeglfshooks_stub.cpp \ qeglfshooks_stub.cpp \
qeglfscursor.cpp qeglfscursor.cpp \
qeglfscontext.cpp
HEADERS = qeglfsintegration.h \ HEADERS = qeglfsintegration.h \
qeglfswindow.h \ qeglfswindow.h \
qeglfsbackingstore.h \ qeglfsbackingstore.h \
qeglfsscreen.h \ qeglfsscreen.h \
qeglfscursor.h \ qeglfscursor.h \
qeglfshooks.h qeglfshooks.h \
qeglfscontext.h
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF

View File

@ -41,6 +41,7 @@
#include "qeglfsbackingstore.h" #include "qeglfsbackingstore.h"
#include "qeglfscursor.h" #include "qeglfscursor.h"
#include "qeglfswindow.h"
#include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice> #include <QtGui/QOpenGLPaintDevice>
@ -56,7 +57,7 @@ QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
, m_texture(0) , m_texture(0)
, m_program(0) , m_program(0)
{ {
m_context->setFormat(window->requestedFormat()); m_context->setFormat(window->format());
m_context->setScreen(window->screen()); m_context->setScreen(window->screen());
m_context->create(); m_context->create();
} }
@ -193,7 +194,7 @@ void QEglFSBackingStore::makeCurrent()
{ {
// needed to prevent QOpenGLContext::makeCurrent() from failing // needed to prevent QOpenGLContext::makeCurrent() from failing
window()->setSurfaceType(QSurface::OpenGLSurface); window()->setSurfaceType(QSurface::OpenGLSurface);
(static_cast<QEglFSWindow *>(window()->handle()))->create();
m_context->makeCurrent(window()); 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 <QtGui/QScreen>
#include <qpa/qplatformcursor.h> #include <qpa/qplatformcursor.h>
#include "qeglfscontext.h"
#include <EGL/egl.h> #include <EGL/egl.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -88,15 +90,12 @@ QEglFSIntegration::QEglFSIntegration()
qWarning("Could not open egl display\n"); qWarning("Could not open egl display\n");
qFatal("EGL error"); qFatal("EGL error");
} }
qWarning("Opened display %p\n", mDisplay);
if (!eglInitialize(mDisplay, &major, &minor)) { if (!eglInitialize(mDisplay, &major, &minor)) {
qWarning("Could not initialize egl display\n"); qWarning("Could not initialize egl display\n");
qFatal("EGL error"); qFatal("EGL error");
} }
qWarning("Initialized display %d %d\n", major, minor);
int swapInterval = 1; int swapInterval = 1;
QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
if (!swapIntervalString.isEmpty()) { if (!swapIntervalString.isEmpty()) {
@ -109,10 +108,6 @@ QEglFSIntegration::QEglFSIntegration()
mScreen = new QEglFSScreen(mDisplay); mScreen = new QEglFSScreen(mDisplay);
screenAdded(mScreen); screenAdded(mScreen);
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglFSIntegration\n");
#endif
} }
QEglFSIntegration::~QEglFSIntegration() QEglFSIntegration::~QEglFSIntegration()
@ -139,27 +134,19 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
{ {
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglFSIntegration::createPlatformWindow %p\n",window);
#endif
QPlatformWindow *w = new QEglFSWindow(window); QPlatformWindow *w = new QEglFSWindow(window);
w->requestActivateWindow(); w->requestActivateWindow();
return w; return w;
} }
QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
{ {
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglFSIntegration::createWindowSurface %p\n", window);
#endif
return new QEglFSBackingStore(window); return new QEglFSBackingStore(window);
} }
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const 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 QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const

View File

@ -44,45 +44,10 @@
#include "qeglfswindow.h" #include "qeglfswindow.h"
#include "qeglfshooks.h" #include "qeglfshooks.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE 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) QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: m_dpy(dpy) : m_dpy(dpy)
, m_platformContext(0)
, m_surface(0)
, m_window(0)
, m_cursor(0) , m_cursor(0)
{ {
#ifdef QEGL_EXTRA_DEBUG #ifdef QEGL_EXTRA_DEBUG
@ -101,39 +66,6 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
QEglFSScreen::~QEglFSScreen() QEglFSScreen::~QEglFSScreen()
{ {
delete m_cursor; 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 QRect QEglFSScreen::geometry() const
@ -156,13 +88,4 @@ QPlatformCursor *QEglFSScreen::cursor() const
return m_cursor; return m_cursor;
} }
QPlatformOpenGLContext *QEglFSScreen::platformContext() const
{
if (!m_platformContext) {
QEglFSScreen *that = const_cast<QEglFSScreen *>(this);
that->createAndSetPlatformContext();
}
return m_platformContext;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

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

View File

@ -40,13 +40,19 @@
****************************************************************************/ ****************************************************************************/
#include "qeglfswindow.h" #include "qeglfswindow.h"
#include "qeglfshooks.h"
#include <QtGui/QWindowSystemInterface> #include <QtGui/QWindowSystemInterface>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtDebug>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w) QEglFSWindow::QEglFSWindow(QWindow *w)
: QPlatformWindow(w) : QPlatformWindow(w)
, m_surface(0)
, m_window(0)
{ {
static int serialNo = 0; static int serialNo = 0;
m_winid = ++serialNo; m_winid = ++serialNo;
@ -57,6 +63,43 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
setWindowState(Qt::WindowFullScreen); 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 &) void QEglFSWindow::setGeometry(const QRect &)
{ {
// We only support full-screen windows // We only support full-screen windows
@ -77,4 +120,9 @@ WId QEglFSWindow::winId() const
return m_winid; return m_winid;
} }
QSurfaceFormat QEglFSWindow::format() const
{
return hooks->defaultSurfaceFormat();
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

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