diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
index cdef37ffa3993bf0c89b5d87b61d29d24e459677..2ced2048049fe6584373b6c250e4ae8cbcdb8f3a 100644
--- a/src/declarative/items/qsgcanvas.cpp
+++ b/src/declarative/items/qsgcanvas.cpp
@@ -60,6 +60,7 @@
 #include <QtGui/qmatrix4x4.h>
 #include <QtCore/qvarlengtharray.h>
 #include <QtCore/qabstractanimation.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
 
 #include <private/qdeclarativedebugtrace_p.h>
 
@@ -78,6 +79,45 @@ void QSGCanvasPrivate::updateFocusItemTransform()
         qApp->inputPanel()->setInputItemTransform(QSGItemPrivate::get(focus)->itemToCanvasTransform());
 }
 
+class QSGCanvasIncubationController : public QObject, public QDeclarativeIncubationController
+{
+public:
+    QSGCanvasIncubationController(QSGCanvasPrivate *canvas) 
+    : m_canvas(canvas), m_eventSent(false) {}
+
+protected:
+    virtual bool event(QEvent *e)
+    {
+        if (e->type() == QEvent::User) {
+            Q_ASSERT(m_eventSent);
+
+            bool *amtp = m_canvas->thread->allowMainThreadProcessing();
+            while (incubatingObjectCount()) {
+                if (amtp)
+                    incubateWhile(amtp);
+                else
+                    incubateFor(5);
+                QCoreApplication::processEvents();
+            }
+
+            m_eventSent = false;
+        }
+        return QObject::event(e);
+    }
+
+    virtual void incubatingObjectCountChanged(int count)
+    {
+        if (count && !m_eventSent) {
+            m_eventSent = true;
+            QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+        }
+    }
+
+private:
+    QSGCanvasPrivate *m_canvas;
+    bool m_eventSent;
+};
+
 class QSGCanvasPlainRenderLoop : public QObject, public QSGCanvasRenderLoop
 {
 public:
@@ -416,6 +456,7 @@ QSGCanvasPrivate::QSGCanvasPrivate()
     , thread(0)
     , animationDriver(0)
     , renderTarget(0)
+    , incubationController(0)
 {
 }
 
@@ -792,6 +833,8 @@ QSGCanvas::~QSGCanvas()
     QSGItemPrivate *rootItemPrivate = QSGItemPrivate::get(d->rootItem);
     rootItemPrivate->removeFromDirtyList();
 
+    delete d->incubationController; d->incubationController = 0;
+
     delete d->rootItem; d->rootItem = 0;
     d->cleanupNodes();
 }
@@ -1830,6 +1873,21 @@ QImage QSGCanvas::grabFrameBuffer()
     return d->thread ? d->thread->grab() : QImage();
 }
 
+/*!
+    Returns an incubation controller that splices incubation between frames 
+    for this canvas.  QSGView automatically installs this controller for you.
+
+    The controller is owned by the canvas and will be destroyed when the canvas
+    is deleted.
+*/
+QDeclarativeIncubationController *QSGCanvas::incubationController() const
+{
+    Q_D(const QSGCanvas);
+
+    if (!d->incubationController)
+        d->incubationController = new QSGCanvasIncubationController(const_cast<QSGCanvasPrivate *>(d));
+    return d->incubationController;
+}
 
 
 void QSGCanvasRenderLoop::createGLContext()
@@ -1878,6 +1936,7 @@ void QSGCanvasRenderThread::run()
 #ifdef THREAD_DEBUG
             printf("                RenderThread: aquired sync lock...\n");
 #endif
+            allowMainThreadProcessingFlag = false;
             QCoreApplication::postEvent(this, new QEvent(QEvent::User));
 #ifdef THREAD_DEBUG
             printf("                RenderThread: going to sleep...\n");
@@ -1895,6 +1954,7 @@ void QSGCanvasRenderThread::run()
         inSync = false;
 
         // Wake GUI after sync to let it continue animating and event processing.
+        allowMainThreadProcessingFlag = true;
         wake();
         unlock();
 #ifdef THREAD_DEBUG
diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h
index a2bb278c0a324b1f2a5b92cc240c8dad55aa3762..094fe4055325762c3967a37be42406954fc410e2 100644
--- a/src/declarative/items/qsgcanvas.h
+++ b/src/declarative/items/qsgcanvas.h
@@ -56,6 +56,7 @@ class QSGItem;
 class QSGEngine;
 class QSGCanvasPrivate;
 class QOpenGLFramebufferObject;
+class QDeclarativeIncubationController;
 
 class Q_DECLARATIVE_EXPORT QSGCanvas : public QWindow
 {
@@ -85,6 +86,8 @@ public:
     void setRenderTarget(QOpenGLFramebufferObject *fbo);
     QOpenGLFramebufferObject *renderTarget() const;
 
+    QDeclarativeIncubationController *incubationController() const;
+
 Q_SIGNALS:
     void frameSwapped();
     void sceneGraphInitialized();
diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h
index 6a8e0a0ce0226c5af426961a4a0ff56647dc6f17..4a53e6bb1b920e3ef925124927d0595f6a1ecce6 100644
--- a/src/declarative/items/qsgcanvas_p.h
+++ b/src/declarative/items/qsgcanvas_p.h
@@ -84,6 +84,7 @@ class QSGCanvasPrivate;
 
 class QTouchEvent;
 class QSGCanvasRenderLoop;
+class QSGCanvasIncubationController;
 
 class QSGCanvasPrivate : public QWindowPrivate
 {
@@ -167,6 +168,8 @@ public:
     QOpenGLFramebufferObject *renderTarget;
 
     QHash<int, QSGItem *> itemForTouchPointId;
+
+    mutable QSGCanvasIncubationController *incubationController;
 };
 
 class QSGCanvasRenderLoop
@@ -196,6 +199,7 @@ public:
     virtual void animationStarted() = 0;
     virtual void animationStopped() = 0;
     virtual void moveContextToThread(QSGContext *) { }
+    virtual bool *allowMainThreadProcessing() { return 0; }
 
 protected:
     void initializeSceneGraph() { d->initializeSceneGraph(); }
@@ -226,6 +230,7 @@ class QSGCanvasRenderThread : public QThread, public QSGCanvasRenderLoop
 public:
     QSGCanvasRenderThread()
         : mutex(QMutex::NonRecursive)
+        , allowMainThreadProcessingFlag(true)
         , animationRunning(false)
         , isGuiBlocked(0)
         , isPaintCompleted(false)
@@ -258,6 +263,7 @@ public:
     void setWindowSize(const QSize &size) { windowSize = size; }
     void maybeUpdate();
     void moveContextToThread(QSGContext *c) { c->moveToThread(this); }
+    bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
 
     bool event(QEvent *);
 
@@ -271,6 +277,8 @@ public:
     QMutex mutex;
     QWaitCondition condition;
 
+    bool allowMainThreadProcessingFlag;
+
     QSize windowSize;
     QSize renderedSize;
 
diff --git a/src/declarative/items/qsgview.cpp b/src/declarative/items/qsgview.cpp
index 236fd4ec1f91fe9d4545d094d056d18d44702fd9..7d9a451e338e0c062791a4e0a1e6af27f9732ca8 100644
--- a/src/declarative/items/qsgview.cpp
+++ b/src/declarative/items/qsgview.cpp
@@ -62,9 +62,13 @@ DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
 
 void QSGViewPrivate::init()
 {
+    Q_Q(QSGView);
+
     QDeclarativeEnginePrivate::get(&engine)->sgContext = QSGCanvasPrivate::context;
 
-    QDeclarativeInspectorService::instance()->addView(q_func());
+    engine.setIncubationController(q->incubationController());
+
+    QDeclarativeInspectorService::instance()->addView(q);
 }
 
 QSGViewPrivate::QSGViewPrivate()