[vlc-commits] [Git][videolan/vlc][master] 5 commits: qml: fix video surface scaling
Thomas Guillem (@tguillem)
gitlab at videolan.org
Wed Jan 17 14:00:37 UTC 2024
Thomas Guillem pushed to branch master at VideoLAN / VLC
Commits:
32836475 by Pierre Lamot at 2024-01-17T13:34:48+00:00
qml: fix video surface scaling
QWindow::devicePixelRatio mixes QPlateformWindow::devicePixelRatio (scale factor
from the plateform) and QHighDpiScaling::factor (QT_SCALE_FACTOR,
QT_SCREEN_SCALE_FACTORS). Platform such as wayland may have a >1 scale factor,
surface are directly scaled by the compositor, so we shouln't re-apply this
scale factor
- - - - -
8d9907bd by Pierre Lamot at 2024-01-17T13:34:48+00:00
qt: fix CompositorVideo interface release order
m_videoWindowHandler references the window, so it needs to be released before the
window is destroyed
- - - - -
a290285a by Pierre Lamot at 2024-01-17T13:34:48+00:00
qt: don't include native interface headers using QPNI_HEADER macro
we have already fixed the private headers includes for QtQuick, this patch uses
the same mechanism
- - - - -
9dc025d0 by Pierre Lamot at 2024-01-17T13:34:48+00:00
qt: add wayland support
fixes #22156
- - - - -
3c622d4c by Pierre Lamot at 2024-01-17T13:34:48+00:00
qt: reorder compositor definitions in Makefile.am
no functionnal changes
- - - - -
16 changed files:
- configure.ac
- modules/gui/qt/Makefile.am
- 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_uisurface.cpp
- + 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/interface_window_handler.hpp
- modules/gui/qt/maininterface/mainctx_win32.cpp
- modules/gui/qt/maininterface/video_window_handler.hpp
- modules/gui/qt/maininterface/videosurface.cpp
- modules/gui/qt/maininterface/videosurface.hpp
- modules/gui/qt/qt.cpp
Changes:
=====================================
configure.ac
=====================================
@@ -3970,6 +3970,8 @@ AC_ARG_ENABLE([qt],
have_qt5_x11="no"
have_qt5_gtk="no"
have_qt5_quick_test="no"
+have_qt5_declarative_private="no"
+have_qt5_gui_private="no"
AS_IF([test "${enable_qt}" != "no"], [
PKG_CHECK_MODULES([QT], [Qt5Core >= 5.12.0 Qt5Widgets Qt5Gui Qt5Quick Qt5QuickWidgets Qt5QuickControls2 Qt5Svg], [
PKG_CHECK_MODULES([QT5_X11], [Qt5X11Extras], [
@@ -4037,7 +4039,9 @@ AS_IF([test "${enable_qt}" != "no"], [
AC_LANG_PUSH([C++])
AC_CHECK_HEADERS([private/qquickitem_p.h private/qquickwindow_p.h],
- [have_declarative_private="yes"], [])
+ [have_qt5_declarative_private="yes"], [])
+ AC_CHECK_HEADERS([QtGui/qpa/qplatformnativeinterface.h],
+ [have_qt5_gui_private="yes"], [])
AC_LANG_POP([C++])
VLC_RESTORE_FLAGS
@@ -4110,7 +4114,8 @@ AM_CONDITIONAL([ENABLE_QT], [test "$enable_qt" != "no"])
AM_CONDITIONAL([HAVE_QT5_X11], [test "${have_qt5_x11}" = "yes"])
AM_CONDITIONAL([HAVE_QT5_WAYLAND], [test "${have_qt5_wayland}" = "yes"])
AM_CONDITIONAL([HAVE_QT5_GTK], [test "${have_qt5_gtk}" = "yes"])
-AM_CONDITIONAL([HAVE_QT5_DECLARATIVE_PRIVATE], [test "${have_declarative_private}" = "yes"])
+AM_CONDITIONAL([HAVE_QT5_DECLARATIVE_PRIVATE], [test "${have_qt5_declarative_private}" = "yes"])
+AM_CONDITIONAL([HAVE_QT5_GUI_PRIVATE], [test "${have_qt5_gui_private}" = "yes"])
AM_CONDITIONAL([HAVE_QT5_QUICK_TEST], [test "${have_qt5_quick_test}" = "yes"])
dnl
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -51,29 +51,15 @@ if HAVE_XCB
libqt_plugin_la_CXXFLAGS += $(XCB_CFLAGS) -DQT5_HAS_X11
libqt_plugin_la_LIBADD += $(XCB_LIBS) $(X_LIBS) $(X_PRE_LIB) -lX11
vlc_qt_check_CXXFLAGS += $(XCB_CFLAGS) -DQT5_HAS_X11
-
-if HAVE_QT5_X11
-if HAVE_XCB_DAMAGE
-if HAVE_XCB_XFIXES
-libqt_plugin_la_CXXFLAGS += -DQT5_HAS_X11_COMPOSITOR \
- $(QT5_X11_CFLAGS) $(XCB_RENDER_CFLAGS) $(XCB_COMPOSITE_CFLAGS) $(XLCB_DAMAGE_CFLAGS) $(XCB_XFIXES_CFLAGS)
-libqt_plugin_la_LIBADD += $(QT5_X11_LIBS) $(XCB_RENDER_LIBS) $(XCB_COMPOSITE_LIBS) $(XCB_DAMAGE_LIBS) $(XCB_XFIXES_LIBS)
-endif
-endif
-endif
endif
-if HAVE_WAYLAND
-libqt_plugin_la_CPPFLAGS += -DQT5_HAS_WAYLAND
-libqt_plugin_la_CXXFLAGS += $(WAYLAND_CLIENT_CFLAGS)
-libqt_plugin_la_LIBADD += $(WAYLAND_CLIENT_LIBS)
-endif
if HAVE_QT5_WAYLAND
libqt_plugin_la_CPPFLAGS += $(QT5_WAYLAND_CFLAGS)
libqt_plugin_la_LIBADD += $(QT5_WAYLAND_LIBS)
vlc_qt_check_CPPFLAGS += $(QT5_WAYLAND_CFLAGS) -DQT5_HAS_WAYLAND
vlc_qt_check_LDADD += $(QT5_WAYLAND_LIBS)
endif
+
if HAVE_WIN32
libqt_plugin_la_CXXFLAGS += $(LIBCOMCXXFLAGS)
libqt_plugin_la_LIBADD += $(LIBCOM) -lcomctl32 -luuid -ld3d11 -ldwmapi
@@ -87,6 +73,15 @@ endif
if HAVE_QT5_GTK
libqt_plugin_la_CPPFLAGS += -DQT5_HAS_GTK
endif
+
+if HAVE_QT5_GUI_PRIVATE
+libqt_plugin_la_CPPFLAGS += -DQT5_GUI_PRIVATE \
+ -I$(QT_INCLUDE_DIRECTORY)/QtCore/$(QT_VERSION) \
+ -I$(QT_INCLUDE_DIRECTORY)/QtCore/$(QT_VERSION)/QtCore \
+ -I$(QT_INCLUDE_DIRECTORY)/QtGui/$(QT_VERSION) \
+ -I$(QT_INCLUDE_DIRECTORY)/QtGui/$(QT_VERSION)/QtGui
+endif
+
if HAVE_QT5_DECLARATIVE_PRIVATE
libqt_plugin_la_CPPFLAGS += -DQT5_DECLARATIVE_PRIVATE \
-I$(QT_INCLUDE_DIRECTORY)/QtCore/$(QT_VERSION) \
@@ -349,46 +344,6 @@ libqt_plugin_la_SOURCES = \
widgets/native/roundimage.cpp widgets/native/roundimage.hpp widgets/native/roundimage_p.hpp \
widgets/native/searchlineedit.cpp widgets/native/searchlineedit.hpp \
widgets/native/viewblockingrectangle.cpp widgets/native/viewblockingrectangle.hpp
-if HAVE_WIN32
-libqt_plugin_la_SOURCES += \
- maininterface/mainctx_win32.cpp \
- maininterface/mainctx_win32.hpp \
- maininterface/compositor_win7.cpp \
- maininterface/compositor_win7.hpp \
- style/windowsthemeprovider.cpp
-
-if HAVE_DCOMP
-libqt_plugin_la_SOURCES += \
- maininterface/compositor_dcomp.cpp \
- maininterface/compositor_dcomp.hpp \
- maininterface/compositor_dcomp_error.hpp \
- maininterface/compositor_dcomp_acrylicsurface.hpp \
- maininterface/compositor_dcomp_acrylicsurface.cpp \
- maininterface/compositor_dcomp_uisurface.cpp \
- maininterface/compositor_dcomp_uisurface.hpp
-endif
-
-endif
-
-if HAVE_QT5_X11
-if HAVE_XCB
-if HAVE_XCB_DAMAGE
-if HAVE_XCB_XFIXES
-libqt_plugin_la_SOURCES += \
- maininterface/compositor_x11.cpp \
- maininterface/compositor_x11.hpp \
- maininterface/compositor_x11_renderclient.cpp \
- maininterface/compositor_x11_renderclient.hpp \
- maininterface/compositor_x11_renderwindow.cpp \
- maininterface/compositor_x11_renderwindow.hpp \
- maininterface/compositor_x11_uisurface.cpp \
- maininterface/compositor_x11_uisurface.hpp \
- maininterface/compositor_x11_utils.cpp \
- maininterface/compositor_x11_utils.hpp
-endif
-endif
-endif
-endif
# Meta-object compilation
@@ -531,57 +486,128 @@ nodist_libqt_plugin_la_SOURCES = \
widgets/native/searchlineedit.moc.cpp \
widgets/native/viewblockingrectangle.moc.cpp
+nodist_libqt_plugin_la_SOURCES += \
+ dialogs/extended/ui_equalizer.h \
+ dialogs/extended/ui_video_effects.h \
+ dialogs/fingerprint/ui_fingerprintdialog.h \
+ dialogs/firstrun/ui_firstrunwizard.h \
+ dialogs/help/ui_about.h \
+ dialogs/help/ui_update.h \
+ dialogs/messages/ui_messages_panel.h \
+ dialogs/open/ui_open.h \
+ dialogs/open/ui_open_capture.h \
+ dialogs/open/ui_open_disk.h \
+ dialogs/open/ui_open_file.h \
+ dialogs/open/ui_open_net.h \
+ dialogs/podcast/ui_podcast_configuration.h \
+ dialogs/preferences/ui_sprefs_audio.h \
+ dialogs/preferences/ui_sprefs_input.h \
+ dialogs/preferences/ui_sprefs_interface.h \
+ dialogs/preferences/ui_sprefs_medialibrary.h \
+ dialogs/preferences/ui_sprefs_subtitles.h \
+ dialogs/preferences/ui_sprefs_video.h \
+ dialogs/sout/ui_profiles.h \
+ dialogs/sout/ui_sout.h \
+ dialogs/vlm/ui_vlm.h
+
+
+# windows compositor
+
if HAVE_WIN32
+
+libqt_plugin_la_SOURCES += \
+ maininterface/mainctx_win32.cpp \
+ maininterface/mainctx_win32.hpp \
+ maininterface/compositor_win7.cpp \
+ maininterface/compositor_win7.hpp \
+ style/windowsthemeprovider.cpp
+
nodist_libqt_plugin_la_SOURCES += maininterface/mainctx_win32.moc.cpp \
maininterface/compositor_win7.moc.cpp
if HAVE_DCOMP
+libqt_plugin_la_SOURCES += \
+ maininterface/compositor_dcomp.cpp \
+ maininterface/compositor_dcomp.hpp \
+ maininterface/compositor_dcomp_error.hpp \
+ maininterface/compositor_dcomp_acrylicsurface.hpp \
+ maininterface/compositor_dcomp_acrylicsurface.cpp \
+ maininterface/compositor_dcomp_uisurface.cpp \
+ maininterface/compositor_dcomp_uisurface.hpp
+
nodist_libqt_plugin_la_SOURCES += \
maininterface/compositor_dcomp_acrylicsurface.moc.cpp \
maininterface/compositor_dcomp.moc.cpp \
maininterface/compositor_dcomp_uisurface.moc.cpp
-endif
endif
+endif
+
+# X11 compositor
if HAVE_QT5_X11
if HAVE_XCB
if HAVE_XCB_DAMAGE
if HAVE_XCB_XFIXES
+
+libqt_plugin_la_CXXFLAGS += -DQT5_HAS_X11_COMPOSITOR \
+ $(QT5_X11_CFLAGS) $(XCB_RENDER_CFLAGS) $(XCB_COMPOSITE_CFLAGS) $(XLCB_DAMAGE_CFLAGS) $(XCB_XFIXES_CFLAGS)
+
+libqt_plugin_la_LIBADD += $(QT5_X11_LIBS) $(XCB_RENDER_LIBS) $(XCB_COMPOSITE_LIBS) $(XCB_DAMAGE_LIBS) $(XCB_XFIXES_LIBS)
+
+libqt_plugin_la_SOURCES += \
+ maininterface/compositor_x11.cpp \
+ maininterface/compositor_x11.hpp \
+ maininterface/compositor_x11_renderclient.cpp \
+ maininterface/compositor_x11_renderclient.hpp \
+ maininterface/compositor_x11_renderwindow.cpp \
+ maininterface/compositor_x11_renderwindow.hpp \
+ maininterface/compositor_x11_uisurface.cpp \
+ maininterface/compositor_x11_uisurface.hpp \
+ maininterface/compositor_x11_utils.cpp \
+ maininterface/compositor_x11_utils.hpp
+
nodist_libqt_plugin_la_SOURCES += \
maininterface/compositor_x11.moc.cpp \
maininterface/compositor_x11_renderclient.moc.cpp \
maininterface/compositor_x11_renderwindow.moc.cpp \
maininterface/compositor_x11_uisurface.moc.cpp \
maininterface/compositor_x11_utils.moc.cpp
+
endif
endif
endif
endif
+# wayland compositor
+
+if HAVE_WAYLAND
+if HAVE_QT5_WAYLAND
+if HAVE_QT5_GUI_PRIVATE
+
+libqt_plugin_la_CPPFLAGS += -DQT5_HAS_WAYLAND_COMPOSITOR
+
+libqt_plugin_la_SOURCES += \
+ maininterface/compositor_wayland.cpp \
+ maininterface/compositor_wayland.hpp
+
+
nodist_libqt_plugin_la_SOURCES += \
- dialogs/extended/ui_equalizer.h \
- dialogs/extended/ui_video_effects.h \
- dialogs/fingerprint/ui_fingerprintdialog.h \
- dialogs/firstrun/ui_firstrunwizard.h \
- dialogs/help/ui_about.h \
- dialogs/help/ui_update.h \
- dialogs/messages/ui_messages_panel.h \
- dialogs/open/ui_open.h \
- dialogs/open/ui_open_capture.h \
- dialogs/open/ui_open_disk.h \
- dialogs/open/ui_open_file.h \
- dialogs/open/ui_open_net.h \
- dialogs/podcast/ui_podcast_configuration.h \
- dialogs/preferences/ui_sprefs_audio.h \
- dialogs/preferences/ui_sprefs_input.h \
- dialogs/preferences/ui_sprefs_interface.h \
- dialogs/preferences/ui_sprefs_medialibrary.h \
- dialogs/preferences/ui_sprefs_subtitles.h \
- dialogs/preferences/ui_sprefs_video.h \
- dialogs/sout/ui_profiles.h \
- dialogs/sout/ui_sout.h \
- dialogs/vlm/ui_vlm.h
+ maininterface/compositor_wayland.moc.cpp
+
+libqt_wayland_plugin_la_CFLAGS = $(AM_CFLAGS) $(WAYLAND_CLIENT_CFLAGS)
+libqt_wayland_plugin_la_LIBADD = $(WAYLAND_CLIENT_LIBS)
+libqt_wayland_plugin_la_SOURCES = \
+ maininterface/compositor_wayland_module.c \
+ maininterface/compositor_wayland_module.h
+
+if ENABLE_QT
+gui_LTLIBRARIES += libqt_wayland_plugin.la
+endif
+
+endif
+endif
+endif
# User interface compilation
=====================================
modules/gui/qt/maininterface/compositor.cpp
=====================================
@@ -32,6 +32,10 @@
# include "compositor_win7.hpp"
#endif
+#ifdef QT5_HAS_WAYLAND_COMPOSITOR
+# include "compositor_wayland.hpp"
+#endif
+
#ifdef QT5_HAS_X11_COMPOSITOR
# include "compositor_x11.hpp"
#endif
@@ -61,6 +65,9 @@ struct {
#endif
{"win7", &instanciateCompositor<CompositorWin7>, &preInit<CompositorWin7> },
#endif
+#ifdef QT5_HAS_WAYLAND_COMPOSITOR
+ {"wayland", &instanciateCompositor<CompositorWayland>, &preInit<CompositorWayland> },
+#endif
#ifdef QT5_HAS_X11_COMPOSITOR
{"x11", &instanciateCompositor<CompositorX11>, &preInit<CompositorX11> },
#endif
@@ -309,7 +316,7 @@ void CompositorVideo::commonGUIDestroy()
void CompositorVideo::commonIntfDestroy()
{
- unloadGUI();
m_videoWindowHandler.reset();
m_videoSurfaceProvider.reset();
+ unloadGUI();
}
=====================================
modules/gui/qt/maininterface/compositor.hpp
=====================================
@@ -58,7 +58,8 @@ public:
DummyCompositor,
Win7Compositor,
DirectCompositionCompositor,
- X11Compositor
+ X11Compositor,
+ WaylandCompositor
};
typedef void (*VoutDestroyCb)(vlc_window_t *p_wnd);
=====================================
modules/gui/qt/maininterface/compositor_dcomp.cpp
=====================================
@@ -37,7 +37,11 @@
#include <QOpenGLFramebufferObject>
#include <QOpenGLExtraFunctions>
-#include QPNI_HEADER
+#ifndef QT5_GUI_PRIVATE
+#warning "qplatformnativeinterface.h header is required for DirectComposiiton compositor"
+#endif
+#include <QtGui/qpa/qplatformnativeinterface.h>
+
#include "compositor_dcomp_error.hpp"
#include "maininterface/interface_window_handler.hpp"
=====================================
modules/gui/qt/maininterface/compositor_dcomp_uisurface.cpp
=====================================
@@ -27,7 +27,10 @@
#include <QQmlEngine>
#include <QQuickItem>
-#include QPNI_HEADER
+#ifndef QT5_GUI_PRIVATE
+#warning "qplatformnativeinterface.h header is required for DirectComposiiton compositor"
+#endif
+#include <QtGui/qpa/qplatformnativeinterface.h>
#include <d3d11_1.h>
#include <d3dcompiler.h>
=====================================
modules/gui/qt/maininterface/compositor_wayland.cpp
=====================================
@@ -0,0 +1,207 @@
+/*****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include "compositor_wayland.hpp"
+
+#include "maininterface/mainctx.hpp"
+#include "maininterface/interface_window_handler.hpp"
+
+#ifndef QT5_GUI_PRIVATE
+#warning "qplatformnativeinterface is requried for wayland compositor"
+#endif
+
+#include <QtGui/qpa/qplatformnativeinterface.h>
+#include <QtGui/qpa/qplatformwindow.h>
+
+#include <vlc_window.h>
+#include <vlc_modules.h>
+
+#include "compositor_wayland_module.h"
+
+namespace vlc {
+
+CompositorWayland::CompositorWayland(qt_intf_t *p_intf, QObject* parent)
+ : CompositorVideo(p_intf, parent)
+{
+}
+
+CompositorWayland::~CompositorWayland()
+{
+ if (m_waylandImpl)
+ {
+ if (m_waylandImpl->p_module)
+ {
+ m_waylandImpl->close(m_waylandImpl);
+ module_unneed(m_waylandImpl, m_waylandImpl->p_module);
+ }
+ vlc_object_delete(m_waylandImpl);
+ }
+}
+
+bool CompositorWayland::preInit(qt_intf_t *)
+{
+ return true;
+}
+
+bool CompositorWayland::init()
+{
+ QPlatformNativeInterface* native = QGuiApplication::platformNativeInterface();
+
+ //get "wl_display" and not "display", as "display" may refer to other concept in other QPA
+ //so this will fail if qt doesn't use wayland
+ void* qpni_display = native->nativeResourceForIntegration("wl_display");
+ if (!qpni_display)
+ return false;
+
+ /*
+ * a separate wayland module is used to perform direct wayland calls
+ * without requiring Qt module to be directly linked to wayland
+ */
+ m_waylandImpl = static_cast<qtwayland_t*>(vlc_object_create(m_intf, sizeof(qtwayland_t)));
+ if (!m_waylandImpl)
+ return false;
+
+ m_waylandImpl->p_module = module_need(m_waylandImpl, "qtwayland", nullptr, false);
+ if (!m_waylandImpl->p_module)
+ {
+ msg_Err(m_intf, "the qtwayland module is not available, wayland"
+ "embedded video output will not be possible");
+ vlc_object_delete(m_waylandImpl);
+ m_waylandImpl = nullptr;
+
+ return false;
+ }
+
+ return m_waylandImpl->init(m_waylandImpl, qpni_display);
+}
+
+bool CompositorWayland::makeMainInterface(MainCtx* mainCtx)
+{
+ assert(mainCtx);
+ m_mainCtx = mainCtx;
+
+ m_qmlView = std::make_unique<QQuickView>();
+ if (m_mainCtx->useClientSideDecoration())
+ m_qmlView->setFlag(Qt::FramelessWindowHint);
+ m_qmlView->setResizeMode(QQuickView::SizeRootObjectToView);
+ m_qmlView->setClearBeforeRendering(true);
+ m_qmlView->setColor(QColor(Qt::transparent));
+
+ m_qmlView->show();
+
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ void* interfaceSurface = nativeInterface->nativeResourceForWindow("surface", m_qmlView.get());
+ if (!interfaceSurface)
+ return false;
+
+ m_waylandImpl->setupInterface(m_waylandImpl, interfaceSurface);
+
+ return commonGUICreate(m_qmlView.get(), m_qmlView.get(),
+ CompositorVideo::CAN_SHOW_PIP);
+}
+
+QWindow* CompositorWayland::interfaceMainWindow() const
+{
+ return m_qmlView.get();
+}
+
+void CompositorWayland::destroyMainInterface()
+{
+ unloadGUI();
+}
+
+void CompositorWayland::unloadGUI()
+{
+ //needs to be released before the window
+ m_interfaceWindowHandler.reset();
+
+ m_qmlView.reset();
+ commonGUIDestroy();
+}
+
+Compositor::Type CompositorWayland::type() const
+{
+ return Compositor::WaylandCompositor;
+}
+
+QQuickItem * CompositorWayland::activeFocusItem() const
+{
+ return m_qmlView->activeFocusItem();
+}
+
+// vout functions
+
+bool CompositorWayland::setupVoutWindow(vlc_window_t* p_wnd, VoutDestroyCb destroyCb)
+{
+ int ret = m_waylandImpl->setupVoutWindow(m_waylandImpl, p_wnd);
+ if (ret != VLC_SUCCESS)
+ return false;
+
+ commonSetupVoutWindow(p_wnd, destroyCb);
+
+ return true;
+}
+
+void CompositorWayland::windowDestroy()
+{
+ m_waylandImpl->teardownVoutWindow(m_waylandImpl);
+ CompositorVideo::windowDestroy();
+}
+
+int CompositorWayland::windowEnable(const vlc_window_cfg_t * cfg)
+{
+ m_waylandImpl->enable(m_waylandImpl, cfg);
+ commonWindowEnable();
+ return VLC_SUCCESS;
+}
+
+void CompositorWayland::windowDisable()
+{
+ m_waylandImpl->disable(m_waylandImpl);
+ commonWindowDisable();
+}
+
+static qreal dprForWindow(QQuickWindow* window)
+{
+ qreal dpr = window->devicePixelRatio();
+
+ QPlatformWindow* nativeWindow = window->handle();
+ if (nativeWindow)
+ dpr /= nativeWindow->devicePixelRatio();
+
+ return dpr;
+}
+
+void CompositorWayland::onSurfacePositionChanged(const QPointF& position)
+{
+ QMargins margins = m_qmlView->frameMargins();
+
+ qreal dpr = dprForWindow(m_qmlView.get());
+
+ m_waylandImpl->move(m_waylandImpl,
+ margins.left() * dpr + position.x(),
+ margins.top() * dpr + position.y());
+}
+
+void CompositorWayland::onSurfaceSizeChanged(const QSizeF& size)
+{
+ m_waylandImpl->resize(m_waylandImpl,
+ size.width(),
+ size.height());
+}
+
+}
=====================================
modules/gui/qt/maininterface/compositor_wayland.hpp
=====================================
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef VLC_COMPOSITOR_WAYLAND
+#define VLC_COMPOSITOR_WAYLAND
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <memory>
+#include "compositor.hpp"
+
+class MainCtx;
+class QQuickView;
+class InterfaceWindowHandler;
+
+extern "C" {
+typedef struct qtwayland_t qtwayland_t;
+}
+
+namespace vlc {
+
+class CompositorWayland : public CompositorVideo
+{
+ Q_OBJECT
+public:
+ CompositorWayland(qt_intf_t *p_intf, QObject* parent = nullptr);
+ virtual ~CompositorWayland();
+
+ static bool preInit(qt_intf_t*);
+ virtual bool init() override;
+
+ virtual bool makeMainInterface(MainCtx*) override;
+
+ /**
+ * @brief release all resources used by the compositor.
+ * this includes the GUI and the video surfaces.
+ */
+ virtual void destroyMainInterface() override;
+
+ /**
+ * @brief unloadGUI unload the UI view from the composition
+ * video view might still be active
+ */
+ virtual void unloadGUI() override;
+
+
+ QWindow* interfaceMainWindow() const override;
+
+ Type type() const override;
+
+ QQuickItem * activeFocusItem() const override;
+
+ //video integration
+
+
+ bool setupVoutWindow(vlc_window_t *p_wnd, VoutDestroyCb destroyCb) override;
+ void windowDestroy() override;
+
+ virtual int windowEnable(const vlc_window_cfg_t *) override;
+ virtual void windowDisable() override;
+
+protected slots:
+ virtual void onSurfacePositionChanged(const QPointF&) override;
+ virtual void onSurfaceSizeChanged(const QSizeF&) override;
+
+
+protected:
+ std::unique_ptr<QQuickView> m_qmlView;
+ qtwayland_t* m_waylandImpl = nullptr;
+};
+
+}
+
+#endif // VLC_COMPOSITOR_WAYLAND
=====================================
modules/gui/qt/maininterface/compositor_wayland_module.c
=====================================
@@ -0,0 +1,244 @@
+/*****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "compositor_wayland_module.h"
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <wayland-client.h>
+
+#include <assert.h>
+
+typedef struct
+{
+ struct wl_display* display;
+ struct wl_event_queue* queue;
+ struct wl_compositor* compositor;
+ struct wl_subcompositor* subcompositor;
+
+ struct wl_surface* interface_surface;
+
+ struct wl_surface* video_surface;
+ struct wl_subsurface* video_subsurface;
+} qtwayland_priv_t;
+
+static void registry_global_cb(void* data, struct wl_registry* registry,
+ uint32_t id, const char* iface, uint32_t version)
+{
+ VLC_UNUSED(version);
+
+ qtwayland_t* obj = (qtwayland_t*)data;
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+
+ if (!strcmp(iface, "wl_subcompositor"))
+ sys->subcompositor = (struct wl_subcompositor*)wl_registry_bind(registry, id, &wl_subcompositor_interface, version);
+ if (!strcmp(iface, "wl_compositor"))
+ sys->compositor = (struct wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, version);
+}
+
+static void registry_global_remove_cb(void* data, struct wl_registry* registry, uint32_t id)
+{
+ VLC_UNUSED(data);
+ VLC_UNUSED(registry);
+ VLC_UNUSED(id);
+}
+
+static const struct wl_registry_listener registry_cbs = {
+ registry_global_cb,
+ registry_global_remove_cb,
+};
+
+static int SetupInterface(qtwayland_t* obj, void* qpni_interface_surface)
+{
+ 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;
+
+ 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;
+
+ struct wl_region* region = wl_compositor_create_region(sys->compositor);
+ if (!region)
+ {
+ wl_surface_destroy(sys->video_surface);
+ sys->video_surface = NULL;
+ return VLC_EGENERIC;
+ }
+ wl_region_add(region, 0, 0, 0, 0);
+ wl_surface_set_input_region(sys->video_surface, region);
+
+ wl_region_destroy(region);
+ wl_surface_commit(sys->video_surface);
+
+ //setup vout window
+ wnd->type = VLC_WINDOW_TYPE_WAYLAND;
+ wnd->handle.wl = sys->video_surface;
+ wnd->display.wl = sys->display;
+
+ return VLC_SUCCESS;
+}
+
+static void TeardownVoutWindow(struct qtwayland_t* obj)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+ vlc_assert(sys->video_surface);
+ wl_surface_destroy(sys->video_surface);
+ sys->video_surface = NULL;
+}
+
+static void Enable(qtwayland_t* obj, const vlc_window_cfg_t * conf)
+{
+ VLC_UNUSED(conf);
+
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+
+ vlc_assert(sys->video_subsurface == NULL);
+ vlc_assert(sys->video_surface);
+ vlc_assert(sys->interface_surface);
+
+ sys->video_subsurface = wl_subcompositor_get_subsurface(sys->subcompositor, sys->video_surface, sys->interface_surface);
+ wl_subsurface_place_below(sys->video_subsurface, sys->interface_surface);
+ wl_subsurface_set_desync(sys->video_subsurface);
+ wl_surface_commit(sys->video_surface);
+}
+
+static void Disable(qtwayland_t* obj)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+ vlc_assert(sys->video_subsurface);
+
+ wl_subsurface_destroy(sys->video_subsurface);
+ sys->video_subsurface = NULL;
+ wl_surface_commit(sys->video_surface);
+}
+
+static void Move(struct qtwayland_t* obj, int x, int y)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)obj->p_sys;
+ wl_subsurface_set_position(sys->video_subsurface, x, y);
+ wl_surface_commit(sys->video_surface);
+}
+
+static void Resize(struct qtwayland_t* obj, size_t width, size_t height)
+{
+ VLC_UNUSED(obj);
+ VLC_UNUSED(width);
+ VLC_UNUSED(height);
+}
+
+static void Close(qtwayland_t* obj)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)(obj->p_sys);
+ wl_display_flush(sys->display);
+ wl_event_queue_destroy(sys->queue);
+}
+
+static bool Init(qtwayland_t* obj, void* qpni_display)
+{
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)(obj->p_sys);
+ struct wl_display* display = (struct wl_display*)(qpni_display);
+
+ sys->display = display;
+ if (!display)
+ {
+ msg_Err(obj, "wayland display is missing");
+ goto error;
+ }
+
+ sys->queue = wl_display_create_queue(display);
+ void* wrapper = wl_proxy_create_wrapper(display);
+ wl_proxy_set_queue((struct wl_proxy*)wrapper, sys->queue);
+
+ struct wl_registry* registry = wl_display_get_registry((struct wl_display*)wrapper);
+ wl_proxy_wrapper_destroy(wrapper);
+
+ wl_registry_add_listener(registry, ®istry_cbs, obj);
+ wl_display_roundtrip_queue(display, sys->queue);
+
+ wl_registry_destroy(registry);
+
+ if (!sys->compositor || !sys->subcompositor )
+ goto error;
+
+ return true;
+
+error:
+ if (sys->queue)
+ wl_event_queue_destroy(sys->queue);
+ return false;
+}
+
+static int Open(vlc_object_t* p_this)
+{
+ qtwayland_t* obj = (qtwayland_t*)p_this;
+
+ struct wl_display *dpy = wl_display_connect( NULL );
+ if( dpy == NULL )
+ {
+ //not using wayland
+ return VLC_EGENERIC;
+ }
+
+ wl_display_disconnect( dpy );
+
+ qtwayland_priv_t* sys = (qtwayland_priv_t*)vlc_obj_calloc(p_this, 1, sizeof(qtwayland_priv_t));
+ if (!sys)
+ return VLC_ENOMEM;
+
+
+ //module functions
+ obj->init = Init;
+ obj->close = Close;
+
+ //interface functions
+ obj->setupInterface = SetupInterface;
+
+ //video functions
+ obj->setupVoutWindow = SetupVoutWindow;
+ obj->teardownVoutWindow = TeardownVoutWindow;
+ obj->enable = Enable;
+ obj->disable = Disable;
+ obj->move = Move;
+ obj->resize = Resize;
+
+ obj->p_sys = sys;
+
+ return VLC_SUCCESS;
+}
+
+vlc_module_begin()
+ set_shortname(N_("QtWayland"))
+ set_description(N_(" calls for compositing with Qt"))
+ set_capability("qtwayland", 10)
+ set_callback(Open)
+vlc_module_end()
=====================================
modules/gui/qt/maininterface/compositor_wayland_module.h
=====================================
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMPOSITOR_WAYLAND_MODULE_H
+#define COMPOSITOR_WAYLAND_MODULE_H
+
+#include <vlc_window.h>
+
+typedef struct qtwayland_t
+{
+ struct vlc_object_t obj;
+
+ module_t* p_module;
+ void* p_sys;
+
+ bool (*init)(struct qtwayland_t*, void* display);
+
+ int (*setupInterface)(struct qtwayland_t*, void* video_surface );
+
+ int (*setupVoutWindow)(struct qtwayland_t*, vlc_window_t* p_wnd);
+ void (*teardownVoutWindow)(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 (*close)(struct qtwayland_t*);
+} qtwayland_t;
+
+
+#endif // COMPOSITOR_WAYLAND_MODULE_H
=====================================
modules/gui/qt/maininterface/interface_window_handler.hpp
=====================================
@@ -22,6 +22,7 @@
#include <QObject>
#include <QWindow>
+#include <QPointer>
class MainCtx;
class InterfaceWindowHandler : public QObject
@@ -69,7 +70,7 @@ private:
protected:
qt_intf_t* p_intf = nullptr;
- QWindow* m_window = nullptr;
+ QPointer<QWindow> m_window;
MainCtx* m_mainCtx = nullptr;
=====================================
modules/gui/qt/maininterface/mainctx_win32.cpp
=====================================
@@ -40,8 +40,11 @@
#include <cassert>
#include <QWindow>
-#include QPNI_HEADER
+#ifndef QT5_GUI_PRIVATE
+#warning "qplatformnativeinterface.h header is required for MainCtxWin32"
+#endif
+#include <QtGui/qpa/qplatformnativeinterface.h>
#include <dwmapi.h>
#define WM_APPCOMMAND 0x0319
=====================================
modules/gui/qt/maininterface/video_window_handler.hpp
=====================================
@@ -26,6 +26,7 @@
#include <QWindow>
#include <QObject>
+#include <QPointer>
#include "qt.hpp"
@@ -59,7 +60,7 @@ protected slots:
private:
qt_intf_t *m_intf = nullptr;
- QWindow* m_window = nullptr;
+ QPointer<QWindow> m_window;
bool m_videoFullScreen = false;
bool m_autoresize = false;
=====================================
modules/gui/qt/maininterface/videosurface.cpp
=====================================
@@ -22,6 +22,11 @@
#include <QThreadPool>
#include <vlc_window.h>
+#include <QQuickRenderControl>
+#ifdef QT5_DECLARATIVE_PRIVATE
+# include <QtGui/qpa/qplatformwindow.h>
+#endif
+
WindowResizer::WindowResizer(vlc_window_t* window):
m_requestedWidth(0),
m_requestedHeight(0),
@@ -367,14 +372,34 @@ void VideoSurface::onProviderVideoChanged(bool hasVideo)
updatePositionAndSize();
}
+static qreal dprForWindow(QQuickWindow* quickWindow)
+{
+ if (!quickWindow)
+ return 1.0;
+
+ QWindow* window = QQuickRenderControl::renderWindowFor(quickWindow);
+ if (!window)
+ window = quickWindow;
+
+ qreal dpr = window->devicePixelRatio();
+
+#ifdef QT5_DECLARATIVE_PRIVATE
+ QPlatformWindow* nativeWindow = window->handle();
+ if (nativeWindow)
+ dpr /= nativeWindow->devicePixelRatio();
+#endif
+
+ return dpr;
+}
+
void VideoSurface::onSurfaceSizeChanged()
{
if (!isEnabled())
return;
- QQuickWindow* window = this->window();
- if (!window)
- return;
- emit surfaceSizeChanged(size() * window->effectiveDevicePixelRatio());
+
+ qreal dpr = dprForWindow(window());
+
+ emit surfaceSizeChanged(size() * dpr);
}
void VideoSurface::onSurfacePositionChanged()
@@ -382,11 +407,10 @@ void VideoSurface::onSurfacePositionChanged()
if (!isEnabled())
return;
+ qreal dpr = dprForWindow(window());
+
QPointF scenePosition = this->mapToScene(QPointF(0,0));
- QQuickWindow* window = this->window();
- if (!window)
- return;
- qreal dpr = window->effectiveDevicePixelRatio();
+
emit surfacePositionChanged(scenePosition * dpr);
}
@@ -395,10 +419,8 @@ void VideoSurface::updatePositionAndSize()
if (!isEnabled())
return;
- QQuickWindow* window = this->window();
- if (!window)
- return;
- qreal dpr = window->effectiveDevicePixelRatio();
+ qreal dpr = dprForWindow(window());
+
emit surfaceSizeChanged(size() * dpr);
QPointF scenePosition = this->mapToScene(QPointF(0, 0));
emit surfacePositionChanged(scenePosition * dpr);
=====================================
modules/gui/qt/maininterface/videosurface.hpp
=====================================
@@ -21,6 +21,7 @@
#include "widgets/native/viewblockingrectangle.hpp"
#include <QMutex>
#include <QRunnable>
+#include <QPointer>
#include "qt.hpp"
#include <vlc_threads.h>
@@ -148,7 +149,7 @@ private:
QPointF m_oldHoverPos;
- VideoSurfaceProvider* m_provider = nullptr;
+ QPointer<VideoSurfaceProvider> m_provider;
};
#endif // VIDEOSURFACE_HPP
=====================================
modules/gui/qt/qt.cpp
=====================================
@@ -268,6 +268,9 @@ static const char *const compositor_vlc[] = {
#endif
"win7",
#endif
+#ifdef QT5_HAS_WAYLAND_COMPOSITOR
+ "wayland",
+#endif
#ifdef QT5_HAS_X11_COMPOSITOR
"x11",
#endif
@@ -281,6 +284,9 @@ static const char *const compositor_user[] = {
#endif
"Windows 7",
#endif
+#ifdef QT5_HAS_WAYLAND_COMPOSITOR
+ "Wayland",
+#endif
#ifdef QT5_HAS_X11_COMPOSITOR
N_("X11"),
#endif
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b2406ca91c882516324d1185ecf10ceed064b9e6...3c622d4cc240883cb4ac03ad8ec7a63ba2dff7d6
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b2406ca91c882516324d1185ecf10ceed064b9e6...3c622d4cc240883cb4ac03ad8ec7a63ba2dff7d6
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