| Index: Source/web/WebViewImpl.cpp
 | 
| diff --git a/Source/web/WebViewImpl.cpp b/Source/web/WebViewImpl.cpp
 | 
| index 9267de1b7f190ef35a802e331a0193ea4c870525..08396b9b7c65f8e18ca80a2921f6edefebe411db 100644
 | 
| --- a/Source/web/WebViewImpl.cpp
 | 
| +++ b/Source/web/WebViewImpl.cpp
 | 
| @@ -1569,8 +1569,8 @@ void WebViewImpl::resize(const WebSize& newSize)
 | 
|          WebFrameImpl* webFrame = mainFrameImpl();
 | 
|          if (webFrame->frameView()) {
 | 
|              webFrame->frameView()->resize(m_size);
 | 
| -            if (page()->settings().pinchVirtualViewportEnabled())
 | 
| -                page()->frameHost().pinchViewport().setSize(m_size);
 | 
| +            if (pinchVirtualViewportEnabled())
 | 
| +                page()->frameHost().pinchViewport().mainFrameDidChangeSize();
 | 
|          }
 | 
|      }
 | 
|  
 | 
| @@ -2637,6 +2637,9 @@ float WebViewImpl::pageScaleFactor() const
 | 
|      if (!page())
 | 
|          return 1;
 | 
|  
 | 
| +    if (pinchVirtualViewportEnabled())
 | 
| +        return pinchViewportScaleFactor();
 | 
| +
 | 
|      return page()->pageScaleFactor();
 | 
|  }
 | 
|  
 | 
| @@ -2654,27 +2657,84 @@ IntPoint WebViewImpl::clampOffsetAtScale(const IntPoint& offset, float scale)
 | 
|      return view->clampOffsetAtScale(offset, scale);
 | 
|  }
 | 
|  
 | 
| -void WebViewImpl::setPageScaleFactor(float scaleFactor, const WebPoint& origin)
 | 
| +bool WebViewImpl::pinchVirtualViewportEnabled() const
 | 
|  {
 | 
| -    if (!page())
 | 
| +    ASSERT(page());
 | 
| +    return page()->settings().pinchVirtualViewportEnabled();
 | 
| +}
 | 
| +
 | 
| +void WebViewImpl::setPinchViewportOffset(const WebFloatPoint& offset)
 | 
| +{
 | 
| +    ASSERT(page());
 | 
| +
 | 
| +    if (!pinchVirtualViewportEnabled())
 | 
|          return;
 | 
|  
 | 
| -    IntPoint newScrollOffset = origin;
 | 
| +    page()->frameHost().pinchViewport().setLocation(offset);
 | 
| +}
 | 
| +
 | 
| +WebFloatPoint WebViewImpl::pinchViewportOffset() const
 | 
| +{
 | 
| +    ASSERT(page());
 | 
| +
 | 
| +    if (!pinchVirtualViewportEnabled())
 | 
| +        return WebFloatPoint();
 | 
| +
 | 
| +    return page()->frameHost().pinchViewport().visibleRect().location();
 | 
| +}
 | 
| +
 | 
| +void WebViewImpl::setPinchViewportScaleFactor(float scaleFactor)
 | 
| +{
 | 
| +    ASSERT(page());
 | 
| +
 | 
|      scaleFactor = clampPageScaleFactorToLimits(scaleFactor);
 | 
| -    newScrollOffset = clampOffsetAtScale(newScrollOffset, scaleFactor);
 | 
| +    if (scaleFactor == pinchViewportScaleFactor())
 | 
| +        return;
 | 
| +
 | 
| +    // TODO(bokan): Old-style pinch path. Remove when we're migrated to
 | 
| +    // virtual viewport pinch.
 | 
| +    if (!pinchVirtualViewportEnabled()) {
 | 
| +        IntPoint scrollOffset(mainFrame()->scrollOffset().width, mainFrame()->scrollOffset().height);
 | 
| +        setPageScaleFactor(scaleFactor, scrollOffset);
 | 
| +        return;
 | 
| +    }
 | 
|  
 | 
| -    page()->setPageScaleFactor(scaleFactor, newScrollOffset);
 | 
| +    page()->frameHost().pinchViewport().setScale(scaleFactor);
 | 
| +    deviceOrPageScaleFactorChanged();
 | 
|  }
 | 
|  
 | 
| -void WebViewImpl::setPageScaleFactorPreservingScrollOffset(float scaleFactor)
 | 
| +float WebViewImpl::pinchViewportScaleFactor() const
 | 
|  {
 | 
| -    if (clampPageScaleFactorToLimits(scaleFactor) == pageScaleFactor())
 | 
| +    if (!pinchVirtualViewportEnabled())
 | 
| +        return pageScaleFactor();
 | 
| +
 | 
| +    if (!page())
 | 
| +        return 1;
 | 
| +
 | 
| +    return page()->frameHost().pinchViewport().scale();
 | 
| +}
 | 
| +
 | 
| +void WebViewImpl::setMainFrameScrollOffset(const WebPoint& origin)
 | 
| +{
 | 
| +    updateMainFrameScrollPosition(origin, false);
 | 
| +}
 | 
| +
 | 
| +void WebViewImpl::setPageScaleFactor(float scaleFactor, const WebPoint& origin)
 | 
| +{
 | 
| +    if (!page())
 | 
|          return;
 | 
|  
 | 
| -    IntPoint scrollOffset(mainFrame()->scrollOffset().width, mainFrame()->scrollOffset().height);
 | 
| -    setPageScaleFactor(scaleFactor, scrollOffset);
 | 
| +    IntPoint newScrollOffset = origin;
 | 
| +    scaleFactor = clampPageScaleFactorToLimits(scaleFactor);
 | 
| +    newScrollOffset = clampOffsetAtScale(newScrollOffset, scaleFactor);
 | 
| +
 | 
| +    if (pinchVirtualViewportEnabled())
 | 
| +        setPinchViewportScaleFactor(scaleFactor);
 | 
| +    else
 | 
| +        page()->setPageScaleFactor(scaleFactor, newScrollOffset);
 | 
|  }
 | 
|  
 | 
| +
 | 
|  float WebViewImpl::deviceScaleFactor() const
 | 
|  {
 | 
|      if (!page())
 | 
| @@ -2775,7 +2835,7 @@ void WebViewImpl::refreshPageScaleFactorAfterLayout()
 | 
|          newPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().initialScale;
 | 
|          m_pageScaleConstraintsSet.setNeedsReset(false);
 | 
|      }
 | 
| -    setPageScaleFactorPreservingScrollOffset(newPageScaleFactor);
 | 
| +    setPinchViewportScaleFactor(newPageScaleFactor);
 | 
|  
 | 
|      updateLayerTreeViewport();
 | 
|  
 | 
| @@ -2912,7 +2972,7 @@ void WebViewImpl::resetSavedScrollAndScaleState()
 | 
|  
 | 
|  void WebViewImpl::resetScrollAndScaleState()
 | 
|  {
 | 
| -    page()->setPageScaleFactor(1, IntPoint());
 | 
| +    setPageScaleFactor(1, IntPoint());
 | 
|  
 | 
|      // Clear out the values for the current history item. This will prevent the history item from clobbering the
 | 
|      // value determined during page scale initialization, which may be less than 1.
 | 
| @@ -3614,13 +3674,11 @@ bool WebViewImpl::allowsAcceleratedCompositing()
 | 
|  
 | 
|  void WebViewImpl::setRootGraphicsLayer(GraphicsLayer* layer)
 | 
|  {
 | 
| -    bool pinchVirtualViewportEnabled = page()->settings().pinchVirtualViewportEnabled();
 | 
|      suppressInvalidations(true);
 | 
|  
 | 
| -    if (pinchVirtualViewportEnabled) {
 | 
| +    if (pinchVirtualViewportEnabled()) {
 | 
|          PinchViewport& pinchViewport = page()->frameHost().pinchViewport();
 | 
|          pinchViewport.attachToLayerTree(layer, graphicsLayerFactory());
 | 
| -        pinchViewport.setSize(mainFrameImpl()->frame()->view()->frameRect().size());
 | 
|          if (layer) {
 | 
|              m_rootGraphicsLayer = pinchViewport.rootGraphicsLayer();
 | 
|              m_rootLayer = pinchViewport.rootGraphicsLayer()->platformLayer();
 | 
| @@ -3645,7 +3703,7 @@ void WebViewImpl::setRootGraphicsLayer(GraphicsLayer* layer)
 | 
|              m_layerTreeView->setRootLayer(*m_rootLayer);
 | 
|              // We register viewport layers here since there may not be a layer
 | 
|              // tree view prior to this point.
 | 
| -            if (pinchVirtualViewportEnabled) {
 | 
| +            if (pinchVirtualViewportEnabled()) {
 | 
|                  page()->frameHost().pinchViewport().registerLayersWithTreeView(m_layerTreeView);
 | 
|              } else {
 | 
|                  GraphicsLayer* rootScrollLayer = compositor()->scrollLayer();
 | 
| @@ -3655,7 +3713,7 @@ void WebViewImpl::setRootGraphicsLayer(GraphicsLayer* layer)
 | 
|              }
 | 
|          } else {
 | 
|              m_layerTreeView->clearRootLayer();
 | 
| -            if (pinchVirtualViewportEnabled)
 | 
| +            if (pinchVirtualViewportEnabled())
 | 
|                  page()->frameHost().pinchViewport().clearLayersForTreeView(m_layerTreeView);
 | 
|              else
 | 
|                  m_layerTreeView->clearViewportLayers();
 | 
| @@ -3812,12 +3870,13 @@ void WebViewImpl::applyScrollAndScale(const WebSize& scrollDelta, float pageScal
 | 
|      if (!mainFrameImpl() || !mainFrameImpl()->frameView())
 | 
|          return;
 | 
|  
 | 
| -    // With virtual viewport we need only set the scale (see TODO below).
 | 
| -    if (page()->settings().pinchVirtualViewportEnabled()) {
 | 
| -        WebSize scrollOffset = mainFrame()->scrollOffset();
 | 
| -        WebPoint scrollPoint(scrollOffset.width, scrollOffset.height);
 | 
| -        setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scrollPoint);
 | 
| -        m_doubleTapZoomPending = false;
 | 
| +    if (pinchVirtualViewportEnabled()) {
 | 
| +        if (pageScaleDelta != 1) {
 | 
| +            // When the virtual viewport is enabled, offsets are already set for us.
 | 
| +            setPinchViewportScaleFactor(pageScaleFactor() * pageScaleDelta);
 | 
| +            m_doubleTapZoomPending = false;
 | 
| +        }
 | 
| +
 | 
|          return;
 | 
|      }
 | 
|  
 | 
| 
 |