From 0265a23bb02b68534bb3c86514cc93bc45a7444f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 6 Jun 2017 23:46:06 +0100 Subject: [PATCH] Fix crash when calling QWidget::grab() on a QOpenGLWidget By avoiding unneeded nested QPainters. Crash was: ASSERT: "s" in file /data/sources/qt/qt5/qtbase/src/gui/painting/qpaintengine_raster.cpp, line 2239 s was nullptr because the inner QPainter had called updateState(0), which is then dereferenced by the outer QPainter. Task-number: QTBUG-61036 Change-Id: I7aad648f805f1abac4d38dfbefa2292da8b52af4 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidget.cpp | 6 ++++-- .../widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a2f3fa4a5f..6112d33974 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5622,13 +5622,15 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP // punch a hole in the backingstore, so the texture will be visible. if (!q->testAttribute(Qt::WA_AlwaysStackOnTop)) { beginBackingStorePainting(); - QPainter p(q); if (backingStore) { + QPainter p(q); p.setCompositionMode(QPainter::CompositionMode_Source); p.fillRect(q->rect(), Qt::transparent); } else { + QImage img = grabFramebuffer(); + QPainter p(q); // We are not drawing to a backingstore: fall back to QImage - p.drawImage(q->rect(), grabFramebuffer()); + p.drawImage(q->rect(), img); skipPaintEvent = true; } endBackingStorePainting(); diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index 5980cb95d0..f51c566f20 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -233,6 +233,8 @@ void tst_QOpenGLWidget::painter() glw->m_clear = true; image = glw->grabFramebuffer(); QVERIFY(image.pixel(20, 10) == qRgb(0, 255, 0)); + + QPixmap pix = glw->grab(); // QTBUG-61036 } void tst_QOpenGLWidget::reparentToAlreadyCreated()