will-change should sometimes trigger compositing
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Aug 2015 18:32:49 +0000 (18:32 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Aug 2015 18:32:49 +0000 (18:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148072

Reviewed by Tim Horton.
Source/JavaScriptCore:

Include will-change as a reason for compositing.

* inspector/protocol/LayerTree.json:

Source/WebCore:

Implement the compositing side-effects of will-change, if any of the
following properties are specified:
    opacity
    filter (as -webkit-filter)
    backdrop-filter (as -webkit-backdrop-filter)
    transform (on transformable elements only)

Tests: compositing/layer-creation/will-change-change.html
       compositing/layer-creation/will-change-layer-creation.html

* inspector/InspectorLayerTreeAgent.cpp:
(WebCore::InspectorLayerTreeAgent::reasonsForCompositingLayer): Tell the inspector
about will-change.
* rendering/RenderElement.cpp:
(WebCore::RenderElement::adjustStyleDifference): Need to trigger a recomposite if
will-change includes a compositing trigger property. This gets called before and
after setting the style, so this checks both states.
(WebCore::RenderElement::shouldWillChangeCreateStackingContext):
* rendering/RenderElement.h:
(WebCore::RenderElement::willChangeCreatesStackingContext): Helper function that
RenderInline uses to determine if it needs to create a RenderLayer, since RenderInline
doesn't get automatic layer RenderLayers as a side effect of having non-auto z-index
in the style.
* rendering/RenderInline.h: Need to trigger a RenderLayer if will-change includes
a property that applies to inlines.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingLayer): Call requiresCompositingForWillChange().
(WebCore::RenderLayerCompositor::requiresOwnBackingStore): Call requiresCompositingForWillChange().
(WebCore::RenderLayerCompositor::reasonsForCompositing): Include requiresCompositingForWillChange().
(WebCore::RenderLayerCompositor::requiresCompositingForWillChange): If will-change contains a
property that would trigger compositing on this element, return true.
* rendering/RenderLayerCompositor.h:
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeRequiresLayout): Set ContextSensitivePropertyWillChange in
changedContextSensitiveProperties if will-change changes.
* rendering/style/RenderStyle.h: Rename for clarity.
* rendering/style/RenderStyleConstants.h: Add ContextSensitivePropertyWillChange.
* rendering/style/WillChangeData.cpp:
(WebCore::propertyCreatesStackingContext): Subset of properties that create stacking
context on any element.
(WebCore::propertyCreatesStackingContextOnBoxesOnly): Additional properties that
create stacking context on boxes.
(WebCore::propertyTriggersCompositing): Properties that trigger compositing on
any element.
(WebCore::propertyTriggersCompositingOnBoxesOnly): Additional properties that
trigger compositing on boxes.
(WebCore::WillChangeData::addFeature): As features are added, manage a set of
flags to know if they trigger stacking context or compositing, on inlines and boxes.
(WebCore::WillChangeData::createsStackingContext): Deleted.
* rendering/style/WillChangeData.h:
(WebCore::WillChangeData::canCreateStackingContext):
(WebCore::WillChangeData::canCreateStackingContextOnInline):
(WebCore::WillChangeData::canTriggerCompositing):
(WebCore::WillChangeData::canTriggerCompositingOnInline):

Source/WebInspectorUI:

Have the web inspector show a correct compositing reason for will-change.
This could be improved to indicate which specific value in will-change triggered
the compositing.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Views/LayerTreeDetailsSidebarPanel.js:
(WebInspector.LayerTreeDetailsSidebarPanel.prototype._populateListOfCompositingReasons):
(WebInspector.LayerTreeDetailsSidebarPanel):

LayoutTests:

* compositing/layer-creation/will-change-change-expected.txt: Added.
* compositing/layer-creation/will-change-change.html: Added.
* compositing/layer-creation/will-change-layer-creation-expected.txt: Added.
* compositing/layer-creation/will-change-layer-creation.html: Added.

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

22 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/layer-creation/will-change-change-expected.txt [new file with mode: 0644]
LayoutTests/compositing/layer-creation/will-change-change.html [new file with mode: 0644]
LayoutTests/compositing/layer-creation/will-change-layer-creation-expected.txt [new file with mode: 0644]
LayoutTests/compositing/layer-creation/will-change-layer-creation.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/LayerTree.json
Source/WebCore/ChangeLog
Source/WebCore/inspector/InspectorLayerTreeAgent.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/RenderStyleConstants.h
Source/WebCore/rendering/style/WillChangeData.cpp
Source/WebCore/rendering/style/WillChangeData.h
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Views/LayerTreeDetailsSidebarPanel.js

index f70f68a..aea9485 100644 (file)
@@ -1,3 +1,15 @@
+2015-08-17  Simon Fraser  <simon.fraser@apple.com>
+
+        will-change should sometimes trigger compositing
+        https://bugs.webkit.org/show_bug.cgi?id=148072
+
+        Reviewed by Tim Horton.
+
+        * compositing/layer-creation/will-change-change-expected.txt: Added.
+        * compositing/layer-creation/will-change-change.html: Added.
+        * compositing/layer-creation/will-change-layer-creation-expected.txt: Added.
+        * compositing/layer-creation/will-change-layer-creation.html: Added.
+
 2015-08-17  Timothy Horton  <timothy_horton@apple.com>
 
         Holes for find matches that span multiple lines are completely wrong
diff --git a/LayoutTests/compositing/layer-creation/will-change-change-expected.txt b/LayoutTests/compositing/layer-creation/will-change-change-expected.txt
new file mode 100644 (file)
index 0000000..2e53f6e
--- /dev/null
@@ -0,0 +1,18 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 100.00 100.00)
+          (contentsOpaque 1)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/layer-creation/will-change-change.html b/LayoutTests/compositing/layer-creation/will-change-change.html
new file mode 100644 (file)
index 0000000..4faa3d1
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            width: 100px;
+            height: 100px;
+            margin: 20px;
+            background-color: blue;
+            position: relative;
+            z-index: 0; /* Avoid changes in stacking triggering compositing */
+        }
+        
+        .removal {
+            will-change: transform;
+        }
+
+        body.changed .addition {
+            will-change: transform;
+        }
+
+        body.changed .removal {
+            will-change: auto;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function doTest()
+        {
+            window.setTimeout(function() {
+                document.body.classList.add('changed');
+                if (window.testRunner) {
+                    document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+                    testRunner.notifyDone();
+                }
+            }, 0)
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+
+<div class="addition box"></div>
+<div class="removal box"></div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/layer-creation/will-change-layer-creation-expected.txt b/LayoutTests/compositing/layer-creation/will-change-layer-creation-expected.txt
new file mode 100644 (file)
index 0000000..c1600bb
--- /dev/null
@@ -0,0 +1,53 @@
+transform opacity transform, background transform, opacity -webkit-filter
+opacity
+transform
+-webkit-filter
+transform-style
+perspective
+background, clip-path, position, z-index, -webkit-mask
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 6
+        (GraphicsLayer
+          (position 104.00 8.00)
+          (bounds 52.00 18.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 345.00 8.00)
+          (bounds 122.00 18.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 486.00 8.00)
+          (bounds 85.00 18.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 18.00 36.00)
+          (bounds 764.00 18.00)
+          (contentsOpaque 1)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 18.00 64.00)
+          (bounds 764.00 18.00)
+          (contentsOpaque 1)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 18.00 92.00)
+          (bounds 764.00 18.00)
+          (contentsOpaque 1)
+          (drawsContent 1)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/layer-creation/will-change-layer-creation.html b/LayoutTests/compositing/layer-creation/will-change-layer-creation.html
new file mode 100644 (file)
index 0000000..6edd7db
--- /dev/null
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            background-color: silver;
+            margin: 10px;
+        }
+        
+    </style>
+    <script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+
+    function dumpLayers()
+    {
+        if (window.testRunner) {
+            document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+        }
+    }
+    
+    window.addEventListener('load', dumpLayers, false);
+    </script>
+</head>
+<body>
+
+<span class="box" style="will-change: transform;">
+    transform
+</span>
+
+<span class="box" style="will-change: opacity;">
+    opacity
+</span>
+
+<span class="box" style="will-change: transform, background;">
+    transform, background
+</span>
+
+<span class="box" style="will-change: transform, opacity;">
+    transform, opacity
+</span>
+
+<span class="box" style="will-change: -webkit-filter;">
+    -webkit-filter
+</span>
+
+<div class="box" style="will-change: opacity;">
+    opacity
+</div>
+
+<div class="box" style="will-change: transform;">
+    transform
+</div>
+
+<div class="box" style="will-change: -webkit-filter;">
+    -webkit-filter
+</div>
+
+<div class="box" style="will-change: transform-style;">
+    transform-style
+</div>
+
+<div class="box" style="will-change: perspective;">
+    perspective
+</div>
+
+<div class="box" style="will-change: background, clip-path, position, z-index, -webkit-mask;">
+    background, clip-path, position, z-index, -webkit-mask
+</div>
+
+<pre id="layers"></pre>
+
+</body>
+</html>
index 1bb4e2d..8123771 100644 (file)
@@ -1,3 +1,14 @@
+2015-08-17  Simon Fraser  <simon.fraser@apple.com>
+
+        will-change should sometimes trigger compositing
+        https://bugs.webkit.org/show_bug.cgi?id=148072
+
+        Reviewed by Tim Horton.
+        
+        Include will-change as a reason for compositing.
+
+        * inspector/protocol/LayerTree.json:
+
 2015-08-17  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [ES6] Implement Reflect.getOwnPropertyDescriptor
index 61211c2..4115cd4 100644 (file)
@@ -71,6 +71,7 @@
                 { "name": "isolatesCompositedBlendingDescendants", "type": "boolean", "optional": true, "description": "Composition due to association with an element isolating compositing descendants having CSS blending applied." },
                 { "name": "perspective", "type": "boolean", "optional": true, "description": "Composition due to association with an element with perspective applied." },
                 { "name": "preserve3D", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"transform-style: preserve-3d\" style." },
+                { "name": "willChange", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"will-change\" style." },
                 { "name": "root", "type": "boolean", "optional": true, "description": "Composition due to association with the root element." },
                 { "name": "blending", "type": "boolean", "optional": true, "description": "Composition due to association with an element with a \"blend-mode\" style." }
             ]
index 97ed3c8..624eb7a 100644 (file)
@@ -1,3 +1,65 @@
+2015-08-17  Simon Fraser  <simon.fraser@apple.com>
+
+        will-change should sometimes trigger compositing
+        https://bugs.webkit.org/show_bug.cgi?id=148072
+
+        Reviewed by Tim Horton.
+        
+        Implement the compositing side-effects of will-change, if any of the
+        following properties are specified:
+            opacity
+            filter (as -webkit-filter)
+            backdrop-filter (as -webkit-backdrop-filter)
+            transform (on transformable elements only)
+
+        Tests: compositing/layer-creation/will-change-change.html
+               compositing/layer-creation/will-change-layer-creation.html
+
+        * inspector/InspectorLayerTreeAgent.cpp:
+        (WebCore::InspectorLayerTreeAgent::reasonsForCompositingLayer): Tell the inspector
+        about will-change.
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::adjustStyleDifference): Need to trigger a recomposite if
+        will-change includes a compositing trigger property. This gets called before and
+        after setting the style, so this checks both states.
+        (WebCore::RenderElement::shouldWillChangeCreateStackingContext):
+        * rendering/RenderElement.h:
+        (WebCore::RenderElement::willChangeCreatesStackingContext): Helper function that
+        RenderInline uses to determine if it needs to create a RenderLayer, since RenderInline
+        doesn't get automatic layer RenderLayers as a side effect of having non-auto z-index
+        in the style.
+        * rendering/RenderInline.h: Need to trigger a RenderLayer if will-change includes
+        a property that applies to inlines.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::requiresCompositingLayer): Call requiresCompositingForWillChange().
+        (WebCore::RenderLayerCompositor::requiresOwnBackingStore): Call requiresCompositingForWillChange().
+        (WebCore::RenderLayerCompositor::reasonsForCompositing): Include requiresCompositingForWillChange().
+        (WebCore::RenderLayerCompositor::requiresCompositingForWillChange): If will-change contains a
+        property that would trigger compositing on this element, return true.
+        * rendering/RenderLayerCompositor.h:
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeRequiresLayout): Set ContextSensitivePropertyWillChange in
+        changedContextSensitiveProperties if will-change changes.
+        * rendering/style/RenderStyle.h: Rename for clarity.
+        * rendering/style/RenderStyleConstants.h: Add ContextSensitivePropertyWillChange.
+        * rendering/style/WillChangeData.cpp:
+        (WebCore::propertyCreatesStackingContext): Subset of properties that create stacking
+        context on any element.
+        (WebCore::propertyCreatesStackingContextOnBoxesOnly): Additional properties that
+        create stacking context on boxes.
+        (WebCore::propertyTriggersCompositing): Properties that trigger compositing on
+        any element.
+        (WebCore::propertyTriggersCompositingOnBoxesOnly): Additional properties that
+        trigger compositing on boxes.
+        (WebCore::WillChangeData::addFeature): As features are added, manage a set of
+        flags to know if they trigger stacking context or compositing, on inlines and boxes.
+        (WebCore::WillChangeData::createsStackingContext): Deleted.
+        * rendering/style/WillChangeData.h:
+        (WebCore::WillChangeData::canCreateStackingContext):
+        (WebCore::WillChangeData::canCreateStackingContextOnInline):
+        (WebCore::WillChangeData::canTriggerCompositing):
+        (WebCore::WillChangeData::canTriggerCompositingOnInline):
+
 2015-08-17  Timothy Horton  <timothy_horton@apple.com>
 
         Holes for find matches that span multiple lines are completely wrong
index f6e41fa..d43b69c 100644 (file)
@@ -307,6 +307,9 @@ void InspectorLayerTreeAgent::reasonsForCompositingLayer(ErrorString& errorStrin
     if (reasonsBitmask & CompositingReasonPreserve3D)
         compositingReasons->setPreserve3D(true);
 
+    if (reasonsBitmask & CompositingReasonWillChange)
+        compositingReasons->setWillChange(true);
+
     if (reasonsBitmask & CompositingReasonRoot)
         compositingReasons->setRoot(true);
     
index 129ea51..12eff79 100644 (file)
@@ -284,6 +284,11 @@ StyleDifference RenderElement::adjustStyleDifference(StyleDifference diff, unsig
             diff = std::max(diff, StyleDifferenceRepaint);
     }
     
+    if (contextSensitiveProperties & ContextSensitivePropertyWillChange) {
+        if (style().willChange() && style().willChange()->canTriggerCompositing())
+            diff = std::max(diff, StyleDifferenceRecompositeLayer);
+    }
+    
     if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer()) {
         RenderLayer* layer = downcast<RenderLayerModelObject>(*this).layer();
         if (!layer->isComposited() || layer->paintsWithFilters())
@@ -1461,6 +1466,16 @@ bool RenderElement::repaintForPausedImageAnimationsIfNeeded(const IntRect& visib
     return true;
 }
 
+bool RenderElement::shouldWillChangeCreateStackingContext() const
+{
+    ASSERT(style().willChange());
+    ASSERT(style().willChange()->canCreateStackingContext());
+
+    // On inlines, we only want to trigger RenderLayer creation
+    // if will-change contains a property that applies to inlines.
+    return is<RenderBox>(this) || (is<RenderInline>(this) && style().willChange()->canCreateStackingContextOnInline());
+}
+
 RenderNamedFlowThread* RenderElement::renderNamedFlowThreadWrapper()
 {
     auto* renderer = this;
index 761abd9..7db2458 100644 (file)
@@ -165,6 +165,10 @@ public:
     bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); }
     bool hasClipPath() const { return style().clipPath(); }
     bool hasHiddenBackface() const { return style().backfaceVisibility() == BackfaceVisibilityHidden; }
+    bool willChangeCreatesStackingContext() const
+    {
+        return style().willChange() && style().willChange()->canCreateStackingContext() && shouldWillChangeCreateStackingContext();
+    }
 
     // anchorRect() is conceptually similar to absoluteBoundingBoxRect(), but is intended for scrolling to an anchor.
     // For inline renderers, this gets the logical top left of the first leaf child and the logical bottom right of the
@@ -304,6 +308,8 @@ private:
     bool getTrailingCorner(FloatPoint& output) const;
 
     void clearLayoutRootIfNeeded() const;
+    
+    bool shouldWillChangeCreateStackingContext() const;
 
     unsigned m_baseTypeFlags : 6;
     unsigned m_ancestorLineBoxDirty : 1;
index 4e0fea9..b9a0cd6 100644 (file)
@@ -136,7 +136,7 @@ private:
 
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override final;
 
-    virtual bool requiresLayer() const override { return isInFlowPositioned() || createsGroup() || hasClipPath(); }
+    virtual bool requiresLayer() const override { return isInFlowPositioned() || createsGroup() || hasClipPath() || willChangeCreatesStackingContext(); }
 
     virtual LayoutUnit offsetLeft() const override final;
     virtual LayoutUnit offsetTop() const override final;
index 2c3bb9f..a6dd85a 100644 (file)
@@ -2190,6 +2190,7 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, R
         || clipsCompositingDescendants(*renderer.layer())
         || requiresCompositingForAnimation(renderer)
         || requiresCompositingForFilters(renderer)
+        || requiresCompositingForWillChange(renderer)
         || requiresCompositingForPosition(renderer, *renderer.layer(), viewportConstrainedNotCompositedReason)
 #if PLATFORM(IOS)
         || requiresCompositingForScrolling(*renderer.layer())
@@ -2232,6 +2233,7 @@ bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer& layer, co
         || requiresCompositingForBackfaceVisibility(renderer)
         || requiresCompositingForAnimation(renderer)
         || requiresCompositingForFilters(renderer)
+        || requiresCompositingForWillChange(renderer)
         || requiresCompositingForPosition(renderer, layer)
         || requiresCompositingForOverflowScrolling(layer)
         || renderer.isTransparent()
@@ -2293,6 +2295,9 @@ CompositingReasons RenderLayerCompositor::reasonsForCompositing(const RenderLaye
     if (requiresCompositingForFilters(renderer))
         reasons |= CompositingReasonFilters;
 
+    if (requiresCompositingForWillChange(renderer))
+        reasons |= CompositingReasonWillChange;
+
     if (requiresCompositingForPosition(renderer, *renderer.layer()))
         reasons |= renderer.style().position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
 
@@ -2658,6 +2663,17 @@ bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject
     return renderer.hasFilter();
 }
 
+bool RenderLayerCompositor::requiresCompositingForWillChange(RenderLayerModelObject& renderer) const
+{
+    if (!renderer.style().willChange() || !renderer.style().willChange()->canTriggerCompositing())
+        return false;
+
+    if (is<RenderBox>(renderer))
+        return true;
+
+    return renderer.style().willChange()->canTriggerCompositingOnInline();
+}
+
 bool RenderLayerCompositor::isAsyncScrollableStickyLayer(const RenderLayer& layer, const RenderLayer** enclosingAcceleratedOverflowLayer) const
 {
     ASSERT(layer.renderer().isStickyPositioned());
index e9b0e48..8f3c0a2 100644 (file)
@@ -80,8 +80,9 @@ enum {
     CompositingReasonBlendingWithCompositedDescendants      = 1 << 20,
     CompositingReasonPerspective                            = 1 << 21,
     CompositingReasonPreserve3D                             = 1 << 22,
-    CompositingReasonRoot                                   = 1 << 23,
-    CompositingReasonIsolatesCompositedBlendingDescendants  = 1 << 24,
+    CompositingReasonWillChange                             = 1 << 23,
+    CompositingReasonRoot                                   = 1 << 24,
+    CompositingReasonIsolatesCompositedBlendingDescendants  = 1 << 25,
 };
 typedef unsigned CompositingReasons;
 
@@ -422,6 +423,7 @@ private:
     bool requiresCompositingForPlugin(RenderLayerModelObject&) const;
     bool requiresCompositingForFrame(RenderLayerModelObject&) const;
     bool requiresCompositingForFilters(RenderLayerModelObject&) const;
+    bool requiresCompositingForWillChange(RenderLayerModelObject&) const;
     bool requiresCompositingForScrollableFrame() const;
     bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RenderLayer::ViewportConstrainedNotCompositedReason* = nullptr) const;
     bool requiresCompositingForOverflowScrolling(const RenderLayer&) const;
index d1326a9..bd3f8b4 100644 (file)
@@ -554,6 +554,11 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& chang
         if (rareNonInheritedData->m_dashboardRegions != other.rareNonInheritedData->m_dashboardRegions)
             return true;
 #endif
+
+        if (!rareNonInheritedData->willChangeDataEquivalent(*other.rareNonInheritedData.get())) {
+            changedContextSensitiveProperties |= ContextSensitivePropertyWillChange;
+            // Don't return; keep looking for another change
+        }
     }
 
     if (rareInheritedData.get() != other.rareInheritedData.get()) {
index ddbd192..b10d9f9 100644 (file)
@@ -1806,7 +1806,7 @@ public:
         if (!willChange())
             return false;
         
-        return willChange()->createsStackingContext();
+        return willChange()->canCreateStackingContext();
     }
 
     const AtomicString& hyphenString() const;
index ec960cf..bbb4caa 100644 (file)
@@ -69,7 +69,8 @@ enum StyleDifferenceContextSensitiveProperty {
     ContextSensitivePropertyOpacity     = 1 << 1,
     ContextSensitivePropertyFilter      = 1 << 2,
     ContextSensitivePropertyClipRect    = 1 << 3,
-    ContextSensitivePropertyClipPath    = 1 << 4
+    ContextSensitivePropertyClipPath    = 1 << 4,
+    ContextSensitivePropertyWillChange  = 1 << 5,
 };
 
 // Static pseudo styles. Dynamic ones are produced on the fly.
index d3d38fe..394c9c9 100644 (file)
@@ -84,13 +84,22 @@ static bool propertyCreatesStackingContext(CSSPropertyID property)
     case CSSPropertyWebkitMask:
     case CSSPropertyWebkitMaskImage:
     case CSSPropertyWebkitMaskBoxImage:
+#if ENABLE(CSS_REGIONS)
+    case CSSPropertyWebkitFlowFrom:
+#endif
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool propertyCreatesStackingContextOnBoxesOnly(CSSPropertyID property)
+{
+    switch (property) {
     case CSSPropertyPerspective:
     case CSSPropertyTransform:
     case CSSPropertyTransformStyle:
     case CSSPropertyWebkitTransformStyle:
-#if ENABLE(CSS_REGIONS)
-    case CSSPropertyWebkitFlowFrom:
-#endif
 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
     case CSSPropertyWebkitOverflowScrolling:
 #endif
@@ -100,19 +109,45 @@ static bool propertyCreatesStackingContext(CSSPropertyID property)
     }
 }
 
-bool WillChangeData::createsStackingContext() const
+static bool propertyTriggersCompositing(CSSPropertyID property)
 {
-    for (const auto& feature : m_animatableFeatures) {
-        if (feature.feature() == Property && propertyCreatesStackingContext(feature.property()))
-            return true;
+    switch (property) {
+    case CSSPropertyOpacity:
+    case CSSPropertyWebkitFilter:
+#if ENABLE(FILTERS_LEVEL_2)
+    case CSSPropertyWebkitBackdropFilter:
+#endif
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool propertyTriggersCompositingOnBoxesOnly(CSSPropertyID property)
+{
+    // Don't trigger for perspective and transform-style, because those
+    // only do compositing if they have a 3d-transformed descendant and
+    // we don't want to do compositing all the time.
+    // Similarly, we don't want -webkit-overflow-scrolling-touch to
+    // always composite if there's no scrollable overflow.
+    switch (property) {
+    case CSSPropertyTransform:
+        return true;
+    default:
+        return false;
     }
-    return false;
 }
 
 void WillChangeData::addFeature(Feature feature, CSSPropertyID propertyID)
 {
     ASSERT(feature == Property || propertyID == CSSPropertyInvalid);
     m_animatableFeatures.append(AnimatableFeature(feature, propertyID));
+
+    m_canCreateStackingContextOnInline |= propertyCreatesStackingContext(propertyID);
+    m_canCreateStackingContext |= m_canCreateStackingContextOnInline | propertyCreatesStackingContextOnBoxesOnly(propertyID);
+
+    m_canTriggerCompositingOnInline |= propertyTriggersCompositing(propertyID);
+    m_canTriggerCompositing |= m_canTriggerCompositingOnInline | propertyTriggersCompositingOnBoxesOnly(propertyID);
 }
 
 WillChangeData::FeaturePropertyPair WillChangeData::featureAt(size_t index) const
index 81ffeb2..465e184 100644 (file)
@@ -53,7 +53,12 @@ public:
     bool containsScrollPosition() const;
     bool containsContents() const;
     bool containsProperty(CSSPropertyID) const;
-    bool createsStackingContext() const;
+
+    bool canCreateStackingContext() const { return m_canCreateStackingContext; }
+    bool canCreateStackingContextOnInline() const { return m_canCreateStackingContextOnInline; }
+
+    bool canTriggerCompositing() const { return m_canTriggerCompositing; }
+    bool canTriggerCompositingOnInline() const { return m_canTriggerCompositingOnInline; }
 
     enum Feature {
         ScrollPosition,
@@ -118,6 +123,10 @@ private:
     };
 
     Vector<AnimatableFeature, 1> m_animatableFeatures;
+    bool m_canCreateStackingContext { false };
+    bool m_canCreateStackingContextOnInline { false };
+    bool m_canTriggerCompositing { false };
+    bool m_canTriggerCompositingOnInline { false };
 };
 
 
index 0f8109a..17f479c 100644 (file)
@@ -1,3 +1,19 @@
+2015-08-17  Simon Fraser  <simon.fraser@apple.com>
+
+        will-change should sometimes trigger compositing
+        https://bugs.webkit.org/show_bug.cgi?id=148072
+
+        Reviewed by Tim Horton.
+        
+        Have the web inspector show a correct compositing reason for will-change.
+        This could be improved to indicate which specific value in will-change triggered
+        the compositing.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Views/LayerTreeDetailsSidebarPanel.js:
+        (WebInspector.LayerTreeDetailsSidebarPanel.prototype._populateListOfCompositingReasons):
+        (WebInspector.LayerTreeDetailsSidebarPanel):
+
 2015-08-14  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: NavigationBar.updateLayoutSoon should use requestAnimationFrame
index 7a90a95..88ff4bf 100644 (file)
Binary files a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js and b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js differ
index b4c91f8..fbe4e8b 100644 (file)
@@ -429,6 +429,8 @@ WebInspector.LayerTreeDetailsSidebarPanel = class LayerTreeDetailsSidebarPanel e
             addReason(WebInspector.UIString("Element has perspective applied"));
         if (compositingReasons.preserve3D)
             addReason(WebInspector.UIString("Element has “transform-style: preserve-3d” style"));
+        if (compositingReasons.willChange)
+            addReason(WebInspector.UIString("Element has “will-change” style with includes opacity, transform, transform-style, perspective, filter or backdrop-filter"));
         if (compositingReasons.root)
             addReason(WebInspector.UIString("Element is the root element"));
         if (compositingReasons.blending)