diff --git a/src/libkwineffects/kwineffectquickview.cpp b/src/libkwineffects/kwineffectquickview.cpp index d62ed607fb..62f9602ee1 100644 --- a/src/libkwineffects/kwineffectquickview.cpp +++ b/src/libkwineffects/kwineffectquickview.cpp @@ -29,8 +29,6 @@ namespace KWin { -static std::unique_ptr s_shareContext; - class Q_DECL_HIDDEN EffectQuickView::Private { public: @@ -88,7 +86,7 @@ EffectQuickView::EffectQuickView(QObject *parent, ExportMode exportMode) format.setStencilBufferSize(8); d->m_glcontext.reset(new QOpenGLContext); - d->m_glcontext->setShareContext(s_shareContext.get()); + d->m_glcontext->setShareContext(QOpenGLContext::globalShareContext()); d->m_glcontext->setFormat(format); d->m_glcontext->create(); @@ -103,11 +101,6 @@ EffectQuickView::EffectQuickView(QObject *parent, ExportMode exportMode) if (!d->m_glcontext->shareContext()) { qCDebug(LIBKWINEFFECTS) << "Failed to create a shared context, falling back to raster rendering"; - - qCDebug(LIBKWINEFFECTS) << "Extra debug:"; - qCDebug(LIBKWINEFFECTS) << "our context:" << d->m_glcontext.data(); - qCDebug(LIBKWINEFFECTS) << "share context:" << s_shareContext.get(); - // still render via GL, but blit for presentation d->m_useBlit = true; } @@ -238,11 +231,6 @@ void EffectQuickView::forwardKeyEvent(QKeyEvent *keyEvent) QCoreApplication::sendEvent(d->m_view, keyEvent); } -void EffectQuickView::setShareContext(std::unique_ptr context) -{ - s_shareContext = std::move(context); -} - QRect EffectQuickView::geometry() const { return d->m_view->geometry(); diff --git a/src/libkwineffects/kwineffectquickview.h b/src/libkwineffects/kwineffectquickview.h index 8a6e7b48b4..9335b69028 100644 --- a/src/libkwineffects/kwineffectquickview.h +++ b/src/libkwineffects/kwineffectquickview.h @@ -21,7 +21,6 @@ class QKeyEvent; class QMouseEvent; -class QOpenGLContext; class QMouseEvent; class QKeyEvent; @@ -49,8 +48,6 @@ class KWINEFFECTS_EXPORT EffectQuickView : public QObject Q_OBJECT public: - static void setShareContext(std::unique_ptr context); - enum class ExportMode { /** The contents will be available as a texture in the shared contexts. Image will be blank*/ Texture, diff --git a/src/main_x11.cpp b/src/main_x11.cpp index 7e4268b6dd..c55f1eb830 100644 --- a/src/main_x11.cpp +++ b/src/main_x11.cpp @@ -417,6 +417,15 @@ int main(int argc, char * argv[]) QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); // KSMServer talks to us directly on DBus. QCoreApplication::setAttribute(Qt::AA_DisableSessionManager); + // For sharing thumbnails between our scene graph and qtquick. + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + // shared opengl contexts must have the same reset notification policy + format.setOptions(QSurfaceFormat::ResetNotification); + // disables vsync for any QtQuick windows we create (BUG 406180) + format.setSwapInterval(0); + QSurfaceFormat::setDefaultFormat(format); KWin::ApplicationX11 a(argc, argv); a.setupTranslator(); @@ -424,11 +433,6 @@ int main(int argc, char * argv[]) KWin::Application::createAboutData(); KQuickAddons::QtQuickSettings::init(); - // disables vsync for any QtQuick windows we create (BUG 406180) - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); - format.setSwapInterval(0); - QSurfaceFormat::setDefaultFormat(format); - QCommandLineOption replaceOption(QStringLiteral("replace"), i18n("Replace already-running ICCCM2.0-compliant window manager")); QCommandLineParser parser; diff --git a/src/plugins/platforms/x11/standalone/eglbackend.cpp b/src/plugins/platforms/x11/standalone/eglbackend.cpp index 49cf664d27..f0855e0c9e 100644 --- a/src/plugins/platforms/x11/standalone/eglbackend.cpp +++ b/src/plugins/platforms/x11/standalone/eglbackend.cpp @@ -6,6 +6,7 @@ */ #include "eglbackend.h" +#include "logging.h" #include "options.h" #include "overlaywindow.h" #include "platform.h" @@ -16,6 +17,9 @@ #include "surfaceitem_x11.h" #include "x11_platform.h" +#include +#include + namespace KWin { @@ -48,6 +52,30 @@ PlatformSurfaceTexture *EglBackend::createPlatformSurfaceTextureX11(SurfacePixma return new EglSurfaceTextureX11(this, texture); } +void EglBackend::init() +{ + QOpenGLContext *qtShareContext = QOpenGLContext::globalShareContext(); + EGLContext shareContext = EGL_NO_CONTEXT; + if (qtShareContext) { + qDebug(KWIN_X11STANDALONE) << "Global share context format:" << qtShareContext->format(); + const QVariant nativeHandle = qtShareContext->nativeHandle(); + if (!nativeHandle.canConvert()) { + setFailed(QStringLiteral("Invalid QOpenGLContext::globalShareContext()")); + return; + } else { + QEGLNativeContext handle = qvariant_cast(nativeHandle); + shareContext = handle.context(); + } + } + if (shareContext == EGL_NO_CONTEXT) { + setFailed(QStringLiteral("QOpenGLContext::globalShareContext() is required")); + return; + } + + kwinApp()->platform()->setSceneEglGlobalShareContext(shareContext); + EglOnXBackend::init(); +} + void EglBackend::screenGeometryChanged(const QSize &size) { Q_UNUSED(size) diff --git a/src/plugins/platforms/x11/standalone/eglbackend.h b/src/plugins/platforms/x11/standalone/eglbackend.h index aefa6448e6..2df83e4222 100644 --- a/src/plugins/platforms/x11/standalone/eglbackend.h +++ b/src/plugins/platforms/x11/standalone/eglbackend.h @@ -27,6 +27,8 @@ public: EglBackend(Display *display, X11StandalonePlatform *platform); ~EglBackend() override; + void init() override; + PlatformSurfaceTexture *createPlatformSurfaceTextureX11(SurfacePixmapX11 *texture) override; QRegion beginFrame(int screenId) override; void endFrame(int screenId, const QRegion &damage, const QRegion &damagedRegion) override; diff --git a/src/plugins/platforms/x11/standalone/glxbackend.cpp b/src/plugins/platforms/x11/standalone/glxbackend.cpp index a52c1e9b6a..81fce36005 100644 --- a/src/plugins/platforms/x11/standalone/glxbackend.cpp +++ b/src/plugins/platforms/x11/standalone/glxbackend.cpp @@ -129,7 +129,6 @@ GlxBackend::~GlxBackend() // do cleanup after initBuffer() cleanupGL(); doneCurrent(); - EffectQuickView::setShareContext(nullptr); if (ctx) glXDestroyContext(display(), ctx); @@ -311,6 +310,24 @@ bool GlxBackend::initRenderingContext() { const bool direct = true; + QOpenGLContext *qtGlobalShareContext = QOpenGLContext::globalShareContext(); + GLXContext globalShareContext = nullptr; + if (qtGlobalShareContext) { + qDebug(KWIN_X11STANDALONE) << "Global share context format:" << qtGlobalShareContext->format(); + const QVariant nativeHandle = qtGlobalShareContext->nativeHandle(); + if (!nativeHandle.canConvert()) { + qCDebug(KWIN_X11STANDALONE) << "Invalid QOpenGLContext::globalShareContext()"; + return false; + } else { + QGLXNativeContext handle = qvariant_cast(nativeHandle); + globalShareContext = handle.context(); + } + } + if (!globalShareContext) { + qCWarning(KWIN_X11STANDALONE) << "QOpenGLContext::globalShareContext() is required"; + return false; + } + // Use glXCreateContextAttribsARB() when it's available if (hasExtension(QByteArrayLiteral("GLX_ARB_create_context"))) { const bool have_robustness = hasExtension(QByteArrayLiteral("GLX_ARB_create_context_robustness")); @@ -352,7 +369,7 @@ bool GlxBackend::initRenderingContext() } for (auto it = candidates.begin(); it != candidates.end(); it++) { const auto attribs = it->build(); - ctx = glXCreateContextAttribsARB(display(), fbconfig, nullptr, true, attribs.data()); + ctx = glXCreateContextAttribsARB(display(), fbconfig, globalShareContext, true, attribs.data()); if (ctx) { qCDebug(KWIN_X11STANDALONE) << "Created GLX context with attributes:" << &(*it); break; @@ -361,7 +378,7 @@ bool GlxBackend::initRenderingContext() } if (!ctx) - ctx = glXCreateNewContext(display(), fbconfig, GLX_RGBA_TYPE, nullptr, direct); + ctx = glXCreateNewContext(display(), fbconfig, GLX_RGBA_TYPE, globalShareContext, direct); if (!ctx) { qCDebug(KWIN_X11STANDALONE) << "Failed to create an OpenGL context."; @@ -375,12 +392,6 @@ bool GlxBackend::initRenderingContext() return false; } - auto qtContext = new QOpenGLContext; - QGLXNativeContext native(ctx, display()); - qtContext->setNativeHandle(QVariant::fromValue(native)); - qtContext->create(); - EffectQuickView::setShareContext(std::unique_ptr(qtContext)); - return true; }