diff options
-rw-r--r-- | src/corelib/global/qnamespace.h | 1 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 5 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 22 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 5 | ||||
-rw-r--r-- | src/widgets/kernel/qopenglwidget.cpp | 25 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp | 27 |
7 files changed, 78 insertions, 9 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 0da868602c..8437eb0469 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -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 diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f6ea3a3a81..8dca48d80d 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -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 diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 2d7900b5d9..75311616a4 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -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; diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 5f9f6ad9f2..0fd4458083 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -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); diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 6b2bb092b1..be8fa2415d 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -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. */ diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 3dae22cdc7..8f7751618d 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -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 */ /*! diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 2ce9dca153..1d6df973ed 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -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) |