Added QOffscreenSurface class.
Inherits QSurface and allows to use OpenGL from an arbitrary thread. Platform plugins can implement QPlatformOffscreenSurface, otherwise an invisible QWindow is used by QOffscreenSurface. This patch includes an implementation of QOffscreenSurface for XCB and EglFS platform plugins using pbuffers. Change-Id: I57b4fc1db417331f34826dcfa754b7698782fde4 Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
This commit is contained in:
parent
f8fdeb68b6
commit
c7a51f1858
6
dist/changes-5.1.0
vendored
6
dist/changes-5.1.0
vendored
@ -29,7 +29,7 @@ General Improvements
|
||||
Third party components
|
||||
----------------------
|
||||
|
||||
-
|
||||
-
|
||||
|
||||
|
||||
****************************************************************************
|
||||
@ -72,7 +72,9 @@ QtCore
|
||||
QtGui
|
||||
-----
|
||||
|
||||
-
|
||||
- QOffscreenSurface
|
||||
* New class for rendering graphics using OpenGL in an arbitrary thread
|
||||
without needing to use a hidden QWindow.
|
||||
|
||||
|
||||
QtNetwork
|
||||
|
@ -24,6 +24,7 @@ HEADERS += \
|
||||
kernel/qplatformthemefactory_p.h \
|
||||
kernel/qplatformthemeplugin.h \
|
||||
kernel/qplatformwindow.h \
|
||||
kernel/qplatformoffscreensurface.h \
|
||||
kernel/qplatformwindow_p.h \
|
||||
kernel/qplatformcursor.h \
|
||||
kernel/qplatformclipboard.h \
|
||||
@ -34,6 +35,7 @@ HEADERS += \
|
||||
kernel/qguiapplication_p.h \
|
||||
kernel/qwindow_p.h \
|
||||
kernel/qwindow.h \
|
||||
kernel/qoffscreensurface.h \
|
||||
kernel/qplatformsurface.h \
|
||||
kernel/qsurface.h \
|
||||
kernel/qclipboard.h \
|
||||
@ -81,6 +83,7 @@ SOURCES += \
|
||||
kernel/qplatformthemefactory.cpp \
|
||||
kernel/qplatformthemeplugin.cpp \
|
||||
kernel/qplatformwindow.cpp \
|
||||
kernel/qplatformoffscreensurface.cpp \
|
||||
kernel/qplatformcursor.cpp \
|
||||
kernel/qplatformclipboard.cpp \
|
||||
kernel/qplatformnativeinterface.cpp \
|
||||
@ -88,6 +91,7 @@ SOURCES += \
|
||||
kernel/qsurfaceformat.cpp \
|
||||
kernel/qguiapplication.cpp \
|
||||
kernel/qwindow.cpp \
|
||||
kernel/qoffscreensurface.cpp \
|
||||
kernel/qplatformsurface.cpp \
|
||||
kernel/qsurface.cpp \
|
||||
kernel/qclipboard.cpp \
|
||||
|
345
src/gui/kernel/qoffscreensurface.cpp
Normal file
345
src/gui/kernel/qoffscreensurface.cpp
Normal file
@ -0,0 +1,345 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module 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 "qoffscreensurface.h"
|
||||
|
||||
#include "qguiapplication_p.h"
|
||||
#include "qscreen.h"
|
||||
#include "qplatformintegration.h"
|
||||
#include "qplatformoffscreensurface.h"
|
||||
#include "qwindow.h"
|
||||
#include "qplatformwindow.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QOffscreenSurface
|
||||
\inmodule QtGui
|
||||
\since 5.1
|
||||
\brief The QOffscreenSurface class represents an offscreen surface in the underlying platform.
|
||||
|
||||
QOffscreenSurface is intended to be used with QOpenGLContext to allow rendering with OpenGL in
|
||||
an arbitrary thread without the need to create a QWindow.
|
||||
|
||||
Even though the surface is renderable, the surface's pixels are not accessible.
|
||||
QOffscreenSurface should only be used to create OpenGL resources such as textures
|
||||
or framebuffer objects.
|
||||
|
||||
An application will typically use QOffscreenSurface to perform some time-consuming tasks in a
|
||||
separate thread in order to avoid stalling the main rendering thread. Resources created in the
|
||||
QOffscreenSurface's context can be shared with the main OpenGL context. Some common use cases
|
||||
are asynchronous texture uploads or rendering into a QOpenGLFramebufferObject.
|
||||
|
||||
How the offscreen surface is implemented depends on the underlying platform, but it will
|
||||
typically use a pixel buffer (pbuffer). If the platform doesn't implement or support
|
||||
offscreen surfaces, QOffscreenSurface will use an invisible QWindow internally.
|
||||
*/
|
||||
class Q_GUI_EXPORT QOffscreenSurfacePrivate : public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QOffscreenSurface)
|
||||
|
||||
public:
|
||||
QOffscreenSurfacePrivate()
|
||||
: QObjectPrivate()
|
||||
, surfaceType(QSurface::OpenGLSurface)
|
||||
, platformOffscreenSurface(0)
|
||||
, offscreenWindow(0)
|
||||
, screen(0)
|
||||
, size(1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
~QOffscreenSurfacePrivate()
|
||||
{
|
||||
}
|
||||
|
||||
QSurface::SurfaceType surfaceType;
|
||||
QPlatformOffscreenSurface *platformOffscreenSurface;
|
||||
QWindow *offscreenWindow;
|
||||
QSurfaceFormat requestedFormat;
|
||||
QScreen *screen;
|
||||
QSize size;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
Creates an offscreen surface for the \a targetScreen.
|
||||
|
||||
The underlying platform surface is not created until create() is called.
|
||||
|
||||
\sa setScreen(), create()
|
||||
*/
|
||||
QOffscreenSurface::QOffscreenSurface(QScreen *targetScreen)
|
||||
: QObject(*new QOffscreenSurfacePrivate(), 0)
|
||||
, QSurface(Offscreen)
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
d->screen = targetScreen;
|
||||
if (!d->screen)
|
||||
d->screen = QGuiApplication::primaryScreen();
|
||||
|
||||
//if your applications aborts here, then chances are your creating a QOffscreenSurface before
|
||||
//the screen list is populated.
|
||||
Q_ASSERT(d->screen);
|
||||
|
||||
connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Destroys the offscreen surface.
|
||||
*/
|
||||
QOffscreenSurface::~QOffscreenSurface()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the surface type of the offscreen surface.
|
||||
|
||||
The surface type of an offscreen surface is always QSurface::OpenGLSurface.
|
||||
*/
|
||||
QOffscreenSurface::SurfaceType QOffscreenSurface::surfaceType() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return d->surfaceType;
|
||||
}
|
||||
|
||||
/*!
|
||||
Allocates the platform resources associated with the offscreen surface.
|
||||
|
||||
It is at this point that the surface format set using setFormat() gets resolved
|
||||
into an actual native surface.
|
||||
|
||||
Call destroy() to free the platform resources if necessary.
|
||||
|
||||
\sa destroy()
|
||||
*/
|
||||
void QOffscreenSurface::create()
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
if (!d->platformOffscreenSurface && !d->offscreenWindow) {
|
||||
d->platformOffscreenSurface = QGuiApplicationPrivate::platformIntegration()->createPlatformOffscreenSurface(this);
|
||||
// No platform offscreen surface, fallback to an invisible window
|
||||
if (!d->platformOffscreenSurface) {
|
||||
d->offscreenWindow = new QWindow(d->screen);
|
||||
d->offscreenWindow->setSurfaceType(QWindow::OpenGLSurface);
|
||||
d->offscreenWindow->setFormat(d->requestedFormat);
|
||||
d->offscreenWindow->setGeometry(0, 0, d->size.width(), d->size.height());
|
||||
d->offscreenWindow->create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Releases the native platform resources associated with this offscreen surface.
|
||||
|
||||
\sa create()
|
||||
*/
|
||||
void QOffscreenSurface::destroy()
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
delete d->platformOffscreenSurface;
|
||||
d->platformOffscreenSurface = 0;
|
||||
if (d->offscreenWindow) {
|
||||
d->offscreenWindow->destroy();
|
||||
delete d->offscreenWindow;
|
||||
d->offscreenWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if this offscreen surface is valid; otherwise returns \c false.
|
||||
|
||||
The offscreen surface is valid if the platform resources have been successfuly allocated.
|
||||
|
||||
\sa create()
|
||||
*/
|
||||
bool QOffscreenSurface::isValid() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return (d->platformOffscreenSurface && d->platformOffscreenSurface->isValid())
|
||||
|| (d->offscreenWindow && d->offscreenWindow->handle());
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the offscreen surface \a format.
|
||||
|
||||
The surface format will be resolved in the create() function. Calling
|
||||
this function after create() will not re-resolve the surface format of the native surface.
|
||||
|
||||
\sa create(), destroy()
|
||||
*/
|
||||
void QOffscreenSurface::setFormat(const QSurfaceFormat &format)
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
d->requestedFormat = format;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the requested surfaceformat of this offscreen surface.
|
||||
|
||||
If the requested format was not supported by the platform implementation,
|
||||
the requestedFormat will differ from the actual offscreen surface format.
|
||||
|
||||
This is the value set with setFormat().
|
||||
|
||||
\sa setFormat(), format()
|
||||
*/
|
||||
QSurfaceFormat QOffscreenSurface::requestedFormat() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return d->requestedFormat;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the actual format of this offscreen surface.
|
||||
|
||||
After the offscreen surface has been created, this function will return the actual
|
||||
surface format of the surface. It might differ from the requested format if the requested
|
||||
format could not be fulfilled by the platform.
|
||||
|
||||
\sa create(), requestedFormat()
|
||||
*/
|
||||
QSurfaceFormat QOffscreenSurface::format() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
if (d->platformOffscreenSurface)
|
||||
return d->platformOffscreenSurface->format();
|
||||
if (d->offscreenWindow)
|
||||
return d->offscreenWindow->format();
|
||||
return d->requestedFormat;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the size of the offscreen surface.
|
||||
*/
|
||||
QSize QOffscreenSurface::size() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return d->size;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the screen to which the offscreen surface is connected.
|
||||
|
||||
\sa setScreen()
|
||||
*/
|
||||
QScreen *QOffscreenSurface::screen() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return d->screen;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the screen to which the offscreen surface is connected.
|
||||
|
||||
If the offscreen surface has been created, it will be recreated on the \a newScreen.
|
||||
|
||||
\sa screen()
|
||||
*/
|
||||
void QOffscreenSurface::setScreen(QScreen *newScreen)
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
if (!newScreen)
|
||||
newScreen = QGuiApplication::primaryScreen();
|
||||
if (newScreen != d->screen) {
|
||||
const bool wasCreated = d->platformOffscreenSurface != 0 || d->offscreenWindow != 0;
|
||||
if (wasCreated)
|
||||
destroy();
|
||||
if (d->screen)
|
||||
disconnect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
|
||||
d->screen = newScreen;
|
||||
if (newScreen) {
|
||||
connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
|
||||
if (wasCreated)
|
||||
create();
|
||||
}
|
||||
emit screenChanged(newScreen);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Called when the offscreen surface's screen is destroyed.
|
||||
|
||||
\internal
|
||||
*/
|
||||
void QOffscreenSurface::screenDestroyed(QObject *object)
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
if (object == static_cast<QObject *>(d->screen))
|
||||
setScreen(0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QOffscreenSurface::screenChanged(QScreen *screen)
|
||||
|
||||
This signal is emitted when an offscreen surface's \a screen changes, either
|
||||
by being set explicitly with setScreen(), or automatically when
|
||||
the window's screen is removed.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns the platform offscreen surface corresponding to the offscreen surface.
|
||||
|
||||
\internal
|
||||
*/
|
||||
QPlatformOffscreenSurface *QOffscreenSurface::handle() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return d->platformOffscreenSurface;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the platform surface corresponding to the offscreen surface.
|
||||
|
||||
\internal
|
||||
*/
|
||||
QPlatformSurface *QOffscreenSurface::surfaceHandle() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
if (d->offscreenWindow)
|
||||
return d->offscreenWindow->handle();
|
||||
|
||||
return d->platformOffscreenSurface;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
98
src/gui/kernel/qoffscreensurface.h
Normal file
98
src/gui/kernel/qoffscreensurface.h
Normal file
@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module 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 QOFFSCREENSURFACE_H
|
||||
#define QOFFSCREENSURFACE_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/qsurface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QOffscreenSurfacePrivate;
|
||||
|
||||
class QScreen;
|
||||
class QPlatformOffscreenSurface;
|
||||
|
||||
class Q_GUI_EXPORT QOffscreenSurface : public QObject, public QSurface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QOffscreenSurface)
|
||||
|
||||
public:
|
||||
|
||||
explicit QOffscreenSurface(QScreen *screen = 0);
|
||||
virtual ~QOffscreenSurface();
|
||||
|
||||
SurfaceType surfaceType() const;
|
||||
|
||||
void create();
|
||||
void destroy();
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void setFormat(const QSurfaceFormat &format);
|
||||
QSurfaceFormat format() const;
|
||||
QSurfaceFormat requestedFormat() const;
|
||||
|
||||
QSize size() const;
|
||||
|
||||
QScreen *screen() const;
|
||||
void setScreen(QScreen *screen);
|
||||
|
||||
QPlatformOffscreenSurface *handle() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void screenChanged(QScreen *screen);
|
||||
|
||||
private Q_SLOTS:
|
||||
void screenDestroyed(QObject *screen);
|
||||
|
||||
private:
|
||||
|
||||
QPlatformSurface *surfaceHandle() const;
|
||||
|
||||
Q_DISABLE_COPY(QOffscreenSurface)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QOFFSCREENSURFACE_H
|
@ -360,4 +360,15 @@ class QPlatformTheme *QPlatformIntegration::createPlatformTheme(const QString &n
|
||||
return new QPlatformTheme;
|
||||
}
|
||||
|
||||
/*!
|
||||
Factory function for QOffscreenSurface. An offscreen surface will typically be implemented with a
|
||||
pixel buffer (pbuffer). If the platform doesn't support offscreen surfaces, an invisible window
|
||||
will be used by QOffscreenSurface instead.
|
||||
*/
|
||||
QPlatformOffscreenSurface *QPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
|
||||
{
|
||||
Q_UNUSED(surface)
|
||||
return 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -75,6 +75,8 @@ class QPlatformDialogHelper;
|
||||
class QPlatformSharedGraphicsCache;
|
||||
class QPlatformServices;
|
||||
class QKeyEvent;
|
||||
class QPlatformOffscreenSurface;
|
||||
class QOffscreenSurface;
|
||||
|
||||
class Q_GUI_EXPORT QPlatformIntegration
|
||||
{
|
||||
@ -146,6 +148,8 @@ public:
|
||||
virtual QStringList themeNames() const;
|
||||
virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
||||
virtual QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
|
||||
|
||||
protected:
|
||||
void screenAdded(QPlatformScreen *screen);
|
||||
};
|
||||
|
93
src/gui/kernel/qplatformoffscreensurface.cpp
Normal file
93
src/gui/kernel/qplatformoffscreensurface.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module 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 "qplatformoffscreensurface.h"
|
||||
|
||||
#include "qoffscreensurface.h"
|
||||
#include "qscreen.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPlatformOffscreenSurfacePrivate
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
QPlatformOffscreenSurface::QPlatformOffscreenSurface(QOffscreenSurface *offscreenSurface)
|
||||
: QPlatformSurface(offscreenSurface)
|
||||
, d_ptr(new QPlatformOffscreenSurfacePrivate)
|
||||
{
|
||||
}
|
||||
|
||||
QPlatformOffscreenSurface::~QPlatformOffscreenSurface()
|
||||
{
|
||||
}
|
||||
|
||||
QOffscreenSurface *QPlatformOffscreenSurface::offscreenSurface() const
|
||||
{
|
||||
return static_cast<QOffscreenSurface*>(m_surface);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the platform screen handle corresponding to this QPlatformOffscreenSurface.
|
||||
*/
|
||||
QPlatformScreen *QPlatformOffscreenSurface::screen() const
|
||||
{
|
||||
return offscreenSurface()->screen()->handle();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the actual surface format of the offscreen surface.
|
||||
*/
|
||||
QSurfaceFormat QPlatformOffscreenSurface::format() const
|
||||
{
|
||||
return QSurfaceFormat();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if the platform offscreen surface has been allocated.
|
||||
*/
|
||||
bool QPlatformOffscreenSurface::isValid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
85
src/gui/kernel/qplatformoffscreensurface.h
Normal file
85
src/gui/kernel/qplatformoffscreensurface.h
Normal file
@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtGui module 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 QPLATFORMOFFSCREENSURFACE_H
|
||||
#define QPLATFORMOFFSCREENSURFACE_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is part of the QPA API and is not meant to be used
|
||||
// in applications. Usage of this API may make your code
|
||||
// source and binary incompatible with future versions of Qt.
|
||||
//
|
||||
|
||||
#include "qplatformsurface.h"
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QOffscreenSurface;
|
||||
class QPlatformScreen;
|
||||
class QPlatformOffscreenSurfacePrivate;
|
||||
|
||||
class Q_GUI_EXPORT QPlatformOffscreenSurface : public QPlatformSurface
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QPlatformOffscreenSurface)
|
||||
public:
|
||||
explicit QPlatformOffscreenSurface(QOffscreenSurface *offscreenSurface);
|
||||
virtual ~QPlatformOffscreenSurface();
|
||||
|
||||
QOffscreenSurface *offscreenSurface() const;
|
||||
|
||||
QPlatformScreen *screen() const;
|
||||
|
||||
virtual QSurfaceFormat format() const;
|
||||
virtual bool isValid() const;
|
||||
|
||||
protected:
|
||||
QScopedPointer<QPlatformOffscreenSurfacePrivate> d_ptr;
|
||||
private:
|
||||
Q_DISABLE_COPY(QPlatformOffscreenSurface)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QPLATFORMOFFSCREENSURFACE_H
|
@ -72,6 +72,7 @@ private:
|
||||
QSurface *m_surface;
|
||||
|
||||
friend class QPlatformWindow;
|
||||
friend class QPlatformOffscreenSurface;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
|
||||
The SurfaceClass enum describes the actual subclass of the surface.
|
||||
|
||||
\value Window The surface is an instance of QWindow.
|
||||
\value Offscreen The surface is an instance of QOffscreenSurface.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -58,7 +58,8 @@ class Q_GUI_EXPORT QSurface
|
||||
{
|
||||
public:
|
||||
enum SurfaceClass {
|
||||
Window
|
||||
Window,
|
||||
Offscreen
|
||||
};
|
||||
|
||||
enum SurfaceType {
|
||||
|
@ -1,10 +1,12 @@
|
||||
contains(QT_CONFIG,egl) {
|
||||
HEADERS += \
|
||||
$$PWD/qeglconvenience_p.h \
|
||||
$$PWD/qeglplatformcontext_p.h
|
||||
$$PWD/qeglplatformcontext_p.h \
|
||||
$$PWD/qeglpbuffer_p.h
|
||||
SOURCES += \
|
||||
$$PWD/qeglconvenience.cpp \
|
||||
$$PWD/qeglplatformcontext.cpp
|
||||
$$PWD/qeglplatformcontext.cpp \
|
||||
$$PWD/qeglpbuffer.cpp
|
||||
|
||||
contains(QT_CONFIG,xlib) {
|
||||
HEADERS += \
|
||||
|
76
src/platformsupport/eglconvenience/qeglpbuffer.cpp
Normal file
76
src/platformsupport/eglconvenience/qeglpbuffer.cpp
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
#include "qeglpbuffer_p.h"
|
||||
#include "qeglconvenience_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
|
||||
: QPlatformOffscreenSurface(offscreenSurface)
|
||||
, m_format(format)
|
||||
, m_display(display)
|
||||
, m_pbuffer(EGL_NO_SURFACE)
|
||||
{
|
||||
EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT);
|
||||
|
||||
if (config) {
|
||||
const EGLint attributes[] = {
|
||||
EGL_WIDTH, offscreenSurface->size().width(),
|
||||
EGL_HEIGHT, offscreenSurface->size().height(),
|
||||
EGL_LARGEST_PBUFFER, EGL_FALSE,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
m_pbuffer = eglCreatePbufferSurface(m_display, config, attributes);
|
||||
|
||||
if (m_pbuffer != EGL_NO_SURFACE)
|
||||
m_format = q_glFormatFromConfig(m_display, config);
|
||||
}
|
||||
}
|
||||
|
||||
QEGLPbuffer::~QEGLPbuffer()
|
||||
{
|
||||
eglDestroySurface(m_display, m_pbuffer);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
69
src/platformsupport/eglconvenience/qeglpbuffer_p.h
Normal file
69
src/platformsupport/eglconvenience/qeglpbuffer_p.h
Normal file
@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QEGLPBUFFER_H
|
||||
#define QEGLPBUFFER_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <qpa/qplatformoffscreensurface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QEGLPbuffer : public QPlatformOffscreenSurface
|
||||
{
|
||||
public:
|
||||
QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface);
|
||||
~QEGLPbuffer();
|
||||
|
||||
QSurfaceFormat format() const { return m_format; }
|
||||
bool isValid() const { return m_pbuffer != EGL_NO_SURFACE; }
|
||||
|
||||
EGLSurface pbuffer() const { return m_pbuffer; }
|
||||
|
||||
private:
|
||||
QSurfaceFormat m_format;
|
||||
EGLDisplay m_display;
|
||||
EGLSurface m_pbuffer;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QEGLPBUFFER_H
|
@ -45,6 +45,8 @@
|
||||
#include "qeglfshooks.h"
|
||||
#include "qeglfsintegration.h"
|
||||
|
||||
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
|
||||
#include <QtGui/QSurface>
|
||||
#include <QtDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -62,16 +64,20 @@ bool QEglFSContext::makeCurrent(QPlatformSurface *surface)
|
||||
|
||||
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||
{
|
||||
QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
|
||||
return window->surface();
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window)
|
||||
return static_cast<QEglFSWindow *>(surface)->surface();
|
||||
else
|
||||
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
|
||||
}
|
||||
|
||||
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();
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
||||
QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
|
||||
// draw the cursor
|
||||
if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(window->screen()->cursor()))
|
||||
cursor->paintOnScreen();
|
||||
}
|
||||
|
||||
QEGLPlatformContext::swapBuffers(surface);
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
|
||||
#include <QtPlatformSupport/private/qeglconvenience_p.h>
|
||||
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
|
||||
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
|
||||
|
||||
#if !defined(QT_NO_EVDEV)
|
||||
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
|
||||
@ -62,6 +63,7 @@
|
||||
#include <QtGui/QSurfaceFormat>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
#include <qpa/qplatformcursor.h>
|
||||
|
||||
#include "qeglfscontext.h"
|
||||
@ -154,6 +156,12 @@ QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLCo
|
||||
return new QEglFSContext(hooks->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay);
|
||||
}
|
||||
|
||||
QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
|
||||
{
|
||||
QEglFSScreen *screen = static_cast<QEglFSScreen *>(surface->screen()->handle());
|
||||
return new QEGLPbuffer(screen->display(), hooks->surfaceFormatFor(surface->requestedFormat()), surface);
|
||||
}
|
||||
|
||||
QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
|
||||
{
|
||||
return mFontDb;
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const;
|
||||
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
|
||||
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
|
||||
QPlatformNativeInterface *nativeInterface() const;
|
||||
|
||||
QPlatformFontDatabase *fontDatabase() const;
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
|
||||
#include "qglxintegration.h"
|
||||
#include <QtPlatformSupport/private/qglxconvenience_p.h>
|
||||
@ -270,6 +271,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
|
||||
, m_screen(screen)
|
||||
, m_context(0)
|
||||
, m_format(format)
|
||||
, m_isPBufferCurrent(false)
|
||||
{
|
||||
m_shareContext = 0;
|
||||
if (share)
|
||||
@ -390,19 +392,35 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
|
||||
{
|
||||
Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
|
||||
|
||||
GLXDrawable glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
|
||||
|
||||
return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxDrawable, m_context);
|
||||
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
|
||||
if (surfaceClass == QSurface::Window) {
|
||||
m_isPBufferCurrent = false;
|
||||
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
|
||||
return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), window->xcb_window(), m_context);
|
||||
} else if (surfaceClass == QSurface::Offscreen) {
|
||||
m_isPBufferCurrent = true;
|
||||
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
|
||||
return glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), pbuffer->pbuffer(), pbuffer->pbuffer(), m_context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void QGLXContext::doneCurrent()
|
||||
{
|
||||
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
|
||||
if (m_isPBufferCurrent)
|
||||
glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0, 0);
|
||||
else
|
||||
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
|
||||
m_isPBufferCurrent = false;
|
||||
}
|
||||
|
||||
void QGLXContext::swapBuffers(QPlatformSurface *surface)
|
||||
{
|
||||
GLXDrawable glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
|
||||
GLXDrawable glxDrawable = 0;
|
||||
if (surface->surface()->surfaceClass() == QSurface::Offscreen)
|
||||
glxDrawable = static_cast<QGLXPbuffer *>(surface)->pbuffer();
|
||||
else
|
||||
glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
|
||||
glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable);
|
||||
}
|
||||
|
||||
@ -454,4 +472,36 @@ bool QGLXContext::isValid() const
|
||||
return m_context != 0;
|
||||
}
|
||||
|
||||
|
||||
QGLXPbuffer::QGLXPbuffer(QOffscreenSurface *offscreenSurface)
|
||||
: QPlatformOffscreenSurface(offscreenSurface)
|
||||
, m_format(offscreenSurface->requestedFormat())
|
||||
, m_screen(static_cast<QXcbScreen *>(offscreenSurface->screen()->handle()))
|
||||
, m_pbuffer(0)
|
||||
{
|
||||
GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), m_format);
|
||||
|
||||
if (config) {
|
||||
const int attributes[] = {
|
||||
GLX_PBUFFER_WIDTH, offscreenSurface->size().width(),
|
||||
GLX_PBUFFER_HEIGHT, offscreenSurface->size().height(),
|
||||
GLX_LARGEST_PBUFFER, False,
|
||||
GLX_PRESERVED_CONTENTS, False,
|
||||
GLX_NONE
|
||||
};
|
||||
|
||||
m_pbuffer = glXCreatePbuffer(DISPLAY_FROM_XCB(m_screen), config, attributes);
|
||||
|
||||
if (m_pbuffer)
|
||||
m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(m_screen), config);
|
||||
}
|
||||
}
|
||||
|
||||
QGLXPbuffer::~QGLXPbuffer()
|
||||
{
|
||||
if (m_pbuffer)
|
||||
glXDestroyPbuffer(DISPLAY_FROM_XCB(m_screen), m_pbuffer);
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "qxcbscreen.h"
|
||||
|
||||
#include <qpa/qplatformopenglcontext.h>
|
||||
#include <qpa/qplatformoffscreensurface.h>
|
||||
#include <QtGui/QSurfaceFormat>
|
||||
|
||||
#include <QtCore/QMutex>
|
||||
@ -89,6 +90,25 @@ private:
|
||||
GLXContext m_context;
|
||||
GLXContext m_shareContext;
|
||||
QSurfaceFormat m_format;
|
||||
bool m_isPBufferCurrent;
|
||||
};
|
||||
|
||||
|
||||
class QGLXPbuffer : public QPlatformOffscreenSurface
|
||||
{
|
||||
public:
|
||||
explicit QGLXPbuffer(QOffscreenSurface *offscreenSurface);
|
||||
~QGLXPbuffer();
|
||||
|
||||
QSurfaceFormat format() const { return m_format; }
|
||||
bool isValid() const { return m_pbuffer != 0; }
|
||||
|
||||
GLXPbuffer pbuffer() const { return m_pbuffer; }
|
||||
|
||||
private:
|
||||
QSurfaceFormat m_format;
|
||||
QXcbScreen *m_screen;
|
||||
GLXPbuffer m_pbuffer;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -78,10 +78,12 @@
|
||||
#elif defined(XCB_USE_EGL)
|
||||
#include "qxcbeglsurface.h"
|
||||
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
|
||||
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
|
||||
#endif
|
||||
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
#include <qpa/qplatformaccessibility.h>
|
||||
#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE
|
||||
@ -168,7 +170,10 @@ public:
|
||||
|
||||
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||
{
|
||||
return static_cast<QXcbWindow *>(surface)->eglSurface()->surface();
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window)
|
||||
return static_cast<QXcbWindow *>(surface)->eglSurface()->surface();
|
||||
else
|
||||
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -205,6 +210,20 @@ QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *wind
|
||||
return new QXcbBackingStore(window);
|
||||
}
|
||||
|
||||
QPlatformOffscreenSurface *QXcbIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
|
||||
{
|
||||
#if defined(XCB_USE_GLX)
|
||||
return new QGLXPbuffer(surface);
|
||||
#elif defined(XCB_USE_EGL)
|
||||
QXcbScreen *screen = static_cast<QXcbScreen *>(surface->screen()->handle());
|
||||
return new QEGLPbuffer(screen->connection()->egl_display(), surface->requestedFormat(), surface);
|
||||
#else
|
||||
Q_UNUSED(surface);
|
||||
qWarning("QXcbIntegration: Cannot create platform offscreen surface, neither GLX nor EGL are enabled");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
|
||||
{
|
||||
switch (cap) {
|
||||
|
@ -68,6 +68,8 @@ public:
|
||||
#endif
|
||||
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
|
||||
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
|
||||
|
||||
bool hasCapability(Capability cap) const;
|
||||
QAbstractEventDispatcher *guiThreadEventDispatcher() const;
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
@ -57,12 +58,18 @@ class tst_QOpenGL : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void sharedResourceCleanup_data();
|
||||
void sharedResourceCleanup();
|
||||
void multiGroupSharedResourceCleanup_data();
|
||||
void multiGroupSharedResourceCleanup();
|
||||
void multiGroupSharedResourceCleanupCustom_data();
|
||||
void multiGroupSharedResourceCleanupCustom();
|
||||
void fboSimpleRendering_data();
|
||||
void fboSimpleRendering();
|
||||
void fboRendering_data();
|
||||
void fboRendering();
|
||||
void fboHandleNulledAfterContextDestroyed();
|
||||
void openGLPaintDevice_data();
|
||||
void openGLPaintDevice();
|
||||
void aboutToBeDestroyed();
|
||||
void QTBUG15621_triangulatingStrokerDivZero();
|
||||
@ -129,16 +136,43 @@ struct SharedResource : public QOpenGLSharedResource
|
||||
SharedResourceTracker *tracker;
|
||||
};
|
||||
|
||||
static QSurface *createSurface(int surfaceClass)
|
||||
{
|
||||
if (surfaceClass == int(QSurface::Window)) {
|
||||
QWindow *window = new QWindow;
|
||||
window->setSurfaceType(QWindow::OpenGLSurface);
|
||||
window->setGeometry(0, 0, 10, 10);
|
||||
window->create();
|
||||
return window;
|
||||
} else if (surfaceClass == int(QSurface::Offscreen)) {
|
||||
QOffscreenSurface *offscreenSurface = new QOffscreenSurface;
|
||||
offscreenSurface->create();
|
||||
return offscreenSurface;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void common_data()
|
||||
{
|
||||
QTest::addColumn<int>("surfaceClass");
|
||||
|
||||
QTest::newRow("Using QWindow") << int(QSurface::Window);
|
||||
QTest::newRow("Using QOffscreenSurface") << int(QSurface::Offscreen);
|
||||
}
|
||||
|
||||
void tst_QOpenGL::sharedResourceCleanup_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QOpenGL::sharedResourceCleanup()
|
||||
{
|
||||
QWindow window;
|
||||
window.setSurfaceType(QWindow::OpenGLSurface);
|
||||
window.setGeometry(0, 0, 10, 10);
|
||||
window.create();
|
||||
QFETCH(int, surfaceClass);
|
||||
QScopedPointer<QSurface> surface(createSurface(surfaceClass));
|
||||
|
||||
QOpenGLContext *ctx = new QOpenGLContext;
|
||||
ctx->create();
|
||||
ctx->makeCurrent(&window);
|
||||
ctx->makeCurrent(surface.data());
|
||||
|
||||
SharedResourceTracker tracker;
|
||||
SharedResource *resource = new SharedResource(&tracker);
|
||||
@ -165,7 +199,7 @@ void tst_QOpenGL::sharedResourceCleanup()
|
||||
QCOMPARE(tracker.freeResourceCalls, 0);
|
||||
QCOMPARE(tracker.destructorCalls, 0);
|
||||
|
||||
ctx2->makeCurrent(&window);
|
||||
ctx2->makeCurrent(surface.data());
|
||||
|
||||
// freeResource() should now have been called
|
||||
QCOMPARE(tracker.invalidateResourceCalls, 0);
|
||||
@ -192,17 +226,20 @@ void tst_QOpenGL::sharedResourceCleanup()
|
||||
QCOMPARE(tracker.destructorCalls, 1);
|
||||
}
|
||||
|
||||
void tst_QOpenGL::multiGroupSharedResourceCleanup_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QOpenGL::multiGroupSharedResourceCleanup()
|
||||
{
|
||||
QWindow window;
|
||||
window.setSurfaceType(QWindow::OpenGLSurface);
|
||||
window.setGeometry(0, 0, 10, 10);
|
||||
window.create();
|
||||
QFETCH(int, surfaceClass);
|
||||
QScopedPointer<QSurface> surface(createSurface(surfaceClass));
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
QOpenGLContext *gl = new QOpenGLContext();
|
||||
gl->create();
|
||||
gl->makeCurrent(&window);
|
||||
gl->makeCurrent(surface.data());
|
||||
{
|
||||
// Cause QOpenGLMultiGroupSharedResource instantiation.
|
||||
QOpenGLFunctions func(gl);
|
||||
@ -214,16 +251,19 @@ void tst_QOpenGL::multiGroupSharedResourceCleanup()
|
||||
// Shouldn't crash when application exits.
|
||||
}
|
||||
|
||||
void tst_QOpenGL::multiGroupSharedResourceCleanupCustom_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QOpenGL::multiGroupSharedResourceCleanupCustom()
|
||||
{
|
||||
QWindow window;
|
||||
window.setSurfaceType(QWindow::OpenGLSurface);
|
||||
window.setGeometry(0, 0, 10, 10);
|
||||
window.create();
|
||||
QFETCH(int, surfaceClass);
|
||||
QScopedPointer<QSurface> surface(createSurface(surfaceClass));
|
||||
|
||||
QOpenGLContext *ctx = new QOpenGLContext();
|
||||
ctx->create();
|
||||
ctx->makeCurrent(&window);
|
||||
ctx->makeCurrent(surface.data());
|
||||
|
||||
QOpenGLMultiGroupSharedResource multiGroupSharedResource;
|
||||
SharedResource *resource = multiGroupSharedResource.value<SharedResource>(ctx);
|
||||
@ -350,17 +390,20 @@ void qt_opengl_check_test_pattern(const QImage& img)
|
||||
QFUZZY_COMPARE_PIXELS(img.pixel(192, 64), QColor(Qt::green).rgb());
|
||||
}
|
||||
|
||||
void tst_QOpenGL::fboSimpleRendering_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QOpenGL::fboSimpleRendering()
|
||||
{
|
||||
QWindow window;
|
||||
window.setSurfaceType(QWindow::OpenGLSurface);
|
||||
window.setGeometry(0, 0, 10, 10);
|
||||
window.create();
|
||||
QFETCH(int, surfaceClass);
|
||||
QScopedPointer<QSurface> surface(createSurface(surfaceClass));
|
||||
|
||||
QOpenGLContext ctx;
|
||||
ctx.create();
|
||||
|
||||
ctx.makeCurrent(&window);
|
||||
ctx.makeCurrent(surface.data());
|
||||
|
||||
if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects())
|
||||
QSKIP("QOpenGLFramebufferObject not supported on this platform");
|
||||
@ -386,6 +429,11 @@ void tst_QOpenGL::fboSimpleRendering()
|
||||
delete fbo;
|
||||
}
|
||||
|
||||
void tst_QOpenGL::fboRendering_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
// NOTE: This tests that CombinedDepthStencil attachment works by assuming the
|
||||
// GL2 engine is being used and is implemented the same way as it was when
|
||||
// this autotest was written. If this is not the case, there may be some
|
||||
@ -397,14 +445,13 @@ void tst_QOpenGL::fboRendering()
|
||||
QSKIP("QTBUG-22617");
|
||||
#endif
|
||||
|
||||
QWindow window;
|
||||
window.setSurfaceType(QWindow::OpenGLSurface);
|
||||
window.setGeometry(0, 0, 10, 10);
|
||||
window.create();
|
||||
QFETCH(int, surfaceClass);
|
||||
QScopedPointer<QSurface> surface(createSurface(surfaceClass));
|
||||
|
||||
QOpenGLContext ctx;
|
||||
ctx.create();
|
||||
|
||||
ctx.makeCurrent(&window);
|
||||
ctx.makeCurrent(surface.data());
|
||||
|
||||
if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects())
|
||||
QSKIP("QOpenGLFramebufferObject not supported on this platform");
|
||||
@ -461,16 +508,19 @@ void tst_QOpenGL::fboHandleNulledAfterContextDestroyed()
|
||||
QCOMPARE(fbo->handle(), 0U);
|
||||
}
|
||||
|
||||
void tst_QOpenGL::openGLPaintDevice_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QOpenGL::openGLPaintDevice()
|
||||
{
|
||||
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__)
|
||||
QSKIP("QTBUG-22617");
|
||||
#endif
|
||||
|
||||
QWindow window;
|
||||
window.setSurfaceType(QWindow::OpenGLSurface);
|
||||
window.setGeometry(0, 0, 128, 128);
|
||||
window.create();
|
||||
QFETCH(int, surfaceClass);
|
||||
QScopedPointer<QSurface> surface(createSurface(surfaceClass));
|
||||
|
||||
QOpenGLContext ctx;
|
||||
ctx.create();
|
||||
@ -478,7 +528,7 @@ void tst_QOpenGL::openGLPaintDevice()
|
||||
QSurfaceFormat format = ctx.format();
|
||||
if (format.majorVersion() < 2)
|
||||
QSKIP("This test requires at least OpenGL 2.0");
|
||||
ctx.makeCurrent(&window);
|
||||
ctx.makeCurrent(surface.data());
|
||||
|
||||
QImage image(128, 128, QImage::Format_RGB32);
|
||||
QPainter p(&image);
|
||||
|
Loading…
Reference in New Issue
Block a user