Add hiDPI support to DumpRenderTree/WebKitTestRunner without the need of reloading...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Feb 2014 21:43:18 +0000 (21:43 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Feb 2014 21:43:18 +0000 (21:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=129438

Reviewed by Simon Fraser.

'hidpi-' prefixed test cases now trigger 2x scale factor on the testing
offscreen window. It makes testing subpixel rendering and positioning possible.

Both the offscreen window's and WebKit's scaling are set accordingly.

Tools:

* DumpRenderTree/mac/DumpRenderTree.mm:
(createWebViewAndOffscreenWindow): cleanup
(destroyWebViewAndOffscreenWindow): cleanup
(dumpRenderTree):
(changeWindowScaleIfNeeded):
(runTest):
* DumpRenderTree/mac/DumpRenderTreeWindow.h:
* DumpRenderTree/mac/DumpRenderTreeWindow.mm:
(-[DumpRenderTreeWindow initWithContentRect:styleMask:backing:defer:]): cleanup
* WebKitTestRunner/PlatformWebView.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::changeWindowScaleIfNeeded):
(WTR::TestInvocation::invoke):
* WebKitTestRunner/efl/PlatformWebViewEfl.cpp:
(WTR::PlatformWebView::changeWindowScaleIfNeeded):
* WebKitTestRunner/gtk/PlatformWebViewGtk.cpp:
(WTR::PlatformWebView::changeWindowScaleIfNeeded):
* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(WTR::PlatformWebView::changeWindowScaleIfNeeded):
* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::changeWindowScaleIfNeeded):

LayoutTests:

* fast/borders/hidpi-simple-hairline-border-painting-expected.html: Added.
* fast/borders/hidpi-simple-hairline-border-painting.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@164882 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/borders/hidpi-simple-hairline-border-painting-expected.html [new file with mode: 0644]
LayoutTests/fast/borders/hidpi-simple-hairline-border-painting.html [new file with mode: 0644]
Tools/ChangeLog
Tools/DumpRenderTree/mac/DumpRenderTree.mm
Tools/DumpRenderTree/mac/DumpRenderTreeWindow.h
Tools/DumpRenderTree/mac/DumpRenderTreeWindow.mm
Tools/WebKitTestRunner/PlatformWebView.h
Tools/WebKitTestRunner/TestInvocation.cpp
Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp
Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp
Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm

index 3fa6ceb..5145fb2 100644 (file)
@@ -1,3 +1,18 @@
+2014-02-28  Zalan Bujtas  <zalan@apple.com>
+
+        Add hiDPI support to DumpRenderTree/WebKitTestRunner without the need of reloading the test case.
+        https://bugs.webkit.org/show_bug.cgi?id=129438
+
+        Reviewed by Simon Fraser.
+
+        'hidpi-' prefixed test cases now trigger 2x scale factor on the testing
+        offscreen window. It makes testing subpixel rendering and positioning possible.
+
+        Both the offscreen window's and WebKit's scaling are set accordingly.
+
+        * fast/borders/hidpi-simple-hairline-border-painting-expected.html: Added.
+        * fast/borders/hidpi-simple-hairline-border-painting.html: Added.
+
 2014-02-28  Alexey Proskuryakov  <ap@apple.com>
 
         paragraphs with different directionality in textarea with unicode-bidi: plaintext are aligned the same
diff --git a/LayoutTests/fast/borders/hidpi-simple-hairline-border-painting-expected.html b/LayoutTests/fast/borders/hidpi-simple-hairline-border-painting-expected.html
new file mode 100644 (file)
index 0000000..51f8cd4
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<title>It tests if 0.5px borders get painted.</title>
+<style>
+  div {
+       width: 49px;
+       height: 49px;
+       border: 1px solid green;
+  }
+</style>
+<body>
+       <div></div>
+</body>
diff --git a/LayoutTests/fast/borders/hidpi-simple-hairline-border-painting.html b/LayoutTests/fast/borders/hidpi-simple-hairline-border-painting.html
new file mode 100644 (file)
index 0000000..0e33d51
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<title>It tests if 0.5px borders get painted.</title>
+<style>
+.outer {
+       width: 50px;
+       height: 50px;
+       border: 0.5px solid green;
+}
+.inner {
+       width: 49px;
+       height: 49px;
+       border: 0.5px solid green;
+}
+</style>
+<body>
+       <div class="outer"><div class="inner"></div></div>
+</body>
index fdcab41..726a122 100644 (file)
@@ -1,3 +1,37 @@
+2014-02-28  Zalan Bujtas  <zalan@apple.com>
+
+        Add hiDPI support to DumpRenderTree/WebKitTestRunner without the need of reloading the test case.
+        https://bugs.webkit.org/show_bug.cgi?id=129438
+
+        Reviewed by Simon Fraser.
+
+        'hidpi-' prefixed test cases now trigger 2x scale factor on the testing
+        offscreen window. It makes testing subpixel rendering and positioning possible.
+
+        Both the offscreen window's and WebKit's scaling are set accordingly.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (createWebViewAndOffscreenWindow): cleanup
+        (destroyWebViewAndOffscreenWindow): cleanup
+        (dumpRenderTree):
+        (changeWindowScaleIfNeeded):
+        (runTest):
+        * DumpRenderTree/mac/DumpRenderTreeWindow.h:
+        * DumpRenderTree/mac/DumpRenderTreeWindow.mm:
+        (-[DumpRenderTreeWindow initWithContentRect:styleMask:backing:defer:]): cleanup
+        * WebKitTestRunner/PlatformWebView.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::changeWindowScaleIfNeeded):
+        (WTR::TestInvocation::invoke):
+        * WebKitTestRunner/efl/PlatformWebViewEfl.cpp:
+        (WTR::PlatformWebView::changeWindowScaleIfNeeded):
+        * WebKitTestRunner/gtk/PlatformWebViewGtk.cpp:
+        (WTR::PlatformWebView::changeWindowScaleIfNeeded):
+        * WebKitTestRunner/ios/PlatformWebViewIOS.mm:
+        (WTR::PlatformWebView::changeWindowScaleIfNeeded):
+        * WebKitTestRunner/mac/PlatformWebViewMac.mm:
+        (WTR::PlatformWebView::changeWindowScaleIfNeeded):
+
 2014-02-28  Anders Carlsson  <andersca@apple.com>
 
         Remove logging.
index a462d65..8655bd4 100644 (file)
@@ -90,6 +90,7 @@
 #import <wtf/Threading.h>
 #import <wtf/ObjcRuntimeExtras.h>
 #import <wtf/OwnPtr.h>
+#import <wtf/text/WTFString.h>
 
 #if !PLATFORM(IOS)
 #import <Carbon/Carbon.h>
@@ -775,6 +776,32 @@ WebView *createWebViewAndOffscreenWindow()
     return webView;
 }
 
+static void destroyWebViewAndOffscreenWindow()
+{
+    WebView *webView = [mainFrame webView];
+#if !PLATFORM(IOS)
+    NSWindow *window = [webView window];
+#endif
+    [webView close];
+    mainFrame = nil;
+
+#if !PLATFORM(IOS)
+    // Work around problem where registering drag types leaves an outstanding
+    // "perform selector" on the window, which retains the window. It's a bit
+    // inelegant and perhaps dangerous to just blow them all away, but in practice
+    // it probably won't cause any trouble (and this is just a test tool, after all).
+    [NSObject cancelPreviousPerformRequestsWithTarget:window];
+
+    [window close]; // releases when closed
+#else
+    UIWindow *uiWindow = [gWebBrowserView window];
+    [uiWindow removeFromSuperview];
+    [uiWindow release];
+#endif
+
+    [webView release];
+}
+
 static NSString *libraryPathForDumpRenderTree()
 {
     //FIXME: This may not be sufficient to prevent interactions/crashes
@@ -1148,27 +1175,7 @@ void dumpRenderTree(int argc, const char *argv[])
     if (threaded)
         stopJavaScriptThreads();
 
-#if !PLATFORM(IOS)
-    NSWindow *window = [webView window];
-#endif
-    [webView close];
-    mainFrame = nil;
-
-#if !PLATFORM(IOS)
-    // Work around problem where registering drag types leaves an outstanding
-    // "perform selector" on the window, which retains the window. It's a bit
-    // inelegant and perhaps dangerous to just blow them all away, but in practice
-    // it probably won't cause any trouble (and this is just a test tool, after all).
-    [NSObject cancelPreviousPerformRequestsWithTarget:window];
-    
-    [window close]; // releases when closed
-#else
-    UIWindow *uiWindow = [gWebBrowserView window];
-    [uiWindow removeFromSuperview];
-    [uiWindow release];
-#endif
-
-    [webView release];
+    destroyWebViewAndOffscreenWindow();
     
     releaseGlobalControllers();
     
@@ -1437,6 +1444,22 @@ static void dumpBackForwardListForWebView(WebView *view)
     printf("===============================================\n");
 }
 
+#if !PLATFORM(IOS)
+static void changeWindowScaleIfNeeded(const char* testPathOrUR)
+{
+    bool hasHighDPIWindow = [[[mainFrame webView] window] backingScaleFactor] != 1;
+    WTF::String localPathOrUrl = String(testPathOrUR);
+    bool needsHighDPIWindow = localPathOrUrl.findIgnoringCase("hidpi-") != notFound;
+    if (hasHighDPIWindow == needsHighDPIWindow)
+        return;
+
+    CGFloat newScaleFactor = needsHighDPIWindow ? 2 : 1;
+    // When the new scale factor is set on the window first, WebView doesn't see it as a new scale and stops propagating the behavior change to WebCore::Page.
+    gTestRunner->setBackingScaleFactor(newScaleFactor);
+    [[[mainFrame webView] window] _setWindowResolution:newScaleFactor displayIfChanged:YES];
+}
+#endif
+
 static void sizeWebViewForCurrentTest()
 {
     // W3C SVG tests expect to be 480x360
@@ -1733,8 +1756,11 @@ static void runTest(const string& inputLine)
         return;
     }
 
-    const string testURL([[url absoluteString] UTF8String]);
+    const char* testURL([[url absoluteString] UTF8String]);
     
+#if !PLATFORM(IOS)
+    changeWindowScaleIfNeeded(testURL);
+#endif
     resetWebViewToConsistentStateBeforeTesting();
 
     gTestRunner = TestRunner::create(testURL, command.expectedPixelHash);
index 89c979c..a91b039 100644 (file)
 
 @class WebView;
 
+@interface NSWindow (Details)
+
+- (void)_setWindowResolution:(CGFloat)resolution displayIfChanged:(BOOL)displayIfChanged;
+
+@end
+
 @interface DumpRenderTreeWindow : NSWindow
 {
 }
index 2ece9c9..13782a9 100644 (file)
@@ -74,8 +74,9 @@ static CFArrayCallBacks NonRetainingArrayCallbacks = {
 #if !PLATFORM(IOS)
 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
 {
-    [self _addToOpenWindows];
-    return [super initWithContentRect:contentRect styleMask:styleMask backing:bufferingType defer:deferCreation];
+    if ((self = [super initWithContentRect:contentRect styleMask:styleMask backing:bufferingType defer:deferCreation]))
+        [self _addToOpenWindows];
+    return self;
 }
 #else
 - (id)initWithLayer:(CALayer *)layer
index db97b64..83d9521 100644 (file)
@@ -89,6 +89,8 @@ public:
     WKRetainPtr<WKImageRef> windowSnapshotImage();
     WKDictionaryRef options() const { return m_options.get(); }
 
+    void changeWindowScaleIfNeeded(float newScale);
+
 private:
     PlatformWKView m_view;
     PlatformWindow m_window;
index f1ddc0e..f76bc85 100644 (file)
@@ -127,6 +127,13 @@ static void sizeWebViewForCurrentTest(const char* pathOrURL)
         TestController::shared().mainWebView()->resizeTo(TestController::viewWidth, TestController::viewHeight);
 }
 
+static void changeWindowScaleIfNeeded(const char* pathOrURL)
+{
+    WTF::String localPathOrUrl = String(pathOrURL);
+    bool needsHighDPIWindow = localPathOrUrl.findIgnoringCase("hidpi-") != notFound;
+    TestController::shared().mainWebView()->changeWindowScaleIfNeeded(needsHighDPIWindow ? 2 : 1);
+}
+
 static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
 {
     return strstr(pathOrURL, "loading/");
@@ -193,6 +200,7 @@ static void updateLayoutType(const char* pathOrURL)
 void TestInvocation::invoke()
 {
     TestController::TimeoutDuration timeoutToUse = TestController::LongTimeout;
+    changeWindowScaleIfNeeded(m_pathOrURL.c_str());
     sizeWebViewForCurrentTest(m_pathOrURL.c_str());
     updateLayoutType(m_pathOrURL.c_str());
     updateThreadedScrollingForCurrentTest(m_pathOrURL.c_str());
index 60f5382..846e4b7 100644 (file)
@@ -127,6 +127,10 @@ void PlatformWebView::makeWebViewFirstResponder()
 {
 }
 
+void PlatformWebView::changeWindowScaleIfNeeded(float)
+{
+}
+
 WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
 {
     int width;
index fd6f846..9e7c876 100644 (file)
@@ -114,6 +114,10 @@ void PlatformWebView::makeWebViewFirstResponder()
 {
 }
 
+void PlatformWebView::changeWindowScaleIfNeeded(float)
+{
+}
+
 WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
 {
     // FIXME: implement to capture pixels in the UI process,
index 5a67527..029f7a4 100644 (file)
@@ -207,6 +207,11 @@ void PlatformWebView::makeWebViewFirstResponder()
 //    [m_window makeFirstResponder:m_view];
 }
 
+void PlatformWebView::changeWindowScaleIfNeeded(float)
+{
+    // Retina only surface.
+}
+
 WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
 {
     return 0; // FIXME for iOS?
index b6c53a2..6b7731d 100644 (file)
@@ -109,6 +109,11 @@ enum {
     NSRect currentFrame = [self frame];
     return NSMakeRect(_fakeOrigin.x, _fakeOrigin.y, currentFrame.size.width, currentFrame.size.height);
 }
+@end
+
+@interface NSWindow (Details)
+
+- (void)_setWindowResolution:(CGFloat)resolution displayIfChanged:(BOOL)displayIfChanged;
 
 @end
 
@@ -242,4 +247,16 @@ bool PlatformWebView::viewSupportsOptions(WKDictionaryRef options) const
     return useThreadedScrolling == [(TestRunnerWKView *)m_view useThreadedScrolling];
 }
 
+void PlatformWebView::changeWindowScaleIfNeeded(float newScale)
+{
+    CGFloat currentScale = [m_window backingScaleFactor];
+    if (currentScale == newScale)
+        return;
+    [m_window _setWindowResolution:newScale displayIfChanged:YES];
+    // Changing the scaling factor on the window does not trigger NSWindowDidChangeBackingPropertiesNotification. We need to send the notification manually.
+    RetainPtr<NSMutableDictionary> notificationUserInfo = [[NSMutableDictionary alloc] initWithCapacity:1];
+    [notificationUserInfo setObject:[NSNumber numberWithDouble:currentScale] forKey:NSBackingPropertyOldScaleFactorKey];
+    [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidChangeBackingPropertiesNotification object:m_window userInfo:notificationUserInfo.get()];
+}
+
 } // namespace WTR