diff options
Diffstat (limited to 'src/effects/qquickmultieffect.cpp')
-rw-r--r-- | src/effects/qquickmultieffect.cpp | 114 |
1 files changed, 66 insertions, 48 deletions
diff --git a/src/effects/qquickmultieffect.cpp b/src/effects/qquickmultieffect.cpp index 14e9a4ee45..7561649fbf 100644 --- a/src/effects/qquickmultieffect.cpp +++ b/src/effects/qquickmultieffect.cpp @@ -11,6 +11,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQuickEffect, "qt.quick.effects") /*! + \keyword Qt Quick Effects \qmlmodule QtQuick.Effects \title Qt Quick Effects QML Types \ingroup qmlmodules @@ -31,11 +32,13 @@ Q_LOGGING_CATEGORY(lcQuickEffect, "qt.quick.effects") \ingroup qtquick-effects \brief Applies post-processing effect to an item. - The MultiEffect type applies a post-processing effect to \l source item. - Compared to \c {Qt Graphical Effects} module, MultiEffect combines multiple - effects (blur, shadow, colorization etc.) into a single item and shader which - makes it better for multiple effects. There are several shader variations - and the most optimal one gets selected based on the features used. + The MultiEffect type, the successor to the deprecated Qt Graphical Effects + from Qt 5, applies a post-processing effect to the \l source item. Compared + to the Qt Graphical Effects module, MultiEffect combines multiple + effects (blur, shadow, colorization etc.) into a single item and shader + which makes it better for multiple effects. There are several shader + variations and the most optimal one gets selected based on the features + used. MultiEffect is designed specifically for most common effects and can be easily animated. If the MultiEffect doesn't contain the effect you need, consider implementing a custom @@ -147,7 +150,7 @@ Q_LOGGING_CATEGORY(lcQuickEffect, "qt.quick.effects") */ /*! - \qmlsignal QtQuick::MultiEffect::shaderChanged() + \qmlsignal QtQuick.Effects::MultiEffect::shaderChanged() This signal is emitted when the used shader changes. \sa fragmentShader, vertexShader @@ -164,7 +167,7 @@ QQuickMultiEffect::~QQuickMultiEffect() } /*! - \qmlproperty Item QtQuick::MultiEffect::source + \qmlproperty Item QtQuick.Effects::MultiEffect::source This property holds the item to be used as a source for the effect. If needed, MultiEffect will internally generate a \l ShaderEffectSource @@ -173,6 +176,11 @@ QQuickMultiEffect::~QQuickMultiEffect() \note It is not supported to let the effect include itself, for instance by setting source to the effect's parent. + \note If the source item has \l {QtQuick::Item::layer.enabled} {layer.enabled} set to true, + it will be used directly. This is good for the performance and often desired, when the source + is hidden. But if the source remains visible and the effect adds padding (autoPaddingEnabled, + paddingRect), that padding can affect the appearance of the source item. + \sa hasProxySource */ QQuickItem *QQuickMultiEffect::source() const @@ -188,7 +196,7 @@ void QQuickMultiEffect::setSource(QQuickItem *item) } /*! - \qmlproperty bool QtQuick::MultiEffect::autoPaddingEnabled + \qmlproperty bool QtQuick.Effects::MultiEffect::autoPaddingEnabled When blur or shadow effects are enabled and this is set to true (default), the item size is padded automatically based on blurMax and blurMultiplier. @@ -215,7 +223,7 @@ void QQuickMultiEffect::setAutoPaddingEnabled(bool enabled) } /*! - \qmlproperty rect QtQuick::MultiEffect::paddingRect + \qmlproperty rect QtQuick.Effects::MultiEffect::paddingRect Set this to increase item size manually so that blur and/or shadows will fit. If autoPaddingEnabled is true and paddingRect is not set, the item is padded @@ -247,7 +255,7 @@ void QQuickMultiEffect::setPaddingRect(const QRectF &rect) } /*! - \qmlproperty real QtQuick::MultiEffect::brightness + \qmlproperty real QtQuick.Effects::MultiEffect::brightness This property defines how much the source brightness is increased or decreased. @@ -268,7 +276,7 @@ void QQuickMultiEffect::setBrightness(qreal brightness) } /*! - \qmlproperty real QtQuick::MultiEffect::contrast + \qmlproperty real QtQuick.Effects::MultiEffect::contrast This property defines how much the source contrast is increased or decreased. @@ -289,7 +297,7 @@ void QQuickMultiEffect::setContrast(qreal contrast) } /*! - \qmlproperty real QtQuick::MultiEffect::saturation + \qmlproperty real QtQuick.Effects::MultiEffect::saturation This property defines how much the source saturation is increased or decreased. @@ -310,7 +318,7 @@ void QQuickMultiEffect::setSaturation(qreal saturation) } /*! - \qmlproperty real QtQuick::MultiEffect::colorization + \qmlproperty real QtQuick.Effects::MultiEffect::colorization This property defines how much the source is colorized with the colorizationColor. @@ -331,7 +339,7 @@ void QQuickMultiEffect::setColorization(qreal colorization) } /*! - \qmlproperty color QtQuick::MultiEffect::colorizationColor + \qmlproperty color QtQuick.Effects::MultiEffect::colorizationColor This property defines the RGBA color value which is used to colorize the source. @@ -353,7 +361,7 @@ void QQuickMultiEffect::setColorizationColor(const QColor &color) } /*! - \qmlproperty bool QtQuick::MultiEffect::blurEnabled + \qmlproperty bool QtQuick.Effects::MultiEffect::blurEnabled Enables the blur effect. @@ -372,7 +380,7 @@ void QQuickMultiEffect::setBlurEnabled(bool enabled) } /*! - \qmlproperty real QtQuick::MultiEffect::blur + \qmlproperty real QtQuick.Effects::MultiEffect::blur This property defines how much blur (radius) is applied to the source. @@ -397,7 +405,7 @@ void QQuickMultiEffect::setBlur(qreal blur) } /*! - \qmlproperty int QtQuick::MultiEffect::blurMax + \qmlproperty int QtQuick.Effects::MultiEffect::blurMax This property defines the maximum pixel radius that blur with value 1.0 will reach. @@ -425,7 +433,7 @@ void QQuickMultiEffect::setBlurMax(int blurMax) } /*! - \qmlproperty real QtQuick::MultiEffect::blurMultiplier + \qmlproperty real QtQuick.Effects::MultiEffect::blurMultiplier This property defines a multiplier for extending the blur radius. @@ -452,7 +460,7 @@ void QQuickMultiEffect::setBlurMultiplier(qreal blurMultiplier) } /*! - \qmlproperty bool QtQuick::MultiEffect::shadowEnabled + \qmlproperty bool QtQuick.Effects::MultiEffect::shadowEnabled Enables the shadow effect. @@ -471,7 +479,7 @@ void QQuickMultiEffect::setShadowEnabled(bool enabled) } /*! - \qmlproperty real QtQuick::MultiEffect::shadowOpacity + \qmlproperty real QtQuick.Effects::MultiEffect::shadowOpacity This property defines the opacity of the drop shadow. This value is multiplied with the \c shadowColor alpha value. @@ -492,7 +500,7 @@ void QQuickMultiEffect::setShadowOpacity(qreal shadowOpacity) } /*! - \qmlproperty real QtQuick::MultiEffect::shadowBlur + \qmlproperty real QtQuick.Effects::MultiEffect::shadowBlur This property defines how much blur (radius) is applied to the shadow. @@ -517,7 +525,7 @@ void QQuickMultiEffect::setShadowBlur(qreal shadowBlur) } /*! - \qmlproperty real QtQuick::MultiEffect::shadowHorizontalOffset + \qmlproperty real QtQuick.Effects::MultiEffect::shadowHorizontalOffset This property defines the horizontal offset of the shadow from the item center. @@ -542,7 +550,7 @@ void QQuickMultiEffect::setShadowHorizontalOffset(qreal offset) } /*! - \qmlproperty real QtQuick::MultiEffect::shadowVerticalOffset + \qmlproperty real QtQuick.Effects::MultiEffect::shadowVerticalOffset This property defines the vertical offset of the shadow from the item center. @@ -567,7 +575,7 @@ void QQuickMultiEffect::setShadowVerticalOffset(qreal offset) } /*! - \qmlproperty color QtQuick::MultiEffect::shadowColor + \qmlproperty color QtQuick.Effects::MultiEffect::shadowColor This property defines the RGBA color value which is used for the shadow. It is useful for example when a shadow is used for @@ -589,7 +597,7 @@ void QQuickMultiEffect::setShadowColor(const QColor &color) } /*! - \qmlproperty real QtQuick::MultiEffect::shadowScale + \qmlproperty real QtQuick.Effects::MultiEffect::shadowScale This property defines the scale of the shadow. Scaling is applied from the center of the item. @@ -614,7 +622,7 @@ void QQuickMultiEffect::setShadowScale(qreal shadowScale) } /*! - \qmlproperty bool QtQuick::MultiEffect::maskEnabled + \qmlproperty bool QtQuick.Effects::MultiEffect::maskEnabled Enables the mask effect. @@ -633,7 +641,7 @@ void QQuickMultiEffect::setMaskEnabled(bool enabled) } /*! - \qmlproperty Item QtQuick::MultiEffect::maskSource + \qmlproperty Item QtQuick.Effects::MultiEffect::maskSource Source item for the mask effect. Should point to ShaderEffectSource, item with \l {QtQuick::Item::layer.enabled} {layer.enabled} set to \c true, @@ -653,7 +661,7 @@ void QQuickMultiEffect::setMaskSource(QQuickItem *item) } /*! - \qmlproperty real QtQuick::MultiEffect::maskThresholdMin + \qmlproperty real QtQuick.Effects::MultiEffect::maskThresholdMin This property defines a lower threshold value for the mask pixels. The mask pixels that have an alpha value below this property are used @@ -677,7 +685,7 @@ void QQuickMultiEffect::setMaskThresholdMin(qreal threshold) } /*! - \qmlproperty real QtQuick::MultiEffect::maskSpreadAtMin + \qmlproperty real QtQuick.Effects::MultiEffect::maskSpreadAtMin This property defines the smoothness of the mask edges near the maskThresholdMin. Setting higher spread values softens the transition @@ -700,7 +708,7 @@ void QQuickMultiEffect::setMaskSpreadAtMin(qreal spread) } /*! - \qmlproperty real QtQuick::MultiEffect::maskThresholdMax + \qmlproperty real QtQuick.Effects::MultiEffect::maskThresholdMax This property defines an upper threshold value for the mask pixels. The mask pixels that have an alpha value below this property are used @@ -724,7 +732,7 @@ void QQuickMultiEffect::setMaskThresholdMax(qreal threshold) } /*! - \qmlproperty real QtQuick::MultiEffect::maskSpreadAtMax + \qmlproperty real QtQuick.Effects::MultiEffect::maskSpreadAtMax This property defines the smoothness of the mask edges near the maskThresholdMax. Using higher spread values softens the transition @@ -747,7 +755,7 @@ void QQuickMultiEffect::setMaskSpreadAtMax(qreal spread) } /*! - \qmlproperty bool QtQuick::MultiEffect::maskInverted + \qmlproperty bool QtQuick.Effects::MultiEffect::maskInverted This property switches the mask to the opposite side; instead of masking away the content outside maskThresholdMin and maskThresholdMax, @@ -768,7 +776,8 @@ void QQuickMultiEffect::setMaskInverted(bool inverted) } /*! - \qmlproperty rect QtQuick::MultiEffect::itemRect + \qmlproperty rect QtQuick.Effects::MultiEffect::itemRect + \readonly Read-only access to effect item rectangle. This can be used e.g. to see the area item covers. @@ -782,7 +791,7 @@ QRectF QQuickMultiEffect::itemRect() const } /*! - \qmlproperty string QtQuick::MultiEffect::fragmentShader + \qmlproperty string QtQuick.Effects::MultiEffect::fragmentShader \readonly Read-only access to filename of the currently used fragment shader. @@ -794,7 +803,7 @@ QString QQuickMultiEffect::fragmentShader() const } /*! - \qmlproperty string QtQuick::MultiEffect::vertexShader + \qmlproperty string QtQuick.Effects::MultiEffect::vertexShader \readonly Read-only access to filename of the currently used vertex shader. @@ -806,7 +815,7 @@ QString QQuickMultiEffect::vertexShader() const } /*! - \qmlproperty bool QtQuick::MultiEffect::hasProxySource + \qmlproperty bool QtQuick.Effects::MultiEffect::hasProxySource \readonly Returns true when the MultiEffect internally creates \l ShaderEffectSource @@ -1490,9 +1499,11 @@ void QQuickMultiEffectPrivate::updateColorizationColor() if (!m_shaderEffect) return; - int alpha = std::clamp(int(m_colorizationColor.alpha() * m_colorization), 0, 255); - QColor colorizationColor = m_colorizationColor; - colorizationColor.setAlpha(alpha); + float alpha = std::clamp(float(m_colorizationColor.alphaF() * m_colorization), 0.0f, 1.0f); + QVector4D colorizationColor(m_colorizationColor.redF(), + m_colorizationColor.greenF(), + m_colorizationColor.blueF(), + alpha); m_shaderEffect->setProperty("colorizationColor", colorizationColor); } @@ -1501,9 +1512,12 @@ void QQuickMultiEffectPrivate::updateShadowColor() if (!m_shaderEffect) return; - int alpha = std::clamp(int(m_shadowColor.alpha() * m_shadowOpacity), 0, 255); - QColor shadowColor = m_shadowColor; - shadowColor.setAlpha(alpha); + float alpha = std::clamp(float(m_shadowColor.alphaF() * m_shadowOpacity), 0.0f, 1.0f); + QVector4D shadowColor(m_shadowColor.redF(), + m_shadowColor.greenF(), + m_shadowColor.blueF(), + alpha); + m_shaderEffect->setProperty("shadowColor", shadowColor); } @@ -1558,8 +1572,8 @@ void QQuickMultiEffectPrivate::updateBlurItemSizes(bool forceUpdate) // First blur item size to be half of th source item // extended size, rounded to next divisible by 16. QSizeF sourceSize = itemRect().size(); - QSizeF firstItemSize(std::ceil(sourceSize.width() / 32) * 16, - std::ceil(sourceSize.height() / 32) * 16); + QSizeF firstItemSize(std::ceil(sourceSize.width() / 16) * 8, + std::ceil(sourceSize.height() / 16) * 8); if (!forceUpdate && m_firstBlurItemSize == firstItemSize) return; @@ -1582,7 +1596,7 @@ void QQuickMultiEffectPrivate::updateBlurItemSizes(bool forceUpdate) void QQuickMultiEffectPrivate::updateEffectShaders() { Q_Q(QQuickMultiEffect); - if (!q->isComponentComplete()) + if (!q->isComponentComplete() || !m_shaderEffect) return; QString vShader = QStringLiteral("multieffect_c"); @@ -1649,6 +1663,10 @@ void QQuickMultiEffectPrivate::updateBlurItemsAmount(int blurLevel) if (!m_shaderEffect) return; + const auto engine = qmlEngine(q); + if (!engine) + return; + // Lowest blur level uses 3 items, highest 5 items. int itemsAmount = blurLevel == 0 ? 0 : blurLevel + 2; @@ -1656,7 +1674,6 @@ void QQuickMultiEffectPrivate::updateBlurItemsAmount(int blurLevel) // Add more blur items. // Note that by design blur items are only added and never reduced // during the lifetime of the effect component. - const auto engine = qmlEngine(q); QUrl blurVs = QUrl(QStringLiteral("qrc:/data/shaders/bluritems.vert.qsb")); QUrl blurFs = QUrl(QStringLiteral("qrc:/data/shaders/bluritems.frag.qsb")); QQmlComponent blurComponent(engine, QUrl(QStringLiteral("qrc:/data/BlurItem.qml"))); @@ -1680,11 +1697,12 @@ void QQuickMultiEffectPrivate::updateBlurItemsAmount(int blurLevel) } // Set the blur items source components - static const auto dummyShaderSource = new QQuickShaderEffectSource(q); + if (!m_dummyShaderSource) + m_dummyShaderSource = new QQuickShaderEffectSource(q); for (int i = 0; i < m_blurEffects.size(); i++) { auto *blurEffect = m_blurEffects[i]; auto sourceItem = (i >= itemsAmount) ? - static_cast<QQuickItem *>(dummyShaderSource) : (i == 0) ? + static_cast<QQuickItem *>(m_dummyShaderSource) : (i == 0) ? static_cast<QQuickItem *>(m_shaderSource->output()) : static_cast<QQuickItem *>(m_blurEffects[i - 1]); auto sourceVariant = QVariant::fromValue<QQuickItem*>(sourceItem); |