diff options
Diffstat (limited to 'src/quick/items/qquickwindowmanager.cpp')
-rw-r--r-- | src/quick/items/qquickwindowmanager.cpp | 176 |
1 files changed, 54 insertions, 122 deletions
diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp index 55f11bf4c0..5de8ad1279 100644 --- a/src/quick/items/qquickwindowmanager.cpp +++ b/src/quick/items/qquickwindowmanager.cpp @@ -48,8 +48,8 @@ #include <QtCore/private/qabstractanimation_p.h> #include <QtGui/QOpenGLContext> -#include <QtGui/QPlatformIntegration> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qplatformintegration_qpa.h> #include <QtQml/private/qqmlglobal_p.h> @@ -145,6 +145,10 @@ DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP); //#define THREAD_DEBUG +QQuickWindowManager::~QQuickWindowManager() +{ +} + class QQuickRenderThreadSingleContextWindowManager : public QThread, public QQuickWindowManager { Q_OBJECT @@ -165,7 +169,6 @@ public: , shouldExit(false) , hasExited(false) , isDeferredUpdatePosted(false) - , runToReleaseResources(false) , canvasToGrab(0) { sg->moveToThread(this); @@ -176,13 +179,10 @@ public: connect(animationDriver, SIGNAL(stopped()), this, SLOT(animationStopped())); } - ~QQuickRenderThreadSingleContextWindowManager() - { - releaseResources(); - } - QSGContext *sceneGraphContext() const { return sg; } + void releaseResources() { } + void show(QQuickCanvas *canvas); void hide(QQuickCanvas *canvas); @@ -193,6 +193,7 @@ public: void resize(QQuickCanvas *canvas, const QSize &size); void handleDeferredUpdate(); void maybeUpdate(QQuickCanvas *canvas); + void wakeup(); void startRendering(); void stopRendering(); @@ -201,10 +202,8 @@ public: void sync(bool guiAlreadyLocked); void initialize(); - void releaseResources(); - void releaseResourcesInThread(); - bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; } + volatile bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; } bool event(QEvent *); @@ -245,7 +244,7 @@ private: QMutex mutex; QWaitCondition condition; - bool allowMainThreadProcessingFlag; + volatile bool allowMainThreadProcessingFlag; int isGuiLocked; uint animationRunning: 1; @@ -258,7 +257,6 @@ private: uint shouldExit : 1; uint hasExited : 1; uint isDeferredUpdatePosted : 1; - uint runToReleaseResources : 1; QQuickCanvas *canvasToGrab; QImage grabContent; @@ -291,29 +289,26 @@ class QQuickTrivialWindowManager : public QObject, public QQuickWindowManager { public: QQuickTrivialWindowManager(); - ~QQuickTrivialWindowManager() - { - releaseResources(); - } void show(QQuickCanvas *canvas); void hide(QQuickCanvas *canvas); void canvasDestroyed(QQuickCanvas *canvas); - void releaseResources(); void initializeGL(); void renderCanvas(QQuickCanvas *canvas); void paint(QQuickCanvas *canvas); QImage grab(QQuickCanvas *canvas); void resize(QQuickCanvas *canvas, const QSize &size); + void wakeup(); void maybeUpdate(QQuickCanvas *canvas); - bool *allowMainThreadProcessing(); + void releaseResources() { } + + volatile bool *allowMainThreadProcessing(); QSGContext *sceneGraphContext() const; - QQuickCanvas *masterCanvas() const; bool event(QEvent *); @@ -564,18 +559,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(); @@ -772,6 +759,12 @@ void QQuickRenderThreadSingleContextWindowManager::run() m_removed_windows << m_rendered_windows.keys(); handleRemovedWindows(); + sg->invalidate(); + + gl->doneCurrent(); + delete gl; + gl = 0; + #ifdef THREAD_DEBUG printf(" RenderThread: render loop exited... Good Night!\n"); #endif @@ -790,59 +783,6 @@ 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 (isRunning()) { - 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()); @@ -1074,6 +1014,7 @@ void QQuickRenderThreadSingleContextWindowManager::startRendering() animationTimer = -1; } + } @@ -1190,6 +1131,14 @@ void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickCanvas *) } +void QQuickRenderThreadSingleContextWindowManager::wakeup() +{ + lockInGui(); + if (isRenderBlocked) + wake(); + unlockInGui(); +} + QQuickTrivialWindowManager::QQuickTrivialWindowManager() : gl(0) , eventPending(false) @@ -1216,46 +1165,17 @@ void QQuickTrivialWindowManager::hide(QQuickCanvas *canvas) m_windows.remove(canvas); QQuickCanvasPrivate *cd = QQuickCanvasPrivate::get(canvas); cd->cleanupNodesOnShutdown(); -} - -void QQuickTrivialWindowManager::canvasDestroyed(QQuickCanvas *canvas) -{ - hide(canvas); -} - -void QQuickTrivialWindowManager::releaseResources() -{ - if (m_windows.size() == 0 && gl) { - 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); - } + if (m_windows.size() == 0) { sg->invalidate(); delete gl; gl = 0; - - delete tmpSurface; } } -QQuickCanvas *QQuickTrivialWindowManager::masterCanvas() const +void QQuickTrivialWindowManager::canvasDestroyed(QQuickCanvas *canvas) { - // 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(canvas); } void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas) @@ -1265,20 +1185,30 @@ void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas) CanvasData &data = const_cast<CanvasData &>(m_windows[canvas]); - QQuickCanvas *window = canvas->visible() ? canvas : masterCanvas(); + QQuickCanvas *masterCanvas = 0; + if (!canvas->visible()) { + // Find a "proper surface" to bind... + for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin(); + it != m_windows.constEnd() && !masterCanvas; ++it) { + if (it.key()->visible()) + masterCanvas = it.key(); + } + } else { + masterCanvas = canvas; + } - if (!window) + if (!masterCanvas) return; if (!gl) { gl = new QOpenGLContext(); - gl->setFormat(window->requestedFormat()); + gl->setFormat(masterCanvas->requestedFormat()); gl->create(); - if (!gl->makeCurrent(window)) + if (!gl->makeCurrent(masterCanvas)) qWarning("QQuickCanvas: makeCurrent() failed..."); sg->initialize(gl); } else { - gl->makeCurrent(window); + gl->makeCurrent(masterCanvas); } bool alsoSwap = data.updatePending; @@ -1348,9 +1278,11 @@ void QQuickTrivialWindowManager::maybeUpdate(QQuickCanvas *canvas) } } +void QQuickTrivialWindowManager::wakeup() +{ +} - -bool *QQuickTrivialWindowManager::allowMainThreadProcessing() +volatile bool *QQuickTrivialWindowManager::allowMainThreadProcessing() { return 0; } |