x11: Use global share context
This is needed to share window thumbnails between kwin's scene graph and qtquick.
This commit is contained in:
parent
8ed364337b
commit
172c541cad
6 changed files with 60 additions and 30 deletions
|
@ -29,8 +29,6 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
static std::unique_ptr<QOpenGLContext> 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<QOpenGLContext> context)
|
||||
{
|
||||
s_shareContext = std::move(context);
|
||||
}
|
||||
|
||||
QRect EffectQuickView::geometry() const
|
||||
{
|
||||
return d->m_view->geometry();
|
||||
|
|
|
@ -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<QOpenGLContext> context);
|
||||
|
||||
enum class ExportMode {
|
||||
/** The contents will be available as a texture in the shared contexts. Image will be blank*/
|
||||
Texture,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <QOpenGLContext>
|
||||
#include <QtPlatformHeaders/QEGLNativeContext>
|
||||
|
||||
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<QEGLNativeContext>()) {
|
||||
setFailed(QStringLiteral("Invalid QOpenGLContext::globalShareContext()"));
|
||||
return;
|
||||
} else {
|
||||
QEGLNativeContext handle = qvariant_cast<QEGLNativeContext>(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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<QGLXNativeContext>()) {
|
||||
qCDebug(KWIN_X11STANDALONE) << "Invalid QOpenGLContext::globalShareContext()";
|
||||
return false;
|
||||
} else {
|
||||
QGLXNativeContext handle = qvariant_cast<QGLXNativeContext>(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<QOpenGLContext>(qtContext));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue