From 2f0e5e726d76b8ad5a0e9b07aeb57006490e18b4 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Sat, 9 Jan 2016 09:05:00 +0100 Subject: Make Item::layer::effect: Effect {} work again Task-number: QTBUG-49979 Change-Id: I7745b313194570b7ca0d086d41894a6d71f7610a Reviewed-by: J-P Nurmi --- src/effects/private/qgfxsourceproxy.cpp | 36 +++++++++++++++++++++++---------- src/effects/private/qgfxsourceproxy_p.h | 1 + 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/effects/private/qgfxsourceproxy.cpp b/src/effects/private/qgfxsourceproxy.cpp index e9b4254..bd55ff0 100644 --- a/src/effects/private/qgfxsourceproxy.cpp +++ b/src/effects/private/qgfxsourceproxy.cpp @@ -100,6 +100,17 @@ void QGfxSourceProxy::useProxy() setOutput(m_proxy); } +QObject *QGfxSourceProxy::findLayer(QQuickItem *item) +{ + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + if (d->extra.isAllocated() && d->extra->layer) { + QObject *layer = qvariant_cast(item->property("layer")); + if (layer && layer->property("enabled").toBool()) + return layer; + } + return 0; +} + void QGfxSourceProxy::updatePolish() { if (m_input == 0) { @@ -107,7 +118,6 @@ void QGfxSourceProxy::updatePolish() return; } - QQuickItemPrivate *d = QQuickItemPrivate::get(m_input); QQuickImage *image = qobject_cast(m_input); QQuickShaderEffectSource *shaderSource = qobject_cast(m_input); bool childless = m_input->childItems().size() == 0; @@ -115,15 +125,16 @@ void QGfxSourceProxy::updatePolish() || (m_interpolation == LinearInterpolation && m_input->smooth() == true) || (m_interpolation == NearestInterpolation && m_input->smooth() == false); - - // Layer logic is handled via QObject properties since the class is not - // private exported.. - bool maybeLayered = d->extra.isAllocated() && d->extra->layer; - QObject *layer = 0; - if (maybeLayered) { - layer = qvariant_cast(m_input->property("layer")); - if (!layer || !layer->property("enabled").toBool()) - layer = 0; + // Layers can be used in two different ways. Option 1 is when the item is + // used as input to a separate ShaderEffect component. In this case, + // m_input will be the item itself. + QObject *layer = findLayer(m_input); + if (!layer && shaderSource) { + // Alternatively, the effect is applied via layer.effect, and the + // input to the effect will be the layer's internal ShaderEffectSource + // item. In this case, we need to backtrack and find the item that has + // the layer and configure it accordingly. + layer = findLayer(shaderSource->sourceItem()); } // A bit crude test, but we're only using source rect for @@ -133,7 +144,10 @@ void QGfxSourceProxy::updatePolish() bool direct = false; if (layer) { - // Item layer which we can configure to our needs + // Auto-configure the layer so interpolation and padding works as + // expected without allocating additional FBOs. In edgecases, where + // this feature is undesiered, the user can simply use + // ShaderEffectSource rather than layer. layer->setProperty("sourceRect", m_sourceRect); layer->setProperty("smooth", m_interpolation != NearestInterpolation); direct = true; diff --git a/src/effects/private/qgfxsourceproxy_p.h b/src/effects/private/qgfxsourceproxy_p.h index 69d8e10..d54c155 100644 --- a/src/effects/private/qgfxsourceproxy_p.h +++ b/src/effects/private/qgfxsourceproxy_p.h @@ -90,6 +90,7 @@ signals: private: void setOutput(QQuickItem *output); void useProxy(); + static QObject *findLayer(QQuickItem *); QRectF m_sourceRect; QQuickItem *m_input; -- cgit v1.2.1