Search code examples
c++qtqmlwaylandqtwayland

QtWayland registration from c++ fails for qml clients


i have a strange problem with my qtwayland compositor test. It seems only working for qt c++ clients. Qml clients end in a deadlock and the event processing stops (for the client). I have changed this https://doc.qt.io/archives/qt-5.11/qtwaylandcompositor-qwindow-compositor-example.html example and added following functionality:

void Compositor::onSurfaceCreated(QWaylandSurface *surface)
{
    connect(surface, &QWaylandSurface::subsurfacePositionChanged, this, &WaylandInterface::onSubsurfacePositionChanged);
    QQuickWindow *window = new QQuickWindow();
    window->resize( 400, 400);
    window->setVisible(true);
    QWaylandOutput* output = new QWaylandOutput( this, window );

    QCoreApplication::processEvents();
    View *view = new View(this);
    view->setSurface(surface);
    view->setOutput(output);
    view->m_window = window;
    m_views << view;

    connect(surface, &QWaylandSurface::surfaceDestroyed, view, [view] {
        view->m_window->requestUpdate();
    } );

    connect(surface, &QWaylandSurface::hasContentChanged, this, &WaylandInterface::surfaceHasContentChanged);
    connect(surface, &QWaylandSurface::hasContentChanged, view, [view] {
        view->m_window->requestUpdate();
    } );
    connect(surface, &QWaylandSurface::redraw, view, [view] {
        view->m_window->requestUpdate();
    } );


    QWaylandQuickItem * surfacItem = new QWaylandQuickItem( view->m_window->contentItem() );
    surfacItem->setSurface( surface );
    surfacItem->setOutput( view->output() );
    surfacItem->setPaintEnabled(true);
    surfacItem->setInputEventsEnabled(true);
    connect(surface, &QWaylandSurface::offsetForNextFrame, view, &View::onOffsetForNextFrame);
    connect(view, &QWaylandView::surfaceDestroyed, this, &WaylandInterface::viewSurfaceDestroyed);
}

for c++ clients it create a window and embeds the client into it, while qml clients are unresponsive. Is the order for creating the window, output and QuickItem is correct? Do I miss something?

Thanks, kane


Solution

  • The c++ clients were using single threaded rendering, while the qml clients uses a render thread. When an expose event is send to the renderer, qtwayland will block it unless the output were ordered to release the mutex. While the renderer locks the framebuffer, it is waiting for the server, and the main thread is waiting for the render thread => Deadlock.

    The callbacks can be send via output->frameStarted(); // before rendering output->sendFrameCallbacks(); // after rendering