Don't enable speculative tiles immediately after main load stops progressing
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Jan 2014 22:03:27 +0000 (22:03 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Jan 2014 22:03:27 +0000 (22:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127507

Reviewed by Andreas Kling.

It is common for timers and events to trigger more loading after the initial main frame loading
has completed. We should delay a bit before enabling speculative tiles and keep them disabled
if loading still continues.

* page/FrameView.cpp:
(WebCore::FrameView::FrameView):
(WebCore::FrameView::adjustTiledBackingCoverage):
(WebCore::shouldEnableSpeculativeTilingDuringLoading):
(WebCore::FrameView::enableSpeculativeTilingIfNeeded):

    When load progression stops wait 0.5s before enabling speculative tiles.

(WebCore::FrameView::speculativeTilingEnableTimerFired):

    Don't enable speculative tiles if the progression has started again. Instead restart the timer.

* page/FrameView.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::RenderLayerBacking):
(WebCore::computeTileCoverage):

    Move the FrameView level code to FrameView (so we don't need to add a timer to every RenderLayerBacking).

* rendering/RenderLayerBacking.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@162640 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h

index 79c4179..9a9930d 100644 (file)
@@ -1,5 +1,37 @@
 2014-01-23  Antti Koivisto  <antti@apple.com>
 
+        Don't enable speculative tiles immediately after main load stops progressing
+        https://bugs.webkit.org/show_bug.cgi?id=127507
+
+        Reviewed by Andreas Kling.
+
+        It is common for timers and events to trigger more loading after the initial main frame loading
+        has completed. We should delay a bit before enabling speculative tiles and keep them disabled 
+        if loading still continues.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::FrameView):
+        (WebCore::FrameView::adjustTiledBackingCoverage):
+        (WebCore::shouldEnableSpeculativeTilingDuringLoading):
+        (WebCore::FrameView::enableSpeculativeTilingIfNeeded):
+        
+            When load progression stops wait 0.5s before enabling speculative tiles.
+
+        (WebCore::FrameView::speculativeTilingEnableTimerFired):
+        
+            Don't enable speculative tiles if the progression has started again. Instead restart the timer.
+
+        * page/FrameView.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::RenderLayerBacking):
+        (WebCore::computeTileCoverage):
+        
+            Move the FrameView level code to FrameView (so we don't need to add a timer to every RenderLayerBacking).
+
+        * rendering/RenderLayerBacking.h:
+
+2014-01-23  Antti Koivisto  <antti@apple.com>
+
         Loads started soon after main frame completion should be considered part of the main load
         https://bugs.webkit.org/show_bug.cgi?id=127504
 
index 43204d4..b8beacc 100644 (file)
@@ -204,6 +204,8 @@ FrameView::FrameView(Frame& frame)
     , m_exposedRect(FloatRect::infiniteRect())
     , m_deferSetNeedsLayouts(0)
     , m_setNeedsLayoutWasDeferred(false)
+    , m_speculativeTilingEnabled(false)
+    , m_speculativeTilingEnableTimer(this, &FrameView::speculativeTilingEnableTimerFired)
 #if PLATFORM(IOS)
     , m_useCustomFixedPositionLayoutRect(false)
 #endif
@@ -2426,6 +2428,9 @@ void FrameView::updateLayerFlushThrottlingInAllFrames()
 
 void FrameView::adjustTiledBackingCoverage()
 {
+    if (!m_speculativeTilingEnabled)
+        enableSpeculativeTilingIfNeeded();
+
 #if USE(ACCELERATED_COMPOSITING)
     RenderView* renderView = this->renderView();
     if (renderView && renderView->layer()->backing())
@@ -2433,10 +2438,39 @@ void FrameView::adjustTiledBackingCoverage()
 #endif
 #if PLATFORM(IOS)
     if (TileCache* tileCache = this->tileCache())
-        tileCache->setSpeculativeTileCreationEnabled(!m_frame->page()->progress().isMainLoadProgressing());
+        tileCache->setSpeculativeTileCreationEnabled(m_speculativeTilingEnabled);
 #endif
 }
 
+static bool shouldEnableSpeculativeTilingDuringLoading(const FrameView& view)
+{
+    return view.isVisuallyNonEmpty() && !view.frame().page()->progress().isMainLoadProgressing();
+}
+
+void FrameView::enableSpeculativeTilingIfNeeded()
+{
+    ASSERT(!m_speculativeTilingEnabled);
+    if (m_wasScrolledByUser) {
+        m_speculativeTilingEnabled = true;
+        return;
+    }
+    if (!shouldEnableSpeculativeTilingDuringLoading(*this))
+        return;
+    if (m_speculativeTilingEnableTimer.isActive())
+        return;
+    // Delay enabling a bit as load completion may trigger further loading from scripts.
+    static const double speculativeTilingEnableDelay = 0.5;
+    m_speculativeTilingEnableTimer.startOneShot(speculativeTilingEnableDelay);
+}
+
+void FrameView::speculativeTilingEnableTimerFired(Timer<FrameView>&)
+{
+    if (m_speculativeTilingEnabled)
+        return;
+    m_speculativeTilingEnabled = shouldEnableSpeculativeTilingDuringLoading(*this);
+    adjustTiledBackingCoverage();
+}
+
 void FrameView::layoutTimerFired(Timer<FrameView>&)
 {
 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
index 164673b..ce46655 100644 (file)
@@ -269,6 +269,7 @@ public:
 
     void updateLayerFlushThrottlingInAllFrames();
     void adjustTiledBackingCoverage();
+    bool speculativeTilingEnabled() const { return m_speculativeTilingEnabled; }
 
 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
     void updateAnnotatedRegions();
@@ -557,6 +558,9 @@ private:
     void updateDeferredRepaintDelayAfterRepaint();
     double adjustedDeferredRepaintDelay() const;
 
+    void enableSpeculativeTilingIfNeeded();
+    void speculativeTilingEnableTimerFired(Timer<FrameView>&);
+
     bool updateEmbeddedObjects();
     void updateEmbeddedObject(RenderEmbeddedObject&);
     void scrollToAnchor();
@@ -664,6 +668,9 @@ private:
     // Renderer to hold our custom scroll corner.
     RenderPtr<RenderScrollbarPart> m_scrollCorner;
 
+    bool m_speculativeTilingEnabled;
+    Timer<FrameView> m_speculativeTilingEnableTimer;
+
 #if PLATFORM(IOS)
     bool m_useCustomFixedPositionLayoutRect;
     IntRect m_customFixedPositionLayoutRect;
index 3fac275..f57645f 100644 (file)
@@ -123,7 +123,6 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
     , m_canCompositeFilters(false)
 #endif
     , m_backgroundLayerPaintsFixedRootBackground(false)
-    , m_didSwitchToFullTileCoverageDuringLoading(false)
 {
     Page* page = renderer().frame().page();
 
@@ -220,14 +219,7 @@ static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backin
 
     TiledBacking::TileCoverage tileCoverage = TiledBacking::CoverageForVisibleArea;
     bool useMinimalTilesDuringLiveResize = frameView.inLiveResize();
-    bool useMinimalTilesDuringLoading = false;
-    // Avoid churn.
-    if (!backing->didSwitchToFullTileCoverageDuringLoading()) {
-        useMinimalTilesDuringLoading = !frameView.isVisuallyNonEmpty() || (frameView.frame().page()->progress().isMainLoadProgressing() && !frameView.wasScrolledByUser());
-        if (!useMinimalTilesDuringLoading)
-            backing->setDidSwitchToFullTileCoverageDuringLoading();
-    }
-    if (!(useMinimalTilesDuringLoading || useMinimalTilesDuringLiveResize)) {
+    if (frameView.speculativeTilingEnabled() && !useMinimalTilesDuringLiveResize) {
         bool clipsToExposedRect = !frameView.exposedRect().isInfinite();
         if (frameView.horizontalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
             tileCoverage |= TiledBacking::CoverageForHorizontalScrolling;
index 9645e05..ce0f420 100644 (file)
@@ -202,9 +202,6 @@ public:
     // Return an estimate of the backing store area (in pixels) allocated by this object's GraphicsLayers.
     double backingStoreMemoryEstimate() const;
 
-    bool didSwitchToFullTileCoverageDuringLoading() const { return m_didSwitchToFullTileCoverageDuringLoading; }
-    void setDidSwitchToFullTileCoverageDuringLoading() { m_didSwitchToFullTileCoverageDuringLoading = true; }
-
 #if ENABLE(CSS_COMPOSITING)
     void setBlendMode(BlendMode);
 #endif
@@ -324,7 +321,6 @@ private:
     bool m_canCompositeFilters;
 #endif
     bool m_backgroundLayerPaintsFixedRootBackground;
-    bool m_didSwitchToFullTileCoverageDuringLoading;
 
     static bool m_creatingPrimaryGraphicsLayer;
 };