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));
}
}