zhangqd / chromiumembedded

Automatically exported from code.google.com/p/chromiumembedded
0 stars 1 forks source link

Re-implement off-screen rendering using the new delegated renderer code path #1257

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The legacy software rendering path used by CEF's off-screen rendering mode is 
being removed from Chromium (http://crbug.com/362164). It will be necessary to 
re-implement CEF's off-screen rendering support using the new software 
compositor code path. Quoting from 
https://groups.google.com/a/chromium.org/d/msg/graphics-dev/egxMy4gRmqw/pWSJ7xTl
3c0J:

The software compositor is currently in a bit of flux. Once 
https://codereview.chromium.org/25942002/ is checked in you'll be able to hook 
into the SoftwareFramebuffer. However, for aura we'll probably be switching 
over to delegated rendering/ubercompositor by default, so that will change how 
all this behaves. It might be best to create a 
RenderWidgetHostViewFrameSubscriber or similar to capture the frame from the 
RenderWidgetHostViewAura; that abstracts out many of the details and gives back 
a media::VideoFrame.

Original issue reported on code.google.com by magreenb...@gmail.com on 23 Apr 2014 at 9:03

GoogleCodeExporter commented 9 years ago
The legacy off-screen rendering implementation has been removed in trunk 
revision 1678. This was necessitated by the removal of required legacy code 
from Chromium trunk. The off-screen rendering functionality will be re-added 
once a new implementation is available.

Original comment by magreenb...@gmail.com on 25 Apr 2014 at 1:42

GoogleCodeExporter commented 9 years ago
It seems like the best cross-platform approach at this time is to hook into 
RenderWidgetHostView::OnSwapCompositorFrame and use CopyFromCompositingSurface 
to get the CompositorFrame as an SkBitmap. 
RenderViewDevToolsAgentHost::OnSwapCompositorFrame seems an interesting model 
for this (inspecting the ViewHostMsg_SwapCompositorFrame IPC message).

For this to work correctly the RWHV will likely need to believe that it's 
visible even when the underlying native window is hidden or non-existing (see 
Frame Capture Content API document). For this or other reasons (e.g. proper 
event and/or display/screen size handling) we may need to create a custom 
WebContentsView/RenderWidgetHostView implementation similar to the previous 
legacy approach (modify content::CreateWebContentsView to return the custom 
implementation).

Related graphics-dev discussion:
https://groups.google.com/a/chromium.org/d/msg/graphics-dev/8Pgpja6c5cg/wG7pksNU
zW4J

Related design documents:
http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-
in-chrome
http://www.chromium.org/developers/design-documents/oop-iframes/oop-iframes-rend
ering

In the future we might also consider using the proposed Frame Capture Content 
API:
https://code.google.com/p/chromium/issues/detail?id=376769

Original comment by magreenb...@gmail.com on 19 Jun 2014 at 5:46

GoogleCodeExporter commented 9 years ago
@#2: I now have a working implementation of this approach on Windows and Linux 
which I will merge once the OS X implementation is complete.

The new implementation supports both GPU compositing and software compositing 
(used when GPU is not supported or when passing `--disable-gpu 
--disable-gpu-compositing` command-line flags). GPU-accelerated features that 
did not work with the previous off-screen rendering implementation do work with 
this implementation when GPU support is available. Rendering now operates on a 
per-frame basis. The frame rate is configurable via 
CefBrowserSettings.windowless_frame_rate up to a maximum of 60fps (potentially 
limited by how fast the system can generate them). CEF generates a bitmap from 
the compositor backing and passes it to CefRenderHandler::OnPaint.

Based on limited testing on Windows and Linux performance seems acceptable 
(within a few CPU % of windowed rendering mode using the WebGL field example). 
There are various potential inefficiencies due to Chromium's existing delegated 
rendering implementation. Some known issues that may be addressed in future 
updates:

A. The software compositor path involves a per-frame bitmap allocation.
B. It is no longer possible to provide invalidation regions so clients must 
always update the whole view.

The previous API for CEF off-screen rendering has been restored mostly as-is 
with some minor changes:

1. CefBrowserHost::Invalidate no longer accepts a CefRect argument. Instead, 
calling this method will trigger generation of a new frame if one was not 
already scheduled.

2. The |dirtyRects| argument to CefRenderHandler::OnPaint will always be a 
single CefRect representing the whole view (frame) size.

3. Linux: CefBrowserHost::SendKeyEvent now expects X11 event information 
instead of GTK event information. Cefclient will contain an example of 
converting GTK events to the necessary format.

Original comment by magreenb...@gmail.com on 27 Jun 2014 at 11:55

GoogleCodeExporter commented 9 years ago

Original comment by magreenb...@gmail.com on 28 Jun 2014 at 12:10

GoogleCodeExporter commented 9 years ago

Original comment by magreenb...@gmail.com on 28 Jun 2014 at 12:11

GoogleCodeExporter commented 9 years ago
@#3: Implementation added in trunk revision 1751. In addition to the API 
changes already described:

4. Sizes passed to the CefRenderHandler OnPaint and OnPopupSize methods are now 
already DPI scaled. Previously, the client had to perform DPI scaling.

5. Includes drag&drop implementation from issue #1032.

Original comment by magreenb...@gmail.com on 30 Jun 2014 at 10:32

GoogleCodeExporter commented 9 years ago
AFAICT, OSR support is completely missing from the 1916 branch.  Is there an 
imminent  backport of the "new OSR" support from trunk to the 1916 branch?  Or 
maybe the plan is to leave out OSR altogether for the 1916 branch?

Original comment by john....@scala.com on 25 Jul 2014 at 3:47

GoogleCodeExporter commented 9 years ago
@#7: OSR exists in 1916 branch. It uses the old implementation.

Original comment by magreenb...@gmail.com on 12 Aug 2014 at 9:58

GoogleCodeExporter commented 9 years ago
Which branch is this new OSR implemented in? I am having problems compiling 
from r1751. Also, how do you set transparent rendering in the new OSR 
implementation? Or is it always transparent?

Original comment by haakon.n...@gmail.com on 2 Sep 2014 at 5:09

GoogleCodeExporter commented 9 years ago
@#9: The new OSR implementation is in the 2062 branch and trunk. Configuration 
of transparency is still via CefWindowInfo.transparent_painting_enabled.

Original comment by magreenb...@gmail.com on 2 Sep 2014 at 4:44

GoogleCodeExporter commented 9 years ago
@#3: Trunk revision 1945 and 2171 branch revision 1946 includes the following 
changes:
- The |dirtyRects| argument to CefRenderHandler::OnPaint is now a single 
rectangle representing the union of all dirty rectangles since the last frame 
was generated. In most cases this rectangle will be smaller than the view 
(frame) size.
- cefclient: Use a ScopedGLContext class on all platforms to manage the current 
GL context and avoid GL state leaks.
- cefclient: Add debug checks in ClientOSRenderer for GL errors and fix some 
errors that were discovered.
- cefclient: Add a new `--show-update-rect` command-line flag that provides 
visualization of the update rectangle by drawing a red border around it for 
each frame.

Original comment by magreenb...@gmail.com on 2 Dec 2014 at 11:25

GoogleCodeExporter commented 9 years ago
In regards to dirtyRects, will the `RectList` be replaced with a single 
`CefRect`?

(I'm currently using `2171`)

Original comment by maitland...@gmail.com on 16 Feb 2015 at 11:47

GoogleCodeExporter commented 9 years ago
Will there be any documentation updates to show how to enable osr and 
transparency with the new system?

Original comment by salamand...@gmail.com on 23 Feb 2015 at 5:53