summaryrefslogtreecommitdiff
path: root/src/effects/GaussianBlur.qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects/GaussianBlur.qml')
-rw-r--r--src/effects/GaussianBlur.qml147
1 files changed, 98 insertions, 49 deletions
diff --git a/src/effects/GaussianBlur.qml b/src/effects/GaussianBlur.qml
index 8c3f0e6..72a55f3 100644
--- a/src/effects/GaussianBlur.qml
+++ b/src/effects/GaussianBlur.qml
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Graphical Effects module.
@@ -39,6 +40,7 @@
****************************************************************************/
import QtQuick 2.0
+import QtQuick.Window 2.1
import QtGraphicalEffects.private 1.0
/*!
@@ -68,9 +70,13 @@ import QtGraphicalEffects.private 1.0
The following example shows how to apply the effect.
\snippet GaussianBlur-example.qml example
+ Performing blur live is a costly operation. Fullscreen gaussian blur
+ with even a moderate number of samples will only run at 60 fps on highend
+ graphics hardware.
+
*/
Item {
- id: rootItem
+ id: root
/*!
This property defines the source item that is going to be blurred.
@@ -92,6 +98,8 @@ Item {
The value ranges from 0.0 (no blur) to inf. By default, the property is
set to \c 0.0 (no blur).
+ By default, this property is set to \c 4.
+
\table
\header
\li Output examples with different radius values
@@ -116,7 +124,7 @@ Item {
\endtable
*/
- property real radius: 0.0
+ property real radius: Math.floor(samples / 2);
/*!
This property defines how many samples are taken per pixel when blur
@@ -124,16 +132,16 @@ Item {
to render.
Ideally, this value should be twice as large as the highest required
- radius value, for example, if the radius is animated between 0.0 and
- 4.0, samples should be set to 8.
+ radius value plus 1, for example, if the radius is animated between 0.0
+ and 4.0, samples should be set to 9.
- The value ranges from 0 to 32. By default, the property is set to \c 0.
+ By default, the property is set to \c 9.
- This property is not intended to be animated. Changing this property may
+ \warn This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
*/
- property int samples: 0
+ property int samples: 9
/*!
This property is a parameter to the gaussian function that is used when
@@ -220,6 +228,10 @@ Item {
\li \l deviation: 2.7
\endtable
+ \warn This property is not intended to be animated. Changing this property may
+ cause the underlying OpenGL shaders to be recompiled.
+
+
*/
property bool transparentBorder: false
@@ -238,58 +250,95 @@ Item {
*/
property bool cached: false
+
+ // private members...
+ property int _paddedTexWidth: transparentBorder ? width + 2 * _kernelRadius: width;
+ property int _paddedTexHeight: transparentBorder ? height + 2 * _kernelRadius: height;
+ property int _kernelRadius: Math.max(0, samples / 2);
+ property int _kernelSize: _kernelRadius * 2 + 1;
+ property int _dpr: Screen.devicePixelRatio;
+ property bool _alphaOnly: false;
+
+ property alias _output: sourceProxy.output;
+ property alias _outputRect: sourceProxy.sourceRect;
+ property alias _color: verticalBlur.color;
+ property real _thickness: 0;
+
+ onSamplesChanged: rebuildShaders();
+ on_KernelSizeChanged: rebuildShaders();
+ onDeviationChanged: rebuildShaders();
+ on_DprChanged: rebuildShaders();
+ Component.onCompleted: rebuildShaders();
+
+ function rebuildShaders() {
+ if (samples < 1)
+ return;
+
+ var params = {
+ radius: _kernelRadius,
+ deviation: deviation,
+ alphaOnly: root._alphaOnly,
+ masked: false
+ }
+ var shaders = ShaderBuilder.gaussianBlur(params);
+ horizontalBlur.fragmentShader = shaders.fragmentShader;
+ horizontalBlur.vertexShader = shaders.vertexShader;
+ }
+
SourceProxy {
id: sourceProxy
- input: rootItem.source
- sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
+ interpolation: SourceProxy.LinearInterpolation
+ input: root.source
+ sourceRect: root.transparentBorder
+ ? Qt.rect(-root._kernelRadius, 0, root._paddedTexWidth, parent.height)
+ : Qt.rect(0, 0, 0, 0)
+ }
+
+ ShaderEffect {
+ id: horizontalBlur
+ width: root.transparentBorder ? root._paddedTexWidth : root.width
+ height: root.height;
+ property Item source: sourceProxy.output;
+ property real deviation: root.deviation
+ property real radius: root._kernelRadius
+ property real spread: root.radius / root._kernelRadius;
+ property var step: Qt.vector2d(1 / (root._paddedTexWidth * root._dpr), 0);
+ property color color: "white"
+ property real thickness: Math.max(0, Math.min(0.98, 1 - root._thickness * 0.98));
+ layer.enabled: true
+ layer.smooth: true
+ layer.sourceRect: root.transparentBorder
+ ? Qt.rect(0, -root._kernelRadius, width, root._paddedTexHeight)
+ : Qt.rect(0, 0, 0, 0)
+ visible: false
+ blending: false
+ }
+
+ ShaderEffect {
+ id: verticalBlur
+ x: transparentBorder ? -root._kernelRadius : 0
+ y: x;
+ width: root.transparentBorder ? root._paddedTexWidth: root.width
+ height: root.transparentBorder ? root._paddedTexHeight : root.height;
+ fragmentShader: horizontalBlur.fragmentShader
+ vertexShader: horizontalBlur.vertexShader
+ property Item source: horizontalBlur
+ property real deviation: horizontalBlur.deviation
+ property real radius: horizontalBlur.radius
+ property real spread: horizontalBlur.spread
+ property var step: Qt.vector2d(0, 1 / (root._paddedTexHeight * root._dpr));
+ property color color: "black"
+ property real thickness: horizontalBlur.thickness;
+ visible: true;
}
ShaderEffectSource {
id: cacheItem
anchors.fill: verticalBlur
- visible: rootItem.cached
+ visible: root.cached
smooth: true
sourceItem: verticalBlur
- live: true
hideSource: visible
}
- GaussianDirectionalBlur {
- id: verticalBlur
- x: transparentBorder ? -maximumRadius - 1 : 0
- y: transparentBorder ? -maximumRadius - 1 : 0
- width: horizontalBlur.width
- height: horizontalBlur.height
-
- horizontalStep: 0.0
- verticalStep: 1.0 / parent.height
-
- source: ShaderEffectSource {
- id: horizontalBlurSource
- sourceItem: horizontalBlur
- hideSource: true
- visible: false
- smooth: true
- }
-
- deviation: rootItem.deviation
- radius: rootItem.radius
- maximumRadius: rootItem.samples * 0.5
- transparentBorder: rootItem.transparentBorder
- }
-
- GaussianDirectionalBlur {
- id: horizontalBlur
- width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
- height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
-
- horizontalStep: 1.0 / parent.width
- verticalStep: 0.0
-
- source: sourceProxy.output
- deviation: rootItem.deviation
- radius: rootItem.radius
- maximumRadius: rootItem.samples / 2.0
- transparentBorder: rootItem.transparentBorder
- }
}