diff options
Diffstat (limited to 'tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp')
-rw-r--r-- | tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp | 107 |
1 files changed, 101 insertions, 6 deletions
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index 4d3699009f..51f898c953 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -1,9 +1,10 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtOpenGLWidgets/QOpenGLWidget> #include <QtGui/QOpenGLFunctions> #include <QtGui/QPainter> +#include <QtGui/QBackingStore> #include <QtGui/QScreen> #include <QtGui/QStaticText> #include <QtWidgets/QGraphicsView> @@ -21,7 +22,9 @@ #include <private/qopengltextureglyphcache_p.h> #include <qpa/qplatformintegration.h> #include <private/qguiapplication_p.h> +#include <qpa/qplatformbackingstore.h> #include <qpa/qplatformintegration.h> +#include <rhi/qrhi.h> class tst_QOpenGLWidget : public QObject { @@ -33,6 +36,9 @@ private slots: void clearAndGrab(); void clearAndResizeAndGrab(); void createNonTopLevel(); +#if QT_CONFIG(egl) + void deviceLoss(); +#endif void painter(); void reparentToAlreadyCreated(); void reparentToNotYetCreated(); @@ -189,6 +195,45 @@ void tst_QOpenGLWidget::createNonTopLevel() QVERIFY(QOpenGLContext::currentContext() == glw->context() && glw->context()); } +#if QT_CONFIG(egl) +void tst_QOpenGLWidget::deviceLoss() +{ + QScopedPointer<QOpenGLWidget> w(new ClearWidget(0, 640, 480)); + + w->resize(640, 480); + w->show(); + + auto rhi = w->backingStore()->handle()->rhi(w->windowHandle()); + QNativeInterface::QEGLContext *rhiContext = nullptr; + if (rhi->backend() == QRhi::OpenGLES2) { + auto rhiHandles = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles()); + rhiContext = rhiHandles->context->nativeInterface<QNativeInterface::QEGLContext>(); + } + if (!rhiContext) + QSKIP("deviceLoss needs EGL"); + + QVERIFY(QTest::qWaitForWindowExposed(w.data())); + + QImage image = w->grabFramebuffer(); + QVERIFY(!image.isNull()); + QCOMPARE(image.width(), w->width()); + QCOMPARE(image.height(), w->height()); + QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); + + rhiContext->invalidateContext(); + + w->resize(600, 600); + QSignalSpy frameSwappedSpy(w.get(), &QOpenGLWidget::resized); + QTRY_VERIFY(frameSwappedSpy.size() > 0); + + image = w->grabFramebuffer(); + QVERIFY(!image.isNull()); + QCOMPARE(image.width(), w->width()); + QCOMPARE(image.height(), w->height()); + QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); +} +#endif + class PainterWidget : public QOpenGLWidget, protected QOpenGLFunctions { public: @@ -524,6 +569,21 @@ void tst_QOpenGLWidget::showHide() QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255)); } +QtMessageHandler oldHandler = nullptr; + +void nativeWindowMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + if (oldHandler) + oldHandler(type, context, msg); + + if (type == QtWarningMsg + && (msg.contains("QOpenGLContext::makeCurrent() called with non-opengl surface") + || msg.contains("Failed to make context current"))) + { + QFAIL("Unexpected warning got printed"); + } +} + void tst_QOpenGLWidget::nativeWindow() { #ifdef Q_OS_ANDROID @@ -535,6 +595,10 @@ void tst_QOpenGLWidget::nativeWindow() // presented correctly as we can only do verification with // grabFramebuffer() here which only exercises a part of the pipeline. + // Install a message handler that looks for some typical warnings from + // QRhi/QOpenGLConext that occur when the RHI-related logic in widgets goes wrong. + oldHandler = qInstallMessageHandler(nativeWindowMessageHandler); + { QScopedPointer<ClearWidget> w(new ClearWidget(nullptr, 800, 600)); w->resize(800, 600); @@ -550,7 +614,33 @@ void tst_QOpenGLWidget::nativeWindow() QVERIFY(w->internalWinId()); } - // Now as a native child + // QTBUG-113557: a plain _raster_ QWidget that is a _native_ child in a toplevel + // combined with a RHI-based (non-native) widget (QOpenGLWidget in this case) + // in the same toplevel. + { + QWidget topLevel; + topLevel.resize(800, 600); + + ClearWidget *child = new ClearWidget(&topLevel, 800, 600); + child->setClearColor(1, 0, 0); + child->resize(400, 400); + child->move(23, 34); + + QWidget *raster = new QWidget(&topLevel); + raster->setGeometry(23, 240, 120, 120); + raster->setStyleSheet("QWidget { background-color: yellow; }"); + + raster->winId(); + + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + + // Do not bother checking the output, i.e. if the yellow raster native child + // shows up as it should, but rather rely on the message handler catching the + // qWarnings if they occur. + } + + // Now with the QOpenGLWidget being a native child { QWidget topLevel; topLevel.resize(800, 600); @@ -616,7 +706,7 @@ void tst_QOpenGLWidget::nativeWindow() ClearWidget *child = new ClearWidget(nullptr, 800, 600); // set the parent separately, this is important, see next test case child->setParent(container); - child->setClearColor(0, 1, 0); + child->setClearColor(0, 0, 1); child->resize(400, 400); child->move(23, 34); @@ -630,7 +720,7 @@ void tst_QOpenGLWidget::nativeWindow() QImage image = child->grabFramebuffer(); QCOMPARE(image.width(), child->width()); QCOMPARE(image.height(), child->height()); - QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0)); + QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255)); } // Again as a child of a native child, but this time specifying the parent @@ -642,7 +732,7 @@ void tst_QOpenGLWidget::nativeWindow() container->winId(); // parent it right away ClearWidget *child = new ClearWidget(container, 800, 600); - child->setClearColor(0, 1, 0); + child->setClearColor(0, 0, 1); child->resize(400, 400); child->move(23, 34); topLevel.show(); @@ -653,7 +743,12 @@ void tst_QOpenGLWidget::nativeWindow() QImage image = child->grabFramebuffer(); QCOMPARE(image.width(), child->width()); QCOMPARE(image.height(), child->height()); - QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0)); + QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255)); + } + + if (oldHandler) { + qInstallMessageHandler(oldHandler); + oldHandler = nullptr; } } |