aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorAlan Alpert <aalpert@blackberry.com>2013-05-31 10:38:33 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-07 19:09:33 +0200
commit9d75626b1073113d77988bcb52e99215d5af4787 (patch)
treeb42ad298daaae258a405367da1c9fd0d56d3013c /src/quick/scenegraph
parentcfd4bf9d6cb8a932eab5ac99bae8973b9cedc803 (diff)
Set incubation controller when a Window{} is loaded via QQmlApplicationEngine
This was the one convenience that was lost when transitioning templates from QQuickView + Item{} to QQmlApplicationEngine + Window{}. As the default window incubation controller was tied to the first window's frameSwapped, we could easily run into a situation where a secondary window required incubation while the first window was idle. This would then starve the incubation controller. Instead make it so that the renderloop emits "timeToIncubate" once it is done with a renderpass over all windows, so the incubator gets to run once and exactly once per vsync when animating. The incubator logic was also flawed in that it could post a lot of events to itself as a result of incubatingObjectCountChanged and thus starve system events while processing incubation requests. Now we start a timer and don't start it again until we have completed an incubation pass. Task-number: QTBUG-31203 Change-Id: Iea9e2c81efb46bb7875c70ccda0cdc4b3b3e58e7 Reviewed-by: Alan Alpert <aalpert@blackberry.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h9
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp10
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h6
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp7
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop_p.h6
6 files changed, 31 insertions, 9 deletions
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 3a608a911d..e099d94a53 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -82,7 +82,7 @@ QSGRenderLoop::~QSGRenderLoop()
{
}
-class QSGGuiThreadRenderLoop : public QObject, public QSGRenderLoop
+class QSGGuiThreadRenderLoop : public QSGRenderLoop
{
Q_OBJECT
public:
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index b18e6f00ad..6ff9c4c5f9 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -51,8 +51,10 @@ class QQuickWindow;
class QSGContext;
class QAnimationDriver;
-class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop
+class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop : public QObject
{
+ Q_OBJECT
+
public:
virtual ~QSGRenderLoop();
@@ -77,6 +79,11 @@ public:
static QSGRenderLoop *instance();
static void setInstance(QSGRenderLoop *instance);
+ virtual bool interleaveIncubation() const { return false; }
+
+signals:
+ void timeToIncubate();
+
private:
static QSGRenderLoop *s_instance;
};
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index bd69fd5464..bfd9a2fb20 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -574,6 +574,7 @@ void QSGRenderThread::syncAndRender()
int waitTime = vsyncDelta - (int) waitTimer.elapsed();
if (waitTime > 0)
msleep(waitTime);
+ emit wm->timeToIncubate();
return;
}
@@ -600,6 +601,7 @@ void QSGRenderThread::syncAndRender()
d->fireFrameSwapped();
}
RLDEBUG(" Render: - rendering done");
+ emit wm->timeToIncubate();
#ifndef QSG_NO_RENDER_TIMING
if (qsg_render_timing)
@@ -723,7 +725,7 @@ QSGContext *QSGThreadedRenderLoop::sceneGraphContext() const
return m_thread->sg;
}
-bool QSGThreadedRenderLoop::anyoneShowing()
+bool QSGThreadedRenderLoop::anyoneShowing() const
{
for (int i=0; i<m_windows.size(); ++i) {
QQuickWindow *c = m_windows.at(i).window;
@@ -733,6 +735,11 @@ bool QSGThreadedRenderLoop::anyoneShowing()
return false;
}
+bool QSGThreadedRenderLoop::interleaveIncubation() const
+{
+ return m_animation_driver->isRunning() && anyoneShowing();
+}
+
void QSGThreadedRenderLoop::animationStarted()
{
RLDEBUG("GUI: animationStarted()");
@@ -1011,7 +1018,6 @@ void QSGThreadedRenderLoop::polishAndSync()
RLDEBUG("GUI: - animations advancing");
m_animation_driver->advance();
RLDEBUG("GUI: - animations done");
-
// We need to trigger another sync to keep animations running...
maybePostPolishRequest();
} else if (m_sync_triggered_update) {
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index aab0e8726f..6ff5cabf43 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QSGRenderThread;
-class QSGThreadedRenderLoop : public QObject, public QSGRenderLoop
+class QSGThreadedRenderLoop : public QSGRenderLoop
{
Q_OBJECT
public:
@@ -79,7 +79,7 @@ public:
bool event(QEvent *);
- void wakeup();
+ bool interleaveIncubation() const;
public slots:
void animationStarted();
@@ -91,7 +91,7 @@ private:
void releaseResources(QQuickWindow *window, bool inDestructor);
bool checkAndResetForceUpdate(QQuickWindow *window);
- bool anyoneShowing();
+ bool anyoneShowing() const;
void initialize();
void maybePostPolishRequest();
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index ce43ccf531..8e97f65ea5 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -102,6 +102,11 @@ QSGWindowsRenderLoop::QSGWindowsRenderLoop()
#endif
}
+bool QSGWindowsRenderLoop::interleaveIncubation() const
+{
+ return m_animationDriver->isRunning() && anyoneShowing();
+}
+
QSGWindowsRenderLoop::WindowData *QSGWindowsRenderLoop::windowData(QQuickWindow *window)
{
for (int i=0; i<m_windows.size(); ++i) {
@@ -390,6 +395,8 @@ void QSGWindowsRenderLoop::render()
// and thus another render pass, so to keep things running,
// make sure there is another frame pending.
maybePostUpdateTimer();
+
+ emit timeToIncubate();
}
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
index dc3a409cd5..218e18c3e2 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h
+++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
-class QSGWindowsRenderLoop : public QObject, public QSGRenderLoop
+class QSGWindowsRenderLoop : public QSGRenderLoop
{
Q_OBJECT
public:
@@ -80,6 +80,9 @@ public:
void resize(QQuickWindow *, const QSize &) { }
bool event(QEvent *event);
+ bool anyoneShowing() const;
+
+ bool interleaveIncubation() const;
public slots:
void started();
@@ -93,7 +96,6 @@ private:
void handleObscurity();
void maybePostUpdateTimer();
- bool anyoneShowing() const;
WindowData *windowData(QQuickWindow *window);
QList<WindowData> m_windows;