[vlc-commits] [Git][videolan/vlc][master] qt: support ViewBlockingRectangle with software renderer

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Nov 5 21:47:41 UTC 2022



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


Commits:
3e306e48 by Fatih Uzunoglu at 2022-11-05T21:10:42+00:00
qt: support ViewBlockingRectangle with software renderer

- - - - -


2 changed files:

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


Changes:

=====================================
modules/gui/qt/widgets/native/viewblockingrectangle.cpp
=====================================
@@ -18,9 +18,74 @@
 
 #include "viewblockingrectangle.hpp"
 
-#include <QSGRectangleNode>
 #include <QQuickWindow>
+#include <QPainter>
+#include <QPointer>
+#include <QSGRectangleNode>
 #include <QSGMaterial>
+#include <QSGRenderNode>
+
+class SoftwareRenderNode : public QSGRenderNode
+{
+public:
+    void render(const RenderState *renderState) override
+    {
+        assert(m_window);
+        const auto painter = static_cast<QPainter *>(m_window->rendererInterface()->getResource(m_window, QSGRendererInterface::PainterResource));
+        assert(painter);
+
+        const auto clipRegion = renderState->clipRegion();
+        if (clipRegion && !clipRegion->isEmpty())
+            painter->setClipRegion(*clipRegion, Qt::ReplaceClip);
+
+        painter->setTransform(matrix()->toTransform());
+        painter->setOpacity(inheritedOpacity());
+
+        painter->fillRect(rect().toRect(), m_color);
+    }
+
+    RenderingFlags flags() const override
+    {
+        return BoundedRectRendering | DepthAwareRendering | OpaqueRendering;
+    }
+
+    QRectF rect() const override
+    {
+        return m_rect;
+    }
+
+    void setRect(const QRectF& rect)
+    {
+        if (m_rect != rect)
+        {
+            m_rect = rect;
+            markDirty(DirtyGeometry);
+        }
+    }
+
+    void setWindow(QQuickWindow* const window)
+    {
+        if (Q_LIKELY(m_window != window))
+        {
+            m_window = window;
+            markDirty(DirtyForceUpdate);
+        }
+    }
+
+    void setColor(const QColor& color)
+    {
+        if (m_color != color)
+        {
+            m_color = color;
+            markDirty(DirtyMaterial);
+        }
+    }
+
+private:
+    QPointer<QQuickWindow> m_window = nullptr;
+    QRectF m_rect;
+    QColor m_color {Qt::transparent};
+};
 
 ViewBlockingRectangle::ViewBlockingRectangle(QQuickItem *parent)
     : QQuickItem(parent)
@@ -28,40 +93,67 @@ ViewBlockingRectangle::ViewBlockingRectangle(QQuickItem *parent)
 {
     setFlag(QQuickItem::ItemHasContents);
     connect(this, &ViewBlockingRectangle::colorChanged, this, &QQuickItem::update);
+    connect(this, &ViewBlockingRectangle::windowChanged, this, [this] { m_windowChanged = true; });
 }
 
 QSGNode *ViewBlockingRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
 {
-    auto node = static_cast<QSGRectangleNode*>(oldNode);
-
-    const auto rect = boundingRect();
+    auto rectangleNode = dynamic_cast<QSGRectangleNode*>(oldNode);
+    auto softwareRenderNode = dynamic_cast<SoftwareRenderNode*>(oldNode);
 
-    const auto disableBlending = [&node]() {
-        assert(node->material());
-        // Software backend check: (Qt bug)
-        if (node->material() != reinterpret_cast<QSGMaterial*>(1))
-            node->material()->setFlag(QSGMaterial::Blending, false);
-    };
+    assert(window());
+    const bool softwareMode = (window()->rendererInterface()->graphicsApi() == QSGRendererInterface::GraphicsApi::Software);
 
-    if (!node)
+    if (Q_UNLIKELY(oldNode && ((softwareMode && !softwareRenderNode)
+                               || (!softwareMode && !rectangleNode))))
     {
-        assert(window());
-        node = window()->createRectangleNode();
-        assert(node);
+        delete oldNode;
+        oldNode = nullptr;
+    }
 
-        disableBlending();
+    if (!oldNode)
+    {
+        if (softwareMode)
+        {
+            softwareRenderNode = new SoftwareRenderNode;
+            softwareRenderNode->setWindow(window());
+        }
+        else
+        {
+            rectangleNode = window()->createRectangleNode();
+            assert(rectangleNode);
+            assert(rectangleNode->material());
+            rectangleNode->material()->setFlag(QSGMaterial::Blending, false);
+        }
     }
 
-    // Geometry:
-    if (node->rect() != rect)
-        node->setRect(rect);
+    const auto rect = boundingRect();
 
-    // Material:
-    if (node->color() != m_color)
+    if (softwareMode)
     {
-        node->setColor(m_color);
-        disableBlending();
+        softwareRenderNode->setRect(rect);
+        softwareRenderNode->setColor(m_color);
+
+        if (Q_UNLIKELY(m_windowChanged))
+        {
+            softwareRenderNode->setWindow(window());
+            m_windowChanged = false;
+        }
+
+        return softwareRenderNode;
     }
+    else
+    {
+        if (rectangleNode->rect() != rect)
+            rectangleNode->setRect(rect);
 
-    return node;
+        if (rectangleNode->color() != m_color)
+        {
+            rectangleNode->setColor(m_color);
+            assert(rectangleNode->material());
+            rectangleNode->material()->setFlag(QSGMaterial::Blending, false);
+        }
+
+        return rectangleNode;
+    }
 }


=====================================
modules/gui/qt/widgets/native/viewblockingrectangle.hpp
=====================================
@@ -36,6 +36,7 @@ protected:
 
 private:
     QColor m_color;
+    bool m_windowChanged = false;
 
 signals:
     void colorChanged();



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/3e306e484814e2692c23bd7d3e0c9896a03fef82

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/3e306e484814e2692c23bd7d3e0c9896a03fef82
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