[iOS WK2] Don't create backing store for -webkit-overflow-scrolling:touch that can...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 May 2014 21:24:54 +0000 (21:24 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 May 2014 21:24:54 +0000 (21:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=132487
<rdar://problem/16758041>

Reviewed by Sam Weinig.

Source/WebCore:

Previously, -webkit-overflow-scrolling:touch would cause us to make compositing
layers for any element that had overflow: auto or scroll on either axis. This
created lots of backing store when not required.

Improve this to only create compositing for scrolling when there is actually
scrollable overflow. This makes things slightly more complex, because we can
only know when layout is up to date.

* rendering/RenderBox.cpp:
(WebCore::RenderBox::computeRectForRepaint): usesCompositedScrolling() tells
us if we're actually doing composited overflow.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hasTouchScrollableOverflow):
(WebCore::RenderLayer::handleTouchEvent):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::layerOrAncestorIsTransformedOrUsingCompositedScrolling):
(WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Only update
scrolling and clipping layers if layout is not pending.
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
(WebCore::RenderLayerBacking::updateScrollingLayers): The caller calls
updateInternalHierarchy(), so no need to do it here.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingForScrolling): We
can only determine that we're scrollable after layout.
(WebCore::isStickyInAcceleratedScrollingLayerOrViewport):
(WebCore::isMainFrameScrollingOrOverflowScrolling):

LayoutTests:

These are all progressions, and show that we make layers in fewer cases.

* platform/ios-sim/compositing/overflow/iframe-inside-overflow-clipping-expected.txt:
* platform/ios-sim/compositing/overflow/overflow-auto-with-touch-no-overflow-expected.txt:
* platform/ios-sim/compositing/overflow/overflow-overlay-with-touch-no-overflow-expected.txt:
* platform/ios-sim/compositing/overflow/overflow-scroll-with-touch-no-overflow-expected.txt:
* platform/ios-sim/compositing/overflow/subpixel-overflow-expected.txt:

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/ios-sim/compositing/overflow/iframe-inside-overflow-clipping-expected.txt
LayoutTests/platform/ios-sim/compositing/overflow/overflow-auto-with-touch-no-overflow-expected.txt
LayoutTests/platform/ios-sim/compositing/overflow/overflow-overlay-with-touch-no-overflow-expected.txt
LayoutTests/platform/ios-sim/compositing/overflow/overflow-scroll-with-touch-no-overflow-expected.txt
LayoutTests/platform/ios-sim/compositing/overflow/subpixel-overflow-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp

index a4db758..5d2904e 100644 (file)
@@ -1,3 +1,19 @@
+2014-05-02  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Don't create backing store for -webkit-overflow-scrolling:touch that can't scroll
+        https://bugs.webkit.org/show_bug.cgi?id=132487
+        <rdar://problem/16758041>
+
+        Reviewed by Sam Weinig.
+        
+        These are all progressions, and show that we make layers in fewer cases.
+
+        * platform/ios-sim/compositing/overflow/iframe-inside-overflow-clipping-expected.txt:
+        * platform/ios-sim/compositing/overflow/overflow-auto-with-touch-no-overflow-expected.txt:
+        * platform/ios-sim/compositing/overflow/overflow-overlay-with-touch-no-overflow-expected.txt:
+        * platform/ios-sim/compositing/overflow/overflow-scroll-with-touch-no-overflow-expected.txt:
+        * platform/ios-sim/compositing/overflow/subpixel-overflow-expected.txt:
+
 2014-05-02  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r168150.
index 85e4177..8b13789 100644 (file)
@@ -1,26 +1 @@
-(GraphicsLayer
-  (bounds 800.00 600.00)
-  (children 1
-    (GraphicsLayer
-      (bounds 800.00 600.00)
-      (children 1
-        (GraphicsLayer
-          (position 8.00 8.00)
-          (bounds 300.00 300.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 300.00 300.00)
-              (children 1
-                (GraphicsLayer
-                  (bounds 300.00 300.00)
-                  (drawsContent 1)
-                )
-              )
-            )
-          )
-        )
-      )
-    )
-  )
-)
 
index 85e4177..8b13789 100644 (file)
@@ -1,26 +1 @@
-(GraphicsLayer
-  (bounds 800.00 600.00)
-  (children 1
-    (GraphicsLayer
-      (bounds 800.00 600.00)
-      (children 1
-        (GraphicsLayer
-          (position 8.00 8.00)
-          (bounds 300.00 300.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 300.00 300.00)
-              (children 1
-                (GraphicsLayer
-                  (bounds 300.00 300.00)
-                  (drawsContent 1)
-                )
-              )
-            )
-          )
-        )
-      )
-    )
-  )
-)
 
index 85e4177..8b13789 100644 (file)
@@ -1,26 +1 @@
-(GraphicsLayer
-  (bounds 800.00 600.00)
-  (children 1
-    (GraphicsLayer
-      (bounds 800.00 600.00)
-      (children 1
-        (GraphicsLayer
-          (position 8.00 8.00)
-          (bounds 300.00 300.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 300.00 300.00)
-              (children 1
-                (GraphicsLayer
-                  (bounds 300.00 300.00)
-                  (drawsContent 1)
-                )
-              )
-            )
-          )
-        )
-      )
-    )
-  )
-)
 
index 9a0dc7f..40ba98a 100644 (file)
@@ -3,65 +3,4 @@ Content
 Content
  
 Content
- (GraphicsLayer
-  (bounds 800.00 600.00)
-  (children 1
-    (GraphicsLayer
-      (bounds 800.00 600.00)
-      (children 3
-        (GraphicsLayer
-          (position 18.00 18.00)
-          (bounds 202.00 202.50)
-          (drawsContent 1)
-          (children 1
-            (GraphicsLayer
-              (position 1.00 1.00)
-              (bounds 200.00 200.00)
-              (children 1
-                (GraphicsLayer
-                  (bounds 200.00 200.00)
-                  (drawsContent 1)
-                )
-              )
-            )
-          )
-        )
-        (GraphicsLayer
-          (position 244.00 18.00)
-          (bounds 202.00 202.50)
-          (drawsContent 1)
-          (children 1
-            (GraphicsLayer
-              (position 1.00 1.00)
-              (bounds 200.00 201.00)
-              (children 1
-                (GraphicsLayer
-                  (bounds 200.00 201.00)
-                  (drawsContent 1)
-                )
-              )
-            )
-          )
-        )
-        (GraphicsLayer
-          (position 470.00 18.00)
-          (bounds 202.00 203.00)
-          (drawsContent 1)
-          (children 1
-            (GraphicsLayer
-              (position 1.00 1.00)
-              (bounds 200.00 201.00)
-              (children 1
-                (GraphicsLayer
-                  (bounds 200.00 201.00)
-                  (drawsContent 1)
-                )
-              )
-            )
-          )
-        )
-      )
-    )
-  )
-)
 
index b7af8b8..45bfc46 100644 (file)
@@ -1,3 +1,39 @@
+2014-05-02  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Don't create backing store for -webkit-overflow-scrolling:touch that can't scroll
+        https://bugs.webkit.org/show_bug.cgi?id=132487
+        <rdar://problem/16758041>
+
+        Reviewed by Sam Weinig.
+
+        Previously, -webkit-overflow-scrolling:touch would cause us to make compositing
+        layers for any element that had overflow: auto or scroll on either axis. This
+        created lots of backing store when not required.
+        
+        Improve this to only create compositing for scrolling when there is actually
+        scrollable overflow. This makes things slightly more complex, because we can
+        only know when layout is up to date.
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::computeRectForRepaint): usesCompositedScrolling() tells
+        us if we're actually doing composited overflow.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hasTouchScrollableOverflow):
+        (WebCore::RenderLayer::handleTouchEvent):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::layerOrAncestorIsTransformedOrUsingCompositedScrolling):
+        (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Only update
+        scrolling and clipping layers if layout is not pending.
+        (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+        (WebCore::RenderLayerBacking::updateScrollingLayers): The caller calls
+        updateInternalHierarchy(), so no need to do it here.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::requiresCompositingForScrolling): We
+        can only determine that we're scrollable after layout.
+        (WebCore::isStickyInAcceleratedScrollingLayerOrViewport):
+        (WebCore::isMainFrameScrollingOrOverflowScrolling):
+
 2014-05-02  Anders Carlsson  <andersca@apple.com>
 
         Clean up FormDataElement
index 5dea106..e5e4742 100644 (file)
@@ -2176,7 +2176,7 @@ void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintConta
     if (o->hasOverflowClip()) {
         RenderBox* containerBox = toRenderBox(o);
 #if PLATFORM(IOS)
-        if (!containerBox->layer() || !containerBox->layer()->hasAcceleratedTouchScrolling()) {
+        if (!containerBox->layer() || !containerBox->layer()->usesCompositedScrolling()) {
 #endif
         containerBox->applyCachedClipAndScrollOffsetForRepaint(rect);
         if (rect.isEmpty())
index 2df96c3..6f6992a 100644 (file)
@@ -2115,11 +2115,16 @@ bool RenderLayer::hasAcceleratedTouchScrolling() const
 #endif
 }
 
-#if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
+bool RenderLayer::hasTouchScrollableOverflow() const
+{
+    return hasAcceleratedTouchScrolling() && (hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
+}
+
+#if ENABLE(TOUCH_EVENTS)
 bool RenderLayer::handleTouchEvent(const PlatformTouchEvent& touchEvent)
 {
     // If we have accelerated scrolling, let the scrolling be handled outside of WebKit.
-    if (hasAcceleratedTouchScrolling())
+    if (hasTouchScrollableOverflow())
         return false;
 
     return ScrollableArea::handleTouchEvent(touchEvent);
index 992256a..fc59177 100644 (file)
@@ -460,6 +460,8 @@ public:
 
     // Returns true when the layer could do touch scrolling, but doesn't look at whether there is actually scrollable overflow.
     bool hasAcceleratedTouchScrolling() const;
+    // Returns true when there is actually scrollable overflow (requires layout to be up-to-date).
+    bool hasTouchScrollableOverflow() const;
 #endif
 
     int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
index b99703c..436b16c 100644 (file)
@@ -406,7 +406,7 @@ static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer&
     for (RenderLayer* curr = &layer; curr; curr = curr->parent()) {
         if (curr->hasTransform()
 #if PLATFORM(IOS)
-            || curr->hasAcceleratedTouchScrolling()
+            || curr->hasTouchScrollableOverflow()
 #else
             || curr->needsCompositedScrolling()
 #endif
@@ -536,29 +536,31 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
         layerConfigChanged = true;
     
     bool needsDescendentsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
-    bool usesCompositedScrolling;
+
+    if (!renderer().view().needsLayout()) {
+        bool usesCompositedScrolling;
 #if PLATFORM(IOS)
-    usesCompositedScrolling = m_owningLayer.hasAcceleratedTouchScrolling();
+        usesCompositedScrolling = m_owningLayer.hasTouchScrollableOverflow();
 #else
-    usesCompositedScrolling = m_owningLayer.needsCompositedScrolling();
+        usesCompositedScrolling = m_owningLayer.needsCompositedScrolling();
 #endif
+        // Our scrolling layer will clip.
+        if (usesCompositedScrolling)
+            needsDescendentsClippingLayer = false;
 
-    // Our scrolling layer will clip.
-    if (usesCompositedScrolling)
-        needsDescendentsClippingLayer = false;
+        if (updateScrollingLayers(usesCompositedScrolling))
+            layerConfigChanged = true;
 
-    if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
-        layerConfigChanged = true;
+        if (updateDescendantClippingLayer(needsDescendentsClippingLayer))
+            layerConfigChanged = true;
+    }
 
-    if (updateDescendantClippingLayer(needsDescendentsClippingLayer))
+    if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
         layerConfigChanged = true;
 
     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
         layerConfigChanged = true;
 
-    if (updateScrollingLayers(usesCompositedScrolling))
-        layerConfigChanged = true;
-
     if (layerConfigChanged)
         updateInternalHierarchy();
 
@@ -752,7 +754,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
         graphicsLayerParentLocation = renderer().view().documentRect().location();
 
 #if PLATFORM(IOS)
-    if (compAncestor && compAncestor->hasAcceleratedTouchScrolling()) {
+    if (compAncestor && compAncestor->hasTouchScrollableOverflow()) {
         RenderBox* renderBox = toRenderBox(&compAncestor->renderer());
         LayoutRect paddingBox(renderBox->borderLeft(), renderBox->borderTop(),
             renderBox->width() - renderBox->borderLeft() - renderBox->borderRight(),
@@ -1440,7 +1442,6 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
         m_scrollingContentsLayer = nullptr;
     }
 
-    updateInternalHierarchy();
     m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
     m_graphicsLayer->setNeedsDisplay(); // Because painting phases changed.
 
index 3a976bb..a554ea9 100644 (file)
@@ -2476,7 +2476,15 @@ bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerMode
 #if PLATFORM(IOS)
 bool RenderLayerCompositor::requiresCompositingForScrolling(const RenderLayer& layer) const
 {
-    return layer.hasAcceleratedTouchScrolling();
+    if (!layer.hasAcceleratedTouchScrolling())
+        return false;
+
+    if (!m_inPostLayoutUpdate) {
+        m_reevaluateCompositingAfterLayout = true;
+        return layer.isComposited();
+    }
+
+    return layer.hasTouchScrollableOverflow();
 }
 #endif
 
@@ -2499,7 +2507,7 @@ static bool isStickyInAcceleratedScrollingLayerOrViewport(const RenderLayer& lay
     ASSERT(layer.renderer().isStickyPositioned());
 
     RenderLayer* enclosingOverflowLayer = layer.enclosingOverflowClipLayer(ExcludeSelf);
-    if (enclosingOverflowLayer && enclosingOverflowLayer->hasAcceleratedTouchScrolling()) {
+    if (enclosingOverflowLayer && enclosingOverflowLayer->hasTouchScrollableOverflow()) {
         if (enclosingAcceleratedOverflowLayer)
             *enclosingAcceleratedOverflowLayer = enclosingOverflowLayer;
         return true;
@@ -2537,7 +2545,7 @@ static bool isMainFrameScrollingOrOverflowScrolling(RenderView& view, const Rend
         return true;
 
 #if PLATFORM(IOS)
-    return layer.hasAcceleratedTouchScrolling();
+    return layer.hasTouchScrollableOverflow();
 #else
     return layer.needsCompositedScrolling();
 #endif