Fix for screen flickering on page have lots of contents size change
authorChanghyup Jwa <ch.jwa@samsung.com>
Tue, 26 Mar 2013 11:21:12 +0000 (20:21 +0900)
committerGerrit Code Review <gerrit2@kim11>
Thu, 4 Apr 2013 06:18:33 +0000 (15:18 +0900)
[Title] Fix for screen flickering on page have lots of contents size change
[issue#] Web-2826
[Problem] Screen is flickering continuosly
[Cause] ContentSize is incresing/decreasing continuosly
        and setVisibleContentRect is called whenever it's changed
[Solution] Fit viewport to content only on load finish

Change-Id: I7cf4676804774182a7d7a40aaf100c1e90e6eec0

Source/WebKit2/UIProcess/API/efl/EwkViewImpl.cpp
Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp
Source/WebKit2/UIProcess/API/efl/PageClientImpl.h

index a46d890..f6430b4 100755 (executable)
@@ -561,6 +561,8 @@ void EwkViewImpl::informLoadFinished()
 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
     pageProxy->setLoadingFinished(true);
 #endif
+    if (pageClient->wasViewportFitsToContent())
+        pageClient->fitViewportToContent();
 
 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
     ewk_view_form_password_data_fill(m_view);
index 04a095c..11bd36e 100755 (executable)
@@ -90,6 +90,8 @@ PageClientImpl::PageClientImpl(EwkViewImpl* viewImpl)
     , m_viewFocused(false)
     , m_viewWindowActive(true)
     , m_pageDidRendered(false)
+    , m_viewportAngle(0)
+    , m_viewportFitsToContent(false)
 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
     , m_visibleContentRect(IntRect())
     , m_scaleFactor(1.0f)
@@ -195,12 +197,6 @@ void PageClientImpl::updateViewportSize(const IntSize& viewportSize)
 
     // update viewport size of webkit
     m_visibleContentRect.setSize(viewportSize);
-
-    // Update visible content rect before resize viewport
-    // setVisibleContentRect() should be called once at here or ewk_view_focused_node_adjust()
-    if (!ewk_view_focused_node_adjust(m_viewImpl->view()) && m_pageDidRendered)
-        setVisibleContentRect(m_visibleContentRect, scaleFactor());
-
     m_viewImpl->page()->setViewportSize(viewportSize);
 }
 #endif
@@ -227,6 +223,21 @@ void PageClientImpl::initializeVisibleContentRect()
 #endif
 }
 
+double PageClientImpl::availableMinimumScale()
+{
+    // recalculate minimum scale factor if contents' width exceeds viewport layout width and userScalable is true.
+    // minimum scale factor shouldn't be smaller than 0.25(minimum zoom level)
+    IntSize contentsSize = m_viewImpl->page()->contentsSize();
+    double horizontalMinScale = max(((double)viewSize().width() / contentsSize.width()), 0.25);
+    double verticalMinScale = max(((double)viewSize().height() / contentsSize.height()), 0.25);
+    return max(horizontalMinScale, verticalMinScale);
+}
+
+void PageClientImpl::fitViewportToContent()
+{
+    setVisibleContentRect(m_visibleContentRect, m_viewportConstraints.minimumScale);
+}
+
 void PageClientImpl::setFocusedNodeRect(const IntRect& focusedNodeRect)
 {
     m_focusedNodeRect = focusedNodeRect;
@@ -355,31 +366,38 @@ void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
 
 void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes& attributes)
 {
-    float prevMinimumScale = m_viewportConstraints.minimumScale;
     m_viewportConstraints = computeViewportConstraints(attributes);
-    // setVisibleContentRect() is called to adjust visible content rect after device rotation
-    // In below cases, it shouldn't be called
-    // 1. page is not rendered yet
-    // 2. viewport attributes are changed by WebCore's empty document(progress == 0.1)
-    // 3. there's no input field zoom(device rotation without IME)
-    if (m_pageDidRendered && m_viewImpl->page()->estimatedProgress() > 0.1 && !ewk_view_focused_node_adjust(m_viewImpl->view())) {
-        IntSize contentsSize = m_viewImpl->page()->contentsSize();
-        double minimumScaleByContentWidth = max(((double)viewSize().width() / contentsSize.width()), 0.25);
-        float newScale = scaleFactor();
-
-        // If contents width exceeds viewport layout width and content is userScalable, update minimumScale.
-        if (m_viewportConstraints.userScalable)
-            m_viewportConstraints.minimumScale = minimumScaleByContentWidth;
-
-        // If zoom was fitted to width before the rotation, newScale should be fitted to width again.
-        if (fabs(scaleFactor() - prevMinimumScale) < numeric_limits<double>::epsilon())
+
+    // if content is reloaded, contents size will not be changed
+    // so, we need to calculate minimum scale here.
+    // if content size is changed later, minimum scale will be re-calculated on didChangeContentsSize()
+    if (m_viewportConstraints.userScalable)
+        m_viewportConstraints.minimumScale = availableMinimumScale();
+
+    // setVisibleContentRect() should be called to adjust visible content rect only when view is resized
+    if (!m_pageDidRendered || m_viewImpl->page()->estimatedProgress() <= 0.1)
+        return;
+
+    // if IME is opened, visible content rect will be updated by ewk_view_focused_node_adjust()
+    if (ewk_view_focused_node_adjust(m_viewImpl->view()))
+        return;
+
+    float newScale = scaleFactor();
+    Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewImpl->view()));
+    int angle = ecore_evas_rotation_get(ee);
+    bool isRotated = (angle != m_viewportAngle);
+
+    // if it's rotated, we need to fit content to viewport by minimize the scale
+    if (isRotated) {
+        m_viewportAngle = angle;
+        if (m_viewportFitsToContent)
             newScale = m_viewportConstraints.minimumScale;
+    }
 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
-        setVisibleContentRect(m_visibleContentRect, newScale);
+    setVisibleContentRect(m_visibleContentRect, newScale);
 #else
-        m_viewImpl->page()->scalePage(newScale, m_visibleContentRect.location());
+    m_viewImpl->page()->scalePage(newScale, m_visibleContentRect.location());
 #endif
-    }
 
 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_viewImpl->view()));
@@ -599,35 +617,29 @@ void PageClientImpl::didChangeContentsSize(const WebCore::IntSize size)
         drawingArea()->layerTreeCoordinatorProxy()->setContentsSize(WebCore::FloatSize(size.width(), size.height()));
 #endif
 
-    // But we should recalculate this when viewport argument's minimum scale is not fixed.
-    // if contents' width exceeds viewport layout width and userScalable is true.
-    // And minimumScaleByContentWidth shouldn't be smaller than 0.25(minimum zoom level)
-    double oldMinimumScale = m_viewportConstraints.minimumScale;
-    double newMinimumScale = max(((double)viewSize().width() / size.width()), 0.25);
-    bool isMinimized = fabs(scaleFactor() - oldMinimumScale) < numeric_limits<float>::epsilon();
-
     // if minimum scale factor is changed, update minimumScale.
-    if (m_viewportConstraints.userScalable
-        && fabs(oldMinimumScale - newMinimumScale) > numeric_limits<float>::epsilon()) {
+    if (m_viewportConstraints.userScalable) {
+        double minimumScale = availableMinimumScale();
+
         // Sometimes initializeVisibleContentRect can be called after content size change.
         // So, if initialScale is not set explicitly in content's meta viewport tag and is same to minimumScale, update initialScale too.
         if (!m_viewportConstraints.contentsDefinedInitialScale
-            && fabs(m_viewportConstraints.initialScale - oldMinimumScale) < numeric_limits<float>::epsilon())
-            m_viewportConstraints.initialScale = newMinimumScale;
-        m_viewportConstraints.minimumScale = newMinimumScale;
-    }
-
-    // If current scale factor was minimized, minimize new scale factor
-    if (m_pageDidRendered && isMinimized && m_viewportConstraints.userScalable) {
-#if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
-        setVisibleContentRect(m_visibleContentRect, newMinimumScale);
-#else
-        m_viewImpl->page()->scalePage(newMinimumScale, m_visibleContentRect.location());
-#endif
+            && fabs(m_viewportConstraints.initialScale - m_viewportConstraints.minimumScale) < numeric_limits<float>::epsilon())
+            m_viewportConstraints.initialScale = minimumScale;
+        m_viewportConstraints.minimumScale = minimumScale;
     }
 #else
     m_viewImpl->informContentsSizeChange(size);
 #endif
+    if (!m_pageDidRendered || m_viewImpl->page()->estimatedProgress() <= 0.1)
+        return;
+
+    // FIXME: Do we really need to adjust visible content rect at here?
+    // if contents size is changed smaller and visible content rect is outside of content area,
+    // adjust visible content rect
+    IntRect adjustedVisibleContentRect = adjustVisibleContentRect(m_visibleContentRect, scaleFactor());
+    if (adjustedVisibleContentRect != m_visibleContentRect)
+        setVisibleContentRect(m_visibleContentRect, scaleFactor());
 }
 
 void PageClientImpl::pageScaleFactorDidChange()
@@ -640,6 +652,7 @@ void PageClientImpl::didCommitLoadForMainFrame(bool)
 {
 #if OS(TIZEN)
     m_pageDidRendered = false;
+    m_viewportFitsToContent = false;
 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
     m_restoredScaleFactor = 0;
 #endif
@@ -786,6 +799,7 @@ void PageClientImpl::setVisibleContentRect(const IntRect& newRect, float newScal
 #endif
 
     m_scaleFactor = adjustScaleWithViewport(newScale);
+    m_viewportFitsToContent = fabs(m_scaleFactor - m_viewportConstraints.minimumScale) < numeric_limits<float>::epsilon();
     m_visibleContentRect.setLocation(newRect.location());
     m_visibleContentRect = adjustVisibleContentRect(m_visibleContentRect, m_scaleFactor);
 
index 213f78a..5abbb9a 100755 (executable)
@@ -113,6 +113,9 @@ public:
     TIZEN_VIRTUAL void updateViewportSize(const WebCore::IntSize& viewportSize);
 #endif
     void initializeVisibleContentRect();
+    double availableMinimumScale();
+    void fitViewportToContent();
+    bool wasViewportFitsToContent() { return m_viewportFitsToContent; }
 
     void setFocusedNodeRect(const WebCore::IntRect&);
     WebCore::IntRect focusedNodeRect() { return m_focusedNodeRect; };
@@ -388,6 +391,10 @@ protected:
 
     bool m_pageDidRendered;
 
+    // Both angle and wasMinimized are added to handle device rotation
+    int m_viewportAngle;
+    bool m_viewportFitsToContent;
+
     WebCore::IntRect m_focusedNodeRect;
 
 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)