Skip to content
  • commit-queue@webkit.org's avatar
    Throttle DOM timers on hidden pages. · 9b4ec58f
    commit-queue@webkit.org authored
    https://bugs.webkit.org/show_bug.cgi?id=98474
    
    Patch by Kiran Muppala <cmuppala@apple.com> on 2012-10-08
    Reviewed by Maciej Stachowiak.
    
    Source/JavaScriptCore:
    
    Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define.
    
    * Configurations/FeatureDefines.xcconfig:
    
    Source/WebCore:
    
    When the visibility of a page changes to "hidden", all it's DOM timers are
    updated to align their fire times on one second intervals.  This limits the
    number of CPU wakes due to a hidden pages to one per second.
    
    Test: fast/dom/timer-throttling-hidden-page.html
    
    * Configurations/FeatureDefines.xcconfig:
    * WebCore.exp.in:
    * dom/Document.cpp:
    (WebCore):
    (WebCore::Document::timerAlignmentInterval):
    Read Page::timerAlignmentInterval and pass it along to DOMTimer.
    
    * dom/Document.h:
    (Document):
    * dom/ScriptExecutionContext.cpp:
    (WebCore):
    (WebCore::ScriptExecutionContext::didChangeTimerAlignmentInterval):
    Scan through self DOM Timers and tell them to recompute their fire
    time based on the updated alignment interval.
    (WebCore::ScriptExecutionContext::timerAlignmentInterval):
    
    * dom/ScriptExecutionContext.h:
    (ScriptExecutionContext):
    * page/DOMTimer.cpp:
    (WebCore):
    (WebCore::DOMTimer::alignedFireTime):
    If the document's alignment interval is non zero, round up the fire
    time to the next multiple of alignment interval.
    
    * page/DOMTimer.h:
    (DOMTimer):
    (WebCore::DOMTimer::defaultTimerAlignmentInterval):
    (WebCore::DOMTimer::setDefaultTimerAlignmentInterval):
    * page/Page.cpp:
    (WebCore::Page::Page):
    (WebCore):
    (WebCore::Page::setTimerAlignmentInterval):
    (WebCore::Page::timerAlignmentInterval):
    (WebCore::Page::setVisibilityState):
    Getter and Setter for alignment interval.  Expose setVisibilityState
    if either PAGE_VISIBILITY_API is enabled or if HIDDEN_PAGE_DOM_TIMER_REDUCTION
    is enabled.
    
    * page/Page.h:
    (Page):
    * page/Settings.cpp:
    (WebCore):
    (WebCore::Settings::setDefaultDOMTimerAlignmentInterval):
    (WebCore::Settings::defaultDOMTimerAlignmentInterval):
    (WebCore::Settings::setDOMTimerAlignmentInterval):
    (WebCore::Settings::domTimerAlignmentInterval):
    * page/Settings.h:
    (Settings):
    * page/SuspendableTimer.cpp:
    (WebCore::SuspendableTimer::suspend):
    Save the time remaining to the original unaligned fire time, so that
    on resuming, the fire time will be correctly aligned using the latest
    alignment interval.
    
    * platform/ThreadTimers.cpp:
    (WebCore::ThreadTimers::sharedTimerFiredInternal):
    Clear m_unalignedNextFireTime along with m_nextFireTime to keep
    them always in sync.
    
    * platform/Timer.cpp:
    (WebCore::TimerBase::TimerBase):
    (WebCore::TimerBase::setNextFireTime):
    Save the requested fire time in m_unalignedNextFireTime and
    set m_nextFireTime to the aligned value.  The unalinged value
    is used to recompute fire time if alignment interval changes.
    (WebCore):
    (WebCore::TimerBase::didChangeAlignmentInterval):
    Recompute next fire time from m_unalignedNextFireTime.
    (WebCore::TimerBase::nextUnalignedFireInterval):
    Interval from current time to the original unaligned fire time.
    
    * platform/Timer.h:
    (TimerBase):
    (WebCore::TimerBase::alignedFireTime):
    
    Source/WebKit/mac:
    
    Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define and provide a SPI for
    DumpRenderTree to modify the visibility state of a page.  The latter
    is needed to test throttling of timers on hidden pages through DumpRenderTree.
    
    * Configurations/FeatureDefines.xcconfig:
    * WebView/WebView.mm:
    (-[WebView _setVisibilityState:isInitialState:]):
    * WebView/WebViewPrivate.h:
    
    Source/WebKit2:
    
    Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define.  Use existing code of
    PAGE_VISIBILITY_API to detect changes to page visibility state.
    
    * Configurations/FeatureDefines.xcconfig:
    * UIProcess/WebPageProxy.cpp:
    (WebKit::WebPageProxy::WebPageProxy):
    Check visibility state on construction.
    (WebKit::WebPageProxy::initializeWebPage):
    Send initial visibility state message if HIDDEN_PAGE_DOM_TIMER_THROTTLING
    is enabled or if PAGE_VISIBILITY_API is enabled.
    (WebKit::WebPageProxy::viewStateDidChange):
    When PAGE_VISIBILITY_API is not enabled, compare new visibility against
    WebPageProxy::m_isVisible, to minimize number of messages sent.
    Remove unnecessary second call to PageClient::isViewVisible for updating
    visibility state.
    
    * WebProcess/InjectedBundle/InjectedBundle.cpp:
    (WebKit::InjectedBundle::setPageVisibilityState):
    WebKitTestRunner uses this method to implement testRunner.setPageVisibility(),
    hence enable it for testing hidden page timer throttling as well.
    
    * WebProcess/WebPage/WebPage.cpp:
    (WebKit):
    (WebKit::WebPage::setVisibilityState):
    Ensure Page::setVisibilityState is called either if PAGE_VISIBILITY_API is
    enabled or if HIDDEN_PAGE_DOM_TIMER_THROTTLING is enabled.
    
    * WebProcess/WebPage/WebPage.h:
    (WebPage):
    * WebProcess/WebPage/WebPage.messages.in:
    
    Tools:
    
    Implement testRunner.setPageVisibility on mac for testing throttling
    of timers on hidden pages using DumpRenderTree.
    
    * DumpRenderTree/mac/Configurations/Base.xcconfig:
    Fix build error on mac-ews bot.  Add JSC copy of ICU headers to search path.
    
    * DumpRenderTree/mac/TestRunnerMac.mm:
    (TestRunner::resetPageVisibility):
    (TestRunner::setPageVisibility):
    
    WebKitLibraries:
    
    Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define.
    
    * win/tools/vsprops/FeatureDefines.vsprops:
    * win/tools/vsprops/FeatureDefinesCairo.vsprops:
    
    LayoutTests:
    
    Add a test for DOM timer throttling on hidden pages.
    
    * fast/dom/timer-throttling-hidden-page-expected.txt: Added.
    * fast/dom/timer-throttling-hidden-page.html: Added.
    * platform/chromium/TestExpectations:
    * platform/efl/TestExpectations:
    * platform/gtk/TestExpectations:
    * platform/qt/TestExpectations:
    * platform/win/TestExpectations:
    Skip the test since HIDDEN_PAGE_DOM_TIMER_THROTTLING is not enabled by default.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@130720 268f45cc-cd09-0410-ab3c-d52691b4dbfc
    9b4ec58f