[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