diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2018-08-22 13:02:04 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2018-08-24 08:30:28 +0000 |
commit | f71048a5314c93732a8a77460b465709b632ff5e (patch) | |
tree | 6b311d5e57d668c2579b8da782f25fbf8122edf8 /tests | |
parent | 981b16d9ba5a4bb7c6fdc0009fda9a4a74a92f9a (diff) |
Fix crash when combining QOpenGLWidget, QStaticText and Qt Quick
Under certain circumstances, if you had a widget with a QOpenGLPaintEngine,
and drew QStaticText into this, and then later had Qt Quick access the same
cache and try to resize it, we would get a crash because the resize function
would have a pointer to the paint engine and try to access its shader manager
(which would now be null, since this is outside the begin()/end() phase of the
paint engine.
The solution is to reset the paint engine pointer to null on the cache once it
has been populated and it is no longer needed.
[ChangeLog][QtGui][Text] Fixed a possible crash when combining QStaticText,
QOpenGLWidget and Qt Quick in the same application.
Task-number: QTBUG-70096
Change-Id: I7383ad7456d1a72499cfcd2da09a5a808d4b3eff
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index db125f6644..21c9f41646 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -30,6 +30,7 @@ #include <QtGui/QOpenGLFunctions> #include <QtGui/QPainter> #include <QtGui/QScreen> +#include <QtGui/QStaticText> #include <QtWidgets/QDesktopWidget> #include <QtWidgets/QGraphicsView> #include <QtWidgets/QGraphicsScene> @@ -40,6 +41,8 @@ #include <QtTest/QtTest> #include <QSignalSpy> #include <private/qguiapplication_p.h> +#include <private/qstatictext_p.h> +#include <private/qopengltextureglyphcache_p.h> #include <qpa/qplatformintegration.h> class tst_QOpenGLWidget : public QObject @@ -64,6 +67,10 @@ private slots: void stackWidgetOpaqueChildIsVisible(); void offscreen(); void offscreenThenOnscreen(); + +#ifdef QT_BUILD_INTERNAL + void staticTextDanglingPointer(); +#endif }; void tst_QOpenGLWidget::initTestCase() @@ -675,6 +682,53 @@ void tst_QOpenGLWidget::offscreenThenOnscreen() QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255)); } +class StaticTextPainterWidget : public QOpenGLWidget +{ +public: + StaticTextPainterWidget(QWidget *parent = nullptr) + : QOpenGLWidget(parent) + { + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + text.setText(QStringLiteral("test")); + p.drawStaticText(0, 0, text); + + ctx = QOpenGLContext::currentContext(); + } + + QStaticText text; + QOpenGLContext *ctx; +}; + +#ifdef QT_BUILD_INTERNAL +void tst_QOpenGLWidget::staticTextDanglingPointer() +{ + QWidget w; + StaticTextPainterWidget *glw = new StaticTextPainterWidget(&w); + w.resize(640, 480); + glw->resize(320, 200); + w.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&w)); + QStaticTextPrivate *d = QStaticTextPrivate::get(&glw->text); + + QCOMPARE(d->itemCount, 1); + QFontEngine *fe = d->items->fontEngine(); + + for (int i = QFontEngine::Format_None; i <= QFontEngine::Format_ARGB; ++i) { + QOpenGLTextureGlyphCache *cache = + (QOpenGLTextureGlyphCache *) fe->glyphCache(glw->ctx, + QFontEngine::GlyphFormat(i), + QTransform()); + if (cache != nullptr) + QCOMPARE(cache->paintEnginePrivate(), nullptr); + } +} +#endif + QTEST_MAIN(tst_QOpenGLWidget) #include "tst_qopenglwidget.moc" |