Page 1 of 2

Running CEF browser and renderer synchronously

PostPosted: Thu Apr 13, 2017 4:32 pm
by danmontz
Is it possible to run CEF in a way that every call to CefDoMessageLoopWork() is guaranteed to end with a call with the CefRendererHandler.OnPaint() call?

I am working on a Linux application that needs cef functionality, but it needs to be synchronous with video v-sync. I can make the main message loop run on top of v-sync, but I also need an image for that frame time. I have plenty of CPU and am hoping that CEF is fast enough to run at video frame rates (59.94Hz).

I have been playing around with the external message pump, but I'm not able to always guarantee an OnPaint call for each call to CefDoMessageLoopWork().

Can CEF operate in this manner?

Any and all suggestions are greatly appreciated!!!

Re: Running CEF browser and renderer synchronously

PostPosted: Fri Apr 14, 2017 7:31 am
by magreenblatt
No, it is not possible.

Re: Running CEF browser and renderer synchronously

PostPosted: Mon Apr 17, 2017 3:01 pm
by danmontz
This is not possible even with the manual message loop?

What if after the renderer's OnPaint callback, we held off the main browser thread until "v-sync" occurs and then call the CefDoMessageLoopWork() function repeatedly until the next OnPaint occurs. I have prototyped this and it appears to work, but I'm not sure what I'm missing.

Anyone else trying to do this? Synchronize the output of pictures relative to another clock?

Re: Running CEF browser and renderer synchronously

PostPosted: Mon Apr 24, 2017 12:30 pm
by danmontz
As I learn more, I will continue to update this post:

Using javascript's requestAnimationFrame() timing control, I can now guarantee my javascript animations are synchronized with v-sync. Now my issue is, is there an easy way in CEF to provide vsync to chromium?

Re: Running CEF browser and renderer synchronously

PostPosted: Fri May 05, 2017 10:45 am
by danmontz
The Chromium team is working on a headless chromium mode. The key feature that I found that fits my needs is the Controlling BeginFrames through DevTools (headless) ... link:
https://docs.google.com/document/d/1LVMYDkfjrrX9PNkrD8pJH5-Np_XUTQHIuJ8IEOirQH4/edit?ts=57d96dbd#heading=h.ndv831lc9uf0

This feature would allow me to synchronously control the browser timing which is exactly what I'm looking for.

Is there any chance this feature would be included in the CEF implementation in the future?

Re: Running CEF browser and renderer synchronously

PostPosted: Fri May 05, 2017 11:00 am
by magreenblatt
If they implement the feature in Chromium then it likely will also be available in CEF.

Re: Running CEF browser and renderer synchronously

PostPosted: Fri May 05, 2017 11:02 am
by magreenblatt
danmontz wrote:Using javascript's requestAnimationFrame() timing control, I can now guarantee my javascript animations are synchronized with v-sync. Now my issue is, is there an easy way in CEF to provide vsync to chromium?

You can specify the frame rate via CefBrowserHost::SetWindowlessFrameRate. However, that does not tie frames to a specific CefDoMessageLoopWork call.

Re: Running CEF browser and renderer synchronously

PostPosted: Fri May 05, 2017 11:13 am
by magreenblatt
Why do you need OnPaint to be called exactly on your vsync clock? OnPaint provides a buffer that you in any case will need to copy somewhere else. You can copy the buffer when OnPaint is called and then render it on your vsync clock.

Also, you should call CefDoMessageLoopWork at the timing requested by CefBrowserProcessHandler::OnScheduleMessagePumpWork. Failing to do so may cause systems to behave incorrectly (internal timers will not fire at the correct intervals, etc).

Re: Running CEF browser and renderer synchronously

PostPosted: Mon May 08, 2017 4:15 pm
by danmontz
magreenblatt wrote:Why do you need OnPaint to be called exactly on your vsync clock? OnPaint provides a buffer that you in any case will need to copy somewhere else. You can copy the buffer when OnPaint is called and then render it on your vsync clock.

Also, you should call CefDoMessageLoopWork at the timing requested by CefBrowserProcessHandler::OnScheduleMessagePumpWork. Failing to do so may cause systems to behave incorrectly (internal timers will not fire at the correct intervals, etc).


We are trying to use cef/chromium as a rendering mechanism. We are not guaranteed to run at vsync rates and our timing model may be a bit spuratic. In order to guarantee that I can get every frame, I would really like to simply control the timing model. I would like to be able to issue "BeginFrame", wait for the OnPaint call, copy out the picture, then wait until it's time to issue "BeginFrame" again. I don't want any deadline processing and I don't want to miss any frames to "catch up" or "skip ahead".

Also we have a a very tight command and control path that doesn't really allow me to buffer up images.

Thanks for the info!

Re: Running CEF browser and renderer synchronously

PostPosted: Thu Apr 16, 2020 5:04 pm
by danmontz
CEF now has an option called: external_begin_frame_enabled

This does exactly what I want it to do.