Title: [108445] trunk/Source
Revision
108445
Author
[email protected]
Date
2012-02-21 21:29:06 -0800 (Tue, 21 Feb 2012)

Log Message

[chromium] Add three small zoom gesture features
https://bugs.webkit.org/show_bug.cgi?id=74216

Patch by Alexandre Elias <[email protected]> on 2012-02-21
Reviewed by James Robinson.

1. Support panning around with two fingers.
2. When double-tap zooming, issue the commit at final/scroll scale as
early as possible.
3. When pinch zooming out, issue a commit at minimum scale to avoid
showing checkerboard.

Added test for panning to CCLayerTreeHostImplTest::pinchGesture.
(The other features are heuristics whose exact behavior we don't need
to lock in with a test.)

* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::startPageScaleAnimation):
(WebCore::CCLayerTreeHostImpl::pinchGestureBegin):
(WebCore::CCLayerTreeHostImpl::pinchGestureUpdate):
(WebCore::CCLayerTreeHostImpl::computeDoubleTapZoomDeltas):
(WebCore::CCLayerTreeHostImpl::computePinchZoomDeltas):
(WebCore::CCLayerTreeHostImpl::makeScrollAndScaleSet):
(WebCore::CCLayerTreeHostImpl::processScrollDeltas):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (108444 => 108445)


--- trunk/Source/WebCore/ChangeLog	2012-02-22 05:23:19 UTC (rev 108444)
+++ trunk/Source/WebCore/ChangeLog	2012-02-22 05:29:06 UTC (rev 108445)
@@ -1,3 +1,30 @@
+2012-02-21  Alexandre Elias  <[email protected]>
+
+        [chromium] Add three small zoom gesture features
+        https://bugs.webkit.org/show_bug.cgi?id=74216
+
+        Reviewed by James Robinson.
+
+        1. Support panning around with two fingers.
+        2. When double-tap zooming, issue the commit at final/scroll scale as
+        early as possible.
+        3. When pinch zooming out, issue a commit at minimum scale to avoid
+        showing checkerboard.
+
+        Added test for panning to CCLayerTreeHostImplTest::pinchGesture.
+        (The other features are heuristics whose exact behavior we don't need
+        to lock in with a test.)
+
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::startPageScaleAnimation):
+        (WebCore::CCLayerTreeHostImpl::pinchGestureBegin):
+        (WebCore::CCLayerTreeHostImpl::pinchGestureUpdate):
+        (WebCore::CCLayerTreeHostImpl::computeDoubleTapZoomDeltas):
+        (WebCore::CCLayerTreeHostImpl::computePinchZoomDeltas):
+        (WebCore::CCLayerTreeHostImpl::makeScrollAndScaleSet):
+        (WebCore::CCLayerTreeHostImpl::processScrollDeltas):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+
 2012-02-21  Filip Pizlo  <[email protected]>
 
         JSC should be a triple-tier VM

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (108444 => 108445)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-02-22 05:23:19 UTC (rev 108444)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-02-22 05:29:06 UTC (rev 108445)
@@ -137,6 +137,7 @@
         m_pageScaleAnimation->zoomTo(targetPosition, pageScale, durationMs);
 
     m_client->setNeedsRedrawOnImplThread();
+    m_client->setNeedsCommitOnImplThread();
 }
 
 void CCLayerTreeHostImpl::trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList)
@@ -498,6 +499,7 @@
 void CCLayerTreeHostImpl::pinchGestureBegin()
 {
     m_pinchGestureActive = true;
+    m_previousPinchAnchor = IntPoint();
 }
 
 void CCLayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta,
@@ -505,18 +507,20 @@
 {
     TRACE_EVENT("CCLayerTreeHostImpl::pinchGestureUpdate", this, 0);
 
-    if (magnifyDelta == 1.0)
-        return;
     if (!m_scrollLayerImpl)
         return;
 
+    if (m_previousPinchAnchor == IntPoint::zero())
+        m_previousPinchAnchor = anchor;
+
     // Keep the center-of-pinch anchor specified by (x, y) in a stable
     // position over the course of the magnify.
-    FloatPoint prevScaleAnchor(anchor.x() / m_pageScaleDelta, anchor.y() / m_pageScaleDelta);
+    FloatPoint previousScaleAnchor(m_previousPinchAnchor.x() / m_pageScaleDelta, m_previousPinchAnchor.y() / m_pageScaleDelta);
     setPageScaleDelta(m_pageScaleDelta * magnifyDelta);
     FloatPoint newScaleAnchor(anchor.x() / m_pageScaleDelta, anchor.y() / m_pageScaleDelta);
+    FloatSize move = previousScaleAnchor - newScaleAnchor;
 
-    FloatSize move = prevScaleAnchor - newScaleAnchor;
+    m_previousPinchAnchor = anchor;
 
     m_scrollLayerImpl->scrollBy(roundedIntSize(move));
     m_client->setNeedsCommitOnImplThread();
@@ -530,12 +534,68 @@
     m_client->setNeedsCommitOnImplThread();
 }
 
+void CCLayerTreeHostImpl::computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo)
+{
+    float pageScale = m_pageScaleAnimation->finalPageScale();
+    IntSize scrollOffset = m_pageScaleAnimation->finalScrollOffset();
+    scrollOffset.scale(m_pageScale / pageScale);
+    makeScrollAndScaleSet(scrollInfo, scrollOffset, pageScale);
+}
+
+void CCLayerTreeHostImpl::computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo)
+{
+    if (!m_scrollLayerImpl)
+        return;
+
+    // Only send fake scroll/zoom deltas if we're pinch zooming out by a
+    // significant amount. This also ensures only one fake delta set will be
+    // sent.
+    const float pinchZoomOutSensitivity = 0.95;
+    if (m_pageScaleDelta > pinchZoomOutSensitivity)
+        return;
+
+    // Compute where the scroll offset/page scale would be if fully pinch-zoomed
+    // out from the anchor point.
+    FloatSize scrollBegin = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
+    scrollBegin.scale(m_pageScaleDelta);
+    float scaleBegin = m_pageScale * m_pageScaleDelta;
+    float pageScaleDeltaToSend = m_minPageScale / m_pageScale;
+    FloatSize scaledContentsSize = contentSize();
+    scaledContentsSize.scale(pageScaleDeltaToSend);
+
+    FloatSize anchor = toSize(m_previousPinchAnchor);
+    FloatSize scrollEnd = scrollBegin + anchor;
+    scrollEnd.scale(m_minPageScale / scaleBegin);
+    scrollEnd -= anchor;
+    scrollEnd = scrollEnd.shrunkTo(roundedIntSize(scaledContentsSize - m_viewportSize)).expandedTo(FloatSize(0, 0));
+    scrollEnd.scale(1 / pageScaleDeltaToSend);
+
+    makeScrollAndScaleSet(scrollInfo, roundedIntSize(scrollEnd), m_minPageScale);
+}
+
+void CCLayerTreeHostImpl::makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale)
+{
+    if (!m_scrollLayerImpl)
+        return;
+
+    CCLayerTreeHostCommon::ScrollUpdateInfo scroll;
+    scroll.layerId = m_scrollLayerImpl->id();
+    scroll.scrollDelta = scrollOffset - toSize(m_scrollLayerImpl->scrollPosition());
+    scrollInfo->scrolls.append(scroll);
+    m_scrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);
+    m_sentPageScaleDelta = scrollInfo->pageScaleDelta = pageScale / m_pageScale;
+}
+
 PassOwnPtr<CCScrollAndScaleSet> CCLayerTreeHostImpl::processScrollDeltas()
 {
     OwnPtr<CCScrollAndScaleSet> scrollInfo = adoptPtr(new CCScrollAndScaleSet());
     bool didMove = m_scrollLayerImpl && (!m_scrollLayerImpl->scrollDelta().isZero() || m_pageScaleDelta != 1.0f);
     if (!didMove || m_pinchGestureActive || m_pageScaleAnimation) {
         m_sentPageScaleDelta = scrollInfo->pageScaleDelta = 1;
+        if (m_pinchGestureActive)
+            computePinchZoomDeltas(scrollInfo.get());
+        else if (m_pageScaleAnimation.get())
+            computeDoubleTapZoomDeltas(scrollInfo.get());
         return scrollInfo.release();
     }
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h (108444 => 108445)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h	2012-02-22 05:23:19 UTC (rev 108444)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h	2012-02-22 05:29:06 UTC (rev 108445)
@@ -128,6 +128,10 @@
 private:
     typedef Vector<RefPtr<CCLayerImpl> > CCLayerList;
 
+    void computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo);
+    void computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo);
+    void makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale);
+
     void setPageScaleDelta(float);
     void applyPageScaleDeltaToScrollLayer();
     void adjustScrollsForPageScaleChange(float);
@@ -151,6 +155,7 @@
     float m_minPageScale, m_maxPageScale;
 
     bool m_pinchGestureActive;
+    IntPoint m_previousPinchAnchor;
 
     OwnPtr<CCPageScaleAnimation> m_pageScaleAnimation;
 

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp (108444 => 108445)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2012-02-22 05:23:19 UTC (rev 108444)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2012-02-22 05:29:06 UTC (rev 108445)
@@ -67,7 +67,8 @@
         for (size_t i = 0; i < scrollInfo.scrolls.size(); ++i) {
             if (scrollInfo.scrolls[i].layerId != id)
                 continue;
-            ASSERT_EQ(scrollInfo.scrolls[i].scrollDelta, scrollDelta);
+            EXPECT_EQ(scrollDelta.width(), scrollInfo.scrolls[i].scrollDelta.width());
+            EXPECT_EQ(scrollDelta.height(), scrollInfo.scrolls[i].scrollDelta.height());
             timesEncountered++;
         }
 
@@ -142,14 +143,14 @@
     scrollInfo = m_hostImpl->processScrollDeltas();
     ASSERT_EQ(scrollInfo->scrolls.size(), 1u);
     EXPECT_EQ(root->sentScrollDelta(), scrollDelta);
-    expectContains(*scrollInfo.get(), root->id(), scrollDelta);
+    expectContains(*scrollInfo, root->id(), scrollDelta);
 
     IntSize scrollDelta2(-5, 27);
     root->scrollBy(scrollDelta2);
     scrollInfo = m_hostImpl->processScrollDeltas();
     ASSERT_EQ(scrollInfo->scrolls.size(), 1u);
     EXPECT_EQ(root->sentScrollDelta(), scrollDelta + scrollDelta2);
-    expectContains(*scrollInfo.get(), root->id(), scrollDelta + scrollDelta2);
+    expectContains(*scrollInfo, root->id(), scrollDelta + scrollDelta2);
 
     root->scrollBy(IntSize());
     scrollInfo = m_hostImpl->processScrollDeltas();
@@ -184,6 +185,7 @@
     {
         m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale);
         scrollLayer->setPageScaleDelta(1);
+        scrollLayer->setScrollDelta(IntSize());
 
         float pageScaleDelta = 2;
         m_hostImpl->pinchGestureBegin();
@@ -200,6 +202,7 @@
     {
         m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale);
         scrollLayer->setPageScaleDelta(1);
+        scrollLayer->setScrollDelta(IntSize());
         float pageScaleDelta = 10;
 
         m_hostImpl->pinchGestureBegin();
@@ -214,6 +217,7 @@
     {
         m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale);
         scrollLayer->setPageScaleDelta(1);
+        scrollLayer->setScrollDelta(IntSize());
         scrollLayer->setScrollPosition(IntPoint(50, 50));
 
         float pageScaleDelta = 0.1;
@@ -225,8 +229,26 @@
         EXPECT_EQ(scrollInfo->pageScaleDelta, minPageScale);
 
         // Pushed to (0,0) via clamping against contents layer size.
-        expectContains(*scrollInfo.get(), scrollLayer->id(), IntSize(-50, -50));
+        expectContains(*scrollInfo, scrollLayer->id(), IntSize(-50, -50));
     }
+
+    // Two-finger panning
+    {
+        m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale);
+        scrollLayer->setPageScaleDelta(1);
+        scrollLayer->setScrollDelta(IntSize());
+        scrollLayer->setScrollPosition(IntPoint(20, 20));
+
+        float pageScaleDelta = 1;
+        m_hostImpl->pinchGestureBegin();
+        m_hostImpl->pinchGestureUpdate(pageScaleDelta, IntPoint(10, 10));
+        m_hostImpl->pinchGestureUpdate(pageScaleDelta, IntPoint(20, 20));
+        m_hostImpl->pinchGestureEnd();
+
+        OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas();
+        EXPECT_EQ(scrollInfo->pageScaleDelta, pageScaleDelta);
+        expectContains(*scrollInfo, scrollLayer->id(), IntSize(-10, -10));
+    }
 }
 
 TEST_F(CCLayerTreeHostImplTest, pageScaleAnimation)
@@ -255,7 +277,7 @@
 
         OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas();
         EXPECT_EQ(scrollInfo->pageScaleDelta, 2);
-        expectContains(*scrollInfo.get(), scrollLayer->id(), IntSize(-50, -50));
+        expectContains(*scrollInfo, scrollLayer->id(), IntSize(-50, -50));
     }
 
     // Anchor zoom-out
@@ -272,7 +294,7 @@
         OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas();
         EXPECT_EQ(scrollInfo->pageScaleDelta, minPageScale);
         // Pushed to (0,0) via clamping against contents layer size.
-        expectContains(*scrollInfo.get(), scrollLayer->id(), IntSize(-50, -50));
+        expectContains(*scrollInfo, scrollLayer->id(), IntSize(-50, -50));
     }
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to