Cordova: elements with tag position:fixed disappears (flickering) when a long content...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Nov 2017 05:27:22 +0000 (05:27 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Nov 2017 05:27:22 +0000 (05:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178066

Reviewed by Tim Horton.

In UIWebView, we were failing to call setIsViewportConstrained() on layers for position:fixed,
causing us to detach their backing store sometimes on page scrolling.

Fix by hoisting the call to RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole()
up the stack into code that runs for both UIWebView and WKWebView. This required moving some of
the sanity check code up out of updateScrollCoordinatedLayer() into the caller.

Not testable because the bug only manifested in UIWebView.

* rendering/RenderLayerCompositor.cpp:
(WebCore::canCoordinateScrollingForLayer):
(WebCore::RenderLayerCompositor::updateScrollCoordinatedStatus):
(WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayerCompositor.cpp

index 7978783..3e5b4cc 100644 (file)
@@ -1,3 +1,24 @@
+2017-11-08  Simon Fraser  <simon.fraser@apple.com>
+
+        Cordova: elements with tag position:fixed disappears (flickering) when a long content is scrolling and appears again when the scroll is finished.
+        https://bugs.webkit.org/show_bug.cgi?id=178066
+
+        Reviewed by Tim Horton.
+
+        In UIWebView, we were failing to call setIsViewportConstrained() on layers for position:fixed,
+        causing us to detach their backing store sometimes on page scrolling.
+        
+        Fix by hoisting the call to RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole()
+        up the stack into code that runs for both UIWebView and WKWebView. This required moving some of
+        the sanity check code up out of updateScrollCoordinatedLayer() into the caller.
+
+        Not testable because the bug only manifested in UIWebView.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::canCoordinateScrollingForLayer):
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedStatus):
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):
+
 2017-11-08  Zalan Bujtas  <zalan@apple.com>
 
         [LayoutState cleanup] Move RenderMultiColumnFlow::computeLineGridPaginationOrigin to LayoutState
index 18bd410..eeb9eaa 100644 (file)
@@ -3506,6 +3506,11 @@ void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
         rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
 }
 
+static bool canCoordinateScrollingForLayer(const RenderLayer& layer)
+{
+    return (layer.isRenderViewLayer() || layer.parent()) && layer.isComposited();
+}
+
 void RenderLayerCompositor::updateScrollCoordinatedStatus(RenderLayer& layer, OptionSet<ScrollingNodeChangeFlags> changes)
 {
     LayerScrollCoordinationRoles coordinationRoles = 0;
@@ -3515,7 +3520,10 @@ void RenderLayerCompositor::updateScrollCoordinatedStatus(RenderLayer& layer, Op
     if (useCoordinatedScrollingForLayer(layer))
         coordinationRoles |= Scrolling;
 
-    if (coordinationRoles) {
+    if (layer.isComposited())
+        layer.backing()->setIsScrollCoordinatedWithViewportConstrainedRole(coordinationRoles & ViewportConstrained);
+
+    if (coordinationRoles && canCoordinateScrollingForLayer(layer)) {
         if (m_scrollCoordinatedLayers.add(&layer).isNewEntry)
             m_subframeScrollLayersNeedReattach = true;
 
@@ -3721,20 +3729,13 @@ void RenderLayerCompositor::updateScrollCoordinationForThisFrame(ScrollingNodeID
 
 void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, LayerScrollCoordinationRoles reasons, OptionSet<ScrollingNodeChangeFlags> changes)
 {
-    auto* scrollingCoordinator = this->scrollingCoordinator();
-    if (!scrollingCoordinator || !scrollingCoordinator->coordinatesScrollingForFrameView(m_renderView.frameView()))
-        return;
-
     bool isRenderViewLayer = layer.isRenderViewLayer();
 
-    if (!layer.parent() && !isRenderViewLayer)
-        return;
-
     ASSERT(m_scrollCoordinatedLayers.contains(&layer));
     ASSERT(layer.isComposited());
 
-    auto* backing = layer.backing();
-    if (!backing)
+    auto* scrollingCoordinator = this->scrollingCoordinator();
+    if (!scrollingCoordinator || !scrollingCoordinator->coordinatesScrollingForFrameView(m_renderView.frameView()))
         return;
 
     if (!m_renderView.frame().isMainFrame()) {
@@ -3751,6 +3752,8 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Lay
     if (!parentNodeID && !isRenderViewLayer)
         return;
 
+    auto* backing = layer.backing();
+
     // Always call this even if the backing is already attached because the parent may have changed.
     // If a node plays both roles, fixed/sticky is always the ancestor node of scrolling.
     if (reasons & ViewportConstrained) {