diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2013-11-13 11:08:06 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-15 13:49:20 +0100 |
commit | b6039e76c2ecfd6b95359d6ac1bc7ecbd6c1d9c5 (patch) | |
tree | 6db862015e15b9ad30363327c1b43b6a8657a878 | |
parent | 42a4854214a7440f482f0ba613725701688a7efe (diff) |
Add some QQuickWebView graphics stack tests.
This does basic sanity testing of the graphics stack for both the
hardware accelerated and software codepaths.
This also adds a required signal to report the CompositingSurface later
on if the QWindow wasn't available yet when Chromium asked for it.
Change-Id: I402ec5ade9114c78bea7960c5f0de989f54110e3
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
-rw-r--r-- | lib/quick/render_widget_host_view_qt_delegate_quick.cpp | 9 | ||||
-rw-r--r-- | lib/quick/render_widget_host_view_qt_delegate_quick.h | 4 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt.cpp | 9 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt.h | 2 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate.h | 1 | ||||
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics.pro | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics_software.pro | 6 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebviewgraphics/tst_qquickwebviewgraphics.cpp | 200 | ||||
-rw-r--r-- | tests/auto/quick/quick.pro | 5 | ||||
-rw-r--r-- | tests/auto/quick/tests.pri | 18 |
11 files changed, 256 insertions, 3 deletions
diff --git a/lib/quick/render_widget_host_view_qt_delegate_quick.cpp b/lib/quick/render_widget_host_view_qt_delegate_quick.cpp index dbd1ea911..8d0f5f0cc 100644 --- a/lib/quick/render_widget_host_view_qt_delegate_quick.cpp +++ b/lib/quick/render_widget_host_view_qt_delegate_quick.cpp @@ -50,7 +50,7 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW WId RenderWidgetHostViewQtDelegateQuick::nativeWindowIdForCompositor() const { - return QQuickItem::window()->winId(); + return QQuickItem::window() ? QQuickItem::window()->winId() : 0; } void RenderWidgetHostViewQtDelegateQuick::update(const QRect&) @@ -58,6 +58,13 @@ void RenderWidgetHostViewQtDelegateQuick::update(const QRect&) QQuickItem::update(); } +void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const ItemChangeData &value) +{ + QQuickItem::itemChange(change, value); + if (change == QQuickItem::ItemSceneChange && value.window) + m_client->compositingSurfaceUpdated(); +} + QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { return m_client->updatePaintNode(oldNode, QQuickItem::window()); diff --git a/lib/quick/render_widget_host_view_qt_delegate_quick.h b/lib/quick/render_widget_host_view_qt_delegate_quick.h index 64e84cd44..e8e073c24 100644 --- a/lib/quick/render_widget_host_view_qt_delegate_quick.h +++ b/lib/quick/render_widget_host_view_qt_delegate_quick.h @@ -213,8 +213,10 @@ class RenderWidgetHostViewQtDelegateQuick : public RenderWidgetHostViewQtDelegat public: RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, QQuickItem *parent = 0); - virtual WId nativeWindowIdForCompositor() const Q_DECL_OVERRIDE; + virtual WId nativeWindowIdForCompositor() const; virtual void update(const QRect& rect = QRect()) Q_DECL_OVERRIDE; + + virtual void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; }; #endif // QT_VERSION diff --git a/lib/render_widget_host_view_qt.cpp b/lib/render_widget_host_view_qt.cpp index 82d8e14bb..84192bef0 100644 --- a/lib/render_widget_host_view_qt.cpp +++ b/lib/render_widget_host_view_qt.cpp @@ -146,6 +146,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget , m_anchorPositionWithinSelection(0) , m_cursorPositionWithinSelection(0) , m_initPending(false) + , m_readyForSurface(false) { m_host->SetView(this); } @@ -243,6 +244,7 @@ gfx::NativeView RenderWidgetHostViewQt::GetNativeView() const gfx::NativeViewId RenderWidgetHostViewQt::GetNativeViewId() const { + const_cast<RenderWidgetHostViewQt *>(this)->m_readyForSurface = true; return m_delegate->nativeWindowIdForCompositor(); } @@ -733,6 +735,13 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) co } } +void RenderWidgetHostViewQt::compositingSurfaceUpdated() +{ + // Don't report an update until we get asked at least once. + if (m_readyForSurface) + m_host->CompositingSurfaceUpdated(); +} + void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) { ScopedVector<ui::TouchEvent> events; if (!content::MakeUITouchEventsFromWebTouchEvents(touch, &events, content::LOCAL_COORDINATES)) diff --git a/lib/render_widget_host_view_qt.h b/lib/render_widget_host_view_qt.h index f9666f5bf..bf29938c6 100644 --- a/lib/render_widget_host_view_qt.h +++ b/lib/render_widget_host_view_qt.h @@ -172,6 +172,7 @@ public: virtual void notifyResize() Q_DECL_OVERRIDE; virtual bool forwardEvent(QEvent *) Q_DECL_OVERRIDE; virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const Q_DECL_OVERRIDE; + virtual void compositingSurfaceUpdated() Q_DECL_OVERRIDE; void handleMouseEvent(QMouseEvent*); void handleKeyEvent(QKeyEvent*); @@ -223,6 +224,7 @@ private: size_t m_cursorPositionWithinSelection; bool m_initPending; + bool m_readyForSurface; }; #endif // RENDER_WIDGET_HOST_VIEW_QT_H diff --git a/lib/render_widget_host_view_qt_delegate.h b/lib/render_widget_host_view_qt_delegate.h index 2f1401b6d..d08296a8e 100644 --- a/lib/render_widget_host_view_qt_delegate.h +++ b/lib/render_widget_host_view_qt_delegate.h @@ -68,6 +68,7 @@ public: virtual void notifyResize() = 0; virtual bool forwardEvent(QEvent *) = 0; virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const = 0; + virtual void compositingSurfaceUpdated() = 0; }; class QWEBENGINE_EXPORT RenderWidgetHostViewQtDelegate { diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 1ae65f98b..359bc3145 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs -qtHaveModule(widgets): SUBDIRS = widgets +SUBDIRS = quick +qtHaveModule(widgets): SUBDIRS += widgets diff --git a/tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics.pro b/tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics.pro new file mode 100644 index 000000000..ff6c49628 --- /dev/null +++ b/tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics.pro @@ -0,0 +1,2 @@ +include(../tests.pri) +exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics_software.pro b/tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics_software.pro new file mode 100644 index 000000000..07ef8be5b --- /dev/null +++ b/tests/auto/quick/qquickwebviewgraphics/qquickwebviewgraphics_software.pro @@ -0,0 +1,6 @@ +TARGET = qquickwebviewgraphics +include(../tests.pri) +TARGET = $${TARGET}_software +OBJECTS_DIR = $${OBJECTS_DIR}_software + +DEFINES += TST_QQUICKWEBVIEWGRAPHICS_SOFTWARE=1
\ No newline at end of file diff --git a/tests/auto/quick/qquickwebviewgraphics/tst_qquickwebviewgraphics.cpp b/tests/auto/quick/qquickwebviewgraphics/tst_qquickwebviewgraphics.cpp new file mode 100644 index 000000000..a88389c58 --- /dev/null +++ b/tests/auto/quick/qquickwebviewgraphics/tst_qquickwebviewgraphics.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QQmlContext> +#include <QQuickView> +#include <QQuickItem> +#include <QtQuick/private/qsgcontext_p.h> + +class TestView : public QQuickView { + Q_OBJECT +public: + virtual void exposeEvent(QExposeEvent *e) Q_DECL_OVERRIDE { + QQuickView::exposeEvent(e); + emit exposeChanged(); + } + +Q_SIGNALS: + void exposeChanged(); +}; + +class tst_QQuickWebViewGraphics : public QObject +{ + Q_OBJECT +public: + tst_QQuickWebViewGraphics(); + virtual ~tst_QQuickWebViewGraphics(); + +public Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + +private Q_SLOTS: + void simpleGraphics(); + void renderAfterNodeCleanup(); + void showHideShow(); + void simpleAcceleratedLayer(); + void reparentToOtherWindow(); + +private: + void setHtml(const QString &html); + QScopedPointer<TestView> m_view; +}; + +static const QString greenSquare("<div style=\"background-color: #00ff00; position:absolute; left:50px; top: 50px; width: 50px; height: 50px;\"></div>"); +static const QString acLayerGreenSquare("<div style=\"background-color: #00ff00; position:absolute; left:50px; top: 50px; width: 50px; height: 50px; transform: translateZ(0); -webkit-transform: translateZ(0);\"></div>"); + +static QImage get150x150GreenReferenceImage() +{ + static QImage reference; + if (reference.isNull()) { + reference = QImage(150, 150, QImage::Format_RGB32); + reference.fill(Qt::white); + QPainter painter(&reference); + painter.fillRect(50, 50, 50, 50, QColor("#00ff00")); + } + return reference; +} + +tst_QQuickWebViewGraphics::tst_QQuickWebViewGraphics() +{ +} + +tst_QQuickWebViewGraphics::~tst_QQuickWebViewGraphics() +{ +} + +// This will be called before the first test function is executed. +// It is only called once. +void tst_QQuickWebViewGraphics::initTestCase() +{ +#if defined(TST_QQUICKWEBVIEWGRAPHICS_SOFTWARE) + qApp->setProperty("QQuickWebEngineView_DisableHardwareAcceleration", QVariant(true)); +#else + // This is currently needed by all QtWebEngine application using the HW accelerated QQuickWebView. + // It enables sharing between the QOpenGLContext of all QQuickWindows of the application. + // We have to do so until we expose a public API for it, or chose enable it by default in Qt 5.3.0. + QOpenGLContext *shareContext = new QOpenGLContext; + shareContext->create(); + QSGContext::setSharedOpenGLContext(shareContext); +#endif +} + +void tst_QQuickWebViewGraphics::init() +{ + m_view.reset(new TestView); +} + +void tst_QQuickWebViewGraphics::cleanup() +{ +} + +void tst_QQuickWebViewGraphics::simpleGraphics() +{ + setHtml(greenSquare); + QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage()); +} + +void tst_QQuickWebViewGraphics::renderAfterNodeCleanup() +{ + setHtml(greenSquare); + + // Do it twice in a row, if the window isn't visible, the scene graph is going to be trashed by QQuickWindow::grabWindow after the first render. + QVERIFY(!m_view->isVisible()); + QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage()); + +#if !defined(TST_QQUICKWEBVIEWGRAPHICS_SOFTWARE) + QEXPECT_FAIL("", "FIXME: This isn't working properly yet, QQuickWindow::grab() destroys the DelegatedFrameNode after it's done." + " There might be a way to trigger a repaint in Chromium, or we might have to prevent the destruction of our node tree.", Continue); +#endif + + QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage()); +} + +void tst_QQuickWebViewGraphics::showHideShow() +{ + setHtml(greenSquare); + QSignalSpy exposeSpy(m_view.data(), SIGNAL(exposeChanged())); + m_view->show(); + QVERIFY(exposeSpy.wait(500)); + QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage()); + + m_view->hide(); + QVERIFY(exposeSpy.wait(500)); + m_view->show(); + QVERIFY(exposeSpy.wait(500)); + QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage()); +} + +void tst_QQuickWebViewGraphics::simpleAcceleratedLayer() +{ + setHtml(acLayerGreenSquare); + QCOMPARE(m_view->grabWindow(), get150x150GreenReferenceImage()); +} + +void tst_QQuickWebViewGraphics::reparentToOtherWindow() +{ + setHtml(greenSquare); + QQuickWindow window; + window.resize(m_view->size()); + window.create(); + + m_view->rootObject()->setParentItem(window.contentItem()); + QCOMPARE(window.grabWindow(), get150x150GreenReferenceImage()); +} + +void tst_QQuickWebViewGraphics::setHtml(const QString &html) +{ + QString htmlData = QUrl::toPercentEncoding(html); + QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.0; WebEngineView { width: 150; height: 150; url: loadUrl }")); + m_view->rootContext()->setContextProperty("loadUrl", QUrl(QStringLiteral("data:text/html,%1").arg(htmlData))); + m_view->setSource(QUrl(QStringLiteral("data:text/plain,%1").arg(qmlData))); + m_view->create(); + + // FIXME: Replace with a proper initialLayout signal. + QTest::qWait(200); + QCOMPARE(m_view->rootObject()->property("loading"), QVariant(false)); +} + +QTEST_MAIN(tst_QQuickWebViewGraphics) +#include "tst_qquickwebviewgraphics.moc" diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro new file mode 100644 index 000000000..96e12c32f --- /dev/null +++ b/tests/auto/quick/quick.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + qquickwebviewgraphics/qquickwebviewgraphics.pro \ + qquickwebviewgraphics/qquickwebviewgraphics_software.pro \ diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri new file mode 100644 index 000000000..618ffe0cd --- /dev/null +++ b/tests/auto/quick/tests.pri @@ -0,0 +1,18 @@ +TEMPLATE = app + +CONFIG += testcase +VPATH += $$_PRO_FILE_PWD_ +TARGET = tst_$$TARGET + +SOURCES += $${TARGET}.cpp +INCLUDEPATH += \ + $$PWD \ + $$PWD/../Api + +QT += testlib network quick +QT_PRIVATE += quick-private gui-private core-private + +include($$QTWEBENGINE_ROOT/common.pri) + +# This define is used by some tests to look up resources in the source tree +DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD/\\\" |