diff options
author | Miikka Heikkinen <miikka.heikkinen@theqtcompany.com> | 2015-08-10 14:33:14 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@theqtcompany.com> | 2015-08-20 09:49:18 +0000 |
commit | 3f4d7a755585f1b79c7e9675220b8210f10f358e (patch) | |
tree | 50e4e4faef56413bede418bcf495ca7fe41677ba | |
parent | 04f30db289225e700fe99c163f53f0dd7e920caf (diff) |
Add possibility to mirror ShaderEffectSource generated textures
Using textures generated by ShaderEffectSource items (or Item.layer)
with custom OpenGL code was non-intuitive due to mismatching coordinate
systems, so added a possibility to control the generated texture
orientation.
[ChangeLog][QtQuick][ShaderEffectSource] Added possibility to mirror
generated OpenGL texture.
Change-Id: I7c03d8b6fbfc43d69812c15d244200fb8e7c7bb9
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
-rw-r--r-- | src/quick/items/qquickitem.cpp | 31 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 6 | ||||
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource.cpp | 34 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource_p.h | 13 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultlayer.cpp | 25 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultlayer_p.h | 10 | ||||
-rw-r--r-- | tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml | 159 | ||||
-rw-r--r-- | tests/auto/quick/qquickitemlayer/qquickitemlayer.pro | 3 | ||||
-rw-r--r-- | tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp | 93 |
11 files changed, 375 insertions, 2 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 32c3e651dd..0c9ee4fe73 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7488,6 +7488,7 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item) , m_effectComponent(0) , m_effect(0) , m_effectSource(0) + , m_textureMirroring(QQuickShaderEffectSource::MirrorVertically) { } @@ -7559,6 +7560,7 @@ void QQuickItemLayer::activate() m_effectSource->setMipmap(m_mipmap); m_effectSource->setWrapMode(m_wrapMode); m_effectSource->setFormat(m_format); + m_effectSource->setTextureMirroring(m_textureMirroring); if (m_effectComponent) activateEffect(); @@ -7812,6 +7814,35 @@ void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode) } /*! + \qmlproperty enumeration QtQuick::Item::layer.textureMirroring + \since 5.6 + + This property defines how the generated OpenGL texture should be mirrored. + The default value is \c{ShaderEffectSource.MirrorVertically}. + Custom mirroring can be useful if the generated texture is directly accessed by custom shaders, + such as those specified by ShaderEffect. If no effect is specified for the layered + item, mirroring has no effect on the UI representation of the item. + + \list + \li ShaderEffectSource.NoMirroring - No mirroring + \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. + \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. + \endlist + */ + +void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring) +{ + if (mirroring == m_textureMirroring) + return; + m_textureMirroring = mirroring; + + if (m_effectSource) + m_effectSource->setTextureMirroring(m_textureMirroring); + + emit textureMirroringChanged(mirroring); +} + +/*! \qmlproperty string QtQuick::Item::layer.samplerName Holds the name of the effect's source texture property. diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 5e0246c32e..942b51bf68 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -143,6 +143,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener Q_PROPERTY(QQuickShaderEffectSource::Format format READ format WRITE setFormat NOTIFY formatChanged) Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged) + Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged) public: QQuickItemLayer(QQuickItem *item); ~QQuickItemLayer(); @@ -177,6 +178,9 @@ public: QQmlComponent *effect() const { return m_effectComponent; } void setEffect(QQmlComponent *effect); + QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; } + void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring); + QQuickShaderEffectSource *effectSource() const { return m_effectSource; } void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) Q_DECL_OVERRIDE; @@ -200,6 +204,7 @@ Q_SIGNALS: void smoothChanged(bool smooth); void formatChanged(QQuickShaderEffectSource::Format format); void sourceRectChanged(const QRectF &sourceRect); + void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring); private: friend class QQuickTransformAnimatorJob; @@ -223,6 +228,7 @@ private: QQmlComponent *m_effectComponent; QQuickItem *m_effect; QQuickShaderEffectSource *m_effectSource; + QQuickShaderEffectSource::TextureMirroring m_textureMirroring; }; class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate : public QObjectPrivate diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 4df1ef038c..62e0adcb0a 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -273,6 +273,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow"); qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey", QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties")); + qmlRegisterType<QQuickShaderEffectSource, 1>(uri, 2, 6, "ShaderEffectSource"); } static void initResources() diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index bf69fe4277..2effc0d0ae 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -189,6 +189,7 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent) , m_mipmap(false) , m_recursive(false) , m_grab(true) + , m_textureMirroring(MirrorVertically) { setFlag(ItemHasContents); } @@ -543,6 +544,37 @@ void QQuickShaderEffectSource::setRecursive(bool enabled) } /*! + \qmlproperty enumeration QtQuick::ShaderEffectSource::textureMirroring + \since 5.6 + + This property defines how the generated OpenGL texture should be mirrored. + The default value is \c{ShaderEffectSource.MirrorVertically}. + Custom mirroring can be useful if the generated texture is directly accessed by custom shaders, + such as those specified by ShaderEffect. Mirroring has no effect on the UI representation of + the ShaderEffectSource item itself. + + \list + \li ShaderEffectSource.NoMirroring - No mirroring + \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. + \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. + \endlist +*/ + +QQuickShaderEffectSource::TextureMirroring QQuickShaderEffectSource::textureMirroring() const +{ + return QQuickShaderEffectSource::TextureMirroring(m_textureMirroring); +} + +void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring) +{ + if (mirroring == QQuickShaderEffectSource::TextureMirroring(m_textureMirroring)) + return; + m_textureMirroring = mirroring; + update(); + emit textureMirroringChanged(); +} + +/*! \qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate() Schedules a re-rendering of the texture for the next frame. @@ -642,6 +674,8 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint m_texture->setRecursive(m_recursive); m_texture->setFormat(GLenum(m_format)); m_texture->setHasMipmaps(m_mipmap); + m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally); + m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically); if (m_grab) m_texture->scheduleUpdate(); diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 94bb315566..629acf0f55 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged) Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged) Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) + Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1) public: enum WrapMode { @@ -83,6 +84,13 @@ public: }; Q_ENUM(Format) + enum TextureMirroring { + NoMirroring = 0x00, + MirrorHorizontally = 0x01, + MirrorVertically = 0x02 + }; + Q_ENUM(TextureMirroring) + QQuickShaderEffectSource(QQuickItem *parent = 0); ~QQuickShaderEffectSource(); @@ -113,6 +121,9 @@ public: bool recursive() const; void setRecursive(bool enabled); + TextureMirroring textureMirroring() const; + void setTextureMirroring(TextureMirroring mirroring); + bool isTextureProvider() const Q_DECL_OVERRIDE { return true; } QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE; @@ -128,6 +139,7 @@ Q_SIGNALS: void hideSourceChanged(); void mipmapChanged(); void recursiveChanged(); + void textureMirroringChanged(); void scheduledUpdateCompleted(); @@ -157,6 +169,7 @@ private: uint m_mipmap : 1; uint m_recursive : 1; uint m_grab : 1; + uint m_textureMirroring : 2; // Stores TextureMirroring enum }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 1253711a94..fde3fa06b2 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -195,6 +195,8 @@ public: virtual void setFormat(GLenum format) = 0; virtual void setHasMipmaps(bool mipmap) = 0; virtual void setDevicePixelRatio(qreal ratio) = 0; + virtual void setMirrorHorizontal(bool mirror) = 0; + virtual void setMirrorVertical(bool mirror) = 0; Q_SLOT virtual void markDirtyTexture() = 0; Q_SLOT virtual void invalidated() = 0; diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index cca0712ece..fa69f911dd 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -97,6 +97,8 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) , m_multisamplingChecked(false) , m_multisampling(false) , m_grab(false) + , m_mirrorHorizontal(false) + , m_mirrorVertical(true) { } @@ -259,6 +261,16 @@ void QSGDefaultLayer::setRecursive(bool recursive) m_recursive = recursive; } +void QSGDefaultLayer::setMirrorHorizontal(bool mirror) +{ + m_mirrorHorizontal = mirror; +} + +void QSGDefaultLayer::setMirrorVertical(bool mirror) +{ + m_mirrorVertical = mirror; +} + void QSGDefaultLayer::markDirtyTexture() { m_dirtyTexture = true; @@ -365,7 +377,10 @@ void QSGDefaultLayer::grab() m_renderer->setDeviceRect(m_size); m_renderer->setViewportRect(m_size); - QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height()); + QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(), + m_mirrorVertical ? m_rect.bottom() : m_rect.top(), + m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), + m_mirrorVertical ? -m_rect.height() : m_rect.height()); m_renderer->setProjectionMatrixToRect(mirrored); m_renderer->setClearColor(Qt::transparent); @@ -428,3 +443,11 @@ QImage QSGDefaultLayer::toImage() const return QImage(); } + +QRectF QSGDefaultLayer::normalizedTextureSubRect() const +{ + return QRectF(m_mirrorHorizontal ? 1 : 0, + m_mirrorVertical ? 0 : 1, + m_mirrorHorizontal ? -1 : 1, + m_mirrorVertical ? 1 : -1); +} diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h index 0ba7109ef6..7baaed5f67 100644 --- a/src/quick/scenegraph/qsgdefaultlayer_p.h +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -78,10 +78,18 @@ public: void setDevicePixelRatio(qreal ratio) Q_DECL_OVERRIDE { m_device_pixel_ratio = ratio; } + bool mirrorHorizontal() const { return bool(m_mirrorHorizontal); } + void setMirrorHorizontal(bool mirror) Q_DECL_OVERRIDE; + + bool mirrorVertical() const { return bool(m_mirrorVertical); } + void setMirrorVertical(bool mirror) Q_DECL_OVERRIDE; + void scheduleUpdate() Q_DECL_OVERRIDE; QImage toImage() const Q_DECL_OVERRIDE; + QRectF normalizedTextureSubRect() const Q_DECL_OVERRIDE; + public Q_SLOTS: void markDirtyTexture() Q_DECL_OVERRIDE; void invalidated() Q_DECL_OVERRIDE; @@ -115,6 +123,8 @@ private: uint m_multisamplingChecked : 1; uint m_multisampling : 1; uint m_grab : 1; + uint m_mirrorHorizontal : 1; + uint m_mirrorVertical : 1; }; #endif // QSGDEFAULTLAYER_P_H diff --git a/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml b/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml new file mode 100644 index 0000000000..2827960153 --- /dev/null +++ b/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml @@ -0,0 +1,159 @@ +import QtQuick 2.6 + +Item +{ + width: 250 + height: 50 + + property int mirroring: 0 + + // Layered box without effect. Mirroring should not affect how it looks. + Rectangle { + x: 0 + y: 0 + width: 50 + height: 50 + layer.enabled: true + layer.textureMirroring: mirroring + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + + // Layered box with effect. Mirroring should affect how it looks. + Rectangle { + id: layeredEffectBox + x: 50 + y: 0 + width: 50 + height: 50 + layer.enabled: true + layer.textureMirroring: mirroring + layer.samplerName: "source" + layer.effect: ShaderEffect { + property variant source: layeredEffectBox + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(source, qt_TexCoord0); + }" + + } + + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + + // Non-layered source item for ShaderEffectSource. Mirroring should not affect how it looks. + Rectangle { + id: box2 + x: 100 + y: 0 + width: 50 + height: 50 + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + // ShaderEffectSource item. Mirroring should not affect how it looks. + ShaderEffectSource { + id: theSource + x: 150 + y: 0 + width: 50 + height: 50 + sourceItem: box2 + textureMirroring: mirroring + } + // ShaderEffect item. Mirroring should affect how it looks. + ShaderEffect { + x: 200 + y: 0 + width: 50 + height: 50 + property variant source: theSource + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(source, qt_TexCoord0); + }" + } +} diff --git a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro index 999f0cf23d..a087948f6d 100644 --- a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro +++ b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro @@ -25,5 +25,6 @@ OTHER_FILES += \ data/DisableLayer.qml \ data/SamplerNameChange.qml \ data/ItemEffect.qml \ - data/RectangleEffect.qml + data/RectangleEffect.qml \ + data/TextureMirroring.qml DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 25a75c0580..094b69c07f 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -87,7 +87,12 @@ private slots: void itemEffect(); void rectangleEffect(); + void textureMirroring_data(); + void textureMirroring(); + private: + void mirroringCheck(int mirroring, int x, bool shouldMirror, const QImage &fb); + bool m_isMesaSoftwareRasterizer; int m_mesaVersion; }; @@ -434,6 +439,94 @@ void tst_QQuickItemLayer::rectangleEffect() QCOMPARE(fb.pixel(0, 100), qRgb(0, 0, 0xff)); } +void tst_QQuickItemLayer::textureMirroring_data() +{ + QTest::addColumn<int>("mirroring"); + + QTest::newRow("no mirroring") << 0; + QTest::newRow("horizontal") << 1; + QTest::newRow("vertical") << 2; + QTest::newRow("horizontal | vertical") << 3; +} + +void tst_QQuickItemLayer::textureMirroring() +{ + QFETCH(int, mirroring); + + QQuickView view; + view.setSource(testFileUrl("TextureMirroring.qml")); + + QQuickItem *child = view.contentItem()->childItems().at(0); + child->setProperty("mirroring", mirroring); + + view.show(); + + QTest::qWaitForWindowExposed(&view); + + QImage fb = view.grabWindow(); + + // Mirroring should have no visual effect on layered item without shader effect + mirroringCheck(mirroring, 0, false, fb); + + // Mirroring should have visual effect on layered item with shader effect + mirroringCheck(mirroring, 50, true, fb); + + // Mirroring should have no visual effect on source item for ShaderEffectSource + mirroringCheck(mirroring, 100, false, fb); + + // Mirroring should have no visual effect on ShaderEffectSource item + mirroringCheck(mirroring, 150, false, fb); + + // Mirroring should have visual effect on ShaderEffect item itself + mirroringCheck(mirroring, 200, true, fb); +} + +void tst_QQuickItemLayer::mirroringCheck(int mirroring, int x, bool shouldMirror, const QImage &fb) +{ + int offset = 10; + int spacing = 25; + + if (shouldMirror) { + switch (mirroring) { + case 0: { // No mirroring -> Visually Y gets swapped, X is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0xff, 0, 0)); + break; + } + case 1: { // Horizontal mirroring -> Visually both X and Y get swapped, as neither is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0)); + break; + } + case 2: { // Vertical mirroring -> The default case, nothing gets swapped + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0xff)); + break; + } + case 3: { // Both axes mirrored -> Visually X gets swapped, Y is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0xff, 0)); + break; + } + default: + qWarning() << "Invalid case!"; + break; + } + } else { + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0xff)); + } +} QTEST_MAIN(tst_QQuickItemLayer) |