Created
July 6, 2012 16:21
-
-
Save balazs/3061148 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Source/WebKit2/Shared/API/c/qt/WKImageQt.cpp b/Source/WebKit2/Shared/API/c/qt/WKImageQt.cpp | |
index d0975f6..bb7f89a 100644 | |
--- a/Source/WebKit2/Shared/API/c/qt/WKImageQt.cpp | |
+++ b/Source/WebKit2/Shared/API/c/qt/WKImageQt.cpp | |
@@ -25,10 +25,27 @@ | |
#include "ShareableBitmap.h" | |
#include "WKSharedAPICast.h" | |
#include "WebImage.h" | |
+#include <QPainter> | |
+#include <WebCore/IntSize.h> | |
+#include <WebCore/GraphicsContext.h> | |
+using namespace WebCore; | |
using namespace WebKit; | |
QImage WKImageCreateQImage(WKImageRef imageRef) | |
{ | |
return toImpl(imageRef)->bitmap()->createQImage().copy(); | |
} | |
+ | |
+WKImageRef WKImageCreateFromQImage(QImage image) | |
+{ | |
+ ASSERT(image.bytesPerLine() == image.width() * 4); | |
+ | |
+ RefPtr<WebImage> webImage = WebImage::create(image.size(), static_cast<ImageOptions>(0)); | |
+ if (!webImage->bitmap()) | |
+ return 0; | |
+ OwnPtr<GraphicsContext> graphicsContext = webImage->bitmap()->createGraphicsContext(); | |
+ QPainter* painter = graphicsContext->platformContext(); | |
+ painter->drawImage(QPoint(0, 0), image); | |
+ return toAPI(webImage.release().leakRef()); | |
+} | |
diff --git a/Source/WebKit2/Shared/API/c/qt/WKImageQt.h b/Source/WebKit2/Shared/API/c/qt/WKImageQt.h | |
index 1e5073a..d14c391 100644 | |
--- a/Source/WebKit2/Shared/API/c/qt/WKImageQt.h | |
+++ b/Source/WebKit2/Shared/API/c/qt/WKImageQt.h | |
@@ -27,5 +27,6 @@ | |
#include <WebKit2/WKImage.h> | |
WK_EXPORT QImage WKImageCreateQImage(WKImageRef image); | |
+WK_EXPORT WKImageRef WKImageCreateFromQImage(QImage image); | |
#endif | |
diff --git a/Tools/WebKitTestRunner/PlatformWebView.h b/Tools/WebKitTestRunner/PlatformWebView.h | |
index a8cf0d6..74ce123 100644 | |
--- a/Tools/WebKitTestRunner/PlatformWebView.h | |
+++ b/Tools/WebKitTestRunner/PlatformWebView.h | |
@@ -29,10 +29,12 @@ | |
#include <WebKit2/WKRetainPtr.h> | |
#if defined(BUILDING_QT__) | |
-class QQuickWebView; | |
-typedef QQuickWebView* PlatformWKView; | |
-class QQuickView; | |
-typedef QQuickView* PlatformWindow; | |
+class QRawWebView; | |
+typedef QRawWebView* PlatformWKView; | |
+namespace WTR { | |
+class QtView; | |
+} | |
+typedef WTR::QtView* PlatformWindow; | |
class QEventLoop; | |
#elif defined(__APPLE__) && __APPLE__ | |
#if __OBJC__ | |
diff --git a/Tools/WebKitTestRunner/Target.pri b/Tools/WebKitTestRunner/Target.pri | |
index b3b5c2c..1b7a7f9 100644 | |
--- a/Tools/WebKitTestRunner/Target.pri | |
+++ b/Tools/WebKitTestRunner/Target.pri | |
@@ -27,6 +27,9 @@ DESTDIR = $${ROOT_BUILD_DIR}/bin | |
QT = core gui widgets network testlib quick quick-private webkit | |
+INCLUDEPATH += \ | |
+ $${ROOT_WEBKIT_DIR}/Source/WebKit2/UIProcess/API/qt/raw | |
+ | |
WEBKIT += wtf javascriptcore webkit2 | |
DEFINES += USE_SYSTEM_MALLOC=1 | |
diff --git a/Tools/WebKitTestRunner/TestInvocation.cpp b/Tools/WebKitTestRunner/TestInvocation.cpp | |
index d5c0af6..9bbdc1d 100644 | |
--- a/Tools/WebKitTestRunner/TestInvocation.cpp | |
+++ b/Tools/WebKitTestRunner/TestInvocation.cpp | |
@@ -263,7 +263,7 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName | |
fputs("#EOF\n", stdout); | |
fflush(stdout); | |
fflush(stderr); | |
- | |
+ | |
m_gotFinalMessage = true; | |
TestController::shared().notifyDone(); | |
return; | |
diff --git a/Tools/WebKitTestRunner/qt/PlatformWebViewQt.cpp b/Tools/WebKitTestRunner/qt/PlatformWebViewQt.cpp | |
index 0211df5..81dcbab 100644 | |
--- a/Tools/WebKitTestRunner/qt/PlatformWebViewQt.cpp | |
+++ b/Tools/WebKitTestRunner/qt/PlatformWebViewQt.cpp | |
@@ -31,52 +31,163 @@ | |
#include "qquickwebview_p.h" | |
#include <QCoreApplication> | |
+#include <QGuiApplication> | |
#include <QEventLoop> | |
-#include <QQmlProperty> | |
-#include <QtQuick/QQuickView> | |
+#include <QMatrix4x4> | |
+#include <QOpenGLContext> | |
+#include <QTimer> | |
+#include <QWindow> | |
+#include <WebKit2/WKImageQt.h> | |
+#include <qrawwebview_p.h> | |
#include <qwindowsysteminterface_qpa.h> | |
+#define WRITE_SNAPSHOT 1 | |
+ | |
+#if WRITE_SNAPSHOT | |
+#include <QImageWriter> | |
+#include <QFile> | |
+#endif | |
+ | |
namespace WTR { | |
-class WrapperWindow : public QQuickView { | |
+class QtView : public QWindow, private QRawWebViewClient { | |
Q_OBJECT | |
public: | |
- WrapperWindow(QQuickWebView* view) | |
- : QQuickView(QUrl("data:text/plain,import QtQuick 2.0\nItem { objectName: 'root' }")) | |
- , m_view(view) | |
- { | |
- connect(this, SIGNAL(statusChanged(QQuickView::Status)), SLOT(handleStatusChanged(QQuickView::Status))); | |
- } | |
+ QtView(WKContextRef contextRef, WKPageGroupRef pageGroupRef); | |
+ ~QtView(); | |
+ | |
+ QImage createSnapshot(); | |
+ | |
+ QRawWebView* view() const { return m_view; } | |
+ | |
+ // QRawWebViewClient | |
+ virtual void viewNeedsDisplay(const QRect&); | |
+ virtual void viewRenderedFrame(); | |
+ virtual void viewRequestedCursorOverride(const QCursor&); | |
+ virtual void viewRequestedScroll(const QPoint&) { } | |
+ virtual void viewProcessCrashed() { } | |
+ virtual void viewProcessRelaunched() { } | |
+ virtual void viewContentSizeChanged(const QSize&) { } | |
+ virtual void doneWithKeyEvent(const QKeyEvent*, bool) { } | |
+ virtual void doneWithTouchEvent(const QTouchEvent*, bool) { } | |
+signals: | |
+ void didPaint(); | |
+private: | |
+ QRawWebView* m_view; | |
+ QOpenGLContext* m_glContext; | |
+ bool m_isWaitingForSnapshot; | |
+}; | |
+ | |
+QtView::QtView(WKContextRef context, WKPageGroupRef pageGroup) | |
+ : m_isWaitingForSnapshot(false) | |
+{ | |
+ const QSize initialSize(800, 600); | |
-private slots: | |
- void handleStatusChanged(QQuickView::Status status) | |
- { | |
- if (status != QQuickView::Ready) | |
- return; | |
+ setSurfaceType(OpenGLSurface); | |
+ setGeometry(0, 0, initialSize.width(), initialSize.height()); | |
+ setWindowFlags(Qt::Window | Qt::WindowTitleHint); | |
+ create(); | |
- setGeometry(0, 0, 800, 600); | |
+ m_glContext = new QOpenGLContext(); | |
+ m_glContext->create(); | |
+ m_glContext->makeCurrent(this); | |
+ glViewport(0, 0, size().width(), size().height()); | |
+ glClearColor(0, 0, 0, 0); | |
+ glClear(GL_COLOR_BUFFER_BIT); | |
- setResizeMode(QQuickView::SizeRootObjectToView); | |
- m_view->setParentItem(rootObject()); | |
- QQmlProperty::write(m_view, "anchors.fill", qVariantFromValue(rootObject())); | |
+ m_view = new QRawWebView(context, pageGroup, this); | |
+ m_view->setSize(initialSize); | |
+ m_view->create(); | |
+} | |
- QWindowSystemInterface::handleWindowActivated(this); | |
- m_view->page()->setFocus(true); | |
+QtView::~QtView() | |
+{ | |
+ delete m_view; | |
+ delete m_glContext; | |
+} | |
+ | |
+QImage QtView::createSnapshot() | |
+{ | |
+ m_isWaitingForSnapshot = true; | |
+ m_view->update(); | |
+ | |
+ QEventLoop loop; | |
+ QTimer watchDogTimer; | |
+ QObject::connect(this, SIGNAL(didPaint()), &loop, SLOT(quit())); | |
+ QObject::connect(&watchDogTimer, SIGNAL(timeout()), &loop, SLOT(quit())); | |
+ watchDogTimer.singleShot(2000, &loop, SLOT(quit())); | |
+ loop.exec(); | |
+ | |
+ if (m_isWaitingForSnapshot) { | |
+ m_isWaitingForSnapshot = false; | |
+ fprintf(stderr, "did not paint\n"); | |
+ return QImage(); | |
} | |
-private: | |
- QQuickWebView* m_view; | |
-}; | |
+ Q_ASSERT(QOpenGLContext::currentContext() == m_glContext); | |
+ QImage image(size(), QImage::Format_ARGB32_Premultiplied); | |
+ uchar* bits = const_cast<uchar*>(image.constBits()); | |
+ glReadPixels(0, 0, size().width(), size().height(), GL_RGBA, GL_UNSIGNED_BYTE, bits); | |
+ | |
+ // FIXME: should use a transformation matrix fot this. | |
+ QImage imageFlipped(size(), QImage::Format_ARGB32_Premultiplied); | |
+ uint height = image.size().height(); | |
+ for (uint y = 0; y < height; ++y) { | |
+ const uchar* src = image.constScanLine(y); | |
+ const uchar* constDst = imageFlipped.constScanLine(height - 1 - y); | |
+ uchar* dst = const_cast<uchar*>(constDst); | |
+ memcpy(dst, src, image.bytesPerLine()); | |
+ } | |
+ | |
+#if WRITE_SNAPSHOT | |
+ static int c = 0; | |
+ QString fname("snapshot.%1.bmp"); | |
+ QFile f(fname.arg(c++)); | |
+ f.open(QFile::WriteOnly); | |
+ QImageWriter w(&f, "bmp"); | |
+ w.write(imageFlipped); | |
+ f.close(); | |
+#endif | |
+ | |
+ return imageFlipped; | |
+} | |
+ | |
+static inline QMatrix4x4 matrix() | |
+{ | |
+ QMatrix4x4 mx; | |
+ //mx.rotate(180, 0, 1, 0); | |
+ return mx; | |
+} | |
+ | |
+void QtView::viewNeedsDisplay(const QRect&) | |
+{ | |
+ m_glContext->makeCurrent(this); | |
+ m_view->paint(matrix(), 1, 0); | |
+} | |
+ | |
+void QtView::viewRenderedFrame() | |
+{ | |
+ if (!m_isWaitingForSnapshot) | |
+ return; | |
-PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef) | |
- : m_view(new QQuickWebView(contextRef, pageGroupRef)) | |
- , m_window(new WrapperWindow(m_view)) | |
- , m_windowIsKey(true) | |
- , m_modalEventLoop(0) | |
+ m_glContext->makeCurrent(this); | |
+ m_view->paint(matrix(), 1, 0); | |
+ m_isWaitingForSnapshot = false; | |
+ emit didPaint(); | |
+} | |
+ | |
+void QtView::viewRequestedCursorOverride(const QCursor& cursor) | |
{ | |
- QQuickWebViewExperimental experimental(m_view); | |
- experimental.setRenderToOffscreenBuffer(true); | |
- m_view->setAllowAnyHTTPSCertificateForLocalHost(true); | |
+ QGuiApplication::setOverrideCursor(cursor); | |
+} | |
+ | |
+PlatformWebView::PlatformWebView(WKContextRef context, WKPageGroupRef pageGroup) | |
+ : m_modalEventLoop(0) | |
+{ | |
+ m_window = new QtView(context, pageGroup); | |
+ m_view = m_window->view(); | |
+ | |
+ focus(); | |
} | |
PlatformWebView::~PlatformWebView() | |
@@ -86,27 +197,21 @@ PlatformWebView::~PlatformWebView() | |
m_modalEventLoop->exit(); | |
} | |
-void PlatformWebView::resizeTo(unsigned width, unsigned height) | |
+WKPageRef PlatformWebView::page() | |
{ | |
- // If we do not have a platform window we will never get the necessary | |
- // resize event, so simulate it in that case to make sure the quickview is | |
- // resized to what the layout test expects. | |
- if (!m_window->handle()) { | |
- QRect newGeometry(m_window->x(), m_window->y(), width, height); | |
- QWindowSystemInterface::handleSynchronousGeometryChange(m_window, newGeometry); | |
- } | |
- | |
- m_window->resize(width, height); | |
+ return m_view->pageRef(); | |
} | |
-WKPageRef PlatformWebView::page() | |
+void PlatformWebView::resizeTo(unsigned width, unsigned height) | |
{ | |
- return m_view->pageRef(); | |
+ m_view->setSize(QSize(width, height)); | |
} | |
void PlatformWebView::focus() | |
{ | |
- m_view->setFocus(Qt::OtherFocusReason); | |
+ m_view->setFocused(true); | |
+ m_view->setVisible(true); | |
+ m_view->setActive(true); | |
} | |
WKRect PlatformWebView::windowFrame() | |
@@ -123,6 +228,7 @@ WKRect PlatformWebView::windowFrame() | |
void PlatformWebView::setWindowFrame(WKRect wkRect) | |
{ | |
m_window->setGeometry(wkRect.origin.x, wkRect.origin.y, wkRect.size.width, wkRect.size.height); | |
+ resizeTo(wkRect.size.width, wkRect.size.height); | |
} | |
bool PlatformWebView::sendEvent(QEvent* event) | |
@@ -149,9 +255,7 @@ void PlatformWebView::makeWebViewFirstResponder() | |
WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage() | |
{ | |
- // FIXME: implement to capture pixels in the UI process, | |
- // which may be necessary to capture things like 3D transforms. | |
- return 0; | |
+ return WKImageCreateFromQImage(m_window->createSnapshot()); | |
} | |
} // namespace WTR | |
diff --git a/Tools/WebKitTestRunner/qt/TestInvocationQt.cpp b/Tools/WebKitTestRunner/qt/TestInvocationQt.cpp | |
index 01630d9..425ab16 100644 | |
--- a/Tools/WebKitTestRunner/qt/TestInvocationQt.cpp | |
+++ b/Tools/WebKitTestRunner/qt/TestInvocationQt.cpp | |
@@ -25,6 +25,8 @@ | |
#include "config.h" | |
+#include "PlatformWebView.h" | |
+#include "TestController.h" | |
#include "TestInvocation.h" | |
#include <QBuffer> | |
@@ -67,7 +69,14 @@ void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef imageRef, WKArr | |
//FIXME: https://bugs.webkit.org/show_bug.cgi?id=68870 | |
UNUSED_PARAM(repaintRects); | |
- QImage image = WKImageCreateQImage(imageRef); | |
+ PlatformWebView* webView = TestController::shared().mainWebView(); | |
+ WKRetainPtr<WKImageRef> windowSnapshot = webView->windowSnapshotImage(); | |
+ QImage image; | |
+ if (windowSnapshot) | |
+ image = WKImageCreateQImage(windowSnapshot.get()); | |
+ else | |
+ image = WKImageCreateQImage(imageRef); | |
+ | |
QCryptographicHash hash(QCryptographicHash::Md5); | |
for (unsigned row = 0; row < image.height(); ++row) | |
hash.addData(reinterpret_cast<const char*>(image.constScanLine(row)), image.bytesPerLine()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment