Rendering control for Headless Chrome

1,226 views
Skip to first unread message

Eric Seckler

unread,
Oct 18, 2017, 9:34:29 AM10/18/17
to headless-dev
Hi all,

We've now landed a first _experimental_ version of the rendering control (aka BeginFrameControl) - for headless on Linux/Windows only -, under the HeadlessExperimental domain [1]. It is intended to help reduce the headless resource footprint further, by rendering only when you require it, for further background please see the original design doc [2].

If you'd like to give it a try, here some first starting points. Feel free to send feedback and follow the related bug [3].

BeginFrames are chromium's internal vsync signal and drive the rendering pipeline. In essence, they control when rendering happens. The new BeginFrameControl (BFC) allows you to replace chromium's default vsync signal and issue BeginFrames manually via DevTools instead.

You can enable BFC when creating a new HeadlessWebContents or DevTools target page (Target.createTarget now accepts an enableBeginFrameControl parameter). Afterwards, you can enable the HeadlessExperimental domain on the new target (HeadlessExperimental.enable) and wait for the HeadlessExperimental.needsBeginFramesChanged event.

This needsBeginFrames signal tells you whether chromium's compositor currently has pending updates that it would like to render. While needsBeginFrames is true, you can send BeginFrames via HeadlessExperimental.beginFrame.

After the target's main frame has committed its first display frame, you will receive the HeadlessExperimental.mainFrameReadyForScreenshots event, which signals you that you can now use HeadlessExperimental.beginFrame to capture a screenshot. For that purpose, you need to set the command's screenshot parameter. You can send such screenshotting BeginFrames even if needsBeginFrames is false.

Note that a BeginFrame may or may not be answered with a display update. For example, sometimes no display update is necessary afterall, or one of chromium's compositor stages may not be ready to send its updates yet. As a consequence, you might need to send multiple BeginFrames while the target's renderer process is initializing until you receive the mainFrameReadyForScreenshots event.

Furthermore, it is likely that you want to use the --run-all-compositor-stages-before-draw command line flag with BFC. This flag ensures that the compositor does not prematurely commit display frames that are missing some compositing updates. At the moment, this mode has some caveats: It doesn't work well during renderer initialization or window resizes yet. We are working on fixing these issues.

We currently only have a browser test to show all this in action [4]. It may be a useful starting point nevertheless.

Please remember that this functionality is still considered experimental and will likely change in the near future. For example, we intend to make the --run-all-compositor-stages-before-draw mode more dynamic - so that you can specify whether to run all stages for individual BeginFrames. We're also working on supporting BFC in desktop (non-headless) mode, which will result in changes to the commands.

Cheers,
Eric
Reply all
Reply to author
Forward
0 new messages