Chromium Code Reviews| Index: cc/CCLayerTreeHostImpl.cpp |
| =================================================================== |
| --- cc/CCLayerTreeHostImpl.cpp (revision 156389) |
| +++ cc/CCLayerTreeHostImpl.cpp (working copy) |
| @@ -48,6 +48,49 @@ |
| namespace WebCore { |
| +FloatRect CCPinchZoomViewport::bounds() const |
| +{ |
| + FloatSize scaledBounds = m_unpinchedBounds; |
| + if (m_pageScaleFactor > 1) |
| + scaledBounds.scale(1 / m_pageScaleFactor); |
| + |
| + FloatRect bounds; |
| + bounds.setSize(scaledBounds); |
| + bounds.setLocation(m_pinchViewportScrollDelta); |
| + |
| + return bounds; |
| +} |
| + |
| +FloatSize CCPinchZoomViewport::applyScroll(FloatSize& delta) |
| +{ |
| + FloatSize overflow; |
| + FloatRect pinchedBounds = bounds(); |
| + |
| + pinchedBounds.move(delta); |
| + if (pinchedBounds.x() < 0) { |
| + pinchedBounds.setX(0); |
| + overflow.setWidth(pinchedBounds.x()); |
| + } |
| + |
| + if (pinchedBounds.y() < 0) { |
| + pinchedBounds.setY(0); |
| + overflow.setHeight(pinchedBounds.y()); |
| + } |
| + |
| + if (pinchedBounds.maxX() > m_unpinchedBounds.width()) { |
| + pinchedBounds.move(m_unpinchedBounds.width() - pinchedBounds.maxX(), 0); |
| + overflow.setWidth(pinchedBounds.maxX() - m_unpinchedBounds.width()); |
| + } |
| + |
| + if (pinchedBounds.maxY() > m_unpinchedBounds.height()) { |
| + pinchedBounds.move(0, m_unpinchedBounds.height() - pinchedBounds.maxY()); |
| + overflow.setHeight(pinchedBounds.maxY() - m_unpinchedBounds.height()); |
| + } |
| + m_pinchViewportScrollDelta = pinchedBounds.location(); |
| + |
| + return overflow; |
| +} |
| + |
| class CCLayerTreeHostImplTimeSourceAdapter : public CCTimeSourceClient { |
| WTF_MAKE_NONCOPYABLE(CCLayerTreeHostImplTimeSourceAdapter); |
| public: |
| @@ -107,11 +150,11 @@ |
| , m_visible(true) |
| , m_contentsTexturesPurged(false) |
| , m_memoryAllocationLimitBytes(CCPrioritizedTextureManager::defaultMemoryAllocationLimit()) |
| - , m_pageScale(1) |
| + , m_pageScaleFactor(1) |
| , m_pageScaleDelta(1) |
| , m_sentPageScaleDelta(1) |
| - , m_minPageScale(0) |
| - , m_maxPageScale(0) |
| + , m_minPageScaleFactor(0) |
| + , m_maxPageScaleFactor(0) |
| , m_backgroundColor(0) |
| , m_hasTransparentBackground(false) |
| , m_needsAnimateLayers(false) |
| @@ -188,7 +231,7 @@ |
| IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); |
| scrollTotal.scale(m_pageScaleDelta); |
| - float scaleTotal = m_pageScale * m_pageScaleDelta; |
| + float scaleTotal = m_pageScaleFactor * m_pageScaleDelta; |
| IntSize scaledContentSize = contentSize(); |
| scaledContentSize.scale(m_pageScaleDelta); |
| @@ -726,6 +769,8 @@ |
| m_layoutViewportSize = layoutViewportSize; |
| m_deviceViewportSize = deviceViewportSize; |
| + m_pinchZoomViewport.setUnpinchedBounds(FloatSize(layoutViewportSize)); |
| + |
| updateMaxScrollPosition(); |
| if (m_renderer) |
| @@ -734,22 +779,6 @@ |
| m_client->onCanDrawStateChanged(canDraw()); |
| } |
| -static void adjustScrollsForPageScaleChange(CCLayerImpl* layerImpl, float pageScaleChange) |
| -{ |
| - if (!layerImpl) |
| - return; |
| - |
| - if (layerImpl->scrollable()) { |
| - // We need to convert impl-side scroll deltas to pageScale space. |
| - FloatSize scrollDelta = layerImpl->scrollDelta(); |
| - scrollDelta.scale(pageScaleChange); |
| - layerImpl->setScrollDelta(scrollDelta); |
| - } |
| - |
| - for (size_t i = 0; i < layerImpl->children().size(); ++i) |
| - adjustScrollsForPageScaleChange(layerImpl->children()[i].get(), pageScaleChange); |
| -} |
| - |
| void CCLayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor) |
| { |
| if (deviceScaleFactor == m_deviceScaleFactor) |
| @@ -760,23 +789,19 @@ |
| } |
| -void CCLayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScale, float minPageScale, float maxPageScale) |
| +void CCLayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor) |
| { |
| - if (!pageScale) |
| + if (!pageScaleFactor) |
| return; |
| - if (m_sentPageScaleDelta == 1 && pageScale == m_pageScale && minPageScale == m_minPageScale && maxPageScale == m_maxPageScale) |
| + if (m_sentPageScaleDelta == 1 && pageScaleFactor == m_pageScaleFactor && minPageScaleFactor == m_minPageScaleFactor && maxPageScaleFactor == m_maxPageScaleFactor) |
| return; |
| - m_minPageScale = minPageScale; |
| - m_maxPageScale = maxPageScale; |
| + m_minPageScaleFactor = minPageScaleFactor; |
| + m_maxPageScaleFactor = maxPageScaleFactor; |
| - float pageScaleChange = pageScale / m_pageScale; |
| - m_pageScale = pageScale; |
| + m_pageScaleFactor = pageScaleFactor; |
| - if (pageScaleChange != 1) |
| - adjustScrollsForPageScaleChange(m_rootScrollLayerImpl, pageScaleChange); |
| - |
| // Clamp delta to limits and refresh display matrix. |
| setPageScaleDelta(m_pageScaleDelta / m_sentPageScaleDelta); |
| m_sentPageScaleDelta = 1; |
| @@ -787,11 +812,11 @@ |
| void CCLayerTreeHostImpl::setPageScaleDelta(float delta) |
| { |
| // Clamp to the current min/max limits. |
| - float finalMagnifyScale = m_pageScale * delta; |
| - if (m_minPageScale && finalMagnifyScale < m_minPageScale) |
| - delta = m_minPageScale / m_pageScale; |
| - else if (m_maxPageScale && finalMagnifyScale > m_maxPageScale) |
| - delta = m_maxPageScale / m_pageScale; |
| + float finalMagnifyScale = m_pageScaleFactor * delta; |
| + if (m_minPageScaleFactor && finalMagnifyScale < m_minPageScaleFactor) |
| + delta = m_minPageScaleFactor / m_pageScaleFactor; |
| + else if (m_maxPageScaleFactor && finalMagnifyScale > m_maxPageScaleFactor) |
| + delta = m_maxPageScaleFactor / m_pageScaleFactor; |
| if (delta == m_pageScaleDelta) |
| return; |
| @@ -799,8 +824,10 @@ |
| m_pageScaleDelta = delta; |
| updateMaxScrollPosition(); |
| - if (m_rootScrollLayerImpl) |
| + if (m_rootScrollLayerImpl) { |
| m_rootScrollLayerImpl->setPageScaleDelta(m_pageScaleDelta); |
| + m_rootScrollLayerImpl->setPageScaleFactor(m_pageScaleFactor); |
| + } |
| } |
| void CCLayerTreeHostImpl::updateMaxScrollPosition() |
| @@ -819,8 +846,13 @@ |
| viewBounds.scale(1 / m_pageScaleDelta); |
| // maxScroll is computed in physical pixels, but scroll positions are in layout pixels. |
| - IntSize maxScroll = contentSize() - expandedIntSize(viewBounds); |
| - maxScroll.scale(1 / m_deviceScaleFactor); |
| + // Compute the contentSize in terms of layout pixels. |
| + IntSize scaledContentSize = contentSize(); |
| + scaledContentSize.scale(1 / (m_pageScaleFactor * m_deviceScaleFactor)); |
| + |
| + IntSize maxScroll = scaledContentSize - expandedIntSize(viewBounds); |
| + maxScroll.scale(1 / (m_deviceScaleFactor)); |
| + |
| // The viewport may be larger than the contents in some cases, such as |
| // having a vertical scrollbar but no horizontal overflow. |
| maxScroll.clampNegativeToZero(); |
| @@ -903,7 +935,7 @@ |
| return ScrollIgnored; |
| } |
| -static FloatSize scrollLayerWithScreenSpaceDelta(CCLayerImpl& layerImpl, const FloatPoint& screenSpacePoint, const FloatSize& screenSpaceDelta) |
| +static FloatSize scrollLayerWithScreenSpaceDelta(CCPinchZoomViewport* viewport, CCLayerImpl& layerImpl, const FloatPoint& screenSpacePoint, const FloatSize& screenSpaceDelta) |
| { |
| // Layers with non-invertible screen space transforms should not have passed the scroll hit |
| // test in the first place. |
| @@ -925,8 +957,13 @@ |
| // Apply the scroll delta. |
| FloatSize previousDelta(layerImpl.scrollDelta()); |
| - layerImpl.scrollBy(localEndPoint - localStartPoint); |
| + FloatSize unscrolled = layerImpl.scrollBy(localEndPoint - localStartPoint); |
| + if (viewport) { |
| + viewport->applyScroll(unscrolled); |
| + layerImpl.setLocalOffset(FloatSize(-viewport->scrollDelta().x(), -viewport->scrollDelta().y())); |
| + } |
| + |
| // Calculate the applied scroll delta in screen space coordinates. |
| FloatPoint actualLocalEndPoint = localStartPoint + layerImpl.scrollDelta() - previousDelta; |
| FloatPoint actualScreenSpaceEndPoint = CCMathUtil::mapPoint(layerImpl.screenSpaceTransform(), actualLocalEndPoint, endClipped); |
| @@ -957,9 +994,10 @@ |
| if (!layerImpl->scrollable()) |
| continue; |
| + CCPinchZoomViewport* viewport = layerImpl == m_rootScrollLayerImpl ? &m_pinchZoomViewport : 0; |
| FloatSize appliedDelta; |
| if (m_scrollDeltaIsInScreenSpace) |
| - appliedDelta = scrollLayerWithScreenSpaceDelta(*layerImpl, viewportPoint, pendingDelta); |
| + appliedDelta = scrollLayerWithScreenSpaceDelta(viewport, *layerImpl, viewportPoint, pendingDelta); |
| else |
| appliedDelta = scrollLayerWithLocalDelta(*layerImpl, pendingDelta); |
| @@ -1029,10 +1067,17 @@ |
| FloatPoint newScaleAnchor(anchor.x() / m_pageScaleDelta, anchor.y() / m_pageScaleDelta); |
| FloatSize move = previousScaleAnchor - newScaleAnchor; |
| + // Compute the appliation of the delta with respect to the current page zoom of the page. |
| + move.scale(1 / m_pageScaleFactor); |
| + |
| m_previousPinchAnchor = anchor; |
| - m_rootScrollLayerImpl->scrollBy(roundedIntSize(move)); |
| + m_pinchZoomViewport.setTotalPageScaleFactor(m_pageScaleFactor * m_pageScaleDelta); |
| + FloatSize scrollOverflow = m_pinchZoomViewport.applyScroll(move); |
| + m_rootScrollLayerImpl->setLocalOffset(FloatSize(-m_pinchZoomViewport.scrollDelta().x(), -m_pinchZoomViewport.scrollDelta().y())); |
| + m_rootScrollLayerImpl->scrollBy(roundedIntSize(scrollOverflow)); |
| + |
| if (m_rootScrollLayerImpl->scrollbarAnimationController()) |
| m_rootScrollLayerImpl->scrollbarAnimationController()->didPinchGestureUpdate(); |
| @@ -1054,7 +1099,7 @@ |
| { |
| float pageScale = m_pageScaleAnimation->finalPageScale(); |
| IntSize scrollOffset = m_pageScaleAnimation->finalScrollOffset(); |
| - scrollOffset.scale(m_pageScale / pageScale); |
| + scrollOffset.scale(m_pageScaleFactor / pageScale); |
| makeScrollAndScaleSet(scrollInfo, scrollOffset, pageScale); |
| } |
| @@ -1074,20 +1119,20 @@ |
| // out from the anchor point. |
| IntSize scrollBegin = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); |
| scrollBegin.scale(m_pageScaleDelta); |
| - float scaleBegin = m_pageScale * m_pageScaleDelta; |
| - float pageScaleDeltaToSend = m_minPageScale / m_pageScale; |
| + float scaleBegin = m_pageScaleFactor * m_pageScaleDelta; |
| + float pageScaleDeltaToSend = m_minPageScaleFactor / m_pageScaleFactor; |
| FloatSize scaledContentsSize = contentSize(); |
| scaledContentsSize.scale(pageScaleDeltaToSend); |
| FloatSize anchor = toSize(m_previousPinchAnchor); |
| FloatSize scrollEnd = scrollBegin + anchor; |
| - scrollEnd.scale(m_minPageScale / scaleBegin); |
| + scrollEnd.scale(m_minPageScaleFactor / scaleBegin); |
| scrollEnd -= anchor; |
| scrollEnd = scrollEnd.shrunkTo(roundedIntSize(scaledContentsSize - m_deviceViewportSize)).expandedTo(FloatSize(0, 0)); |
| scrollEnd.scale(1 / pageScaleDeltaToSend); |
| scrollEnd.scale(m_deviceScaleFactor); |
| - makeScrollAndScaleSet(scrollInfo, roundedIntSize(scrollEnd), m_minPageScale); |
| + makeScrollAndScaleSet(scrollInfo, roundedIntSize(scrollEnd), m_minPageScaleFactor); |
| } |
| void CCLayerTreeHostImpl::makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale) |
| @@ -1100,7 +1145,7 @@ |
| scroll.scrollDelta = scrollOffset - toSize(m_rootScrollLayerImpl->scrollPosition()); |
| scrollInfo->scrolls.append(scroll); |
| m_rootScrollLayerImpl->setSentScrollDelta(scroll.scrollDelta); |
| - m_sentPageScaleDelta = scrollInfo->pageScaleDelta = pageScale / m_pageScale; |
| + m_sentPageScaleDelta = scrollInfo->pageScaleDelta = pageScale / m_pageScaleFactor; |
| } |
| static void collectScrollDeltas(CCScrollAndScaleSet* scrollInfo, CCLayerImpl* layerImpl) |
| @@ -1127,10 +1172,12 @@ |
| if (m_pinchGestureActive || m_pageScaleAnimation) { |
| m_sentPageScaleDelta = scrollInfo->pageScaleDelta = 1; |
| +#if 0 |
|
enne (OOO)
2012/09/13 19:40:54
?
Jeff Timanus
2012/09/13 19:58:50
This code needs to be retained so that the android
|
| if (m_pinchGestureActive) |
| computePinchZoomDeltas(scrollInfo.get()); |
| else if (m_pageScaleAnimation.get()) |
| computeDoubleTapZoomDeltas(scrollInfo.get()); |
| +#endif |
| return scrollInfo.release(); |
| } |
| @@ -1156,7 +1203,7 @@ |
| IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); |
| - setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pageScale); |
| + setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pageScaleFactor); |
| IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime); |
| nextScroll.scale(1 / m_pageScaleDelta); |
| m_rootScrollLayerImpl->scrollBy(nextScroll - scrollTotal); |