[vlc-commits] [Git][videolan/vlc][master] 6 commits: qt: make it possible to combine video surface updates

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Nov 16 02:58:32 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
1240ed59 by Fatih Uzunoglu at 2025-11-16T02:43:33+00:00
qt: make it possible to combine video surface updates

- - - - -
65cdabc2 by Fatih Uzunoglu at 2025-11-16T02:43:33+00:00
qt: implement combined surface updates in `CompositorDirectComposition`

- - - - -
3f1b586b by Fatih Uzunoglu at 2025-11-16T02:43:33+00:00
qt: introduce `commitSurface()` in qt wayland module

- - - - -
4795ae16 by Fatih Uzunoglu at 2025-11-16T02:43:33+00:00
qt: make it possible to disable surface commit in `move()` and `resize()` in qt wayland module

- - - - -
89bc113b by Fatih Uzunoglu at 2025-11-16T02:43:33+00:00
qt: implement combined surface updates in `CompositorWayland`

- - - - -
a8cc3f6d by Fatih Uzunoglu at 2025-11-16T02:43:33+00:00
qt: call `vlc_window_ReportSize()` before the video surface changes are committed

- - - - -


10 changed files:

- modules/gui/qt/maininterface/compositor.cpp
- modules/gui/qt/maininterface/compositor.hpp
- modules/gui/qt/maininterface/compositor_dcomp.cpp
- modules/gui/qt/maininterface/compositor_dcomp.hpp
- modules/gui/qt/maininterface/compositor_wayland.cpp
- modules/gui/qt/maininterface/compositor_wayland.hpp
- modules/gui/qt/maininterface/compositor_wayland_module.c
- modules/gui/qt/maininterface/compositor_wayland_module.h
- modules/gui/qt/maininterface/videosurface.cpp
- modules/gui/qt/maininterface/videosurface.hpp


Changes:

=====================================
modules/gui/qt/maininterface/compositor.cpp
=====================================
@@ -230,12 +230,8 @@ void CompositorVideo::commonSetupVoutWindow(vlc_window_t* p_wnd, VoutDestroyCb d
     // these signals are emitted. VOut window might not be set, or worse, compositor's
     // internal preparations might not be completed yet:
     constexpr auto connType = static_cast<Qt::ConnectionType>(Qt::UniqueConnection | Qt::DirectConnection);
-    connect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfacePositionChanged,
-            this, &CompositorVideo::onSurfacePositionChanged, connType);
-    connect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceSizeChanged,
-            this, &CompositorVideo::onSurfaceSizeChanged, connType);
-    connect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceScaleChanged,
-            this, &CompositorVideo::onSurfaceScaleChanged, connType);
+    connect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfacePropertiesChanged,
+            this, &CompositorVideo::onSurfacePropertiesChanged, connType);
 }
 
 void CompositorVideo::windowDestroy()
@@ -243,12 +239,8 @@ void CompositorVideo::windowDestroy()
     // Current thread may not be the thread where
     // m_videoSurfaceProvider belongs to, so do not delete
     // it here:
-    disconnect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfacePositionChanged,
-               this, &CompositorVideo::onSurfacePositionChanged);
-    disconnect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceSizeChanged,
-               this, &CompositorVideo::onSurfaceSizeChanged);
-    disconnect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceScaleChanged,
-               this, &CompositorVideo::onSurfaceScaleChanged);
+    disconnect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfacePropertiesChanged,
+               this, &CompositorVideo::onSurfacePropertiesChanged);
 
     m_wnd = nullptr;
 }


=====================================
modules/gui/qt/maininterface/compositor.hpp
=====================================
@@ -25,6 +25,8 @@
 #include <memory>
 
 #include <QObject>
+#include <QPointF>
+#include <QSizeF>
 
 #include <vlc_common.h>
 
@@ -151,6 +153,12 @@ protected:
 
     bool setBlurBehind(QWindow* window, bool enable = true);
 
+    // The following method should return true if surface updates can be combined:
+    // Note that in such a case, `::commitSurface()` must be implemented.
+    virtual bool canDoCombinedSurfaceUpdates() const { return false; };
+
+    virtual void commitSurface() {}
+
 protected:
     /**
      * @brief commonGUICreate setup the QML view for video composition
@@ -178,10 +186,29 @@ private slots:
     void adjustBlurBehind();
 
 protected slots:
+    // WARNING: If `::canDoCombinedSurfaceUpdates()` returns `true`, individual
+    //          position and size change handlers should ideally not commit the
+    //          changes , for the compositor to apply the changes at the same
+    //          time with an explicit call to `commitSurface()`:
     virtual void onSurfacePositionChanged(const QPointF&) {}
     virtual void onSurfaceSizeChanged(const QSizeF&) {}
     virtual void onSurfaceScaleChanged(qreal) {}
 
+    virtual void onSurfacePropertiesChanged(const std::optional<QSizeF>& size,
+                                            const std::optional<QPointF>& position,
+                                            const std::optional<qreal>& scale)
+    {
+        if (size)
+            onSurfaceSizeChanged(*size);
+        if (position)
+            onSurfacePositionChanged(*position);
+        if (scale)
+            onSurfaceScaleChanged(*scale);
+
+        if (canDoCombinedSurfaceUpdates())
+            commitSurface();
+    }
+
 protected:
     qt_intf_t *m_intf = nullptr;
     vlc_window_t* m_wnd = nullptr;


=====================================
modules/gui/qt/maininterface/compositor_dcomp.cpp
=====================================
@@ -328,7 +328,9 @@ void CompositorDirectComposition::onSurfacePositionChanged(const QPointF& positi
 
     m_videoVisual->SetOffsetX(position.x());
     m_videoVisual->SetOffsetY(position.y());
-    m_dcompDevice->Commit();
+
+    // WARNING: Commit is requested explicitly through `::commitSurface()` after size
+    //          and position changes are applied.
 }
 
 void CompositorDirectComposition::onSurfaceSizeChanged(const QSizeF&)
@@ -472,4 +474,10 @@ bool CompositorDirectComposition::eventFilter(QObject *watched, QEvent *event)
     return QObject::eventFilter(watched, event);
 }
 
+void CompositorDirectComposition::commitSurface()
+{
+    assert(m_dcompDevice);
+    m_dcompDevice->Commit();
+}
+
 }


=====================================
modules/gui/qt/maininterface/compositor_dcomp.hpp
=====================================
@@ -71,6 +71,10 @@ public:
 
     bool canDoThreadedSurfaceUpdates() const override { return true; };
 
+protected:
+    bool canDoCombinedSurfaceUpdates() const override { return true; };
+    void commitSurface() override;
+
 private slots:
     void onSurfacePositionChanged(const QPointF& position) override;
     void onSurfaceSizeChanged(const QSizeF& size) override;


=====================================
modules/gui/qt/maininterface/compositor_wayland.cpp
=====================================
@@ -215,6 +215,12 @@ void CompositorWayland::windowDisable()
     commonWindowDisable();
 }
 
+void CompositorWayland::commitSurface()
+{
+    assert(m_waylandImpl);
+    m_waylandImpl->commitSurface(m_waylandImpl);
+}
+
 void CompositorWayland::onSurfacePositionChanged(const QPointF& position)
 {
     QMargins margins = m_qmlView->frameMargins();
@@ -222,10 +228,13 @@ void CompositorWayland::onSurfacePositionChanged(const QPointF& position)
     qreal qtDpr = m_qmlView.get()->effectiveDevicePixelRatio();
     qreal nativeDpr = dprForWindow(m_qmlView.get());
 
+    // WARNING: Commit is requested explicitly through `::commitSurface()` after size
+    //          and position changes are applied:
     m_waylandImpl->move(
         m_waylandImpl,
         (margins.left() * qtDpr + position.x() ) / nativeDpr,
-        (margins.top()  * qtDpr + position.y() ) / nativeDpr
+        (margins.top()  * qtDpr + position.y() ) / nativeDpr,
+        false
     );
 }
 
@@ -233,9 +242,12 @@ void CompositorWayland::onSurfaceSizeChanged(const QSizeF& size)
 {
     qreal nativeDpr = dprForWindow(m_qmlView.get());
 
+    // WARNING: Commit is requested explicitly through `::commitSurface()` after size
+    //          and position changes are applied:
     m_waylandImpl->resize(m_waylandImpl,
                         std::ceil(size.width() / nativeDpr),
-                        std::ceil(size.height() / nativeDpr));
+                        std::ceil(size.height() / nativeDpr),
+                        false);
 }
 
 void CompositorWayland::onSurfaceScaleChanged(qreal dpr)


=====================================
modules/gui/qt/maininterface/compositor_wayland.hpp
=====================================
@@ -80,6 +80,10 @@ public:
 
     bool canDoThreadedSurfaceUpdates() const override { return true; };
 
+protected:
+    bool canDoCombinedSurfaceUpdates() const override { return true; };
+    void commitSurface() override;
+
 protected slots:
     void onSurfacePositionChanged(const QPointF&) override;
     void onSurfaceSizeChanged(const QSizeF&) override;


=====================================
modules/gui/qt/maininterface/compositor_wayland_module.c
=====================================
@@ -103,7 +103,7 @@ static void SetSize(struct qtwayland_t* obj, size_t width, size_t height)
     sys->height = height;
 }
 
-static bool CommitSize(struct qtwayland_t* obj)
+static bool CommitSize(struct qtwayland_t* obj, bool commitSurface)
 {
 #ifdef QT_HAS_WAYLAND_FRACTIONAL_SCALING
     assert(obj);
@@ -123,7 +123,8 @@ static bool CommitSize(struct qtwayland_t* obj)
         // Qt Quick window which uses the fractional scale protocol itself
         // to determine the device pixel ratio.
         wp_viewport_set_destination(sys->viewport, sys->width, sys->height);
-        wl_surface_commit(sys->video_surface);
+        if (commitSurface)
+            wl_surface_commit(sys->video_surface);
         return true;
     }
 #endif
@@ -174,7 +175,7 @@ static void CommitScale(struct qtwayland_t* obj)
                 }
 
                 // Started using viewport, commit size so that viewport destination is set:
-                CommitSize(obj);
+                CommitSize(obj, true);
             }
         }
         else
@@ -305,16 +306,17 @@ static void Disable(qtwayland_t* obj)
     wl_surface_commit(sys->video_surface);
 }
 
-static void Move(struct qtwayland_t* obj, int x, int y)
+static void Move(struct qtwayland_t* obj, int x, int y, bool commitSurface)
 {
     qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
     if(sys->video_subsurface == NULL)
         return;
     wl_subsurface_set_position(sys->video_subsurface, x, y);
-    wl_surface_commit(sys->video_surface);
+    if (commitSurface)
+        wl_surface_commit(sys->video_surface);
 }
 
-static void Resize(struct qtwayland_t* obj, size_t width, size_t height)
+static void Resize(struct qtwayland_t* obj, size_t width, size_t height, bool commitSurface)
 {
     assert(obj);
     qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
@@ -336,7 +338,7 @@ static void Resize(struct qtwayland_t* obj, size_t width, size_t height)
     }
 
     if (commitNecessary)
-        CommitSize(obj);
+        CommitSize(obj, commitSurface);
 }
 
 
@@ -364,6 +366,18 @@ static void Rescale(struct qtwayland_t* obj, double scale)
         CommitScale(obj);
 }
 
+static void CommitSurface(struct qtwayland_t* obj)
+{
+    assert(obj);
+    qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+    assert(sys);
+
+    if (!sys->video_surface)
+        return;
+
+    wl_surface_commit(sys->video_surface);
+}
+
 static void Close(qtwayland_t* obj)
 {
     qtwayland_priv_t* sys = (qtwayland_priv_t*)(obj->p_sys);
@@ -460,6 +474,7 @@ int OpenCompositor(vlc_object_t* p_this)
     obj->move = Move;
     obj->resize = Resize;
     obj->rescale = Rescale;
+    obj->commitSurface = CommitSurface;
 
     obj->p_sys = sys;
 


=====================================
modules/gui/qt/maininterface/compositor_wayland_module.h
=====================================
@@ -37,10 +37,12 @@ typedef struct qtwayland_t
 
     void (*enable)(struct qtwayland_t*, const vlc_window_cfg_t *);
     void (*disable)(struct qtwayland_t*);
-    void (*move)(struct qtwayland_t*, int x, int y);
-    void (*resize)(struct qtwayland_t*, size_t width, size_t height);
+    void (*move)(struct qtwayland_t*, int x, int y, bool commitSurface);
+    void (*resize)(struct qtwayland_t*, size_t width, size_t height, bool commitSurface);
     void (*rescale)(struct qtwayland_t*, double scale);
 
+    void (*commitSurface)(struct qtwayland_t*);
+
     void (*close)(struct qtwayland_t*);
 } qtwayland_t;
 


=====================================
modules/gui/qt/maininterface/videosurface.cpp
=====================================
@@ -108,11 +108,13 @@ void VideoSurfaceProvider::onKeyPressed(int key, Qt::KeyboardModifiers modifiers
         vlc_window_ReportKeyPress(m_voutWindow, vlckey);
 }
 
-void VideoSurfaceProvider::onSurfaceSizeChanged(QSizeF size)
+void VideoSurfaceProvider::onSurfacePropertiesChanged(const std::optional<QSizeF>& size,
+                                                      const std::optional<QPointF>& position,
+                                                      const std::optional<qreal>& scale)
 {
-    emit surfaceSizeChanged(size);
-    if (m_voutWindow)
-        vlc_window_ReportSize(m_voutWindow, std::ceil(size.width()), std::ceil(size.height()));
+    if (m_voutWindow && size)
+        vlc_window_ReportSize(m_voutWindow, std::ceil(size->width()), std::ceil(size->height()));
+    emit surfacePropertiesChanged(size, position, scale);
 }
 
 
@@ -250,11 +252,15 @@ void VideoSurface::synchronize()
         position = renderPosition();
     }
 
+    std::optional<QSizeF> newSize;
+    std::optional<QPointF> newPosition;
+    std::optional<qreal> newScale;
+
     if (m_allDirty || m_dprDirty || m_oldRenderSize != size)
     {
         if (!size.isEmpty())
         {
-            emit surfaceSizeChanged(size * m_dpr);
+            newSize = size * m_dpr;
             m_oldRenderSize = size;
         }
     }
@@ -263,17 +269,20 @@ void VideoSurface::synchronize()
     {
         if (position.x() >= 0.0 && position.y() >= 0.0)
         {
-            emit surfacePositionChanged(position * m_dpr); // render position is relative to scene/viewport
+            newPosition = position * m_dpr; // render position is relative to scene/viewport
             m_oldRenderPosition = position;
         }
     }
 
     if (m_allDirty || m_dprDirty)
     {
-        emit surfaceScaleChanged(m_dpr);
+        newScale = m_dpr;
         m_dprDirty = false;
     }
 
+    if (newPosition || newSize || newScale)
+        emit surfacePropertiesChanged(newSize, newPosition, newScale);
+
     m_allDirty = false;
 }
 
@@ -347,9 +356,7 @@ void VideoSurface::setVideoSurfaceProvider(VideoSurfaceProvider *newVideoSurface
         connect(this, &VideoSurface::mouseDblClicked, m_provider, &VideoSurfaceProvider::onMouseDoubleClick);
         connect(this, &VideoSurface::mouseReleased, m_provider, &VideoSurfaceProvider::onMouseReleased);
         connect(this, &VideoSurface::keyPressed, m_provider, &VideoSurfaceProvider::onKeyPressed);
-        connect(this, &VideoSurface::surfaceSizeChanged, m_provider, &VideoSurfaceProvider::onSurfaceSizeChanged, Qt::DirectConnection);
-        connect(this, &VideoSurface::surfacePositionChanged, m_provider, &VideoSurfaceProvider::surfacePositionChanged, Qt::DirectConnection);
-        connect(this, &VideoSurface::surfaceScaleChanged, m_provider, &VideoSurfaceProvider::surfaceScaleChanged, Qt::DirectConnection);
+        connect(this, &VideoSurface::surfacePropertiesChanged, m_provider, &VideoSurfaceProvider::onSurfacePropertiesChanged, Qt::DirectConnection);
 
         // With auto connection, this should be queued if the signal was emitted from vout thread,
         // so that the slot is executed in item's thread:


=====================================
modules/gui/qt/maininterface/videosurface.hpp
=====================================
@@ -62,9 +62,9 @@ signals:
     void ctxChanged(MainCtx*);
     bool videoEnabledChanged(bool);
     bool hasVideoEmbedChanged(bool);
-    void surfacePositionChanged(QPointF position);
-    void surfaceSizeChanged(QSizeF size);
-    void surfaceScaleChanged(qreal);
+    void surfacePropertiesChanged(const std::optional<QSizeF>& size,
+                                  const std::optional<QPointF>& position,
+                                  const std::optional<qreal>& scale);
 
 public slots:
     void onWindowClosed();
@@ -74,7 +74,9 @@ public slots:
     void onMouseMoved( float x, float y );
     void onMouseWheeled(int vlcButton);
     void onKeyPressed(int key, Qt::KeyboardModifiers modifiers);
-    void onSurfaceSizeChanged(QSizeF size);
+    void onSurfacePropertiesChanged(const std::optional<QSizeF>& size,
+                                    const std::optional<QPointF>& position,
+                                    const std::optional<qreal>& scale);
 
 protected:
     vlc_window_t* m_voutWindow = nullptr;
@@ -115,9 +117,9 @@ protected:
 
     void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
 signals:
-    void surfaceSizeChanged(QSizeF);
-    void surfacePositionChanged(QPointF);
-    void surfaceScaleChanged(qreal);
+    void surfacePropertiesChanged(const std::optional<QSizeF>& size,
+                                  const std::optional<QPointF>& position,
+                                  const std::optional<qreal>& scale);
 
     void mousePressed( int vlcButton );
     void mouseReleased( int vlcButton );



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81191b4c5eaba0f5158d9f6400810db1622052e3...a8cc3f6db15da074287fcd6cb9fdb7d938fff971

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81191b4c5eaba0f5158d9f6400810db1622052e3...a8cc3f6db15da074287fcd6cb9fdb7d938fff971
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list