Video playback pauses while a menu fades out
Reported by
sid...@s4y.us,
Apr 19 2016
|
||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36 Example URL: https://www.youtube.com/watch?v=BDMBtQjS1bQ Steps to reproduce the problem: 1. Visit any page with a video and start it playing. 2. Open a native menu (from the menu bar, a contextual menu, etc.). 3. Close the menu. What is the expected behavior? The video plays uninterrupted. What went wrong? Video (but not audio) playback pauses while the menu is fading out. Did this work before? N/A Is it a problem with Flash or HTML5? HTML5 Does this work in other browsers? Yes Chrome version: 49.0.2623.112 Channel: stable OS Version: OS X 10.11.4 Flash Version: Shockwave Flash 21.0 r0 This may be a Mac-specific issue.
,
Apr 20 2016
I did some more poking, and it's not restricted to video. CSS animations and JavaScript timers, at least, are also affected. It's just the most obvious for video playback. I made a little test app to play around with this stuff. It looks like, while a menu is fading out, the main run loop switches to com.apple.hitoolbox.windows.windowfadingmode, which isn't in NSRunLoopCommonModes. Apple controls' animation isn't affected, apparently because they're all driven from a separate UI heartbeat thread. I'm not sure whether Safari is doing some trickery to do work on the main thread in uncommon run loop modes or driving its UI from a non-main thread.
,
Apr 20 2016
One last comment after some further poking around — as far as I can tell, Safari isn't affected by this issue because it renders pages out-of-process. You can test this yourself by sending the main Safari process SIGSTOP — JavaScript timers, videos, and CSS animations all keep going (they just stop being interactive). I have a hunch that this uses the IOSurface API, which lets a process turn control of an onscreen buffer over to helper process. It seems like doing something similar in Chrome could be a *huge* performance win.
,
Apr 20 2016
Is this really a compositing bug? Seems more like a core mac bug.
,
Apr 20 2016
sidney: Thanks for the investigation! My first guess is that during the menubar fade out animation, our browser process main thread run loop is not running tasks. That seems like a Chrome bug. I can't think of any situation where we don't want our browser process main thread running tasks. I thought that we were responsible for driving our own message loop on the main thread, so I'm not sure how its mode can change. This bears further investigation. https://code.google.com/p/chromium/codesearch#chromium/src/base/message_loop/message_pump_mac.mm&sq=package:chromium&type=cs&l=554
,
Apr 20 2016
In case it helps: CFRunLoopRunInMode can be called recursively. Even though Chrome only calls it with kCFRunLoopDefaultMode, it's valid for anyone (in this case, Apple's menu code) to call it with a custom mode and block the main thread until they're done with it. Modal dialogs used to be (maybe still are?) handled this way.
The call stack ends up looking roughly like this for the duration of the fade:
main()
CFRunLoopRunInMode(kCFRunLoopDefaultMode)
HandleMouseUp() // or whatever triggered the close
CloseMenu()
CFRunLoopRunInMode("com.apple.hitoolbox.windows.windowfadingmode")
// only fading-related tasks are handled here
,
Apr 20 2016
I imagine we can add the timer to the com.apple.hitoolbox.windows.windowfadingmode mode?
,
Apr 20 2016
That would make this particular issue go away, but AppKit uses other modes too, none of them documented/stable. The idea, as I understand it, is that the main event loop is only for user input, and temporarily blocking it is okay. Anyone is permitted to make up their own private run loop mode and use it for a blocking operation. As far as I know, the "correct" solution is to run non-user-input-specific tasks, like A/V playback, in another thread (or, in Safari's case, another process).
,
Apr 20 2016
ccameron says it would be nice to move the compositor off of the main thread, or even into the GPU process. There's a project called MUS which may or may not be doing something similar. [Google only, sorry] https://docs.google.com/document/d/1PaEmyqwiHfCsJteNp9Rh-I0PkUSVXZKm-MhUEMr8z8k/edit This is something for the Chrome Mac team to talk about in more detail. It may be a good topic for the next convergence. This is a lot of work, so we shouldn't attempt it unless there are very tangible benefits [beyond this bug, and nested input handlers in general]. It's also possible that we will find ourselves MUS-ified, much like we were mojo-ified.
,
Apr 23 2016
Thanks for the update, Erik. I'll leave y'all to it!
,
Aug 24 2016
,
Oct 28 2016
,
Nov 28 2016
sdy@ just showed me a demo where a javascript-driven animation in a Safari renderer will continue to function [and display pixels!] even when the browser process has been sent SIGSTOP. This implies that they have some type of surfaces-like embedding API, which we very much so should be using.
,
Nov 28 2016
,
Nov 28 2016
Yes, the WindowServer does a lot of the functions in Safari that the browser process does in Chrome. Because we're using remote CALayers, we have this ability, too. What prevents us from doing this is twofold 1. the renderer waits for ticks (aka BeginFrame messages) from the browser to update content 2. the renderer can't update the CALayer tree itself -- it is done by the browser's GLRenderer (and the browser process' SurfaceManager) So, if you hang the browser, both [1] and [2] will prevent the renderers from getting any content on the screen. There is work in process to move these functions over to the GPU process -- I think it's part of the Mus work, although it could be done independently.
,
Nov 28 2016
Given that we think Safari no longer uses remote CALayers, we should figure out how they're doing this? Maybe there's another API we should be using?
,
Dec 1 2016
Oh -- Safari is still using remote CALayers (I think they just changed APIs every once in a while) -- that's how they're not pausing.
,
Feb 23 2017
,
Feb 23 2017
,
May 12 2017
r470769 is in Version 60.0.3097.0 canary and seems to fix this. On a different bug - http://crbug.com/652007#c14 - a brief pause can still be seen. That's probably happening for video as well, but it's too brief for my eyes to notice.
,
May 12 2017
Great!
,
May 12 2017
Nice! This fixes this particular issue. I can still freeze it in fullscreen by moving my mouse up to show and hide the menu bar. Think I should make a separate bug for that?
,
May 15 2017
I don't have an opinion about opening a new bug. A fix may be as simple as observing another of the pricate runloop modes. I hacked together a ScopedRunLoopSpy in https://codereview.chromium.org/2863883002/diff/40001/ui/views/controls/menu/menu_runner_impl_cocoa.mm#newcode152 which might have some useful code fragments.
,
May 25 2017
,
May 25 2017
,
May 25 2018
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue. Sorry for the inconvenience if the bug really should have been left as Available. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
May 25 2018
This is currently broken in MacViews w/ system menus.
,
Aug 14
,
Aug 24
,
Aug 24
|
||||||||||||||
►
Sign in to add a comment |
||||||||||||||
Comment 1 by erikc...@chromium.org
, Apr 19 2016Components: Internals>Compositing
Status: Available (was: Unconfirmed)