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_UseDesktopOpenGL:
|
||||||
case Qt::AA_UseOpenGLES:
|
case Qt::AA_UseOpenGLES:
|
||||||
case Qt::AA_UseSoftwareOpenGL:
|
case Qt::AA_UseSoftwareOpenGL:
|
||||||
case Qt::AA_ShareOpenGLContexts:
|
|
||||||
#ifdef QT_BOOTSTRAPPED
|
#ifdef QT_BOOTSTRAPPED
|
||||||
qWarning("Attribute %d must be set before QCoreApplication is created.",
|
qWarning("Attribute %d must be set before QCoreApplication is created.",
|
||||||
attribute);
|
attribute);
|
||||||
|
@ -727,8 +727,7 @@ QGuiApplication::~QGuiApplication()
|
|||||||
QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv)
|
QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv)
|
||||||
: QCoreApplicationPrivate(argc, argv),
|
: QCoreApplicationPrivate(argc, argv),
|
||||||
inputMethod(nullptr),
|
inputMethod(nullptr),
|
||||||
lastTouchType(QEvent::TouchEnd),
|
lastTouchType(QEvent::TouchEnd)
|
||||||
ownGlobalShareContext(false)
|
|
||||||
{
|
{
|
||||||
self = this;
|
self = this;
|
||||||
application_type = QCoreApplicationPrivate::Gui;
|
application_type = QCoreApplicationPrivate::Gui;
|
||||||
@ -1740,17 +1739,6 @@ void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::init()
|
|||||||
qRegisterGuiGetInterpolator();
|
qRegisterGuiGetInterpolator();
|
||||||
#endif
|
#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();
|
QWindowSystemInterfacePrivate::eventTime.start();
|
||||||
|
|
||||||
is_app_running = true;
|
is_app_running = true;
|
||||||
|
@ -342,6 +342,10 @@ public:
|
|||||||
|
|
||||||
static QThreadPool *qtGuiThreadPool();
|
static QThreadPool *qtGuiThreadPool();
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
bool ownGlobalShareContext = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void handleThemeChanged();
|
virtual void handleThemeChanged();
|
||||||
|
|
||||||
@ -366,8 +370,6 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
std::shared_ptr<QColorTrcLut> m_a32ColorProfile;
|
std::shared_ptr<QColorTrcLut> m_a32ColorProfile;
|
||||||
|
|
||||||
bool ownGlobalShareContext;
|
|
||||||
|
|
||||||
static QInputDeviceManager *m_inputDeviceManager;
|
static QInputDeviceManager *m_inputDeviceManager;
|
||||||
|
|
||||||
// Cache the maximum device pixel ratio, to iterate through the screen list
|
// 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,
|
This is useful if you need to upload OpenGL objects (buffers, textures,
|
||||||
etc.) before creating or showing a QOpenGLWidget or QQuickWidget.
|
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
|
\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
|
current on any surface. Instead, you can create a new context which shares
|
||||||
with the global one, and then make the new context current.
|
with the global one, and then make the new context current.
|
||||||
@ -972,6 +968,14 @@ bool QOpenGLContext::supportsThreadedOpenGL()
|
|||||||
QOpenGLContext *QOpenGLContext::globalShareContext()
|
QOpenGLContext *QOpenGLContext::globalShareContext()
|
||||||
{
|
{
|
||||||
Q_ASSERT(qGuiApp);
|
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();
|
return qt_gl_global_share_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include <QtGui/qcolorspace.h>
|
#include <QtGui/qcolorspace.h>
|
||||||
#include <QtGui/qguiapplication.h>
|
#include <QtGui/qguiapplication.h>
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
#include <QtGui/private/qopenglcontext_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef major
|
#ifdef major
|
||||||
#undef major
|
#undef major
|
||||||
#endif
|
#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
|
and surfaces, even the ones created internally by Qt, will use the same
|
||||||
format.
|
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
|
\since 5.4
|
||||||
\sa defaultFormat()
|
\sa defaultFormat()
|
||||||
*/
|
*/
|
||||||
@ -820,7 +818,7 @@ void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format)
|
|||||||
{
|
{
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
if (qApp) {
|
if (qApp) {
|
||||||
QOpenGLContext *globalContext = QOpenGLContext::globalShareContext();
|
QOpenGLContext *globalContext = qt_gl_global_share_context();
|
||||||
if (globalContext && globalContext->isValid()) {
|
if (globalContext && globalContext->isValid()) {
|
||||||
qWarning("Warning: Setting a new default format with a different version or profile "
|
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 "
|
"after the global shared context is created may cause issues with context "
|
||||||
|
@ -74,7 +74,7 @@ bool QBackingStoreRhiSupport::create()
|
|||||||
params.fallbackSurface = surface;
|
params.fallbackSurface = surface;
|
||||||
params.window = m_window;
|
params.window = m_window;
|
||||||
params.format = m_format;
|
params.format = m_format;
|
||||||
params.shareContext = qt_gl_global_share_context();
|
params.shareContext = QOpenGLContext::globalShareContext();
|
||||||
rhi = QRhi::create(QRhi::OpenGLES2, ¶ms, flags);
|
rhi = QRhi::create(QRhi::OpenGLES2, ¶ms, flags);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -771,7 +771,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
|
|||||||
if (maybeShareContext) {
|
if (maybeShareContext) {
|
||||||
ctx->setShareContext(maybeShareContext);
|
ctx->setShareContext(maybeShareContext);
|
||||||
ctx->setScreen(maybeShareContext->screen());
|
ctx->setScreen(maybeShareContext->screen());
|
||||||
} else if (QOpenGLContext *shareContext = qt_gl_global_share_context()) {
|
} else if (QOpenGLContext *shareContext = QOpenGLContext::globalShareContext()) {
|
||||||
ctx->setShareContext(shareContext);
|
ctx->setShareContext(shareContext);
|
||||||
ctx->setScreen(shareContext->screen());
|
ctx->setScreen(shareContext->screen());
|
||||||
} else if (maybeWindow) {
|
} else if (maybeWindow) {
|
||||||
|
@ -161,7 +161,7 @@ public:
|
|||||||
, shareContext(shareContext)
|
, shareContext(shareContext)
|
||||||
{
|
{
|
||||||
if (!shareContext)
|
if (!shareContext)
|
||||||
this->shareContext = qt_gl_global_share_context();
|
this->shareContext = QOpenGLContext::globalShareContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
~QOpenGLWindowPrivate();
|
~QOpenGLWindowPrivate();
|
||||||
|
@ -856,7 +856,7 @@ void QOpenGLWidgetPrivate::initialize()
|
|||||||
context = new QOpenGLContext;
|
context = new QOpenGLContext;
|
||||||
context->setFormat(requestedFormat);
|
context->setFormat(requestedFormat);
|
||||||
|
|
||||||
QOpenGLContext *shareContext = contextFromRhi ? contextFromRhi : qt_gl_global_share_context();
|
QOpenGLContext *shareContext = contextFromRhi ? contextFromRhi : QOpenGLContext::globalShareContext();
|
||||||
if (shareContext) {
|
if (shareContext) {
|
||||||
context->setShareContext(shareContext);
|
context->setShareContext(shareContext);
|
||||||
context->setScreen(shareContext->screen());
|
context->setScreen(shareContext->screen());
|
||||||
|
@ -108,14 +108,14 @@ void QEglFSWindow::setBackingStore(QOpenGLCompositorBackingStore *backingStore)
|
|||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
if (!m_rasterCompositingContext) {
|
if (!m_rasterCompositingContext) {
|
||||||
m_rasterCompositingContext = new QOpenGLContext;
|
m_rasterCompositingContext = new QOpenGLContext;
|
||||||
m_rasterCompositingContext->setShareContext(qt_gl_global_share_context());
|
m_rasterCompositingContext->setShareContext(QOpenGLContext::globalShareContext());
|
||||||
m_rasterCompositingContext->setFormat(m_format);
|
m_rasterCompositingContext->setFormat(m_format);
|
||||||
m_rasterCompositingContext->setScreen(window()->screen());
|
m_rasterCompositingContext->setScreen(window()->screen());
|
||||||
if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
|
if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
|
||||||
qFatal("EGLFS: Failed to create compositing context");
|
qFatal("EGLFS: Failed to create compositing context");
|
||||||
// If there is a "root" window into which raster and QOpenGLWidget content is
|
// If there is a "root" window into which raster and QOpenGLWidget content is
|
||||||
// composited, all other contexts must share with its context.
|
// 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);
|
qt_gl_set_global_share_context(m_rasterCompositingContext);
|
||||||
}
|
}
|
||||||
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
|
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
|
||||||
@ -145,7 +145,7 @@ void QEglFSWindow::destroy()
|
|||||||
|
|
||||||
if (compositor->windows().isEmpty()) {
|
if (compositor->windows().isEmpty()) {
|
||||||
compositor->destroy();
|
compositor->destroy();
|
||||||
if (qt_gl_global_share_context() == m_rasterCompositingContext)
|
if (QOpenGLContext::globalShareContext() == m_rasterCompositingContext)
|
||||||
qt_gl_set_global_share_context(nullptr);
|
qt_gl_set_global_share_context(nullptr);
|
||||||
delete m_rasterCompositingContext;
|
delete m_rasterCompositingContext;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1273,7 +1273,7 @@ void tst_QGuiApplication::globalShareContext()
|
|||||||
int argc = 1;
|
int argc = 1;
|
||||||
char *argv[] = { const_cast<char*>("tst_qguiapplication") };
|
char *argv[] = { const_cast<char*>("tst_qguiapplication") };
|
||||||
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
|
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
|
||||||
QOpenGLContext *ctx = qt_gl_global_share_context();
|
QOpenGLContext *ctx = QOpenGLContext::globalShareContext();
|
||||||
QVERIFY(ctx);
|
QVERIFY(ctx);
|
||||||
app.reset();
|
app.reset();
|
||||||
ctx = qt_gl_global_share_context();
|
ctx = qt_gl_global_share_context();
|
||||||
@ -1282,8 +1282,16 @@ void tst_QGuiApplication::globalShareContext()
|
|||||||
// Test that there is no global share context by default.
|
// Test that there is no global share context by default.
|
||||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, false);
|
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, false);
|
||||||
app.reset(new QGuiApplication(argc, argv));
|
app.reset(new QGuiApplication(argc, argv));
|
||||||
ctx = qt_gl_global_share_context();
|
ctx = QOpenGLContext::globalShareContext();
|
||||||
QVERIFY(!ctx);
|
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
|
#else
|
||||||
QSKIP("No OpenGL support");
|
QSKIP("No OpenGL support");
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user