diff --git a/modules/gui/qt/maininterface/compositor.cpp b/modules/gui/qt/maininterface/compositor.cpp
index dc5b6933ba0da0ad0f2428ca794c53e2584c129c..f49c17adfa256005151165e2d76883f8e326237a 100644
--- a/modules/gui/qt/maininterface/compositor.cpp
+++ b/modules/gui/qt/maininterface/compositor.cpp
@@ -28,26 +28,62 @@
 
 namespace vlc {
 
-Compositor* Compositor::createCompositor(qt_intf_t *p_intf)
-{
-    bool ret;
-    VLC_UNUSED(ret);
+template<typename T>
+static Compositor* instanciateCompositor(qt_intf_t *p_intf) {
+    return new T(p_intf);
+}
+
+template<typename T>
+static bool preInit(qt_intf_t *p_intf) {
+    return T::preInit(p_intf);
+}
+
+struct {
+    const char* name;
+    Compositor* (*instanciate)(qt_intf_t *p_intf);
+    bool (*preInit)(qt_intf_t *p_intf);
+} static compositorList[] = {
 #ifdef _WIN32
 #ifdef HAVE_DCOMP_H
-    CompositorDirectComposition* dcomp_compositor = new CompositorDirectComposition(p_intf);
-    ret = dcomp_compositor->init();
-    if (ret)
-        return dcomp_compositor;
-    delete dcomp_compositor;
-    msg_Dbg(p_intf, "failed to create DirectComposition backend, use fallback");
+    {"dcomp", &instanciateCompositor<CompositorDirectComposition>, &preInit<CompositorDirectComposition> },
 #endif
-    CompositorWin7* win7_compositor = new CompositorWin7(p_intf);
-    if (win7_compositor->init())
-        return win7_compositor;
-    delete win7_compositor;
-    msg_Dbg(p_intf, "failed to create Win7 compositor backend, use fallback");
+    {"win7", &instanciateCompositor<CompositorWin7>, &preInit<CompositorWin7> },
 #endif
-    return new CompositorDummy(p_intf);
+    {"dummy", &instanciateCompositor<CompositorDummy>, &preInit<CompositorDummy> }
+};
+
+CompositorFactory::CompositorFactory(qt_intf_t *p_intf, const char* compositor)
+    : m_intf(p_intf)
+    , m_compositorName(compositor)
+{
+}
+
+bool CompositorFactory::preInit()
+{
+    for (; m_compositorIndex < ARRAY_SIZE(compositorList); m_compositorIndex++)
+    {
+        if (m_compositorName == "auto" || m_compositorName == compositorList[m_compositorIndex].name)
+        {
+            if (compositorList[m_compositorIndex].preInit(m_intf))
+                return true;
+        }
+    }
+    return false;
+}
+
+Compositor* CompositorFactory::createCompositor()
+{
+    for (; m_compositorIndex < ARRAY_SIZE(compositorList); m_compositorIndex++)
+    {
+        if (m_compositorName == "auto" || m_compositorName == compositorList[m_compositorIndex].name)
+        {
+            Compositor* compositor = compositorList[m_compositorIndex].instanciate(m_intf);
+            if (compositor->init())
+                return compositor;
+        }
+    }
+    msg_Err(m_intf, "no suitable compositor found");
+    return nullptr;
 }
 
 void Compositor::onWindowDestruction(vout_window_t *p_wnd)
diff --git a/modules/gui/qt/maininterface/compositor.hpp b/modules/gui/qt/maininterface/compositor.hpp
index 4e29f29e229187281aaca5c336ffb17af097dbfe..2a558e1765be7b55a4e8fe57fc5ff5a000e2f581 100644
--- a/modules/gui/qt/maininterface/compositor.hpp
+++ b/modules/gui/qt/maininterface/compositor.hpp
@@ -48,6 +48,8 @@ public:
 public:
     virtual ~Compositor() = default;
 
+    virtual bool init() = 0;
+
     virtual MainInterface* makeMainInterface() = 0;
     virtual void destroyMainInterface() = 0;
 
@@ -57,15 +59,56 @@ public:
 
     virtual Type type() const = 0;
 
-    //factory
-    static Compositor* createCompositor(qt_intf_t *p_intf);
-
 protected:
     void onWindowDestruction(vout_window_t *p_wnd);
 
     VoutDestroyCb m_destroyCb = nullptr;
 };
 
+/**
+ * @brief The CompositorFactory class will instanciate a compositor
+ * in auto mode, compositor will be instantiated from the list by order declaration,
+ * compositor can be explicitly defined by passing its name.
+ *
+ * the usual scenario is:
+ *
+ *   - call to preInit that will try to preInit compositors from list until we find
+ *     a matching candidate
+ *
+ *   - start Qt main loop
+ *
+ *   - call to createCompositor to instantiate the compositor, if it fails it will
+ *     try to initialize the next compositors from the list
+ */
+class CompositorFactory {
+public:
+
+    CompositorFactory(qt_intf_t *p_intf, const char* compositor = "auto");
+
+    /**
+     * @brief preInit will check whether a compositor can be used, before starting Qt,
+     * each candidate will may perform some basic checks and can setup Qt enviroment variable if required
+     *
+     * @note if a compositor return true on preinit but fails to initialize afterwards, next
+     * compositor in chain will be initialized without the preinit phaze (as Qt will be already started)
+     * this might lead to an unstable configuration if incompatible operations are done in the preInit phase
+     *
+     * @return true if a compositor can be instantiated
+     */
+    bool preInit();
+
+    /**
+     * @brief createCompositor will instantiate a compositor
+     *
+     * @return the instantaied compositor, null if no compsitor can be instanciated
+     */
+    Compositor* createCompositor();
+
+private:
+    qt_intf_t* m_intf = nullptr;
+    QString m_compositorName;
+    size_t m_compositorIndex = 0;
+};
 
 }
 
diff --git a/modules/gui/qt/maininterface/compositor_dcomp.cpp b/modules/gui/qt/maininterface/compositor_dcomp.cpp
index 01026cc8605a476051d027c1f62c995de40a9bb5..3966ee1baa36c548e6cf24c4602ad91b36ff5330 100644
--- a/modules/gui/qt/maininterface/compositor_dcomp.cpp
+++ b/modules/gui/qt/maininterface/compositor_dcomp.cpp
@@ -140,6 +140,14 @@ CompositorDirectComposition::~CompositorDirectComposition()
         FreeLibrary(m_dcomp_dll);
 }
 
+bool CompositorDirectComposition::preInit(qt_intf_t * p_intf)
+{
+    //force usage of ANGLE backend
+    QApplication::setAttribute( Qt::AA_UseOpenGLES );
+
+    return true;
+}
+
 bool CompositorDirectComposition::init()
 {
     //import DirectComposition API (WIN8+)
@@ -187,8 +195,6 @@ bool CompositorDirectComposition::init()
     if (FAILED(hr))
         return false;
 
-    QApplication::setAttribute( Qt::AA_UseOpenGLES ); //force usage of ANGLE backend
-
     return true;
 }
 
diff --git a/modules/gui/qt/maininterface/compositor_dcomp.hpp b/modules/gui/qt/maininterface/compositor_dcomp.hpp
index 78e8f8a69d1a2550fff08d7717743ef11e5d3901..cc5dba10ff8481a4d2a3b99ba1a9b05bd609c4ae 100644
--- a/modules/gui/qt/maininterface/compositor_dcomp.hpp
+++ b/modules/gui/qt/maininterface/compositor_dcomp.hpp
@@ -45,7 +45,8 @@ public:
     CompositorDirectComposition(qt_intf_t *p_intf, QObject* parent = nullptr);
     ~CompositorDirectComposition();
 
-    bool init();
+    static bool preInit(qt_intf_t *);
+    bool init() override;
 
     MainInterface *makeMainInterface() override;
     void destroyMainInterface() override;
@@ -70,6 +71,7 @@ private:
     qt_intf_t *m_intf = nullptr;
 
     MainInterface* m_rootWindow = nullptr;
+
     std::unique_ptr<CompositorDCompositionUISurface> m_uiSurface;
     vout_window_t *m_window = nullptr;
     std::unique_ptr<MainUI> m_ui;
diff --git a/modules/gui/qt/maininterface/compositor_dummy.cpp b/modules/gui/qt/maininterface/compositor_dummy.cpp
index f44cbd1b3ef5a5b8bcf209d077134593a45e57c7..8d123de4562a16e6ce01843c0dbd08bd456ab641 100644
--- a/modules/gui/qt/maininterface/compositor_dummy.cpp
+++ b/modules/gui/qt/maininterface/compositor_dummy.cpp
@@ -29,6 +29,16 @@ CompositorDummy::CompositorDummy(qt_intf_t *p_intf, QObject* parent)
 {
 }
 
+bool CompositorDummy::preInit(qt_intf_t *)
+{
+    return true;
+}
+
+bool CompositorDummy::init()
+{
+    return true;
+}
+
 MainInterface* CompositorDummy::makeMainInterface()
 {
     m_rootWindow = new MainInterface(m_intf);
diff --git a/modules/gui/qt/maininterface/compositor_dummy.hpp b/modules/gui/qt/maininterface/compositor_dummy.hpp
index 31c817b5b5a26dc718e5f777502d7fe4b756ff6d..216c879f0ab87d88f9bf68a60692d25f2c3a70f7 100644
--- a/modules/gui/qt/maininterface/compositor_dummy.hpp
+++ b/modules/gui/qt/maininterface/compositor_dummy.hpp
@@ -37,6 +37,9 @@ public:
     CompositorDummy(qt_intf_t *p_intf, QObject* parent = nullptr);
     virtual ~CompositorDummy() = default;
 
+    static bool preInit(qt_intf_t*);
+    virtual bool init() override;
+
     virtual MainInterface *makeMainInterface() override;
 
     /**
diff --git a/modules/gui/qt/maininterface/compositor_win7.cpp b/modules/gui/qt/maininterface/compositor_win7.cpp
index f00605fefa457191486aab55788bda55e3beb791..2b4833afd45e2a1e43f8420f48440e78129c162c 100644
--- a/modules/gui/qt/maininterface/compositor_win7.cpp
+++ b/modules/gui/qt/maininterface/compositor_win7.cpp
@@ -96,7 +96,7 @@ CompositorWin7::~CompositorWin7()
         delete m_stable;
 }
 
-bool CompositorWin7::init()
+bool CompositorWin7::preInit(qt_intf_t *p_intf)
 {
     //check whether D3DCompiler is available. whitout it Angle won't work
     QLibrary d3dCompilerDll;
@@ -134,13 +134,18 @@ bool CompositorWin7::init()
     //otherwise Qt will load angle and fail.
     if (!d3dCompilerDll.isLoaded() || FAILED(hr))
     {
-        msg_Info(m_intf, "no D3D support, use software backend");
+        msg_Info(p_intf, "no D3D support, use software backend");
         QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
     }
 
     return true;
 }
 
+bool CompositorWin7::init()
+{
+    return true;
+}
+
 MainInterface* CompositorWin7::makeMainInterface()
 {
     //Tool flag needs to be passed in the window constructor otherwise the
diff --git a/modules/gui/qt/maininterface/compositor_win7.hpp b/modules/gui/qt/maininterface/compositor_win7.hpp
index aa007baf594f24b43810252d78741e1e05f030c5..6a432d18157d1ec22fcacf65273b1ff8e23e3291 100644
--- a/modules/gui/qt/maininterface/compositor_win7.hpp
+++ b/modules/gui/qt/maininterface/compositor_win7.hpp
@@ -46,7 +46,8 @@ public:
 
     virtual ~CompositorWin7();
 
-    bool init();
+    static bool preInit(qt_intf_t *p_intf);
+    virtual bool init() override;
 
     virtual MainInterface *makeMainInterface() override;
     virtual void destroyMainInterface() override;
diff --git a/modules/gui/qt/qt.cpp b/modules/gui/qt/qt.cpp
index bbaa36dc6e232620f17e58b78cf2962a1df88995..aa6557b2678a0ddf830cda8cfcce22b9324241c4 100644
--- a/modules/gui/qt/qt.cpp
+++ b/modules/gui/qt/qt.cpp
@@ -647,7 +647,9 @@ static void *Thread( void *obj )
 
     Q_INIT_RESOURCE( vlc );
 
-    p_intf->p_compositor = vlc::Compositor::createCompositor(p_intf);
+    vlc::CompositorFactory compositorFactory(p_intf);
+
+    compositorFactory.preInit();
 
     QApplication::setAttribute( Qt::AA_EnableHighDpiScaling );
     QApplication::setAttribute( Qt::AA_UseHighDpiPixmaps );
@@ -730,7 +732,12 @@ static void *Thread( void *obj )
 
     if( !p_intf->b_isDialogProvider )
     {
-        p_mi = p_intf->p_compositor->makeMainInterface();
+        do {
+            p_intf->p_compositor = compositorFactory.createCompositor();
+            if (! p_intf->p_compositor)
+                break;
+            p_mi = p_intf->p_compositor->makeMainInterface();
+        } while(p_mi == nullptr);
         p_intf->p_mi = p_mi;
 
         if (!p_mi)