[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: add missing composition mode adjustment in SoftwareRenderNode

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Tue Jul 2 00:38:24 UTC 2024



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
99a823ac by Fatih Uzunoglu at 2024-07-02T00:24:28+00:00
qt: add missing composition mode adjustment in SoftwareRenderNode

- - - - -
e51fdd5c by Fatih Uzunoglu at 2024-07-02T00:24:28+00:00
qt: support software rendering with x11 composition

- - - - -


3 changed files:

- modules/gui/qt/maininterface/compositor_x11_uisurface.cpp
- modules/gui/qt/maininterface/compositor_x11_uisurface.hpp
- modules/gui/qt/widgets/native/viewblockingrectangle.cpp


Changes:

=====================================
modules/gui/qt/maininterface/compositor_x11_uisurface.cpp
=====================================
@@ -28,6 +28,8 @@
 #include <QOpenGLFramebufferObject>
 #include <QOpenGLExtraFunctions>
 #include <QThread>
+#include <QBackingStore>
+#include <QPainter>
 
 #include "compositor_x11_uisurface.hpp"
 #include "compositor_common.hpp"
@@ -38,47 +40,60 @@ CompositorX11UISurface::CompositorX11UISurface(QWindow* window, QScreen* screen)
     : QWindow(screen)
     , m_renderWindow(window)
 {
-    setSurfaceType(QWindow::OpenGLSurface);
+    if (qgetenv("QT_QUICK_BACKEND").compare("software"))
+    {
+        setSurfaceType(QWindow::OpenGLSurface);
 
-    m_renderWindow->installEventFilter(this);
+        QSurfaceFormat format;
+        // Qt Quick may need a depth and stencil buffer. Always make sure these are available.
+        format.setDepthBufferSize(16);
+        format.setStencilBufferSize(8);
+        format.setAlphaBufferSize(8);
+        format.setSwapInterval(0);
+
+        // UI is renderred on offscreen, no need for double bufferring
+        format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
 
-    QSurfaceFormat format;
-    // Qt Quick may need a depth and stencil buffer. Always make sure these are available.
-    format.setDepthBufferSize(16);
-    format.setStencilBufferSize(8);
-    format.setAlphaBufferSize(8);
-    format.setSwapInterval(0);
+        // Check if this is XWayland:
+        if (Q_UNLIKELY(QApplication::platformName() == QLatin1String("xcb") &&
+                       qEnvironmentVariable("XDG_SESSION_TYPE") == QLatin1String("wayland")))
+        {
+            applyNvidiaWorkaround(format);
+        }
 
-    // UI is renderred on offscreen, no need for double bufferring
-    format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
+        setFormat(format);
 
-    // Check if this is XWayland:
-    if (Q_UNLIKELY(QApplication::platformName() == QLatin1String("xcb") &&
-                   qEnvironmentVariable("XDG_SESSION_TYPE") == QLatin1String("wayland")))
+        m_context = new QOpenGLContext();
+        m_context->setScreen(this->screen());
+        m_context->setFormat(format);
+        m_context->create();
+    }
+    else
     {
-        applyNvidiaWorkaround(format);
+        m_backingStore = new QBackingStore(this);
+        m_backingStorePainter = new QPainter;
+        m_backingStorePainter->setCompositionMode(QPainter::CompositionMode_Source);
     }
 
-    setFormat(format);
-
-    m_context = new QOpenGLContext();
-    m_context->setScreen(this->screen());
-    m_context->setFormat(format);
-    m_context->create();
+    m_renderWindow->installEventFilter(this);
 
     m_uiRenderControl = new CompositorX11RenderControl(window);
 
     m_uiWindow = new CompositorOffscreenWindow(m_uiRenderControl);
     m_uiWindow->setDefaultAlphaBuffer(true);
-    m_uiWindow->setFormat(format);
+    m_uiWindow->setFormat(format());
     m_uiWindow->setColor(Qt::transparent);
 
     m_qmlEngine = new QQmlEngine();
     if (!m_qmlEngine->incubationController())
         m_qmlEngine->setIncubationController(m_uiWindow->incubationController());
 
-    connect(m_uiWindow, &QQuickWindow::sceneGraphInitialized, this, &CompositorX11UISurface::createFbo);
-    connect(m_uiWindow, &QQuickWindow::sceneGraphInvalidated, this, &CompositorX11UISurface::destroyFbo);
+    if (m_context)
+    {
+        connect(m_uiWindow, &QQuickWindow::sceneGraphInitialized, this, &CompositorX11UISurface::createFbo);
+        connect(m_uiWindow, &QQuickWindow::sceneGraphInvalidated, this, &CompositorX11UISurface::destroyFbo);
+    }
+
     connect(m_uiWindow, &QQuickWindow::beforeRendering, this, &CompositorX11UISurface::beforeRendering);
     connect(m_uiWindow, &QQuickWindow::afterRendering, this, &CompositorX11UISurface::afterRendering);
 
@@ -92,30 +107,33 @@ CompositorX11UISurface::~CompositorX11UISurface()
 {
     m_renderWindow->removeEventFilter(this);
 
-    auto surface = new QOffscreenSurface();
-    surface->setFormat(m_context->format());
-    surface->create();
-
-    // Make sure the context is current while doing cleanup. Note that we use the
-    // offscreen surface here because passing 'this' at this point is not safe: the
-    // underlying platform window may already be destroyed. To avoid all the trouble, use
-    // another surface that is valid for sure.
-    m_context->makeCurrent(surface);
+    QOffscreenSurface *surface = nullptr;
+    if (m_context)
+    {
+        surface = new QOffscreenSurface();
+        surface->setFormat(m_context->format());
+        surface->create();
+
+        // Make sure the context is current while doing cleanup. Note that we use the
+        // offscreen surface here because passing 'this' at this point is not safe: the
+        // underlying platform window may already be destroyed. To avoid all the trouble, use
+        // another surface that is valid for sure.
+        m_context->makeCurrent(surface);
+    }
 
     delete m_rootItem;
     delete m_uiRenderControl;
     delete m_uiWindow;
     delete m_qmlEngine;
 
-    if (m_textureId)
-        m_context->functions()->glDeleteTextures(1, &m_textureId);
-
-    if (m_fboId)
-        m_context->functions()->glDeleteFramebuffers(1, &m_fboId);
-
-    m_context->doneCurrent();
+    if (m_context)
+    {
+        destroyFbo();
+        m_context->doneCurrent();
+    }
 
     delete m_context;
+    delete m_backingStorePainter;
 }
 
 
@@ -129,9 +147,12 @@ void CompositorX11UISurface::setContent(QQmlComponent*,  QQuickItem* rootItem)
 
     m_rootItem->forceActiveFocus();
 
-    m_context->makeCurrent(this);
-    m_uiWindow->setGraphicsDevice(QQuickGraphicsDevice::fromOpenGLContext(m_context));
-    m_uiRenderControl->initialize();
+    if (m_context)
+    {
+        m_context->makeCurrent(this);
+        m_uiWindow->setGraphicsDevice(QQuickGraphicsDevice::fromOpenGLContext(m_context));
+        m_uiRenderControl->initialize();
+    }
 
     initialized = true;
 }
@@ -186,29 +207,42 @@ void CompositorX11UISurface::render()
     if (!isExposed())
         return;
 
-    const bool current = m_context->makeCurrent(this);
-    assert(current);
+    if (m_context)
+    {
+        const bool current = m_context->makeCurrent(this);
+        assert(current);
+        m_uiRenderControl->beginFrame();
+    }
 
-    m_uiRenderControl->beginFrame();
     m_uiRenderControl->polishItems();
     m_uiRenderControl->sync();
 
     // TODO: investigate multithreaded renderer
     m_uiRenderControl->render();
 
-    m_uiRenderControl->endFrame();
-
-    //m_uiWindow->resetOpenGLState();
+    if (m_context)
+    {
+        m_uiRenderControl->endFrame();
+        QOpenGLFramebufferObject::bindDefault();
+        m_context->functions()->glFlush();
 
-    QOpenGLFramebufferObject::bindDefault();
-    m_context->functions()->glFlush();
+        const QSize fboSize = size() * devicePixelRatio();
 
-    const QSize fboSize = size() * devicePixelRatio();
+        m_context->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fboId);
+        m_context->functions()->glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureId, 0);
+        m_context->extraFunctions()->glBlitFramebuffer(0, 0, fboSize.width(), fboSize.height(), 0, 0, fboSize.width(), fboSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
+        m_context->swapBuffers(this);
+    }
+    else
+    {
+        m_backingStore->beginPaint(geometry());
+        m_backingStorePainter->begin(m_backingStore->paintDevice());
+        m_backingStorePainter->drawImage(QPoint(0, 0), m_uiWindow->grabWindow());
+        m_backingStorePainter->end();
+        m_backingStore->endPaint();
+        m_backingStore->flush(geometry());
+    }
 
-    m_context->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fboId);
-    m_context->functions()->glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureId, 0);
-    m_context->extraFunctions()->glBlitFramebuffer(0, 0, fboSize.width(), fboSize.height(), 0, 0, fboSize.width(), fboSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
-    m_context->swapBuffers(this);
 
     emit updated();
 }
@@ -220,6 +254,9 @@ void CompositorX11UISurface::updateSizes()
 
     m_onscreenSize = windowSize * dpr;
 
+    if (m_backingStore)
+        m_backingStore->resize(m_onscreenSize);
+
     // Behave like SizeRootObjectToView.
     m_rootItem->setSize(windowSize);
     m_uiWindow->resize(windowSize);
@@ -280,7 +317,9 @@ bool CompositorX11UISurface::eventFilter(QObject*, QEvent *event)
         QResizeEvent* resizeEvent = static_cast<QResizeEvent*>(event);
         m_uiWindow->resize(resizeEvent->size());
         resize( resizeEvent->size() );
-        resizeFbo();
+        if (m_context)
+            resizeFbo();
+        updateSizes();
         break;
     }
 
@@ -411,14 +450,18 @@ void CompositorX11UISurface::applyNvidiaWorkaround(QSurfaceFormat &format)
 void CompositorX11UISurface::resizeEvent(QResizeEvent *)
 {
     if (m_onscreenSize != size() * devicePixelRatio())
-        resizeFbo();
+    {
+        if (m_context)
+            resizeFbo();
+        updateSizes();
+    }
 }
 
 void CompositorX11UISurface::exposeEvent(QExposeEvent *)
 {
     if (isExposed())
     {
-        if (!initialized)
+        if (!m_backingStore && !initialized)
         {
             m_uiRenderControl->initialize();
         }


=====================================
modules/gui/qt/maininterface/compositor_x11_uisurface.hpp
=====================================
@@ -98,6 +98,8 @@ private:
 
     QQuickItem* m_rootItem = nullptr;
     QOpenGLContext *m_context = nullptr;
+    QBackingStore *m_backingStore = nullptr;
+    QPainter *m_backingStorePainter = nullptr;
     CompositorOffscreenWindow* m_uiWindow = nullptr;
     QQmlEngine* m_qmlEngine = nullptr;
     QWindow* m_renderWindow = nullptr;


=====================================
modules/gui/qt/widgets/native/viewblockingrectangle.cpp
=====================================
@@ -34,6 +34,8 @@ public:
         const auto painter = static_cast<QPainter *>(m_window->rendererInterface()->getResource(m_window, QSGRendererInterface::PainterResource));
         assert(painter);
 
+        painter->setCompositionMode(QPainter::CompositionMode_Source);
+
         const auto clipRegion = renderState->clipRegion();
         if (clipRegion && !clipRegion->isEmpty())
             painter->setClipRegion(*clipRegion, Qt::ReplaceClip);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/31b383f5fe84e8ace741b4f28aafa467cc5b0b92...e51fdd5c36e94afea6e571811514c2ef916d9abd

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/31b383f5fe84e8ace741b4f28aafa467cc5b0b92...e51fdd5c36e94afea6e571811514c2ef916d9abd
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