aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2014-07-04 15:43:55 +0200
committerGunnar Sletta <gunnar.sletta@jollamobile.com>2014-07-29 17:41:18 +0200
commit4c5445ddb0e7388247783c868925c086bdd666f7 (patch)
treeb5ad9edf5c8fe096eff837aca305d83eb0b28f1c
parent6457541ddc1193045fbd2259df2374396ef41a22 (diff)
Introducing QQuickItem::sceneGraphInvalidated/sceneGraphInitialized
[ChangeLog][QtQuick][QQuickItem] Added signals sceneGraphInitialized and sceneGraphInvalidated Change-Id: Idaea88bc743f0637d093cf1ba7ac4f78acd7e6ad Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
-rw-r--r--src/quick/items/qquickitem.cpp67
-rw-r--r--src/quick/items/qquickitem.h3
-rw-r--r--src/quick/items/qquickitem_p.h1
-rw-r--r--src/quick/items/qquickwindow.cpp5
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp34
5 files changed, 110 insertions, 0 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 51bec66d22..54c63c4cbf 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2622,6 +2622,11 @@ void QQuickItemPrivate::refWindow(QQuickWindow *c)
Q_ASSERT(window == 0);
window = c;
+ if (q->flags() & QQuickItem::ItemHasContents) {
+ QObject::connect(window, SIGNAL(sceneGraphInvalidated()), q, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection);
+ QObject::connect(window, SIGNAL(sceneGraphInitialized()), q, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection);
+ }
+
if (polishScheduled)
QQuickWindowPrivate::get(window)->itemsToPolish.insert(q);
@@ -2651,6 +2656,11 @@ void QQuickItemPrivate::derefWindow()
if (--windowRefCount > 0)
return; // There are still other references, so don't set window to null yet.
+ if (q->flags() & QQuickItem::ItemHasContents) {
+ QObject::disconnect(window, SIGNAL(sceneGraphInvalidated()), q, SIGNAL(sceneGraphInvalidated()));
+ QObject::disconnect(window, SIGNAL(sceneGraphInitialized()), q, SIGNAL(sceneGraphInitialized()));
+ }
+
q->releaseResources();
removeFromDirtyList();
QQuickWindowPrivate *c = QQuickWindowPrivate::get(window);
@@ -5794,10 +5804,67 @@ void QQuickItem::setFlags(Flags flags)
if (int(flags & ItemClipsChildrenToShape) != int(d->flags & ItemClipsChildrenToShape))
d->dirty(QQuickItemPrivate::Clip);
+ if (window() && (flags & ItemHasContents) ^ (d->flags & ItemHasContents)) {
+ if (flags & ItemHasContents) {
+ connect(window(), SIGNAL(sceneGraphInvalidated()), this, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection);
+ connect(window(), SIGNAL(sceneGraphInitialized()), this, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection);
+ } else {
+ disconnect(window(), SIGNAL(sceneGraphInvalidated()), this, SIGNAL(sceneGraphInvalidated()));
+ disconnect(window(), SIGNAL(sceneGraphInitialized()), this, SIGNAL(sceneGraphInitialized()));
+ }
+ }
+
d->flags = flags;
}
/*!
+ \fn void QQuickItem::sceneGraphInvalidated()
+
+ This signal is emitted when the scene graph is invalidated for
+ items that have the ItemHasContents flag set.
+
+ QSGNode instances will be cleaned up by the scene graph
+ automatically. An application will only need to react to this signal
+ to clean up resources that are stored and managed outside the
+ QSGNode structure returned from updatePaintNode().
+
+ When the scene graph is using a dedicated render thread, this
+ signal will be emitted on the scene graph's render thread. The
+ GUI thread is blocked for the duration of this call. Connections
+ should for this reason be made using Qt::DirectConnection.
+
+ The OpenGL context of this item's window will be bound when this
+ signal is emitted. The only exception is if the native OpenGL has
+ been destroyed outside Qt's control, for instance through
+ EGL_CONTEXT_LOST.
+
+ \since 5.4
+ \since QtQuick 2.4
+
+ \sa QQuickWindow::sceneGraphInvalidated()
+ */
+
+/*!
+ \fn void QQuickItem::sceneGraphInitialized()
+
+ This signal is emitted when the scene graph is is initialized for
+ items that have the ItemHasContents flag set.
+
+ When the scene graph is using a dedicated render thread, this
+ function will be called on the scene graph's render thread. The
+ GUI thread is blocked for the duration of this call. Connections
+ should for this reason be made using Qt::DirectConnection.
+
+ The OpenGL context of this item's window will be bound when
+ this signal is emitted.
+
+ \since 5.4
+ \since QtQuick 2.4
+
+ \sa QQuickWindow::sceneGraphInitialized()
+ */
+
+/*!
\qmlproperty real QtQuick::Item::x
\qmlproperty real QtQuick::Item::y
\qmlproperty real QtQuick::Item::width
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 91940c7cf0..fee04984a4 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -385,6 +385,9 @@ Q_SIGNALS:
void implicitWidthChanged();
void implicitHeightChanged();
+ Q_REVISION(2) void sceneGraphInvalidated();
+ Q_REVISION(2) void sceneGraphInitialized();
+
protected:
virtual bool event(QEvent *);
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index dbd4d51941..9ac4758182 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -297,6 +297,7 @@ public:
static void transform_clear(QQmlListProperty<QQuickTransform> *list);
void _q_resourceObjectDeleted(QObject *);
+ void _q_windowChanged(QQuickWindow *w);
enum ChangeType {
Geometry = 0x01,
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 37525e6151..63e57615ba 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2868,6 +2868,11 @@ QOpenGLContext *QQuickWindow::openglContext() const
has been invalidated and all user resources tied to that context
should be released.
+ The OpenGL context of this window will be bound when this function
+ is called. The only exception is if the native OpenGL has been
+ destroyed outside Qt's control, for instance through
+ EGL_CONTEXT_LOST.
+
This signal will be emitted from the scene graph rendering thread.
*/
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 40327b0666..5993008c4a 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -52,6 +52,7 @@
#include <QQmlEngine>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
+#include <QSignalSpy>
class TestItem : public QQuickItem
{
@@ -172,6 +173,8 @@ private slots:
void visualParentOwnership();
void visualParentOwnershipWindow();
+ void testSGInitializeAndInvalidate();
+
private:
enum PaintOrderOp {
@@ -1883,6 +1886,37 @@ void tst_qquickitem::visualParentOwnershipWindow()
}
}
+void tst_qquickitem::testSGInitializeAndInvalidate()
+{
+ for (int i=0; i<2; ++i) {
+ QScopedPointer<QQuickView> view(new QQuickView());
+
+ QQuickItem *item = new QQuickItem();
+
+ int expected;
+ if (i == 0) {
+ // First iteration, item has contents and should get signals
+ expected = 1;
+ item->setFlag(QQuickItem::ItemHasContents, true);
+ } else {
+ // Second iteration, item does not have content and will not get signals
+ expected = 0;
+ }
+
+ QSignalSpy initializeSpy(item, SIGNAL(sceneGraphInitialized()));
+ QSignalSpy invalidateSpy(item, SIGNAL(sceneGraphInvalidated()));
+ item->setParentItem(view->contentItem());
+ view->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(view.data()));
+ QCOMPARE(initializeSpy.size(), expected);
+
+ delete view.take();
+ QCOMPARE(invalidateSpy.size(), expected);
+ }
+
+}
+
QTEST_MAIN(tst_qquickitem)
#include "tst_qquickitem.moc"