A sample application to demonstrate how to use the proposed OnAcceleratedPaint()
callback when using CEF for HTML off-screen rendering. This application uses D3D11 shared textures for CEF which improves the OSR rendering performance.
If you don't have it already - install CMake and Visual Studio 2017
Download latest CEF to create a custom build or use an example binary distribution
Note: The above sample distributions are not supported official builds - they are intended for testing/demo purposes.
> set CEF_ROOT=<path\to\cef\binary-distribution>
> gen_vs2017.bat
Note: if you're building for x86 you will need to modify gen_vs2017.bat to specify the correct generator for CMake
If using one of the sample binary distributions from step 2 - make sure to change the build configuration to Release since the distributions above do not contain Debug versions
Build the ALL_BUILD project
Run the cefmixer.exe application
Once the cefmixer.exe is built, it can be run without any arguments - in which case it will automatically navigate to https://webglsamples.org/aquarium/aquarium.html
In addition to rendering an HTML view off-screen, the demo application will also create an overlay layer using a PNG image file (the red DEMO graphic in the screenshots below).
The following screenshot was taken when running on a gaming monitor at 144Hz:
The url for the HTML layer can be specified as a command line argument: (width x height for the window size are also supported on the command-line)
cefmixer.exe https://threejs.org/examples/webgl_animation_keyframes_json.html --width=960 --height=540
Pressing Ctrl+V
will allow the HTML view to run unthrottled with no v-sync:
Obviously, there are not many use cases to render frames completely unthrottled - but the point is to let the integrating application control all timing aspects. This demo application uses the new SendExternalBeginFrame
method to issue BeginFrame requests to Chromium to synchronize HTML updates with its render loop.
The application can tile a url into layers arranged in a grid to test multiple HTML browser instances. Each layer is an independent CEF Browser instance. The following example uses the --grid
command-line switch to specify a 2 x 2 grid:
cefmixer.exe http://webglsamples.org/dynamic-cubemap/dynamic-cubemap.html --grid=2x2
The command-line examples above work to get something running quickly. However, it is also possible to define the layers using a simple JSON file.
For example, if the following is saved to a file called composition.json
:
{
"width":960,
"height":540,
"layers": [
{
"type":"web",
"src":"http://webglsamples.org/spacerocks/spacerocks.html"
},
{
"type":"web",
"src":"file:///C:/examples/overlay.svg",
"left":0.5,
"top":0.5,
"width":0.5,
"height":0.5
}
]
}
Note: layer positions are in normalized 0..1 units where 0,0 is the top-left corner and 1,1 is the bottom-right corner.
We can run cefmixer
using the above JSON layer description:
cefmixer.exe c:\examples\composition.json
The application uses the handy utility method CefParseJSON
in CEF to parse JSON strings.
The update to CEF proposes the following changes to the API for application integration.
CefWindowInfo info;
info.SetAsWindowless(nullptr);
info.shared_texture_enabled = true;
OnAcceleratedPaint
method in a CefRenderHandler
derived class:void OnAcceleratedPaint(
CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
void* share_handle) override
{
}
OnAcceleratedPaint
will be invoked rather than the existing OnPaint
when shared_texture_enabled
is set to true and Chromium is able to create a shared D3D11 texture for the HTML view.
CefWindowInfo info;
info.SetAsWindowless(nullptr);
info.shared_texture_enabled = true;
info.external_begin_frame_enabled = true;
At an interval suitable for your application, make the following call (see web_layer.cpp for a full example) :
browser->GetHost()->SendExternalBeginFrame();
When using SendExternalBeginFrame
, the default timing in CEF is disabled and the windowless_frame_rate
setting is ignored.
A future update could include the following
OffscreenBrowserCompositorOutputSurface
class to handle both the Reflector and a shared texture