From f5592ef682ce18e7e6fd3770de722a5255a34ef7 Mon Sep 17 00:00:00 2001 From: Sami Kyostila Date: Mon, 28 Mar 2011 18:08:29 +0200 Subject: QMeeGoLivePixmapData: Verify dimensions of locked pixmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a switch from HW rendering to SW rendering is done, all EGL surfaces backing a live pixmap become invalid because EGL is terminated. Thanks to a recent patch, all live images are now automatically invalidated when SW rendering is activated. Even with this mechanism in place, it is possible for the underlying EGL surface to be different than what the live pixmap is expecting. This can happen, for instance, if the X pixmap gets destroyed and a different X drawable is created using the same XID. Even though this is an unlikely scenario, it can result in a complete system failure if the surface dimensions do not match and the live pixmap user ends up writing over internal graphics driver structures. This patch adds a safeguard which disallows locking EGL surfaces with non-matching dimensions. Fixes Harmattan bug NB#237138. Merge-request: 2583 Reviewed-by: Samuel Rødal --- src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp index 0970b89..b6ba7ec 100644 --- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp +++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp @@ -194,6 +194,8 @@ QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync) void *data = 0; int pitch = 0; + int surfaceWidth = 0; + int surfaceHeight = 0; EGLSurface surface = 0; QImage::Format format; lockedImage = QImage(); @@ -206,9 +208,11 @@ QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync) eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) &data); eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) &pitch); + eglQuerySurface(QEgl::display(), surface, EGL_WIDTH, (EGLint*) &surfaceWidth); + eglQuerySurface(QEgl::display(), surface, EGL_HEIGHT, (EGLint*) &surfaceHeight); // Ok, here we know we just support those two formats. Real solution would be: - // uqery also the format. + // query also the format. if (backingX11Pixmap->depth() > 16) format = QImage::Format_ARGB32_Premultiplied; else @@ -219,6 +223,12 @@ QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync) return &lockedImage; } + if (width() != surfaceWidth || height() != surfaceHeight) { + qWarning("Live texture dimensions don't match!"); + QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface); + return &lockedImage; + } + lockedImage = QImage((uchar *) data, width(), height(), pitch, format); return &lockedImage; } -- cgit v0.12