diff options
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickshadereffectsource.cpp | 15 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickwindowmodule.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 53 | ||||
-rw-r--r-- | src/quick/util/qquickpixmapcache.cpp | 11 |
5 files changed, 49 insertions, 33 deletions
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index e076a342df..98203c51e5 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -158,16 +158,24 @@ QQuickShaderEffectTexture::QQuickShaderEffectTexture(QQuickItem *shaderSource) QQuickShaderEffectTexture::~QQuickShaderEffectTexture() { - if (m_renderer) - disconnect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture())); + invalidated(); +} + +void QQuickShaderEffectTexture::invalidated() +{ delete m_renderer; + m_renderer = 0; delete m_fbo; delete m_secondaryFbo; + m_fbo = m_secondaryFbo = 0; #ifdef QSG_DEBUG_FBO_OVERLAY delete m_debugOverlay; + m_debugOverlay = 0; #endif - if (m_transparentTexture) + if (m_transparentTexture) { glDeleteTextures(1, &m_transparentTexture); + m_transparentTexture = 0; + } } int QQuickShaderEffectTexture::textureId() const @@ -609,6 +617,7 @@ void QQuickShaderEffectSource::ensureTexture() "Cannot be used outside the rendering thread"); m_texture = new QQuickShaderEffectTexture(this); + connect(QQuickItemPrivate::get(this)->window, SIGNAL(sceneGraphInvalidated()), m_texture, SLOT(invalidated()), Qt::DirectConnection); connect(m_texture, SIGNAL(updateRequested()), this, SLOT(update())); connect(m_texture, SIGNAL(scheduledUpdateCompleted()), this, SIGNAL(scheduledUpdateCompleted())); } diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 6218775700..efa963fe64 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -124,6 +124,7 @@ Q_SIGNALS: public Q_SLOTS: void markDirtyTexture(); + void invalidated(); private: void grab(); diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index cd1b68991d..44a4bf3db6 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -82,7 +82,7 @@ public: if (!m_complete) m_visibility = visibility; else - QQuickWindow::setVisibility(m_visibility); + QQuickWindow::setVisibility(visibility); } Q_SIGNALS: diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 6c27cb68c7..d779285a44 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -48,6 +48,7 @@ #include <QtGui/QGuiApplication> #include <QtGui/QScreen> +#include <QtGui/QOffscreenSurface> #include <QtQuick/QQuickWindow> #include <private/qquickwindow_p.h> @@ -205,12 +206,14 @@ public: class WMTryReleaseEvent : public WMWindowEvent { public: - WMTryReleaseEvent(QQuickWindow *win, bool destroy) + WMTryReleaseEvent(QQuickWindow *win, bool destroy, QOffscreenSurface *fallback) : WMWindowEvent(win, WM_TryRelease) , inDestructor(destroy) + , fallbackSurface(fallback) {} bool inDestructor; + QOffscreenSurface *fallbackSurface; }; class WMExposeEvent : public WMWindowEvent @@ -295,7 +298,7 @@ public: delete sgrc; } - void invalidateOpenGL(QQuickWindow *window, bool inDestructor); + void invalidateOpenGL(QQuickWindow *window, bool inDestructor, QOffscreenSurface *backupSurface); void initializeOpenGL(); bool event(QEvent *); @@ -362,17 +365,9 @@ bool QSGRenderThread::event(QEvent *e) case WM_Expose: { QSG_RT_DEBUG("WM_Expose"); WMExposeEvent *se = static_cast<WMExposeEvent *>(e); - - pendingUpdate |= RepaintRequest; - Q_ASSERT(!window || window == se->window); - + pendingUpdate |= RepaintRequest; windowSize = se->size; - if (window) { - QSG_RT_DEBUG(" - window already added..."); - return true; - } - window = se->window; return true; } @@ -383,7 +378,7 @@ bool QSGRenderThread::event(QEvent *e) mutex.lock(); if (window) { - QSG_RT_DEBUG(" - removed one..."); + QSG_RT_DEBUG(" - removed window..."); window = 0; } waitCondition.wakeOne(); @@ -406,7 +401,7 @@ bool QSGRenderThread::event(QEvent *e) WMTryReleaseEvent *wme = static_cast<WMTryReleaseEvent *>(e); if (!window || wme->inDestructor) { QSG_RT_DEBUG(" - setting exit flag and invalidating GL"); - invalidateOpenGL(wme->window, wme->inDestructor); + invalidateOpenGL(wme->window, wme->inDestructor, wme->fallbackSurface); active = gl; if (sleeping) stopEventProcessing = true; @@ -455,7 +450,7 @@ bool QSGRenderThread::event(QEvent *e) return QThread::event(e); } -void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor) +void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, QOffscreenSurface *fallback) { QSG_RT_DEBUG("invalidateOpenGL()"); @@ -471,7 +466,13 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor) bool wipeSG = inDestructor || !window->isPersistentSceneGraph(); bool wipeGL = inDestructor || (wipeSG && !window->isPersistentOpenGLContext()); - gl->makeCurrent(window); + bool current = gl->makeCurrent(fallback ? static_cast<QSurface *>(fallback) : static_cast<QSurface *>(window)); + if (!current) { +#ifndef QT_NO_DEBUG + qWarning() << "Scene Graph failed to acquire GL context during cleanup"; +#endif + return; + } // The canvas nodes must be cleaned up regardless if we are in the destructor.. if (wipeSG) { @@ -479,6 +480,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor) dd->cleanupNodesOnShutdown(); } else { QSG_RT_DEBUG(" - persistent SG, avoiding cleanup"); + gl->doneCurrent(); return; } @@ -512,7 +514,6 @@ void QSGRenderThread::sync() if (windowSize.width() > 0 && windowSize.height() > 0) current = gl->makeCurrent(window); if (current) { - gl->makeCurrent(window); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); bool hadRenderer = d->renderer != 0; d->syncSceneGraph(); @@ -530,7 +531,6 @@ void QSGRenderThread::sync() QSG_RT_DEBUG(" - window has bad size, waiting..."); } - QSG_RT_DEBUG(" - window has bad size, waiting..."); waitCondition.wakeOne(); mutex.unlock(); } @@ -1041,9 +1041,26 @@ void QSGThreadedRenderLoop::releaseResources(QQuickWindow *window, bool inDestru w->thread->mutex.lock(); if (w->thread->isRunning() && w->thread->active) { + + // The platform window might have been destroyed before + // hide/release/windowDestroyed is called, so we need to have a + // fallback surface to perform the cleanup of the scene graph + // and the OpenGL resources. + // QOffscreenSurface must be created on the GUI thread, so we + // create it here and pass it on to QSGRenderThread::invalidateGL() + QOffscreenSurface *fallback = 0; + if (!window->handle()) { + QSG_GUI_DEBUG(w->window, " - using fallback surface"); + fallback = new QOffscreenSurface(); + fallback->setFormat(window->requestedFormat()); + fallback->create(); + } + QSG_GUI_DEBUG(w->window, " - posting release request to render thread"); - w->thread->postEvent(new WMTryReleaseEvent(window, inDestructor)); + w->thread->postEvent(new WMTryReleaseEvent(window, inDestructor, fallback)); w->thread->waitCondition.wait(&w->thread->mutex); + + delete fallback; } w->thread->mutex.unlock(); } diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 16ed94f91f..055d6b7e29 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -1033,17 +1033,6 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q if (localFile.isEmpty()) return 0; - // check for "retina" high-dpi and use @2x file if it exixts - if (qApp->devicePixelRatio() > 1) { - const int dotIndex = localFile.lastIndexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString retinaFile = localFile; - retinaFile.insert(dotIndex, QStringLiteral("@2x")); - if (QFile(retinaFile).exists()) - localFile = retinaFile; - } - } - QFile f(localFile); QSize readSize; QString errorString; |