Title: [186155] trunk/Source
Revision
186155
Author
[email protected]
Date
2015-06-30 18:08:41 -0700 (Tue, 30 Jun 2015)

Log Message

[iOS] Missing tiles inside position:fixed on scrolling
https://bugs.webkit.org/show_bug.cgi?id=146485
rdar://problem/21226861

Reviewed by Tim Horton.

Layer flushing adjusts the coverage rect for tiled layers, but does so at times
when position:fixed layers are moved around by the scrolling tree. The computed
coverage rect then doesn't reflect the layer's on-screen position, causing missing
tiles.

Fix by pushing the notion of being in a "stable state" onto FrameView, and passing
that state into the layer flush. When not in a stable state, flushing doesn't change
the visible and coverage rects for layers that are viewport-constrained.

Source/WebCore:

* page/FrameView.cpp:
(WebCore::FrameView::reset):
* page/FrameView.h: Remove some velocity-related data members that were unused.
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::flushCompositingState):
(WebCore::GraphicsLayer::flushCompositingStateForThisLayerOnly):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::flushCompositingState):
(WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly):
(WebCore::GraphicsLayerCA::setVisibleAndCoverageRects): If this is a viewport-constrained
layer, and the viewport is not stable, don't touch the rects.
(WebCore::GraphicsLayerCA::recursiveCommitChanges):
* platform/graphics/ca/GraphicsLayerCA.h:
(WebCore::GraphicsLayerCA::CommitState::CommitState):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::flushPendingLayerChanges):

Source/WebKit2:

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::updateVisibleContentRects):
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::flushLayers):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (186154 => 186155)


--- trunk/Source/WebCore/ChangeLog	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/ChangeLog	2015-07-01 01:08:41 UTC (rev 186155)
@@ -1,5 +1,39 @@
 2015-06-30  Simon Fraser  <[email protected]>
 
+        [iOS] Missing tiles inside position:fixed on scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=146485
+        rdar://problem/21226861
+
+        Reviewed by Tim Horton.
+
+        Layer flushing adjusts the coverage rect for tiled layers, but does so at times
+        when position:fixed layers are moved around by the scrolling tree. The computed
+        coverage rect then doesn't reflect the layer's on-screen position, causing missing
+        tiles.
+
+        Fix by pushing the notion of being in a "stable state" onto FrameView, and passing
+        that state into the layer flush. When not in a stable state, flushing doesn't change
+        the visible and coverage rects for layers that are viewport-constrained.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::reset):
+        * page/FrameView.h: Remove some velocity-related data members that were unused.
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::flushCompositingState):
+        (WebCore::GraphicsLayer::flushCompositingStateForThisLayerOnly):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::flushCompositingState):
+        (WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly):
+        (WebCore::GraphicsLayerCA::setVisibleAndCoverageRects): If this is a viewport-constrained
+        layer, and the viewport is not stable, don't touch the rects.
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges):
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        (WebCore::GraphicsLayerCA::CommitState::CommitState):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::flushPendingLayerChanges):
+
+2015-06-30  Simon Fraser  <[email protected]>
+
         Rename GraphicsLayer's allowsBackingStoreDetachment to isViewportConstrained
         https://bugs.webkit.org/show_bug.cgi?id=146483
 

Modified: trunk/Source/WebCore/page/FrameView.cpp (186154 => 186155)


--- trunk/Source/WebCore/page/FrameView.cpp	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/page/FrameView.cpp	2015-07-01 01:08:41 UTC (rev 186155)
@@ -188,10 +188,6 @@
 #if PLATFORM(IOS)
     , m_useCustomFixedPositionLayoutRect(false)
     , m_useCustomSizeForResizeEvent(false)
-    , m_horizontalVelocity(0)
-    , m_verticalVelocity(0)
-    , m_scaleChangeRate(0)
-    , m_lastVelocityUpdateTime(0)
 #endif
     , m_hasOverrideViewportSize(false)
     , m_shouldAutoSize(false)
@@ -290,6 +286,7 @@
     m_visuallyNonEmptyPixelCount = 0;
     m_isVisuallyNonEmpty = false;
     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
+    m_viewportIsStable = true;
     m_maintainScrollPositionAnchor = nullptr;
 }
 

Modified: trunk/Source/WebCore/page/FrameView.h (186154 => 186155)


--- trunk/Source/WebCore/page/FrameView.h	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/page/FrameView.h	2015-07-01 01:08:41 UTC (rev 186155)
@@ -129,6 +129,9 @@
 
     WEBCORE_EXPORT bool renderedCharactersExceed(unsigned threshold);
 
+    WEBCORE_EXPORT void setViewportIsStable(bool stable) { m_viewportIsStable = stable; }
+    bool viewportIsStable() const { return m_viewportIsStable; }
+
 #if PLATFORM(IOS)
     bool useCustomFixedPositionLayoutRect() const { return m_useCustomFixedPositionLayoutRect; }
     IntRect customFixedPositionLayoutRect() const { return m_customFixedPositionLayoutRect; }
@@ -743,6 +746,8 @@
     bool m_isVisuallyNonEmpty;
     bool m_firstVisuallyNonEmptyLayoutCallbackPending;
 
+    bool m_viewportIsStable { true };
+
     RefPtr<ContainerNode> m_maintainScrollPositionAnchor;
 
     // Renderer to hold our custom scroll corner.
@@ -757,11 +762,6 @@
 
     bool m_useCustomSizeForResizeEvent;
     IntSize m_customSizeForResizeEvent;
-
-    double m_horizontalVelocity;
-    double m_verticalVelocity;
-    double m_scaleChangeRate;
-    double m_lastVelocityUpdateTime;
 #endif
 
     IntSize m_overrideViewportSize;

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (186154 => 186155)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2015-07-01 01:08:41 UTC (rev 186155)
@@ -504,8 +504,8 @@
     // Some compositing systems may do internal batching to synchronize compositing updates
     // with updates drawn into the window. These methods flush internal batched state on this layer
     // and descendant layers, and this layer only.
-    virtual void flushCompositingState(const FloatRect& /* clipRect */) { }
-    virtual void flushCompositingStateForThisLayerOnly() { }
+    virtual void flushCompositingState(const FloatRect& /* clipRect */, bool /* viewportIsStable */) { }
+    virtual void flushCompositingStateForThisLayerOnly(bool /* viewportIsStable */) { }
 
     // If the exposed rect of this layer changes, returns true if this or descendant layers need a flush,
     // for example to allocate new tiles.

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (186154 => 186155)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2015-07-01 01:08:41 UTC (rev 186155)
@@ -1092,20 +1092,20 @@
     return FloatPoint();
 }
 
-void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect)
+void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect, bool viewportIsStable)
 {
     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
     FloatQuad coverageQuad(clipRect);
     state.setSecondaryQuad(&coverageQuad);
-    recursiveCommitChanges(CommitState(), state);
+    recursiveCommitChanges(CommitState(viewportIsStable), state);
 }
 
-void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
+void GraphicsLayerCA::flushCompositingStateForThisLayerOnly(bool viewportIsStable)
 {
     float pageScaleFactor;
     bool hadChanges = m_uncommittedChanges;
     
-    CommitState commitState;
+    CommitState commitState(viewportIsStable);
 
     FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
     commitLayerChangesBeforeSublayers(commitState, pageScaleFactor, offset);
@@ -1272,13 +1272,16 @@
     return true;
 }
 
-void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool isViewportConstrained)
+void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool isViewportConstrained, bool viewportIsStable)
 {
     bool visibleRectChanged = rects.visibleRect != m_visibleRect;
     bool coverageRectChanged = rects.coverageRect != m_coverageRect;
     if (!visibleRectChanged && !coverageRectChanged)
         return;
 
+    if (isViewportConstrained && !viewportIsStable)
+        return;
+
     // FIXME: we need to take reflections into account when determining whether this layer intersects the coverage rect.
     bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(FloatRect(m_boundsOrigin, size()));
     if (intersectsCoverageRect != m_intersectsCoverageRect) {
@@ -1329,7 +1332,7 @@
             localState.setLastPlanarSecondaryQuad(&secondaryQuad);
         }
     }
-    setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained);
+    setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained, commitState.viewportIsStable);
 
 #ifdef VISIBLE_TILE_WASH
     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (186154 => 186155)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2015-07-01 01:08:41 UTC (rev 186155)
@@ -152,11 +152,17 @@
         int treeDepth { 0 };
         bool ancestorHasTransformAnimation { false };
         bool ancestorIsViewportConstrained { false };
+        bool viewportIsStable { true };
+        
+        CommitState(bool stableViewport)
+            : viewportIsStable(stableViewport)
+        {
+        }
     };
     void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
 
-    WEBCORE_EXPORT virtual void flushCompositingState(const FloatRect&) override;
-    WEBCORE_EXPORT virtual void flushCompositingStateForThisLayerOnly() override;
+    WEBCORE_EXPORT virtual void flushCompositingState(const FloatRect&, bool viewportIsStable) override;
+    WEBCORE_EXPORT virtual void flushCompositingStateForThisLayerOnly(bool viewportIsStable) override;
 
     WEBCORE_EXPORT virtual bool visibleRectChangeRequiresFlush(const FloatRect& visibleRect) const override;
 
@@ -294,7 +300,7 @@
     const FloatRect& visibleRect() const { return m_visibleRect; }
     const FloatRect& coverageRect() const { return m_coverageRect; }
 
-    void setVisibleAndCoverageRects(const VisibleAndCoverageRects&, bool isViewportConstrained);
+    void setVisibleAndCoverageRects(const VisibleAndCoverageRects&, bool isViewportConstrained, bool viewportIsStable);
     
     static FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize);
 

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (186154 => 186155)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2015-07-01 01:08:41 UTC (rev 186155)
@@ -468,18 +468,18 @@
     if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
 #if PLATFORM(IOS)
         FloatRect exposedRect = frameView.exposedContentRect();
-        LOG(Compositing, "RenderLayerCompositor %p flushPendingLayerChanges(%d) %.2f, %.2f, %.2fx%.2f", this, isFlushRoot,
-            exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height());
-        rootLayer->flushCompositingState(exposedRect);
+        LOG(Compositing, "RenderLayerCompositor %p flushPendingLayerChanges(%d) %.2f, %.2f, %.2fx%.2f (stable viewport %d)", this, isFlushRoot,
+            exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height(), frameView.viewportIsStable());
+        rootLayer->flushCompositingState(exposedRect, frameView.viewportIsStable());
 #else
         // Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
         IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView.unscaledVisibleContentSizeIncludingObscuredArea()) : frameView.visibleContentRect();
         if (!frameView.exposedRect().isInfinite())
             visibleRect.intersect(IntRect(frameView.exposedRect()));
 
-        LOG(Compositing, "RenderLayerCompositor %p flushPendingLayerChanges(%d) %d, %d, %dx%d", this, isFlushRoot,
-            visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height());
-        rootLayer->flushCompositingState(visibleRect);
+        LOG(Compositing, "RenderLayerCompositor %p flushPendingLayerChanges(%d) %d, %d, %dx%d (stable viewport %d)", this, isFlushRoot,
+            visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height(), frameView.viewportIsStable());
+        rootLayer->flushCompositingState(visibleRect, frameView.viewportIsStable());
 #endif
     }
     

Modified: trunk/Source/WebKit2/ChangeLog (186154 => 186155)


--- trunk/Source/WebKit2/ChangeLog	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebKit2/ChangeLog	2015-07-01 01:08:41 UTC (rev 186155)
@@ -1,3 +1,25 @@
+2015-06-30  Simon Fraser  <[email protected]>
+
+        [iOS] Missing tiles inside position:fixed on scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=146485
+        rdar://problem/21226861
+
+        Reviewed by Tim Horton.
+
+        Layer flushing adjusts the coverage rect for tiled layers, but does so at times
+        when position:fixed layers are moved around by the scrolling tree. The computed
+        coverage rect then doesn't reflect the layer's on-screen position, causing missing
+        tiles.
+
+        Fix by pushing the notion of being in a "stable state" onto FrameView, and passing
+        that state into the layer flush. When not in a stable state, flushing doesn't change
+        the visible and coverage rects for layers that are viewport-constrained.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::updateVisibleContentRects):
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::flushLayers):
+
 2015-06-30  Hyungwook Lee  <[email protected]>
 
         [EFL] Implement ewk_favicon_database_clear() API.

Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (186154 => 186155)


--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2015-07-01 01:08:41 UTC (rev 186155)
@@ -2870,6 +2870,7 @@
     double scaleChangeRate = visibleContentRectUpdateInfo.scaleChangeRate();
     adjustVelocityDataForBoundedScale(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.scale(), m_viewportConfiguration.minimumScale(), m_viewportConfiguration.maximumScale());
 
+    frameView.setViewportIsStable(m_isInStableState);
     frameView.setScrollVelocity(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.timestamp());
 
     if (m_isInStableState)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (186154 => 186155)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2015-07-01 01:01:13 UTC (rev 186154)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2015-07-01 01:08:41 UTC (rev 186155)
@@ -371,9 +371,9 @@
 
     // Because our view-relative overlay root layer is not attached to the FrameView's GraphicsLayer tree, we need to flush it manually.
     if (m_viewOverlayRootLayer)
-        m_viewOverlayRootLayer->flushCompositingState(visibleRect);
+        m_viewOverlayRootLayer->flushCompositingState(visibleRect, m_webPage.mainFrameView()->viewportIsStable());
 
-    m_rootLayer->flushCompositingStateForThisLayerOnly();
+    m_rootLayer->flushCompositingStateForThisLayerOnly(m_webPage.mainFrameView()->viewportIsStable());
 
     // FIXME: Minimize these transactions if nothing changed.
     RemoteLayerTreeTransaction layerTransaction;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to