diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-06-08 16:59:33 +1000 |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-06-08 16:59:50 +1000 |
commit | e2d979243c398a46ee9c3b1f36c647884952b6c7 (patch) | |
tree | 38fe296b1f668600648a61087e93b6c027459187 | |
parent | 6dbd4286eb19e9ac45665046a43342bcdc8b127e (diff) |
Don't crash if GL context initialization failed
-rw-r--r-- | src/declarative/items/qsgcanvas.cpp | 84 | ||||
-rw-r--r-- | src/declarative/items/qsgcanvas_p.h | 1 |
2 files changed, 49 insertions, 36 deletions
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 16bd8ce44c..8caf1856ab 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -222,29 +222,31 @@ void QSGCanvas::showEvent(QShowEvent *e) QGLWidget::showEvent(e); - if (d->threadedRendering) { - d->contextInThread = true; - doneCurrent(); - if (!d->animationDriver) { - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(_q_animationStarted()), Qt::DirectConnection); - connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(_q_animationStopped()), Qt::DirectConnection); - } - d->animationDriver->install(); - d->mutex.lock(); - d->thread->start(); - d->wait.wait(&d->mutex); - d->mutex.unlock(); - } else { - makeCurrent(); + if (!d->contextFailed) { + if (d->threadedRendering) { + d->contextInThread = true; + doneCurrent(); + if (!d->animationDriver) { + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), this, SLOT(_q_animationStarted()), Qt::DirectConnection); + connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(_q_animationStopped()), Qt::DirectConnection); + } + d->animationDriver->install(); + d->mutex.lock(); + d->thread->start(); + d->wait.wait(&d->mutex); + d->mutex.unlock(); + } else { + makeCurrent(); - if (!d->context || !d->context->isReady()) { - d->initializeSceneGraph(); - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); - } + if (!d->context || !d->context->isReady()) { + d->initializeSceneGraph(); + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); + } - d->animationDriver->install(); + d->animationDriver->install(); + } } } @@ -252,10 +254,12 @@ void QSGCanvas::hideEvent(QHideEvent *e) { Q_D(QSGCanvas); - if (d->threadedRendering) - d->stopRenderingThread(); + if (!d->contextFailed) { + if (d->threadedRendering) + d->stopRenderingThread(); - d->animationDriver->uninstall(); + d->animationDriver->uninstall(); + } QGLWidget::hideEvent(e); } @@ -460,6 +464,7 @@ QSGCanvasPrivate::QSGCanvasPrivate() , hoverItem(0) , dirtyItemList(0) , context(0) + , contextFailed(false) , contextInThread(false) , threadedRendering(false) , exitThread(false) @@ -482,6 +487,11 @@ void QSGCanvasPrivate::init(QSGCanvas *c) { QUnifiedTimer::instance(true)->setConsistentTiming(qmlFixedAnimationStep()); + if (!c->context() || !c->context()->isValid()) { + contextFailed = true; + qWarning("QSGCanvas: Couldn't acquire a GL context."); + } + q_ptr = c; Q_Q(QSGCanvas); @@ -960,18 +970,20 @@ QSGCanvas::~QSGCanvas() d->cleanupNodes(); - // We need to remove all references to textures pointing to "our" QSGContext - // from the QDeclarativePixmapCache. Call into the cache to remove the GL / Scene Graph - // part of those cache entries. - // To "play nice" with other GL apps that are potentially running in the GUI thread, - // We get the current context and only temporarily make our own current - QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext()); - makeCurrent(); - extern void qt_declarative_pixmapstore_clean(QSGContext *context); - qt_declarative_pixmapstore_clean(d->context); - delete d->context; - if (currentContext) - currentContext->makeCurrent(); + if (!d->contextFailed) { + // We need to remove all references to textures pointing to "our" QSGContext + // from the QDeclarativePixmapCache. Call into the cache to remove the GL / Scene Graph + // part of those cache entries. + // To "play nice" with other GL apps that are potentially running in the GUI thread, + // We get the current context and only temporarily make our own current + QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext()); + makeCurrent(); + extern void qt_declarative_pixmapstore_clean(QSGContext *context); + qt_declarative_pixmapstore_clean(d->context); + delete d->context; + if (currentContext) + currentContext->makeCurrent(); + } } QSGItem *QSGCanvas::rootItem() const diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h index 6b8034f922..9d37391f57 100644 --- a/src/declarative/items/qsgcanvas_p.h +++ b/src/declarative/items/qsgcanvas_p.h @@ -156,6 +156,7 @@ public: QSGContext *context; + uint contextFailed : 1; uint contextInThread : 1; uint threadedRendering : 1; uint exitThread : 1; |