[Webkit-unassigned] [Bug 178396] New: Composited frames incorrectly get requestAnimationFrame throttled

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Oct 17 10:27:14 PDT 2017


https://bugs.webkit.org/show_bug.cgi?id=178396

            Bug ID: 178396
           Summary: Composited frames incorrectly get
                    requestAnimationFrame throttled
           Product: WebKit
           Version: WebKit Nightly Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: Animations
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: mihaip at chromium.org
                CC: dino at apple.com

I'm observing iframes having their requestAnimationFrame callbacks getting incorrectly throttled because WebKit thinks that they are outside of the viewport, when they are in fact visible. To reproduce (in either Safari 11.0 or more recent WebKit builds - I tried r223536):

1. Go to http://persistent.info/webkit/test-cases/frame-raf-throttling/container.html. There is an "overflow: auto" scrollable div (gray background, 300 pixels wide) in which there is a composited iframe (yellow, 2000 pixels wide). The iframe uses requestAnimationFrame (for how it just reports the interval between successive calls, to make throttling more apparent)
2. Scroll the container sideways
3. Once the scroll offset goes past the window width (there's a "Scroll to Window Width" button to do this) then the requestAnimationFrame cadence drops down every 10 seconds, corresponding to the aggressiveThrottlingAnimationInterval value in ScriptedAnimationController (which is triggered by ThrottlingReason::OutsideViewport)

What I've traced is that when the area gets scrolled, we end up in FrameView::viewportContentsChanged, which uses applyRecursivelyWithVisibleRect() to get the visible rect to determine if the iframe is visible. That in turn relies on windowClipRect(), and that returns a 0x0 sized rectangle.

Digging into windowClipRect, we end up in windowClipRectForFrameOwner, which since the frame has an enclosing layer uses that layer's childrenClipRect. The return value of that is (-<scroll offset>, y - <window width> x <window height>). Thus if the scroll offset is greater than the window width, when we intersect the rectangle with the window's clip rectangle.

The reason why childrenClipRect's return value appears to refleect the window's dimensions is because it passes renderer().view().unscaledDocumentRect() as the paintDirtyRect parameter to calculateRects (which forms the basis of the return value).

I'm out of my depth here as far as my WebKit knowledge, so someone with more familiarity will need to attempt a fix. Though the manifestation of this bug is that requestAnimationFrame gets throttled incorrectly, since the problem is at a lower level (as far as determining its visible rectangle) there may be other side effects too.

Given that unscaledDocumentRect is used as the initial value, a workaround is to add an element to the main frame document that is as wide as the iframe. This is what the "Add Filler" button does, and once that element is present (even if the main frame document uses "overflow: hidden") then throttling does not occur.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20171017/9a6f51e8/attachment.html>


More information about the webkit-unassigned mailing list