Title: [211612] trunk
Revision
211612
Author
[email protected]
Date
2017-02-02 17:00:30 -0800 (Thu, 02 Feb 2017)

Log Message

Suspend SVG animations in hidden pages
https://bugs.webkit.org/show_bug.cgi?id=167763
<rdar://problem/29986313>

Reviewed by Simon Fraser.

Source/WebCore:

Suspend SVG animations in hidden pages to save power, similarly to what
we already do for another types of animations.

Test: svg/animations/animations-paused-page-non-visible.html

* page/Page.cpp:
(WebCore::setSVGAnimationSuspended):
(WebCore::Page::setIsVisibleInternal):
* svg/SVGDocumentExtensions.cpp:
(WebCore::SVGDocumentExtensions::pauseAnimations):
(WebCore::SVGDocumentExtensions::unpauseAnimations):
* svg/SVGDocumentExtensions.h:
(WebCore::SVGDocumentExtensions::areAnimationsPaused):
* testing/Internals.cpp:
(WebCore::Internals::areSVGAnimationsPaused):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Add layout test coverage.

* svg/animations/animations-paused-page-non-visible-expected.txt: Added.
* svg/animations/animations-paused-page-non-visible.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (211611 => 211612)


--- trunk/LayoutTests/ChangeLog	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/LayoutTests/ChangeLog	2017-02-03 01:00:30 UTC (rev 211612)
@@ -1,5 +1,18 @@
 2017-02-02  Chris Dumez  <[email protected]>
 
+        Suspend SVG animations in hidden pages
+        https://bugs.webkit.org/show_bug.cgi?id=167763
+        <rdar://problem/29986313>
+
+        Reviewed by Simon Fraser.
+
+        Add layout test coverage.
+
+        * svg/animations/animations-paused-page-non-visible-expected.txt: Added.
+        * svg/animations/animations-paused-page-non-visible.html: Added.
+
+2017-02-02  Chris Dumez  <[email protected]>
+
         {}.toString.call(crossOriginWindow) should return "[object Object]"
         https://bugs.webkit.org/show_bug.cgi?id=167701
         <rdar://problem/30330797>

Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (211611 => 211612)


--- trunk/LayoutTests/platform/ios-simulator/TestExpectations	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations	2017-02-03 01:00:30 UTC (rev 211612)
@@ -300,6 +300,7 @@
 
 # testRunner.setPageVisibility is not implemented for iOS
 webkit.org/b/165799 fast/events/page-visibility-onvisibilitychange.html [ Skip ]
+webkit.org/b/165799 svg/animations/animations-paused-page-non-visible.html [ Skip ]
 
 # AutoFill button is not supported
 fast/forms/auto-fill-button/mouse-down-input-mouse-release-auto-fill-button.html

Added: trunk/LayoutTests/svg/animations/animations-paused-page-non-visible-expected.txt (0 => 211612)


--- trunk/LayoutTests/svg/animations/animations-paused-page-non-visible-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-page-non-visible-expected.txt	2017-02-03 01:00:30 UTC (rev 211612)
@@ -0,0 +1,16 @@
+Tests that SVG animations are properly paused when the page becomes hidden.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS internals.areSVGAnimationsPaused is false
+* Page is now hidden
+PASS document.hidden is true
+PASS internals.areSVGAnimationsPaused is true
+* Page is now visible
+PASS document.hidden is false
+PASS internals.areSVGAnimationsPaused is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/animations/animations-paused-page-non-visible.html (0 => 211612)


--- trunk/LayoutTests/svg/animations/animations-paused-page-non-visible.html	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-page-non-visible.html	2017-02-03 01:00:30 UTC (rev 211612)
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<svg width="300px" height="100px">
+    <rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" />
+    <circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1">
+        <animate attributeName="cx" from="0" to="100" dur="5s" repeatCount="indefinite" />
+    </circle>
+</svg>
+<script>
+description("Tests that SVG animations are properly paused when the page becomes hidden.");
+jsTestIsAsync = true;
+
+var expectedState = "hidden";
+
+window._onload_ = function() {
+    shouldBeFalse("internals.areSVGAnimationsPaused");
+    document.addEventListener("visibilitychange", function() {
+        if (expectedState == "hidden") {
+            debug("* Page is now hidden");
+            shouldBeTrue("document.hidden");
+            setTimeout(function() {
+                shouldBeTrue("internals.areSVGAnimationsPaused");
+                expectedState = "visible";
+                testRunner.setPageVisibility("visible");
+            }, 0);
+        } else {
+            debug("* Page is now visible");
+            shouldBeFalse("document.hidden");
+            setTimeout(function() {
+                shouldBeFalse("internals.areSVGAnimationsPaused");
+                finishJSTest();
+            }, 0);
+        }
+    });
+    if (window.testRunner)
+        testRunner.setPageVisibility("hidden");
+}
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (211611 => 211612)


--- trunk/Source/WebCore/ChangeLog	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/ChangeLog	2017-02-03 01:00:30 UTC (rev 211612)
@@ -1,3 +1,29 @@
+2017-02-02  Chris Dumez  <[email protected]>
+
+        Suspend SVG animations in hidden pages
+        https://bugs.webkit.org/show_bug.cgi?id=167763
+        <rdar://problem/29986313>
+
+        Reviewed by Simon Fraser.
+
+        Suspend SVG animations in hidden pages to save power, similarly to what
+        we already do for another types of animations.
+
+        Test: svg/animations/animations-paused-page-non-visible.html
+
+        * page/Page.cpp:
+        (WebCore::setSVGAnimationSuspended):
+        (WebCore::Page::setIsVisibleInternal):
+        * svg/SVGDocumentExtensions.cpp:
+        (WebCore::SVGDocumentExtensions::pauseAnimations):
+        (WebCore::SVGDocumentExtensions::unpauseAnimations):
+        * svg/SVGDocumentExtensions.h:
+        (WebCore::SVGDocumentExtensions::areAnimationsPaused):
+        * testing/Internals.cpp:
+        (WebCore::Internals::areSVGAnimationsPaused):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2017-02-02  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r211596 and r211605.

Modified: trunk/Source/WebCore/page/Page.cpp (211611 => 211612)


--- trunk/Source/WebCore/page/Page.cpp	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/page/Page.cpp	2017-02-03 01:00:30 UTC (rev 211612)
@@ -81,6 +81,7 @@
 #include "RenderWidget.h"
 #include "ResourceUsageOverlay.h"
 #include "RuntimeEnabledFeatures.h"
+#include "SVGDocumentExtensions.h"
 #include "SchemeRegistry.h"
 #include "ScriptController.h"
 #include "ScrollingCoordinator.h"
@@ -1531,6 +1532,24 @@
         setActivityState((m_activityState & ~(ActivityState::IsVisible | ActivityState::IsVisibleOrOccluded)) | ActivityState::IsVisuallyIdle);
 }
 
+enum class SVGAnimationsState { Paused, Resumed };
+static inline void setSVGAnimationsState(Page& page, SVGAnimationsState state)
+{
+    for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        auto* document = frame->document();
+        if (!document)
+            continue;
+
+        if (!document->svgExtensions())
+            continue;
+
+        if (state == SVGAnimationsState::Paused)
+            document->accessSVGExtensions().pauseAnimations();
+        else
+            document->accessSVGExtensions().unpauseAnimations();
+    }
+}
+
 void Page::setIsVisibleInternal(bool isVisible)
 {
     // FIXME: The visibility state should be stored on the top-level document.
@@ -1550,6 +1569,8 @@
         if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
             mainFrame().animation().resumeAnimations();
 
+        setSVGAnimationsState(*this, SVGAnimationsState::Resumed);
+
         resumeAnimatingImages();
     }
 
@@ -1564,6 +1585,8 @@
         if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
             mainFrame().animation().suspendAnimations();
 
+        setSVGAnimationsState(*this, SVGAnimationsState::Paused);
+
 #if PLATFORM(IOS)
         suspendDeviceMotionAndOrientationUpdates();
 #endif

Modified: trunk/Source/WebCore/svg/SVGDocumentExtensions.cpp (211611 => 211612)


--- trunk/Source/WebCore/svg/SVGDocumentExtensions.cpp	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/svg/SVGDocumentExtensions.cpp	2017-02-03 01:00:30 UTC (rev 211612)
@@ -102,6 +102,7 @@
 {
     for (auto& container : m_timeContainers)
         container->pauseAnimations();
+    m_areAnimationsPaused = true;
 }
 
 void SVGDocumentExtensions::unpauseAnimations()
@@ -108,6 +109,7 @@
 {
     for (auto& container : m_timeContainers)
         container->unpauseAnimations();
+    m_areAnimationsPaused = false;
 }
 
 void SVGDocumentExtensions::dispatchSVGLoadEventToOutermostSVGElements()

Modified: trunk/Source/WebCore/svg/SVGDocumentExtensions.h (211611 => 211612)


--- trunk/Source/WebCore/svg/SVGDocumentExtensions.h	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/svg/SVGDocumentExtensions.h	2017-02-03 01:00:30 UTC (rev 211612)
@@ -54,6 +54,7 @@
     void pauseAnimations();
     void unpauseAnimations();
     void dispatchSVGLoadEventToOutermostSVGElements();
+    bool areAnimationsPaused() const { return m_areAnimationsPaused; }
 
     void reportWarning(const String&);
     void reportError(const String&);
@@ -88,6 +89,8 @@
     std::unique_ptr<SVGResourcesCache> m_resourcesCache;
 
     Vector<SVGElement*> m_rebuildElements;
+    bool m_areAnimationsPaused { false }; // For testing.
+
 public:
     // This HashMap contains a list of pending resources. Pending resources, are such
     // which are referenced by any object in the SVG document, but do NOT exist yet.

Modified: trunk/Source/WebCore/testing/Internals.cpp (211611 => 211612)


--- trunk/Source/WebCore/testing/Internals.cpp	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/testing/Internals.cpp	2017-02-03 01:00:30 UTC (rev 211612)
@@ -113,6 +113,7 @@
 #include "RenderView.h"
 #include "RenderedDocumentMarker.h"
 #include "ResourceLoadObserver.h"
+#include "SVGDocumentExtensions.h"
 #include "SVGPathStringBuilder.h"
 #include "SchemeRegistry.h"
 #include "ScriptedAnimationController.h"
@@ -498,6 +499,18 @@
     return WorkerThread::workerThreadCount();
 }
 
+bool Internals::areSVGAnimationsPaused() const
+{
+    auto* document = contextDocument();
+    if (!document)
+        return false;
+
+    if (!document->svgExtensions())
+        return false;
+
+    return document->accessSVGExtensions().areAnimationsPaused();
+}
+
 String Internals::address(Node& node)
 {
     return String::format("%p", &node);

Modified: trunk/Source/WebCore/testing/Internals.h (211611 => 211612)


--- trunk/Source/WebCore/testing/Internals.h	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/testing/Internals.h	2017-02-03 01:00:30 UTC (rev 211612)
@@ -250,6 +250,7 @@
 
     InternalSettings* settings() const;
     unsigned workerThreadCount() const;
+    bool areSVGAnimationsPaused() const;
 
     ExceptionOr<void> setDeviceProximity(const String& eventType, double value, double min, double max);
 

Modified: trunk/Source/WebCore/testing/Internals.idl (211611 => 211612)


--- trunk/Source/WebCore/testing/Internals.idl	2017-02-03 00:53:10 UTC (rev 211611)
+++ trunk/Source/WebCore/testing/Internals.idl	2017-02-03 01:00:30 UTC (rev 211612)
@@ -246,6 +246,8 @@
     readonly attribute InternalSettings settings;
     readonly attribute unsigned long workerThreadCount;
 
+    readonly attribute boolean areSVGAnimationsPaused;
+
     // Flags for layerTreeAsText.
     const unsigned short LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1;
     const unsigned short LAYER_TREE_INCLUDES_TILE_CACHES = 2;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to