Title: [140025] trunk/Source/WebKit/chromium
Revision
140025
Author
ael...@chromium.org
Date
2013-01-17 12:26:25 -0800 (Thu, 17 Jan 2013)

Log Message

[chromium] Make new-style page scale work with fixed layout
https://bugs.webkit.org/show_bug.cgi?id=106951

Reviewed by Adam Barth.

This makes non-CSS-transform page scaling work with fixed-layout mode,
including viewport tag support.

- dispatchViewportPropertiesDidChange() now works entirely with DIP
pixels instead of physical pixels, and is made compatible with
separating deviceScaleFactor from pageScaleFactor.

- In this mode, the "layout viewport" size in the pinch-zoom model is
made a first-class concept separate from the device size.  This
is a viewport with the same aspect ratio as the device but with the
layout width of the page.  This viewport is used:
  - As FrameView::visibleContentRect.
  - Returned from WebView::size().
  - Given to the compositor as layoutViewportSize.

- m_deviceScaleInCompositor is deleted as it's clearer to use the
applyDeviceScaleInCompositor setting directly.

* src/ChromeClientImpl.cpp:
(WebKit::ChromeClientImpl::dispatchViewportPropertiesDidChange):
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::WebViewImpl):
(WebKit::WebViewImpl::size):
(WebKit):
(WebKit::WebViewImpl::resize):
(WebKit::WebViewImpl::setPageScaleFactor):
(WebKit::WebViewImpl::setDeviceScaleFactor):
(WebKit::WebViewImpl::layoutSize):
(WebKit::WebViewImpl::computePageScaleFactorLimits):
(WebKit::WebViewImpl::dipSize):
(WebKit::WebViewImpl::didChangeContentsSize):
(WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
(WebKit::WebViewImpl::updateLayerTreeViewport):
* src/WebViewImpl.h:
(WebViewImpl):

Modified Paths

Diff

Modified: trunk/Source/WebKit/chromium/ChangeLog (140024 => 140025)


--- trunk/Source/WebKit/chromium/ChangeLog	2013-01-17 20:20:11 UTC (rev 140024)
+++ trunk/Source/WebKit/chromium/ChangeLog	2013-01-17 20:26:25 UTC (rev 140025)
@@ -1,3 +1,46 @@
+2013-01-17  Alexandre Elias  <ael...@chromium.org>
+
+        [chromium] Make new-style page scale work with fixed layout
+        https://bugs.webkit.org/show_bug.cgi?id=106951
+
+        Reviewed by Adam Barth.
+
+        This makes non-CSS-transform page scaling work with fixed-layout mode,
+        including viewport tag support.
+
+        - dispatchViewportPropertiesDidChange() now works entirely with DIP
+        pixels instead of physical pixels, and is made compatible with
+        separating deviceScaleFactor from pageScaleFactor.
+
+        - In this mode, the "layout viewport" size in the pinch-zoom model is
+        made a first-class concept separate from the device size.  This
+        is a viewport with the same aspect ratio as the device but with the
+        layout width of the page.  This viewport is used:
+          - As FrameView::visibleContentRect.
+          - Returned from WebView::size().
+          - Given to the compositor as layoutViewportSize.
+
+        - m_deviceScaleInCompositor is deleted as it's clearer to use the
+        applyDeviceScaleInCompositor setting directly.
+
+        * src/ChromeClientImpl.cpp:
+        (WebKit::ChromeClientImpl::dispatchViewportPropertiesDidChange):
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::WebViewImpl):
+        (WebKit::WebViewImpl::size):
+        (WebKit):
+        (WebKit::WebViewImpl::resize):
+        (WebKit::WebViewImpl::setPageScaleFactor):
+        (WebKit::WebViewImpl::setDeviceScaleFactor):
+        (WebKit::WebViewImpl::layoutSize):
+        (WebKit::WebViewImpl::computePageScaleFactorLimits):
+        (WebKit::WebViewImpl::dipSize):
+        (WebKit::WebViewImpl::didChangeContentsSize):
+        (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+        (WebKit::WebViewImpl::updateLayerTreeViewport):
+        * src/WebViewImpl.h:
+        (WebViewImpl):
+
 2013-01-17  Sheriff Bot  <webkit.review....@gmail.com>
 
         Unreviewed.  Rolled Chromium DEPS to r177369.  Requested by

Modified: trunk/Source/WebKit/chromium/src/ChromeClientImpl.cpp (140024 => 140025)


--- trunk/Source/WebKit/chromium/src/ChromeClientImpl.cpp	2013-01-17 20:20:11 UTC (rev 140024)
+++ trunk/Source/WebKit/chromium/src/ChromeClientImpl.cpp	2013-01-17 20:26:25 UTC (rev 140025)
@@ -96,6 +96,7 @@
 #include "WebPopupMenuInfo.h"
 #include "WebPopupType.h"
 #include "WebSettings.h"
+#include "WebSettingsImpl.h"
 #include "WebTextDirection.h"
 #include "WebViewClient.h"
 #include "WebViewImpl.h"
@@ -643,47 +644,37 @@
     if (!m_webView->isFixedLayoutModeEnabled() || !m_webView->client() || !m_webView->page())
         return;
 
-    WebViewClient* client = m_webView->client();
-    WebSize deviceSize = m_webView->size();
-    // If the window size has not been set yet don't attempt to set the viewport
-    if (!deviceSize.width || !deviceSize.height)
+    IntSize viewportSize = m_webView->dipSize();
+    float deviceScaleFactor = m_webView->client()->screenInfo().deviceScaleFactor;
+
+    // If the window size has not been set yet don't attempt to set the viewport.
+    if (!viewportSize.width() || !viewportSize.height())
         return;
 
-    int viewportWidthInDIPs = m_webView->dipSize().width();
-    ViewportArguments effectiveViewportArguments;
-    int effectiveFallbackWidth;
+    ViewportAttributes computed;
     if (m_webView->settings()->viewportEnabled()) {
-        effectiveViewportArguments = arguments;
-        effectiveFallbackWidth = std::max(m_webView->page()->settings()->layoutFallbackWidth(), viewportWidthInDIPs);
+        computed = arguments.resolve(viewportSize, viewportSize, m_webView->page()->settings()->layoutFallbackWidth());
     } else {
-        // This is for Android WebView to use layout width in device-independent pixels.
-        // Once WebViewImpl on Android will start using DIP pixels size,
-        // dispatchViewportPropertiesDidChange can bail out when viewport is disabled.
-        effectiveViewportArguments = ViewportArguments();
-        effectiveFallbackWidth = viewportWidthInDIPs;
+        // If viewport tag is disabled but fixed layout is still enabled, (for
+        // example, on Android WebView with UseWideViewport false), compute
+        // based on the default viewport arguments.
+        computed = ViewportArguments().resolve(viewportSize, viewportSize, viewportSize.width());
     }
-    float devicePixelRatio = client->screenInfo().deviceScaleFactor;
-    // Call the common viewport computing logic in ViewportArguments.cpp.
-    ViewportAttributes computed = computeViewportAttributes(
-        effectiveViewportArguments, effectiveFallbackWidth, deviceSize.width, deviceSize.height,
-        devicePixelRatio, IntSize(deviceSize.width, deviceSize.height));
-
     restrictScaleFactorToInitialScaleIfNotUserScalable(computed);
 
     if (m_webView->ignoreViewportTagMaximumScale()) {
         computed.maximumScale = max(computed.maximumScale, m_webView->maxPageScaleFactor);
         computed.userScalable = true;
     }
+    if (!m_webView->settingsImpl()->applyDeviceScaleFactorInCompositor())
+        computed.initialScale *= deviceScaleFactor;
 
-    int layoutWidth = computed.layoutSize.width();
-    int layoutHeight = computed.layoutSize.height();
-    m_webView->setFixedLayoutSize(IntSize(layoutWidth, layoutHeight));
-
     bool needInitializePageScale = !m_webView->isPageScaleFactorSet();
-    m_webView->setDeviceScaleFactor(devicePixelRatio);
+    m_webView->setFixedLayoutSize(flooredIntSize(computed.layoutSize));
+    m_webView->setDeviceScaleFactor(deviceScaleFactor);
     m_webView->setPageScaleFactorLimits(computed.minimumScale, computed.maximumScale);
     if (needInitializePageScale)
-        m_webView->setPageScaleFactorPreservingScrollOffset(computed.initialScale * devicePixelRatio);
+        m_webView->setPageScaleFactorPreservingScrollOffset(computed.initialScale);
 #endif
 }
 

Modified: trunk/Source/WebKit/chromium/src/WebViewImpl.cpp (140024 => 140025)


--- trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2013-01-17 20:20:11 UTC (rev 140024)
+++ trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2013-01-17 20:26:25 UTC (rev 140025)
@@ -428,7 +428,6 @@
     , m_compositorCreationFailed(false)
     , m_recreatingGraphicsContext(false)
     , m_compositorSurfaceReady(false)
-    , m_deviceScaleInCompositor(1)
     , m_inputHandlerIdentifier(-1)
 #endif
 #if ENABLE(INPUT_SPEECH)
@@ -1580,6 +1579,14 @@
         pluginContainer->willStartLiveResize();
 }
 
+WebSize WebViewImpl::size()
+{
+    if (isFixedLayoutModeEnabled() && settingsImpl()->applyPageScaleFactorInCompositor())
+        return layoutSize();
+
+    return m_size;
+}
+
 void WebViewImpl::resize(const WebSize& newSize)
 {
     if (m_shouldAutoResize || m_size == newSize)
@@ -1607,15 +1614,18 @@
     if (!agentPrivate || !agentPrivate->metricsOverridden()) {
         WebFrameImpl* webFrame = mainFrameImpl();
         if (webFrame->frameView())
-            webFrame->frameView()->resize(newSize.width, newSize.height);
+            webFrame->frameView()->resize(size());
     }
 
 #if ENABLE(VIEWPORT)
     if (settings()->viewportEnabled()) {
-        // Relayout immediately to obtain the new content width, which is needed
-        // to calculate the minimum scale limit.
-        view->layout();
+        if (!settingsImpl()->applyPageScaleFactorInCompositor()) {
+            // Relayout immediately to obtain the new content width, which is needed
+            // to calculate the minimum scale limit.
+            view->layout();
+        }
         computePageScaleFactorLimits();
+
         // When the device rotates:
         // - If the page width is unchanged, then zoom by new width/old width
         //   such as to keep the same content horizontally onscreen.
@@ -1631,7 +1641,8 @@
         float scaleMultiplier = viewportWidthRatio / fixedLayoutWidthRatio;
         if (scaleMultiplier != 1) {
             IntSize scrollOffsetAtNewScale = oldScrollOffset;
-            scrollOffsetAtNewScale.scale(scaleMultiplier);
+            if (!settingsImpl()->applyPageScaleFactorInCompositor())
+                scrollOffsetAtNewScale.scale(scaleMultiplier);
             setPageScaleFactor(oldPageScaleFactor * scaleMultiplier, IntPoint(scrollOffsetAtNewScale));
         }
     }
@@ -2915,12 +2926,6 @@
     if (!scaleFactor)
         scaleFactor = 1;
 
-    if (m_deviceScaleInCompositor != 1) {
-        // Don't allow page scaling when compositor scaling is being used,
-        // as they are currently incompatible.
-        ASSERT(scaleFactor == 1);
-    }
-
     scaleFactor = clampPageScaleFactorToLimits(scaleFactor);
     WebPoint scrollOffset;
     if (!m_page->settings()->applyPageScaleFactorInCompositor()) {
@@ -2954,16 +2959,8 @@
 
     page()->setDeviceScaleFactor(scaleFactor);
 
-    if (m_layerTreeView && m_webSettings->applyDeviceScaleFactorInCompositor()) {
-        m_deviceScaleInCompositor = page()->deviceScaleFactor();
-        m_layerTreeView->setDeviceScaleFactor(m_deviceScaleInCompositor);
-    }
-    if (m_deviceScaleInCompositor != 1) {
-        // Don't allow page scaling when compositor scaling is being used,
-        // as they are currently incompatible. This means the deviceScale
-        // needs to match the one in the compositor.
-        ASSERT(scaleFactor == m_deviceScaleInCompositor);
-    }
+    if (m_layerTreeView && m_webSettings->applyDeviceScaleFactorInCompositor())
+        m_layerTreeView->setDeviceScaleFactor(scaleFactor);
 }
 
 bool WebViewImpl::isFixedLayoutModeEnabled() const
@@ -3036,6 +3033,19 @@
     return root->unscaledDocumentRect().size();
 }
 
+IntSize WebViewImpl::layoutSize() const
+{
+    if (!isFixedLayoutModeEnabled())
+        return m_size;
+
+    IntSize contentSize = unscaledContentsSize(page()->mainFrame());
+    if (fixedLayoutSize().width >= contentSize.width())
+        return fixedLayoutSize();
+
+    float aspectRatio = static_cast<float>(m_size.height) / m_size.width;
+    return IntSize(contentSize.width(), contentSize.width() * aspectRatio);
+}
+
 bool WebViewImpl::computePageScaleFactorLimits()
 {
     if (m_pageDefinedMinimumPageScaleFactor == -1 || m_pageDefinedMaximumPageScaleFactor == -1)
@@ -3044,10 +3054,18 @@
     if (!mainFrame() || !page() || !page()->mainFrame() || !page()->mainFrame()->view())
         return false;
 
-    m_minimumPageScaleFactor = min(max(m_pageDefinedMinimumPageScaleFactor, minPageScaleFactor), maxPageScaleFactor) * (deviceScaleFactor() / m_deviceScaleInCompositor);
-    m_maximumPageScaleFactor = max(min(m_pageDefinedMaximumPageScaleFactor, maxPageScaleFactor), minPageScaleFactor) * (deviceScaleFactor() / m_deviceScaleInCompositor);
+    FrameView* view = page()->mainFrame()->view();
 
-    int viewWidthNotIncludingScrollbars = page()->mainFrame()->view()->visibleContentRect(false).width();
+    m_minimumPageScaleFactor = min(max(m_pageDefinedMinimumPageScaleFactor, minPageScaleFactor), maxPageScaleFactor);
+    m_maximumPageScaleFactor = max(min(m_pageDefinedMaximumPageScaleFactor, maxPageScaleFactor), minPageScaleFactor);
+    if (!m_webSettings->applyDeviceScaleFactorInCompositor()) {
+        m_minimumPageScaleFactor *= deviceScaleFactor();
+        m_maximumPageScaleFactor *= deviceScaleFactor();
+    }
+
+    int viewWidthNotIncludingScrollbars = m_size.width;
+    if (viewWidthNotIncludingScrollbars && view->verticalScrollbar() && !view->verticalScrollbar()->isOverlayScrollbar())
+        viewWidthNotIncludingScrollbars -= view->verticalScrollbar()->width();
     int unscaledContentsWidth = unscaledContentsSize(page()->mainFrame()).width();
     if (viewWidthNotIncludingScrollbars && unscaledContentsWidth) {
         // Limit page scaling down to the document width.
@@ -3146,13 +3164,12 @@
     frame->view()->setFixedLayoutSize(layoutSize);
 }
 
-WebCore::FloatSize WebViewImpl::dipSize() const
+WebCore::IntSize WebViewImpl::dipSize() const
 {
-    if (!page() || m_webSettings->applyDeviceScaleFactorInCompositor())
-        return FloatSize(m_size.width, m_size.height);
-
-    float deviceScaleFactor = page()->deviceScaleFactor();
-    return FloatSize(m_size.width / deviceScaleFactor, m_size.height / deviceScaleFactor);
+    IntSize dipSize = m_size;
+    if (!m_webSettings->applyDeviceScaleFactorInCompositor())
+        dipSize.scale(1 / m_client->screenInfo().deviceScaleFactor);
+    return dipSize;
 }
 
 void WebViewImpl::performMediaPlayerAction(const WebMediaPlayerAction& action,
@@ -3697,27 +3714,29 @@
 void WebViewImpl::didChangeContentsSize()
 {
 #if ENABLE(VIEWPORT)
-    if (!settings()->viewportEnabled())
+    if (!settings()->viewportEnabled() || !mainFrameImpl())
         return;
 
-    bool didChangeScale = false;
+    bool mayNeedLayout = false;
     if (!isPageScaleFactorSet()) {
         // If the viewport tag failed to be processed earlier, we need
         // to recompute it now.
         ViewportArguments viewportArguments = mainFrameImpl()->frame()->document()->viewportArguments();
         m_page->chrome()->client()->dispatchViewportPropertiesDidChange(viewportArguments);
-        didChangeScale = true;
+        mayNeedLayout = true;
     } else
-        didChangeScale = computePageScaleFactorLimits();
+        mayNeedLayout = computePageScaleFactorLimits();
 
-    if (!didChangeScale)
-        return;
+    FrameView* view = mainFrameImpl()->frameView();
+    if (settingsImpl()->applyPageScaleFactorInCompositor() && view && view->visibleContentRect(true).width() != layoutSize().width()) {
+        view->resize(layoutSize());
+        mayNeedLayout = true;
+    }
 
-    if (!mainFrameImpl())
-        return;
-
-    FrameView* view = mainFrameImpl()->frameView();
-    if (view && view->needsLayout())
+    // didChangeContentsSize() may be called from FrameView::layout; we need to
+    // relayout to avoid triggering the assertion that needsLayout() isn't set
+    // at the end of a layout.
+    if (mayNeedLayout && view && view->needsLayout())
         view->layout();
 #endif
 }
@@ -4053,13 +4072,9 @@
             m_ownsLayerTreeView = true;
         }
         if (m_layerTreeView) {
-            if (m_webSettings->applyDeviceScaleFactorInCompositor() && page()->deviceScaleFactor() != 1) {
-                ASSERT(page()->deviceScaleFactor());
+            if (m_webSettings->applyDeviceScaleFactorInCompositor() && page()->deviceScaleFactor() != 1)
+                setDeviceScaleFactor(page()->deviceScaleFactor());
 
-                m_deviceScaleInCompositor = page()->deviceScaleFactor();
-                setDeviceScaleFactor(m_deviceScaleInCompositor);
-            }
-
             bool visible = page()->visibilityState() == PageVisibilityStateVisible;
             m_layerTreeView->setVisible(visible);
             m_layerTreeView->setPageScaleFactorAndLimits(pageScaleFactor(), m_minimumPageScaleFactor, m_maximumPageScaleFactor);
@@ -4197,12 +4212,11 @@
 
     m_nonCompositedContentHost->setViewport(visibleRect.size(), view->contentsSize(), scroll, view->scrollOrigin());
 
-    IntSize layoutViewportSize = size();
-    IntSize deviceViewportSize = size();
+    IntSize layoutViewportSize = visibleRect.size();
+    IntSize deviceViewportSize = m_size;
+    if (m_webSettings->applyDeviceScaleFactorInCompositor())
+        deviceViewportSize.scale(deviceScaleFactor());
 
-    // This part of the deviceScale will be used to scale the contents of
-    // the NCCH's GraphicsLayer.
-    deviceViewportSize.scale(m_deviceScaleInCompositor);
     m_layerTreeView->setViewportSize(layoutViewportSize, deviceViewportSize);
     m_layerTreeView->setPageScaleFactorAndLimits(pageScaleFactor(), m_minimumPageScaleFactor, m_maximumPageScaleFactor);
 }

Modified: trunk/Source/WebKit/chromium/src/WebViewImpl.h (140024 => 140025)


--- trunk/Source/WebKit/chromium/src/WebViewImpl.h	2013-01-17 20:20:11 UTC (rev 140024)
+++ trunk/Source/WebKit/chromium/src/WebViewImpl.h	2013-01-17 20:26:25 UTC (rev 140025)
@@ -136,7 +136,7 @@
 
     // WebWidget methods:
     virtual void close();
-    virtual WebSize size() { return m_size; }
+    virtual WebSize size();
     virtual void willStartLiveResize();
     virtual void resize(const WebSize&);
     virtual void willEndLiveResize();
@@ -243,7 +243,6 @@
     virtual void enableFixedLayoutMode(bool enable);
     virtual WebSize fixedLayoutSize() const;
     virtual void setFixedLayoutSize(const WebSize&);
-    virtual WebCore::FloatSize dipSize() const;
     virtual void enableAutoResizeMode(
         const WebSize& minSize,
         const WebSize& maxSize);
@@ -460,6 +459,9 @@
         return m_maxAutoSize;
     }
 
+    WebCore::IntSize dipSize() const;
+    WebCore::IntSize layoutSize() const;
+
     // Set the disposition for how this webview is to be initially shown.
     void setInitialNavigationPolicy(WebNavigationPolicy policy)
     {
@@ -851,7 +853,6 @@
     // If true, the graphics context is being restored.
     bool m_recreatingGraphicsContext;
     bool m_compositorSurfaceReady;
-    float m_deviceScaleInCompositor;
     int m_inputHandlerIdentifier;
 #endif
     static const WebInputEvent* m_currentInputEvent;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to