[vlc-commits] [Git][videolan/vlc][master] 3 commits: qt: introduce `SGManipulator`
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Fri Mar 27 08:10:01 UTC 2026
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
06233dff by Fatih Uzunoglu at 2026-03-27T08:45:36+01:00
qt: introduce `SGManipulator`
This class provides explicit control over
qt scene graph nodes.
- - - - -
28d86a45 by Fatih Uzunoglu at 2026-03-27T08:45:36+01:00
qt: register qml type `SGManipulator`
- - - - -
c6762c24 by Fatih Uzunoglu at 2026-03-27T08:45:36+01:00
qml: disable blending for video surface fade rectangles
Ideally Qt should do this optimization itself for all
bottom-most nodes, since blending is irrelevant to them.
They have no target to blend into, and these nodes can
be considered quasi-opaque, even if they are not really
opaque (as the case with the video fade rectangles here).
- - - - -
6 changed files:
- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/meson.build
- modules/gui/qt/player/qml/Player.qml
- + modules/gui/qt/util/sgmanipulator.cpp
- + modules/gui/qt/util/sgmanipulator.hpp
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -349,6 +349,8 @@ libqt_plugin_la_SOURCES = \
util/kirigamiwheelhandler.hpp \
util/textureproviderindirection.cpp \
util/textureproviderindirection.hpp \
+ util/sgmanipulator.cpp \
+ util/sgmanipulator.hpp \
widgets/native/animators.cpp \
widgets/native/animators.hpp \
widgets/native/customwidgets.cpp widgets/native/customwidgets.hpp \
@@ -508,6 +510,7 @@ nodist_libqt_plugin_la_SOURCES = \
util/textureproviderobserver.moc.cpp \
util/kirigamiwheelhandler.moc.cpp \
util/textureproviderindirection.moc.cpp \
+ util/sgmanipulator.moc.cpp \
widgets/native/animators.moc.cpp \
widgets/native/csdthemeimage.moc.cpp \
widgets/native/customwidgets.moc.cpp \
=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -51,6 +51,7 @@
#include "util/ui_notifier.hpp"
#include "util/textureproviderobserver.hpp"
#include "util/textureproviderindirection.hpp"
+#include "util/sgmanipulator.hpp"
#include "dialogs/help/aboutmodel.hpp"
#include "dialogs/dialogs_provider.hpp"
@@ -397,6 +398,7 @@ void MainUI::registerQMLTypes()
qmlRegisterType<DoubleClickIgnoringItem>( uri, versionMajor, versionMinor, "DoubleClickIgnoringItem" );
qmlRegisterType<TextureProviderObserver>( uri, versionMajor, versionMinor, "TextureProviderObserver" );
qmlRegisterType<TextureProviderIndirection>( uri, versionMajor, versionMinor, "TextureProviderIndirection" );
+ qmlRegisterType<SGManipulator>( uri, versionMajor, versionMinor, "SGManipulator" );
qmlRegisterModule(uri, versionMajor, versionMinor);
qmlProtectModule(uri, versionMajor);
=====================================
modules/gui/qt/meson.build
=====================================
@@ -155,6 +155,7 @@ moc_headers = files(
'util/textureproviderobserver.hpp',
'util/kirigamiwheelhandler.hpp',
'util/textureproviderindirection.hpp',
+ 'util/sgmanipulator.hpp',
'widgets/native/animators.hpp',
'widgets/native/csdthemeimage.hpp',
'widgets/native/customwidgets.hpp',
@@ -500,6 +501,8 @@ qt_plugin_sources = files(
'util/kirigamiwheelhandler.hpp',
'util/textureproviderindirection.cpp',
'util/textureproviderindirection.hpp',
+ 'util/sgmanipulator.cpp',
+ 'util/sgmanipulator.hpp',
'widgets/native/animators.cpp',
'widgets/native/animators.hpp',
'widgets/native/customwidgets.cpp',
=====================================
modules/gui/qt/player/qml/Player.qml
=====================================
@@ -232,7 +232,19 @@ FocusScope {
}
}
- Rectangle {
+ component FadeRectangle : Rectangle {
+ implicitHeight: VLCStyle.dp(206, VLCStyle.scale)
+
+ SGManipulator {
+ // The rectangle is the bottom-most item in the interface,
+ // it does not need blending even though it is not opaque.
+ // Since `Rectangle` does not provide explicit control over
+ // blending, we are using `SGManipulator`:
+ blending: false
+ }
+ }
+
+ FadeRectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@@ -248,7 +260,7 @@ FocusScope {
}
}
- Rectangle {
+ FadeRectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
=====================================
modules/gui/qt/util/sgmanipulator.cpp
=====================================
@@ -0,0 +1,119 @@
+/*****************************************************************************
+ * Copyright (C) 2026 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 "sgmanipulator.hpp"
+
+#include <QSGRenderNode>
+#include <QSGGeometryNode>
+#include <QSGTransformNode>
+#include <QSGMaterial>
+
+
+SGManipulator::SGManipulator(QQuickItem *parent)
+ : QQuickItem(parent)
+{
+ setFlag(QQuickItem::ItemHasContents);
+
+ connect(this, &SGManipulator::constantUpdateChanged, this, [this](bool constantUpdate) {
+ if (constantUpdate)
+ update();
+ });
+}
+
+QJSValue SGManipulator::blending() const
+{
+ if (m_blending)
+ return *m_blending;
+ else
+ return {};
+}
+
+void SGManipulator::setBlending(const QJSValue& blending)
+{
+ if ((!m_blending && blending.isNull()) || (m_blending == blending.toBool()))
+ return;
+
+ m_blending = blending.toBool();
+
+ emit blendingChanged(blending);
+
+ update();
+}
+
+void SGManipulator::resetBlending()
+{
+ m_blending.reset();
+}
+
+QSGNode *SGManipulator::updatePaintNode(QSGNode *, UpdatePaintNodeData *data)
+{
+ assert(data);
+
+ const auto transformNode = data->transformNode;
+ assert(transformNode);
+
+ QSGNode *targetNode = nullptr;
+ QSGGeometryNode *targetGeometryNode = nullptr;
+ QSGRenderNode *targetRenderNode = nullptr;
+
+ QSGNode *i = transformNode;
+ while (i)
+ {
+ // NOTE: The target node must not be a transform node.
+ // NOTE: The transform nodes parent sibling item's rendering nodes.
+ if (dynamic_cast<QSGTransformNode*>(i))
+ {
+ i = i->previousSibling();
+ continue;
+ }
+
+ targetNode = i;
+ targetGeometryNode = dynamic_cast<QSGGeometryNode*>(i);
+ targetRenderNode = dynamic_cast<QSGRenderNode*>(i);
+
+ break;
+ }
+
+ if (targetNode)
+ {
+ if (targetGeometryNode)
+ {
+ bool materialChangeMade = false;
+
+ if (const auto material = targetGeometryNode->material())
+ {
+ if (m_blending)
+ {
+ if (*m_blending != material->flags().testFlag(QSGMaterial::Blending))
+ {
+ qDebug() << "SGManipulator: Blending is overridden as" << *m_blending << "for target material" << material;
+ material->setFlag(QSGMaterial::Blending, *m_blending);
+ materialChangeMade = true;
+ }
+ }
+
+ if (materialChangeMade)
+ targetGeometryNode->markDirty(QSGNode::DirtyMaterial);
+ }
+ }
+ }
+
+ if (m_constantUpdate)
+ update(); // re-schedule an update
+
+ return nullptr;
+}
=====================================
modules/gui/qt/util/sgmanipulator.hpp
=====================================
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * Copyright (C) 2026 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.
+ *****************************************************************************/
+#ifndef SGMANIPULATOR_H
+#define SGMANIPULATOR_H
+
+#include <QQuickItem>
+#include <QJSValue>
+
+#include <optional>
+
+// This class allows manipulating the parent item's scene graph node.
+// Visibility can be set to to false to disable manipulation.
+// It is the user's responsibility to call `QQuickItem::update()`
+// to update the settings. Currently an update is scheduled as soon
+// as a manipulating property is changed. This means that if the
+// target node is altered without the control of this class, an
+// update should be scheduled (unless `constantUpdate` is set),
+// this can be for example `Image` switching from a opaque image
+// to a translucent one, or `Rectangle` switching from a opaque
+// color to a transparent one. The same applies when the target
+// node itself changes (such as due to re-parenting).
+class SGManipulator : public QQuickItem
+{
+ Q_OBJECT
+
+ // This is not really expensive, but still avoid constant updates if possible:
+ Q_PROPERTY(bool constantUpdate MEMBER m_constantUpdate NOTIFY constantUpdateChanged FINAL)
+
+ Q_PROPERTY(QJSValue blending READ blending WRITE setBlending RESET resetBlending NOTIFY blendingChanged FINAL)
+
+ QML_ELEMENT
+
+public:
+ explicit SGManipulator(QQuickItem* parent = nullptr);
+
+ QJSValue blending() const;
+ void setBlending(const QJSValue& blending);
+ void resetBlending();
+
+signals:
+ void blendingChanged(const QJSValue&);
+ void constantUpdateChanged(bool);
+
+protected:
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+
+private:
+ std::optional<bool> m_blending;
+ bool m_constantUpdate = false;
+};
+
+#endif // SGMANIPULATOR_H
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/342a1575c077c478eaa5bfa522d35ed0f1e306dd...c6762c241fd2d6c4896fa17b4de0d1f5bec41afe
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/342a1575c077c478eaa5bfa522d35ed0f1e306dd...c6762c241fd2d6c4896fa17b4de0d1f5bec41afe
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list