Process suppression should throttle scripted animations
https://bugs.webkit.org/show_bug.cgi?id=115812

Reviewed by Simon Fraser.

<rdar://problem/13799726>

Source/WebCore: 

* WebCore.exp.in:
    - Expose Page::setThrottled
* dom/Document.cpp:
(WebCore::Document::scriptedAnimationControllerSetThrottled):
(WebCore):
* dom/Document.h:
(Document):
    - Forwards to ScriptedAnimationController::setThrottled
* dom/ScriptedAnimationController.cpp:
(WebCore::ScriptedAnimationController::setThrottled):
(WebCore):
* dom/ScriptedAnimationController.h:
    - Force use of a timer.
(ScriptedAnimationController):
* page/Page.cpp:
(WebCore::Page::setThrottled):
(WebCore):
* page/Page.h:
(Page):
    - When under throttling force the ScriptedAnimationController to use a timer.

Source/WebKit2: 

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setThrottled):
(WebKit):
* WebProcess/WebPage/WebPage.h:
(WebPage):
    - Added setThrottled, forwards to WebCore::Page.
* WebProcess/WebProcess.cpp:
(WebKit):
(WebKit::WebProcess::setProcessSuppressionEnabled):
* WebProcess/WebProcess.h:
(WebProcess):
    - Intercept calls to setProcessSuppressionEnabled, also mark all pages as being throttled.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150156 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index c594e35..6712358 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,33 @@
+2013-05-08  Gavin Barraclough  <barraclough@apple.com>
+
+        Process suppression should throttle scripted animations
+        https://bugs.webkit.org/show_bug.cgi?id=115812
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/13799726>
+
+        * WebCore.exp.in:
+            - Expose Page::setThrottled
+        * dom/Document.cpp:
+        (WebCore::Document::scriptedAnimationControllerSetThrottled):
+        (WebCore):
+        * dom/Document.h:
+        (Document):
+            - Forwards to ScriptedAnimationController::setThrottled
+        * dom/ScriptedAnimationController.cpp:
+        (WebCore::ScriptedAnimationController::setThrottled):
+        (WebCore):
+        * dom/ScriptedAnimationController.h:
+            - Force use of a timer.
+        (ScriptedAnimationController):
+        * page/Page.cpp:
+        (WebCore::Page::setThrottled):
+        (WebCore):
+        * page/Page.h:
+        (Page):
+            - When under throttling force the ScriptedAnimationController to use a timer.
+
 2013-05-15  Igor Oliveira  <igor.o@sisa.samsung.com>
 
         Implement run-in remove child cases.
diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in
index 6859ad5..ea2e9f0 100644
--- a/Source/WebCore/WebCore.exp.in
+++ b/Source/WebCore/WebCore.exp.in
@@ -845,6 +845,7 @@
 __ZN7WebCore4Page11PageClientsC1Ev
 __ZN7WebCore4Page11PageClientsD1Ev
 __ZN7WebCore4Page12setGroupNameERKN3WTF6StringE
+__ZN7WebCore4Page12setThrottledEb
 __ZN7WebCore4Page13rangeOfStringERKN3WTF6StringEPNS_5RangeEj
 __ZN7WebCore4Page13setIsInWindowEb
 __ZN7WebCore4Page13setPaginationERKNS_10PaginationE
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 11cf856..c771680 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -4886,6 +4886,14 @@
 #endif
 }
 
+void Document::scriptedAnimationControllerSetThrottled(bool isThrottled)
+{
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+    if (m_scriptedAnimationController)
+        m_scriptedAnimationController->setThrottled(isThrottled);
+#endif
+}
+
 void Document::windowScreenDidChange(PlatformDisplayID displayID)
 {
     UNUSED_PARAM(displayID);
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index 3570929..2efe6a6 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -947,6 +947,7 @@
 
     void suspendScriptedAnimationControllerCallbacks();
     void resumeScriptedAnimationControllerCallbacks();
+    virtual void scriptedAnimationControllerSetThrottled(bool);
     
     void windowScreenDidChange(PlatformDisplayID);
 
diff --git a/Source/WebCore/dom/ScriptedAnimationController.cpp b/Source/WebCore/dom/ScriptedAnimationController.cpp
index afa131b..84fb9b5 100644
--- a/Source/WebCore/dom/ScriptedAnimationController.cpp
+++ b/Source/WebCore/dom/ScriptedAnimationController.cpp
@@ -82,6 +82,13 @@
         scheduleAnimation();
 }
 
+void ScriptedAnimationController::setThrottled(bool isThrottled)
+{
+#if USE(REQUEST_ANIMATION_FRAME_TIMER) && USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+    m_useTimer = isThrottled;
+#endif
+}
+
 ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(PassRefPtr<RequestAnimationFrameCallback> callback)
 {
     ScriptedAnimationController::CallbackId id = ++m_nextCallbackId;
diff --git a/Source/WebCore/dom/ScriptedAnimationController.h b/Source/WebCore/dom/ScriptedAnimationController.h
index 450a87b..9ecc823 100644
--- a/Source/WebCore/dom/ScriptedAnimationController.h
+++ b/Source/WebCore/dom/ScriptedAnimationController.h
@@ -65,6 +65,7 @@
 
     void suspend();
     void resume();
+    void setThrottled(bool);
 
     void windowScreenDidChange(PlatformDisplayID);
 
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index 244edf7..8e7886f 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -950,6 +950,14 @@
     }
 }
 
+void Page::setThrottled(bool isThrottled)
+{
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+        if (frame->document())
+            frame->document()->scriptedAnimationControllerSetThrottled(isThrottled);
+    }
+}
+
 void Page::userStyleSheetLocationChanged()
 {
     // FIXME: Eventually we will move to a model of just being handed the sheet
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index 1da14d4..6f36d40 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -302,6 +302,7 @@
     void suspendScriptedAnimations();
     void resumeScriptedAnimations();
     bool scriptedAnimationsSuspended() const { return m_scriptedAnimationsSuspended; }
+    void setThrottled(bool);
 
     void userStyleSheetLocationChanged();
     const String& userStyleSheet() const;
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index 9971651..b879dbf 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,25 @@
+2013-05-08  Gavin Barraclough  <barraclough@apple.com>
+
+        Process suppression should throttle scripted animations
+        https://bugs.webkit.org/show_bug.cgi?id=115812
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/13799726>
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::setThrottled):
+        (WebKit):
+        * WebProcess/WebPage/WebPage.h:
+        (WebPage):
+            - Added setThrottled, forwards to WebCore::Page.
+        * WebProcess/WebProcess.cpp:
+        (WebKit):
+        (WebKit::WebProcess::setProcessSuppressionEnabled):
+        * WebProcess/WebProcess.h:
+        (WebProcess):
+            - Intercept calls to setProcessSuppressionEnabled, also mark all pages as being throttled.
+
 2013-05-15  Anders Carlsson  <andersca@apple.com>
 
         WKPageGetPluginInformationDisplayNameKey doesn't return the right key
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index f01d5ca..808d21f 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -3755,6 +3755,12 @@
 }
 #endif
 
+void WebPage::setThrottled(bool isThrottled)
+{
+    if (m_page)
+        m_page->setThrottled(isThrottled);
+}
+
 void WebPage::setScrollingPerformanceLoggingEnabled(bool enabled)
 {
     m_scrollingPerformanceLoggingEnabled = enabled;
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h
index 7749ba1..28ff6fa 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h
@@ -608,6 +608,7 @@
 #if ENABLE(PAGE_VISIBILITY_API) || ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
     void setVisibilityState(uint32_t /* WebCore::PageVisibilityState */, bool isInitialState);
 #endif
+    void setThrottled(bool isThrottled);
 
 #if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
     uint64_t nativeWindowHandle() { return m_nativeWindowHandle; }
diff --git a/Source/WebKit2/WebProcess/WebProcess.cpp b/Source/WebKit2/WebProcess/WebProcess.cpp
index 2e0a1aa..23f4e18 100644
--- a/Source/WebKit2/WebProcess/WebProcess.cpp
+++ b/Source/WebKit2/WebProcess/WebProcess.cpp
@@ -553,6 +553,19 @@
     return 0;
 }
     
+#if PLATFORM(MAC)
+void WebProcess::setProcessSuppressionEnabled(bool processSuppressionEnabled)
+{
+    HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end();
+    for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) {
+        WebPage* page = (*it).value.get();
+        page->setThrottled(processSuppressionEnabled);
+    }
+    
+    ChildProcess::setProcessSuppressionEnabled(processSuppressionEnabled);
+}
+#endif
+
 WebPage* WebProcess::webPage(uint64_t pageID) const
 {
     return m_pageMap.get(pageID);
diff --git a/Source/WebKit2/WebProcess/WebProcess.h b/Source/WebKit2/WebProcess/WebProcess.h
index c10b4b7..99301b0 100644
--- a/Source/WebKit2/WebProcess/WebProcess.h
+++ b/Source/WebKit2/WebProcess/WebProcess.h
@@ -132,6 +132,8 @@
 #if PLATFORM(MAC)
     pid_t presenterApplicationPid() const { return m_presenterApplicationPid; }
     bool shouldForceScreenFontSubstitution() const { return m_shouldForceScreenFontSubstitution; }
+
+    void setProcessSuppressionEnabled(bool);
 #endif
     
     const TextCheckerState& textCheckerState() const { return m_textCheckerState; }