Position of WebGL <canvas> on iOS is incorrect with CSS borders
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Jun 2016 20:58:19 +0000 (20:58 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Jun 2016 20:58:19 +0000 (20:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156790

Patch by Antoine Quint <graouts@apple.com> on 2016-06-06
Reviewed by Simon Fraser.

Source/WebKit2:

WebGL layers on iOS are hosted by a WKRemoteView, which applies a transform scaling
its content by the inverse of the device pixel ratio, which affects how positions are
applied to the WebGL layer. The container layer of the layer hosted by a WKRemoteView
then has an inverse transform applied to it in the PlatformCALayerRemoteCustom
constructor. However, the position of a CALayer is not affected by its transform.

The fix for <rdar://problem/18316542> should be specific to video, so we only apply the
scaling in the case of a LayerTypeAVPlayerLayer.

* UIProcess/ios/RemoteLayerTreeHostIOS.mm:
(-[WKRemoteView initWithFrame:contextID:]):
(WebKit::RemoteLayerTreeHost::createLayer):
(-[WKRemoteView initWithFrame:contextID:hostingDeviceScaleFactor:]): Deleted.
* WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.mm:
(WebKit::PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom):

LayoutTests:

Adding new tests checking that CSS border, box-shadow and padding properties used on a
WebGL <canvas> element correctly affect the position of the WebGL content.

* webgl/webgl-border-expected.html: Added.
* webgl/webgl-border.html: Added.
* webgl/webgl-box-shadow-expected.html: Added.
* webgl/webgl-box-shadow.html: Added.
* webgl/webgl-padding-expected.html: Added.
* webgl/webgl-padding.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/webgl/webgl-border-expected.html [new file with mode: 0644]
LayoutTests/webgl/webgl-border.html [new file with mode: 0644]
LayoutTests/webgl/webgl-box-shadow-expected.html [new file with mode: 0644]
LayoutTests/webgl/webgl-box-shadow.html [new file with mode: 0644]
LayoutTests/webgl/webgl-padding-expected.html [new file with mode: 0644]
LayoutTests/webgl/webgl-padding.html [new file with mode: 0644]
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/ios/RemoteLayerTreeHostIOS.mm
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.mm

index 11aa926..d1dcccf 100644 (file)
@@ -1,3 +1,20 @@
+2016-06-06  Antoine Quint  <graouts@apple.com>
+
+        Position of WebGL <canvas> on iOS is incorrect with CSS borders
+        https://bugs.webkit.org/show_bug.cgi?id=156790
+
+        Reviewed by Simon Fraser.
+
+        Adding new tests checking that CSS border, box-shadow and padding properties used on a
+        WebGL <canvas> element correctly affect the position of the WebGL content.
+
+        * webgl/webgl-border-expected.html: Added.
+        * webgl/webgl-border.html: Added.
+        * webgl/webgl-box-shadow-expected.html: Added.
+        * webgl/webgl-box-shadow.html: Added.
+        * webgl/webgl-padding-expected.html: Added.
+        * webgl/webgl-padding.html: Added.
+
 2016-06-06  Skachkov Oleksandr  <gskachkov@gmail.com>
 
         [ESNext] Support trailing commas in function param lists
diff --git a/LayoutTests/webgl/webgl-border-expected.html b/LayoutTests/webgl/webgl-border-expected.html
new file mode 100644 (file)
index 0000000..498eeaf
--- /dev/null
@@ -0,0 +1,14 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+
+    div {
+        width: 100px;
+        height: 100px;
+        background-color: black;
+        border: 20px solid blue;
+    }
+
+    </style>
+</head>
+<div></div>
diff --git a/LayoutTests/webgl/webgl-border.html b/LayoutTests/webgl/webgl-border.html
new file mode 100644 (file)
index 0000000..ebd00a7
--- /dev/null
@@ -0,0 +1,26 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+
+    canvas {
+        width: 100px;
+        height: 100px;
+        background-color: red;
+        border: 20px solid blue;
+    }
+
+    </style>
+</head>
+<canvas>
+<script type="text/javascript">
+
+    var canvas = document.querySelector("canvas");
+    canvas.width = canvas.clientWidth * window.devicePixelRatio;
+    canvas.height = canvas.clientHeight * window.devicePixelRatio;
+
+    var gl = canvas.getContext("webgl");
+    gl.clearColor(0, 0, 0, 1);
+    gl.clear(gl.COLOR_BUFFER_BIT);
+
+</script>
+</canvas>
diff --git a/LayoutTests/webgl/webgl-box-shadow-expected.html b/LayoutTests/webgl/webgl-box-shadow-expected.html
new file mode 100644 (file)
index 0000000..cda6950
--- /dev/null
@@ -0,0 +1,14 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+
+    div {
+        width: 100px;
+        height: 100px;
+        background-color: black;
+        box-shadow: 10px 10px 0px blue;
+    }
+
+    </style>
+</head>
+<div></div>
diff --git a/LayoutTests/webgl/webgl-box-shadow.html b/LayoutTests/webgl/webgl-box-shadow.html
new file mode 100644 (file)
index 0000000..97f3889
--- /dev/null
@@ -0,0 +1,26 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+
+    canvas {
+        width: 100px;
+        height: 100px;
+        background-color: red;
+        box-shadow: 10px 10px 0px blue;
+    }
+
+    </style>
+</head>
+<canvas>
+<script type="text/javascript">
+
+    var canvas = document.querySelector("canvas");
+    canvas.width = canvas.clientWidth * window.devicePixelRatio;
+    canvas.height = canvas.clientHeight * window.devicePixelRatio;
+
+    var gl = canvas.getContext("webgl");
+    gl.clearColor(0, 0, 0, 1);
+    gl.clear(gl.COLOR_BUFFER_BIT);
+
+</script>
+</canvas>
diff --git a/LayoutTests/webgl/webgl-padding-expected.html b/LayoutTests/webgl/webgl-padding-expected.html
new file mode 100644 (file)
index 0000000..39f2889
--- /dev/null
@@ -0,0 +1,14 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+
+    div {
+        width: 100px;
+        height: 100px;
+        background-color: black;
+        padding: 10px;
+    }
+
+    </style>
+</head>
+<div></div>
diff --git a/LayoutTests/webgl/webgl-padding.html b/LayoutTests/webgl/webgl-padding.html
new file mode 100644 (file)
index 0000000..802b120
--- /dev/null
@@ -0,0 +1,26 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+
+    canvas {
+        width: 100px;
+        height: 100px;
+        background-color: black;
+        padding: 10px;
+    }
+
+    </style>
+</head>
+<canvas>
+<script type="text/javascript">
+
+    var canvas = document.querySelector("canvas");
+    canvas.width = canvas.clientWidth * window.devicePixelRatio;
+    canvas.height = canvas.clientHeight * window.devicePixelRatio;
+
+    var gl = canvas.getContext("webgl");
+    gl.clearColor(0, 0, 0, 1);
+    gl.clear(gl.COLOR_BUFFER_BIT);
+
+</script>
+</canvas>
index 2e6a712..5434c52 100644 (file)
@@ -1,3 +1,26 @@
+2016-06-06  Antoine Quint  <graouts@apple.com>
+
+        Position of WebGL <canvas> on iOS is incorrect with CSS borders
+        https://bugs.webkit.org/show_bug.cgi?id=156790
+
+        Reviewed by Simon Fraser.
+
+        WebGL layers on iOS are hosted by a WKRemoteView, which applies a transform scaling
+        its content by the inverse of the device pixel ratio, which affects how positions are
+        applied to the WebGL layer. The container layer of the layer hosted by a WKRemoteView
+        then has an inverse transform applied to it in the PlatformCALayerRemoteCustom
+        constructor. However, the position of a CALayer is not affected by its transform.
+
+        The fix for <rdar://problem/18316542> should be specific to video, so we only apply the
+        scaling in the case of a LayerTypeAVPlayerLayer.
+
+        * UIProcess/ios/RemoteLayerTreeHostIOS.mm:
+        (-[WKRemoteView initWithFrame:contextID:]):
+        (WebKit::RemoteLayerTreeHost::createLayer):
+        (-[WKRemoteView initWithFrame:contextID:hostingDeviceScaleFactor:]): Deleted.
+        * WebProcess/WebPage/mac/PlatformCALayerRemoteCustom.mm:
+        (WebKit::PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom):
+
 2016-06-06  Brady Eidson  <beidson@apple.com>
 
         Fix build after r201717
index 367ac13..c32571e 100644 (file)
@@ -140,14 +140,10 @@ using namespace WebCore;
 
 @implementation WKRemoteView
 
-- (instancetype)initWithFrame:(CGRect)frame contextID:(uint32_t)contextID hostingDeviceScaleFactor:(float)scaleFactor
+- (instancetype)initWithFrame:(CGRect)frame contextID:(uint32_t)contextID
 {
-    if ((self = [super initWithFrame:frame])) {
+    if ((self = [super initWithFrame:frame]))
         [[self layer] setContextId:contextID];
-        // Invert the scale transform added in the WebProcess to fix <rdar://problem/18316542>.
-        float inverseScale = 1 / scaleFactor;
-        [[self layer] setTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
-    }
     
     return self;
 }
@@ -211,9 +207,14 @@ LayerOrView *RemoteLayerTreeHost::createLayer(const RemoteLayerTreeTransaction::
     case PlatformCALayer::LayerTypeCustom:
     case PlatformCALayer::LayerTypeAVPlayerLayer:
     case PlatformCALayer::LayerTypeWebGLLayer:
-        if (!m_isDebugLayerTreeHost)
-            view = adoptNS([[WKRemoteView alloc] initWithFrame:CGRectZero contextID:properties.hostingContextID hostingDeviceScaleFactor:properties.hostingDeviceScaleFactor]);
-        else
+        if (!m_isDebugLayerTreeHost) {
+            view = adoptNS([[WKRemoteView alloc] initWithFrame:CGRectZero contextID:properties.hostingContextID]);
+            if (properties.type == PlatformCALayer::LayerTypeAVPlayerLayer) {
+                // Invert the scale transform added in the WebProcess to fix <rdar://problem/18316542>.
+                float inverseScale = 1 / properties.hostingDeviceScaleFactor;
+                [[view layer] setTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
+            }
+        } else
             view = adoptNS([[WKCompositingView alloc] init]);
         break;
     case PlatformCALayer::LayerTypeShapeLayer:
index 110d946..1542a6b 100644 (file)
@@ -65,10 +65,12 @@ PlatformCALayerRemoteCustom::PlatformCALayerRemoteCustom(LayerType layerType, Pl
     case LayerHostingMode::OutOfProcess:
         m_layerHostingContext = LayerHostingContext::createForExternalHostingProcess();
 #if PLATFORM(IOS)
-        float scaleFactor = context.deviceScaleFactor();
-        // Set a scale factor here to make convertRect:toLayer:nil take scale factor into account. <rdar://problem/18316542>.
-        // This scale factor is inverted in the hosting process.
-        [customLayer setTransform:CATransform3DMakeScale(scaleFactor, scaleFactor, 1)];
+        if (layerType == LayerTypeAVPlayerLayer) {
+            float scaleFactor = context.deviceScaleFactor();
+            // Set a scale factor here to make convertRect:toLayer:nil take scale factor into account. <rdar://problem/18316542>.
+            // This scale factor is inverted in the hosting process.
+            [customLayer setTransform:CATransform3DMakeScale(scaleFactor, scaleFactor, 1)];
+        }
 #endif
         break;
 #endif