1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Copyright (C) 2017 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the Qt Graphical Effects module.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41import QtQuick 2.12
42import QtGraphicalEffects.private 1.12
43
44/*!
45    \qmltype MaskedBlur
46    \inqmlmodule QtGraphicalEffects
47    \since QtGraphicalEffects 1.0
48    \inherits QtQuick2::Item
49    \ingroup qtgraphicaleffects-blur
50    \brief Applies a blur effect with a varying intesity.
51
52    MaskedBlur effect softens the image by blurring it. The intensity of the
53    blur can be controlled for each pixel using maskSource so that some parts of
54    the source are blurred more than others.
55
56    Performing blur live is a costly operation. Fullscreen gaussian blur
57    with even a moderate number of samples will only run at 60 fps on highend
58    graphics hardware.
59
60    \table
61    \header
62        \li Source
63        \li MaskSource
64        \li Effect applied
65    \row
66        \li \image Original_bug.png
67        \li \image MaskedBlur_mask.png
68        \li \image MaskedBlur_bug.png
69    \endtable
70
71    \note This effect is available when running with OpenGL.
72
73    \section1 Example
74
75    The following example shows how to apply the effect.
76    \snippet MaskedBlur-example.qml example
77
78*/
79Item {
80    id: root
81
82    /*!
83        This property defines the source item that is going to be blurred.
84
85        \note It is not supported to let the effect include itself, for
86        instance by setting source to the effect's parent.
87    */
88    property alias source: blur.source
89
90    /*!
91        This property defines the item that is controlling the final intensity
92        of the blur. The pixel alpha channel value from maskSource defines the
93        actual blur radius that is going to be used for blurring the
94        corresponding source pixel.
95
96        Opaque maskSource pixels produce blur with specified
97        \l{MaskedBlur::radius}{radius}, while transparent pixels suppress the
98        blur completely. Semitransparent maskSource pixels produce blur with a
99        radius that is interpolated according to the pixel transparency level.
100    */
101    property alias maskSource: maskProxy.input
102
103    /*!
104        This property defines the distance of the neighboring pixels which
105        affect the blurring of an individual pixel. A larger radius increases
106        the blur effect.
107
108        Depending on the radius value, value of the
109        \l{MaskedBlur::samples}{samples} should be set to sufficiently large to
110        ensure the visual quality.
111
112        The value ranges from 0.0 (no blur) to inf. By default, the property is
113        set to \c 0.0 (no blur).
114
115        \table
116        \header
117        \li Output examples with different radius values
118        \li
119        \li
120        \row
121            \li \image MaskedBlur_radius1.png
122            \li \image MaskedBlur_radius2.png
123            \li \image MaskedBlur_radius3.png
124        \row
125            \li \b { radius: 0 }
126            \li \b { radius: 8 }
127            \li \b { radius: 16 }
128        \row
129            \li \l samples: 25
130            \li \l samples: 25
131            \li \l samples: 25
132        \endtable
133
134    */
135    property alias radius: blur.radius
136
137    /*!
138        This property defines how many samples are taken per pixel when blur
139        calculation is done. Larger value produces better quality, but is slower
140        to render.
141
142        Ideally, this value should be twice as large as the highest required
143        radius value plus 1, for example, if the radius is animated between 0.0
144        and 4.0, samples should be set to 9.
145
146        By default, the property is set to \c 9.
147
148        This property is not intended to be animated. Changing this property may
149        cause the underlying OpenGL shaders to be recompiled.
150    */
151    property alias samples: blur.samples
152
153    /*!
154        This property allows the effect output pixels to be cached in order to
155        improve the rendering performance. Every time the source or effect
156        properties are changed, the pixels in the cache must be updated. Memory
157        consumption is increased, because an extra buffer of memory is required
158        for storing the effect output.
159
160        It is recommended to disable the cache when the source or the effect
161        properties are animated.
162
163        By default, the property is set to \c false.
164
165    */
166    property alias cached: cacheItem.visible
167
168    /*!
169        \internal
170
171        Kept for source compatibility only. Removed in Qt 5.6
172        ### Qt6: remove
173    */
174    property bool fast: false
175
176    /*!
177        \internal
178
179        Kept for source compatibility only. Removed in Qt 5.6
180
181        Doing transparent border on a masked source doesn't make any sense
182        as the padded exterior will have a mask alpha value of 0 which means
183        no blurring and as the padded exterior of the source is a transparent
184        pixel, the result is no pixels at all.
185
186        In Qt 5.6 and before, this worked based on that the mask source
187        was scaled up to fit the padded blur target rect, which would lead
188        to inconsistent and buggy results.
189
190        ### Qt6: remove
191    */
192    property bool transparentBorder;
193
194    GaussianBlur {
195        id: blur
196
197        source: root.source;
198        anchors.fill: parent
199        _maskSource: maskProxy.output;
200
201        SourceProxy {
202            id: maskProxy
203        }
204    }
205
206    ShaderEffectSource {
207        id: cacheItem
208        x: -blur._kernelRadius
209        y: -blur._kernelRadius
210        width: blur.width + 2 * blur._kernelRadius
211        height: blur.height + 2 * blur._kernelRadius
212        visible: false
213        smooth: true
214        sourceRect: Qt.rect(-blur._kernelRadius, -blur._kernelRadius, width, height);
215        sourceItem: blur
216        hideSource: visible
217    }
218}
219