Animated GIFs scrolled out of view still cause titlebar blur to update, on tumblr...
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Aug 2014 05:38:50 +0000 (05:38 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Aug 2014 05:38:50 +0000 (05:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136139

Reviewed by Simon Fraser.

Source/WebCore:

The mechanism for pausing GIF images outside the viewport did not work for subframes.

Test: fast/repaint/no-animation-outside-viewport-subframe.html

* WebCore.exp.in:
* page/FrameView.cpp:
(WebCore::FrameView::scrollPositionChanged):
(WebCore::FrameView::resumeVisibleImageAnimationsIncludingSubframes):

    Add a function for resuming animations as needed in all subframes.
    This is used after scrolling instead of calling the RenderView function directly.

* page/FrameView.h:
* page/Page.cpp:
(WebCore::Page::resumeAnimatingImages):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::newImageAnimationFrameAvailable):

    Determine the overall visible rect so that it is correct in subframes too.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::scrollTo):
* rendering/RenderView.cpp:
(WebCore::RenderView::resumePausedImageAnimationsIfNeeded):

LayoutTests:

* fast/repaint/no-animation-outside-viewport-subframe-expected.txt: Added.
* fast/repaint/no-animation-outside-viewport-subframe.html: Added.

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/repaint/no-animation-outside-viewport-subframe-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/no-animation-outside-viewport-subframe.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/page/Page.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderView.cpp
Source/WebKit/mac/WebView/WebView.mm

index 28f3ee4..7ba98b6 100644 (file)
@@ -1,3 +1,13 @@
+2014-08-21  Antti Koivisto  <antti@apple.com>
+
+        Animated GIFs scrolled out of view still cause titlebar blur to update, on tumblr.com page
+        https://bugs.webkit.org/show_bug.cgi?id=136139
+
+        Reviewed by Simon Fraser.
+
+        * fast/repaint/no-animation-outside-viewport-subframe-expected.txt: Added.
+        * fast/repaint/no-animation-outside-viewport-subframe.html: Added.
+
 2014-08-21  Zalan Bujtas  <zalan@apple.com>
 
         ruby-base-merge-block-children-crash-2.html should not use render tree dump.
diff --git a/LayoutTests/fast/repaint/no-animation-outside-viewport-subframe-expected.txt b/LayoutTests/fast/repaint/no-animation-outside-viewport-subframe-expected.txt
new file mode 100644 (file)
index 0000000..5963c30
--- /dev/null
@@ -0,0 +1,12 @@
+Test that animated gif in a frame outside viewport does not trigger repaint.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS repaintRectsAfterScroll is ""
+PASS repaintRectsAfterScrollBack is not ""
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/fast/repaint/no-animation-outside-viewport-subframe.html b/LayoutTests/fast/repaint/no-animation-outside-viewport-subframe.html
new file mode 100644 (file)
index 0000000..0ac7325
--- /dev/null
@@ -0,0 +1,53 @@
+<html>
+<head>
+<script>jsTestIsAsync = true;</script>
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+    description("Test that animated gif in a frame outside viewport does not trigger repaint.");
+    function startTrackingRepaints()
+    {
+        document.body.offsetTop;
+        window.internals.startTrackingRepaints();
+        window.scrollTo(0,200);
+        testRunner.display();
+        setTimeout(testAfterScroll, 200);
+    }
+
+    function testAfterScroll()
+    {
+        repaintRectsAfterScroll = window.internals.repaintRectsAsText();
+        window.internals.stopTrackingRepaints();
+
+        shouldBeEqualToString("repaintRectsAfterScroll", "");
+
+        window.internals.startTrackingRepaints();
+        window.scrollTo(0,0);
+        testRunner.display();
+        setTimeout(testAfterScrollBack, 200);
+    }
+
+    function testAfterScrollBack()
+    {
+        repaintRectsAfterScrollBack = window.internals.repaintRectsAsText();
+        window.internals.stopTrackingRepaints();
+
+        shouldNotBeEqualToString("repaintRectsAfterScrollBack", "");
+
+        finishJSTest();
+    }
+
+    function start() {
+        if (!window.testRunner || !window.internals)
+            return;
+
+        var img = new Image();
+        img.onload = startTrackingRepaints;
+        img.src = "resources/animated.gif";
+    }
+</script>
+</head>
+<body onload="start()">
+<iframe srcdoc="<img src=resources/animated.gif>"></iframe>
+<div style="height:1000px"></div>
+<script src="../../resources/js-test-post.js"></script>
+</html>
index 4bbf57a..1fe5b63 100644 (file)
@@ -1,3 +1,35 @@
+2014-08-21  Antti Koivisto  <antti@apple.com>
+
+        Animated GIFs scrolled out of view still cause titlebar blur to update, on tumblr.com page
+        https://bugs.webkit.org/show_bug.cgi?id=136139
+
+        Reviewed by Simon Fraser.
+
+        The mechanism for pausing GIF images outside the viewport did not work for subframes.
+
+        Test: fast/repaint/no-animation-outside-viewport-subframe.html
+
+        * WebCore.exp.in:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollPositionChanged):
+        (WebCore::FrameView::resumeVisibleImageAnimationsIncludingSubframes):
+
+            Add a function for resuming animations as needed in all subframes.
+            This is used after scrolling instead of calling the RenderView function directly.
+
+        * page/FrameView.h:
+        * page/Page.cpp:
+        (WebCore::Page::resumeAnimatingImages):
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::newImageAnimationFrameAvailable):
+
+            Determine the overall visible rect so that it is correct in subframes too.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollTo):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::resumePausedImageAnimationsIfNeeded):
+
 2014-08-21  Alex Christensen  <achristensen@webkit.org>
 
         More WEBCORE_EXPORT macros!
index 2f370db..b36a138 100644 (file)
@@ -2527,7 +2527,6 @@ _WebThreadUnlockGuardForMail
 _WebUIApplicationDidBecomeActiveNotification
 _WebUIApplicationWillEnterForegroundNotification
 _WebUIApplicationWillResignActiveNotification
-__ZN7WebCore10RenderView35resumePausedImageAnimationsIfNeededEv
 __ZN7WebCore10ScrollView15setScrollOffsetERKNS_8IntPointE
 __ZN7WebCore10ScrollView21setExposedContentRectERKNS_9FloatRectE
 __ZN7WebCore10ScrollView24setUnobscuredContentSizeERKNS_9FloatSizeE
@@ -2752,6 +2751,7 @@ __ZN7WebCore9FrameView30graphicsLayerForPlatformWidgetEP7WAKView
 __ZN7WebCore9FrameView32setCustomFixedPositionLayoutRectERKNS_7IntRectE
 __ZN7WebCore9FrameView33rectForViewportConstrainedObjectsERKNS_10LayoutRectERKNS_10LayoutSizeEfbNS_30ScrollBehaviorForFixedElementsE
 __ZN7WebCore9FrameView36scheduleLayerFlushAllowingThrottlingEv
+__ZN7WebCore9FrameView46resumeVisibleImageAnimationsIncludingSubframesEv
 __ZN7WebCore9PageGroup17removeVisitedLinkERKNS_3URLE
 __ZNK7WebCore10FloatPointcv7CGPointEv
 __ZNK7WebCore10ScrollView18exposedContentRectEv
index cbe7bdb..57e53e3 100644 (file)
@@ -2084,10 +2084,20 @@ void FrameView::scrollPositionChanged(const IntPoint& oldPosition, const IntPoin
         document->sendWillRevealEdgeEventsIfNeeded(oldPosition, newPosition, visibleContentRect(), contentsSize());
 
     if (RenderView* renderView = this->renderView()) {
-        renderView->resumePausedImageAnimationsIfNeeded();
         if (renderView->usesCompositing())
             renderView->compositor().frameViewDidScroll();
     }
+
+    resumeVisibleImageAnimationsIncludingSubframes();
+}
+
+void FrameView::resumeVisibleImageAnimationsIncludingSubframes()
+{
+    // A change in scroll position may affect image visibility in subframes.
+    for (auto* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
+        if (auto* renderView = frame->contentRenderer())
+            renderView->resumePausedImageAnimationsIfNeeded();
+    }
 }
 
 void FrameView::updateLayerPositionsAfterScrolling()
index 978f544..1789472 100644 (file)
@@ -243,6 +243,8 @@ public:
     virtual IntPoint maximumScrollPosition() const override;
     void delayedScrollEventTimerFired(Timer<FrameView>&);
 
+    void resumeVisibleImageAnimationsIncludingSubframes();
+
     // This is different than visibleContentRect() in that it ignores negative (or overly positive)
     // offsets from rubber-banding, and it takes zooming into account. 
     LayoutRect viewportConstrainedVisibleContentRect() const;
index 7dd285e..ad0aa3d 100644 (file)
@@ -1203,11 +1203,8 @@ void Page::resumeAnimatingImages()
 {
     // Drawing models which cache painted content while out-of-window (WebKit2's composited drawing areas, etc.)
     // require that we repaint animated images to kickstart the animation loop.
-
-    for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
-        if (auto* renderView = frame->contentRenderer())
-            renderView->resumePausedImageAnimationsIfNeeded();
-    }
+    if (FrameView* view = mainFrame().view())
+        view->resumeVisibleImageAnimationsIncludingSubframes();
 }
 
 void Page::createPageThrottler()
index a60c362..bdb9d3b 100644 (file)
@@ -1310,7 +1310,8 @@ static bool shouldRepaintForImageAnimation(const RenderElement& renderer, const
 
 void RenderElement::newImageAnimationFrameAvailable(CachedImage& image)
 {
-    auto visibleRect = view().frameView().visibleContentRect();
+    auto& frameView = view().frameView();
+    auto visibleRect = frameView.windowToContents(frameView.windowClipRect());
     if (!shouldRepaintForImageAnimation(*this, visibleRect)) {
         view().addRendererWithPausedImageAnimations(*this);
         return;
index bd9a6b7..a3a46e6 100644 (file)
@@ -2321,7 +2321,7 @@ void RenderLayer::scrollTo(int x, int y)
     if (scrollsOverflow())
         frame.loader().client().didChangeScrollOffset();
 
-    renderer().view().resumePausedImageAnimationsIfNeeded();
+    view.frameView().resumeVisibleImageAnimationsIncludingSubframes();
 }
 
 static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView* frameView) 
index 3b0b428..290c702 100644 (file)
@@ -1361,7 +1361,7 @@ void RenderView::removeRendererWithPausedImageAnimations(RenderElement& renderer
 
 void RenderView::resumePausedImageAnimationsIfNeeded()
 {
-    auto visibleRect = frameView().visibleContentRect();
+    auto visibleRect = frameView().windowToContents(frameView().windowClipRect());
     Vector<RenderElement*, 10> toRemove;
     for (auto* renderer : m_renderersWithPausedImageAnimation) {
         if (renderer->repaintForPausedImageAnimationsIfNeeded(visibleRect))
index 6853baa..0d23b1f 100644 (file)
@@ -1573,9 +1573,8 @@ static NSMutableSet *knownPluginMIMETypes()
     _private->mainViewIsScrollingOrZooming = NO;
     [self setDefersCallbacks:NO];
     [[self mainFrame] setTimeoutsPaused:NO];
-    FrameView* view = [self _mainCoreFrame]->view();
-    if (view && view->renderView())
-        view->renderView()->resumePausedImageAnimationsIfNeeded();
+    if (FrameView* view = [self _mainCoreFrame]->view())
+        view->resumeVisibleImageAnimationsIncludingSubframes();
 }
 
 - (void)_setResourceLoadSchedulerSuspended:(BOOL)suspend