John graciously explained all this to me so I thought I'd write what I
know before I forget. Amanda/John, please correct me where I'm wrong!
Windowless plugins are designed to run directly within the rendering
pipeline. When WebKit wants to draw a region of the screen involving
the plugin it calls into the plugin code, handing it a drawing
context. Windowless plugins are often used in situations where the
plugin is expected to be transparent over the page -- it's up to the
plugin drawing code to decide how it munges the bit of the page it's
given.
To take windowless plugins out of process, you still need to
incorporate their rendering in the (synchronous) rendering pass done
by WebKit. A naively slow option is to clip out the region that the
plugin will draw on then synchronously ship that over to the plugin
process and let it draw. This can then be sped up with some shared
memory.
However, rendering speed is then at the mercy of the plugin process
(imagine a page with 30 transparent plugins -- we'd need 30 round
trips to the plugin process). So instead we have windowless plugins
asynchronously paint, much like how our existing page rendering is
asynchronous with respect to the screen. The renderer has effectively
a backing store of what the plugin's rendered area looks like and uses
this image when drawing, and the plugin is free to asynchronously send
over new updates representing changes to the rendered area.
All of this is complicated a bit by "transparent" plugins. The plugin
process needs to know what pixels it wants to draw over. So it also
keeps a cache of what the renderer last sent it as the page background
behind the plugin, then lets the plugin repeatedly draw over that.
So, in all, here are the buffers involved for the region drawn by a
windowless plugin:
Renderer process
- backing store of what the plugin last rendered as
- shared memory with the plugin for receiving updates ("transport DIB")
- copy of the page background behind the plugin (described below)
Plugin process
- copy of the page background behind the plugin, used as the source
material when drawing
- shared memory with the renderer for sending updates ("transport DIB")
Why does the renderer keep a copy of the page background? Because if
the page background changes, we need to synchronously get the plugin
to redraw over the new background it will appear to lag. We can tell
that the background changed by comparing the newly-rendered background
against our copy of what the plugin thinks the background. Since the
plugin and renderer processes are asynchronous with respect to one
another, they need separate copies.
All of this sounds heinously slow, and it is, but it means there are
no glitches when drawing, just burned CPU.
On Linux we have the extra twist that the plugin expects to draw on an
X Drawable, not a memory buffer. However, in the local X server case
it seems to me we can make the transport DIB live in shared memory
(much like it does in our fast drawing path in the renderer->browser
communication). Implementing this is another story. :)
--~--~---------~--~----~------------~-------~--~----~
Chromium Developers mailing list: [email protected]
View archives, change email options, or unsubscribe:
http://groups.google.com/group/chromium-dev
-~----------~----~----~----~------~----~------~--~---