Make clip-path work on <video>, <canvas> etc.
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Mar 2015 06:35:20 +0000 (06:35 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Mar 2015 06:35:20 +0000 (06:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=138684

Reviewed by Darin Adler.

Source/WebCore:

clip-path only worked in compositing layers on the painted contents of the layer,
and failed to clip children. Fix this by translating the clip path into a Path
which is set on a CA shape layer (for Mac and iOS), or painted into the
RenderLayerBacking's mask layer. There are two code paths:

1. clip-path which is a <basic-shape> or <geometry-box>, and no mask.
    Here we can use the optimal code path of converting the clip into a path
    that is put onto a CAShapeLayer, which is then used as a mask. There is no
    additional backing store.
2. clip-path with an SVG reference, or clip-path combined with -webkit-mask:
    Here we have to allocate backing store for the mask layer, and paint the
    clip path (possibly with the mask).

We add GraphicsLayer::Type::Shape, and add a getter for the layer type.

Tests: compositing/masks/compositing-clip-path-and-mask.html
       compositing/masks/compositing-clip-path-mask-change.html
       compositing/masks/compositing-clip-path.html
       compositing/masks/reference-clip-path-on-composited.html

* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::GraphicsLayer): Store the type in the layer so the getter can return it.
(WebCore::GraphicsLayer::shapeLayerPath): Get and set the shape layer path.
(WebCore::GraphicsLayer::setShapeLayerPath): Ditto.
(WebCore::GraphicsLayer::shapeLayerWindRule): Get and set the shape layer wind rule.
(WebCore::GraphicsLayer::setShapeLayerWindRule): Ditto.
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::type): Expose the type.
(WebCore::GraphicsLayer::supportsLayerType): Allow the cross-platform code to use
shape layers when it knows they are available.
(WebCore::GraphicsLayer::needsClippingMaskLayer): Deleted. This was never used.
* platform/graphics/GraphicsLayerClient.h: Align the bits (helps avoid typos). Add a
GraphicsLayerPaintClipPath phase.
* platform/graphics/Path.h: Some exports since WK2 needs to encode Paths now.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::initialize): Make shape layers.
(WebCore::GraphicsLayerCA::setShapeLayerPath): Setter for the shape path. Sadly we
can't early return on unchanged paths yet.
(WebCore::GraphicsLayerCA::setShapeLayerWindRule):
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Updates for shape path
and wind rule.
(WebCore::GraphicsLayerCA::updateShape):
(WebCore::GraphicsLayerCA::updateWindRule):
* platform/graphics/ca/GraphicsLayerCA.h: Some new dirty bits for shape path and wind rule.
* platform/graphics/ca/PlatformCALayer.h:
* platform/graphics/ca/mac/PlatformCALayerMac.h:
* platform/graphics/ca/mac/PlatformCALayerMac.mm: Got rid of lots of m_layer.get().
(PlatformCALayerMac::~PlatformCALayerMac):
(PlatformCALayerMac::setNeedsDisplay):
(PlatformCALayerMac::setNeedsDisplayInRect):
(PlatformCALayerMac::removeFromSuperlayer):
(PlatformCALayerMac::setSublayers):
(PlatformCALayerMac::removeAllSublayers):
(PlatformCALayerMac::appendSublayer):
(PlatformCALayerMac::insertSublayer):
(PlatformCALayerMac::replaceSublayer):
(PlatformCALayerMac::adoptSublayers):
(PlatformCALayerMac::addAnimationForKey):
(PlatformCALayerMac::removeAnimationForKey):
(PlatformCALayerMac::animationForKey):
(PlatformCALayerMac::setMask):
(PlatformCALayerMac::isOpaque):
(PlatformCALayerMac::setOpaque):
(PlatformCALayerMac::bounds):
(PlatformCALayerMac::setBounds):
(PlatformCALayerMac::position):
(PlatformCALayerMac::setPosition):
(PlatformCALayerMac::anchorPoint):
(PlatformCALayerMac::setAnchorPoint):
(PlatformCALayerMac::transform):
(PlatformCALayerMac::setTransform):
(PlatformCALayerMac::sublayerTransform):
(PlatformCALayerMac::setSublayerTransform):
(PlatformCALayerMac::setHidden):
(PlatformCALayerMac::setGeometryFlipped):
(PlatformCALayerMac::isDoubleSided):
(PlatformCALayerMac::setDoubleSided):
(PlatformCALayerMac::masksToBounds):
(PlatformCALayerMac::setMasksToBounds):
(PlatformCALayerMac::acceleratesDrawing):
(PlatformCALayerMac::setAcceleratesDrawing):
(PlatformCALayerMac::contents):
(PlatformCALayerMac::setContents):
(PlatformCALayerMac::setContentsRect):
(PlatformCALayerMac::setMinificationFilter):
(PlatformCALayerMac::setMagnificationFilter):
(PlatformCALayerMac::backgroundColor):
(PlatformCALayerMac::setBackgroundColor):
(PlatformCALayerMac::setBorderWidth):
(PlatformCALayerMac::setBorderColor):
(PlatformCALayerMac::opacity):
(PlatformCALayerMac::setOpacity):
(PlatformCALayerMac::copyFiltersFrom):
(PlatformCALayerMac::setName):
(PlatformCALayerMac::setSpeed):
(PlatformCALayerMac::setTimeOffset):
(PlatformCALayerMac::contentsScale):
(PlatformCALayerMac::setContentsScale):
(PlatformCALayerMac::cornerRadius):
(PlatformCALayerMac::setCornerRadius):
(PlatformCALayerMac::setEdgeAntialiasingMask):
(PlatformCALayerMac::shapeWindRule): New function.
(PlatformCALayerMac::setShapeWindRule): Ditto.
(PlatformCALayerMac::shapePath): Ditto.
(PlatformCALayerMac::setShapePath): Ditto.
(PlatformCALayer::isWebLayer):
* platform/graphics/cg/PathCG.cpp:
(WebCore::Path::Path): nullptr.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintsWithClipPath): Return true if the clip path is painted.
(WebCore::RenderLayer::computeClipPath): Factor code that computes the clip path into this
function, so we can call it from RenderLayerBacking too.
(WebCore::RenderLayer::setupClipPath):
(WebCore::RenderLayer::paintLayerContents): We only want to apply the clip path
for painting when we're either painting a non-composited layer, or we're painting the
mask layer of a composited layer. We in the latter case, we just want to fill the clip
path with black, so re-use the paintChildClippingMaskForFragments() which does this.
* rendering/RenderLayer.h: Align the bits, add PaintLayerPaintingCompositingClipPathPhase.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::~RenderLayerBacking):
(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::RenderLayerBacking::updateGeometry): Move mask updating into its own function.
(WebCore::RenderLayerBacking::updateMaskingLayerGeometry): If we're using the shape layer
code path, compute the Path and set it and the wind rule on the mask layer.
(WebCore::RenderLayerBacking::updateMaskingLayer): This is now more complex, as it has
to deal with combinations of clip-path and mask, some of which allow for the shape layer
mask, and we handle dynamic changes between these and painted masks.
(WebCore::RenderLayerBacking::paintingPhaseForPrimaryLayer): Include the GraphicsLayerPaintClipPath phase.
(WebCore::RenderLayerBacking::paintIntoLayer): Map GraphicsLayerPaintClipPath to PaintLayerPaintingCompositingClipPathPhase.
(WebCore::RenderLayerBacking::updateMaskLayer): Deleted.
* rendering/RenderLayerBacking.h:

Source/WebKit2:

Support encode/decode for WebCore Path objects, which is done by traversing
the path.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::pathPointCountApplierFunction):
(IPC::pathEncodeApplierFunction):
(IPC::ArgumentCoder<Path>::encode):
(IPC::ArgumentCoder<Path>::decode):
* Shared/WebCoreArgumentCoders.h:
* Shared/mac/RemoteLayerTreePropertyApplier.mm:
(WebKit::applyPropertiesToLayer): Actually apply the path and wind rule to the shape layer.
* Shared/mac/RemoteLayerTreeTransaction.h: Include path and wind rule in the layer properties.
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
(WebKit::RemoteLayerTreeTransaction::LayerProperties::encode): Encode shape and wind rule.
(WebKit::RemoteLayerTreeTransaction::LayerProperties::decode): Decode shape and wind rule.
* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(WebKit::PlatformCALayerRemote::shapePath):
(WebKit::PlatformCALayerRemote::setShapePath):
(WebKit::PlatformCALayerRemote::shapeWindRule):
(WebKit::PlatformCALayerRemote::setShapeWindRule):
* WebProcess/WebPage/mac/PlatformCALayerRemote.h:

LayoutTests:

Tests for various combinations of clip-path and mask, and dynamic changes
thereof.

* compositing/masks/compositing-clip-path-and-mask-expected.html: Added.
* compositing/masks/compositing-clip-path-and-mask.html: Added.
* compositing/masks/compositing-clip-path-expected.html: Added.
* compositing/masks/compositing-clip-path-mask-change-expected.html: Added.
* compositing/masks/compositing-clip-path-mask-change.html: Added.
* compositing/masks/compositing-clip-path.html: Added.
* compositing/masks/reference-clip-path-on-composited-expected.html: Added.
* compositing/masks/reference-clip-path-on-composited.html: Added.

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

34 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/masks/compositing-clip-path-and-mask-expected.html [new file with mode: 0644]
LayoutTests/compositing/masks/compositing-clip-path-and-mask.html [new file with mode: 0644]
LayoutTests/compositing/masks/compositing-clip-path-expected.html [new file with mode: 0644]
LayoutTests/compositing/masks/compositing-clip-path-mask-change-expected.html [new file with mode: 0644]
LayoutTests/compositing/masks/compositing-clip-path-mask-change.html [new file with mode: 0644]
LayoutTests/compositing/masks/compositing-clip-path.html [new file with mode: 0644]
LayoutTests/compositing/masks/reference-clip-path-on-composited-expected.html [new file with mode: 0644]
LayoutTests/compositing/masks/reference-clip-path-on-composited.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GraphicsLayer.cpp
Source/WebCore/platform/graphics/GraphicsLayer.h
Source/WebCore/platform/graphics/GraphicsLayerClient.h
Source/WebCore/platform/graphics/Path.h
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
Source/WebCore/platform/graphics/ca/PlatformCALayer.h
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.h
Source/WebCore/platform/graphics/cg/PathCG.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebCoreArgumentCoders.cpp
Source/WebKit2/Shared/WebCoreArgumentCoders.h
Source/WebKit2/Shared/mac/RemoteLayerTreePropertyApplier.mm
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h

index c711757..53f9ab3 100644 (file)
@@ -1,3 +1,22 @@
+2015-03-01  Simon Fraser  <simon.fraser@apple.com>
+
+        Make clip-path work on <video>, <canvas> etc.
+        https://bugs.webkit.org/show_bug.cgi?id=138684
+
+        Reviewed by Darin Adler.
+        
+        Tests for various combinations of clip-path and mask, and dynamic changes
+        thereof.
+
+        * compositing/masks/compositing-clip-path-and-mask-expected.html: Added.
+        * compositing/masks/compositing-clip-path-and-mask.html: Added.
+        * compositing/masks/compositing-clip-path-expected.html: Added.
+        * compositing/masks/compositing-clip-path-mask-change-expected.html: Added.
+        * compositing/masks/compositing-clip-path-mask-change.html: Added.
+        * compositing/masks/compositing-clip-path.html: Added.
+        * compositing/masks/reference-clip-path-on-composited-expected.html: Added.
+        * compositing/masks/reference-clip-path-on-composited.html: Added.
+
 2015-03-01  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
 
         Unreviewed EFL gardening. Mark crash tests of webgl to CRASH.
diff --git a/LayoutTests/compositing/masks/compositing-clip-path-and-mask-expected.html b/LayoutTests/compositing/masks/compositing-clip-path-and-mask-expected.html
new file mode 100644 (file)
index 0000000..e9f2dcc
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 300px;
+          height: 300px;
+          background-color: blue;
+        }
+        
+        .clipped {
+            -webkit-clip-path: inset(0 50px);
+            -webkit-mask: linear-gradient(transparent, black);
+        }
+    </style>
+</head>
+<body>
+    <div class="clipped box"></div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/compositing-clip-path-and-mask.html b/LayoutTests/compositing/masks/compositing-clip-path-and-mask.html
new file mode 100644 (file)
index 0000000..b7d3ad6
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 300px;
+          height: 300px;
+          background-color: blue;
+        }
+        
+        .composited {
+          -webkit-transform: translateZ(0);
+        }
+        
+        .clipped {
+            -webkit-clip-path: inset(0 50px);
+            -webkit-mask: linear-gradient(transparent, black);
+        }
+    </style>
+</head>
+<body>
+    <div class="clipped composited box">asdf</div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/compositing-clip-path-expected.html b/LayoutTests/compositing/masks/compositing-clip-path-expected.html
new file mode 100644 (file)
index 0000000..09ef63b
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 300px;
+          height: 300px;
+          background-color: blue;
+        }
+        
+        .clipped {
+            -webkit-clip-path: inset(0 50px);
+        }
+    </style>
+</head>
+<body>
+    <div class="clipped box"></div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/compositing-clip-path-mask-change-expected.html b/LayoutTests/compositing/masks/compositing-clip-path-mask-change-expected.html
new file mode 100644 (file)
index 0000000..6a05987
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 200px;
+          height: 200px;
+          margin: 10px;
+          background-color: blue;
+        }
+        
+        .composited {
+          -webkit-transform: translateZ(0);
+        }
+        
+        .clipped {
+            -webkit-clip-path: inset(0 30px);
+        }
+        
+        .masked {
+            -webkit-mask: linear-gradient(transparent, black);
+        }
+        
+    </style>
+</head>
+<body>
+
+<div id="gain-mask" class="masked clipped composited box"></div>
+<div id="lose-mask" class="clipped composited box"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/compositing-clip-path-mask-change.html b/LayoutTests/compositing/masks/compositing-clip-path-mask-change.html
new file mode 100644 (file)
index 0000000..bca02d4
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 200px;
+          height: 200px;
+          margin: 10px;
+          background-color: blue;
+        }
+        
+        .composited {
+          -webkit-transform: translateZ(0);
+        }
+        
+        .clipped {
+            -webkit-clip-path: inset(0 30px);
+        }
+        
+        .masked {
+            -webkit-mask: linear-gradient(transparent, black);
+        }
+        
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        function doTest()
+        {
+            window.setTimeout(function() {
+                document.getElementById('gain-mask').classList.add('masked');
+                document.getElementById('lose-mask').classList.remove('masked');
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+
+<div id="gain-mask" class="clipped composited box"></div>
+<div id="lose-mask" class="masked clipped composited box"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/compositing-clip-path.html b/LayoutTests/compositing/masks/compositing-clip-path.html
new file mode 100644 (file)
index 0000000..dbefdcf
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 300px;
+          height: 300px;
+          background-color: blue;
+        }
+        
+        .composited {
+          -webkit-transform: translateZ(0);
+        }
+        
+        .clipped {
+            -webkit-clip-path: inset(0 50px);
+        }
+    </style>
+</head>
+<body>
+    <div class="clipped composited box"></div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/reference-clip-path-on-composited-expected.html b/LayoutTests/compositing/masks/reference-clip-path-on-composited-expected.html
new file mode 100644 (file)
index 0000000..e3cf284
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+    .container {
+        width: 200px;
+        height: 200px;
+        border: 1px solid black;
+    }
+    .clipped {
+        width: 180px;
+        height: 180px;
+        margin: 10px;
+        background-color: green;
+        -webkit-clip-path: url(#clipper);
+    }
+</style>
+</head>
+<body>
+
+<div class="container">
+    <div class="clipped box"></div>
+</div>
+
+<svg height="0">
+    <clipPath id="clipper" clipPathUnits="objectBoundingBox">
+        <rect x="0.25" y="0.25" width="0.5" height="0.5"/>
+    </clipPath>
+</svg>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/compositing/masks/reference-clip-path-on-composited.html b/LayoutTests/compositing/masks/reference-clip-path-on-composited.html
new file mode 100644 (file)
index 0000000..3527881
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+    .container {
+        width: 200px;
+        height: 200px;
+        border: 1px solid black;
+    }
+    .clipped {
+        width: 180px;
+        height: 180px;
+        margin: 10px;
+        background-color: green;
+        -webkit-clip-path: url(#clipper);
+    }
+    
+    .composited {
+      -webkit-transform: translateZ(0);
+    }
+    
+</style>
+</head>
+<body>
+
+<div class="container">
+    <div class="clipped composited box"></div>
+</div>
+
+<svg height="0">
+    <clipPath id="clipper" clipPathUnits="objectBoundingBox">
+        <rect x="0.25" y="0.25" width="0.5" height="0.5"/>
+    </clipPath>
+</svg>
+
+</body>
+</html>
\ No newline at end of file
index cb10ad0..837aa09 100644 (file)
@@ -1,3 +1,142 @@
+2015-03-01  Simon Fraser  <simon.fraser@apple.com>
+
+        Make clip-path work on <video>, <canvas> etc.
+        https://bugs.webkit.org/show_bug.cgi?id=138684
+
+        Reviewed by Darin Adler.
+        
+        clip-path only worked in compositing layers on the painted contents of the layer,
+        and failed to clip children. Fix this by translating the clip path into a Path
+        which is set on a CA shape layer (for Mac and iOS), or painted into the
+        RenderLayerBacking's mask layer. There are two code paths:
+
+        1. clip-path which is a <basic-shape> or <geometry-box>, and no mask.
+            Here we can use the optimal code path of converting the clip into a path
+            that is put onto a CAShapeLayer, which is then used as a mask. There is no
+            additional backing store.
+        2. clip-path with an SVG reference, or clip-path combined with -webkit-mask:
+            Here we have to allocate backing store for the mask layer, and paint the
+            clip path (possibly with the mask).
+        
+        We add GraphicsLayer::Type::Shape, and add a getter for the layer type.
+
+        Tests: compositing/masks/compositing-clip-path-and-mask.html
+               compositing/masks/compositing-clip-path-mask-change.html
+               compositing/masks/compositing-clip-path.html
+               compositing/masks/reference-clip-path-on-composited.html
+
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::GraphicsLayer): Store the type in the layer so the getter can return it.
+        (WebCore::GraphicsLayer::shapeLayerPath): Get and set the shape layer path.
+        (WebCore::GraphicsLayer::setShapeLayerPath): Ditto.
+        (WebCore::GraphicsLayer::shapeLayerWindRule): Get and set the shape layer wind rule.
+        (WebCore::GraphicsLayer::setShapeLayerWindRule): Ditto.
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::type): Expose the type.
+        (WebCore::GraphicsLayer::supportsLayerType): Allow the cross-platform code to use
+        shape layers when it knows they are available.
+        (WebCore::GraphicsLayer::needsClippingMaskLayer): Deleted. This was never used.
+        * platform/graphics/GraphicsLayerClient.h: Align the bits (helps avoid typos). Add a
+        GraphicsLayerPaintClipPath phase.
+        * platform/graphics/Path.h: Some exports since WK2 needs to encode Paths now.
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::initialize): Make shape layers.
+        (WebCore::GraphicsLayerCA::setShapeLayerPath): Setter for the shape path. Sadly we
+        can't early return on unchanged paths yet.
+        (WebCore::GraphicsLayerCA::setShapeLayerWindRule):
+        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Updates for shape path
+        and wind rule.
+        (WebCore::GraphicsLayerCA::updateShape):
+        (WebCore::GraphicsLayerCA::updateWindRule):
+        * platform/graphics/ca/GraphicsLayerCA.h: Some new dirty bits for shape path and wind rule.
+        * platform/graphics/ca/PlatformCALayer.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm: Got rid of lots of m_layer.get().
+        (PlatformCALayerMac::~PlatformCALayerMac):
+        (PlatformCALayerMac::setNeedsDisplay):
+        (PlatformCALayerMac::setNeedsDisplayInRect):
+        (PlatformCALayerMac::removeFromSuperlayer):
+        (PlatformCALayerMac::setSublayers):
+        (PlatformCALayerMac::removeAllSublayers):
+        (PlatformCALayerMac::appendSublayer):
+        (PlatformCALayerMac::insertSublayer):
+        (PlatformCALayerMac::replaceSublayer):
+        (PlatformCALayerMac::adoptSublayers):
+        (PlatformCALayerMac::addAnimationForKey):
+        (PlatformCALayerMac::removeAnimationForKey):
+        (PlatformCALayerMac::animationForKey):
+        (PlatformCALayerMac::setMask):
+        (PlatformCALayerMac::isOpaque):
+        (PlatformCALayerMac::setOpaque):
+        (PlatformCALayerMac::bounds):
+        (PlatformCALayerMac::setBounds):
+        (PlatformCALayerMac::position):
+        (PlatformCALayerMac::setPosition):
+        (PlatformCALayerMac::anchorPoint):
+        (PlatformCALayerMac::setAnchorPoint):
+        (PlatformCALayerMac::transform):
+        (PlatformCALayerMac::setTransform):
+        (PlatformCALayerMac::sublayerTransform):
+        (PlatformCALayerMac::setSublayerTransform):
+        (PlatformCALayerMac::setHidden):
+        (PlatformCALayerMac::setGeometryFlipped):
+        (PlatformCALayerMac::isDoubleSided):
+        (PlatformCALayerMac::setDoubleSided):
+        (PlatformCALayerMac::masksToBounds):
+        (PlatformCALayerMac::setMasksToBounds):
+        (PlatformCALayerMac::acceleratesDrawing):
+        (PlatformCALayerMac::setAcceleratesDrawing):
+        (PlatformCALayerMac::contents):
+        (PlatformCALayerMac::setContents):
+        (PlatformCALayerMac::setContentsRect):
+        (PlatformCALayerMac::setMinificationFilter):
+        (PlatformCALayerMac::setMagnificationFilter):
+        (PlatformCALayerMac::backgroundColor):
+        (PlatformCALayerMac::setBackgroundColor):
+        (PlatformCALayerMac::setBorderWidth):
+        (PlatformCALayerMac::setBorderColor):
+        (PlatformCALayerMac::opacity):
+        (PlatformCALayerMac::setOpacity):
+        (PlatformCALayerMac::copyFiltersFrom):
+        (PlatformCALayerMac::setName):
+        (PlatformCALayerMac::setSpeed):
+        (PlatformCALayerMac::setTimeOffset):
+        (PlatformCALayerMac::contentsScale):
+        (PlatformCALayerMac::setContentsScale):
+        (PlatformCALayerMac::cornerRadius):
+        (PlatformCALayerMac::setCornerRadius):
+        (PlatformCALayerMac::setEdgeAntialiasingMask):
+        (PlatformCALayerMac::shapeWindRule): New function.
+        (PlatformCALayerMac::setShapeWindRule): Ditto.
+        (PlatformCALayerMac::shapePath): Ditto.
+        (PlatformCALayerMac::setShapePath): Ditto.
+        (PlatformCALayer::isWebLayer):
+        * platform/graphics/cg/PathCG.cpp:
+        (WebCore::Path::Path): nullptr.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintsWithClipPath): Return true if the clip path is painted.
+        (WebCore::RenderLayer::computeClipPath): Factor code that computes the clip path into this
+        function, so we can call it from RenderLayerBacking too.
+        (WebCore::RenderLayer::setupClipPath):
+        (WebCore::RenderLayer::paintLayerContents): We only want to apply the clip path
+        for painting when we're either painting a non-composited layer, or we're painting the
+        mask layer of a composited layer. We in the latter case, we just want to fill the clip
+        path with black, so re-use the paintChildClippingMaskForFragments() which does this.
+        * rendering/RenderLayer.h: Align the bits, add PaintLayerPaintingCompositingClipPathPhase.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::~RenderLayerBacking):
+        (WebCore::RenderLayerBacking::updateConfiguration):
+        (WebCore::RenderLayerBacking::updateGeometry): Move mask updating into its own function.
+        (WebCore::RenderLayerBacking::updateMaskingLayerGeometry): If we're using the shape layer
+        code path, compute the Path and set it and the wind rule on the mask layer.
+        (WebCore::RenderLayerBacking::updateMaskingLayer): This is now more complex, as it has
+        to deal with combinations of clip-path and mask, some of which allow for the shape layer
+        mask, and we handle dynamic changes between these and painted masks.
+        (WebCore::RenderLayerBacking::paintingPhaseForPrimaryLayer): Include the GraphicsLayerPaintClipPath phase.
+        (WebCore::RenderLayerBacking::paintIntoLayer): Map GraphicsLayerPaintClipPath to PaintLayerPaintingCompositingClipPathPhase.
+        (WebCore::RenderLayerBacking::updateMaskLayer): Deleted.
+        * rendering/RenderLayerBacking.h:
+
 2015-03-01  Hunseop Jeong  <hs85.jeong@samsung.com>
 
         [Cairo] Implement Path::addEllipse 
index e8f5334..48c6f40 100644 (file)
@@ -71,7 +71,40 @@ void KeyframeValueList::insert(std::unique_ptr<const AnimationValue> value)
     m_values.append(WTF::move(value));
 }
 
-GraphicsLayer::GraphicsLayer(Type, GraphicsLayerClient& client)
+#if !USE(CA)
+bool GraphicsLayer::supportsLayerType(Type type)
+{
+    switch (type) {
+    case Type::Normal:
+    case Type::PageTiledBacking:
+    case Type::Scrolling:
+        return true;
+    case Type::Shape:
+        return false;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool GraphicsLayer::supportsBackgroundColorContent()
+{
+#if USE(TEXTURE_MAPPER)
+    return true;
+#else
+    return false;
+#endif
+}
+#endif
+
+#if !USE(COORDINATED_GRAPHICS)
+bool GraphicsLayer::supportsContentsTiling()
+{
+    // FIXME: Enable the feature on different ports.
+    return false;
+}
+#endif
+
+GraphicsLayer::GraphicsLayer(Type type, GraphicsLayerClient& client)
     : m_client(client)
     , m_anchorPoint(0.5f, 0.5f, 0)
     , m_opacity(1)
@@ -79,6 +112,7 @@ GraphicsLayer::GraphicsLayer(Type, GraphicsLayerClient& client)
 #if ENABLE(CSS_COMPOSITING)
     , m_blendMode(BlendModeNormal)
 #endif
+    , m_type(type)
     , m_contentsOpaque(false)
     , m_preserves3D(false)
     , m_backfaceVisibility(true)
@@ -274,6 +308,42 @@ void GraphicsLayer::setMaskLayer(GraphicsLayer* layer)
     m_maskLayer = layer;
 }
 
+Path GraphicsLayer::shapeLayerPath() const
+{
+#if USE(CA)
+    return m_shapeLayerPath;
+#else
+    return Path();
+#endif
+}
+
+void GraphicsLayer::setShapeLayerPath(const Path& path)
+{
+#if USE(CA)
+    m_shapeLayerPath = path;
+#else
+    UNUSED_PARAM(path);
+#endif
+}
+
+WindRule GraphicsLayer::shapeLayerWindRule() const
+{
+#if USE(CA)
+    return m_shapeLayerWindRule;
+#else
+    return RULE_NONZERO;
+#endif
+}
+
+void GraphicsLayer::setShapeLayerWindRule(WindRule windRule)
+{
+#if USE(CA)
+    m_shapeLayerWindRule = windRule;
+#else
+    UNUSED_PARAM(windRule);
+#endif
+}
+
 void GraphicsLayer::noteDeviceOrPageScaleFactorChangedIncludingDescendants()
 {
     deviceOrPageScaleFactorChanged();
index cfea5eb..000bc77 100644 (file)
 #include "FloatSize.h"
 #include "GraphicsLayerClient.h"
 #include "IntRect.h"
+#include "Path.h"
 #include "PlatformLayer.h"
 #include "TransformOperations.h"
+#include "WindRule.h"
 #include <wtf/TypeCasts.h>
 
 #if ENABLE(CSS_COMPOSITING)
@@ -198,12 +200,15 @@ public:
     enum class Type {
         Normal,
         PageTiledBacking,
-        Scrolling
+        Scrolling,
+        Shape
     };
     
     WEBCORE_EXPORT static std::unique_ptr<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient&, Type = Type::Normal);
     
     WEBCORE_EXPORT virtual ~GraphicsLayer();
+    
+    Type type() const { return m_type; }
 
     virtual void initialize(Type) { }
 
@@ -381,6 +386,12 @@ public:
     FloatRoundedRect maskToBoundsRect() const { return m_masksToBoundsRect; };
     virtual bool setMasksToBoundsRect(const FloatRoundedRect& roundedRect) { m_masksToBoundsRect = roundedRect; return false; }
 
+    Path shapeLayerPath() const;
+    virtual void setShapeLayerPath(const Path&);
+
+    WindRule shapeLayerWindRule() const;
+    virtual void setShapeLayerWindRule(WindRule);
+
     // Transitions are identified by a special animation name that cannot clash with a keyframe identifier.
     static String animationNameForTransition(AnimatedPropertyID);
     
@@ -480,24 +491,9 @@ public:
     void resetTrackedRepaints();
     void addRepaintRect(const FloatRect&);
 
-    static bool supportsBackgroundColorContent()
-    {
-#if USE(CA) || USE(TEXTURE_MAPPER)
-        return true;
-#else
-        return false;
-#endif
-    }
-
-#if USE(COORDINATED_GRAPHICS)
+    static bool supportsBackgroundColorContent();
+    static bool supportsLayerType(Type);
     static bool supportsContentsTiling();
-#else
-    static bool supportsContentsTiling()
-    {
-        // FIXME: Enable the feature on different ports.
-        return false;
-    }
-#endif
 
     void updateDebugIndicators();
 
@@ -507,8 +503,6 @@ public:
     virtual bool isGraphicsLayerCARemote() const { return false; }
     virtual bool isGraphicsLayerTextureMapper() const { return false; }
 
-    virtual bool needsClippingMaskLayer() { return true; };
-
 protected:
     WEBCORE_EXPORT explicit GraphicsLayer(Type, GraphicsLayerClient&);
 
@@ -570,6 +564,8 @@ protected:
     BlendMode m_blendMode;
 #endif
 
+    const Type m_type;
+
     bool m_contentsOpaque : 1;
     bool m_preserves3D: 1;
     bool m_backfaceVisibility : 1;
@@ -604,6 +600,11 @@ protected:
 
     int m_repaintCount;
     CustomAppearance m_customAppearance;
+
+#if USE(CA)
+    Path m_shapeLayerPath;
+    WindRule m_shapeLayerWindRule { RULE_NONZERO };
+#endif
 };
 
 } // namespace WebCore
index 1dccc57..71c8920 100644 (file)
@@ -39,13 +39,14 @@ class IntRect;
 class TransformationMatrix;
 
 enum GraphicsLayerPaintingPhaseFlags {
-    GraphicsLayerPaintBackground = (1 << 0),
-    GraphicsLayerPaintForeground = (1 << 1),
-    GraphicsLayerPaintMask = (1 << 2),
-    GraphicsLayerPaintOverflowContents = (1 << 3),
-    GraphicsLayerPaintCompositedScroll = (1 << 4),
-    GraphicsLayerPaintChildClippingMask = (1 << 5),
-    GraphicsLayerPaintAllWithOverflowClip = (GraphicsLayerPaintBackground | GraphicsLayerPaintForeground | GraphicsLayerPaintMask)
+    GraphicsLayerPaintBackground            = 1 << 0,
+    GraphicsLayerPaintForeground            = 1 << 1,
+    GraphicsLayerPaintMask                  = 1 << 2,
+    GraphicsLayerPaintClipPath              = 1 << 3,
+    GraphicsLayerPaintOverflowContents      = 1 << 4,
+    GraphicsLayerPaintCompositedScroll      = 1 << 5,
+    GraphicsLayerPaintChildClippingMask     = 1 << 6,
+    GraphicsLayerPaintAllWithOverflowClip   = GraphicsLayerPaintBackground | GraphicsLayerPaintForeground
 };
 typedef unsigned GraphicsLayerPaintingPhase;
 
@@ -58,14 +59,14 @@ enum AnimatedPropertyID {
 };
 
 enum LayerTreeAsTextBehaviorFlags {
-    LayerTreeAsTextBehaviorNormal = 0,
-    LayerTreeAsTextDebug = 1 << 0, // Dump extra debugging info like layer addresses.
-    LayerTreeAsTextIncludeVisibleRects = 1 << 1,
-    LayerTreeAsTextIncludeTileCaches = 1 << 2,
-    LayerTreeAsTextIncludeRepaintRects = 1 << 3,
-    LayerTreeAsTextIncludePaintingPhases = 1 << 4,
-    LayerTreeAsTextIncludeContentLayers = 1 << 5,
-    LayerTreeAsTextIncludePageOverlayLayers = 1 << 6,
+    LayerTreeAsTextBehaviorNormal               = 0,
+    LayerTreeAsTextDebug                        = 1 << 0, // Dump extra debugging info like layer addresses.
+    LayerTreeAsTextIncludeVisibleRects          = 1 << 1,
+    LayerTreeAsTextIncludeTileCaches            = 1 << 2,
+    LayerTreeAsTextIncludeRepaintRects          = 1 << 3,
+    LayerTreeAsTextIncludePaintingPhases        = 1 << 4,
+    LayerTreeAsTextIncludeContentLayers         = 1 << 5,
+    LayerTreeAsTextIncludePageOverlayLayers     = 1 << 6,
 };
 typedef unsigned LayerTreeAsTextBehavior;
 
index 7bfc75c..cbb3776 100644 (file)
@@ -90,8 +90,8 @@ namespace WebCore {
 #endif
         WEBCORE_EXPORT ~Path();
 
-        Path(const Path&);
-        Path& operator=(const Path&);
+        WEBCORE_EXPORT Path(const Path&);
+        WEBCORE_EXPORT Path& operator=(const Path&);
 
         bool contains(const FloatPoint&, WindRule rule = RULE_NONZERO) const;
         bool strokeContains(StrokeStyleApplier*, const FloatPoint&) const;
@@ -105,7 +105,7 @@ namespace WebCore {
         FloatPoint pointAtLength(float length, bool& ok) const;
         float normalAngleAtLength(float length, bool& ok) const;
 
-        void clear();
+        WEBCORE_EXPORT void clear();
         bool isNull() const { return !m_path; }
         bool isEmpty() const;
         // Gets the current point of the current path, which is conceptually the final point reached by the path so far.
@@ -113,12 +113,12 @@ namespace WebCore {
         bool hasCurrentPoint() const;
         FloatPoint currentPoint() const;
 
-        void moveTo(const FloatPoint&);
-        void addLineTo(const FloatPoint&);
-        void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint);
-        void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);
+        WEBCORE_EXPORT void moveTo(const FloatPoint&);
+        WEBCORE_EXPORT void addLineTo(const FloatPoint&);
+        WEBCORE_EXPORT void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint);
+        WEBCORE_EXPORT void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);
         void addArcTo(const FloatPoint&, const FloatPoint&, float radius);
-        void closeSubpath();
+        WEBCORE_EXPORT void closeSubpath();
 
         void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
         void addRect(const FloatRect&);
@@ -144,7 +144,7 @@ namespace WebCore {
         // ensurePlatformPath() will allocate a PlatformPath if it has not yet been and will never return null.
         PlatformPathPtr ensurePlatformPath();
 
-        void apply(void* info, PathApplierFunction) const;
+        WEBCORE_EXPORT void apply(void* info, PathApplierFunction) const;
         void transform(const AffineTransform&);
 
         void addBeziersForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
index 2414be8..acffd73 100644 (file)
@@ -276,6 +276,30 @@ static inline bool supportsAcceleratedFilterAnimations()
 #endif
 }
 
+bool GraphicsLayer::supportsLayerType(Type type)
+{
+    switch (type) {
+    case Type::Normal:
+    case Type::PageTiledBacking:
+    case Type::Scrolling:
+        return true;
+    case Type::Shape:
+#if PLATFORM(COCOA)
+        // FIXME: we can use shaper layers on Windows when PlatformCALayerMac::setShapePath() etc are implemented.
+        return true;
+#else
+        return false;
+#endif
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool GraphicsLayer::supportsBackgroundColorContent()
+{
+    return true;
+}
+
 std::unique_ptr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient& client, Type layerType)
 {
     std::unique_ptr<GraphicsLayer> graphicsLayer;
@@ -351,6 +375,9 @@ void GraphicsLayerCA::initialize(Type layerType)
     case Type::Scrolling:
         platformLayerType = PlatformCALayer::LayerType::LayerTypeScrollingLayer;
         break;
+    case Type::Shape:
+        platformLayerType = PlatformCALayer::LayerType::LayerTypeShapeLayer;
+        break;
     }
     m_layer = createPlatformCALayer(platformLayerType, this);
     noteLayerPropertyChanged(ContentsScaleChanged);
@@ -807,6 +834,22 @@ bool GraphicsLayerCA::setMasksToBoundsRect(const FloatRoundedRect& roundedRect)
     return true;
 }
 
+void GraphicsLayerCA::setShapeLayerPath(const Path& path)
+{
+    // FIXME: need to check for path equality. No bool Path::operator==(const Path&)!.
+    GraphicsLayer::setShapeLayerPath(path);
+    noteLayerPropertyChanged(ShapeChanged);
+}
+
+void GraphicsLayerCA::setShapeLayerWindRule(WindRule windRule)
+{
+    if (windRule == m_shapeLayerWindRule)
+        return;
+
+    GraphicsLayer::setShapeLayerWindRule(windRule);
+    noteLayerPropertyChanged(WindRuleChanged);
+}
+
 bool GraphicsLayerCA::shouldRepaintOnSizeChange() const
 {
     return drawsContent() && !tiledBacking();
@@ -1371,6 +1414,12 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers(CommitState& commitState
         updateBlendMode();
 #endif
 
+    if (m_uncommittedChanges & ShapeChanged)
+        updateShape();
+
+    if (m_uncommittedChanges & WindRuleChanged)
+        updateWindRule();
+
     if (m_uncommittedChanges & AnimationChanged)
         updateAnimations();
 
@@ -1730,6 +1779,16 @@ void GraphicsLayerCA::updateBlendMode()
 }
 #endif
 
+void GraphicsLayerCA::updateShape()
+{
+    m_layer->setShapePath(m_shapeLayerPath);
+}
+
+void GraphicsLayerCA::updateWindRule()
+{
+    m_layer->setShapeWindRule(m_shapeLayerWindRule);
+}
+
 void GraphicsLayerCA::updateStructuralLayer()
 {
     ensureStructuralLayer(structuralLayerPurpose());
index 480114c..c800d29 100644 (file)
@@ -120,6 +120,9 @@ public:
     WEBCORE_EXPORT virtual void setContentsClippingRect(const FloatRoundedRect&) override;
     WEBCORE_EXPORT virtual bool setMasksToBoundsRect(const FloatRoundedRect&) override;
 
+    WEBCORE_EXPORT virtual void setShapeLayerPath(const Path&);
+    WEBCORE_EXPORT virtual void setShapeLayerWindRule(WindRule);
+
     WEBCORE_EXPORT virtual void suspendAnimations(double time) override;
     WEBCORE_EXPORT virtual void resumeAnimations() override;
 
@@ -203,13 +206,6 @@ private:
     WEBCORE_EXPORT virtual bool shouldRepaintOnSizeChange() const override;
 
     WEBCORE_EXPORT void layerDidDisplay(PlatformCALayer*);
-    void updateOpacityOnLayer();
-    void updateFilters();
-    void updateBackdropFilters();
-
-#if ENABLE(CSS_COMPOSITING)
-    void updateBlendMode();
-#endif
 
     virtual PassRefPtr<PlatformCALayer> createPlatformCALayer(PlatformCALayer::LayerType, PlatformCALayerClient* owner);
     virtual PassRefPtr<PlatformCALayer> createPlatformCALayer(PlatformLayer*, PlatformCALayerClient* owner);
@@ -384,6 +380,17 @@ private:
     void updateContentsScale(float pageScaleFactor);
     void updateCustomAppearance();
 
+    void updateOpacityOnLayer();
+    void updateFilters();
+    void updateBackdropFilters();
+
+#if ENABLE(CSS_COMPOSITING)
+    void updateBlendMode();
+#endif
+
+    void updateShape();
+    void updateWindRule();
+
     enum StructuralLayerPurpose {
         NoStructuralLayer = 0,
         StructuralLayerForPreserves3D,
@@ -448,6 +455,8 @@ private:
         DebugIndicatorsChanged =        1LLU << 31,
         CustomAppearanceChanged =       1LLU << 32,
         BlendModeChanged =              1LLU << 33,
+        ShapeChanged =                  1LLU << 34,
+        WindRuleChanged =               1LLU << 35,
     };
     typedef uint64_t LayerChangeFlags;
     enum ScheduleFlushOrNot { ScheduleFlush, DontScheduleFlush };
index 2a36744..bcfc046 100644 (file)
@@ -210,6 +210,13 @@ public:
     // Only used by LayerTypeShapeLayer.
     virtual FloatRoundedRect shapeRoundedRect() const = 0;
     virtual void setShapeRoundedRect(const FloatRoundedRect&) = 0;
+
+    // Only used by LayerTypeShapeLayer.
+    virtual Path shapePath() const = 0;
+    virtual void setShapePath(const Path&) = 0;
+
+    virtual WindRule shapeWindRule() const = 0;
+    virtual void setShapeWindRule(WindRule) = 0;
     
     virtual GraphicsLayer::CustomAppearance customAppearance() const = 0;
     virtual void updateCustomAppearance(GraphicsLayer::CustomAppearance) = 0;
index 6fa6d57..0b53514 100644 (file)
@@ -142,6 +142,12 @@ public:
     virtual FloatRoundedRect shapeRoundedRect() const override;
     virtual void setShapeRoundedRect(const FloatRoundedRect&) override;
 
+    virtual Path shapePath() const override;
+    virtual void setShapePath(const Path&) override;
+
+    virtual WindRule shapeWindRule() const override;
+    virtual void setShapeWindRule(WindRule) override;
+
     virtual GraphicsLayer::CustomAppearance customAppearance() const override { return m_customAppearance; }
     virtual void updateCustomAppearance(GraphicsLayer::CustomAppearance) override;
 
index 7be1694..0407aa4 100644 (file)
@@ -349,7 +349,7 @@ PassRefPtr<PlatformCALayer> PlatformCALayerMac::clone(PlatformCALayerClient* own
 
 PlatformCALayerMac::~PlatformCALayerMac()
 {
-    [m_layer.get() setValue:nil forKey:platformCALayerPointer];
+    [m_layer setValue:nil forKey:platformCALayerPointer];
     
     // Remove the owner pointer from the delegate in case there is a pending animationStarted event.
     [static_cast<WebAnimationDelegate*>(m_delegate.get()) setOwner:nil];
@@ -373,14 +373,14 @@ void PlatformCALayerMac::animationEnded(const String& animationKey)
 void PlatformCALayerMac::setNeedsDisplay()
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setNeedsDisplay];
+    [m_layer setNeedsDisplay];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setNeedsDisplayInRect(const FloatRect& dirtyRect)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setNeedsDisplayInRect:dirtyRect];
+    [m_layer setNeedsDisplayInRect:dirtyRect];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -403,7 +403,7 @@ PlatformCALayer* PlatformCALayerMac::superlayer() const
 void PlatformCALayerMac::removeFromSuperlayer()
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() removeFromSuperlayer];
+    [m_layer removeFromSuperlayer];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -420,7 +420,7 @@ void PlatformCALayerMac::setSublayers(const PlatformCALayerList& list)
     for (size_t i = 0; i < list.size(); ++i)
         [sublayers addObject:list[i]->m_layer.get()];
 
-    [m_layer.get() setSublayers:sublayers];
+    [m_layer setSublayers:sublayers];
     [sublayers release];
     END_BLOCK_OBJC_EXCEPTIONS
 }
@@ -428,7 +428,7 @@ void PlatformCALayerMac::setSublayers(const PlatformCALayerList& list)
 void PlatformCALayerMac::removeAllSublayers()
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setSublayers:nil];
+    [m_layer setSublayers:nil];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -436,7 +436,7 @@ void PlatformCALayerMac::appendSublayer(PlatformCALayer& layer)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
     ASSERT(m_layer != layer.m_layer);
-    [m_layer.get() addSublayer:layer.m_layer.get()];
+    [m_layer addSublayer:layer.m_layer.get()];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -444,7 +444,7 @@ void PlatformCALayerMac::insertSublayer(PlatformCALayer& layer, size_t index)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
     ASSERT(m_layer != layer.m_layer);
-    [m_layer.get() insertSublayer:layer.m_layer.get() atIndex:index];
+    [m_layer insertSublayer:layer.m_layer.get() atIndex:index];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -452,14 +452,14 @@ void PlatformCALayerMac::replaceSublayer(PlatformCALayer& reference, PlatformCAL
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
     ASSERT(m_layer != layer.m_layer);
-    [m_layer.get() replaceSublayer:reference.m_layer.get() with:layer.m_layer.get()];
+    [m_layer replaceSublayer:reference.m_layer.get() with:layer.m_layer.get()];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::adoptSublayers(PlatformCALayer& source)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setSublayers:[source.m_layer.get() sublayers]];
+    [m_layer setSublayers:[source.m_layer.get() sublayers]];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -477,20 +477,20 @@ void PlatformCALayerMac::addAnimationForKey(const String& key, PlatformCAAnimati
         [propertyAnimation setDelegate:static_cast<id>(m_delegate.get())];
      
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() addAnimation:propertyAnimation forKey:key];
+    [m_layer addAnimation:propertyAnimation forKey:key];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::removeAnimationForKey(const String& key)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() removeAnimationForKey:key];
+    [m_layer removeAnimationForKey:key];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 PassRefPtr<PlatformCAAnimation> PlatformCALayerMac::animationForKey(const String& key)
 {
-    CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>([m_layer.get() animationForKey:key]);
+    CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>([m_layer animationForKey:key]);
     if (!propertyAnimation)
         return 0;
     return PlatformCAAnimationMac::create(propertyAnimation);
@@ -499,31 +499,31 @@ PassRefPtr<PlatformCAAnimation> PlatformCALayerMac::animationForKey(const String
 void PlatformCALayerMac::setMask(PlatformCALayer* layer)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setMask:layer ? layer->platformLayer() : nil];
+    [m_layer setMask:layer ? layer->platformLayer() : nil];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 bool PlatformCALayerMac::isOpaque() const
 {
-    return [m_layer.get() isOpaque];
+    return [m_layer isOpaque];
 }
 
 void PlatformCALayerMac::setOpaque(bool value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setOpaque:value];
+    [m_layer setOpaque:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 FloatRect PlatformCALayerMac::bounds() const
 {
-    return [m_layer.get() bounds];
+    return [m_layer bounds];
 }
 
 void PlatformCALayerMac::setBounds(const FloatRect& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setBounds:value];
+    [m_layer setBounds:value];
     
     if (requiresCustomAppearanceUpdateOnBoundsChange())
         updateCustomAppearance(m_customAppearance);
@@ -533,144 +533,144 @@ void PlatformCALayerMac::setBounds(const FloatRect& value)
 
 FloatPoint3D PlatformCALayerMac::position() const
 {
-    CGPoint point = [m_layer.get() position];
-    return FloatPoint3D(point.x, point.y, [m_layer.get() zPosition]);
+    CGPoint point = [m_layer position];
+    return FloatPoint3D(point.x, point.y, [m_layer zPosition]);
 }
 
 void PlatformCALayerMac::setPosition(const FloatPoint3D& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setPosition:CGPointMake(value.x(), value.y())];
-    [m_layer.get() setZPosition:value.z()];
+    [m_layer setPosition:CGPointMake(value.x(), value.y())];
+    [m_layer setZPosition:value.z()];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 FloatPoint3D PlatformCALayerMac::anchorPoint() const
 {
-    CGPoint point = [m_layer.get() anchorPoint];
+    CGPoint point = [m_layer anchorPoint];
     float z = 0;
-    z = [m_layer.get() anchorPointZ];
+    z = [m_layer anchorPointZ];
     return FloatPoint3D(point.x, point.y, z);
 }
 
 void PlatformCALayerMac::setAnchorPoint(const FloatPoint3D& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setAnchorPoint:CGPointMake(value.x(), value.y())];
-    [m_layer.get() setAnchorPointZ:value.z()];
+    [m_layer setAnchorPoint:CGPointMake(value.x(), value.y())];
+    [m_layer setAnchorPointZ:value.z()];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 TransformationMatrix PlatformCALayerMac::transform() const
 {
-    return [m_layer.get() transform];
+    return [m_layer transform];
 }
 
 void PlatformCALayerMac::setTransform(const TransformationMatrix& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setTransform:value];
+    [m_layer setTransform:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 TransformationMatrix PlatformCALayerMac::sublayerTransform() const
 {
-    return [m_layer.get() sublayerTransform];
+    return [m_layer sublayerTransform];
 }
 
 void PlatformCALayerMac::setSublayerTransform(const TransformationMatrix& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setSublayerTransform:value];
+    [m_layer setSublayerTransform:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setHidden(bool value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setHidden:value];
+    [m_layer setHidden:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setGeometryFlipped(bool value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setGeometryFlipped:value];
+    [m_layer setGeometryFlipped:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 bool PlatformCALayerMac::isDoubleSided() const
 {
-    return [m_layer.get() isDoubleSided];
+    return [m_layer isDoubleSided];
 }
 
 void PlatformCALayerMac::setDoubleSided(bool value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setDoubleSided:value];
+    [m_layer setDoubleSided:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 bool PlatformCALayerMac::masksToBounds() const
 {
-    return [m_layer.get() masksToBounds];
+    return [m_layer masksToBounds];
 }
 
 void PlatformCALayerMac::setMasksToBounds(bool value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setMasksToBounds:value];
+    [m_layer setMasksToBounds:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 bool PlatformCALayerMac::acceleratesDrawing() const
 {
-    return [m_layer.get() acceleratesDrawing];
+    return [m_layer acceleratesDrawing];
 }
 
 void PlatformCALayerMac::setAcceleratesDrawing(bool acceleratesDrawing)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setAcceleratesDrawing:acceleratesDrawing];
+    [m_layer setAcceleratesDrawing:acceleratesDrawing];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 CFTypeRef PlatformCALayerMac::contents() const
 {
-    return [m_layer.get() contents];
+    return [m_layer contents];
 }
 
 void PlatformCALayerMac::setContents(CFTypeRef value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setContents:static_cast<id>(const_cast<void*>(value))];
+    [m_layer setContents:static_cast<id>(const_cast<void*>(value))];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setContentsRect(const FloatRect& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setContentsRect:value];
+    [m_layer setContentsRect:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setMinificationFilter(FilterType value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setMinificationFilter:toCAFilterType(value)];
+    [m_layer setMinificationFilter:toCAFilterType(value)];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setMagnificationFilter(FilterType value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setMagnificationFilter:toCAFilterType(value)];
+    [m_layer setMagnificationFilter:toCAFilterType(value)];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 Color PlatformCALayerMac::backgroundColor() const
 {
-    return [m_layer.get() backgroundColor];
+    return [m_layer backgroundColor];
 }
 
 void PlatformCALayerMac::setBackgroundColor(const Color& value)
@@ -682,14 +682,14 @@ void PlatformCALayerMac::setBackgroundColor(const Color& value)
     RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setBackgroundColor:color.get()];
+    [m_layer setBackgroundColor:color.get()];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setBorderWidth(float value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setBorderWidth:value];
+    [m_layer setBorderWidth:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -703,24 +703,24 @@ void PlatformCALayerMac::setBorderColor(const Color& value)
         RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
 
         BEGIN_BLOCK_OBJC_EXCEPTIONS
-        [m_layer.get() setBorderColor:color.get()];
+        [m_layer setBorderColor:color.get()];
         END_BLOCK_OBJC_EXCEPTIONS
     } else {
         BEGIN_BLOCK_OBJC_EXCEPTIONS
-        [m_layer.get() setBorderColor:nil];
+        [m_layer setBorderColor:nil];
         END_BLOCK_OBJC_EXCEPTIONS
     }
 }
 
 float PlatformCALayerMac::opacity() const
 {
-    return [m_layer.get() opacity];
+    return [m_layer opacity];
 }
 
 void PlatformCALayerMac::setOpacity(float value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setOpacity:value];
+    [m_layer setOpacity:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -732,7 +732,7 @@ void PlatformCALayerMac::setFilters(const FilterOperations& filters)
 void PlatformCALayerMac::copyFiltersFrom(const PlatformCALayer& sourceLayer)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setFilters:[sourceLayer.platformLayer() filters]];
+    [m_layer setFilters:[sourceLayer.platformLayer() filters]];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -770,41 +770,41 @@ void PlatformCALayerMac::setBlendMode(BlendMode blendMode)
 void PlatformCALayerMac::setName(const String& value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setName:value];
+    [m_layer setName:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setSpeed(float value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setSpeed:value];
+    [m_layer setSpeed:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setTimeOffset(CFTimeInterval value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setTimeOffset:value];
+    [m_layer setTimeOffset:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 float PlatformCALayerMac::contentsScale() const
 {
-    return [m_layer.get() contentsScale];
+    return [m_layer contentsScale];
 }
 
 void PlatformCALayerMac::setContentsScale(float value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setContentsScale:value];
+    [m_layer setContentsScale:value];
 #if PLATFORM(IOS)
-    [m_layer.get() setRasterizationScale:value];
+    [m_layer setRasterizationScale:value];
 
     if (m_layerType == LayerTypeWebTiledLayer) {
         // This will invalidate all the tiles so we won't end up with stale tiles with the wrong scale in the wrong place,
         // see <rdar://problem/9434765> for more information.
         static NSDictionary *optionsDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCATiledLayerRemoveImmediately, nil];
-        [(CATiledLayer *)m_layer.get() setNeedsDisplayInRect:[m_layer.get() bounds] levelOfDetail:0 options:optionsDictionary];
+        [(CATiledLayer *)m_layer.get() setNeedsDisplayInRect:[m_layer bounds] levelOfDetail:0 options:optionsDictionary];
     }
 #endif
     END_BLOCK_OBJC_EXCEPTIONS
@@ -812,20 +812,20 @@ void PlatformCALayerMac::setContentsScale(float value)
 
 float PlatformCALayerMac::cornerRadius() const
 {
-    return [m_layer.get() cornerRadius];
+    return [m_layer cornerRadius];
 }
 
 void PlatformCALayerMac::setCornerRadius(float value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setCornerRadius:value];
+    [m_layer setCornerRadius:value];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
 void PlatformCALayerMac::setEdgeAntialiasingMask(unsigned mask)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    [m_layer.get() setEdgeAntialiasingMask:mask];
+    [m_layer setEdgeAntialiasingMask:mask];
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
@@ -850,6 +850,49 @@ void PlatformCALayerMac::setShapeRoundedRect(const FloatRoundedRect& roundedRect
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
+WindRule PlatformCALayerMac::shapeWindRule() const
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+
+    NSString *fillRule = [(CAShapeLayer *)m_layer fillRule];
+    if ([fillRule isEqualToString:@"even-odd"])
+        return RULE_EVENODD;
+
+    return RULE_NONZERO;
+}
+
+void PlatformCALayerMac::setShapeWindRule(WindRule windRule)
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+
+    switch (windRule) {
+    case RULE_NONZERO:
+        [(CAShapeLayer *)m_layer setFillRule:@"non-zero"];
+        break;
+    case RULE_EVENODD:
+        [(CAShapeLayer *)m_layer setFillRule:@"even-odd"];
+        break;
+    }
+}
+
+Path PlatformCALayerMac::shapePath() const
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS
+    return Path(CGPathCreateMutableCopy([(CAShapeLayer *)m_layer path]));
+    END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void PlatformCALayerMac::setShapePath(const Path& path)
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS
+    [(CAShapeLayer *)m_layer setPath:path.platformPath()];
+    END_BLOCK_OBJC_EXCEPTIONS
+}
+
 bool PlatformCALayerMac::requiresCustomAppearanceUpdateOnBoundsChange() const
 {
     return m_customAppearance == GraphicsLayer::ScrollingShadow;
@@ -892,7 +935,7 @@ bool PlatformCALayer::isWebLayer()
 {
     BOOL result = NO;
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-    result = [m_layer.get() isKindOfClass:[WebLayer self]];
+    result = [m_layer isKindOfClass:[WebLayer self]];
     END_BLOCK_OBJC_EXCEPTIONS
     return result;
 }
index 75eaa1c..1be08df 100644 (file)
@@ -601,6 +601,28 @@ void PlatformCALayerWin::setShapeRoundedRect(const FloatRoundedRect&)
     // FIXME: implement.
 }
 
+WindRule PlatformCALayerWin::shapeWindRule() const
+{
+    // FIXME: implement.
+    return RULE_NONZERO;
+}
+
+void PlatformCALayerWin::setShapeWindRule(WindRule)
+{
+    // FIXME: implement.
+}
+
+Path PlatformCALayerWin::shapePath() const
+{
+    // FIXME: implement.
+    return Path();
+}
+
+void PlatformCALayerWin::setShapePath(const Path&)
+{
+    // FIXME: implement.
+}
+
 #ifndef NDEBUG
 static void printIndent(int indent)
 {
index 260b649..5d2ec90 100644 (file)
@@ -128,6 +128,12 @@ public:
     virtual FloatRoundedRect shapeRoundedRect() const override;
     virtual void setShapeRoundedRect(const FloatRoundedRect&) override;
 
+    virtual Path shapePath() const override;
+    virtual void setShapePath(const Path&) override;
+
+    virtual WindRule shapeWindRule() const override;
+    virtual void setShapeWindRule(WindRule) override;
+
     virtual void setEdgeAntialiasingMask(unsigned) override;
 
     virtual GraphicsLayer::CustomAppearance customAppearance() const override { return m_customAppearance; }
index d23821c..e25a470 100644 (file)
@@ -74,7 +74,7 @@ static inline CGContextRef scratchContext()
 }
 
 Path::Path()
-    : m_path(0)
+    : m_path(nullptr)
 {
 }
 
index 8905ead..63fbfce 100644 (file)
@@ -4023,35 +4023,54 @@ static inline LayoutRect computeReferenceBox(const RenderObject& renderer, const
     return referenceBox;
 }
 
-bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
+bool RenderLayer::paintsWithClipPath() const
 {
-    if (!renderer().hasClipPath() || context->paintingDisabled())
-        return false;
+    return renderer().style().clipPath() && !isComposited();
+}
 
-    if (!rootRelativeBoundsComputed) {
-        rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, 0);
-        rootRelativeBoundsComputed = true;
-    }
+Path RenderLayer::computeClipPath(const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, WindRule& windRule) const
+{
+    const RenderStyle& style = renderer().style();
 
-    RenderStyle& style = renderer().style();
-    ASSERT(style.clipPath());
     if (is<ShapeClipPathOperation>(*style.clipPath())) {
         auto& clipPath = downcast<ShapeClipPathOperation>(*style.clipPath());
-
         LayoutRect referenceBox = computeReferenceBox(renderer(), clipPath, offsetFromRoot, rootRelativeBounds);
-        context->save();
-        context->clipPath(clipPath.pathForReferenceRect(referenceBox), clipPath.windRule());
-        return true;
-    }
 
+        windRule = clipPath.windRule();
+        return clipPath.pathForReferenceRect(referenceBox);
+    }
+    
     if (is<BoxClipPathOperation>(*style.clipPath()) && is<RenderBox>(renderer())) {
+
         auto& clipPath = downcast<BoxClipPathOperation>(*style.clipPath());
 
         RoundedRect shapeRect = computeRoundedRectForBoxShape(clipPath.referenceBox(), downcast<RenderBox>(renderer()));
         shapeRect.move(offsetFromRoot);
 
+        windRule = RULE_NONZERO;
+        return clipPath.pathForReferenceRect(shapeRect);
+    }
+    
+    return Path();
+}
+
+bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
+{
+    if (!renderer().hasClipPath() || context->paintingDisabled())
+        return false;
+
+    if (!rootRelativeBoundsComputed) {
+        rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, offsetFromRoot, 0);
+        rootRelativeBoundsComputed = true;
+    }
+
+    RenderStyle& style = renderer().style();
+    ASSERT(style.clipPath());
+    if (is<ShapeClipPathOperation>(*style.clipPath()) || (is<BoxClipPathOperation>(*style.clipPath()) && is<RenderBox>(renderer()))) {
+        WindRule windRule;
+        Path path = computeClipPath(offsetFromRoot, rootRelativeBounds, windRule);
         context->save();
-        context->clipPath(clipPath.pathForReferenceRect(shapeRect), RULE_NONZERO);
+        context->clipPath(path, windRule);
         return true;
     }
 
@@ -4218,7 +4237,10 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     LayoutSize columnAwareOffsetFromRoot = offsetFromRoot;
     if (renderer().flowThreadContainingBlock() && (renderer().hasClipPath() || hasFilterThatIsPainting(context, paintFlags)))
         columnAwareOffsetFromRoot = toLayoutSize(convertToLayerCoords(paintingInfo.rootLayer, LayoutPoint(), AdjustForColumns));
-    bool hasClipPath = setupClipPath(context, paintingInfo, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
+
+    bool hasClipPath = false;
+    if (paintsWithClipPath() || (localPaintFlags & PaintLayerPaintingCompositingClipPathPhase) || (localPaintFlags & PaintLayerPaintingCompositingMaskPhase))
+        hasClipPath = setupClipPath(context, paintingInfo, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
 
     LayerPaintingInfo localPaintingInfo(paintingInfo);
 
@@ -4319,6 +4341,11 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
         paintMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
     }
 
+    if ((localPaintFlags & PaintLayerPaintingCompositingClipPathPhase) && shouldPaintContent && !selectionOnly) {
+        // Re-use paintChildClippingMaskForFragments to paint black for the compositing clipping mask.
+        paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
+    }
+    
     if ((localPaintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly) {
         // Paint the border radius mask for the fragments.
         paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
index 24e105d..2a7c38d 100644 (file)
@@ -428,20 +428,21 @@ public:
     int zIndex() const { return renderer().style().zIndex(); }
 
     enum PaintLayerFlag {
-        PaintLayerHaveTransparency = 1,
-        PaintLayerAppliedTransform = 1 << 1,
-        PaintLayerTemporaryClipRects = 1 << 2,
-        PaintLayerPaintingReflection = 1 << 3,
-        PaintLayerPaintingOverlayScrollbars = 1 << 4,
-        PaintLayerPaintingCompositingBackgroundPhase = 1 << 5,
-        PaintLayerPaintingCompositingForegroundPhase = 1 << 6,
-        PaintLayerPaintingCompositingMaskPhase = 1 << 7,
-        PaintLayerPaintingCompositingScrollingPhase = 1 << 8,
-        PaintLayerPaintingOverflowContents = 1 << 9,
-        PaintLayerPaintingRootBackgroundOnly = 1 << 10,
-        PaintLayerPaintingSkipRootBackground = 1 << 11,
-        PaintLayerPaintingChildClippingMaskPhase = 1 << 12,
-        PaintLayerPaintingCompositingAllPhases = (PaintLayerPaintingCompositingBackgroundPhase | PaintLayerPaintingCompositingForegroundPhase | PaintLayerPaintingCompositingMaskPhase)
+        PaintLayerHaveTransparency                      = 1 << 0,
+        PaintLayerAppliedTransform                      = 1 << 1,
+        PaintLayerTemporaryClipRects                    = 1 << 2,
+        PaintLayerPaintingReflection                    = 1 << 3,
+        PaintLayerPaintingOverlayScrollbars             = 1 << 4,
+        PaintLayerPaintingCompositingBackgroundPhase    = 1 << 5,
+        PaintLayerPaintingCompositingForegroundPhase    = 1 << 6,
+        PaintLayerPaintingCompositingMaskPhase          = 1 << 7,
+        PaintLayerPaintingCompositingClipPathPhase      = 1 << 8,
+        PaintLayerPaintingCompositingScrollingPhase     = 1 << 9,
+        PaintLayerPaintingOverflowContents              = 1 << 10,
+        PaintLayerPaintingRootBackgroundOnly            = 1 << 11,
+        PaintLayerPaintingSkipRootBackground            = 1 << 12,
+        PaintLayerPaintingChildClippingMaskPhase        = 1 << 13,
+        PaintLayerPaintingCompositingAllPhases          = PaintLayerPaintingCompositingBackgroundPhase | PaintLayerPaintingCompositingForegroundPhase | PaintLayerPaintingCompositingMaskPhase
     };
     
     typedef unsigned PaintLayerFlags;
@@ -752,6 +753,11 @@ private:
     void updateCompositingAndLayerListsIfNeeded();
 
     bool setupFontSubpixelQuantization(GraphicsContext*, bool& didQuantizeFonts);
+
+    bool paintsWithClipPath() const;
+
+    Path computeClipPath(const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, WindRule&) const;
+
     bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
 
     bool hasFilterThatIsPainting(GraphicsContext*, PaintLayerFlags) const;
index ed83151..1c132d6 100644 (file)
@@ -149,7 +149,7 @@ RenderLayerBacking::~RenderLayerBacking()
     updateOverflowControlsLayers(false, false, false);
     updateForegroundLayer(false);
     updateBackgroundLayer(false);
-    updateMaskLayer(false);
+    updateMaskingLayer(false, false);
     updateScrollingLayers(false);
     detachFromScrollingCoordinator();
     destroyGraphicsLayers();
@@ -570,7 +570,7 @@ bool RenderLayerBacking::updateConfiguration()
             m_graphicsLayer->addChild(flatteningLayer);
     }
 
-    updateMaskLayer(renderer().hasMask());
+    updateMaskingLayer(renderer().hasMask(), renderer().hasClipPath());
 
     updateChildClippingStrategy(needsDescendantsClippingLayer);
 
@@ -827,11 +827,8 @@ void RenderLayerBacking::updateGeometry()
         }
     }
     
-    if (m_maskLayer) {
-        m_maskLayer->setSize(m_graphicsLayer->size());
-        m_maskLayer->setPosition(FloatPoint());
-        m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
-    }
+    if (m_maskLayer)
+        updateMaskingLayerGeometry();
     
     if (m_owningLayer.renderer().hasTransformRelatedProperty()) {
         // Update properties that depend on layer dimensions.
@@ -1005,6 +1002,28 @@ void RenderLayerBacking::updateAfterDescendants()
     m_graphicsLayer->setContentsVisible(m_owningLayer.hasVisibleContent() || isPaintDestinationForDescendantLayers());
 }
 
+// FIXME: Avoid repaints when clip path changes.
+void RenderLayerBacking::updateMaskingLayerGeometry()
+{
+    m_maskLayer->setSize(m_graphicsLayer->size());
+    m_maskLayer->setPosition(FloatPoint());
+    m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
+    
+    if (!m_maskLayer->drawsContent()) {
+        if (renderer().hasClipPath()) {
+            ASSERT(renderer().style().clipPath()->type() != ClipPathOperation::Reference);
+
+            WindRule windRule;
+            // FIXME: Use correct reference box for inlines: https://bugs.webkit.org/show_bug.cgi?id=129047
+            LayoutRect referenceBoxForClippedInline = m_owningLayer.boundingBox(&m_owningLayer);
+            Path clipPath = m_owningLayer.computeClipPath(LayoutSize(), referenceBoxForClippedInline, windRule);
+
+            m_maskLayer->setShapeLayerPath(clipPath);
+            m_maskLayer->setShapeLayerWindRule(windRule);
+        }
+    }
+}
+
 void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(LayoutRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
 {
     if (!m_owningLayer.isInsideFlowThread())
@@ -1409,14 +1428,33 @@ bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
     return layerChanged;
 }
 
-void RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
+// Masking layer is used for masks or clip-path.
+void RenderLayerBacking::updateMaskingLayer(bool hasMask, bool hasClipPath)
 {
     bool layerChanged = false;
-    if (needsMaskLayer) {
+    if (hasMask || hasClipPath) {
+        GraphicsLayerPaintingPhase maskPhases = 0;
+        if (hasMask)
+            maskPhases = GraphicsLayerPaintMask;
+        
+        if (hasClipPath) {
+            bool clipNeedsPainting = renderer().style().clipPath()->type() == ClipPathOperation::Reference;
+            if (clipNeedsPainting || !GraphicsLayer::supportsLayerType(GraphicsLayer::Type::Shape))
+                maskPhases |= GraphicsLayerPaintClipPath;
+        }
+
+        bool paintsContent = maskPhases;
+        GraphicsLayer::Type requiredLayerType = paintsContent ? GraphicsLayer::Type::Normal : GraphicsLayer::Type::Shape;
+        if (m_maskLayer && m_maskLayer->type() != requiredLayerType) {
+            m_graphicsLayer->setMaskLayer(nullptr);
+            willDestroyLayer(m_maskLayer.get());
+            m_maskLayer = nullptr;
+        }
+
         if (!m_maskLayer) {
-            m_maskLayer = createGraphicsLayer("Mask");
-            m_maskLayer->setDrawsContent(true);
-            m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
+            m_maskLayer = createGraphicsLayer("Mask", requiredLayerType);
+            m_maskLayer->setDrawsContent(paintsContent);
+            m_maskLayer->setPaintingPhase(maskPhases);
             layerChanged = true;
             m_graphicsLayer->setMaskLayer(m_maskLayer.get());
         }
@@ -1527,8 +1565,6 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co
         phase |= GraphicsLayerPaintBackground;
     if (!m_foregroundLayer)
         phase |= GraphicsLayerPaintForeground;
-    if (!m_maskLayer)
-        phase |= GraphicsLayerPaintMask;
 
     if (m_scrollingContentsLayer) {
         phase &= ~GraphicsLayerPaintForeground;
@@ -2192,6 +2228,8 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
         paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
     if (paintingPhase & GraphicsLayerPaintMask)
         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
+    if (paintingPhase & GraphicsLayerPaintClipPath)
+        paintFlags |= RenderLayer::PaintLayerPaintingCompositingClipPathPhase;
     if (paintingPhase & GraphicsLayerPaintChildClippingMask)
         paintFlags |= RenderLayer::PaintLayerPaintingChildClippingMaskPhase;
     if (paintingPhase & GraphicsLayerPaintOverflowContents)
index 8d83caf..e5da930 100644 (file)
@@ -266,13 +266,15 @@ private:
     bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
     bool updateForegroundLayer(bool needsForegroundLayer);
     bool updateBackgroundLayer(bool needsBackgroundLayer);
-    void updateMaskLayer(bool needsMaskLayer);
+    void updateMaskingLayer(bool hasMask, bool hasClipPath);
     bool requiresHorizontalScrollbarLayer() const;
     bool requiresVerticalScrollbarLayer() const;
     bool requiresScrollCornerLayer() const;
     bool updateScrollingLayers(bool scrollingLayers);
     void updateDrawsContent(bool isSimpleContainer);
     void updateChildClippingStrategy(bool needsDescendantsClippingLayer);
+
+    void updateMaskingLayerGeometry();
     
     void updateRootLayerConfiguration();
 
@@ -339,7 +341,7 @@ private:
     std::unique_ptr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
     std::unique_ptr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
     std::unique_ptr<GraphicsLayer> m_childContainmentLayer; // Only used if we have clipping on a stacking context with compositing children, or if the layer has a tile cache.
-    std::unique_ptr<GraphicsLayer> m_maskLayer; // Only used if we have a mask.
+    std::unique_ptr<GraphicsLayer> m_maskLayer; // Only used if we have a mask and/or clip-path.
     std::unique_ptr<GraphicsLayer> m_childClippingMaskLayer; // Only used if we have to clip child layers or accelerated contents with border radius or clip-path.
 
     std::unique_ptr<GraphicsLayer> m_layerForHorizontalScrollbar;
index b59b58f..71978af 100644 (file)
@@ -1,3 +1,33 @@
+2015-03-01  Simon Fraser  <simon.fraser@apple.com>
+
+        Make clip-path work on <video>, <canvas> etc.
+        https://bugs.webkit.org/show_bug.cgi?id=138684
+
+        Reviewed by Darin Adler.
+        
+        Support encode/decode for WebCore Path objects, which is done by traversing
+        the path.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::pathPointCountApplierFunction):
+        (IPC::pathEncodeApplierFunction):
+        (IPC::ArgumentCoder<Path>::encode):
+        (IPC::ArgumentCoder<Path>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        * Shared/mac/RemoteLayerTreePropertyApplier.mm:
+        (WebKit::applyPropertiesToLayer): Actually apply the path and wind rule to the shape layer.
+        * Shared/mac/RemoteLayerTreeTransaction.h: Include path and wind rule in the layer properties.
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::encode): Encode shape and wind rule.
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::decode): Decode shape and wind rule.
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (WebKit::PlatformCALayerRemote::shapePath):
+        (WebKit::PlatformCALayerRemote::setShapePath):
+        (WebKit::PlatformCALayerRemote::shapeWindRule):
+        (WebKit::PlatformCALayerRemote::setShapeWindRule):
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+
 2015-03-01  Chris Dumez  <cdumez@apple.com>
 
         Make NotificationCenter / Notification suspendable
index 4c1a7c7..cf4f243 100644 (file)
@@ -49,6 +49,7 @@
 #include <WebCore/IDBKeyRangeData.h>
 #include <WebCore/Image.h>
 #include <WebCore/Length.h>
+#include <WebCore/Path.h>
 #include <WebCore/PluginData.h>
 #include <WebCore/ProtectionSpace.h>
 #include <WebCore/Region.h>
@@ -364,6 +365,115 @@ bool ArgumentCoder<IntSize>::decode(ArgumentDecoder& decoder, IntSize& intSize)
     return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
 }
 
+static void pathPointCountApplierFunction(void* info, const PathElement* element)
+{
+    uint64_t* pointCount = static_cast<uint64_t*>(info);
+    ++*pointCount;
+}
+
+static void pathEncodeApplierFunction(void* info, const PathElement* element)
+{
+    ArgumentEncoder& encoder = *static_cast<ArgumentEncoder*>(info);
+
+    encoder.encodeEnum(element->type);
+
+    switch (element->type) {
+    case PathElementMoveToPoint: // The points member will contain 1 value.
+        encoder << element->points[0];
+        break;
+    case PathElementAddLineToPoint: // The points member will contain 1 value.
+        encoder << element->points[0];
+        break;
+    case PathElementAddQuadCurveToPoint: // The points member will contain 2 values.
+        encoder << element->points[0];
+        encoder << element->points[1];
+        break;
+    case PathElementAddCurveToPoint: // The points member will contain 3 values.
+        encoder << element->points[0];
+        encoder << element->points[1];
+        encoder << element->points[2];
+        break;
+    case PathElementCloseSubpath: // The points member will contain no values.
+        break;
+    }
+}
+
+void ArgumentCoder<Path>::encode(ArgumentEncoder& encoder, const Path& path)
+{
+    uint64_t numPoints = 0;
+    path.apply(&numPoints, pathPointCountApplierFunction);
+
+    encoder << numPoints;
+
+    path.apply(&encoder, pathEncodeApplierFunction);
+}
+
+bool ArgumentCoder<Path>::decode(ArgumentDecoder& decoder, Path& path)
+{
+    uint64_t numPoints;
+    if (!decoder.decode(numPoints))
+        return false;
+    
+    path.clear();
+
+    for (uint64_t i = 0; i < numPoints; ++i) {
+    
+        PathElementType elementType;
+        if (!decoder.decodeEnum(elementType))
+            return false;
+        
+        switch (elementType) {
+        case PathElementMoveToPoint: { // The points member will contain 1 value.
+            FloatPoint point;
+            if (!decoder.decode(point))
+                return false;
+            path.moveTo(point);
+            break;
+        }
+        case PathElementAddLineToPoint: { // The points member will contain 1 value.
+            FloatPoint point;
+            if (!decoder.decode(point))
+                return false;
+            path.addLineTo(point);
+            break;
+        }
+        case PathElementAddQuadCurveToPoint: { // The points member will contain 2 values.
+            FloatPoint controlPoint;
+            if (!decoder.decode(controlPoint))
+                return false;
+
+            FloatPoint endPoint;
+            if (!decoder.decode(endPoint))
+                return false;
+
+            path.addQuadCurveTo(controlPoint, endPoint);
+            break;
+        }
+        case PathElementAddCurveToPoint: { // The points member will contain 3 values.
+            FloatPoint controlPoint1;
+            if (!decoder.decode(controlPoint1))
+                return false;
+
+            FloatPoint controlPoint2;
+            if (!decoder.decode(controlPoint2))
+                return false;
+
+            FloatPoint endPoint;
+            if (!decoder.decode(endPoint))
+                return false;
+
+            path.addBezierCurveTo(controlPoint1, controlPoint2, endPoint);
+            break;
+        }
+        case PathElementCloseSubpath: // The points member will contain no values.
+            path.closeSubpath();
+            break;
+        }
+    }
+
+    return true;
+}
+
 template<> struct ArgumentCoder<Region::Span> {
     static void encode(ArgumentEncoder&, const Region::Span&);
     static bool decode(ArgumentDecoder&, Region::Span&);
index 1cddb89..87e72cd 100644 (file)
@@ -54,6 +54,7 @@ class IntSize;
 class KeyframeValueList;
 class LinearTimingFunction;
 class Notification;
+class Path;
 class ProtectionSpace;
 class Region;
 class ResourceError;
@@ -198,6 +199,11 @@ template<> struct ArgumentCoder<WebCore::IntSize> {
     static bool decode(ArgumentDecoder&, WebCore::IntSize&);
 };
 
+template<> struct ArgumentCoder<WebCore::Path> {
+    static void encode(ArgumentEncoder&, const WebCore::Path&);
+    static bool decode(ArgumentDecoder&, WebCore::Path&);
+};
+
 template<> struct ArgumentCoder<WebCore::Region> {
     static void encode(ArgumentEncoder&, const WebCore::Region&);
     static bool decode(ArgumentDecoder&, WebCore::Region&);
index 21fb8dd..f54bc35 100644 (file)
@@ -197,6 +197,11 @@ static void applyPropertiesToLayer(CALayer *layer, RemoteLayerTreeHost* layerTre
         [(CAShapeLayer *)layer setPath:path.platformPath()];
     }
 
+    if (properties.changedProperties & RemoteLayerTreeTransaction::ShapePathChanged) {
+        ASSERT([layer isKindOfClass:[CAShapeLayer class]]);
+        [(CAShapeLayer *)layer setPath:properties.shapePath.platformPath()];
+    }
+
     if (properties.changedProperties & RemoteLayerTreeTransaction::MinificationFilterChanged)
         layer.minificationFilter = toCAFilterType(properties.minificationFilter);
 
@@ -206,6 +211,19 @@ static void applyPropertiesToLayer(CALayer *layer, RemoteLayerTreeHost* layerTre
     if (properties.changedProperties & RemoteLayerTreeTransaction::BlendModeChanged)
         PlatformCAFilters::setBlendingFiltersOnLayer(layer, properties.blendMode);
 
+    if (properties.changedProperties & RemoteLayerTreeTransaction::WindRuleChanged) {
+        ASSERT([layer isKindOfClass:[CAShapeLayer class]]);
+        CAShapeLayer *shapeLayer = (CAShapeLayer *)layer;
+        switch (properties.windRule) {
+        case RULE_NONZERO:
+            shapeLayer.fillRule = @"non-zero";
+            break;
+        case RULE_EVENODD:
+            shapeLayer.fillRule = @"even-odd";
+            break;
+        }
+    }
+
     if (properties.changedProperties & RemoteLayerTreeTransaction::SpeedChanged)
         layer.speed = properties.speed;
 
index b045963..4d02a57 100644 (file)
@@ -73,16 +73,18 @@ public:
         ContentsScaleChanged            = 1LLU << 20,
         CornerRadiusChanged             = 1LLU << 21,
         ShapeRoundedRectChanged         = 1LLU << 22,
-        MinificationFilterChanged       = 1LLU << 23,
-        MagnificationFilterChanged      = 1LLU << 24,
-        BlendModeChanged                = 1LLU << 25,
-        SpeedChanged                    = 1LLU << 26,
-        TimeOffsetChanged               = 1LLU << 27,
-        BackingStoreChanged             = 1LLU << 28,
-        FiltersChanged                  = 1LLU << 29,
-        AnimationsChanged               = 1LLU << 30,
-        EdgeAntialiasingMaskChanged     = 1LLU << 31,
-        CustomAppearanceChanged         = 1LLU << 32
+        ShapePathChanged                = 1LLU << 23,
+        MinificationFilterChanged       = 1LLU << 24,
+        MagnificationFilterChanged      = 1LLU << 25,
+        BlendModeChanged                = 1LLU << 26,
+        WindRuleChanged                 = 1LLU << 27,
+        SpeedChanged                    = 1LLU << 28,
+        TimeOffsetChanged               = 1LLU << 29,
+        BackingStoreChanged             = 1LLU << 30,
+        FiltersChanged                  = 1LLU << 31,
+        AnimationsChanged               = 1LLU << 32,
+        EdgeAntialiasingMaskChanged     = 1LLU << 33,
+        CustomAppearanceChanged         = 1LLU << 34
     };
     typedef uint64_t LayerChange;
 
@@ -136,6 +138,7 @@ public:
         WebCore::FloatRect contentsRect;
         std::unique_ptr<RemoteLayerBackingStore> backingStore;
         std::unique_ptr<WebCore::FilterOperations> filters;
+        WebCore::Path shapePath;
         WebCore::GraphicsLayer::PlatformLayerID maskLayerID;
         WebCore::GraphicsLayer::PlatformLayerID clonedLayerID;
         double timeOffset;
@@ -151,6 +154,7 @@ public:
         WebCore::PlatformCALayer::FilterType minificationFilter;
         WebCore::PlatformCALayer::FilterType magnificationFilter;
         WebCore::BlendMode blendMode;
+        WebCore::WindRule windRule;
         bool hidden;
         bool geometryFlipped;
         bool doubleSided;
index 8968e9c..f26d1b0 100644 (file)
@@ -96,6 +96,7 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
     , minificationFilter(PlatformCALayer::FilterType::Linear)
     , magnificationFilter(PlatformCALayer::FilterType::Linear)
     , blendMode(BlendModeNormal)
+    , windRule(RULE_NONZERO)
     , hidden(false)
     , geometryFlipped(false)
     , doubleSided(true)
@@ -115,6 +116,7 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties(const LayerProperti
     , anchorPoint(other.anchorPoint)
     , bounds(other.bounds)
     , contentsRect(other.contentsRect)
+    , shapePath(other.shapePath)
     , maskLayerID(other.maskLayerID)
     , clonedLayerID(other.clonedLayerID)
     , timeOffset(other.timeOffset)
@@ -130,6 +132,7 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties(const LayerProperti
     , minificationFilter(other.minificationFilter)
     , magnificationFilter(other.magnificationFilter)
     , blendMode(other.blendMode)
+    , windRule(other.windRule)
     , hidden(other.hidden)
     , geometryFlipped(other.geometryFlipped)
     , doubleSided(other.doubleSided)
@@ -224,6 +227,9 @@ void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& e
     if (changedProperties & ShapeRoundedRectChanged)
         encoder << *shapeRoundedRect;
 
+    if (changedProperties & ShapePathChanged)
+        encoder << shapePath;
+
     if (changedProperties & MinificationFilterChanged)
         encoder.encodeEnum(minificationFilter);
 
@@ -233,6 +239,9 @@ void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& e
     if (changedProperties & BlendModeChanged)
         encoder.encodeEnum(blendMode);
 
+    if (changedProperties & WindRuleChanged)
+        encoder.encodeEnum(windRule);
+
     if (changedProperties & SpeedChanged)
         encoder << speed;
 
@@ -393,6 +402,14 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
         result.shapeRoundedRect = std::make_unique<FloatRoundedRect>(roundedRect);
     }
 
+    if (result.changedProperties & ShapePathChanged) {
+        Path path;
+        if (!decoder.decode(path))
+            return false;
+        
+        result.shapePath = WTF::move(path);
+    }
+
     if (result.changedProperties & MinificationFilterChanged) {
         if (!decoder.decodeEnum(result.minificationFilter))
             return false;
@@ -408,6 +425,11 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
             return false;
     }
 
+    if (result.changedProperties & WindRuleChanged) {
+        if (!decoder.decodeEnum(result.windRule))
+            return false;
+    }
+
     if (result.changedProperties & SpeedChanged) {
         if (!decoder.decode(result.speed))
             return false;
index 9c47040..c68cbc3 100644 (file)
@@ -705,6 +705,32 @@ void PlatformCALayerRemote::setShapeRoundedRect(const FloatRoundedRect& roundedR
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ShapeRoundedRectChanged);
 }
 
+Path PlatformCALayerRemote::shapePath() const
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+    return m_properties.shapePath;
+}
+
+void PlatformCALayerRemote::setShapePath(const Path& path)
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+    m_properties.shapePath = path;
+    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ShapePathChanged);
+}
+
+WindRule PlatformCALayerRemote::shapeWindRule() const
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+    return m_properties.windRule;
+}
+
+void PlatformCALayerRemote::setShapeWindRule(WindRule windRule)
+{
+    ASSERT(m_layerType == LayerTypeShapeLayer);
+    m_properties.windRule = windRule;
+    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::WindRuleChanged);
+}
+
 bool PlatformCALayerRemote::requiresCustomAppearanceUpdateOnBoundsChange() const
 {
     return m_properties.customAppearance == GraphicsLayer::ScrollingShadow;
index 4a512c6..2febf2e 100644 (file)
@@ -144,9 +144,16 @@ public:
 
     virtual void setEdgeAntialiasingMask(unsigned) override;
 
+    // FIXME: Having both shapeRoundedRect and shapePath is redundant. We could use shapePath for everything.
     virtual WebCore::FloatRoundedRect shapeRoundedRect() const override;
     virtual void setShapeRoundedRect(const WebCore::FloatRoundedRect&) override;
 
+    virtual WebCore::Path shapePath() const override;
+    virtual void setShapePath(const WebCore::Path&) override;
+
+    virtual WebCore::WindRule shapeWindRule() const override;
+    virtual void setShapeWindRule(WebCore::WindRule) override;
+
     virtual WebCore::GraphicsLayer::CustomAppearance customAppearance() const override;
     virtual void updateCustomAppearance(WebCore::GraphicsLayer::CustomAppearance) override;