summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-09-11 07:31:54 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-09-15 14:13:49 +0200
commit3a7181de414b4952ac93e9f148a98f7e69773718 (patch)
tree46148227ef424761dd45b96b0d4b0d1d0db57297
parentadbe3de48634ec054174f63858a80cb6e50d2120 (diff)
downloadqtgraphicaleffects-3a7181de414b4952ac93e9f148a98f7e69773718.tar.gz
Fix effects for dynamic source item updates
d53af701d166dac56c910319db9eac4b9aa4538d aimed to fix graphical effects when the image source was cleared programmatically after the shader effect had been initialized. The fix made the assumption that the source size of the proxy had been bound to the size of the input, but this turned out to be wrong for many of the effects. Further investigation revealed that the graphical effects were never written to support source items with properties that change. For instance, if you initialize the source image with fill mode == Stretch, it would pick the direct throughput mode and this would stick, even if you change the fill mode later on, causing rendering errors. Similarly, if you dynamically add children to a childless source item at runtime, the effect would not be applied to these items since the proxy render mode is required for that. d53af701d166dac56c910319db9eac4b9aa4538d was only added to 5.15 because that is where the regression is visible, but it turns out that this is a general problem in effects which is also visible in Qt 6, both as rendering errors and also as unpredictable performance implications, where the order of operations can decide which mode of throughput you would end up with. The fix is to redo the polish whenever someone changes any of the properties that might affect the choice of code path. Task-number: QTBUG-84686 Pick-to: 5.15 Change-Id: I4af494a7a7fabe496e2d3442084cb823ec177b04 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r--src/effects/private/qgfxsourceproxy.cpp17
-rw-r--r--src/effects/private/qgfxsourceproxy_p.h3
2 files changed, 19 insertions, 1 deletions
diff --git a/src/effects/private/qgfxsourceproxy.cpp b/src/effects/private/qgfxsourceproxy.cpp
index 88e2780..cf64807 100644
--- a/src/effects/private/qgfxsourceproxy.cpp
+++ b/src/effects/private/qgfxsourceproxy.cpp
@@ -74,8 +74,18 @@ void QGfxSourceProxy::setInput(QQuickItem *input)
{
if (m_input == input)
return;
+
+ if (m_input != nullptr)
+ disconnect(m_input, nullptr, this, nullptr);
m_input = input;
polish();
+ if (m_input != nullptr) {
+ if (QQuickImage *image = qobject_cast<QQuickImage *>(m_input)) {
+ connect(image, &QQuickImage::sourceSizeChanged, this, &QGfxSourceProxy::repolish);
+ connect(image, &QQuickImage::fillModeChanged, this, &QGfxSourceProxy::repolish);
+ }
+ connect(m_input, &QQuickItem::childrenChanged, this, &QGfxSourceProxy::repolish);
+ }
emit inputChanged();
}
@@ -117,6 +127,11 @@ void QGfxSourceProxy::useProxy()
setOutput(m_proxy);
}
+void QGfxSourceProxy::repolish()
+{
+ polish();
+}
+
QObject *QGfxSourceProxy::findLayer(QQuickItem *item)
{
if (!item)
@@ -177,7 +192,7 @@ void QGfxSourceProxy::updatePolish()
if (shaderSource->sourceRect() == m_sourceRect || m_sourceRect.isEmpty())
direct = true;
- } else if (!padded && ((image && image->fillMode() == QQuickImage::Stretch)
+ } else if (!padded && ((image && image->fillMode() == QQuickImage::Stretch && !image->sourceSize().isNull())
|| (!image && m_input->isTextureProvider())
)
) {
diff --git a/src/effects/private/qgfxsourceproxy_p.h b/src/effects/private/qgfxsourceproxy_p.h
index 4a7bd01..8fe592c 100644
--- a/src/effects/private/qgfxsourceproxy_p.h
+++ b/src/effects/private/qgfxsourceproxy_p.h
@@ -104,6 +104,9 @@ signals:
void activeChanged();
void interpolationChanged();
+private slots:
+ void repolish();
+
private:
void setOutput(QQuickItem *output);
void useProxy();