[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: make video surface report scale changes
Steve Lhomme (@robUx4)
gitlab at videolan.org
Sat Jan 18 13:57:20 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
a5efdf49 by Fatih Uzunoglu at 2025-01-18T13:44:05+00:00
qt: make video surface report scale changes
- - - - -
6151e45a by Fatih Uzunoglu at 2025-01-18T13:44:05+00:00
qt: do not use viewporter protocol if scale is not fractional and react to scale changes
- If the scale is not fractional, it is not necessary to use the viewporter protocol.
- React to scale change after initialization.
- - - - -
8 changed files:
- modules/gui/qt/maininterface/compositor.cpp
- modules/gui/qt/maininterface/compositor.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
=====================================
@@ -206,6 +206,8 @@ void CompositorVideo::commonSetupVoutWindow(vlc_window_t* p_wnd, VoutDestroyCb d
this, &CompositorVideo::onSurfacePositionChanged, Qt::UniqueConnection);
connect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceSizeChanged,
this, &CompositorVideo::onSurfaceSizeChanged, Qt::UniqueConnection);
+ connect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceScaleChanged,
+ this, &CompositorVideo::onSurfaceScaleChanged, Qt::UniqueConnection);
}
void CompositorVideo::windowDestroy()
@@ -217,6 +219,8 @@ void CompositorVideo::windowDestroy()
this, &CompositorVideo::onSurfacePositionChanged);
disconnect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceSizeChanged,
this, &CompositorVideo::onSurfaceSizeChanged);
+ disconnect(m_videoSurfaceProvider.get(), &VideoSurfaceProvider::surfaceScaleChanged,
+ this, &CompositorVideo::onSurfaceScaleChanged);
if (m_destroyCb)
m_destroyCb(m_wnd);
=====================================
modules/gui/qt/maininterface/compositor.hpp
=====================================
@@ -173,6 +173,7 @@ private slots:
protected slots:
virtual void onSurfacePositionChanged(const QPointF&) {}
virtual void onSurfaceSizeChanged(const QSizeF&) {}
+ virtual void onSurfaceScaleChanged(qreal) {}
protected:
qt_intf_t *m_intf = nullptr;
=====================================
modules/gui/qt/maininterface/compositor_wayland.cpp
=====================================
@@ -17,8 +17,6 @@
*****************************************************************************/
#include "compositor_wayland.hpp"
-#include <cmath>
-
#include "maininterface/mainctx.hpp"
#include "maininterface/interface_window_handler.hpp"
@@ -117,7 +115,7 @@ bool CompositorWayland::makeMainInterface(MainCtx* mainCtx)
if (!interfaceSurface)
return false;
- m_waylandImpl->setupInterface(m_waylandImpl, interfaceSurface, std::ceil(dprForWindow(m_qmlView.get())));
+ m_waylandImpl->setupInterface(m_waylandImpl, interfaceSurface, dprForWindow(m_qmlView.get()));
CompositorVideo::Flags flags = CompositorVideo::CAN_SHOW_PIP | CompositorVideo::HAS_ACRYLIC;
@@ -238,6 +236,13 @@ void CompositorWayland::onSurfaceSizeChanged(const QSizeF& size)
size.height() / nativeDpr);
}
+void CompositorWayland::onSurfaceScaleChanged(qreal dpr)
+{
+ assert(m_waylandImpl);
+
+ m_waylandImpl->rescale(m_waylandImpl, dpr);
+}
+
#ifdef QT_WAYLAND_HAS_CUSTOM_MARGIN_SUPPORT
void CompositorWayland::adjustQuickWindowMask()
{
=====================================
modules/gui/qt/maininterface/compositor_wayland.hpp
=====================================
@@ -81,6 +81,7 @@ public:
protected slots:
void onSurfacePositionChanged(const QPointF&) override;
void onSurfaceSizeChanged(const QSizeF&) override;
+ void onSurfaceScaleChanged(qreal) override;
#ifdef QT_WAYLAND_HAS_CUSTOM_MARGIN_SUPPORT
void adjustQuickWindowMask();
#endif
=====================================
modules/gui/qt/maininterface/compositor_wayland_module.c
=====================================
@@ -29,7 +29,9 @@
#include "viewporter-client-protocol.h"
#endif
+#include <math.h>
#include <assert.h>
+#include <float.h>
typedef struct
{
@@ -49,6 +51,13 @@ typedef struct
struct wl_subsurface* video_subsurface;
int buffer_scale;
+ bool fractional_scale;
+
+ // Store the size, because we need them
+ // if the scale changes (if fractional)
+ // to update the viewport:
+ int width;
+ int height;
uint32_t compositor_interface_version;
} qtwayland_priv_t;
@@ -84,43 +93,97 @@ static const struct wl_registry_listener registry_cbs = {
registry_global_remove_cb,
};
-static int SetupInterface(qtwayland_t* obj, void* qpni_interface_surface, int scale)
+static void SetSize(struct qtwayland_t* obj, size_t width, size_t height)
{
- qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+ assert(obj);
+ qtwayland_priv_t* const sys = (qtwayland_priv_t*)obj->p_sys;
+ assert(sys);
- if (! qpni_interface_surface)
- return VLC_EGENERIC;
+ sys->width = width;
+ sys->height = height;
+}
- sys->interface_surface = (struct wl_surface*)qpni_interface_surface;
- sys->buffer_scale = scale;
+static void CommitSize(struct qtwayland_t* obj)
+{
+#ifdef QT_HAS_WAYLAND_FRACTIONAL_SCALING
+ assert(obj);
+ const qtwayland_priv_t* const sys = (qtwayland_priv_t*)obj->p_sys;
+ assert(sys);
+ if (!sys->video_surface)
+ return;
+ if (sys->viewport)
+ {
+ // Non-positive size (except (-1, -1) pair) causes protocol error:
+ assert((sys->width > 0 && sys->height > 0) ||
+ (sys->height == -1 && sys->width == -1));
- return VLC_SUCCESS;
+ // width and height here represent the final size, after scaling
+ // is taken into account. The fractional scaling protocol is not
+ // necessary, because the (fractional) scale is retrieved from the
+ // 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);
+ }
+#endif
}
-
-static int SetupVoutWindow(qtwayland_t* obj, vlc_window_t* wnd)
+static void SetScale(struct qtwayland_t* obj, double scale)
{
+ assert(obj);
qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+ assert(sys);
- sys->video_surface = wl_compositor_create_surface(sys->compositor);
- if (!sys->video_surface)
- return VLC_EGENERIC;
+ // Determine if scale is fractional:
+ assert(scale > 0.0);
+ sys->buffer_scale = ceil(scale);
-#ifdef QT_HAS_WAYLAND_FRACTIONAL_SCALING
- if (sys->viewporter)
- sys->viewport = wp_viewporter_get_viewport(sys->viewporter, sys->video_surface);
+ if ((sys->buffer_scale - scale) < DBL_EPSILON)
+ sys->fractional_scale = false;
else
-#endif
+ sys->fractional_scale = true;
+}
+
+static void CommitScale(struct qtwayland_t* obj)
+{
+ assert(obj);
+ qtwayland_priv_t* const sys = (qtwayland_priv_t*)obj->p_sys;
+ assert(sys);
+
+ // Once the scale becomes fractional, viewport is used.
+ // If the scale becomes an integer number after that,
+ // viewport is still used.
+ if (sys->fractional_scale)
{
- // The buffer scale must remain 1 when fractional scaling is used
- if (sys->buffer_scale != 1)
+#ifdef QT_HAS_WAYLAND_FRACTIONAL_SCALING
+ if (sys->viewporter)
+ {
+ if (!sys->viewport)
+ {
+ sys->viewport = wp_viewporter_get_viewport(sys->viewporter, sys->video_surface);
+
+ // The buffer scale must remain 1 when fractional scaling is used:
+ // If compositor has viewport support, it should be at least version 3:
+ if (likely(sys->compositor_interface_version >= 3))
+ {
+ wl_surface_set_buffer_scale(sys->video_surface, 1);
+ wl_surface_commit(sys->video_surface);
+ }
+
+ // Started using viewport, commit size so that viewport destination is set:
+ CommitSize(obj);
+ }
+ }
+ else
+#endif
{
msg_Dbg(obj, "Viewporter protocol is not available or Qt version is less than " \
- "6.5.0, and scale is not 1. Only integer scaling may be possible.");
+ "6.5.0, and scale is fractional. Only integer scaling may be possible.");
if (sys->compositor_interface_version >= 3)
{
wl_surface_set_buffer_scale(sys->video_surface, sys->buffer_scale);
+ wl_surface_commit(sys->video_surface);
}
else
{
@@ -129,6 +192,51 @@ static int SetupVoutWindow(qtwayland_t* obj, vlc_window_t* wnd)
}
}
}
+ else
+ {
+#ifdef QT_HAS_WAYLAND_FRACTIONAL_SCALING
+ // Scale is not fractional, but if viewport has been initialized before, keep using it:
+ if (!sys->viewport)
+#endif
+ {
+ if (sys->compositor_interface_version >= 3)
+ {
+ wl_surface_set_buffer_scale(sys->video_surface, sys->buffer_scale);
+ wl_surface_commit(sys->video_surface);
+ }
+ else
+ {
+ msg_Dbg(obj, "Compositor interface version is below 3, integer scaling " \
+ "is not possible.");
+ }
+ }
+ }
+}
+
+static int SetupInterface(qtwayland_t* obj, void* qpni_interface_surface, double scale)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+
+ if (! qpni_interface_surface)
+ return VLC_EGENERIC;
+
+ sys->interface_surface = (struct wl_surface*)qpni_interface_surface;
+
+ SetScale(obj, scale);
+
+ return VLC_SUCCESS;
+}
+
+
+static int SetupVoutWindow(qtwayland_t* obj, vlc_window_t* wnd)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+
+ sys->video_surface = wl_compositor_create_surface(sys->compositor);
+ if (!sys->video_surface)
+ return VLC_EGENERIC;
+
+ CommitScale(obj);
struct wl_region* region = wl_compositor_create_region(sys->compositor);
if (!region)
@@ -205,22 +313,52 @@ static void Move(struct qtwayland_t* obj, int x, int y)
static void Resize(struct qtwayland_t* obj, size_t width, size_t height)
{
-#ifdef QT_HAS_WAYLAND_FRACTIONAL_SCALING
+ assert(obj);
qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
assert(sys);
- if (!sys->video_surface)
- return;
- if (sys->viewport)
+
+ bool commitNecessary = false;
+
{
- // width and height here represent the final size, after scaling
- // is taken into account. The fractional scaling protocol is not
- // necessary, because the (fractional) scale is retrieved from the
- // Qt Quick window which uses the fractional scale protocol itself
- // to determine the device pixel ratio.
- wp_viewport_set_destination(sys->viewport, width, height);
- wl_surface_commit(sys->video_surface);
+ // Do not directly compare, because SetSize may not directly use size as is
+ const int oldWidth = sys->width;
+ const int oldHeight = sys->height;
+
+ SetSize(obj, width, height);
+
+ if (oldWidth != sys->width)
+ commitNecessary = true;
+ else if (oldHeight != sys->height)
+ commitNecessary = true;
}
-#endif
+
+ if (commitNecessary)
+ CommitSize(obj);
+}
+
+
+static void Rescale(struct qtwayland_t* obj, double scale)
+{
+ assert(obj);
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+ assert(sys);
+
+ bool commitNecessary = false;
+
+ {
+ const int oldBufferScale = sys->buffer_scale;
+ const bool oldFractionalScale = sys->fractional_scale;
+
+ SetScale(obj, scale);
+
+ if (oldBufferScale != sys->buffer_scale)
+ commitNecessary = true;
+ else if (oldFractionalScale != sys->fractional_scale)
+ commitNecessary = true;
+ }
+
+ if (commitNecessary)
+ CommitScale(obj);
}
static void Close(qtwayland_t* obj)
@@ -318,6 +456,7 @@ int OpenCompositor(vlc_object_t* p_this)
obj->disable = Disable;
obj->move = Move;
obj->resize = Resize;
+ obj->rescale = Rescale;
obj->p_sys = sys;
=====================================
modules/gui/qt/maininterface/compositor_wayland_module.h
=====================================
@@ -30,7 +30,7 @@ typedef struct qtwayland_t
bool (*init)(struct qtwayland_t*, void* display);
- int (*setupInterface)(struct qtwayland_t*, void* video_surface, int scale);
+ int (*setupInterface)(struct qtwayland_t*, void* video_surface, double scale);
int (*setupVoutWindow)(struct qtwayland_t*, vlc_window_t* p_wnd);
void (*teardownVoutWindow)(struct qtwayland_t*);
@@ -39,6 +39,7 @@ typedef struct qtwayland_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 (*rescale)(struct qtwayland_t*, double scale);
void (*close)(struct qtwayland_t*);
} qtwayland_t;
=====================================
modules/gui/qt/maininterface/videosurface.cpp
=====================================
@@ -327,7 +327,9 @@ void VideoSurface::updatePolish()
{
QQuickItem::updatePolish();
- if (m_sizeDirty)
+ assert(window());
+
+ if (m_sizeDirty && !size().isEmpty())
{
emit surfaceSizeChanged(size() * window()->effectiveDevicePixelRatio());
m_sizeDirty = false;
@@ -340,6 +342,22 @@ void VideoSurface::updatePolish()
emit surfacePositionChanged(scenePosition * window()->effectiveDevicePixelRatio());
m_positionDirty = false;
}
+
+ if (m_scaleDirty)
+ {
+ emit surfaceScaleChanged(window()->effectiveDevicePixelRatio());
+ m_scaleDirty = false;
+ }
+}
+
+void VideoSurface::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ if (change == ItemDevicePixelRatioHasChanged || change == ItemSceneChange)
+ {
+ updateSurfaceScale();
+ }
+
+ QQuickItem::itemChange(change, value);
}
void VideoSurface::updateSurfacePosition()
@@ -354,10 +372,17 @@ void VideoSurface::updateSurfaceSize()
polish();
}
-void VideoSurface::updateSurfacePositionAndSize()
+void VideoSurface::updateSurfaceScale()
+{
+ m_scaleDirty = true;
+ polish();
+}
+
+void VideoSurface::updateSurface()
{
updateSurfacePosition();
updateSurfaceSize();
+ updateSurfaceScale();
}
void VideoSurface::setVideoSurfaceProvider(VideoSurfaceProvider *newVideoSurfaceProvider)
@@ -381,12 +406,13 @@ void VideoSurface::setVideoSurfaceProvider(VideoSurfaceProvider *newVideoSurface
connect(this, &VideoSurface::keyPressed, m_provider, &VideoSurfaceProvider::onKeyPressed);
connect(this, &VideoSurface::surfaceSizeChanged, m_provider, &VideoSurfaceProvider::onSurfaceSizeChanged);
connect(this, &VideoSurface::surfacePositionChanged, m_provider, &VideoSurfaceProvider::surfacePositionChanged);
+ connect(this, &VideoSurface::surfaceScaleChanged, m_provider, &VideoSurfaceProvider::surfaceScaleChanged);
connect(m_wheelEventConverter, &WheelToVLCConverter::vlcWheelKey, m_provider, &VideoSurfaceProvider::onMouseWheeled);
- connect(m_provider, &VideoSurfaceProvider::videoEnabledChanged, this, &VideoSurface::updateSurfacePositionAndSize);
+ connect(m_provider, &VideoSurfaceProvider::videoEnabledChanged, this, &VideoSurface::updateSurface);
setFlag(ItemHasContents, true);
- updateSurfacePositionAndSize(); // Polish is queued anyway, updatePolish() should be called when the initial size is set.
+ updateSurface(); // Polish is queued anyway, updatePolish() should be called when the initial size is set.
}
else
{
=====================================
modules/gui/qt/maininterface/videosurface.hpp
=====================================
@@ -77,6 +77,7 @@ signals:
bool hasVideoEmbedChanged(bool);
void surfacePositionChanged(QPointF position);
void surfaceSizeChanged(QSizeF size);
+ void surfaceScaleChanged(qreal);
public slots:
void onWindowClosed();
@@ -126,9 +127,12 @@ protected:
void updatePolish() override;
+ void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
+
signals:
void surfaceSizeChanged(QSizeF);
void surfacePositionChanged(QPointF);
+ void surfaceScaleChanged(qreal);
void mousePressed( int vlcButton );
void mouseReleased( int vlcButton );
@@ -141,7 +145,8 @@ signals:
protected slots:
void updateSurfacePosition();
void updateSurfaceSize();
- void updateSurfacePositionAndSize();
+ void updateSurfaceScale();
+ void updateSurface();
void updateParentChanged();
@@ -156,6 +161,7 @@ private:
bool m_sizeDirty = false;
bool m_positionDirty = false;
+ bool m_scaleDirty = false;
};
#endif // VIDEOSURFACE_HPP
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c978d50db67ad19d3739bc184d07ff1af47cd3c0...6151e45a15958f7a804ea3f3245591b211975be1
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c978d50db67ad19d3739bc184d07ff1af47cd3c0...6151e45a15958f7a804ea3f3245591b211975be1
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