From 5cc9b79675c9d1e17e0153ca2ddf42771a09cfe3 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 24 Feb 2012 07:28:54 +0100 Subject: [PATCH] Revert resource releasing logic inside window managers. This was based on the assumption that exposure and visibility would take similar code paths, but this is not the case and the fallout of this change (like not releasing resources at all) is not worth it. This reverts ef6318ae38322b5a4a0619b581924290f114fa74 and most of 5f0013ee76605b9c7ceab168702b57e797b698e0 Change-Id: Ib2e29972502a8ec956cd6bd294a2a2bb50d8e76e Reviewed-by: Alan Alpert --- src/quick/items/qquickwindowmanager.cpp | 154 ++++++++----------------------- src/quick/items/qquickwindowmanager_p.h | 2 + 2 files changed, 39 insertions(+), 117 deletions(-) diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp index b999e6f..16b6d92 100644 --- a/src/quick/items/qquickwindowmanager.cpp +++ b/src/quick/items/qquickwindowmanager.cpp @@ -48,8 +48,8 @@ #include #include -#include #include +#include #include @@ -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); @@ -201,8 +201,6 @@ public: void sync(bool guiAlreadyLocked); void initialize(); - void releaseResources(); - void releaseResourcesInThread(); bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; } @@ -258,7 +256,6 @@ private: uint shouldExit : 1; uint hasExited : 1; uint isDeferredUpdatePosted : 1; - uint runToReleaseResources : 1; QQuickCanvas *canvasToGrab; QImage grabContent; @@ -291,17 +288,12 @@ 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); @@ -310,10 +302,11 @@ public: void maybeUpdate(QQuickCanvas *canvas); + void releaseResources() { } + bool *allowMainThreadProcessing(); QSGContext *sceneGraphContext() const; - QQuickCanvas *masterCanvas() const; bool event(QEvent *); @@ -564,18 +557,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 +757,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 +781,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 +1012,7 @@ void QQuickRenderThreadSingleContextWindowManager::startRendering() animationTimer = -1; } + } @@ -1216,46 +1155,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::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 +1175,30 @@ void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas) CanvasData &data = const_cast(m_windows[canvas]); - QQuickCanvas *window = canvas->visible() ? canvas : masterCanvas(); + QQuickCanvas *masterCanvas = 0; + if (!canvas->visible()) { + // Find a "proper surface" to bind... + for (QHash::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; diff --git a/src/quick/items/qquickwindowmanager_p.h b/src/quick/items/qquickwindowmanager_p.h index 014b381..8631265 100644 --- a/src/quick/items/qquickwindowmanager_p.h +++ b/src/quick/items/qquickwindowmanager_p.h @@ -52,6 +52,8 @@ class QSGContext; class QQuickWindowManager { public: + virtual ~QQuickWindowManager(); + virtual void show(QQuickCanvas *canvas) = 0; virtual void hide(QQuickCanvas *canvas) = 0; -- 1.7.2.5