Disable vsync animations by default
authorGunnar Sletta <gunnar.sletta@nokia.com>
Fri, 10 Jun 2011 11:40:48 +0000 (13:40 +0200)
committerGunnar Sletta <gunnar.sletta@nokia.com>
Fri, 10 Jun 2011 11:40:48 +0000 (13:40 +0200)
Change-Id: Ia614915ddb96f5c51e9883885479f1269ab361ed

src/declarative/items/qsgcanvas.cpp
src/declarative/items/qsgcanvas.h
src/declarative/items/qsgcanvas_p.h
tools/qmlscene/main.cpp

index 3a88fbb..950797a 100644 (file)
@@ -174,7 +174,7 @@ void QSGCanvas::paintEvent(QPaintEvent *)
         int lastFrame = frameTimer.restart();
 #endif
 
-        if (d->animationDriver->isRunning())
+        if (d->animationDriver && d->animationDriver->isRunning())
             d->animationDriver->advance();
 
 #ifdef FRAME_TIMING
@@ -222,7 +222,7 @@ void QSGCanvas::paintEvent(QPaintEvent *)
 
         QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Painting);
 
-        if (d->animationDriver->isRunning())
+        if (d->animationDriver && d->animationDriver->isRunning())
             update();
     } else {
         if (isUpdatesEnabled()) {
@@ -252,12 +252,14 @@ void QSGCanvas::showEvent(QShowEvent *e)
 
     if (!d->contextFailed) {
         if (d->threadedRendering) {
-            if (!d->animationDriver) {
-                d->animationDriver = d->context->createAnimationDriver(this);
-                connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection);
-                connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection);
+            if (d->vsyncAnimations) {
+                if (!d->animationDriver) {
+                    d->animationDriver = d->context->createAnimationDriver(this);
+                    connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection);
+                    connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection);
+                }
+                d->animationDriver->install();
             }
-            d->animationDriver->install();
             d->thread->startRenderThread();
             setUpdatesEnabled(true);
         } else {
@@ -265,11 +267,14 @@ void QSGCanvas::showEvent(QShowEvent *e)
 
             if (!d->context || !d->context->isReady()) {
                 d->initializeSceneGraph();
-                d->animationDriver = d->context->createAnimationDriver(this);
-                connect(d->animationDriver, SIGNAL(started()), this, SLOT(update()));
+                if (d->vsyncAnimations) {
+                    d->animationDriver = d->context->createAnimationDriver(this);
+                    connect(d->animationDriver, SIGNAL(started()), this, SLOT(update()));
+                }
             }
 
-            d->animationDriver->install();
+            if (d->animationDriver)
+                d->animationDriver->install();
         }
     }
 }
@@ -283,12 +288,52 @@ void QSGCanvas::hideEvent(QHideEvent *e)
             d->thread->stopRenderThread();
         }
 
-        d->animationDriver->uninstall();
+        if (d->animationDriver)
+            d->animationDriver->uninstall();
     }
 
     QGLWidget::hideEvent(e);
 }
 
+
+
+/*!
+    Sets weither this canvas should use vsync driven animations.
+
+    This option can only be set on one single QSGCanvas, and that it's
+    vsync signal will then be used to drive all animations in the
+    process.
+
+    This feature is primarily useful for single QSGCanvas, QML-only
+    applications.
+
+    \warning Enabling vsync on multiple QSGCanvas instances has
+    undefined behavior.
+ */
+void QSGCanvas::setVSyncAnimations(bool enabled)
+{
+    Q_D(QSGCanvas);
+    if (isVisible()) {
+        qWarning("QSGCanvas::setVSyncAnimations: Cannot be changed when widget is shown");
+        return;
+    }
+    d->vsyncAnimations = enabled;
+}
+
+
+
+/*!
+    Returns true if this canvas should use vsync driven animations;
+    otherwise returns false.
+ */
+bool QSGCanvas::vsyncAnimations() const
+{
+    Q_D(const QSGCanvas);
+    return d->vsyncAnimations;
+}
+
+
+
 void QSGCanvas::focusOutEvent(QFocusEvent *event)
 {
     Q_D(QSGCanvas);
@@ -384,6 +429,7 @@ QSGCanvasPrivate::QSGCanvasPrivate()
     , threadedRendering(false)
     , animationRunning(false)
     , renderThreadAwakened(false)
+    , vsyncAnimations(false)
     , thread(0)
     , animationDriver(0)
 {
@@ -958,7 +1004,7 @@ bool QSGCanvas::event(QEvent *e)
 
         d->thread->syncAlreadyHappened = false;
 
-        if (d->animationRunning) {
+        if (d->animationRunning && d->animationDriver) {
 #ifdef THREAD_DEBUG
             qDebug("GUI: Advancing animations...\n");
 #endif
@@ -2053,7 +2099,7 @@ void QSGCanvasRenderThread::run()
         // but we don't want to lock an extra time.
         wake();
 
-        if (!d->animationRunning && !isExternalUpdatePending) {
+        if (!d->animationRunning && !isExternalUpdatePending && !shouldExit) {
 #ifdef THREAD_DEBUG
             printf("                RenderThread: nothing to do, going to sleep...\n");
 #endif
index d0d0c79..8913e41 100644 (file)
@@ -75,6 +75,9 @@ public:
 
     QSGEngine *sceneGraphEngine() const;
 
+    void setVSyncAnimations(bool enabled);
+    bool vsyncAnimations() const;
+
     QImage grabFrameBuffer();
 
 Q_SIGNALS:
index 9b2683c..7f7182e 100644 (file)
@@ -160,6 +160,8 @@ public:
     uint animationRunning: 1;
     uint renderThreadAwakened : 1;
 
+    uint vsyncAnimations : 1;
+
     QSGCanvasRenderThread *thread;
     QSize widgetSize;
     QSize viewportSize;
index 765a9dc..d351b27 100644 (file)
@@ -252,6 +252,7 @@ struct Options
         , scenegraphOnGraphicsview(false)
         , clip(false)
         , versionDetection(true)
+        , vsync(true)
     {
     }
 
@@ -263,6 +264,7 @@ struct Options
     bool scenegraphOnGraphicsview;
     bool clip;
     bool versionDetection;
+    bool vsync;
 };
 
 #if defined(QMLSCENE_BUNDLE)
@@ -440,6 +442,7 @@ static void usage()
     qWarning("  --sg-on-gv [--clip] ....................... Scenegraph on graphicsview (and clip to item)");
 #endif
     qWarning("  --no-version-detection .................... Do not try to detect the version of the .qml file");
+    qWarning("  --no-vsync-animations ..................... Do not use vsync based animations");
 
     qWarning(" ");
     exit(1);
@@ -474,6 +477,8 @@ int main(int argc, char ** argv)
             options.versionDetection = false;
         else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("-i") && i + 1 < argc)
             imports.append(QString::fromLatin1(argv[++i]));
+        else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--no-vsync-animations"))
+            options.vsync = false;
         else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--help")
                  || QString::fromLatin1(argv[i]).toLower() == QLatin1String("-help")
                  || QString::fromLatin1(argv[i]).toLower() == QLatin1String("--h")
@@ -520,6 +525,7 @@ int main(int argc, char ** argv)
             if (options.versionDetection)
                 checkAndAdaptVersion(options.file);
             QSGView *qxView = new MyQSGView();
+            qxView->setVSyncAnimations(options.vsync);
             engine = qxView->engine();
             for (int i = 0; i < imports.size(); ++i)
                 engine->addImportPath(imports.at(i));