Main target of this patch, is ability to use a result of hardware offscreen render in CEF client applications without any transfer to system memory. By default, cromium use 3 processes, browser, render and GPU. Hardware painting happens in GPU process. If we want to use a result of this painting in our application, we must use some context\surface sharing mechanism or run GPU command processing in browser process. Sharing is possible for D3D from Windows Vista and for OpenGL in platforms with glXImportContextEXT. Cromium implementation supports natively only D3D sharing, but my patch can be expanded to add support of full sharing on other platforms. Cromium can run GPU command processing in browser process if --in-process-gpu flag was specified, and it is enough stable to use it, opposite to --single-process flag. I am implemented path for D3D in separate GPU process, and OpenGL path for browser GPU command processing. By default, on windows, D3D through EGL and ANGLE were used, but this can be switched to OpenGL by --use-gl=desktop. I think, that most comfortable way, is to use platform specific handle to some object in CEF API, shared texture handle for D3D, HDC of PBUFFER on windows, etc. because Cromium code is strongly platform specific in accelerated drawing functions, and this can give us some freedom for modifications and adding new platforms. Main idea of implementation, is to add new surface type and handle it like regular draw to window, but connect it to texture or PBUFFER at end point. This can be achieved using CreateOffscreenGLSurface instead of CreateViewGLSurface in ImageTransportSurface::CreateNativeSurface.
Here is a brief description of my patch:
Modifications in CEF:
- Added OnAcceleratedPaint in CefRenderHandler.
- Added support of OnAcceleratedPaint in CefRenderWidgetHostViewOSR.
- Removed force accelerated_compositing=STATE_DISABLED in CEF offscreen mode.
- OSR rendering path in cefclient modified for OpenGL hardware acceleration support. Just run with -off-screen-rendering-enabled -in-process-gpu -use-gl=desktop.
Modifications in cromium:
- Added gfx::NATIVE_SURFACE to SurfaceType enum.
- GpuProcessHost modified for gfx::NATIVE_SURFACE and AcceleratedSurfacePostSubBuffer support.
- GpuSurfaceTracker modified for gfx::NATIVE_SURFACE support.
- PassThroughImageTransportSurface modified for gfx::NATIVE_SURFACE support. Some special handling for gfx::NATIVE_SURFACE were introduced (gfx::GLSurfaceAdapter::SwapBuffers skip, share handle transition, glFinish call to prevent flicker and scheduling disable during surface processing in browser).
- ImageTransportSurface::CreateNativeSurface modified on win and linux for gfx::NATIVE_SURFACE support. MAC support must be handled in more special way, I will add this handling, and support of separate GPU process on linux later.
- AddGenericPolicy in sandbox_win modified for --in-process-gpu flag support by default configuration.
- Added resizing support and ShareHandle return in PbufferGLSurfaceWGL.
TEST:
cefclient -off-screen-rendering-enabled -in-process-gpu -use-gl=desktop
Some WebGL demos for performance test:
http://alteredqualia.com/three/examples ... namic.html
http://carvisualizer.plus360degrees.com/threejs/
This is a path for Desktop OpenGL rendering on windows. Everything works OK, and very fast for me including Flash and WebGL.
D3D path is not tested but should work. OpenGL path for Linux is not tested but should work. MAC is not supported for now at all.
TODO:
Test transparency.
Test on compatibility issues.
Test D3D on Windows and OpenGL on Linux.
Add MAC OpenGL support.
Add support for GPU in separate process (MAC and Linux).
Add unittest for OnAcceleratedPaint.
It will be great, if someone help me to finish and test all features.