[vlc-devel] [RFC 48/82] qt: add wayland video renderer

Rémi Denis-Courmont remi at remlab.net
Fri Feb 1 14:32:14 CET 2019


This does not seem to bind to versions correctly. Also error handling seems missing.

Le 1 février 2019 15:01:52 GMT+02:00, Pierre Lamot <pierre at videolabs.io> a écrit :
>From: Alexandre Janniaux <alexandre.janniaux at gmail.com>
>
>---
> modules/gui/qt/Makefile.am                    |   9 +
> .../video_renderer/videorendererwayland.cpp   | 154 ++++++++++++++++++
> .../video_renderer/videorendererwayland.hpp   |  63 +++++++
> 3 files changed, 226 insertions(+)
>create mode 100644
>modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>create mode 100644
>modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>
>diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
>index 7d0132c6a1..e9cd3e61d4 100644
>--- a/modules/gui/qt/Makefile.am
>+++ b/modules/gui/qt/Makefile.am
>@@ -166,6 +166,11 @@ if HAVE_WIN32
> libqt_plugin_la_SOURCES += \
> 	gui/qt/main_interface_win32.cpp gui/qt/main_interface_win32.hpp
> endif
>+if HAVE_WAYLAND
>+libqt_plugin_la_SOURCES += \
>+	gui/qt/components/video_renderer/videorendererwayland.hpp \
>+	gui/qt/components/video_renderer/videorendererwayland.cpp
>+endif
> 
> # Meta-object compilation
> 
>@@ -260,6 +265,10 @@ if HAVE_WIN32
> nodist_libqt_plugin_la_SOURCES += gui/qt/main_interface_win32.moc.cpp
> endif
> 
>+if HAVE_WAYLAND
>+nodist_libqt_plugin_la_SOURCES +=
>gui/qt/components/video_renderer/videorendererwayland.moc.cpp
>+endif
>+
> nodist_libqt_plugin_la_SOURCES += \
> 	gui/qt/ui/equalizer.h \
> 	gui/qt/ui/video_effects.h \
>diff --git
>a/modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>b/modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>new file mode 100644
>index 0000000000..120bb9a24c
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>@@ -0,0 +1,154 @@
>+#include "videorendererwayland.hpp"
>+#include <QtQuick/QSGImageNode>
>+#include <QtQuick/QSGRectangleNode>
>+#include <QtQuick/QQuickWindow>
>+#include <vlc_vout_window.h>
>+#include "main_interface.hpp"
>+
>+#include QPNI_HEADER
>+#include <wayland-client.h>
>+#include <wayland-client-protocol.h>
>+
>+void VideoRendererWayland::registry_global( void *data, wl_registry
>*registry,
>+                                       uint32_t name, const char
>*intf,
>+                                       uint32_t version )
>+{
>+    VideoRendererWayland *renderer =
>static_cast<VideoRendererWayland*>( data );
>+
>+    if( !strcmp(intf, "wl_compositor") )
>+        renderer->m_compositor = static_cast<wl_compositor*>(
>+                                 wl_registry_bind( registry, name,
>+                                                  
>&wl_compositor_interface,
>+                                                   version ));
>+
>+    else
>+    if( !strcmp(intf, "wl_subcompositor") )
>+        renderer->m_subcompositor = static_cast<wl_subcompositor*>(
>+                                    wl_registry_bind( registry, name,
>+                                                     
>&wl_subcompositor_interface,
>+                                                      version ));
>+}
>+
>+void VideoRendererWayland::registry_global_remove( void *, wl_registry
>*, uint32_t )
>+{
>+    // nothing to do
>+}
>+
>+VideoRendererWayland::VideoRendererWayland( MainInterface* p_mi,
>QObject* parent )
>+    : VideoRenderer( parent )
>+    , m_mainInterface( p_mi )
>+{
>+    assert( m_mainInterface );
>+    m_surfaceProvider = new VideoSurfaceWayland( this, this );
>+}
>+
>+VideoRendererWayland::~VideoRendererWayland()
>+{
>+    if( m_subsurface )
>+        wl_subsurface_destroy( m_subsurface );
>+    if( m_surface )
>+        wl_surface_destroy( m_surface );
>+    if( m_compositor )
>+        wl_compositor_destroy( m_compositor );
>+    if( m_subcompositor )
>+        wl_subcompositor_destroy( m_subcompositor );
>+}
>+
>+void VideoRendererWayland::enableVideo(unsigned width, unsigned
>height, bool fullscreen)
>+{
>+    VideoRenderer::enableVideo(width, height, fullscreen);
>+    if (!m_hasVideo) //no window out has been set
>+        return;
>+
>+    m_voutWindow->type = VOUT_WINDOW_TYPE_WAYLAND;
>+
>+    QPlatformNativeInterface *qni = qApp->platformNativeInterface();
>+
>+    m_voutWindow->display.wl = static_cast<wl_display *>(
>+        
>qni->nativeResourceForIntegration(QByteArrayLiteral("wl_display")));
>+
>+    const wl_registry_listener registry_cbs =
>+    {
>+        registry_global,
>+        registry_global_remove,
>+    };
>+
>+    wl_registry *registry = wl_display_get_registry(
>m_voutWindow->display.wl );
>+    wl_registry_add_listener( registry, &registry_cbs, this );
>+    wl_display_roundtrip( m_voutWindow->display.wl );
>+    wl_registry_destroy( registry );
>+
>+    if( !m_compositor || !m_subcompositor )
>+        return; // TODO: what to do
>+
>+    QWindow *root_window = m_mainInterface->window()->windowHandle();
>+    wl_surface *root_surface = static_cast<wl_surface *>(
>+        qni->nativeResourceForWindow( QByteArrayLiteral("surface"),
>+                                      root_window ));
>+
>+    m_surface =
>+    m_voutWindow->handle.wl = wl_compositor_create_surface(
>m_compositor );
>+    m_subsurface = wl_subcompositor_get_subsurface( m_subcompositor,
>+                                                   
>m_voutWindow->handle.wl,
>+                                                    root_surface );
>+
>+    wl_subsurface_place_below( m_subsurface, root_surface );
>+    wl_subsurface_set_desync( m_subsurface );
>+
>+    /* HACK: disable event input on surface, so that Qt don't try
>+     * to cast it's userdata */
>+    wl_region *region = wl_compositor_create_region( m_compositor );
>+    wl_region_add( region, 0, 0, 0, 0 );
>+    wl_surface_set_input_region( m_voutWindow->handle.wl, region );
>+    wl_region_destroy( region );
>+}
>+
>+
>+void VideoRendererWayland::disableVideo()
>+{
>+    VideoRenderer::disableVideo();
>+    if( m_subsurface )
>+        wl_subsurface_destroy( m_subsurface );
>+    if( m_surface )
>+        wl_surface_destroy( m_surface );
>+    if( m_subcompositor )
>+        wl_subcompositor_destroy( m_subcompositor );
>+    if( m_compositor )
>+        wl_compositor_destroy( m_compositor );
>+    m_subsurface = nullptr; m_surface = nullptr;
>+    m_compositor = nullptr; m_subcompositor = nullptr;
>+}
>+
>+VideoSurfaceProvider *VideoRendererWayland::getVideoSurfaceProvider()
>+{
>+    return m_surfaceProvider;
>+}
>+
>+VideoSurfaceWayland::VideoSurfaceWayland(VideoRendererWayland*
>renderer, QObject* parent)
>+    : VideoSurfaceProvider( parent )
>+    , m_renderer(renderer)
>+{
>+    connect(this, &VideoSurfaceWayland::mouseMoved, m_renderer,
>&VideoRenderer::onMouseMoved, Qt::QueuedConnection);
>+    connect(this, &VideoSurfaceWayland::mousePressed, m_renderer,
>&VideoRenderer::onMousePressed, Qt::QueuedConnection);
>+    connect(this, &VideoSurfaceWayland::mouseDblClicked, m_renderer,
>&VideoRenderer::onMouseDoubleClick, Qt::QueuedConnection);
>+    connect(this, &VideoSurfaceWayland::mouseReleased, m_renderer,
>&VideoRenderer::onMouseReleased, Qt::QueuedConnection);
>+
>+    connect(this, &VideoSurfaceWayland::surfaceSizeChanged,
>m_renderer, &VideoRenderer::onSurfaceSizeChanged);
>+
>+    connect(m_renderer, &VideoRendererWayland::updated, this,
>&VideoSurfaceWayland::update, Qt::QueuedConnection);
>+}
>+
>+QSGNode* VideoSurfaceWayland::updatePaintNode(QQuickItem* item,
>QSGNode* oldNode, QQuickItem::UpdatePaintNodeData*)
>+{
>+    QSGRectangleNode* node = static_cast<QSGRectangleNode*>(oldNode);
>+
>+    if (!node)
>+    {
>+        node = item->window()->createRectangleNode();
>+        node->setColor(Qt::transparent);
>+    }
>+    node->setRect(item->boundingRect());
>+
>+    return node;
>+}
>+
>diff --git
>a/modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>b/modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>new file mode 100644
>index 0000000000..c3c3462368
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>@@ -0,0 +1,63 @@
>+#ifndef VLC_QT_VIDEORENDERERWL_HPP
>+#define VLC_QT_VIDEORENDERERWL_HPP
>+
>+#include <inttypes.h>
>+#include <QtQuick/QQuickItem>
>+#include <QMutex>
>+#include <QtQuick/QSGRectangleNode>
>+#include <components/qml_main_context.hpp>
>+#include "qt.hpp"
>+
>+#include "videorenderer.hpp"
>+
>+class MainInterface;
>+class VideoSurfaceWayland;
>+
>+struct wl_compositor;
>+struct wl_subcompositor;
>+struct wl_subsurface;
>+struct wl_registry;
>+
>+class VideoRendererWayland: public VideoRenderer
>+{
>+    Q_OBJECT
>+public:
>+    VideoRendererWayland(MainInterface* p_mi,  QObject *parent =
>nullptr);
>+    ~VideoRendererWayland() override;
>+
>+    void enableVideo(unsigned int width, unsigned int height, bool
>fullscreen);
>+    void disableVideo();
>+
>+    VideoSurfaceProvider *getVideoSurfaceProvider() override;
>+
>+signals:
>+    void updated();
>+
>+private:
>+    /* wayland registry callbacks */
>+    static void registry_global( void *, wl_registry *, uint32_t,
>+                                 const char *, uint32_t );
>+    static void registry_global_remove( void *, wl_registry *,
>uint32_t );
>+
>+    MainInterface *m_mainInterface;
>+    VideoSurfaceWayland *m_surfaceProvider = nullptr;
>+    wl_compositor *m_compositor = nullptr;
>+    wl_subcompositor *m_subcompositor = nullptr;
>+    wl_subsurface *m_subsurface = nullptr;
>+    wl_surface *m_surface = nullptr;
>+};
>+
>+class VideoSurfaceWayland : public VideoSurfaceProvider
>+{
>+    Q_OBJECT
>+public:
>+    VideoSurfaceWayland(VideoRendererWayland* renderer, QObject*
>parent = nullptr);
>+
>+private:
>+    QSGNode *updatePaintNode(QQuickItem* item, QSGNode *,
>QQuickItem::UpdatePaintNodeData *) override;
>+
>+private:
>+    VideoRendererWayland* m_renderer = nullptr;
>+};
>+
>+#endif // VLC_QT_VIDEORENDERERWL_HPP
>-- 
>2.19.1
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel

-- 
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20190201/0170fc54/attachment.html>


More information about the vlc-devel mailing list