aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-06-08 16:59:33 +1000
committerAaron Kennedy <aaron.kennedy@nokia.com>2011-06-08 16:59:50 +1000
commite2d979243c398a46ee9c3b1f36c647884952b6c7 (patch)
tree38fe296b1f668600648a61087e93b6c027459187
parent6dbd4286eb19e9ac45665046a43342bcdc8b127e (diff)
Don't crash if GL context initialization failed
-rw-r--r--src/declarative/items/qsgcanvas.cpp84
-rw-r--r--src/declarative/items/qsgcanvas_p.h1
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;