[vlc-commits] [Git][videolan/vlc][master] 3 commits: qml: do not switch the source in the visual delegate in `DualKawaseBlur`

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat May 30 13:35:58 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
483f9d89 by Fatih Uzunoglu at 2026-05-30T13:25:27+00:00
qml: do not switch the source in the visual delegate in `DualKawaseBlur`

Switching the source seems to cause visible twitching. We can simply
use the indirection at all times here.

- - - - -
324b2be1 by Fatih Uzunoglu at 2026-05-30T13:25:27+00:00
qml: do not use indirection for the visual delegate in `DualKawaseBlur`

Although the previous patch should fix the twitching artifact, and the
indirection has minimal overhead, we can nevertheless get rid of the
indirection texture provider because:

- We can set the wrap mode directly in the source layer.
- We can use `SubTexture.vert`, as we already do it for `sourceRect`
  in `ds1`. Using a custom vertex shader breaks batch rendering, but
  it is already not a concern here since layers are involved.

- - - - -
abad2972 by Fatih Uzunoglu at 2026-05-30T13:25:27+00:00
qml: take `sourceRect` in item coordinates in `DualKawaseBlur`

- - - - -


2 changed files:

- modules/gui/qt/widgets/qml/DualKawaseBlur.qml
- modules/gui/qt/widgets/qml/PartialEffect.qml


Changes:

=====================================
modules/gui/qt/widgets/qml/DualKawaseBlur.qml
=====================================
@@ -94,6 +94,17 @@ Item {
     // it is wanted or necessary anyway.
     property Item source
 
+    readonly property real eDPR: _eDPR
+    property real _eDPR: MainCtx.effectiveDevicePixelRatio(Window.window) || 1.0
+
+    Connections {
+        target: MainCtx
+
+        function onIntfDevicePixelRatioChanged() {
+            root._eDPR = MainCtx.effectiveDevicePixelRatio(root.Window.window) || 1.0
+        }
+    }
+
     /// <debug>
     readonly property QtObject _sourceWindow: (source?.Window.window ?? null)
     function _onWindowChanged() {
@@ -109,6 +120,8 @@ Item {
 
     // Arbitrary sub-texturing (no need to be set for atlas textures):
     // `QSGTextureView` can also be used instead of sub-texturing here.
+    // NOTE: `sourceRect` is expected to be in item coordinates, similar to
+    //       `ShaderEffectSource::sourceRect`.
     property rect sourceRect
 
     // Viewport rect allows to discard an unwanted area in effect's local coordinates.
@@ -129,8 +142,10 @@ Item {
     // adjusting the position of the visual when viewport rect is smaller than
     // the effect size, since with only viewport rect the visual is always
     // centered in the parent (effect).
+    // NOTE: `visualRect` is expected to be in item coordinates, similar to
+    //       `sourceRect`.
     property rect visualRect
-    property int visualWrapMode: TextureProviderIndirection.ClampToEdge
+    property int visualWrapMode: ShaderEffectSource.ClampToEdge
 
     // Local viewport rect is viewport rect divided by two, because it is used as the source
     // rect of last layer, which is 2x upsampled by the painter delegate (us2):
@@ -277,10 +292,10 @@ Item {
         //       and normalize in the vertex shader, but we can not because we are
         //       targeting GLSL 1.20/ESSL 1.0, even though the shader is written in
         //       GLSL 4.40.
-        normalRect: (root.sourceRect.width > 0.0 && root.sourceRect.height > 0.0) ? Qt.rect(root.sourceRect.x / sourceTextureSize.width,
-                                                                                            root.sourceRect.y / sourceTextureSize.height,
-                                                                                            root.sourceRect.width / sourceTextureSize.width,
-                                                                                            root.sourceRect.height / sourceTextureSize.height)
+        normalRect: (root.sourceRect.width > 0.0 && root.sourceRect.height > 0.0) ? Qt.rect(root.sourceRect.x * root.eDPR / sourceTextureSize.width,
+                                                                                            root.sourceRect.y * root.eDPR / sourceTextureSize.height,
+                                                                                            root.sourceRect.width * root.eDPR / sourceTextureSize.width,
+                                                                                            root.sourceRect.height * root.eDPR / sourceTextureSize.height)
                                                                                   : Qt.rect(0.0, 0.0, 0.0, 0.0)
     }
 
@@ -292,6 +307,8 @@ Item {
         // Last layer for two pass mode, so use the viewport rect:
         sourceRect: (root.mode === DualKawaseBlur.Mode.TwoPass) ? root._localViewportRect : Qt.rect(0, 0, 0, 0)
         
+        wrapMode: (root.mode === DualKawaseBlur.Mode.TwoPass) ? root.visualWrapMode : ShaderEffectSource.ClampToEdge
+
         function scheduleChainedUpdate() {
             if (!ds1layer) // context is lost, Qt bug (reproduced with 6.2)
                 return
@@ -402,6 +419,8 @@ Item {
         // No need to check for the mode because this layer is not used in two pass mode anyway.
         sourceRect: root._localViewportRect
 
+        wrapMode: (root.mode === DualKawaseBlur.Mode.FourPass) ? root.visualWrapMode : ShaderEffectSource.ClampToEdge
+
         function scheduleChainedUpdate() {
             if (!us1layer) // context is lost, Qt bug (reproduced with 6.2)
                 return
@@ -475,13 +494,13 @@ Item {
         id: us2
 
         // {us1/ds1}.size * 2, unless visual rect is used
-        anchors.centerIn: useIndirection ? undefined : parent
+        anchors.centerIn: useSubTexture ? undefined : parent
 
-        x: useIndirection ? root.visualRect.x : 0
-        y: useIndirection ? root.visualRect.y : 0
+        x: useSubTexture ? root.visualRect.x : 0
+        y: useSubTexture ? root.visualRect.y : 0
 
         width: {
-            if (useIndirection)
+            if (useSubTexture)
                 return root.visualRect.width
 
             if (root.viewportRect.width > 0)
@@ -491,7 +510,7 @@ Item {
         }
 
         height: {
-            if (useIndirection)
+            if (useSubTexture)
                 return root.visualRect.height
 
             if (root.viewportRect.height > 0)
@@ -500,13 +519,11 @@ Item {
             return parent.height
         }
 
-        readonly property bool useIndirection: (root.visualRect.width > 0 && root.visualRect.height > 0)
+        readonly property bool useSubTexture: (root.visualRect.width > 0 && root.visualRect.height > 0)
 
         visible: tpObserver.isValid && root.available
 
-        source: useIndirection ? textureProviderIndirection : targetSource
-
-        readonly property Item targetSource: (root.mode === DualKawaseBlur.Mode.TwoPass) ? ds1layer : us1layer
+        source: (root.mode === DualKawaseBlur.Mode.TwoPass) ? ds1layer : us1layer
 
         property alias tint: root.tint
         property alias tintStrength: root.tintStrength
@@ -517,28 +534,11 @@ Item {
         fragmentShader: root.postprocess ? "qrc:///shaders/DualKawaseBlur_upsample_postprocess.frag.qsb"
                                          : "qrc:///shaders/DualKawaseBlur_upsample.frag.qsb"
 
-        property real _eDPR: MainCtx.effectiveDevicePixelRatio(Window.window) || 1.0
+        // NOTE: Vertex shader is set in `DefaultShaderEffect` when `normalRect` is valid.
 
-        Connections {
-            target: MainCtx
-
-            function onIntfDevicePixelRatioChanged() {
-                us2._eDPR = MainCtx.effectiveDevicePixelRatio(us2.Window.window) || 1.0
-            }
-        }
-
-        TextureProviderIndirection {
-            id: textureProviderIndirection
-
-            source: us2.targetSource
-
-            textureSubRect: Qt.rect(0,
-                                    0,
-                                    root._localVisualRect.width * us2._eDPR,
-                                    root._localVisualRect.height * us2._eDPR)
-
-            horizontalWrapMode: root.visualWrapMode
-            verticalWrapMode: root.visualWrapMode
-        }
+        normalRect: useSubTexture ? Qt.rect(0, 0,
+                                            root._localVisualRect.width * root.eDPR / sourceTextureSize.width,
+                                            root._localVisualRect.height * root.eDPR / sourceTextureSize.height)
+                                  : Qt.rect(0,0,0,0)
     }
 }


=====================================
modules/gui/qt/widgets/qml/PartialEffect.qml
=====================================
@@ -173,7 +173,10 @@ Item {
             target: root.effect
             property: "sourceRect"
             when: textureProviderIndirection.effectAcceptsSourceRect
-            value: textureProviderIndirection.textureSubRect
+            value: Qt.rect(textureProviderIndirection.x,
+                           textureProviderIndirection.y,
+                           textureProviderIndirection.width,
+                           textureProviderIndirection.height)
         }
 
         // Adjust the blending. Currently MultiEffect/FastBlur does not



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6f539a6178c10a1022d73062f6ce960ce4fed3e9...abad2972122fff89b3964c2fbdefb55d34efa9dc

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6f539a6178c10a1022d73062f6ce960ce4fed3e9...abad2972122fff89b3964c2fbdefb55d34efa9dc
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list