Add an option to share between TLWs

Task-number: QTBUG-41191
Change-Id: I510d1631926ed0d9e371703d22229aed92432aa6
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
Laszlo Agocs 2014-09-09 10:06:45 +02:00
parent 162010441f
commit 2f96fb1bee
7 changed files with 78 additions and 9 deletions

View File

@ -527,6 +527,7 @@ public:
AA_UseDesktopOpenGL = 15,
AA_UseOpenGLES = 16,
AA_UseSoftwareOpenGL = 17,
AA_ShareOpenGLContexts = 18,
// Add new attributes before this line
AA_AttributeCount

View File

@ -188,6 +188,11 @@
instance \l{Qt for Windows}, for more information. This value has
been added in Qt 5.4.
\value AA_ShareOpenGLContexts Enables resource sharing between the OpenGL
contexts used by classes like QOpenGLWidget and QQuickWidget. This
allows sharing OpenGL resources, like textures, between QOpenGLWidget
instances that belong to different top-level windows.
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully

View File

@ -82,6 +82,7 @@
#include <qpa/qwindowsysteminterface_p.h>
#include "private/qwindow_p.h"
#include "private/qcursor_p.h"
#include "private/qopenglcontext_p.h"
#include "private/qdnd_p.h"
#include <qpa/qplatformthemefactory_p.h>
@ -604,7 +605,8 @@ QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags
: QCoreApplicationPrivate(argc, argv, flags),
styleHints(0),
inputMethod(0),
lastTouchType(QEvent::TouchEnd)
lastTouchType(QEvent::TouchEnd),
ownGlobalShareContext(false)
{
self = this;
application_type = QCoreApplicationPrivate::Gui;
@ -1313,6 +1315,17 @@ void QGuiApplicationPrivate::init()
// trigger registering of animation interpolators
qRegisterGuiGetInterpolator();
// set a global share context when enabled unless there is already one
#ifndef QT_NO_OPENGL
if (qApp->testAttribute(Qt::AA_ShareOpenGLContexts) && !qt_gl_global_share_context()) {
QOpenGLContext *ctx = new QOpenGLContext;
ctx->setFormat(QSurfaceFormat::defaultFormat());
ctx->create();
qt_gl_set_global_share_context(ctx);
ownGlobalShareContext = true;
}
#endif
QWindowSystemInterfacePrivate::eventTime.start();
is_app_running = true;
@ -1374,6 +1387,13 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
QPixmapCache::clear();
#ifndef QT_NO_OPENGL
if (ownGlobalShareContext) {
delete qt_gl_global_share_context();
qt_gl_set_global_share_context(0);
}
#endif
delete platform_theme;
platform_theme = 0;
delete platform_integration;

View File

@ -307,6 +307,8 @@ private:
static QTouchDevice *m_fakeTouchDevice;
static int m_fakeMouseSourcePointId;
QAtomicPointer<QDrawHelperGammaTables> m_gammaTables;
bool ownGlobalShareContext;
};
Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);

View File

@ -245,8 +245,9 @@ QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex;
/*!
\internal
This function is used by the Qt WebEngine to set up context sharing
across multiple windows. Do not use it for any other purpose.
This function is used by Qt::AA_ShareOpenGLContexts and the Qt
WebEngine to set up context sharing across multiple windows. Do
not use it for any other purpose.
Please maintain the binary compatibility of these functions.
*/

View File

@ -297,6 +297,18 @@ QT_BEGIN_NAMESPACE
sharable resources, like textures, and there is no need for an extra "global
share" context, as was the case with QGLWidget.
To set up sharing between QOpenGLWidget instances belonging to different
windows, set the Qt::AA_ShareOpenGLContexts application attribute before
instantiating QApplication. This will trigger sharing between all
QOpenGLWidget instances without any further steps.
Creating extra QOpenGLContext instances that share resources like textures
with the QOpenGLWidget's context is also possible. Simply pass the pointer
returned from context() to QOpenGLContext::setShareContext() before calling
QOpenGLContext::create(). The resulting context can also be used on a
different thread, allowing threaded generation of textures and asynchronous
texture uploads.
Note that QOpenGLWidget expects a standard conformant implementation of
resource sharing when it comes to the underlying graphics drivers. For
example, some drivers, in particular for mobile and embedded hardware, have
@ -359,11 +371,12 @@ QT_BEGIN_NAMESPACE
each QOpenGLWidget's associated context is destroyed together with the
QOpenGLWidget, the sharable resources in that context, like textures, will
stay valid until the top-level window, in which the QOpenGLWidget lived, is
destroyed. Additionally, some Qt modules may trigger an even wider scope for
sharing contexts, potentially leading to keeping the resources in question
alive for the entire lifetime of the application. Therefore the safest and
most robust is always to perform explicit cleanup for all resources and
resource wrappers used in the QOpenGLWidget.
destroyed. Additionally, settings like Qt::AA_ShareOpenGLContexts and some Qt
modules may trigger an even wider scope for sharing contexts, potentially
leading to keeping the resources in question alive for the entire lifetime of
the application. Therefore the safest and most robust is always to perform
explicit cleanup for all resources and resource wrappers used in the
QOpenGLWidget.
\section1 Limitations
@ -388,7 +401,7 @@ QT_BEGIN_NAMESPACE
\e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other
countries.}
\sa QOpenGLFunctions, QOpenGLWindow
\sa QOpenGLFunctions, QOpenGLWindow, Qt::AA_ShareOpenGLContexts
*/
/*!

View File

@ -53,6 +53,8 @@
#include <QOpenGLContext>
#endif
#include <QtGui/private/qopenglcontext_p.h>
#include <QDebug>
#include "tst_qcoreapplication.h"
@ -79,6 +81,7 @@ private slots:
void quitOnLastWindowClosed();
void genericPluginsAndWindowSystemEvents();
void layoutDirection();
void globalShareContext();
};
void tst_QGuiApplication::cleanup()
@ -915,4 +918,28 @@ void tst_QGuiApplication::layoutDirection()
QCOMPARE(signalSpy.count(), 1);
}
void tst_QGuiApplication::globalShareContext()
{
#ifndef QT_NO_OPENGL
// Test that there is a global share context when requested.
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
int argc = 1;
char *argv[] = { const_cast<char*>("tst_qguiapplication") };
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
QOpenGLContext *ctx = qt_gl_global_share_context();
QVERIFY(ctx);
app.reset();
ctx = qt_gl_global_share_context();
QVERIFY(!ctx);
// Test that there is no global share context by default.
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, false);
app.reset(new QGuiApplication(argc, argv));
ctx = qt_gl_global_share_context();
QVERIFY(!ctx);
#else
QSKIP("No OpenGL support");
#endif
}
QTEST_APPLESS_MAIN(tst_QGuiApplication)