Lazily create global share context when Qt::AA_ShareOpenGLContexts is set
The requirement to set Qt::AA_ShareOpenGLContexts before creating QGuiApp was forcing users to also set the default surface format before QGuiApp, which prevents us from initializing a default surface format based on the platform integration. By creating the global share context lazily when requested via the Qt::AA_ShareOpenGLContext application attribute we open up this possibility. Change-Id: I958639c997e96321013b1080c31e2533a36c13ff Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
868fc456ac
commit
4a7ccb65f0
@ -1013,7 +1013,6 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
|
||||
case Qt::AA_UseDesktopOpenGL:
|
||||
case Qt::AA_UseOpenGLES:
|
||||
case Qt::AA_UseSoftwareOpenGL:
|
||||
case Qt::AA_ShareOpenGLContexts:
|
||||
#ifdef QT_BOOTSTRAPPED
|
||||
qWarning("Attribute %d must be set before QCoreApplication is created.",
|
||||
attribute);
|
||||
|
@ -727,8 +727,7 @@ QGuiApplication::~QGuiApplication()
|
||||
QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv)
|
||||
: QCoreApplicationPrivate(argc, argv),
|
||||
inputMethod(nullptr),
|
||||
lastTouchType(QEvent::TouchEnd),
|
||||
ownGlobalShareContext(false)
|
||||
lastTouchType(QEvent::TouchEnd)
|
||||
{
|
||||
self = this;
|
||||
application_type = QCoreApplicationPrivate::Gui;
|
||||
@ -1740,17 +1739,6 @@ void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::init()
|
||||
qRegisterGuiGetInterpolator();
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
|
@ -342,6 +342,10 @@ public:
|
||||
|
||||
static QThreadPool *qtGuiThreadPool();
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
bool ownGlobalShareContext = false;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void handleThemeChanged();
|
||||
|
||||
@ -366,8 +370,6 @@ private:
|
||||
#endif
|
||||
std::shared_ptr<QColorTrcLut> m_a32ColorProfile;
|
||||
|
||||
bool ownGlobalShareContext;
|
||||
|
||||
static QInputDeviceManager *m_inputDeviceManager;
|
||||
|
||||
// Cache the maximum device pixel ratio, to iterate through the screen list
|
||||
|
@ -959,10 +959,6 @@ bool QOpenGLContext::supportsThreadedOpenGL()
|
||||
This is useful if you need to upload OpenGL objects (buffers, textures,
|
||||
etc.) before creating or showing a QOpenGLWidget or QQuickWidget.
|
||||
|
||||
\note You must set the Qt::AA_ShareOpenGLContexts flag on QGuiApplication
|
||||
before creating the QGuiApplication object, otherwise Qt may not create a
|
||||
global shared context.
|
||||
|
||||
\warning Do not attempt to make the context returned by this function
|
||||
current on any surface. Instead, you can create a new context which shares
|
||||
with the global one, and then make the new context current.
|
||||
@ -972,6 +968,14 @@ bool QOpenGLContext::supportsThreadedOpenGL()
|
||||
QOpenGLContext *QOpenGLContext::globalShareContext()
|
||||
{
|
||||
Q_ASSERT(qGuiApp);
|
||||
// Lazily create a global share context when enabled unless there is already one
|
||||
if (!qt_gl_global_share_context() && qGuiApp->testAttribute(Qt::AA_ShareOpenGLContexts)) {
|
||||
QOpenGLContext *ctx = new QOpenGLContext;
|
||||
ctx->setFormat(QSurfaceFormat::defaultFormat());
|
||||
ctx->create();
|
||||
qt_gl_set_global_share_context(ctx);
|
||||
QGuiApplicationPrivate::instance()->ownGlobalShareContext = true;
|
||||
}
|
||||
return qt_gl_global_share_context();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include <QtGui/qcolorspace.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
#include <QtGui/private/qopenglcontext_p.h>
|
||||
#endif
|
||||
|
||||
#ifdef major
|
||||
#undef major
|
||||
#endif
|
||||
@ -807,12 +811,6 @@ Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format)
|
||||
and surfaces, even the ones created internally by Qt, will use the same
|
||||
format.
|
||||
|
||||
\note When setting Qt::AA_ShareOpenGLContexts, it is strongly recommended to
|
||||
place the call to this function before the construction of the
|
||||
QGuiApplication or QApplication. Otherwise \a format will not be applied to
|
||||
the global share context and therefore issues may arise with context sharing
|
||||
afterwards.
|
||||
|
||||
\since 5.4
|
||||
\sa defaultFormat()
|
||||
*/
|
||||
@ -820,7 +818,7 @@ void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format)
|
||||
{
|
||||
#ifndef QT_NO_OPENGL
|
||||
if (qApp) {
|
||||
QOpenGLContext *globalContext = QOpenGLContext::globalShareContext();
|
||||
QOpenGLContext *globalContext = qt_gl_global_share_context();
|
||||
if (globalContext && globalContext->isValid()) {
|
||||
qWarning("Warning: Setting a new default format with a different version or profile "
|
||||
"after the global shared context is created may cause issues with context "
|
||||
|
@ -74,7 +74,7 @@ bool QBackingStoreRhiSupport::create()
|
||||
params.fallbackSurface = surface;
|
||||
params.window = m_window;
|
||||
params.format = m_format;
|
||||
params.shareContext = qt_gl_global_share_context();
|
||||
params.shareContext = QOpenGLContext::globalShareContext();
|
||||
rhi = QRhi::create(QRhi::OpenGLES2, ¶ms, flags);
|
||||
}
|
||||
#endif
|
||||
|
@ -771,7 +771,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
|
||||
if (maybeShareContext) {
|
||||
ctx->setShareContext(maybeShareContext);
|
||||
ctx->setScreen(maybeShareContext->screen());
|
||||
} else if (QOpenGLContext *shareContext = qt_gl_global_share_context()) {
|
||||
} else if (QOpenGLContext *shareContext = QOpenGLContext::globalShareContext()) {
|
||||
ctx->setShareContext(shareContext);
|
||||
ctx->setScreen(shareContext->screen());
|
||||
} else if (maybeWindow) {
|
||||
|
@ -161,7 +161,7 @@ public:
|
||||
, shareContext(shareContext)
|
||||
{
|
||||
if (!shareContext)
|
||||
this->shareContext = qt_gl_global_share_context();
|
||||
this->shareContext = QOpenGLContext::globalShareContext();
|
||||
}
|
||||
|
||||
~QOpenGLWindowPrivate();
|
||||
|
@ -856,7 +856,7 @@ void QOpenGLWidgetPrivate::initialize()
|
||||
context = new QOpenGLContext;
|
||||
context->setFormat(requestedFormat);
|
||||
|
||||
QOpenGLContext *shareContext = contextFromRhi ? contextFromRhi : qt_gl_global_share_context();
|
||||
QOpenGLContext *shareContext = contextFromRhi ? contextFromRhi : QOpenGLContext::globalShareContext();
|
||||
if (shareContext) {
|
||||
context->setShareContext(shareContext);
|
||||
context->setScreen(shareContext->screen());
|
||||
|
@ -108,14 +108,14 @@ void QEglFSWindow::setBackingStore(QOpenGLCompositorBackingStore *backingStore)
|
||||
#ifndef QT_NO_OPENGL
|
||||
if (!m_rasterCompositingContext) {
|
||||
m_rasterCompositingContext = new QOpenGLContext;
|
||||
m_rasterCompositingContext->setShareContext(qt_gl_global_share_context());
|
||||
m_rasterCompositingContext->setShareContext(QOpenGLContext::globalShareContext());
|
||||
m_rasterCompositingContext->setFormat(m_format);
|
||||
m_rasterCompositingContext->setScreen(window()->screen());
|
||||
if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
|
||||
qFatal("EGLFS: Failed to create compositing context");
|
||||
// If there is a "root" window into which raster and QOpenGLWidget content is
|
||||
// composited, all other contexts must share with its context.
|
||||
if (!qt_gl_global_share_context())
|
||||
if (!QOpenGLContext::globalShareContext())
|
||||
qt_gl_set_global_share_context(m_rasterCompositingContext);
|
||||
}
|
||||
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
|
||||
@ -145,7 +145,7 @@ void QEglFSWindow::destroy()
|
||||
|
||||
if (compositor->windows().isEmpty()) {
|
||||
compositor->destroy();
|
||||
if (qt_gl_global_share_context() == m_rasterCompositingContext)
|
||||
if (QOpenGLContext::globalShareContext() == m_rasterCompositingContext)
|
||||
qt_gl_set_global_share_context(nullptr);
|
||||
delete m_rasterCompositingContext;
|
||||
} else {
|
||||
|
@ -1273,7 +1273,7 @@ void tst_QGuiApplication::globalShareContext()
|
||||
int argc = 1;
|
||||
char *argv[] = { const_cast<char*>("tst_qguiapplication") };
|
||||
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
|
||||
QOpenGLContext *ctx = qt_gl_global_share_context();
|
||||
QOpenGLContext *ctx = QOpenGLContext::globalShareContext();
|
||||
QVERIFY(ctx);
|
||||
app.reset();
|
||||
ctx = qt_gl_global_share_context();
|
||||
@ -1282,8 +1282,16 @@ void tst_QGuiApplication::globalShareContext()
|
||||
// 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();
|
||||
ctx = QOpenGLContext::globalShareContext();
|
||||
QVERIFY(!ctx);
|
||||
|
||||
// Test that setting AA_ShareOpenGLContexts can happen after creating
|
||||
// QGuiApplication.
|
||||
app.reset();
|
||||
app.reset(new QGuiApplication(argc, argv));
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
|
||||
ctx = QOpenGLContext::globalShareContext();
|
||||
QVERIFY(ctx);
|
||||
#else
|
||||
QSKIP("No OpenGL support");
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user