Title: [166380] trunk/Source
Revision
166380
Author
[email protected]
Date
2014-03-27 16:22:55 -0700 (Thu, 27 Mar 2014)

Log Message

[iOS][WK2] Compute a good exposed rect when scaling WKContentView
https://bugs.webkit.org/show_bug.cgi?id=130761

Patch by Benjamin Poulain <[email protected]> on 2014-03-27
Reviewed by Simon Fraser.

Source/WebCore: 

* WebCore.exp.in:
* platform/ScrollView.h:
* platform/ios/ScrollViewIOS.mm:
(WebCore::ScrollView::setScrollVelocity):
(WebCore::ScrollView::computeCoverageRect):
While scaling in, do not add margins tiles. When scaling out, add 1 margin tile size
all around.

Source/WebKit2: 

Add a simple heuristic to improve tiling while zooming. In theory we could take the zoom
center and scaleRate to split the speed between scrolling and pinching. In practice,
zoom is transitory and is not as predictable as scrolling, so this patch just does a very
simple heuristic:
-When zooming in, do not expand coverage.
-When zooming out, add half a tile size on every side.

* Shared/VisibleContentRectUpdateInfo.cpp:
(WebKit::VisibleContentRectUpdateInfo::encode):
(WebKit::VisibleContentRectUpdateInfo::decode):
* Shared/VisibleContentRectUpdateInfo.h:
(WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
(WebKit::VisibleContentRectUpdateInfo::timestamp):
(WebKit::VisibleContentRectUpdateInfo::horizontalVelocity):
(WebKit::VisibleContentRectUpdateInfo::verticalVelocity):
(WebKit::VisibleContentRectUpdateInfo::scaleChangeRate):
* UIProcess/ios/WKContentView.mm:
(WebKit::HistoricalVelocityData::VelocityData::VelocityData):
(WebKit::HistoricalVelocityData::velocityForNewData):
(WebKit::HistoricalVelocityData::append):
(-[WKContentView didUpdateVisibleRect:unobscuredRect:scale:inStableState:]):
* WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::adjustExposedRectForBoundedScale):
When zooming past the maximum size, adjust the exposed rect to continue tiling the area
at maximum size. Otherwise, we tile a tiny area, and have to retile larger when the animation
pull back the view to maximum scale.

(WebKit::adjustVelocityDataForBoundedScale):
Since we do not split the velocity from scrolling from the scaling, just clear the velocity when zooming.
Also clear the scaleChangeRate when the scale is out of bounds. There is no reason to add tiles for
temporary state.

(WebKit::WebPage::updateVisibleContentRects):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (166379 => 166380)


--- trunk/Source/WebCore/ChangeLog	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebCore/ChangeLog	2014-03-27 23:22:55 UTC (rev 166380)
@@ -1,3 +1,18 @@
+2014-03-27  Benjamin Poulain  <[email protected]>
+
+        [iOS][WK2] Compute a good exposed rect when scaling WKContentView
+        https://bugs.webkit.org/show_bug.cgi?id=130761
+
+        Reviewed by Simon Fraser.
+
+        * WebCore.exp.in:
+        * platform/ScrollView.h:
+        * platform/ios/ScrollViewIOS.mm:
+        (WebCore::ScrollView::setScrollVelocity):
+        (WebCore::ScrollView::computeCoverageRect):
+        While scaling in, do not add margins tiles. When scaling out, add 1 margin tile size
+        all around.
+
 2014-03-27  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r166360.

Modified: trunk/Source/WebCore/WebCore.exp.in (166379 => 166380)


--- trunk/Source/WebCore/WebCore.exp.in	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebCore/WebCore.exp.in	2014-03-27 23:22:55 UTC (rev 166380)
@@ -2412,7 +2412,7 @@
 _WebUIApplicationWillResignActiveNotification
 __ZN7WebCore10FloatPointC1ERK7CGPoint
 __ZN7WebCore10ScrollView15setScrollOffsetERKNS_8IntPointE
-__ZN7WebCore10ScrollView17setScrollVelocityEddd
+__ZN7WebCore10ScrollView17setScrollVelocityEdddd
 __ZN7WebCore10ScrollView21setExposedContentRectERKNS_7IntRectE
 __ZN7WebCore10ScrollView24setUnobscuredContentRectERKNS_7IntRectE
 __ZN7WebCore10XLinkNames4initEv

Modified: trunk/Source/WebCore/platform/ScrollView.h (166379 => 166380)


--- trunk/Source/WebCore/platform/ScrollView.h	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebCore/platform/ScrollView.h	2014-03-27 23:22:55 UTC (rev 166380)
@@ -186,7 +186,7 @@
     void setExposedContentRect(const IntRect&);
     void setUnobscuredContentRect(const IntRect&);
 
-    void setScrollVelocity(double horizontalVelocity, double verticalVelocity, double timestamp);
+    void setScrollVelocity(double horizontalVelocity, double verticalVelocity, double scaleChangeRate, double timestamp);
     FloatRect computeCoverageRect(double horizontalMargin, double verticalMargin) const;
 
     void setActualScrollPosition(const IntPoint&);
@@ -420,6 +420,7 @@
 
     double m_horizontalVelocity;
     double m_verticalVelocity;
+    double m_scaleChangeRate;
     double m_lastVelocityUpdateTime;
 #else
     IntRect m_fixedVisibleContentRect;

Modified: trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm (166379 => 166380)


--- trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm	2014-03-27 23:22:55 UTC (rev 166380)
@@ -119,10 +119,11 @@
     m_unobscuredContentRect = rect;
 }
 
-void ScrollView::setScrollVelocity(double horizontalVelocity, double verticalVelocity, double timestamp)
+void ScrollView::setScrollVelocity(double horizontalVelocity, double verticalVelocity, double scaleChangeRate, double timestamp)
 {
     m_horizontalVelocity = horizontalVelocity;
     m_verticalVelocity = verticalVelocity;
+    m_scaleChangeRate = scaleChangeRate;
     m_lastVelocityUpdateTime = timestamp;
 }
 
@@ -148,7 +149,7 @@
             futureRect.setY(std::max(futureRect.y() - verticalMargin, 0.));
     }
 
-    if (!m_horizontalVelocity && !m_verticalVelocity) {
+    if (m_scaleChangeRate <= 0 && !m_horizontalVelocity && !m_verticalVelocity) {
         futureRect.setWidth(futureRect.width() + horizontalMargin);
         futureRect.setHeight(futureRect.height() + verticalMargin);
         futureRect.setX(std::max(futureRect.x() - horizontalMargin / 2, 0.));

Modified: trunk/Source/WebKit2/ChangeLog (166379 => 166380)


--- trunk/Source/WebKit2/ChangeLog	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebKit2/ChangeLog	2014-03-27 23:22:55 UTC (rev 166380)
@@ -1,3 +1,45 @@
+2014-03-27  Benjamin Poulain  <[email protected]>
+
+        [iOS][WK2] Compute a good exposed rect when scaling WKContentView
+        https://bugs.webkit.org/show_bug.cgi?id=130761
+
+        Reviewed by Simon Fraser.
+
+        Add a simple heuristic to improve tiling while zooming. In theory we could take the zoom
+        center and scaleRate to split the speed between scrolling and pinching. In practice,
+        zoom is transitory and is not as predictable as scrolling, so this patch just does a very
+        simple heuristic:
+        -When zooming in, do not expand coverage.
+        -When zooming out, add half a tile size on every side.
+
+        * Shared/VisibleContentRectUpdateInfo.cpp:
+        (WebKit::VisibleContentRectUpdateInfo::encode):
+        (WebKit::VisibleContentRectUpdateInfo::decode):
+        * Shared/VisibleContentRectUpdateInfo.h:
+        (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
+        (WebKit::VisibleContentRectUpdateInfo::timestamp):
+        (WebKit::VisibleContentRectUpdateInfo::horizontalVelocity):
+        (WebKit::VisibleContentRectUpdateInfo::verticalVelocity):
+        (WebKit::VisibleContentRectUpdateInfo::scaleChangeRate):
+        * UIProcess/ios/WKContentView.mm:
+        (WebKit::HistoricalVelocityData::VelocityData::VelocityData):
+        (WebKit::HistoricalVelocityData::velocityForNewData):
+        (WebKit::HistoricalVelocityData::append):
+        (-[WKContentView didUpdateVisibleRect:unobscuredRect:scale:inStableState:]):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+
+        (WebKit::adjustExposedRectForBoundedScale):
+        When zooming past the maximum size, adjust the exposed rect to continue tiling the area
+        at maximum size. Otherwise, we tile a tiny area, and have to retile larger when the animation
+        pull back the view to maximum scale.
+
+        (WebKit::adjustVelocityDataForBoundedScale):
+        Since we do not split the velocity from scrolling from the scaling, just clear the velocity when zooming.
+        Also clear the scaleChangeRate when the scale is out of bounds. There is no reason to add tiles for
+        temporary state.
+
+        (WebKit::WebPage::updateVisibleContentRects):
+
 2014-03-27  Anders Carlsson  <[email protected]>
 
         Add _ prefix to WKRemoteObjectRegistery and WKRemoteObjectInterface

Modified: trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp (166379 => 166380)


--- trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp	2014-03-27 23:22:55 UTC (rev 166380)
@@ -41,6 +41,7 @@
     encoder << m_timestamp;
     encoder << m_horizontalVelocity;
     encoder << m_verticalVelocity;
+    encoder << m_scaleChangeRate;
 }
 
 bool VisibleContentRectUpdateInfo::decode(IPC::ArgumentDecoder& decoder, VisibleContentRectUpdateInfo& result)
@@ -63,6 +64,8 @@
         return false;
     if (!decoder.decode(result.m_verticalVelocity))
         return false;
+    if (!decoder.decode(result.m_scaleChangeRate))
+        return false;
 
     return true;
 }

Modified: trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h (166379 => 166380)


--- trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h	2014-03-27 23:22:55 UTC (rev 166380)
@@ -44,7 +44,7 @@
     {
     }
 
-    VisibleContentRectUpdateInfo(uint64_t updateID, const WebCore::FloatRect& exposedRect, const WebCore::FloatRect& unobscuredRect, const WebCore::FloatRect& customFixedPositionRect, double scale, bool inStableState, double timestamp, double horizontalVelocity, double verticalVelocity)
+    VisibleContentRectUpdateInfo(uint64_t updateID, const WebCore::FloatRect& exposedRect, const WebCore::FloatRect& unobscuredRect, const WebCore::FloatRect& customFixedPositionRect, double scale, bool inStableState, double timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate)
         : m_exposedRect(exposedRect)
         , m_unobscuredRect(unobscuredRect)
         , m_customFixedPositionRect(customFixedPositionRect)
@@ -54,6 +54,7 @@
         , m_timestamp(timestamp)
         , m_horizontalVelocity(horizontalVelocity)
         , m_verticalVelocity(verticalVelocity)
+        , m_scaleChangeRate(scaleChangeRate)
     {
     }
 
@@ -64,6 +65,11 @@
     uint64_t updateID() const { return m_updateID; }
     bool inStableState() const { return m_inStableState; }
 
+    double timestamp() const { return m_timestamp; }
+    double horizontalVelocity() const { return m_horizontalVelocity; }
+    double verticalVelocity() const { return m_verticalVelocity; }
+    double scaleChangeRate() const { return m_scaleChangeRate; }
+
     void encode(IPC::ArgumentEncoder&) const;
     static bool decode(IPC::ArgumentDecoder&, VisibleContentRectUpdateInfo&);
 
@@ -74,10 +80,10 @@
     double m_scale;
     uint64_t m_updateID;
     bool m_inStableState;
-public:
     double m_timestamp;
     double m_horizontalVelocity;
     double m_verticalVelocity;
+    double m_scaleChangeRate;
 };
 
 inline bool operator==(const VisibleContentRectUpdateInfo& a, const VisibleContentRectUpdateInfo& b)

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (166379 => 166380)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2014-03-27 23:22:55 UTC (rev 166380)
@@ -65,6 +65,26 @@
 namespace WebKit {
 class HistoricalVelocityData {
 public:
+    struct VelocityData {
+        VelocityData()
+            : horizontalVelocity(0)
+            , verticalVelocity(0)
+            , scaleChangeRate(0)
+        {
+        }
+
+        VelocityData(double horizontalVelocity, double verticalVelocity, double scaleChangeRate)
+            : horizontalVelocity(horizontalVelocity)
+            , verticalVelocity(verticalVelocity)
+            , scaleChangeRate(scaleChangeRate)
+        {
+        }
+
+        double horizontalVelocity;
+        double verticalVelocity;
+        double scaleChangeRate;
+    };
+
     HistoricalVelocityData()
         : m_historySize(0)
         , m_latestDataIndex(0)
@@ -72,13 +92,13 @@
     {
     }
 
-    CGSize velocityForNewData(CGPoint newPosition, double timestamp)
+    VelocityData velocityForNewData(CGPoint newPosition, double scale, double timestamp)
     {
         // Due to all the source of rect update, the input is very noisy. To smooth the output, we accumulate all changes
         // within 1 frame as a single update. No speed computation is ever done on data within the same frame.
         const double filteringThreshold = 1 / 60.;
 
-        CGSize velocity = CGSizeZero;
+        VelocityData velocityData;
         if (m_historySize > 0) {
             unsigned oldestDataIndex;
             unsigned distanceToLastHistoricalData = m_historySize - 1;
@@ -88,25 +108,27 @@
                 oldestDataIndex = m_historySize - (distanceToLastHistoricalData - m_latestDataIndex);
 
             double timeDelta = timestamp - m_history[oldestDataIndex].timestamp;
-            if (timeDelta > filteringThreshold)
-                velocity =  CGSizeMake((newPosition.x - m_history[oldestDataIndex].position.x) / timeDelta, (newPosition.y - m_history[oldestDataIndex].position.y) / timeDelta);
+            if (timeDelta > filteringThreshold) {
+                Data& oldestData = m_history[oldestDataIndex];
+                velocityData = VelocityData((newPosition.x - oldestData.position.x) / timeDelta, (newPosition.y - oldestData.position.y) / timeDelta, (scale - oldestData.scale) / timeDelta);
+            }
         }
 
         double timeSinceLastAppend = timestamp - m_lastAppendTimestamp;
         if (timeSinceLastAppend > filteringThreshold)
-            append(newPosition, timestamp);
+            append(newPosition, scale, timestamp);
         else
-            m_history[m_latestDataIndex] = { timestamp, newPosition };
-        return velocity;
+            m_history[m_latestDataIndex] = { timestamp, newPosition, scale };
+        return velocityData;
     }
 
     void clear() { m_historySize = 0; }
 
 private:
-    void append(CGPoint newPosition, double timestamp)
+    void append(CGPoint newPosition, double scale, double timestamp)
     {
         m_latestDataIndex = (m_latestDataIndex + 1) % maxHistoryDepth;
-        m_history[m_latestDataIndex] = { timestamp, newPosition };
+        m_history[m_latestDataIndex] = { timestamp, newPosition, scale };
 
         unsigned size = m_historySize + 1;
         if (size <= maxHistoryDepth)
@@ -122,10 +144,10 @@
     unsigned m_latestDataIndex;
     double m_lastAppendTimestamp;
 
-    // FIXME: add scale information.
     struct Data {
         double timestamp;
         CGPoint position;
+        double scale;
     } m_history[maxHistoryDepth];
 };
 } // namespace WebKit
@@ -279,9 +301,9 @@
 - (void)didUpdateVisibleRect:(CGRect)visibleRect unobscuredRect:(CGRect)unobscuredRect scale:(CGFloat)zoomScale inStableState:(BOOL)isStableState
 {
     double timestamp = monotonicallyIncreasingTime();
-    CGSize velocity = CGSizeZero;
+    HistoricalVelocityData::VelocityData velocityData;
     if (!isStableState)
-        velocity = _historicalKinematicData.velocityForNewData(visibleRect.origin, timestamp);
+        velocityData = _historicalKinematicData.velocityForNewData(visibleRect.origin, zoomScale, timestamp);
     else
         _historicalKinematicData.clear();
 
@@ -294,7 +316,7 @@
     }
 
     FloatRect customFixedPositionRect = fixedPositionRectFromExposedRect(unobscuredRect, [self bounds].size, zoomScale);
-    _page->updateVisibleContentRects(VisibleContentRectUpdateInfo(_page->nextVisibleContentRectUpdateID(), visibleRect, unobscuredRect, customFixedPositionRect, filteredScale, isStableState, timestamp, velocity.width, velocity.height));
+    _page->updateVisibleContentRects(VisibleContentRectUpdateInfo(_page->nextVisibleContentRectUpdateID(), visibleRect, unobscuredRect, customFixedPositionRect, filteredScale, isStableState, timestamp, velocityData.horizontalVelocity, velocityData.verticalVelocity, velocityData.scaleChangeRate));
     
     RemoteScrollingCoordinatorProxy* scrollingCoordinator = _page->scrollingCoordinatorProxy();
     scrollingCoordinator->viewportChangedViaDelegatedScrolling(scrollingCoordinator->rootScrollingNodeID(), unobscuredRect, zoomScale);

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


--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2014-03-27 22:59:07 UTC (rev 166379)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2014-03-27 23:22:55 UTC (rev 166380)
@@ -1711,7 +1711,7 @@
 
         IntRect unobscuredContentRect(scrollPosition, minimumLayoutSizeInDocumentCoordinate);
         frameView.setUnobscuredContentRect(unobscuredContentRect);
-        frameView.setScrollVelocity(0, 0, monotonicallyIncreasingTime());
+        frameView.setScrollVelocity(0, 0, 0, monotonicallyIncreasingTime());
 
         // FIXME: We could send down the obscured margins to find a better exposed rect and unobscured rect.
         // It is not a big deal at the moment because the tile coverage will always extend past the obscured bottom inset.
@@ -1735,18 +1735,45 @@
     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationDidBecomeActiveNotification object:nil];
 }
 
+static inline FloatRect adjustExposedRectForBoundedScale(const FloatRect& exposedRect, double exposedRectScale, double boundedScale)
+{
+    if (exposedRectScale < boundedScale)
+        return exposedRect;
+
+    double overscaledWidth = exposedRect.width();
+    double missingHorizonalMargin = exposedRect.width() * exposedRectScale / boundedScale - overscaledWidth;
+
+    double overscaledHeight = exposedRect.height();
+    double missingVerticalMargin = exposedRect.height() * exposedRectScale / boundedScale - overscaledHeight;
+
+    return FloatRect(exposedRect.x() - missingHorizonalMargin / 2, exposedRect.y() - missingVerticalMargin / 2, exposedRect.width() + missingHorizonalMargin, exposedRect.height() + missingVerticalMargin);
+}
+
+static inline void adjustVelocityDataForBoundedScale(double& horizontalVelocity, double& verticalVelocity, double& scaleChangeRate, double exposedRectScale, double boundedScale)
+{
+    if (scaleChangeRate) {
+        horizontalVelocity = 0;
+        verticalVelocity = 0;
+    }
+
+    if (exposedRectScale != boundedScale)
+        scaleChangeRate = 0;
+}
+
 void WebPage::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visibleContentRectUpdateInfo)
 {
     m_hasReceivedVisibleContentRectsAfterDidCommitLoad = true;
     m_lastVisibleContentRectUpdateID = visibleContentRectUpdateInfo.updateID();
 
+    double boundedScale = std::min(m_viewportConfiguration.maximumScale(), std::max(m_viewportConfiguration.minimumScale(), visibleContentRectUpdateInfo.scale()));
+
     FloatRect exposedRect = visibleContentRectUpdateInfo.exposedRect();
-    m_drawingArea->setExposedContentRect(enclosingIntRect(exposedRect));
+    FloatRect adjustedExposedRect = adjustExposedRectForBoundedScale(exposedRect, visibleContentRectUpdateInfo.scale(), boundedScale);
+    m_drawingArea->setExposedContentRect(enclosingIntRect(adjustedExposedRect));
 
     IntRect roundedUnobscuredRect = roundedIntRect(visibleContentRectUpdateInfo.unobscuredRect());
     IntPoint scrollPosition = roundedUnobscuredRect.location();
 
-    double boundedScale = std::min(m_viewportConfiguration.maximumScale(), std::max(m_viewportConfiguration.minimumScale(), visibleContentRectUpdateInfo.scale()));
     float floatBoundedScale = boundedScale;
     if (floatBoundedScale != m_page->pageScaleFactor()) {
         m_scaleWasSetByUIProcess = true;
@@ -1759,8 +1786,14 @@
 
     m_page->mainFrame().view()->setScrollOffset(scrollPosition);
     m_page->mainFrame().view()->setUnobscuredContentRect(roundedUnobscuredRect);
-    m_page->mainFrame().view()->setScrollVelocity(visibleContentRectUpdateInfo.m_horizontalVelocity, visibleContentRectUpdateInfo.m_verticalVelocity, visibleContentRectUpdateInfo.m_timestamp);
 
+    double horizontalVelocity = visibleContentRectUpdateInfo.horizontalVelocity();
+    double verticalVelocity = visibleContentRectUpdateInfo.verticalVelocity();
+    double scaleChangeRate = visibleContentRectUpdateInfo.scaleChangeRate();
+    adjustVelocityDataForBoundedScale(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.scale(), boundedScale);
+
+    m_page->mainFrame().view()->setScrollVelocity(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.timestamp());
+
     if (visibleContentRectUpdateInfo.inStableState())
         m_page->mainFrame().view()->setCustomFixedPositionLayoutRect(enclosingIntRect(visibleContentRectUpdateInfo.customFixedPositionRect()));
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to