diff options
author | Pauli Jarvinen <ext-pauli.p.jarvinen@nokia.com> | 2012-02-03 12:14:05 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-08 12:19:04 (GMT) |
commit | f0d703557322d1b536e72bbba8209f6a615f6dc1 (patch) | |
tree | 24f04fca831b23fea4728f5d841dff33cfba478c /src/gui/kernel | |
parent | d5649547d641b9c5af3c3f814caf8e1ab5bf9f47 (diff) | |
download | Qt-f0d703557322d1b536e72bbba8209f6a615f6dc1.zip Qt-f0d703557322d1b536e72bbba8209f6a615f6dc1.tar.gz Qt-f0d703557322d1b536e72bbba8209f6a615f6dc1.tar.bz2 |
Prevent crashing on Symbian in case EGL surface creation fails.
It is possible in environment with limited resources, that EGL
surface creation fails. When this happens, the QPainter doesn't
get properly activated, which in turn caused a crash later in
the drawing code.
Now, a check has been added into qapplication_s60.cpp to abort
window drawing immediately, if surface creation has failed. The
EGL surface is then tried to be recreated on the next time when
the window becomes visible, which usually allows the application
to recover.
In most cases, the crash happened in the function qDrawBorderPixmap,
which didn't check the validity of the QPaintEngine pointer before
accessing it. This method is analogous with the public methods of
the class QPainter where, on the other hand, availability of
QPaintEngine was always checked. To be in line, and to prevent
ptential crashes, a similar safety check and warning message have
now been added to method qDrawBorderPixmap.
Furthermore, a null-check was added to qwindowsurface_gl.cpp for the
QGLContext pointer. The same pointer was already previously
null-checked in the other branch of the same function, indicating
that the null-check is probably necessary.
Task-number: ou1cimx1#969923
Change-Id: I6d78be72b9c2308ef74b1119d8c8ec34ec015195
Reviewed-by: Jaakko Helanti <ext-jaakko.helanti@nokia.com>
Reviewed-by: Pasi Pentikäinen <ext-pasi.a.pentikainen@nokia.com>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 11 | ||||
-rw-r--r-- | src/gui/kernel/qt_s60_p.h | 1 |
2 files changed, 11 insertions, 1 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 2338ff4..38947e1 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -243,7 +243,9 @@ void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible) QApplicationPrivate *d = QApplicationPrivate::instance(); d->emitAboutToUseGpuResources(); - if (backingStore.data()) { + // (Re)create the backing store and force repaint if we have no + // backing store already, or EGL surface cration failed on last attempt. + if (backingStore.data() && !S60->eglSurfaceCreationError) { backingStore.registerWidget(widget); } else { S60->eglSurfaceCreationError = false; @@ -1348,6 +1350,13 @@ void QSymbianControl::Draw(const TRect& aRect) const void QSymbianControl::doDraw(const TRect& controlRect) const { + // Bail out immediately, if we don't have a drawing surface. Surface is attempted to be recreated + // when this application becomes visible for the next time. + if (S60->eglSurfaceCreationError) { + qWarning() << "QSymbianControl::doDraw: EGL surface creation has failed, abort"; + return; + } + // Set flag to avoid calling DrawNow in window surface QWidget *window = qwidget->window(); Q_ASSERT(window); diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index ab0aeb5..e1f50f4 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -388,6 +388,7 @@ inline QS60Data::QS60Data() screenFurnitureFullyCreated(0), beginFullScreenCalled(0), endFullScreenCalled(0), + eglSurfaceCreationError(0), s60ApplicationFactory(0), s60InstalledTrapHandler(0), editorFlags(0) |