[kwin_waylnad] Fix support for QtWayland's client buffer integration
QtWayland performs an eglInitialize in the main thread when for the first time an OpenGL context/window is needed. In KWin's startup this happens during initializing Scripting which creates a QDesktopWidget and triggers the creation of a QWindow with a RasterGLSurface. Calling eglInitialize in the main thread blocks as it calls wl_roundtrip. We cannot just disable OpenGL as that would mean that we cannot use QtQuick. The workaround in this change is to create a QWindow with a RasterGLSurface in a thread and call create on it. This ensures that OpenGL gets initialized in the thread and doesn't block.
This commit is contained in:
parent
54c2c5db2d
commit
9dcd123438
1 changed files with 21 additions and 3 deletions
|
@ -39,6 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
// system
|
// system
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
|
@ -165,12 +166,29 @@ void ApplicationWayland::continueStartupWithX()
|
||||||
::exit(1);
|
::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: create a QWindow in a thread to force QtWayland to create the client buffer integration
|
||||||
|
// this performs an eglInitialize which would block as it does a roundtrip to the Wayland server
|
||||||
|
// in the main thread. By moving into a thread we get the initialize without hitting the problem
|
||||||
|
// This needs to be done before creating the Workspace as from inside Workspace the dangerous code
|
||||||
|
// gets hit in the main thread
|
||||||
|
QFutureWatcher<void> *eglInitWatcher = new QFutureWatcher<void>(this);
|
||||||
|
connect(eglInitWatcher, &QFutureWatcher<void>::finished, this,
|
||||||
|
[this, eglInitWatcher] {
|
||||||
|
eglInitWatcher->deleteLater();
|
||||||
|
|
||||||
createWorkspace();
|
createWorkspace();
|
||||||
|
|
||||||
Xcb::sync(); // Trigger possible errors, there's still a chance to abort
|
Xcb::sync(); // Trigger possible errors, there's still a chance to abort
|
||||||
|
|
||||||
notifyKSplash();
|
notifyKSplash();
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
eglInitWatcher->setFuture(QtConcurrent::run([] {
|
||||||
|
QWindow w;
|
||||||
|
w.setSurfaceType(QSurface::RasterGLSurface);
|
||||||
|
w.create();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
void ApplicationWayland::createX11Connection()
|
void ApplicationWayland::createX11Connection()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue