[vlc-devel] [PATCH 16/16] qt: provide video integration for windows 7
Steve Lhomme
robux4 at ycbcr.xyz
Thu Aug 6 16:35:12 CEST 2020
On 2020-08-06 9:44, Pierre Lamot wrote:
> this class is also used on windows when D3D isn't supported, because the dummy
> compositor uses QQuickWidget which requires opengl offscreen rendering (trough
> angle on windows)
> ---
> modules/gui/qt/Makefile.am | 7 +-
> modules/gui/qt/maininterface/compositor.cpp | 8 +
> .../gui/qt/maininterface/compositor_dummy.hpp | 8 +-
> .../gui/qt/maininterface/compositor_win7.cpp | 347 ++++++++++++++++++
> .../gui/qt/maininterface/compositor_win7.hpp | 85 +++++
> 5 files changed, 449 insertions(+), 6 deletions(-)
> create mode 100644 modules/gui/qt/maininterface/compositor_win7.cpp
> create mode 100644 modules/gui/qt/maininterface/compositor_win7.hpp
>
> diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
> index b5bcc03f73..c67b51abb0 100644
> --- a/modules/gui/qt/Makefile.am
> +++ b/modules/gui/qt/Makefile.am
> @@ -224,7 +224,9 @@ libqt_plugin_la_SOURCES = \
> if HAVE_WIN32
> libqt_plugin_la_SOURCES += \
> gui/qt/maininterface/main_interface_win32.cpp \
> - gui/qt/maininterface/main_interface_win32.hpp
> + gui/qt/maininterface/main_interface_win32.hpp \
> + gui/qt/maininterface/compositor_win7.cpp \
> + gui/qt/maininterface/compositor_win7.hpp
>
> if HAVE_DCOMP
> libqt_plugin_la_SOURCES += \
> @@ -343,7 +345,8 @@ nodist_libqt_plugin_la_SOURCES = \
> gui/qt/widgets/native/searchlineedit.moc.cpp
>
> if HAVE_WIN32
> -nodist_libqt_plugin_la_SOURCES += gui/qt/maininterface/main_interface_win32.moc.cpp
> +nodist_libqt_plugin_la_SOURCES += gui/qt/maininterface/main_interface_win32.moc.cpp \
> + gui/qt/maininterface/compositor_win7.moc.cpp
>
> if HAVE_DCOMP
> nodist_libqt_plugin_la_SOURCES += \
> diff --git a/modules/gui/qt/maininterface/compositor.cpp b/modules/gui/qt/maininterface/compositor.cpp
> index 535a49ea8e..ddfd217838 100644
> --- a/modules/gui/qt/maininterface/compositor.cpp
> +++ b/modules/gui/qt/maininterface/compositor.cpp
> @@ -23,6 +23,7 @@
> #ifdef HAVE_DCOMP_H
> # include "compositor_dcomp.hpp"
> #endif
> +# include "compositor_win7.hpp"
> #endif
>
> namespace vlc {
> @@ -39,7 +40,14 @@ Compositor* Compositor::createCompositor(intf_thread_t *p_intf)
> return dcomp_compositor;
> else
> delete dcomp_compositor;
> + msg_Dbg(p_intf, "failed to create DirectComposition backend, use fallback");
> #endif
> + CompositorWin7* win7_compositor = new CompositorWin7(p_intf);
> + if (win7_compositor->init())
> + return win7_compositor;
> + else
nitpicking: usually you don't need an "else" after a "return".
> + delete win7_compositor;
> + msg_Dbg(p_intf, "failed to create Win7 compositor backend, use fallback");
> #endif
> return new CompositorDummy(p_intf);
> }
> diff --git a/modules/gui/qt/maininterface/compositor_dummy.hpp b/modules/gui/qt/maininterface/compositor_dummy.hpp
> index 521700418d..a4af11439a 100644
> --- a/modules/gui/qt/maininterface/compositor_dummy.hpp
> +++ b/modules/gui/qt/maininterface/compositor_dummy.hpp
> @@ -34,18 +34,18 @@ class CompositorDummy : public QObject, public Compositor
> Q_OBJECT
> public:
> CompositorDummy(intf_thread_t *p_intf, QObject* parent = nullptr);
> - ~CompositorDummy() = default;
> + virtual ~CompositorDummy() = default;
>
> - MainInterface *makeMainInterface() override;
> + virtual MainInterface *makeMainInterface() override;
> virtual void destroyMainInterface() override;
>
> bool setupVoutWindow(vout_window_t *p_wnd, VoutDestroyCb destroyCb) override;
>
> -private:
> +protected:
>
> intf_thread_t *m_intf;
>
> - MainInterface* m_rootWindow;
> + MainInterface* m_rootWindow = nullptr;
> };
>
> }
> diff --git a/modules/gui/qt/maininterface/compositor_win7.cpp b/modules/gui/qt/maininterface/compositor_win7.cpp
> new file mode 100644
> index 0000000000..c923d2f9d9
> --- /dev/null
> +++ b/modules/gui/qt/maininterface/compositor_win7.cpp
> @@ -0,0 +1,347 @@
> +/*****************************************************************************
> + * Copyright (C) 2020 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_win7.hpp"
> +#include "main_interface_win32.hpp"
> +#include "mainui.hpp"
> +
> +#include <d3d11.h>
> +
> +#include <dwmapi.h>
> +#include <QLibrary>
> +
> +using namespace vlc;
> +
> +namespace {
> +struct VoutWindowPriv {
> + CompositorWin7* that = nullptr;
> + CompositorWin7::VoutDestroyCb voutDestroyCb = nullptr;
> +};
> +
> +}
> +
> +int CompositorWin7::window_enable(struct vout_window_t * p_wnd, const vout_window_cfg_t *)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + msg_Dbg(that->m_intf, "window_enable");
> + that->m_qmlVideoSurfaceProvider->enable(p_wnd);
> + return VLC_SUCCESS;
> +}
> +
> +void CompositorWin7::window_disable(struct vout_window_t * p_wnd)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + that->m_qmlVideoSurfaceProvider->disable();
> + that->m_videoWindowHandler->disable();
> + msg_Dbg(that->m_intf, "window_disable");
> +}
> +
> +void CompositorWin7::window_resize(struct vout_window_t * p_wnd, unsigned width, unsigned height)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + msg_Dbg(that->m_intf, "window_resize %ux%u", width, height);
> + that->m_videoWindowHandler->requestResizeVideo(width, height);
> +}
> +
> +void CompositorWin7::window_destroy(struct vout_window_t * p_wnd)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + bool canRelease = sys->voutDestroyCb(p_wnd);
> + delete sys;
> + if (!canRelease)
> + return;
> + msg_Dbg(that->m_intf, "window_destroy");
> +}
> +
> +void CompositorWin7::window_set_state(struct vout_window_t * p_wnd, unsigned state)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + msg_Dbg(that->m_intf, "window_set_state");
> + that->m_videoWindowHandler->requestVideoState(static_cast<vout_window_state>(state));
> +}
> +
> +void CompositorWin7::window_unset_fullscreen(struct vout_window_t * p_wnd)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + msg_Dbg(that->m_intf, "window_unset_fullscreen");
> + that->m_videoWindowHandler->requestVideoWindowed();
> +}
> +
> +void CompositorWin7::window_set_fullscreen(struct vout_window_t * p_wnd, const char *id)
> +{
> + VoutWindowPriv* sys = static_cast<VoutWindowPriv*>(p_wnd->sys);
> + CompositorWin7* that = sys->that;
> + msg_Dbg(that->m_intf, "window_set_fullscreen");
> + that->m_videoWindowHandler->requestVideoFullScreen(id);
> +}
> +
> +
> +CompositorWin7::CompositorWin7(intf_thread_t *p_intf, QObject* parent)
> + : CompositorDummy(p_intf, parent)
> +{
> +}
> +
> +CompositorWin7::~CompositorWin7()
> +{
> + if (m_taskbarWidget)
> + qApp->removeNativeEventFilter(m_taskbarWidget);
> + if (m_nativeEventFilter)
> + qApp->removeNativeEventFilter(m_nativeEventFilter);
> + if (m_stable)
> + delete m_stable;
> +}
> +
> +bool CompositorWin7::init()
> +{
> + //check whether D3DCompiler is available. whitout it Angle won't work
> + QLibrary d3dCompilerDll;
> + for (int i = 47; i > 41; --i)
> + {
> + d3dCompilerDll.setFileName(QString("D3DCOMPILER_%1.dll").arg(i));
> + if (d3dCompilerDll.load())
> + break;
> + }
> +
> + D3D_FEATURE_LEVEL requestedFeatureLevels[] = {
> + D3D_FEATURE_LEVEL_9_1,
> + D3D_FEATURE_LEVEL_9_2,
> + D3D_FEATURE_LEVEL_9_3,
> + D3D_FEATURE_LEVEL_10_0,
> + D3D_FEATURE_LEVEL_10_1,
> + D3D_FEATURE_LEVEL_11_1,
> + D3D_FEATURE_LEVEL_11_0,
> + };
> +
> + HRESULT hr = D3D11CreateDevice(
> + nullptr, // Adapter
> + D3D_DRIVER_TYPE_HARDWARE,
> + nullptr, // Module
> + D3D11_CREATE_DEVICE_BGRA_SUPPORT,
> + requestedFeatureLevels,
> + ARRAY_SIZE(requestedFeatureLevels),
> + D3D11_SDK_VERSION,
> + nullptr, //D3D device
> + nullptr, // Actual feature level
> + nullptr //D3D context
> + );
Since this is a D3D11 compositor. Can't there be some code shared with
the other non-win7 one ?
> +
> + //no hw acceleration, manually select the software backend
> + //otherwise Qt will load angle and fail.
> + if (!d3dCompilerDll.isLoaded() || FAILED(hr))
> + {
> + msg_Info(m_intf, "no D3D support, use software backend");
> + QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
> + }
> +
> + return true;
> +}
More information about the vlc-devel
mailing list