| Index: cc/CCLayerTreeHostImpl.cpp
|
| ===================================================================
|
| --- cc/CCLayerTreeHostImpl.cpp (revision 157978)
|
| +++ cc/CCLayerTreeHostImpl.cpp (working copy)
|
| @@ -48,6 +48,49 @@
|
|
|
| namespace cc {
|
|
|
| +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:
|
| @@ -115,20 +158,23 @@
|
| , 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)
|
| , m_pinchGestureActive(false)
|
| + , m_applyPinchZoomInImpl(false)
|
| , m_fpsCounter(CCFrameRateCounter::create())
|
| , m_debugRectHistory(CCDebugRectHistory::create())
|
| {
|
| ASSERT(CCProxy::isImplThread());
|
| didVisibilityChange(this, m_visible);
|
| +
|
| + m_applyPinchZoomInImpl = CCSettings::pageScalePinchZoomEnabled();
|
| }
|
|
|
| CCLayerTreeHostImpl::~CCLayerTreeHostImpl()
|
| @@ -196,7 +242,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);
|
|
|
| @@ -233,6 +279,13 @@
|
| }
|
| }
|
|
|
| +void CCLayerTreeHostImpl::updateRootScrollLayerImplTransform()
|
| +{
|
| + if (m_rootScrollLayerImpl) {
|
| + m_rootScrollLayerImpl->setImplTransform(implTransform());
|
| + }
|
| +}
|
| +
|
| void CCLayerTreeHostImpl::calculateRenderSurfaceLayerList(CCLayerList& renderSurfaceLayerList)
|
| {
|
| ASSERT(renderSurfaceLayerList.isEmpty());
|
| @@ -240,6 +293,8 @@
|
| ASSERT(m_renderer); // For maxTextureSize.
|
|
|
| {
|
| + updateRootScrollLayerImplTransform();
|
| +
|
| TRACE_EVENT0("cc", "CCLayerTreeHostImpl::calcDrawEtc");
|
| CCLayerTreeHostCommon::calculateDrawTransforms(m_rootLayerImpl.get(), deviceViewportSize(), m_deviceScaleFactor, &m_layerSorter, rendererCapabilities().maxTextureSize, renderSurfaceLayerList);
|
| CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
|
| @@ -767,6 +822,8 @@
|
| m_layoutViewportSize = layoutViewportSize;
|
| m_deviceViewportSize = deviceViewportSize;
|
|
|
| + m_pinchZoomViewport.setUnpinchedBounds(FloatSize(layoutViewportSize));
|
| +
|
| updateMaxScrollPosition();
|
|
|
| if (m_renderer)
|
| @@ -801,38 +858,38 @@
|
| }
|
|
|
|
|
| -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;
|
| + float pageScaleChange = pageScaleFactor / m_pageScaleFactor;
|
| + m_pageScaleFactor = pageScaleFactor;
|
|
|
| - if (pageScaleChange != 1)
|
| - adjustScrollsForPageScaleChange(m_rootScrollLayerImpl, pageScaleChange);
|
| + if (!m_applyPinchZoomInImpl) {
|
| + if (pageScaleChange != 1)
|
| + adjustScrollsForPageScaleChange(m_rootScrollLayerImpl, pageScaleChange);
|
| + }
|
|
|
| // Clamp delta to limits and refresh display matrix.
|
| setPageScaleDelta(m_pageScaleDelta / m_sentPageScaleDelta);
|
| m_sentPageScaleDelta = 1;
|
| - if (m_rootScrollLayerImpl)
|
| - m_rootScrollLayerImpl->setPageScaleDelta(m_pageScaleDelta);
|
| }
|
|
|
| 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;
|
| @@ -840,8 +897,6 @@
|
| m_pageScaleDelta = delta;
|
|
|
| updateMaxScrollPosition();
|
| - if (m_rootScrollLayerImpl)
|
| - m_rootScrollLayerImpl->setPageScaleDelta(m_pageScaleDelta);
|
| }
|
|
|
| void CCLayerTreeHostImpl::updateMaxScrollPosition()
|
| @@ -859,9 +914,18 @@
|
| }
|
| viewBounds.scale(1 / m_pageScaleDelta);
|
|
|
| - // maxScroll is computed in physical pixels, but scroll positions are in layout pixels.
|
| - IntSize maxScroll = contentSize() - expandedIntSize(viewBounds);
|
| + IntSize contentBounds = contentSize();
|
| + if (m_applyPinchZoomInImpl) {
|
| + // Pinch with pageScale scrolls entirely in layout space. contentSize
|
| + // returns the bounds including the page scale factor, so calculate the
|
| + // pre page-scale layout size here.
|
| + contentBounds.setWidth(contentBounds.width() / m_pageScaleFactor);
|
| + contentBounds.setHeight(contentBounds.height() / m_pageScaleFactor);
|
| + }
|
| +
|
| + IntSize maxScroll = contentBounds - 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();
|
| @@ -944,7 +1008,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.
|
| @@ -966,8 +1030,11 @@
|
|
|
| // Apply the scroll delta.
|
| FloatSize previousDelta(layerImpl.scrollDelta());
|
| - layerImpl.scrollBy(localEndPoint - localStartPoint);
|
| + FloatSize unscrolled = layerImpl.scrollBy(localEndPoint - localStartPoint);
|
|
|
| + if (viewport)
|
| + viewport->applyScroll(unscrolled);
|
| +
|
| // Calculate the applied scroll delta in screen space coordinates.
|
| FloatPoint actualLocalEndPoint = localStartPoint + layerImpl.scrollDelta() - previousDelta;
|
| FloatPoint actualScreenSpaceEndPoint = CCMathUtil::mapPoint(layerImpl.screenSpaceTransform(), actualLocalEndPoint, endClipped);
|
| @@ -998,9 +1065,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);
|
|
|
| @@ -1071,9 +1139,16 @@
|
| FloatSize move = previousScaleAnchor - newScaleAnchor;
|
|
|
| m_previousPinchAnchor = anchor;
|
| + m_pinchZoomViewport.setTotalPageScaleFactor(m_pageScaleFactor * m_pageScaleDelta);
|
|
|
| - m_rootScrollLayerImpl->scrollBy(roundedIntSize(move));
|
| + if (m_applyPinchZoomInImpl) {
|
| + // Compute the application of the delta with respect to the current page zoom of the page.
|
| + move.scale(1 / (m_pageScaleFactor * m_deviceScaleFactor));
|
| + }
|
|
|
| + FloatSize scrollOverflow = m_applyPinchZoomInImpl? m_pinchZoomViewport.applyScroll(move) : move;
|
| + m_rootScrollLayerImpl->scrollBy(roundedIntSize(scrollOverflow));
|
| +
|
| if (m_rootScrollLayerImpl->scrollbarAnimationController())
|
| m_rootScrollLayerImpl->scrollbarAnimationController()->didPinchGestureUpdate();
|
|
|
| @@ -1095,7 +1170,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);
|
| }
|
|
|
| @@ -1115,20 +1190,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)
|
| @@ -1141,7 +1216,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)
|
| @@ -1168,10 +1243,14 @@
|
|
|
| if (m_pinchGestureActive || m_pageScaleAnimation) {
|
| m_sentPageScaleDelta = scrollInfo->pageScaleDelta = 1;
|
| - if (m_pinchGestureActive)
|
| - computePinchZoomDeltas(scrollInfo.get());
|
| - else if (m_pageScaleAnimation.get())
|
| - computeDoubleTapZoomDeltas(scrollInfo.get());
|
| + // If pinch zoom is applied in the impl thread, then there is no need to
|
| + // calculate these intermediate scale deltas.
|
| + if (!m_applyPinchZoomInImpl) {
|
| + if (m_pinchGestureActive)
|
| + computePinchZoomDeltas(scrollInfo.get());
|
| + else if (m_pageScaleAnimation.get())
|
| + computeDoubleTapZoomDeltas(scrollInfo.get());
|
| + }
|
| return scrollInfo.release();
|
| }
|
|
|
| @@ -1181,6 +1260,22 @@
|
| return scrollInfo.release();
|
| }
|
|
|
| +WebTransformationMatrix CCLayerTreeHostImpl::implTransform() const
|
| +{
|
| + WebTransformationMatrix transform;
|
| + transform.scale(m_pageScaleDelta);
|
| +
|
| + // If the pinch state is applied in the impl, then push it to the
|
| + // impl transform, otherwise the scale is handled by WebCore.
|
| + if (m_applyPinchZoomInImpl) {
|
| + transform.scale(m_pageScaleFactor);
|
| + transform.translate(-m_pinchZoomViewport.scrollDelta().x(),
|
| + -m_pinchZoomViewport.scrollDelta().y());
|
| + }
|
| +
|
| + return transform;
|
| +}
|
| +
|
| void CCLayerTreeHostImpl::setFullRootLayerDamage()
|
| {
|
| if (m_rootLayerImpl) {
|
| @@ -1197,7 +1292,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);
|
|
|