From 96e484c95629afd1f550449296f82c0561e64d26 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Tue, 8 Nov 2011 10:04:45 +0200 Subject: Fix to QtOpenGL crash on Symbian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under some rare circumstances EGL context creation fails on Symbian leading to application crash. However, Qt is able to recover from this if context pointers are guarded by null pointer checks in QtOpenGL. Task-number: QT-5334 Reviewed-by: Samuel Rødal --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 4 +++ src/opengl/qwindowsurface_gl.cpp | 31 +++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index f5fe739..2db5b79 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -2108,6 +2108,10 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) return false; d->ctx = d->device->context(); +#ifdef Q_OS_SYMBIAN + if (!d->ctx) + return false; +#endif d->ctx->d_ptr->active_engine = this; const QSize sz = d->device->size(); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index d93efb4..e963f8c 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -192,6 +192,14 @@ public: if (!initializing && !widget && !cleanedUp) { initializing = true; widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer)); +#ifdef Q_OS_SYMBIAN + if (!widget->context()->isValid()) { + delete widget; + widget = 0; + initializing = false; + return 0; + } +#endif widget->resize(1, 1); // We don't need this internal widget to appear in QApplication::topLevelWidgets() @@ -369,7 +377,7 @@ QGLWindowSurface::~QGLWindowSurface() #ifdef Q_OS_SYMBIAN // Destroy the context if necessary. - if (!qt_gl_share_widget()->context()->isSharing()) + if (qt_gl_share_widget() && !qt_gl_share_context()->isSharing()) qt_destroy_gl_share_widget(); #endif } @@ -420,7 +428,12 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) ctx = new QGLContext(surfaceFormat, widget); ctx->create(qt_gl_share_context()); - +#ifdef Q_OS_SYMBIAN + if (!ctx->isValid()) { + delete ctx; + return; + } +#endif #ifndef QT_NO_EGL static bool checkedForNOKSwapRegion = false; static bool haveNOKSwapRegion = false; @@ -468,6 +481,10 @@ QPaintDevice *QGLWindowSurface::paintDevice() { updateGeometry(); +#ifdef Q_OS_SYMBIAN + // On symbian we always return glDevice, even if it's invalid + return &d_ptr->glDevice; +#else if (d_ptr->pb) return d_ptr->pb; @@ -479,6 +496,7 @@ QPaintDevice *QGLWindowSurface::paintDevice() Q_ASSERT(d_ptr->fbo); return d_ptr->fbo; +#endif } static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &src = QRectF()); @@ -693,6 +711,10 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & QGLContext *previous_ctx = const_cast(QGLContext::currentContext()); QGLContext *ctx = reinterpret_cast(parent->d_func()->extraData()->glContext); +#ifdef Q_OS_SYMBIAN + if (!ctx) + return; +#endif // QPainter::end() should have unbound the fbo, otherwise something is very wrong... Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound()); @@ -892,7 +914,10 @@ void QGLWindowSurface::updateGeometry() { hijackWindow(window()); QGLContext *ctx = reinterpret_cast(wd->extraData()->glContext); - +#ifdef Q_OS_SYMBIAN + if (!ctx) + return; +#endif #ifdef Q_WS_MAC ctx->updatePaintDevice(); #endif -- cgit v0.12