aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-02-15 20:56:51 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-02-15 20:56:51 +0100
commit74d92ef80f5e13f2e10a592e0389a10bbeab189e (patch)
treeb6aa6e592e98004c89d76e348ac5b05023cd7e38
parent7764833edf8f7ca8a53b4ea18688051ea010b70c (diff)
parent24f3fd69a2e953619c48b4a632262ce8419fee40 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7v5.7.0-alpha1
Conflicts: .qmake.conf Change-Id: Ia67a352bb51848428f8b907629c70ed340b57d78
-rw-r--r--src/effects/private/qgfxsourceproxy.cpp69
-rw-r--r--src/effects/private/qgfxsourceproxy_p.h1
-rw-r--r--tests/manual/SourceProxyTest.qml2
-rw-r--r--tests/manual/testSourceProxy.qml6
4 files changed, 60 insertions, 18 deletions
diff --git a/src/effects/private/qgfxsourceproxy.cpp b/src/effects/private/qgfxsourceproxy.cpp
index c3dce8c..201e191 100644
--- a/src/effects/private/qgfxsourceproxy.cpp
+++ b/src/effects/private/qgfxsourceproxy.cpp
@@ -106,6 +106,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<QObject *>(item->property("layer"));
+ if (layer && layer->property("enabled").toBool())
+ return layer;
+ }
+ return 0;
+}
+
void QGfxSourceProxy::updatePolish()
{
if (m_input == 0) {
@@ -113,26 +124,56 @@ void QGfxSourceProxy::updatePolish()
return;
}
- QQuickItemPrivate *d = QQuickItemPrivate::get(m_input);
QQuickImage *image = qobject_cast<QQuickImage *>(m_input);
QQuickShaderEffectSource *shaderSource = qobject_cast<QQuickShaderEffectSource *>(m_input);
- bool layered = d->extra.isAllocated() && d->extra->transparentForPositioner;
+ bool childless = m_input->childItems().size() == 0;
+ bool interpOk = m_interpolation == AnyInterpolation
+ || (m_interpolation == LinearInterpolation && m_input->smooth() == true)
+ || (m_interpolation == NearestInterpolation && m_input->smooth() == false);
+
+ // 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());
+ }
- if (shaderSource) {
- if (layered) {
- shaderSource->setSourceRect(m_sourceRect);
- shaderSource->setSmooth(m_interpolation != NearestInterpolation);
- }
- setOutput(m_input);
+ // A bit crude test, but we're only using source rect for
+ // blurring+transparent edge, so this is good enough.
+ bool padded = m_sourceRect.x() < 0 || m_sourceRect.y() < 0;
- } else if (image && image->fillMode() == QQuickImage::Stretch && m_input->childItems().size() == 0) {
- // item is an image with default tiling, use directly
- setOutput(m_input);
+ bool direct = false;
- } else if (!image && m_input->isTextureProvider() && m_input->childItems().size() == 0) {
- // item is a texture provider without children, use directly...
- setOutput(m_input);
+ if (layer) {
+ // 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;
+
+ } else if (childless && interpOk) {
+ if (shaderSource) {
+ if (shaderSource->sourceRect() == m_sourceRect)
+ direct = true;
+
+ } else if (!padded && ((image && image->fillMode() == QQuickImage::Stretch)
+ || (!image && m_input->isTextureProvider())
+ )
+ ) {
+ direct = true;
+ }
+ }
+
+ if (direct) {
+ setOutput(m_input);
} else {
useProxy();
}
diff --git a/src/effects/private/qgfxsourceproxy_p.h b/src/effects/private/qgfxsourceproxy_p.h
index b09d04f..9b84bc7 100644
--- a/src/effects/private/qgfxsourceproxy_p.h
+++ b/src/effects/private/qgfxsourceproxy_p.h
@@ -96,6 +96,7 @@ signals:
private:
void setOutput(QQuickItem *output);
void useProxy();
+ static QObject *findLayer(QQuickItem *);
QRectF m_sourceRect;
QQuickItem *m_input;
diff --git a/tests/manual/SourceProxyTest.qml b/tests/manual/SourceProxyTest.qml
index 94c948d..5ba74e7 100644
--- a/tests/manual/SourceProxyTest.qml
+++ b/tests/manual/SourceProxyTest.qml
@@ -91,7 +91,7 @@ Rectangle {
SourceProxy {
id: proxy
- input: sourcing == "shadersource" ? shaderSource : text;
+ input: sourcing == "shadersource" ? shaderSource : (root.sourcing == "layered" ? text : null);
visible: false
sourceRect: proxyPadding ? Qt.rect(-1, -1, text.width, text.height) : Qt.rect(0, 0, 0, 0);
}
diff --git a/tests/manual/testSourceProxy.qml b/tests/manual/testSourceProxy.qml
index 1ca3f95..a623ff7 100644
--- a/tests/manual/testSourceProxy.qml
+++ b/tests/manual/testSourceProxy.qml
@@ -223,19 +223,19 @@ Item {
label: "source: none\nproxy: any-interpolation"
sourcing: "none"
proxyInterpolation: SourceProxy.AnyInterpolation
- expectProxy: true
+ expectProxy: false
}
SourceProxyTest {
label: "source: none\nproxy: nearest-interpolation"
sourcing: "none"
proxyInterpolation: SourceProxy.NearestInterpolation
- expectProxy: true
+ expectProxy: false
}
SourceProxyTest {
label: "source: none\nproxy: linear-interpolation"
sourcing: "none"
proxyInterpolation: SourceProxy.LinearInterpolation
- expectProxy: true
+ expectProxy: false
}