注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

写着玩

Bob

 
 
 

日志

 
 
 
 

Plugin Architecture  

2010-01-10 21:15:39|  分类: Chrome |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Background

Before reading this document, you should be familiar with Chromium's multi-process architecture.

Overview

Plugins are a major source of browser crashes. (Flash is in the callstack of a nontrivial percentage of Firefox crashes.) Plugins also make sandboxing the process where the renderer runs impractical, as plugins are written by third-parties and we can't control their access to the operating system. The solution is to run plugins in their own separate process.

Detailed design

Plugin interfaces

To run plugins in a separate process, the first step is to separate the code that needs to run in the same process as the plugin from the code that needs to run in the same process as the renderer. The de style="color: rgb(0, 96, 0); "<WebPluginde< interface runs in the render process, and de style="color: rgb(0, 96, 0); "<WebPluginDelegatede< is in the plugin process. All communication from the renderer to the plugin, and vice versa, goes through these interfaces.

With these interfaces, simply running plugins in process requires an implementation of de style="color: rgb(0, 96, 0); "<WebPluginde<, which is our de style="color: rgb(0, 96, 0); "<WebPluginImplde< class. Similarly,de style="color: rgb(0, 96, 0); "<WebPluginDelegateImplde< implements the de style="color: rgb(0, 96, 0); "<WebPluginDelegatede< interface. Each object has a pointer to the other interface.

Plugin Architecture - yolcy - 写着玩

The issues with running plugins in the same process as the renderer are:

  • Crashes in the plugin will crash the renderer
  • The process can't be sandboxed because the plugin needs access to the operating system

Moving plugins out-of-process

When running plugins in a separate process from the renderer, the de style="color: rgb(0, 96, 0); "<WebPluginImplde< object lives in the render process, while the de style="color: rgb(0, 96, 0); "<WebPluginDelegateImplde< is now in a different process (plugin process).

For these two objects to communicate transparently, we use the proxy/stub concept from COM. de style="color: rgb(0, 96, 0); "<WebPluginImplde<, instead of getting a pointer tode style="color: rgb(0, 96, 0); "<WebPluginDelegateImplde<, gets a de style="color: rgb(0, 96, 0); "<WebPluginDelegateProxyde<. This object implements the de style="color: rgb(0, 96, 0); "<WebPluginDelegatede< interface, and sends all the function calls over IPC to a corresponding de style="color: rgb(0, 96, 0); "<WebPluginDelegateStubde< in the plugin process. There, de style="color: rgb(0, 96, 0); "<WebPluginDelegateStubde< wraps around a de style="color: rgb(0, 96, 0); "<WebPluginDelegateImplde< and translates the IPC messages to the actual calls.

Similarly, the de style="color: rgb(0, 96, 0); "<WebPluginDelegateImplde< gets a de style="color: rgb(0, 96, 0); "<WebPluginProxyde< object, which sends all calls over IPC to a de style="color: rgb(0, 96, 0); "<WebPluginStubde< object in the render process.

Plugin Architecture - yolcy - 写着玩

Windowless Plugins

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.
  评论这张
 
阅读(520)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017