Title: [197006] trunk/Source/WebCore
Revision
197006
Author
barraclo...@apple.com
Date
2016-02-23 16:32:40 -0800 (Tue, 23 Feb 2016)

Log Message

Add a mechanism to automatically ramp up timer alignment.
https://bugs.webkit.org/show_bug.cgi?id=154578

Reviewed by Antti Koivisto & Chris Dumez.

Allow timer alignment duration to be proportional to the time the page
has been hidden. This implementation does so by scaling up the throttle
in exponential steps, spaced exponentially far apart.

* page/Page.cpp:
(WebCore::Page::Page):
    - initialize timer.
(WebCore::Page::hiddenPageDOMTimerThrottlingStateChanged):
    - if setting are changed fully disable/reenable to ensure new setting are read.
(WebCore::Page::setTimerThrottlingEnabled):
    - enebled bool flag converted to an Optional<double>, tracking time throttling
      is enabled.
(WebCore::Page::setDOMTimerAlignmentInterval):
    - when new mechanism is enabled schedule a timer to step up alignment.
(WebCore::Page::timerAlignmentIntervalIncreaseTimerFired):
    - when timer fires increase alignment.
* page/Page.h:
    - added new member.
* page/Settings.cpp:
(WebCore::Settings::Settings):
    - initialize new member.
(WebCore::Settings::setHiddenPageDOMTimerThrottlingAutoIncreaseLimit):
    - added, update new setting. Setting to zero disabled. A non-zero value is a
      duration in seconds for timer throttling to ramp up to.
* page/Settings.h:
(WebCore::Settings::hiddenPageDOMTimerThrottlingAutoIncreases):
    - read as boolean whether throttle increasing is enabled.
(WebCore::Settings::hiddenPageDOMTimerThrottlingAutoIncreaseLimit):
    - read throttle increasing limit.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (197005 => 197006)


--- trunk/Source/WebCore/ChangeLog	2016-02-24 00:30:48 UTC (rev 197005)
+++ trunk/Source/WebCore/ChangeLog	2016-02-24 00:32:40 UTC (rev 197006)
@@ -1,3 +1,40 @@
+2016-02-23  Gavin Barraclough  <barraclo...@apple.com>
+
+        Add a mechanism to automatically ramp up timer alignment.
+        https://bugs.webkit.org/show_bug.cgi?id=154578
+
+        Reviewed by Antti Koivisto & Chris Dumez.
+
+        Allow timer alignment duration to be proportional to the time the page
+        has been hidden. This implementation does so by scaling up the throttle
+        in exponential steps, spaced exponentially far apart.
+
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+            - initialize timer.
+        (WebCore::Page::hiddenPageDOMTimerThrottlingStateChanged):
+            - if setting are changed fully disable/reenable to ensure new setting are read.
+        (WebCore::Page::setTimerThrottlingEnabled):
+            - enebled bool flag converted to an Optional<double>, tracking time throttling
+              is enabled.
+        (WebCore::Page::setDOMTimerAlignmentInterval):
+            - when new mechanism is enabled schedule a timer to step up alignment.
+        (WebCore::Page::timerAlignmentIntervalIncreaseTimerFired):
+            - when timer fires increase alignment.
+        * page/Page.h:
+            - added new member.
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+            - initialize new member.
+        (WebCore::Settings::setHiddenPageDOMTimerThrottlingAutoIncreaseLimit):
+            - added, update new setting. Setting to zero disabled. A non-zero value is a
+              duration in seconds for timer throttling to ramp up to.
+        * page/Settings.h:
+        (WebCore::Settings::hiddenPageDOMTimerThrottlingAutoIncreases):
+            - read as boolean whether throttle increasing is enabled.
+        (WebCore::Settings::hiddenPageDOMTimerThrottlingAutoIncreaseLimit):
+            - read throttle increasing limit.
+
 2016-02-22  Ada Chan  <adac...@apple.com>
 
         Refactor script that updates fullscreen buttons.

Modified: trunk/Source/WebCore/page/Page.cpp (197005 => 197006)


--- trunk/Source/WebCore/page/Page.cpp	2016-02-24 00:30:48 UTC (rev 197005)
+++ trunk/Source/WebCore/page/Page.cpp	2016-02-24 00:32:40 UTC (rev 197006)
@@ -204,8 +204,8 @@
 #if ENABLE(VIEW_MODE_CSS_MEDIA)
     , m_viewMode(ViewModeWindowed)
 #endif // ENABLE(VIEW_MODE_CSS_MEDIA)
-    , m_timerThrottlingEnabled(false)
     , m_timerAlignmentInterval(DOMTimer::defaultAlignmentInterval())
+    , m_timerAlignmentIntervalIncreaseTimer(*this, &Page::timerAlignmentIntervalIncreaseTimerFired)
     , m_isEditable(false)
     , m_isPrerender(false)
     , m_viewState(PageInitialViewState)
@@ -1157,6 +1157,8 @@
 
 void Page::hiddenPageDOMTimerThrottlingStateChanged()
 {
+    // Disable & reengage to ensure state is updated.
+    setTimerThrottlingEnabled(false);
     setTimerThrottlingEnabled(m_viewState & ViewState::IsVisuallyIdle);
 }
 
@@ -1167,23 +1169,50 @@
         enabled = false;
 #endif
 
-    if (enabled == m_timerThrottlingEnabled)
+    if (enabled == !!m_timerThrottlingEnabledTime)
         return;
 
-    m_timerThrottlingEnabled = enabled;
+    m_timerThrottlingEnabledTime = enabled ? monotonicallyIncreasingTime() : Optional<double>();
     setDOMTimerAlignmentInterval(enabled ? DOMTimer::hiddenPageAlignmentInterval() : DOMTimer::defaultAlignmentInterval());
 }
 
 void Page::setDOMTimerAlignmentInterval(double alignmentInterval)
 {
+    // If the new alignmentInterval is shorter than the one presently in effect we need to update
+    // existing timers (e.g. when a hidden page becomes visible throttled timers must be unthrottled).
+    // However when lengthening the alignment interval, no need to update existing timers. Not doing
+    // so means that timers scheduled while the page is visible get to fire accurately (repeating
+    // timers will be throttled on the next timer fire).
+    bool shouldRescheduleExistingTimers = alignmentInterval < m_timerAlignmentInterval;
+
     m_timerAlignmentInterval = alignmentInterval;
-    
-    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (frame->document())
-            frame->document()->didChangeTimerAlignmentInterval();
+
+    if (shouldRescheduleExistingTimers) {
+        for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (auto* document = frame->document())
+                document->didChangeTimerAlignmentInterval();
+        }
     }
+
+    // If throttling is enabled and auto-increasing of throttling is enabled then arm the timer to
+    // consider an increase. Time to wait between increases is equal to the current throttle time.
+    // Since alinment interval increases exponentially, time between steps is exponential too.
+    if (m_timerThrottlingEnabledTime && m_settings->hiddenPageDOMTimerThrottlingAutoIncreases())
+        m_timerAlignmentIntervalIncreaseTimer.startOneShot(m_timerAlignmentInterval);
+    else
+        m_timerAlignmentIntervalIncreaseTimer.stop();
 }
 
+void Page::timerAlignmentIntervalIncreaseTimerFired()
+{
+    ASSERT(m_timerThrottlingEnabledTime && m_settings->hiddenPageDOMTimerThrottlingAutoIncreases());
+        
+    // Alignment interval is increased to equal the time the page has been throttled.
+    double throttledDuration = monotonicallyIncreasingTime() - m_timerThrottlingEnabledTime.value();
+    double alignmentInterval = std::max(m_timerAlignmentInterval, throttledDuration);
+    setDOMTimerAlignmentInterval(alignmentInterval);
+}
+
 void Page::dnsPrefetchingStateChanged()
 {
     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())

Modified: trunk/Source/WebCore/page/Page.h (197005 => 197006)


--- trunk/Source/WebCore/page/Page.h	2016-02-24 00:30:48 UTC (rev 197005)
+++ trunk/Source/WebCore/page/Page.h	2016-02-24 00:32:40 UTC (rev 197006)
@@ -42,6 +42,7 @@
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/Optional.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
@@ -523,7 +524,7 @@
     void hiddenPageDOMTimerThrottlingStateChanged();
     void setTimerThrottlingEnabled(bool);
     void setDOMTimerAlignmentInterval(double);
-    void timerAlignmentIntervalTimerFired();
+    void timerAlignmentIntervalIncreaseTimerFired();
 
     const std::unique_ptr<Chrome> m_chrome;
     const std::unique_ptr<DragCaretController> m_dragCaretController;
@@ -609,8 +610,9 @@
     ViewMode m_viewMode;
 #endif // ENABLE(VIEW_MODE_CSS_MEDIA)
 
-    bool m_timerThrottlingEnabled;
+    Optional<double> m_timerThrottlingEnabledTime;
     double m_timerAlignmentInterval;
+    Timer m_timerAlignmentIntervalIncreaseTimer;
 
     bool m_isEditable;
     bool m_isPrerender;

Modified: trunk/Source/WebCore/page/Settings.cpp (197005 => 197006)


--- trunk/Source/WebCore/page/Settings.cpp	2016-02-24 00:30:48 UTC (rev 197005)
+++ trunk/Source/WebCore/page/Settings.cpp	2016-02-24 00:32:40 UTC (rev 197006)
@@ -681,6 +681,15 @@
 }
 #endif
 
+void Settings::setHiddenPageDOMTimerThrottlingAutoIncreases(bool flag)
+{
+    if (m_hiddenPageDOMTimerThrottlingAutoIncreases == flag)
+        return;
+    m_hiddenPageDOMTimerThrottlingAutoIncreases = flag;
+    if (m_page)
+        m_page->hiddenPageDOMTimerThrottlingStateChanged();
+}
+
 void Settings::setHiddenPageCSSAnimationSuspensionEnabled(bool flag)
 {
     if (m_hiddenPageCSSAnimationSuspensionEnabled == flag)

Modified: trunk/Source/WebCore/page/Settings.h (197005 => 197006)


--- trunk/Source/WebCore/page/Settings.h	2016-02-24 00:30:48 UTC (rev 197005)
+++ trunk/Source/WebCore/page/Settings.h	2016-02-24 00:32:40 UTC (rev 197006)
@@ -165,6 +165,8 @@
     bool hiddenPageDOMTimerThrottlingEnabled() const { return m_hiddenPageDOMTimerThrottlingEnabled; }
     WEBCORE_EXPORT void setHiddenPageDOMTimerThrottlingEnabled(bool);
 #endif
+    bool hiddenPageDOMTimerThrottlingAutoIncreases() const { return m_hiddenPageDOMTimerThrottlingAutoIncreases; }
+    WEBCORE_EXPORT void setHiddenPageDOMTimerThrottlingAutoIncreases(bool);
 
     WEBCORE_EXPORT void setUsesPageCache(bool);
     bool usesPageCache() const { return m_usesPageCache; }
@@ -345,6 +347,8 @@
     bool m_resourceUsageOverlayVisible { false };
 #endif
 
+    bool m_hiddenPageDOMTimerThrottlingAutoIncreases { false };
+
 #if USE(AVFOUNDATION)
     WEBCORE_EXPORT static bool gAVFoundationEnabled;
     WEBCORE_EXPORT static bool gAVFoundationNSURLSessionEnabled;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to