From: Gunnar Sletta Date: Thu, 18 Apr 2013 15:02:24 +0000 (+0200) Subject: Implement QQuickWindow::grabWindow() for isVisible=false X-Git-Tag: upstream/5.2.1~798^2~116 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0bcf549647082e3a80768e2ea5336abf420d042d;p=platform%2Fupstream%2Fqtdeclarative.git Implement QQuickWindow::grabWindow() for isVisible=false Webkit uses this for testing. Change-Id: I4539e169a02592fb6c0062903917d4dd23a4303c Reviewed-by: Jocelyn Turcotte --- diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 6b82f3f..a4dff96 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -72,6 +72,8 @@ QT_BEGIN_NAMESPACE +extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); + void QQuickWindowPrivate::updateFocusItemTransform() { Q_Q(QQuickWindow); @@ -2653,7 +2655,10 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const /*! Grabs the contents of the window and returns it as an image. - This function might not work if the window is not visible. + It is possible to call the grabWindow() function when the window is not + visible. This requires that the window is \l{QWindow::create} {created} + and has a valid size and that no other QQuickWindow instances are rendering + in the same process. \warning Calling this function will cause performance problems. @@ -2662,6 +2667,36 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const QImage QQuickWindow::grabWindow() { Q_D(QQuickWindow); + if (!isVisible()) { + + if (d->context->isReady()) { + qWarning("QQuickWindow::grabWindow: scene graph already in use"); + return QImage(); + } + + if (!handle() || !size().isValid()) { + qWarning("QQuickWindow::grabWindow: window must be created and have a valid size"); + return QImage(); + } + + QOpenGLContext context; + context.setFormat(requestedFormat()); + context.create(); + context.makeCurrent(this); + d->context->initialize(&context); + + d->polishItems(); + d->syncSceneGraph(); + d->renderSceneGraph(size()); + + QImage image = qt_gl_read_framebuffer(size(), false, false); + d->cleanupNodesOnShutdown(); + d->context->invalidate(); + context.doneCurrent(); + + return image; + } + return d->windowManager->grab(this); } diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 2d3c8f7..dbf0086 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -304,6 +304,7 @@ private slots: void qmlCreation(); void clearColor(); + void grab_data(); void grab(); void multipleWindows(); @@ -929,15 +930,28 @@ void tst_qquickwindow::clearColor() QCOMPARE(window->color(), QColor(Qt::blue)); } +void tst_qquickwindow::grab_data() +{ + QTest::addColumn("visible"); + QTest::newRow("visible") << true; + QTest::newRow("invisible") << false; +} + void tst_qquickwindow::grab() { + QFETCH(bool, visible); + QQuickWindow window; window.setColor(Qt::red); window.resize(250, 250); - window.show(); - QVERIFY(QTest::qWaitForWindowExposed(&window)); + if (visible) { + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + } else { + window.create(); + } QImage content = window.grabWindow(); QCOMPARE(content.width(), window.width());