QQuickCanvas renames
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickwindowmanager.cpp
index 916615b..28a1e66 100644 (file)
@@ -3,7 +3,7 @@
 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/
 **
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
 ** GNU Lesser General Public License Usage
 
 #include <QtGui/QOpenGLContext>
 #include <QtGui/private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
 
-#include <QtDeclarative/private/qdeclarativeglobal_p.h>
+#include <QtQml/private/qqmlglobal_p.h>
 
-#include <QtQuick/QQuickCanvas>
-#include <QtQuick/private/qquickcanvas_p.h>
+#include <QtQuick/QQuickWindow>
+#include <QtQuick/private/qquickwindow_p.h>
 #include <QtQuick/private/qsgcontext_p.h>
 
 QT_BEGIN_NAMESPACE
@@ -62,9 +63,9 @@ const QEvent::Type QEvent_Sync = QEvent::Type(QEvent::User);
 const QEvent::Type QEvent_DeferredUpdate = QEvent::Type(QEvent::User + 1);
 
 
-#define QQUICK_CANVAS_TIMING
-#ifdef QQUICK_CANVAS_TIMING
-static bool qquick_canvas_timing = !qgetenv("QML_CANVAS_TIMING").isEmpty();
+#define QQUICK_RENDER_TIMING
+#ifdef QQUICK_RENDER_TIMING
+static bool qquick_render_timing = !qgetenv("QML_RENDER_TIMING").isEmpty();
 static QTime threadTimer;
 static int syncTime;
 static int renderTime;
@@ -106,11 +107,6 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
   lock. This variable is an integer to allow for recursive calls to lockInGui()
   without using a recursive mutex. See isPostingSyncEvent.
 
-  RenderThread::isPaintComplete: This variable is cleared when rendering starts and
-  set once rendering is complete. It is monitored in the paintEvent(),
-  resizeEvent() and grab() functions to force them to wait for rendering to
-  complete.
-
   RenderThread::isPostingSyncEvent: This variable is set in the render thread just
   before the sync event is sent to the GUI thread. It is used to avoid deadlocks
   in the case where render thread waits while waiting for GUI to pick up the sync
@@ -139,11 +135,15 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
   after shouldExit has been set to true.
  */
 
-DEFINE_BOOL_CONFIG_OPTION(qmlFixedAnimationStep, QML_FIXED_ANIMATION_STEP);
 DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP);
+DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk
 
 //#define THREAD_DEBUG
 
+QQuickWindowManager::~QQuickWindowManager()
+{
+}
+
 class QQuickRenderThreadSingleContextWindowManager : public QThread, public QQuickWindowManager
 {
     Q_OBJECT
@@ -155,7 +155,6 @@ public:
         , allowMainThreadProcessingFlag(false)
         , isGuiLocked(0)
         , animationRunning(false)
-        , isPaintCompleted(false)
         , isPostingSyncEvent(false)
         , isRenderBlocked(false)
         , isExternalUpdatePending(false)
@@ -164,8 +163,7 @@ public:
         , shouldExit(false)
         , hasExited(false)
         , isDeferredUpdatePosted(false)
-        , runToReleaseResources(false)
-        , canvasToGrab(0)
+        , windowToGrab(0)
     {
         sg->moveToThread(this);
 
@@ -177,16 +175,20 @@ public:
 
     QSGContext *sceneGraphContext() const { return sg; }
 
-    void show(QQuickCanvas *canvas);
-    void hide(QQuickCanvas *canvas);
+    void releaseResources() { }
+
+    void show(QQuickWindow *window);
+    void hide(QQuickWindow *window);
 
-    void canvasDestroyed(QQuickCanvas *canvas);
+    void windowDestroyed(QQuickWindow *window);
 
-    void paint(QQuickCanvas *canvas);
-    QImage grab(QQuickCanvas *canvas);
-    void resize(QQuickCanvas *canvas, const QSize &size);
+    void exposureChanged(QQuickWindow *window);
+    QImage grab(QQuickWindow *window);
+    void resize(QQuickWindow *window, const QSize &size);
     void handleDeferredUpdate();
-    void maybeUpdate(QQuickCanvas *canvas);
+    void maybeUpdate(QQuickWindow *window);
+    void update(QQuickWindow *window) { maybeUpdate(window); } // identical for this implementation
+    void wakeup();
 
     void startRendering();
     void stopRendering();
@@ -195,10 +197,8 @@ public:
     void sync(bool guiAlreadyLocked);
 
     void initialize();
-    void releaseResources();
-    void releaseResourcesInThread();
 
-    bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
+    volatile bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
 
     bool event(QEvent *);
 
@@ -211,9 +211,9 @@ public:
 
     void run();
 
-    QQuickCanvas *masterCanvas() {
-        QQuickCanvas *win = 0;
-        for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
+    QQuickWindow *masterWindow() {
+        QQuickWindow *win = 0;
+        for (QHash<QQuickWindow *, WindowData *>::const_iterator it = m_rendered_windows.constBegin();
             it != m_rendered_windows.constEnd() && !win; ++it) {
             if (it.value()->isVisible)
                 win = it.key();
@@ -224,12 +224,12 @@ public:
 public slots:
     void animationStarted();
     void animationStopped();
-    void canvasVisibilityChanged();
+    void windowVisibilityChanged();
 
 private:
     void handleAddedWindows();
-    void handleAddedWindow(QQuickCanvas *canvas);
-    void handleRemovedWindows();
+    void handleAddedWindow(QQuickWindow *window);
+    void handleRemovedWindows(bool clearGLContext = true);
 
     QSGContext *sg;
     QOpenGLContext *gl;
@@ -239,11 +239,10 @@ private:
     QMutex mutex;
     QWaitCondition condition;
 
-    bool allowMainThreadProcessingFlag;
+    volatile bool allowMainThreadProcessingFlag;
 
     int isGuiLocked;
     uint animationRunning: 1;
-    uint isPaintCompleted : 1;
     uint isPostingSyncEvent : 1;
     uint isRenderBlocked : 1;
     uint isExternalUpdatePending : 1;
@@ -252,12 +251,11 @@ private:
     uint shouldExit : 1;
     uint hasExited : 1;
     uint isDeferredUpdatePosted : 1;
-    uint runToReleaseResources : 1;
 
-    QQuickCanvas *canvasToGrab;
+    QQuickWindow *windowToGrab;
     QImage grabContent;
 
-    struct CanvasData {
+    struct WindowData {
         QSize renderedSize;
         QSize windowSize;
         QSize viewportSize;
@@ -266,18 +264,18 @@ private:
         uint isVisible : 1;
     };
 
-    QHash<QQuickCanvas *, CanvasData *> m_rendered_windows;
+    QHash<QQuickWindow *, WindowData *> m_rendered_windows;
 
-    struct CanvasTracker {
-        QQuickCanvas *canvas;
+    struct WindowTracker {
+        QQuickWindow *window;
         uint isVisible : 1;
         uint toBeRemoved : 1;
     };
 
-    QList<CanvasTracker> m_tracked_windows;
+    QList<WindowTracker> m_tracked_windows;
 
-    QList<QQuickCanvas *> m_removed_windows;
-    QList<QQuickCanvas *> m_added_windows;
+    QList<QQuickWindow *> m_removed_windows;
+    QList<QQuickWindow *> m_added_windows;
 };
 
 
@@ -286,33 +284,35 @@ class QQuickTrivialWindowManager : public QObject, public QQuickWindowManager
 public:
     QQuickTrivialWindowManager();
 
-    void show(QQuickCanvas *canvas);
-    void hide(QQuickCanvas *canvas);
+    void show(QQuickWindow *window);
+    void hide(QQuickWindow *window);
 
-    void canvasDestroyed(QQuickCanvas *canvas);
+    void windowDestroyed(QQuickWindow *window);
 
-    void releaseResources();
     void initializeGL();
-    void renderCanvas(QQuickCanvas *canvas);
-    void paint(QQuickCanvas *canvas);
-    QImage grab(QQuickCanvas *canvas);
-    void resize(QQuickCanvas *canvas, const QSize &size);
+    void renderWindow(QQuickWindow *window);
+    void exposureChanged(QQuickWindow *window);
+    QImage grab(QQuickWindow *window);
+    void resize(QQuickWindow *window, const QSize &size);
+    void wakeup();
+
+    void maybeUpdate(QQuickWindow *window);
+    void update(QQuickWindow *window) { maybeUpdate(window); } // identical for this implementation.
 
-    void maybeUpdate(QQuickCanvas *canvas);
+    void releaseResources() { }
 
-    bool *allowMainThreadProcessing();
+    volatile bool *allowMainThreadProcessing();
 
     QSGContext *sceneGraphContext() const;
-    QQuickCanvas *masterCanvas() const;
 
     bool event(QEvent *);
 
-    struct CanvasData {
+    struct WindowData {
         bool updatePending : 1;
         bool grabOnly : 1;
     };
 
-    QHash<QQuickCanvas *, CanvasData> m_windows;
+    QHash<QQuickWindow *, WindowData> m_windows;
 
     QOpenGLContext *gl;
     QSGContext *sg;
@@ -328,14 +328,32 @@ QQuickWindowManager *QQuickWindowManager::instance()
     static QQuickWindowManager *theInstance;
 
     if (!theInstance) {
-        bool fancy = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL);
+
+        theInstance = QSGContext::createWindowManager();
+
+        bool bufferQueuing = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::BufferQueueingOpenGL);
+        bool fancy = bufferQueuing
+            && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL);
         if (qmlNoThreadedRenderer())
             fancy = false;
-        if (qmlFixedAnimationStep())
+        else if (qmlForceThreadedRenderer())
+            fancy = true;
+
+        // Enable fixed animation steps...
+        QByteArray fixed = qgetenv("QML_FIXED_ANIMATION_STEP");
+        bool fixedAnimationSteps = bufferQueuing;
+        if (fixed == "no")
+            fixedAnimationSteps = false;
+        else if (fixed.length())
+            fixedAnimationSteps = true;
+        if (fixedAnimationSteps)
             QUnifiedTimer::instance(true)->setConsistentTiming(true);
-        theInstance = fancy
-                ? (QQuickWindowManager*) new QQuickRenderThreadSingleContextWindowManager
-                : (QQuickWindowManager*) new QQuickTrivialWindowManager;
+
+        if (!theInstance) {
+            theInstance = fancy
+                    ? (QQuickWindowManager*) new QQuickRenderThreadSingleContextWindowManager
+                    : (QQuickWindowManager*) new QQuickTrivialWindowManager;
+        }
     }
     return theInstance;
 }
@@ -348,7 +366,7 @@ void QQuickRenderThreadSingleContextWindowManager::initialize()
 {
     Q_ASSERT(m_rendered_windows.size());
 
-    QQuickCanvas *win = masterCanvas();
+    QQuickWindow *win = masterWindow();
     if (!win)
         return;
 
@@ -357,7 +375,7 @@ void QQuickRenderThreadSingleContextWindowManager::initialize()
     gl->setFormat(win->requestedFormat());
     gl->create();
     if (!gl->makeCurrent(win))
-        qWarning("QQuickCanvas: makeCurrent() failed...");
+        qWarning("QQuickWindow: makeCurrent() failed...");
 
     Q_ASSERT(!sg->isReady());
     sg->initialize(gl);
@@ -365,42 +383,42 @@ void QQuickRenderThreadSingleContextWindowManager::initialize()
 
 
 /*!
-    This function is called when the canvas is created to register the canvas with
+    This function is called when the window is created to register the window with
     the window manager.
 
     Called on GUI Thread.
  */
 
-void QQuickRenderThreadSingleContextWindowManager::show(QQuickCanvas *canvas)
+void QQuickRenderThreadSingleContextWindowManager::show(QQuickWindow *window)
 {
 #ifdef THREAD_DEBUG
-    printf("GUI: Canvas added to windowing system, %p, %dx%d\n", canvas, canvas->width(), canvas->height());
+    printf("GUI: Window added to windowing system, %p, %dx%d\n", window, window->width(), window->height());
 #endif
 
-    CanvasTracker tracker;
-    tracker.canvas = canvas;
+    WindowTracker tracker;
+    tracker.window = window;
     tracker.isVisible = false;
     tracker.toBeRemoved = false;
     m_tracked_windows << tracker;
 
-    connect(canvas, SIGNAL(widthChanged(int)), this, SLOT(canvasVisibilityChanged()), Qt::DirectConnection);
-    connect(canvas, SIGNAL(heightChanged(int)), this, SLOT(canvasVisibilityChanged()), Qt::DirectConnection);
+    connect(window, SIGNAL(widthChanged(int)), this, SLOT(windowVisibilityChanged()), Qt::DirectConnection);
+    connect(window, SIGNAL(heightChanged(int)), this, SLOT(windowVisibilityChanged()), Qt::DirectConnection);
 
-    canvasVisibilityChanged();
+    windowVisibilityChanged();
 }
 
 
-void QQuickRenderThreadSingleContextWindowManager::handleAddedWindow(QQuickCanvas *canvas)
+void QQuickRenderThreadSingleContextWindowManager::handleAddedWindow(QQuickWindow *window)
 {
 #ifdef THREAD_DEBUG
-    printf("                RenderThread: adding canvas: %p\n", canvas);
+    printf("                RenderThread: adding window: %p\n", window);
 #endif
 
-    CanvasData *data = new CanvasData;
+    WindowData *data = new WindowData;
     data->sizeWasChanged = false;
-    data->windowSize = canvas->size();
-    data->isVisible = canvas->visible();
-    m_rendered_windows[canvas] = data;
+    data->windowSize = window->size();
+    data->isVisible = window->isVisible();
+    m_rendered_windows[window] = data;
 
     isExternalUpdatePending = true;
 }
@@ -416,23 +434,23 @@ void QQuickRenderThreadSingleContextWindowManager::handleAddedWindows()
 #endif
 
     while (m_added_windows.size()) {
-        QQuickCanvas *canvas = m_added_windows.takeLast();
-        handleAddedWindow(canvas);
+        QQuickWindow *window = m_added_windows.takeLast();
+        handleAddedWindow(window);
     }
 }
 
 
 /*!
-    Called on the GUI Thread, from the canvas' destructor
+    Called on the GUI Thread, from the window' destructor
  */
 
-void QQuickRenderThreadSingleContextWindowManager::canvasDestroyed(QQuickCanvas *canvas)
+void QQuickRenderThreadSingleContextWindowManager::windowDestroyed(QQuickWindow *window)
 {
 #ifdef THREAD_DEBUG
-    printf("GUI: Canvas destroyed: %p\n", canvas);
+    printf("GUI: Window destroyed: %p\n", window);
 #endif
 
-    hide(canvas);
+    hide(window);
 }
 
 
@@ -440,15 +458,15 @@ void QQuickRenderThreadSingleContextWindowManager::canvasDestroyed(QQuickCanvas
     Called on GUI Thread
  */
 
-void QQuickRenderThreadSingleContextWindowManager::hide(QQuickCanvas *canvas)
+void QQuickRenderThreadSingleContextWindowManager::hide(QQuickWindow *window)
 {
 #ifdef THREAD_DEBUG
-    printf("GUI: Canvas hidden: %p\n", canvas);
+    printf("GUI: Window hidden: %p\n", window);
 #endif
 
     int position = -1;
     for (int i=0; i<m_tracked_windows.size(); ++i) {
-        if (m_tracked_windows.at(i).canvas == canvas) {
+        if (m_tracked_windows.at(i).window == window) {
             m_tracked_windows[i].toBeRemoved = true;
             position = i;
             break;
@@ -456,21 +474,21 @@ void QQuickRenderThreadSingleContextWindowManager::hide(QQuickCanvas *canvas)
     }
 
     if (position >= 0) {
-        disconnect(canvas, SIGNAL(widthChanged(int)), this, SLOT(canvasVisibilityChanged()));
-        disconnect(canvas, SIGNAL(heightChanged(int)), this, SLOT(canvasVisibilityChanged()));
-        canvasVisibilityChanged();
+        disconnect(window, SIGNAL(widthChanged(int)), this, SLOT(windowVisibilityChanged()));
+        disconnect(window, SIGNAL(heightChanged(int)), this, SLOT(windowVisibilityChanged()));
+        windowVisibilityChanged();
         m_tracked_windows.removeAt(position);
     }
 
 #ifdef THREAD_DEBUG
-    printf("GUI: Canvas removal completed... %p\n", canvas);
+    printf("GUI: Window removal completed... %p\n", window);
 #endif
 }
 
 /*!
     Called on Render Thread
  */
-void QQuickRenderThreadSingleContextWindowManager::handleRemovedWindows()
+void QQuickRenderThreadSingleContextWindowManager::handleRemovedWindows(bool clearGLContext)
 {
 #ifdef THREAD_DEBUG
     printf("                RenderThread: about to remove %d\n", m_removed_windows.size());
@@ -478,20 +496,20 @@ void QQuickRenderThreadSingleContextWindowManager::handleRemovedWindows()
 
     bool removedAnything = false;
     while (m_removed_windows.size()) {
-        QQuickCanvas *canvas = m_removed_windows.takeLast();
+        QQuickWindow *window = m_removed_windows.takeLast();
 #ifdef THREAD_DEBUG
-    printf("                RenderThread: removing %p\n", canvas);
+    printf("                RenderThread: removing %p\n", window);
 #endif
 
-        QQuickCanvasPrivate::get(canvas)->cleanupNodesOnShutdown();
-        delete m_rendered_windows.take(canvas);
+        QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown();
+        delete m_rendered_windows.take(window);
         removedAnything = true;
     }
 
     // If a window is removed because it has been hidden it will take with it
     // the gl context (at least on Mac) if bound, so disconnect the gl context
     // from anything
-    if (removedAnything)
+    if (removedAnything && clearGLContext)
         gl->doneCurrent();
 }
 
@@ -501,26 +519,26 @@ void QQuickRenderThreadSingleContextWindowManager::handleRemovedWindows()
     Called on GUI Thread
  */
 
-void QQuickRenderThreadSingleContextWindowManager::canvasVisibilityChanged()
+void QQuickRenderThreadSingleContextWindowManager::windowVisibilityChanged()
 {
     bool anyoneShowing = false;
-    QList<QQuickCanvas *> toAdd, toRemove;
+    QList<QQuickWindow *> toAdd, toRemove;
 
     // Not optimal, but also not frequently used...
     for (int i=0; i<m_tracked_windows.size(); ++i) {
-        CanvasTracker &t = const_cast<CanvasTracker &>(m_tracked_windows.at(i));
-        QQuickCanvas *win = t.canvas;
+        WindowTracker &t = const_cast<WindowTracker &>(m_tracked_windows.at(i));
+        QQuickWindow *win = t.window;
 
-        Q_ASSERT(win->visible() || QQuickCanvasPrivate::get(win)->renderWithoutShowing || t.toBeRemoved);
-        bool canvasVisible = win->width() > 0 && win->height() > 0;
-        anyoneShowing |= (canvasVisible && !t.toBeRemoved);
+        Q_ASSERT(win->isVisible() || QQuickWindowPrivate::get(win)->renderWithoutShowing || t.toBeRemoved);
+        bool windowVisible = win->width() > 0 && win->height() > 0;
+        anyoneShowing |= (windowVisible && !t.toBeRemoved);
 
-        if ((!canvasVisible && t.isVisible) || t.toBeRemoved) {
+        if ((!windowVisible && t.isVisible) || t.toBeRemoved) {
             toRemove << win;
-        } else if (canvasVisible && !t.isVisible) {
+        } else if (windowVisible && !t.isVisible) {
             toAdd << win;
         }
-        t.isVisible = canvasVisible;
+        t.isVisible = windowVisible;
     }
 
     if (isRunning()) {
@@ -554,18 +572,10 @@ void QQuickRenderThreadSingleContextWindowManager::run()
 #ifdef THREAD_DEBUG
     printf("QML Rendering Thread Started\n");
 #endif
-    lock();
-
-    if (runToReleaseResources) {
-        releaseResourcesInThread();
-        runToReleaseResources = false;
-        unlock();
-        return;
-    }
-
-    if (!gl)
-        initialize();
 
+    lock();
+    Q_ASSERT(!gl);
+    initialize();
     // Wake GUI as it is waiting for the GL context to have appeared, as
     // an indication that the render thread is now running.
     wake();
@@ -606,39 +616,39 @@ void QQuickRenderThreadSingleContextWindowManager::run()
 #ifdef THREAD_DEBUG
         printf("                RenderThread: Doing locked sync\n");
 #endif
-#ifdef QQUICK_CANVAS_TIMING
-        if (qquick_canvas_timing)
+#ifdef QQUICK_RENDER_TIMING
+        if (qquick_render_timing)
             threadTimer.start();
 #endif
         inSync = true;
-        for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
+        for (QHash<QQuickWindow *, WindowData *>::const_iterator it = m_rendered_windows.constBegin();
              it != m_rendered_windows.constEnd(); ++it) {
-            QQuickCanvas *canvas = it.key();
+            QQuickWindow *window = it.key();
 
 #ifdef THREAD_DEBUG
-            printf("                RenderThread: Syncing canvas: %p\n", canvas);
+            printf("                RenderThread: Syncing window: %p\n", window);
 #endif
 
-            CanvasData *canvasData = it.value();
-            QQuickCanvasPrivate *canvasPrivate = QQuickCanvasPrivate::get(canvas);
+            WindowData *windowData = it.value();
+            QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(window);
 
-            Q_ASSERT(canvasData->windowSize.width() > 0 && canvasData->windowSize.height() > 0);
+            Q_ASSERT(windowData->windowSize.width() > 0 && windowData->windowSize.height() > 0);
 
-            if (!canvasData->isVisible)
-                gl->makeCurrent(masterCanvas());
+            if (!windowData->isVisible)
+                gl->makeCurrent(masterWindow());
             else
-                gl->makeCurrent(canvas);
+                gl->makeCurrent(window);
 
-            if (canvasData->viewportSize != canvasData->windowSize) {
+            if (windowData->viewportSize != windowData->windowSize) {
 #ifdef THREAD_DEBUG
                 printf("                RenderThread: --- window has changed size...\n");
 #endif
-                canvasData->viewportSize = canvasData->windowSize;
-                canvasData->sizeWasChanged = true;
-                glViewport(0, 0, canvasData->viewportSize.width(), canvasData->viewportSize.height());
+                windowData->viewportSize = windowData->windowSize;
+                windowData->sizeWasChanged = true;
+                glViewport(0, 0, windowData->viewportSize.width(), windowData->viewportSize.height());
             }
 
-            canvasPrivate->syncSceneGraph();
+            windowPrivate->syncSceneGraph();
         }
         inSync = false;
 
@@ -649,65 +659,65 @@ void QQuickRenderThreadSingleContextWindowManager::run()
 #ifdef THREAD_DEBUG
         printf("                RenderThread: sync done\n");
 #endif
-#ifdef QQUICK_CANVAS_TIMING
-        if (qquick_canvas_timing)
+#ifdef QQUICK_RENDER_TIMING
+        if (qquick_render_timing)
             syncTime = threadTimer.elapsed();
 #endif
 
-        for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
+        for (QHash<QQuickWindow *, WindowData *>::const_iterator it = m_rendered_windows.constBegin();
              it != m_rendered_windows.constEnd(); ++it) {
-            QQuickCanvas *canvas = it.key();
-            CanvasData *canvasData = it.value();
-            QQuickCanvasPrivate *canvasPrivate = QQuickCanvasPrivate::get(canvas);
+            QQuickWindow *window = it.key();
+            WindowData *windowData = it.value();
+            QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(window);
 
 #ifdef THREAD_DEBUG
-            printf("                RenderThread: Rendering canvas %p\n", canvas);
+            printf("                RenderThread: Rendering window %p\n", window);
 #endif
 
-            Q_ASSERT(canvasData->windowSize.width() > 0 && canvasData->windowSize.height() > 0);
+            Q_ASSERT(windowData->windowSize.width() > 0 && windowData->windowSize.height() > 0);
 
 #ifdef THREAD_DEBUG
             printf("                RenderThread: --- rendering at size %dx%d\n",
-                   canvasData->viewportSize.width(), canvasData->viewportSize.height()
+                   windowData->viewportSize.width(), windowData->viewportSize.height()
                    );
 #endif
 
             // We only need to re-makeCurrent when we have multiple surfaces.
             if (m_rendered_windows.size() > 1)
-                gl->makeCurrent(canvas);
+                gl->makeCurrent(window);
 
-            canvasPrivate->renderSceneGraph(canvasData->viewportSize);
-#ifdef QQUICK_CANVAS_TIMING
-            if (qquick_canvas_timing)
+            windowPrivate->renderSceneGraph(windowData->viewportSize);
+#ifdef QQUICK_RENDER_TIMING
+            if (qquick_render_timing)
                 renderTime = threadTimer.elapsed() - syncTime;
 #endif
 
             // The content of the target buffer is undefined after swap() so grab needs
             // to happen before swap();
-            if (canvas == canvasToGrab) {
+            if (window == windowToGrab) {
 #ifdef THREAD_DEBUG
                 printf("                RenderThread: --- grabbing...\n");
 #endif
-                grabContent = qt_gl_read_framebuffer(canvasData->windowSize, false, false);
-                canvasToGrab = 0;
+                grabContent = qt_gl_read_framebuffer(windowData->windowSize, false, false);
+                windowToGrab = 0;
             }
 
 #ifdef THREAD_DEBUG
             printf("                RenderThread: --- wait for swap...\n");
 #endif
 
-            if (canvasData->isVisible)
-                gl->swapBuffers(canvas);
+            if (windowData->isVisible && window->isExposed())
+                gl->swapBuffers(window);
 
-            canvasPrivate->fireFrameSwapped();
+            windowPrivate->fireFrameSwapped();
 #ifdef THREAD_DEBUG
             printf("                RenderThread: --- swap complete...\n");
 #endif
 
         }
 
-#ifdef QQUICK_CANVAS_TIMING
-            if (qquick_canvas_timing) {
+#ifdef QQUICK_RENDER_TIMING
+            if (qquick_render_timing) {
                 swapTime = threadTimer.elapsed() - renderTime;
                 qDebug() << "- Breakdown of frame time; sync:" << syncTime
                          << "ms render:" << renderTime << "ms swap:" << swapTime
@@ -719,15 +729,13 @@ void QQuickRenderThreadSingleContextWindowManager::run()
 
         handleRemovedWindows();
 
-        isPaintCompleted = true;
-
         // Update sizes...
-        for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
+        for (QHash<QQuickWindow *, WindowData *>::const_iterator it = m_rendered_windows.constBegin();
              it != m_rendered_windows.constEnd(); ++it) {
-            CanvasData *canvasData = it.value();
-            if (canvasData->sizeWasChanged) {
-                canvasData->renderedSize = canvasData->viewportSize;
-                canvasData->sizeWasChanged = false;
+            WindowData *windowData = it.value();
+            if (windowData->sizeWasChanged) {
+                windowData->renderedSize = windowData->viewportSize;
+                windowData->sizeWasChanged = false;
             }
         }
 
@@ -738,7 +746,7 @@ void QQuickRenderThreadSingleContextWindowManager::run()
         // but we don't want to lock an extra time.
         wake();
 
-        if (!animationRunning && !isExternalUpdatePending && !shouldExit && !canvasToGrab) {
+        if (!animationRunning && !isExternalUpdatePending && !shouldExit && !windowToGrab) {
 #ifdef THREAD_DEBUG
             printf("                RenderThread: nothing to do, going to sleep...\n");
 #endif
@@ -760,7 +768,13 @@ void QQuickRenderThreadSingleContextWindowManager::run()
 #endif
 
     m_removed_windows << m_rendered_windows.keys();
-    handleRemovedWindows();
+    handleRemovedWindows(false);
+
+    sg->invalidate();
+
+    gl->doneCurrent();
+    delete gl;
+    gl = 0;
 
 #ifdef THREAD_DEBUG
     printf("                RenderThread: render loop exited... Good Night!\n");
@@ -780,67 +794,13 @@ void QQuickRenderThreadSingleContextWindowManager::run()
 #endif
 }
 
-void QQuickRenderThreadSingleContextWindowManager::releaseResourcesInThread()
-{
-#ifdef THREAD_DEBUG
-    printf("                RenderThread: releasing resources...\n");
-#endif
-
-    QQuickCanvas *canvas = masterCanvas();
-    QWindow *tmpSurface = 0;
-
-    if (canvas) {
-        gl->makeCurrent(canvas);
-    } else {
-        tmpSurface = new QWindow();
-        tmpSurface->setSurfaceType(QSurface::OpenGLSurface);
-        tmpSurface->resize(4, 4);
-        tmpSurface->create();
-        gl->makeCurrent(tmpSurface);
-    }
-
-    sg->invalidate();
-    gl->doneCurrent();
-    delete gl;
-    gl = 0;
-
-    if (tmpSurface)
-        delete tmpSurface;
-
-    wake();
-}
-
-void QQuickRenderThreadSingleContextWindowManager::releaseResources()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: releasing resources\n");
-#endif
-
-    lockInGui();
-    if (!isRunning() && gl) {
-        runToReleaseResources = true;
-        start();
-
-        while (gl) {
-            wait();
-        }
-    }
-#ifdef THREAD_DEBUG
-    else {
-        printf("GUI: render thread running not releasing resources...\n");
-    }
-#endif
-    unlockInGui();
-
-}
-
 bool QQuickRenderThreadSingleContextWindowManager::event(QEvent *e)
 {
     Q_ASSERT(QThread::currentThread() == qApp->thread());
 
     if (e->type() == QEvent_Sync) {
 
-        // If all canvases have been hidden, ignore the event
+        // If all windows have been hidden, ignore the event
         if (!isRunning())
             return true;
 
@@ -895,9 +855,9 @@ void QQuickRenderThreadSingleContextWindowManager::sync(bool guiAlreadyLocked)
     if (!guiAlreadyLocked)
         lockInGui();
 
-    for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
+    for (QHash<QQuickWindow *, WindowData *>::const_iterator it = m_rendered_windows.constBegin();
          it != m_rendered_windows.constEnd(); ++it) {
-        QQuickCanvasPrivate::get(it.key())->polishItems();
+        QQuickWindowPrivate::get(it.key())->polishItems();
     }
 
     wake();
@@ -983,50 +943,42 @@ void QQuickRenderThreadSingleContextWindowManager::animationStopped()
 }
 
 
-void QQuickRenderThreadSingleContextWindowManager::paint(QQuickCanvas *canvas)
+void QQuickRenderThreadSingleContextWindowManager::exposureChanged(QQuickWindow *window)
 {
-    Q_UNUSED(canvas);
+    Q_UNUSED(window);
 #ifdef THREAD_DEBUG
-    printf("GUI: paint called: %p\n", canvas);
+    printf("GUI: exposure changed: %p\n", window);
 #endif
 
-    lockInGui();
-    exhaustSyncEvent();
-
-    isPaintCompleted = false;
-    while (isRunning() && !isPaintCompleted) {
-        if (isRenderBlocked)
-            wake();
-        wait();
-    }
-    unlockInGui();
+    if (window->isExposed())
+        maybeUpdate(window);
 
 #ifdef THREAD_DEBUG
-    printf("GUI: paint done: %p\n", canvas);
+    printf("GUI: exposure changed done: %p\n", window);
 #endif
 }
 
 
 
-void QQuickRenderThreadSingleContextWindowManager::resize(QQuickCanvas *canvas, const QSize &size)
+void QQuickRenderThreadSingleContextWindowManager::resize(QQuickWindow *window, const QSize &size)
 {
 #ifdef THREAD_DEBUG
-    printf("GUI: Resize Event: %p = %dx%d\n", canvas, size.width(), size.height());
+    printf("GUI: Resize Event: %p = %dx%d\n", window, size.width(), size.height());
 #endif
 
     // If the rendering thread is not running we do not need to do anything.
-    // Also if the canvas is being resized to an invalid size, it will be removed
-    // by the canvasVisibilityChanged slot as result of width/heightcChanged()
+    // Also if the window is being resized to an invalid size, it will be removed
+    // by the windowVisibilityChanged slot as result of width/heightcChanged()
     if (!isRunning() || size.width() <= 0 || size.height() <= 0)
         return;
 
     lockInGui();
     exhaustSyncEvent();
 
-    CanvasData *canvasData = m_rendered_windows.value(canvas);
-    if (canvasData) {
-        canvasData->windowSize = size;
-        while (isRunning() && canvasData->renderedSize != size && size.width() > 0 && size.height() > 0) {
+    WindowData *windowData = m_rendered_windows.value(window);
+    if (windowData) {
+        windowData->windowSize = size;
+        while (isRunning() && windowData->renderedSize != size && size.width() > 0 && size.height() > 0) {
             if (isRenderBlocked)
                 wake();
             wait();
@@ -1035,7 +987,7 @@ void QQuickRenderThreadSingleContextWindowManager::resize(QQuickCanvas *canvas,
     unlockInGui();
 
 #ifdef THREAD_DEBUG
-    printf("GUI: Resize done: %p\n", canvas);
+    printf("GUI: Resize done: %p\n", window);
 #endif
 }
 
@@ -1065,6 +1017,7 @@ void QQuickRenderThreadSingleContextWindowManager::startRendering()
         animationTimer = -1;
     }
 
+
 }
 
 
@@ -1113,13 +1066,13 @@ void QQuickRenderThreadSingleContextWindowManager::stopRendering()
 
 
 
-QImage QQuickRenderThreadSingleContextWindowManager::grab(QQuickCanvas *canvas)
+QImage QQuickRenderThreadSingleContextWindowManager::grab(QQuickWindow *window)
 {
     if (!isRunning())
         return QImage();
 
     if (QThread::currentThread() != qApp->thread()) {
-        qWarning("QQuickCanvas::grabFrameBuffer: can only be called from the GUI thread");
+        qWarning("QQuickWindow::grabFrameBuffer: can only be called from the GUI thread");
         return QImage();
     }
 
@@ -1130,9 +1083,8 @@ QImage QQuickRenderThreadSingleContextWindowManager::grab(QQuickCanvas *canvas)
     lockInGui();
     exhaustSyncEvent();
 
-    canvasToGrab = canvas;
-    isPaintCompleted = false;
-    while (isRunning() && !isPaintCompleted) {
+    windowToGrab = window;
+    while (isRunning() && windowToGrab) {
         if (isRenderBlocked)
             wake();
         wait();
@@ -1162,10 +1114,10 @@ void QQuickRenderThreadSingleContextWindowManager::handleDeferredUpdate()
     unlockInGui();
 }
 
-void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickCanvas *)
+void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickWindow *)
 {
     Q_ASSERT_X(QThread::currentThread() == QCoreApplication::instance()->thread() || inSync,
-               "QQuickCanvas::update",
+               "QQuickWindow::update",
                "Function can only be called from GUI thread or during QQuickItem::updatePaintNode()");
 
     if (inSync) {
@@ -1181,6 +1133,15 @@ void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickCanvas *)
 
 }
 
+void QQuickRenderThreadSingleContextWindowManager::wakeup()
+{
+    lockInGui();
+    isExternalUpdatePending = true;
+    if (isRenderBlocked)
+        wake();
+    unlockInGui();
+}
+
 QQuickTrivialWindowManager::QQuickTrivialWindowManager()
     : gl(0)
     , eventPending(false)
@@ -1189,129 +1150,107 @@ QQuickTrivialWindowManager::QQuickTrivialWindowManager()
 }
 
 
-void QQuickTrivialWindowManager::show(QQuickCanvas *canvas)
+void QQuickTrivialWindowManager::show(QQuickWindow *window)
 {
-    CanvasData data;
+    WindowData data;
     data.updatePending = false;
     data.grabOnly = false;
-    m_windows[canvas] = data;
+    m_windows[window] = data;
 
-    maybeUpdate(canvas);
+    maybeUpdate(window);
 }
 
-void QQuickTrivialWindowManager::hide(QQuickCanvas *canvas)
+void QQuickTrivialWindowManager::hide(QQuickWindow *window)
 {
-    if (!m_windows.contains(canvas))
+    if (!m_windows.contains(window))
         return;
 
-    m_windows.remove(canvas);
-    QQuickCanvasPrivate *cd = QQuickCanvasPrivate::get(canvas);
+    m_windows.remove(window);
+    QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
     cd->cleanupNodesOnShutdown();
-}
-
-void QQuickTrivialWindowManager::canvasDestroyed(QQuickCanvas *canvas)
-{
-    hide(canvas);
-}
 
-void QQuickTrivialWindowManager::releaseResources()
-{
     if (m_windows.size() == 0) {
-        QQuickCanvas *canvas = masterCanvas();
-        QWindow *tmpSurface = 0;
-
-        if (canvas) {
-            gl->makeCurrent(canvas);
-        } else {
-            tmpSurface = new QWindow();
-            tmpSurface->setSurfaceType(QSurface::OpenGLSurface);
-            tmpSurface->resize(4, 4);
-            tmpSurface->create();
-            gl->makeCurrent(tmpSurface);
-        }
-
         sg->invalidate();
         delete gl;
         gl = 0;
-
-        delete tmpSurface;
     }
 }
 
-QQuickCanvas *QQuickTrivialWindowManager::masterCanvas() const
+void QQuickTrivialWindowManager::windowDestroyed(QQuickWindow *window)
 {
-    // Find a "proper surface" to bind...
-    for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin();
-             it != m_windows.constEnd(); ++it) {
-            if (it.key()->visible())
-                return it.key();
-    }
-    return 0;
+    hide(window);
 }
 
-void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas)
+void QQuickTrivialWindowManager::renderWindow(QQuickWindow *window)
 {
-    if (!m_windows.contains(canvas))
+    if (!window->isExposed() || !m_windows.contains(window))
         return;
 
-    CanvasData &data = const_cast<CanvasData &>(m_windows[canvas]);
+    WindowData &data = const_cast<WindowData &>(m_windows[window]);
 
-    QQuickCanvas *window = canvas->visible() ? canvas : masterCanvas();
+    QQuickWindow *masterWindow = 0;
+    if (!window->isVisible()) {
+        // Find a "proper surface" to bind...
+        for (QHash<QQuickWindow *, WindowData>::const_iterator it = m_windows.constBegin();
+             it != m_windows.constEnd() && !masterWindow; ++it) {
+            if (it.key()->isVisible())
+                masterWindow = it.key();
+        }
+    } else {
+        masterWindow = window;
+    }
 
-    if (!window)
+    if (!masterWindow)
         return;
 
     if (!gl) {
         gl = new QOpenGLContext();
-        gl->setFormat(window->requestedFormat());
+        gl->setFormat(masterWindow->requestedFormat());
         gl->create();
-        if (!gl->makeCurrent(window))
-            qWarning("QQuickCanvas: makeCurrent() failed...");
+        if (!gl->makeCurrent(masterWindow))
+            qWarning("QQuickWindow: makeCurrent() failed...");
         sg->initialize(gl);
     } else {
-        gl->makeCurrent(window);
+        gl->makeCurrent(masterWindow);
     }
 
     bool alsoSwap = data.updatePending;
     data.updatePending = false;
 
-    QQuickCanvasPrivate *cd = QQuickCanvasPrivate::get(canvas);
+    QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
     cd->polishItems();
     cd->syncSceneGraph();
-    cd->renderSceneGraph(canvas->size());
+    cd->renderSceneGraph(window->size());
 
     if (data.grabOnly) {
-        grabContent = qt_gl_read_framebuffer(canvas->size(), false, false);
+        grabContent = qt_gl_read_framebuffer(window->size(), false, false);
         data.grabOnly = false;
     }
 
-    if (alsoSwap && canvas->visible()) {
-        gl->swapBuffers(canvas);
+    if (alsoSwap && window->isVisible()) {
+        gl->swapBuffers(window);
         cd->fireFrameSwapped();
     }
 
     // Might have been set during syncSceneGraph()
     if (data.updatePending)
-        maybeUpdate(canvas);
+        maybeUpdate(window);
 }
 
-void QQuickTrivialWindowManager::paint(QQuickCanvas *canvas)
+void QQuickTrivialWindowManager::exposureChanged(QQuickWindow *window)
 {
-    if (!m_windows.contains(canvas))
-        return;
-
-    m_windows[canvas].updatePending = true;
-    renderCanvas(canvas);
+    if (window->isExposed())
+        maybeUpdate(window);
 }
 
-QImage QQuickTrivialWindowManager::grab(QQuickCanvas *canvas)
+QImage QQuickTrivialWindowManager::grab(QQuickWindow *window)
 {
-    if (!m_windows.contains(canvas))
+    if (!m_windows.contains(window))
         return QImage();
 
-    m_windows[canvas].grabOnly = true;
+    m_windows[window].grabOnly = true;
 
-    renderCanvas(canvas);
+    renderWindow(window);
 
     QImage grabbed = grabContent;
     grabContent = QImage();
@@ -1320,18 +1259,18 @@ QImage QQuickTrivialWindowManager::grab(QQuickCanvas *canvas)
 
 
 
-void QQuickTrivialWindowManager::resize(QQuickCanvas *, const QSize &)
+void QQuickTrivialWindowManager::resize(QQuickWindow *, const QSize &)
 {
 }
 
 
 
-void QQuickTrivialWindowManager::maybeUpdate(QQuickCanvas *canvas)
+void QQuickTrivialWindowManager::maybeUpdate(QQuickWindow *window)
 {
-    if (!m_windows.contains(canvas))
+    if (!m_windows.contains(window))
         return;
 
-    m_windows[canvas].updatePending = true;
+    m_windows[window].updatePending = true;
 
     if (!eventPending) {
         QCoreApplication::postEvent(this, new QEvent(QEvent::User));
@@ -1339,9 +1278,11 @@ void QQuickTrivialWindowManager::maybeUpdate(QQuickCanvas *canvas)
     }
 }
 
+void QQuickTrivialWindowManager::wakeup()
+{
+}
 
-
-bool *QQuickTrivialWindowManager::allowMainThreadProcessing()
+volatile bool *QQuickTrivialWindowManager::allowMainThreadProcessing()
 {
     return 0;
 }
@@ -1358,11 +1299,11 @@ bool QQuickTrivialWindowManager::event(QEvent *e)
 {
     if (e->type() == QEvent::User) {
         eventPending = false;
-        for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin();
+        for (QHash<QQuickWindow *, WindowData>::const_iterator it = m_windows.constBegin();
              it != m_windows.constEnd(); ++it) {
-            const CanvasData &data = it.value();
+            const WindowData &data = it.value();
             if (data.updatePending)
-                renderCanvas(it.key());
+                renderWindow(it.key());
         }
         return true;
     }