Title: [127388] trunk/Source/WebCore
Revision
127388
Author
[email protected]
Date
2012-09-02 03:34:26 -0700 (Sun, 02 Sep 2012)

Log Message

Repaints should not be deferred after initial page load is complete
https://bugs.webkit.org/show_bug.cgi?id=95480

Reviewed by Simon Fraser

Any dynamically triggered resource loading currently sends us back to deferred paint mode, making animation choppy. 
This is not the intention of this code.

This patch adds an additional condition that prevents page from re-entering deferred repaint mode after the initial
load has completed. It also cleans up the code slightly.

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::checkCompleted):
        
    Add additional call to checkStopDelayingDeferredRepaints() after a frame load completes as the
    new condition in shouldUseLoadTimeDeferredRepaintDelay() looks for this change too.

* page/FrameView.cpp:
(WebCore):
        
    Reduced the normal delay from 25ms to 16ms to not interfere with full framerate animation.

(WebCore::FrameView::syncCompositingStateForThisFrame):
(WebCore::FrameView::checkFlushDeferredRepaintsAfterLoadComplete):
        
    Ensure the repaint delay is reset after load completes even if we don't currently need a repaint.

(WebCore::FrameView::flushDeferredRepaints):
        
    We had to identical functions, flushDeferredRepaints() and stopDelayingDeferredRepaints(). Remove
    the latter.

(WebCore::FrameView::shouldUseLoadTimeDeferredRepaintDelay):
        
    Factor the test for using load time repaint timings to a functions. The test for
    initial page load having completed is new.

(WebCore::FrameView::updateDeferredRepaintDelay):
(WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
(WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelay):
* page/FrameView.h:
(FrameView):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (127387 => 127388)


--- trunk/Source/WebCore/ChangeLog	2012-09-02 08:34:17 UTC (rev 127387)
+++ trunk/Source/WebCore/ChangeLog	2012-09-02 10:34:26 UTC (rev 127388)
@@ -1,3 +1,48 @@
+2012-08-31  Antti Koivisto  <[email protected]>
+
+        Repaints should not be deferred after initial page load is complete
+        https://bugs.webkit.org/show_bug.cgi?id=95480
+
+        Reviewed by Simon Fraser
+
+        Any dynamically triggered resource loading currently sends us back to deferred paint mode, making animation choppy. 
+        This is not the intention of this code.
+
+        This patch adds an additional condition that prevents page from re-entering deferred repaint mode after the initial
+        load has completed. It also cleans up the code slightly.
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::checkCompleted):
+        
+            Add additional call to checkStopDelayingDeferredRepaints() after a frame load completes as the
+            new condition in shouldUseLoadTimeDeferredRepaintDelay() looks for this change too.
+
+        * page/FrameView.cpp:
+        (WebCore):
+        
+            Reduced the normal delay from 25ms to 16ms to not interfere with full framerate animation.
+
+        (WebCore::FrameView::syncCompositingStateForThisFrame):
+        (WebCore::FrameView::checkFlushDeferredRepaintsAfterLoadComplete):
+        
+            Ensure the repaint delay is reset after load completes even if we don't currently need a repaint.
+
+        (WebCore::FrameView::flushDeferredRepaints):
+        
+            We had to identical functions, flushDeferredRepaints() and stopDelayingDeferredRepaints(). Remove
+            the latter.
+
+        (WebCore::FrameView::shouldUseLoadTimeDeferredRepaintDelay):
+        
+            Factor the test for using load time repaint timings to a functions. The test for
+            initial page load having completed is new.
+
+        (WebCore::FrameView::updateDeferredRepaintDelay):
+        (WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
+        (WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelay):
+        * page/FrameView.h:
+        (FrameView):
+
 2012-09-02  Filip Pizlo  <[email protected]>
 
         Don't create access error strings if there is no access error

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (127387 => 127388)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2012-09-02 08:34:17 UTC (rev 127387)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2012-09-02 10:34:26 UTC (rev 127388)
@@ -718,7 +718,7 @@
     m_shouldCallCheckCompleted = false;
 
     if (m_frame->view())
-        m_frame->view()->checkStopDelayingDeferredRepaints();
+        m_frame->view()->checkFlushDeferredRepaintsAfterLoadComplete();
 
     // Have we completed before?
     if (m_isComplete)
@@ -753,6 +753,9 @@
     completed();
     if (m_frame->page())
         checkLoadComplete();
+
+    if (m_frame->view())
+        m_frame->view()->checkFlushDeferredRepaintsAfterLoadComplete();
 }
 
 void FrameLoader::checkTimerFired(Timer<FrameLoader>*)

Modified: trunk/Source/WebCore/page/FrameView.cpp (127387 => 127388)


--- trunk/Source/WebCore/page/FrameView.cpp	2012-09-02 08:34:17 UTC (rev 127387)
+++ trunk/Source/WebCore/page/FrameView.cpp	2012-09-02 10:34:26 UTC (rev 127388)
@@ -101,7 +101,7 @@
 // Should be removed when applications start using runtime configuration.
 #if ENABLE(REPAINT_THROTTLING)
 // Normal delay
-double FrameView::s_deferredRepaintDelay = 0.025;
+double FrameView::s_normalDeferredRepaintDelay = 0.016;
 // Negative value would mean that first few repaints happen without a delay
 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
 // The delay grows on each repaint to this maximum value
@@ -112,7 +112,7 @@
 // FIXME: Repaint throttling could be good to have on all platform.
 // The balance between CPU use and repaint frequency will need some tuning for desktop.
 // More hooks may be needed to reset the delay on things like GIF and CSS animations.
-double FrameView::s_deferredRepaintDelay = 0;
+double FrameView::s_normalDeferredRepaintDelay = 0;
 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
@@ -806,7 +806,7 @@
 
     // If we sync compositing layers and allow the repaint to be deferred, there is time for a
     // visible flash to occur. Instead, stop the deferred repaint timer and repaint immediately.
-    stopDelayingDeferredRepaints();
+    flushDeferredRepaints();
 
     root->compositor()->flushPendingLayerChanges(rootFrameForSync == m_frame);
 
@@ -1992,25 +1992,22 @@
     m_deferredRepaintTimer.startOneShot(delay);
 }
 
-void FrameView::checkStopDelayingDeferredRepaints()
+void FrameView::checkFlushDeferredRepaintsAfterLoadComplete()
 {
-    Document* document = m_frame->document();
-    if (document && (document->parsing() || document->cachedResourceLoader()->requestCount()))
+    if (shouldUseLoadTimeDeferredRepaintDelay())
         return;
+    m_deferredRepaintDelay = s_normalDeferredRepaintDelay;
+    flushDeferredRepaints();
+}
 
-    stopDelayingDeferredRepaints();
-}
-    
-void FrameView::stopDelayingDeferredRepaints()
+void FrameView::flushDeferredRepaints()
 {
     if (!m_deferredRepaintTimer.isActive())
         return;
-
     m_deferredRepaintTimer.stop();
-
     doDeferredRepaints();
 }
-    
+
 void FrameView::doDeferredRepaints()
 {
     if (m_disableRepaints)
@@ -2035,21 +2032,32 @@
     m_repaintRects.clear();
     m_repaintCount = 0;
     
-    updateDeferredRepaintDelay();
+    updateDeferredRepaintDelayAfterRepaint();
 }
 
-void FrameView::updateDeferredRepaintDelay()
+bool FrameView::shouldUseLoadTimeDeferredRepaintDelay() const
 {
+    // Don't defer after the initial load of the page has been completed.
+    if (m_frame->tree()->top()->loader()->isComplete())
+        return false;
     Document* document = m_frame->document();
-    if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) {
-        m_deferredRepaintDelay = s_deferredRepaintDelay;
+    if (!document)
+        return false;
+    if (document->parsing())
+        return true;
+    if (document->cachedResourceLoader()->requestCount())
+        return true;
+    return false;
+}
+
+void FrameView::updateDeferredRepaintDelayAfterRepaint()
+{
+    if (!shouldUseLoadTimeDeferredRepaintDelay()) {
+        m_deferredRepaintDelay = s_normalDeferredRepaintDelay;
         return;
     }
-    if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
-        m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
-        if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
-            m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
-    }
+    double incrementedRepaintDelay = m_deferredRepaintDelay + s_deferredRepaintDelayIncrementDuringLoading;
+    m_deferredRepaintDelay = std::min(incrementedRepaintDelay, s_maxDeferredRepaintDelayDuringLoading);
 }
 
 void FrameView::resetDeferredRepaintDelay()
@@ -3314,14 +3322,6 @@
     // This assert ensures that parent frames are clean, when child frames finished updating layout and style.
     ASSERT(!needsLayout());
 }
-    
-void FrameView::flushDeferredRepaints()
-{
-    if (!m_deferredRepaintTimer.isActive())
-        return;
-    m_deferredRepaintTimer.stop();
-    doDeferredRepaints();
-}
 
 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
 {
@@ -3571,7 +3571,7 @@
 // Normal delay
 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
 {
-    s_deferredRepaintDelay = p;
+    s_normalDeferredRepaintDelay = p;
 }
 
 // Negative value would mean that first few repaints happen without a delay

Modified: trunk/Source/WebCore/page/FrameView.h (127387 => 127388)


--- trunk/Source/WebCore/page/FrameView.h	2012-09-02 08:34:17 UTC (rev 127387)
+++ trunk/Source/WebCore/page/FrameView.h	2012-09-02 10:34:26 UTC (rev 127388)
@@ -212,8 +212,8 @@
 
     void beginDeferredRepaints();
     void endDeferredRepaints();
-    void checkStopDelayingDeferredRepaints();
-    void stopDelayingDeferredRepaints();
+    void checkFlushDeferredRepaintsAfterLoadComplete();
+    void flushDeferredRepaints();
     void startDeferredRepaintTimer(double delay);
     void resetDeferredRepaintDelay();
 
@@ -265,7 +265,6 @@
     static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
     
     void updateLayoutAndStyleIfNeededRecursive();
-    void flushDeferredRepaints();
 
     void incrementVisuallyNonEmptyCharacterCount(unsigned);
     void incrementVisuallyNonEmptyPixelCount(const IntSize&);
@@ -428,9 +427,10 @@
 
     virtual void notifyPageThatContentAreaWillPaint() const;
 
+    bool shouldUseLoadTimeDeferredRepaintDelay() const;
     void deferredRepaintTimerFired(Timer<FrameView>*);
     void doDeferredRepaints();
-    void updateDeferredRepaintDelay();
+    void updateDeferredRepaintDelayAfterRepaint();
     double adjustedDeferredRepaintDelay() const;
 
     bool updateWidgets();
@@ -546,7 +546,7 @@
     OwnPtr<ScrollableAreaSet> m_scrollableAreas;
     OwnPtr<FixedObjectSet> m_fixedObjects;
 
-    static double s_deferredRepaintDelay;
+    static double s_normalDeferredRepaintDelay;
     static double s_initialDeferredRepaintDelayDuringLoading;
     static double s_maxDeferredRepaintDelayDuringLoading;
     static double s_deferredRepaintDelayIncrementDuringLoading;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to