From 5cc1870d2084f4f9a291d92d3ccd99f2c18d6fca Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 17 Jan 2012 17:06:08 +0100 Subject: [PATCH] Allow Item components to be assigned to Item.layer.effect. Some complex effects are easier to implement as Items using ShaderEffects internally rather than with a top-level ShaderEffect. Auto-tests added. Change-Id: I4b99811b87e7ca5054bf119b99207b7f5a7c666e Reviewed-by: Gunnar Sletta --- src/quick/items/qquickitem.cpp | 7 +++-- src/quick/items/qquickitem_p.h | 2 +- .../qquickitemlayer/data/ItemEffect.qml | 23 +++++++++++++++ .../qquickitemlayer/data/RectangleEffect.qml | 22 +++++++++++++++ .../qquickitemlayer/qquickitemlayer.pro | 4 ++- .../qquickitemlayer/tst_qquickitemlayer.cpp | 28 +++++++++++++++++++ 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 tests/auto/qtquick2/qquickitemlayer/data/ItemEffect.qml create mode 100644 tests/auto/qtquick2/qquickitemlayer/data/RectangleEffect.qml diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 7195e8ab00..3e59bee180 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -5497,9 +5497,9 @@ void QQuickItemLayer::activateEffect() Q_ASSERT(!m_effect); QObject *created = m_effectComponent->create(); - m_effect = qobject_cast(created); + m_effect = qobject_cast(created); if (!m_effect) { - qWarning("Item: layer.effect is not a ShaderEffect."); + qWarning("Item: layer.effect is not a QML Item."); delete created; return; } @@ -5527,7 +5527,8 @@ void QQuickItemLayer::deactivateEffect() Holds the effect that is applied to this layer. - The effect must be a \l ShaderEffect. + The effect is typically a \l ShaderEffect component, although any \l Item component can be + assigned. The effect should have a source texture property with a name matching \l samplerName. \sa samplerName */ diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 2383ae11ee..1f634bea21 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -225,7 +225,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener QRectF m_sourceRect; QString m_name; QDeclarativeComponent *m_effectComponent; - QQuickShaderEffect *m_effect; + QQuickItem *m_effect; QQuickShaderEffectSource *m_effectSource; }; diff --git a/tests/auto/qtquick2/qquickitemlayer/data/ItemEffect.qml b/tests/auto/qtquick2/qquickitemlayer/data/ItemEffect.qml new file mode 100644 index 0000000000..2f17d78efd --- /dev/null +++ b/tests/auto/qtquick2/qquickitemlayer/data/ItemEffect.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 200 + Rectangle { + anchors.fill: parent + anchors.margins: 99 + gradient: Gradient { + GradientStop { position: 0.3; color: "red" } + GradientStop { position: 0.7; color: "blue" } + } + layer.enabled: true + layer.effect: Item { + property variant source + ShaderEffect { + anchors.fill: parent + anchors.margins: -99 + property variant source: parent.source + } + } + } +} diff --git a/tests/auto/qtquick2/qquickitemlayer/data/RectangleEffect.qml b/tests/auto/qtquick2/qquickitemlayer/data/RectangleEffect.qml new file mode 100644 index 0000000000..94c43f2caf --- /dev/null +++ b/tests/auto/qtquick2/qquickitemlayer/data/RectangleEffect.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 200 + Rectangle { + width: 100 + height: 100 + x: 50 + y: 50 + scale: 1.5 + z: 1 + rotation: 45 + color: "#ff0000" + layer.enabled: true + layer.effect: Rectangle { color: "#0000ff" } + } + Rectangle { + anchors.fill: parent + color: "#00ff00" + } +} diff --git a/tests/auto/qtquick2/qquickitemlayer/qquickitemlayer.pro b/tests/auto/qtquick2/qquickitemlayer/qquickitemlayer.pro index 5c34decdcd..557e23d150 100644 --- a/tests/auto/qtquick2/qquickitemlayer/qquickitemlayer.pro +++ b/tests/auto/qtquick2/qquickitemlayer/qquickitemlayer.pro @@ -25,7 +25,9 @@ OTHER_FILES += \ data/ZOrderChange.qml \ data/ToggleLayerAndEffect.qml \ data/DisableLayer.qml \ - data/SamplerNameChange.qml + data/SamplerNameChange.qml \ + data/ItemEffect.qml \ + data/RectangleEffect.qml diff --git a/tests/auto/qtquick2/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/qtquick2/qquickitemlayer/tst_qquickitemlayer.cpp index 1e55924f86..2a856707ba 100644 --- a/tests/auto/qtquick2/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/qtquick2/qquickitemlayer/tst_qquickitemlayer.cpp @@ -86,6 +86,8 @@ private slots: void toggleLayerAndEffect(); void disableLayer(); void changeSamplerName(); + void itemEffect(); + void rectangleEffect(); private: bool m_isMesaSoftwareRasterizer; @@ -403,6 +405,32 @@ void tst_QQuickItemLayer::changeSamplerName() QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff)); } +void tst_QQuickItemLayer::itemEffect() +{ + if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) + QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + QImage fb = runTest(testFile("ItemEffect.qml")); + QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(199, 0), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(0, 199), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(199, 199), qRgb(0, 0, 0xff)); +} + +void tst_QQuickItemLayer::rectangleEffect() +{ + QImage fb = runTest(testFile("RectangleEffect.qml")); + QCOMPARE(fb.pixel(0, 0), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(199, 0), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(0, 199), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(199, 199), qRgb(0, 0xff, 0)); + + QCOMPARE(fb.pixel(100, 0), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(199, 100), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(100, 199), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(0, 100), qRgb(0, 0, 0xff)); +} + + QTEST_MAIN(tst_QQuickItemLayer) #include "tst_qquickitemlayer.moc"