diff options
author | Liang Qi <liang.qi@qt.io> | 2016-06-06 08:34:03 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-06-06 09:04:55 +0200 |
commit | 57057f76add416d0faf2e09a90c126baafb6198e (patch) | |
tree | 07d54f8e5daeb3ed1161723542e94c324d745166 /tests/auto/widgets/widgets/qopenglwidget | |
parent | dc0ae02ebc8e221f952829230c0301a718a6f10b (diff) | |
parent | fd70978693bd92761e9989bc1c76bf83c1e8c987 (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
.qmake.conf
config.tests/unix/nis/nis.cpp
mkspecs/unsupported/freebsd-g++/qplatformdefs.h
src/corelib/tools/qdatetime.cpp
src/corelib/tools/qsimd.cpp
src/corelib/tools/qsimd_p.h
src/network/access/access.pri
src/network/access/qnetworkreplynsurlconnectionimpl.mm
src/network/access/qnetworkreplynsurlconnectionimpl_p.h
src/plugins/platforms/cocoa/qnsview.mm
src/plugins/printsupport/windows/qwindowsprintdevice.cpp
tests/auto/corelib/kernel/qobject/tst_qobject.cpp
tests/auto/network/access/qnetworkreply/BLACKLIST
tests/auto/widgets/widgets/qopenglwidget/BLACKLIST
Change-Id: I4b32055bbf922392ef0264fd403405416fffee57
Diffstat (limited to 'tests/auto/widgets/widgets/qopenglwidget')
-rw-r--r-- | tests/auto/widgets/widgets/qopenglwidget/BLACKLIST | 3 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp | 133 |
2 files changed, 136 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST index 86c7141268..fa326a6ea5 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST +++ b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST @@ -12,3 +12,6 @@ windows msvc-2010 32bit developer-build #QTBUG-31611 [reparentToNotYetCreated] windows msvc-2010 32bit developer-build + +[stackWidgetOpaqueChildIsVisible] +windows diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index c76c4d927b..e3e26d612f 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -29,11 +29,14 @@ #include <QtWidgets/QOpenGLWidget> #include <QtGui/QOpenGLFunctions> #include <QtGui/QPainter> +#include <QtGui/QScreen> +#include <QtWidgets/QDesktopWidget> #include <QtWidgets/QGraphicsView> #include <QtWidgets/QGraphicsScene> #include <QtWidgets/QGraphicsRectItem> #include <QtWidgets/QVBoxLayout> #include <QtWidgets/QPushButton> +#include <QtWidgets/QStackedWidget> #include <QtTest/QtTest> #include <QSignalSpy> @@ -54,6 +57,7 @@ private slots: void fboRedirect(); void showHide(); void nativeWindow(); + void stackWidgetOpaqueChildIsVisible(); }; void tst_QOpenGLWidget::create() @@ -420,6 +424,135 @@ void tst_QOpenGLWidget::nativeWindow() QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0)); } +static inline QString msgRgbMismatch(unsigned actual, unsigned expected) +{ + return QString::asprintf("Color mismatch, %#010x != %#010x", actual, expected); +} + +static QPixmap grabWidgetWithoutRepaint(const QWidget *widget, QRect clipArea) +{ + const QWidget *targetWidget = widget; +#ifdef Q_OS_WIN + // OpenGL content is not properly grabbed on Windows when passing a top level widget window, + // because GDI functions can't grab OpenGL layer content. + // Instead the whole screen should be captured, with an adjusted clip area, which contains + // the final composited content. + QDesktopWidget *desktopWidget = QApplication::desktop(); + const QWidget *mainScreenWidget = desktopWidget->screen(); + targetWidget = mainScreenWidget; + clipArea = QRect(widget->mapToGlobal(clipArea.topLeft()), + widget->mapToGlobal(clipArea.bottomRight())); +#endif + + const QWindow *window = targetWidget->window()->windowHandle(); + Q_ASSERT(window); + WId windowId = window->winId(); + + QScreen *screen = window->screen(); + Q_ASSERT(screen); + + const QSize size = clipArea.size(); + const QPixmap result = screen->grabWindow(windowId, + clipArea.x(), + clipArea.y(), + size.width(), + size.height()); + return result; +} + +#define VERIFY_COLOR(child, region, color) verifyColor(child, region, color, __LINE__) + +bool verifyColor(const QWidget *widget, const QRect &clipArea, const QColor &color, int callerLine) +{ + for (int t = 0; t < 6; t++) { + const QPixmap pixmap = grabWidgetWithoutRepaint(widget, clipArea); + if (!QTest::qCompare(pixmap.size(), + clipArea.size(), + "pixmap.size()", + "rect.size()", + __FILE__, + callerLine)) + return false; + + + const QImage image = pixmap.toImage(); + QPixmap expectedPixmap(pixmap); /* ensure equal formats */ + expectedPixmap.detach(); + expectedPixmap.fill(color); + + uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0; + uint firstPixel = image.pixel(0,0) | alphaCorrection; + + // Retry a couple of times. Some window managers have transparency animation, or are + // just slow to render. + if (t < 5) { + if (firstPixel == QColor(color).rgb() + && image == expectedPixmap.toImage()) + return true; + else + QTest::qWait(200); + } else { + if (!QTest::qVerify(firstPixel == QColor(color).rgb(), + "firstPixel == QColor(color).rgb()", + qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())), + __FILE__, callerLine)) { + return false; + } + if (!QTest::qVerify(image == expectedPixmap.toImage(), + "image == expectedPixmap.toImage()", + "grabbed pixmap differs from expected pixmap", + __FILE__, callerLine)) { + return false; + } + } + } + + return false; +} + +void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible() +{ +#ifdef Q_OS_OSX + QSKIP("QScreen::grabWindow() doesn't work properly on OSX HighDPI screen: QTBUG-46803"); + return; +#endif + + QStackedWidget stack; + + QWidget* emptyWidget = new QWidget(&stack); + stack.addWidget(emptyWidget); + + // Create an opaque red QOpenGLWidget. + const int dimensionSize = 400; + ClearWidget* clearWidget = new ClearWidget(&stack, dimensionSize, dimensionSize); + clearWidget->setAttribute(Qt::WA_OpaquePaintEvent); + stack.addWidget(clearWidget); + + // Show initial QWidget. + stack.setCurrentIndex(0); + stack.resize(dimensionSize, dimensionSize); + stack.show(); + QTest::qWaitForWindowExposed(&stack); + QTest::qWaitForWindowActive(&stack); + + // Switch to the QOpenGLWidget. + stack.setCurrentIndex(1); + QTRY_COMPARE(clearWidget->m_paintCalled, true); + + // Resize the tested region to be half size in the middle, because some OSes make the widget + // have rounded corners (e.g. OSX), and the grabbed window pixmap will not coincide perfectly + // with what was actually painted. + QRect clipArea = stack.rect(); + clipArea.setSize(clipArea.size() / 2); + const int translationOffsetToMiddle = dimensionSize / 4; + clipArea.translate(translationOffsetToMiddle, translationOffsetToMiddle); + + // Verify that the QOpenGLWidget was actually painted AND displayed. + const QColor red(255, 0, 0, 255); + VERIFY_COLOR(&stack, clipArea, red); + #undef VERIFY_COLOR +} + QTEST_MAIN(tst_QOpenGLWidget) #include "tst_qopenglwidget.moc" |