WebKit之chromium进程创建过程分析

一 chromium for android Browser进程创建过程分析

ContentMainDelegate是客户端程序注册给content_main_runner.cc的回调接口,
content_main_runner.cc通过调用ContentMainDelegate的接口来通知客户端
当前Content框架的状态。
客户端程序通过ContentMainDelegate::RegisterApplicationNativeMethods接口
注册自己的本地方法。
ContentMainDelegate中的有四个函数:
CreateContentBrowserClient();
CreateContentPluginClient();
CreateContentRendererClient();
CreateContentUtilityClient();
用来分别创建ContentBrowserClient,ContentPlunginClient,ContentRendererClient,
ContentUtilityClient的实例。

ContentMainDelegate的注册过程如下:

WebKit之chromium进程创建过程分析_第1张图片

虚拟机在动态库加载完成后调用全局函数JNI_OnLoad,定义在chrome_jni_onload.cc中。
JNI_OnLoad调用全局函数RunChrome,定义在chrome_android_initializer.cc中。
RunChrome调用content命名空间的全局函数SetContentMainDelegate()定义在content_main.cc中。
SetContentMainDelegate()将指向ChromeMainDelegateAndroid对象的指针
保存到全局变量g_content_main_delegate中。
content_main.cc的Start方法会构建一个ContentMainRunner的实例,并将变量g_content_main_delegate
传递给ContentMainRunner实例。
content_main_runner.cc中调用ContentMainDelegate中的所有函数。

android平台的chromium框架由ContentMain.java负责初始化所有类型的进程。 
content_switches.cc中定义了chromium所有的进程类型,
如BrowserProcess,RendererProcess,PluginProcess,WorkerProcess,UtilityProcess等。
应用程序创建Browser进程的过程如下:

WebKit之chromium进程创建过程分析_第2张图片

ContentMain.java只有两个方法:
public static void initApplicationContext(Context context);
public static int start();
客户端程序需要先调用initApplicationContext接口,再调用start接口,才会触发Browser进程或Render进程的创建。
ContentMain.java的jni层对应文件是src/content/app/android/content_main.cc.
将ContentMain.java与content_main.cc连接起来的是Chromium自动生成的jni文件:ContentMain_jni.h
Chromium的jni文件的命名规则是java文件名_jni.h.
编译后这个文件位于:src/out/Release/gen/content/jni
ContentMain.java中的两个方法只是简单的调用native层content_main.cc中的全局函数。
content_main.cc中的start函数主要做三件事:
1.创建一个ContentMainRunner实例,实际创建的是继承自ContentMainRunner的ContentMainRunnerImpl,
这个类定义在content_main_runner.cc中;
2.调用ContentMainRunnerImpl实例的Initialize接口,同时将ContentMainDelegate实例传给ContentMainRunnerImpl;
3.调用ContentMainRunnerImpl实例的Run接口;
ContentMainRunnerImpl::Initialize接口调用ContentClientInitializer::Set(process_type, delegate_),
ContentClientInitializer定义在content_main_runner.cc中,这个类只有一个static方法Set,
Set方法的职责是调用ContentMainDelegate的相应接口设置ContentClient的实例域
ContentBrowserClient,ContentPluginClient,ContentRenderClient,ContentUtilityClient。

ContentMainRunnerImpl::Run会调用全局函数RunNamedProcessTypeMain,这个函数中会调用ContentMainDelegate::RunProcess.
根据前面对ContentMainDelegate的讨论,我们知道实际执行的是ChromeMainDelegateAndroid::RunProcess.
ChromeMainDelegateAndroid::RunProcess主要做两件事:
1.创建BrowserMainRunner实例,实际创建的是继承自BrowserMainRunner的BrowserMainRunnerImpl,
这个类定义在browser_main_runner.cc中;
2.调用BrowserMainRunnerImpl实例的Initialize接口。
BrowserMainRunnerImpl包含BrowserMainLoop的引用。
BrowerMainLoop是Browser进程的核心类,负责Browser进程中所有线程的创建。
BrowserMainRunnerImpl::Initialize函数创建BrowserMainLoop的实例并调用其接口完成Browser进程的准备工作。
上述类之间的关系图如下:

WebKit之chromium进程创建过程分析_第3张图片


二 chromium for android Browser进程结构分析


java层与页面显示有关的类
1.ContentView.java 
功能:ContentViewCore.java的封装类,继承自Android的FrameLayout控件,
提供了类似于Android WebView.java的接口。是android版chrome应用程序可以直接使用的类。
2.ContentViewCore.java
功能:native层WebContent在java端的封装类。包含管理ContentView生命周期所需要的主要功能。
3.ContentViewRenderView.java
功能:封装了SurfaceView.java,继承自Android的FrameLayout控件,
ContentView使用ContentViewRenderView来渲染自身内容。是android版chrome应用程序可以直接使用的类。
ContentViewRenderView.java中包含的SurfaceView在ContentViewRenderView的构造函数中
通过addView操作成为ContentViewRenderView的子View.从而加入到android的view系统中。
ContentViewRenderView.java的native层ContentViewRenderView
ContentViewRenderView继承Compositor::Client.
ContentViewCore.java的native层ContentViewCoreImpl
ContentViewCoreImpl继承ContentViewCore,NotificationObserver.

上述类之间的关系如下:

WebKit之chromium进程创建过程分析_第4张图片

ContentViewCoreImpl直接调用content/browser/web_contents模块的功能,
content/browser/web_contents模块直接调用content/browser/renderer_host/模块的功能。
web_contents和renderer_host模块中的内容构成了Brower进程的主要结构.(参见)

ContentViewRenderView继承了Compositor::Client,所以ContentViewRenderView是Browser
进程中Compositor(android平台定义在compositor_impl_android.cc中)的客户端。
负责创建Compositor,为Compositor设置Surface,调用Compositor的合成动作等。
Compositor是位于Browser进程中的合成器,负责将render进程合成好的texture合成到on-screen surface的back  buffer上。
这篇博客中我们只关注Browser进程中与页面渲染相关的结构。
以ContentViewCoreImpl为起点,可以理清Browser进程中web_contents模块和renderer_host模块的关系以及两者各自的内部结构。
以ContentViewRenderView为起点,可以理清Browser进程中Compositor模块的工作机制,
后面的内容分两个部分:
一.ContentViewCoreImpl引出的web_contents模块,renderer_host模块的内部结构,以及两者之间的联系。
二.ContentViewRenderView引出的Compositor模块的内部结构。(android平台的compositor定义在compositor_impl_android.cc中)。
下面我们分别介绍这两部分。
先分析第一部分。
一.ContentViewCoreImpl引出的web_contents模块,renderer_host模块的内部结构,以及两者之间的联系。
ContentViewCoreImpl包含两个重要的成员变量WebContentsImpl* web_contents_和scoped_refptr root_layer_。
WebContentsImpl是web_contents模块的核心类。
cc::Layer是需要合成的Layer的基类。.
下面我们看ContentViewCoreImpl中包含的WebContentsImpl* web_contents_是怎么创建的。
java层的ContentViewUtil类提供了一个接口可以创建native层WebContents.
ContentViewUtil.createNativeWebContents();
这个调用通过jni调用到native层的CreateNativeWebContents()(定义在content_view_util.cc中).
CreateNativeWebContents()调用content::WebContents::Create(),
content::WebContents::Create()的实现在web_contents_impl.cc中,具体创建的是WebContents的实现类WebContentsImpl。
所以java层ContentViewUtil.createNativeWebContents()接口创建了一个native层WebContentsImpl实例。
在java层的chrome应用程序中,这个实例通过ContentView.newInstance()传递给java层ContentView的构造函数。
java层ContentView的构造函数中创建了ContentViewCore的实例,并调用ContentViewCore.initialize(),
将native层的WebContentsImpl实例传递给了java层的ContentViewCore.
ContentViewCore::initialize(){
 mNativeContentViewCore = nativeInit(mHardwareAccelerated,
                nativeWebContents, viewAndroidNativePointer, windowNativePointer);
}
nativeInit()实际调用的是content_view_core_impl.cc中的Init()函数。
Init()函数中以native层WebContentsImpl实例为参数创建了ContentViewCoreImpl实例。
所以ContentViewCoreImpl中包含的WebContentsImpl* web_contents_实际指向的就是java层
ContentViewUtil.createNativeWebContents()创建的native层WebContentsImpl实例。
ContentViewCoreImpl的构造函数初始化列表中调用cc::Layer::Create()初始化了scoped_refptr root_layer_。
所以ContentViewCoreImpl中的root_layer_指向的是cc::Layer的实例。

下面我们看WebContentsImpl的内部结构。
我们看WebContentsImpl中包含的三个成员变量:
scoped_ptr view_;
RenderViewHostDelegateView* render_view_host_delegate_view_;
RenderViewHostManager render_manager_;
view_和render_view_host_delegate_view_实际指向的都是WebContentsViewAndroid的实例。
WebContentsViewAndroid继承了WebContentsViewPort和RenderViewHostDelegateView。
WebContentsImpl::Init()函数创建了WebContentsViewAndroid实例,对view_和render_view_host_delegate_view_赋值。
WebContentsImpl::Init(){
  view_.reset(CreateWebContentsView(
          this, delegate, &render_view_host_delegate_view_));
}
android平台的CreateWebContentsView()定义在web_contents_view_android.cc中,
创建的是WebContentsViewAndroid实例。
WebContentsViewAndroid包含指向WebContentsImpl和ContentViewCoreImpl的指针变量。
其中,WebContentsImpl指针变量是WebContentsImpl::Init()函数创建WebContentsViewAndroid实例时将自身作为参数传入的。
ContentViewCoreImpl指针变量是ContentViewCoreImpl的构造函数调用ContentViewCoreImpl::InitWebContents()时将自身
作为参数通过调用 ContentViewCoreImpl::InitWebContents(){
 static_cast(web_contents_->GetView())->
      SetContentViewCore(this);
}
WebContentsImpl的构造函数初始化列表中创建了RenderViewHostManager实例。
RenderViewHostManager类为WebContentsImpl管理RenderViewHosts。是WebContentsImpl调用renderer_host模块的桥梁。
RenderViewHostManager类中包含renderer_host模块的核心类RenderViewHostImpl* render_view_host_。
RenderViewHostImpl继承了RenderWidgetHostImpl.
RenderWidgetHost包含一个重要的成员变量RenderWidgetHostViewPort* view_。
RenderWidgetHostView接口代表RenderWidgetHost的View部分,
RenderWidgetHost以及与它相关联的RenderProcessHost维护Model部分,即子renderer进程。
RenderWidgetHostView负责从周围环境接收事件,并将事件传递给RenderWidgetHost。
当RenderWidgetHost的内容发生变化时,RenderWidgetHostView负责实际显示这些内容。
RenderWidgetHostView 类层次结构:
RenderWidgetHostView - 公共接口.
RenderWidgetHostViewPort - 专门针对content/ 和 ports的私有接口.
RenderWidgetHostViewBase - 各平台通用的实现.
RenderWidgetHostViewWin, ... - 平台相关的实现。
RenderWidgetHostView的android平台实现类是RenderWidgetHostViewAndroid。
RenderWidgetHostViewAndroid包含的与网页合成相关的成员变量:
ContentViewCoreImpl* content_view_core_;
scoped_refptr texture_layer_;
scoped_refptr layer_;
texture_layer_是包含render 进程产生的目标texture的layer,也是最终要合成到on-screen surface上的texture.
先看ContentViewCoreImpl* content_view_core_的具体指向。
前面讲过WebContentsViewAndroid包含指向ContentViewCoreImpl的指针变量,这个指针变量是通过如下调用传入的:
ContentViewCoreImpl::InitWebContents(){
 static_cast(web_contents_->GetView())->
      SetContentViewCore(this);
}
接着看WebContentsViewAndroid::SetContentViewCore()
{
 RenderWidgetHostViewAndroid* rwhv = static_cast(
      web_contents_->GetRenderWidgetHostView());
  if (rwhv)
    rwhv->SetContentViewCore(content_view_core_);
}
RenderWidgetHostViewAndroid::SetContentViewCore()将传入的ContentViewCoreImpl*指针变量保存在自己的成员变量ContentViewCoreImpl* content_view_core_中。
RenderWidgetHostViewAndroid的构造函数中调用cc::TextureLayer::Create()创建了TextureLayer的实例,并保存到成员变量scoped_refptr texture_layer_中。
TextureLayer是Layer的具体子类,成员变量scoped_refptr layer_与scoped_refptr texture_layer_指向同一实例。
RenderWidgetHostViewAndroid用到了ImageTransportFactoryAndroid的具体实现类(DirectGLImageTransportFactory或CmdBufferImageTransportFactory)来管理texture和合成同步。
ImageTransportFactoryAndroid的具体实现类CmdBufferImageTransportFactory封装了WebGraphicsContext3DCommandBufferImpl。
CmdBufferImageTransportFactory::CmdBufferImageTransportFactory()的构造函数中创建了WebGraphicsContext3DCommandBufferImpl的实例,surface_id参数为0,代表offscreen.负责管理render进程产生的含有网页内容的目标texture.
WebGraphicsContext3DCommandBufferImpl是与GPU进程通信的类。
下面这个关系的建立发生在Browser进程中合成器:
RenderWidgetHostViewAndroid的scoped_refptr texture_layer_是ContentViewCoreImpl的成员变量scoped_refptr root_layer_的子Layer.
这个关系的建立在RenderWidgetHostViewAndroid::SetContentViewCore()函数中。
RenderWidgetHostViewAndroid::SetContentViewCore()调用AttachLayers()。
RenderWidgetHostViewAndroid::AttachLayers()调用ContentViewCoreImpl::AttachLayer().
ContentViewCoreImpl::AttachLayer(){
 root_layer_->AddChild(layer);

这样,RenderWidgetHostViewAndroid的scoped_refptr texture_layer_就关联到了ContentViewCoreImpl的成员变量scoped_refptr root_layer_为根节点的cc::Layer树上。
上述类之间的关系如下图:


WebKit之chromium进程创建过程分析_第5张图片

这里与网页合成密切相关的类是RenderWidgetHostViewAndroid,以及以ContentViewCoreImpl的成员变量scoped_refptr root_layer_为根节点的cc::Layer树结构。
这两个类会在分析Browser进程的Compositor工作原理时用到。
接下来分析第二部分

二.ContentViewRenderView引出的Compositor模块的内部结构(android平台的compositor定义在compositor_impl_android.cc中)。
ContentViewRenderView包含一个重要的成员变量 scoped_ptr compositor_。
先看这个成员变量的初始化过程:
java层ContentViewRenderView包含的SurfaceView调用
mSurfaceView.getHolder().addCallback(mSurfaceCallback)添加了一组回调接口。
其中surfaceCreated()回调接口的实现调用了ContentViewRenderView的native方法nativeSurfaceCreated(),并将SurfaceView对应的Surface传递给了native层的ContentViewRenderView::SurfaceCreated().
android的Surface类对应一块被屏幕合成器管理的raw buffer.
native层的ContentViewRenderView::SurfaceCreated()调用
ContentViewRenderView::InitCompositor(){
 if (!compositor_)
   compositor_.reset(Compositor::Create(this));
}
android平台的Compositor::Create()实现在compositor_impl_android.cc中。
Compositor::Create()创建了CompositorImpl的实例。
ContentViewRenderView::SurfaceCreated()在调用InitCompositor()创建了CompositorImpl后,
接着调用compositor_->SetSurface(jsurface)将android系统中的Surface类实例传递给CompositorImpl。
CompositorImpl包含以下成员变量:
ANativeWindow* window_; 
int surface_id_;
scoped_refptr root_layer_;
scoped_ptr host_;
先看ANativeWindow* window_的具体指向以及surface_id_的含义。
前面讲过ContentViewRenderView::SurfaceCreated()会调用compositor_->SetSurface(jsurface)将android系统中的Surface类实例传递给CompositorImpl。
CompositorImpl::SetSurface(){
window = ANativeWindow_fromSurface(env, surface);
 if (surface)
    window = ANativeWindow_fromSurface(env, surface);
  if (window) {
    SetWindowSurface(window);
     ......
  }
}
即CompositorImpl::SetSurface()通过android系统中的Surface类实例得到ANativeWindow,并将这个ANativeWindow传递给SetWindowSurface()函数。
CompositorImpl::SetWindowSurface()将传递进来的ANativeWindow实例保存在自己的成员变量ANativeWindow* window_中,
CompositorImpl::SetWindowSurface()调用 
surface_id_ = tracker->AddSurfaceForNativeWidget(window);
注册ANativeWindow到GpuSurfaceTracker,同时将GpuSurfaceTracker中产生的标识该ANativeWindow的surface_id保存到surface_id_中。
先看GpuSurfaceTracker的用途和结构。
GpuSurfaceTracker负责管理暴露给GPU进程使用的rendering surfaces.每个rendering surface都要在GpuSurfaceTracker中注册,并获得一个ID.
所有发给GPU进程的调用和从GPU进程发出的调用(除了CreateViewCommandBuffer)都通过rendering surface的ID来标识这个rendering surface.
GpuSurfaceTracker是线程安全的。
GpuSurfaceTracker通过一个内部结构SurfaceInfo来记录rendering surface的信息.每个rendering surface都由一个唯一的surface_id来标识。
surface_id和rendering surface组成一个键值对存储在map结构SurfaceMap中。
注册到GpuSurfaceTracker中的rendering surface分为两种:
一种由render进程控制GPU进程使用,渲染网页内容的各个层需要用到的rendering surface,这种surface对应的SurfaceInfo要包含如下信息:
renderer_id:使用该rendering surface的render进程ID;
renderer_widget_id:使用该rendering surface的render进程对应的Browser进程中的RenderWidgetHost的route id。
这种rendering surface我们在介绍render进程的内部结构时再详细介绍。
另一种rendering surface就是这里介绍的,由本地窗口系统提供的一块raw buffer(android平台由ANativeWindow标识),
由Browser进程的合成器注册并控制使用,是render进程产生的texture的最终合成目的地。
这种surface对应的SurfaceInfo要包含gfx::AcceleratedWidget信息,gfx::AcceleratedWidget是本地窗口系统提供给合成器的,用来绘制像素的rendering surface.
android平台是ANativeWindow实例。
不需要render_id和render_widget_id信息,所以都置为0. 
所以CompositorImpl中的ANativeWindow* window_代表android平台的窗口系统管理的一块raw buffer,是browser进程的合成器控制gpu进程使用的rendering surface,是网页内容最终合成的目的地;
CompositorImpl中的int surface_id_用来唯一标识ANativeWindow* window_。
CompositorImpl::CreateOutputSurface()中将surface_id_作为参数创建了WebGraphicsContext3DCommandBufferImpl的实例,
并以WebGraphicsContext3DCommandBufferImpl的实例为参数创建了cc::OutputSurface的实例,这个cc::OutputSurface的实例最终被传给了GLRenderer.
RenderWidgetHostViewAndroid用到了ImageTransportFactoryAndroid的具体实现类CmdBufferImageTransportFactory。

CmdBufferImageTransportFactory()负责管理消耗render进程产生的目标texture.
接下来看scoped_refptr root_layer_的具体指向。
java层ContentViewRenderView::setCurrentContentView()
通过JNI调用到native层ContentViewRenderView::SetCurrentContentView(),调用
CompositorImpl::SetRootLayer(),同时将ContentViewCoreImpl::GetLayer()作为参数传入。
CompositorImpl::SetRootLayer(){
root_layer_->RemoveAllChildren();
root_layer_->AddChild(root_layer);
}
所以我们知道了,第一部分中分析的ContentViewCoreImpl的成员变量scoped_refptr root_layer_为根节点的cc::Layer树传递到了CompositorImpl中,
变成了以CompositorImpl中的root_layer_为根节点。
CompositorImpl::root_layer_包含ContentViewCoreImpl::root_layer_,
ContentViewCoreImpl::root_layer_包含RenderWidgetHostViewAndroid::texture_layer_.
这三个cc::Layer组成了以CompositorImpl::root_layer_为根节点的Layer tree.
接下来看scoped_ptr host_的具体创建。
CompositorImpl::SetWindowSurface()调用CompositorImpl::SetVisible().
CompositorImpl::SetVisible()调用 cc::LayerTreeHost::Create()创建了LayerTreeHost.
Compositor::InitializeWithFlags()通过DIRECT_CONTEXT_ON_DRAW_THREAD标识,决定是否将合成动作放在单独的线程中。
接下来看LayerTreeHost的结构。
scoped_ptr proxy_;
scoped_refptr root_layer_;
scoped_ptr contents_texture_manager_;
scoped_ptr surface_memory_placeholder_;
先看proxy_的初始化过程。
CompositorImpl::SetVisible()调用 cc::LayerTreeHost::Create()创建了LayerTreeHost,并传入一个impl_thread作为参数。
如果Compositor::InitializeWithFlags()中判断合成动作不放在单独的线程中,则传入cc::LayerTreeHost::Create()的impl_thread为null.
cc::LayerTreeHost::Create()在创建LayerTreeHost实例后,调用LayerTreeHost::Initialize()同时将CompositorImpl中的impl_thread作为参数传入。
LayerTreeHost::Initialize()根据传入的impl_thread是否为null,来决定创建SingleThreadProxy还是ThreadProxy。
先看DIRECT_CONTEXT_ON_DRAW_THREAD 标志没有设置时的情形,此时LayerTreeHost创建的是SingleThreadProxy实例。
所以scoped_ptr proxy_指向的是SingleThreadProxy实例。
接着看scoped_refptr root_layer_的具体指向。
CompositorImpl::SetVisible()再调用cc::LayerTreeHost::Create()创建完LayerTreeHost后,调用
LayerTreeHost::setRootLayer()将CompositorImpl的root_layer_传给LayerTreeHost.
LayerTreeHost::SetRootLayer()将CompositorImpl的root_layer_保存在自己的root_layer_中。
所以以CompositorImpl中的root_layer_为根节点的Layer树,传到了LayerTreeHost中,以LayerTreeHost::root_layer_为根节点。
接着看scoped_ptr contents_texture_manager_和
scoped_ptr surface_memory_placeholder_的创建过程。
SingleThreadProxy::OnOutputSurfaceInitializeAttempted()调用
LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(){
contents_texture_manager_ = PrioritizedResourceManager::Create(proxy_.get());
surface_memory_placeholder_ = contents_texture_manager_->CreateTexture(gfx::Size(), GL_RGBA);
}
PrioritizedResourceManager是管理PrioritizedResource的类,每个PrioritizedResource都会通过PrioritizedResourceManager::RegisterTexture()
注册给PrioritizedResourceManager。
PrioritizedResourceManager维护一个base::hash_setTextureSet结构,所有注册给PrioritizedResourceManager的PrioritizedResource
都存储在TextureSet结构中。
PrioritizedResource有一个重要的内部结构Backing.Backing继承自Resource。Resource由ResourceProvider负责创建。Resource中含有一个重要变量ResourceProvider::ResourceId id_。
SingleThreadProxy有两个重要的成员变量:
scoped_ptr first_output_surface_;
scoped_ptr layer_tree_host_impl_;
LayerTreeHost::InitializeProxy()先调用CreateOutputSurface().
LayerTreeHost::CreateOutputSurface()调用
CompositorImpl::CreateOutputSurface()创建OutputSurface实例。
LayerTreeHost::InitializeProxy()接着调用proxy_->Start(output_surface.Pass())将新创建的OutputSurface实例传递给SingleThreadProxy.
前面讲过,
CompositorImpl::CreateOutputSurface()中将surface_id_作为参数创建了WebGraphicsContext3DCommandBufferImpl的实例,
并以WebGraphicsContext3DCommandBufferImpl的实例为参数创建了cc::OutputSurface的实例。
SingleThreadProxy::CreateAndInitializeOutputSurface()调用LayerTreeHostImpl::InitializeRenderer()将CompositorImpl::CreateOutputSurface()创建的OutputSurface传递给了GLRenderer.
SingleThreadProxy::Start()调用
LayerTreeHost::CreateLayerTreeHostImpl()
生成LayerTreeHostImpl实例保存在成员变量scoped_ptr layer_tree_host_impl_中。
LayerTreeHostImpl包含如下成员变量:
scoped_ptr resource_provider_;
scoped_ptr tile_manager_;
scoped_ptr renderer_;
scoped_ptr active_tree_;
LayerTreeHostImpl::InitializeRenderer()中调用ResourceProvider::Create()创建了ResourceProvider,同时将CompositorImpl::CreateOutputSurface()创建的OutputSurface传递给了ResourceProvider.
CompositorImpl::SetVisible()将cc::LayerTreeSettings::impl_side_painting = false;所以
LayerTreeHostImpl::InitializeRenderer()没有走下面的分支:
tile_manager_ = TileManager::Create();
所以Browser进程中的LayerTreeHostImpl中包含的scoped_ptr tile_manager_为null.
LayerTreeHostImpl::InitializeRenderer()中调用GLRenderer::Create()创建了GLRenderer,同时将CompositorImpl::CreateOutputSurface()创建的OutputSurface,已经刚刚创建的ResourceProvider传递给
GLRenderer.GLRenderer继承自DirectRenderer,DirectRenderer包含指向ResourceProvider的指针变量。
LayerTreeHostImpl的构造函数中调用LayerTreeImpl::create()创建了LayerTreeImpl实例并保存在active_tree_中。
active_tree_的实际赋值发生在LayerTreeHost::FinishCommitOnImplThread()函数中:

.........
else{ contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
    sync_tree = host_impl->active_tree();
  }

  if (needs_full_tree_sync_)
    sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
        root_layer(), sync_tree->DetachLayerTree(), sync_tree));
  {
    TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
    TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
  }
.........
}
上述代码将LayerTreeHost的Layer树转变为LayerTreeHostImpl的LayerImpl树。

第二部分涉及的类图如下:

WebKit之chromium进程创建过程分析_第6张图片

第二部分总结:
1.LayerTreeHost的成员变量scoped_refptr root_layer_包含RenderWidgetHostViewAndroid的scoped_refptr texture_layer_.
RenderWidgetHostViewAndroid是TextureLayer的Client端。
2.LayerTreeHostImpl的成员变量scoped_ptr active_tree_包含LayerImpl成员变量root_layer_,这里实际是TextureLayerImpl,由1中提到的
RenderWidgetHostViewAndroid的scoped_refptr texture_layer_创建的。 
3.LayerTreeHost与LayerTreeHostImpl是一一对应的关系,LayerTreeHost运行在主线程中,LayerTreeHostImpl运行在主线程的封装线程中,这两个类通过SingleThreadProxy联系起来。
LayerTreeHost的成员变量scoped_refptr root_layer_与LayerTreeHostImpl的active_tree_的成员变量root_layer_是一一对应的关系。
LayerTreeHostImpl的active_tree_是由LayerTreeHost的成员变量scoped_refptr root_layer_创建出来的。
4.SingleThreadProxy继承自Proxy,Proxy是抽象类,负责将compositor的主线程命令代理给compositor的具体实现类。这点会在render进程结构分析中详细说明。
5.LayerTreeHostImpl包含的GLRenderer负责与GPU进程通信,控制具体的合成过程。
GLRenderer,(DirectRenderer包含的)ResourceProvider(包含OutputSurface),都会通过OutputSurface中包含的WebGraphicsContext3DCommandBufferImpl与GPU进程通信。
6.前面讲过OutputSurface中包含的WebGraphicsContext3DCommandBufferImpl在创建时需要surface_id作为参数,这个surface_id是GPU进程使用的,由本地窗口系统提供的一块raw buffer,
在android平台是AnativeWindow.
7.browser进程需要与GPU进程通信,所以browser进程会创建GPUChannelHost的实例。


三 chromium for android render进程创建过程分析

render进程的创建是由应用程序调用ContentView.java的loadUrl开始触发的。
ContentView.java的loadUrl调用ContentViewCore.java的loadUrl,
ContentViewCore.java调用nativeLoadUrl(),通过chromium的jni机制
ContentViewCore_jni.h(定义在out/Release/gen/content/jni)
最终调用到native层的content_view_core_impl.cc的loadUrl.

下面的顺序图是从content_view_core_impl.cc的loadUrl开始的触发render进程创建的整个过程:


WebKit之chromium进程创建过程分析_第7张图片

ChildProcessLauncher.java中的方法是供底层调用,用于启动和停止ChildProcess的。
ChildProcessLauncher.java的warmUp方法完成子进程孵化准备工作,即创建ChildProcessConnection。
warmUp应该在应用程序启动的早期调用,这样子进程的孵化准备工作就可以和其他启动工作并行进行。 
warmUp一定不能在UI线程中调用。 
ChildProcessConnection实现了接口ServiceConnection,用来监测应用程序的子进程的状态。
ChildProcessLauncher.java有一个内部类ChildConnectionAllocator,负责ChildProcessConnection的创建和销毁。
render进程是应用程序的子进程,以service的形式提供给应用程序。
需要在应用程序的AndroidMenifest.xml中声明render进程中运行的service。
声明方式如下:
android:process=":sandboxed_process0" android:isolatedProcess="true" />
       
sandboxservice图:


WebKit之chromium进程创建过程分析_第8张图片

下面的顺序图是应用程序调用warmUp触发的ChildProcessService的创建过程:

WebKit之chromium进程创建过程分析_第9张图片


注意:warmUp在应用程序中只调用一次,所以只有SandboxedProcessService0的创建过程是由warmUp触发的,并且ChildProcessService的onCreate方法中并没有触发到底层process的创建,
即ChildProcessService的onCreate()没有执行到ContentMain.initApplicationContext,就被阻塞了。
render进程的更通用的创建方式是由native层的ChildProcessLauncher(定义在child_process_launcher.cc中)回调java层的ChildProcessLauncher的Start方法触发的。
RenderProcessHost* SiteInstanceImpl::GetProcess()会创建RenderProcessHost
WebContentsImpl::CreateRenderViewForRenderManager()
调用RenderViewHostImpl::CreateRenderView()
{
if (!GetProcess()->Init())
}
RenderViewHostImpl继承自RenderWidgetHostImpl。RenderWidgetHostImpl中定义了GetProcess()返回RenderProcessHost。
RenderProcessHostImpl::Init方法创建了RendererMainThread,也创建了ChildProcessLauncher。

child_process_launcher_.reset(new ChildProcessLauncher(
}
ChildProcessLauncher定义了一个内部的私有类Context。
ChildProcessLauncher的构造函数创建了ChildProcessLauncher::Context的一个实例,并调用launch.
launch调用  BrowserThread::PostTask,
这个调用会导致调用Context::LaunchInternal。
Context::LaunchInternal调用一个全局函数StartChildProcess。
全局函数StartChildProcess定义在child_process_launcher_android.cc中。
StartChildProcess(){
Java_ChildProcessLauncher_start(env,
      base::android::GetApplicationContext(),
      j_argv.obj(),
      j_file_ids.obj(),
      j_file_fds.obj(),
      j_file_auto_close.obj(),
      reinterpret_cast(new StartChildProcessCallback(callback)));
}
Java_ChildProcessLauncher_start定义在out/Release/gen/content/jni/ChildProcessLauncher_jni.h
Java_ChildProcessLauncher_start回调了java层ChildProcessLauncher.start函数。
ChildProcessLauncher.start函数在第一次调用时,由于SandboxedProcessService0已经创建,并阻塞在ChildProcessService的onCreate方法中,所以
ChildProcessLauncher.start使ChildProcessService的onCreate方法继续执行如下片段:
{
 ContentMain.initApplicationContext(sContext.get().getApplicationContext());
 nativeInitChildProcess(sContext.get().getApplicationContext(),ChildProcessService.this, fileIds, fileFds,mCpuCount, mCpuFeatures);
 ContentMain.start();
 nativeExitChildProcess();
}
在创建第二个Tab时,SandboxedProcessService1的创建是由以下调用触发的,
ChildProcessLauncher.start函数调用allocateBoundConnection,
allocateBoundConnection调用allocateConnection生成一个ChildProcessConnection实例。
allocateBoundConnection调用新生成的ChildProcessConnection的bind方法,
ChildProcessConnection的bind调用Context::bindService(),bindService触发SandboxedProcessService1的onCreate方法。
SandboxedProcessService1是ChildProcessService的基类,从ChildProcessService继承onCreate方法。所以实际执行的是
ChildProcessService::onCreate。
目前最多只能创建三个render进程。
接下来的流程与Browser进程的创建过程一样,直到函数ChromeMainDelegateAndroid::RunProcess(
    const std::string& process_type,
    const content::MainFunctionParams& main_function_params) {
  TRACE_EVENT0("startup", "ChromeMainDelegateAndroid::RunProcess")
  if (process_type.empty()) { //创建Browser进程
    JNIEnv* env = base::android::AttachCurrentThread();
    RegisterApplicationNativeMethods(env);

    browser_runner_.reset(content::BrowserMainRunner::Create());
    return browser_runner_->Initialize(main_function_params);
  }
  //创建非Browser进程,比如Render进程 
  return ChromeMainDelegate::RunProcess(process_type, main_function_params);
}
android平台的ChromeMainDelegate::RunProcess返回-1.所以render进程执行RunNamedProcessTypeMain()走的流程是:
return kMainFunctions[i].function(main_function_params);进而调用RenderMain(),RenderMain定义在Render_main.cc中.


四 chromium for android render进程结构分析


一.首先看Render进程中的核心类RenderWidget,RenderView(Impl)与WebKit模块之间关系的建立
RendeWidget与WebKit::WebWidget,RenderView(Impl)与WebKit::WebView(Impl)之间的关系
RenderWidget类是WebKit::WebWidget和RenderWidgetHost之间的通信桥梁。
RenderWidgetHost运行在Browser进程中。
RenderView用来管理WebView,并为内嵌的应用提供通信接口。
RenderWidget包含一个WebKit::WebWidget*类型的成员变量webwidget_。
通过RenderWidget的静态函数Create直接创建RenderWidget的实例时,才会导致WebKit::WebWidget实例的成员变量webwidget_的创建.
RenderViewImpl是RenderWidget的子类同时也是RenderView的实现子类,创建RenderViewImpl实例导致RenderWidget实例被创建时,RenderWidget中不会创建WebKit::WebWidget。
RenderViewImpl::Create()函数中创建了RenderViewImpl,并调用了RenderViewImpl::Initialize().
RenderViewImpl::Initialize()函数中调用webwidget_ = WebView::create(this)创建了WebViewImpl的实例,并保存在RenderWidget中定义的变量webwidget_中。
以上分析,我们可以得到以下结论:
RenderWidget对应于WebKit::WebWidget;
RenderViewImpl对应于WebKit::WebViewImpl(WebKit::WebView的实现子类);
只有创建RenderWidget实例时,才会导致WebKit::WebWidget的具体子类实例的创建;
创建RenderViewImpl实例时,会导致WebKit::WebViewImpl(WebKit::WebView的实现子类)实例的创建;
RenderWidget继承自WebKit::WebWidgetClient,在创建WebKit::WebWidget的具体子类实例时,RenderWidget将自身作为参数传给WebKit::WebWidget的具体子类。
RenderViewImpl继承自WebKit::WebViewClient,在创建WebKit::WebViewImpl时,RenderViewImpl将自身作为参数传给WebKit::WebViewImpl.
WebKit::WebWidget的三个子类WebKit::WebPopupMenu, WebKit::WebPagePopup, WebKit::WebPopupTypeHelperPlugin都包含一个成员变量WebWidgetClient* m_widgetClient,实际指向RenderWidget.
WebKit::WebViewImpl中包含一个成员变量WebViewClient* m_client,这个成员变量指向RenderViewImpl.
这样, RenderWidget包含WebKit::WebWidget的指针变量,WebKit::WebWidget也包含RenderWidget的指针变量,两者可以双向通信了。
同理,RenderViewImpl包含WebKit::WebViewImpl的指针变量,WebKit::WebViewImpl也包含RenderViewImpl的指针变量,两者也可以双向通信了。

类关系图:

WebKit之chromium进程创建过程分析_第10张图片

WebKit之chromium进程创建过程分析_第11张图片

WebKit::WebWidgetClient中提供的接口都与事件处理,窗口渲染相关。
WebKit::WebViewClient中提供的接口都是与界面行为相关的,如Session,zoom,Accessibility,Geolocation,Speech等。
二.接着看WebKit中与网页渲染相关的类结构
WebKit中负责网页内容渲染的主要类如下:
RenderView:
RenderView是RenderTree同时也是RenderLayerTree的根节点,渲染网页内容需要遍历RenderLayerTree.遍历过程是由RenderLayerTree的根结点RenderView触发的。
一个RenderView对应一个RenderLayerCompositor。
RenderLayerCompositor:
RenderLayerCompositor管理compositing layer层次结构,决定可以作为compositing layer的RenderLayer,基于compositing layer的绘制顺序,创建并维护一个GraphicsLayer层次结构。
RenderLayer:
RenderLayer类对应于一颗render object子树,代表一层网页内容。
RenderLayerBacking:
RenderLayerBacking管理和控制RenderLayer的合成行为,包含很多GraphicsLayer对象,用来决定Layer内部的优化。
GraphicsLayer:
GraphicsLayer是后端存储类的抽象,后端存储类由不同平台提供。chromium for android平台提供的是cc::PictureLayer。GraphicsLayer通过一系列的中间layer最终间接包含cc::PictureLayer.
cc::PictureLayer才是GraphicsLayer的后端存储,也就是网页内容的绘制命令的存储地。参考硬件渲染流程分析。
以上各类的关系如下:

WebKit之chromium进程创建过程分析_第12张图片

RenderLayerBacking中包含的GraphicsLayer是理解网页渲染的重要类,我们看RenderLayerBacking创建GraphicsLayer的过程:
下面是调用流程:
FrameView::layout()调用了
FrameView::updateCompositingLayersAfterLayout()调用了
RenderLayerCompositor::updateCompositingLayers()调用了
RenderLayerCompositor::computeCompositingRequirements()调用了
RenderLayerCompositor::updateBacking()中调用了
RenderLayer::ensureBacking()中创建了RenderLayerBacking的实例
RenderLayerBacking的构造函数中调用了
RenderLayerBacking::createPrimaryGraphicsLayer()
调用RenderLayerBacking::createGraphicsLayer()。
GraphicsLayer的创建会导致一系列Layer的创建,我们看GraphicsLayer的构造函数:
GraphicsLayer(){
 m_opaqueRectTrackingContentLayerDelegate = adoptPtr(new OpaqueRectTrackingContentLayerDelegate(this));
 m_layer = adoptPtr(Platform::current()->compositorSupport()->createContentLayer(m_opaqueRectTrackingContentLayerDelegate.get()));
}
GraphicsLayer创建的顺序图如下:

WebKit之chromium进程创建过程分析_第13张图片


由此,我们可以得到以下结论:
WebKit::GraphicsLayer包含WebKit::WebContentLayerImpl,保存在成员变量OwnPtr m_layer中;
WebKit::WebContentLayerImpl包含WebKit::WebLayerImpl,保存在成员变量scoped_ptr layer_中;
WebKit::WebLayerImpl包含cc::PictureLayer,保存在成员变量scoped_refptr layer_中;
RenderLayerBacking中创建的GraphicsLayer实例会被attach到RenderLayerCompositor的成员变量OwnPtr m_rootContentLayer上,具体过程如下:
RenderLayerCompositor::updateCompositingLayers()调用了
RenderLayerCompositor::rebuildCompositingLayerTree().
rebuildCompositingLayerTree()中将RenderLayerBacking的GraphicsLayer添加到一个Vector结构中。
RenderLayerCompositor::updateCompositingLayers()调用完rebuildCompositingLayerTree()后调用
m_rootContentLayer->setChildren(childList);
这样,RenderLayerCompositor的成员变量OwnPtr m_rootContentLayer中就包含了所有的RenderLayerBacking创建的GraphicsLayer。
三.我们看Render进程中控制网页各层内容渲染的类结构
LayerTreeHost,ThreadProxy与LayerTreeHostImpl之间的关系
RenderWidgetCompositor::initialize()中调用LayerTreeHost::Create创建了LayerTreeHost,同时将RenderThreadImpl封装后传给了LayerTreeHost.
LayerTreeHost::Create(),
调用了LayerTreeHost::Initialize()。
LayerTreeHost::Initialize()中可知,RenderWidgetCompositor包含的LayerTreeHost中创建的是ThreadProxy的实例。
Proxy是抽象类,负责将compositor的主线程命令代理给compositor的具体实现类。
class CC_EXPORT Proxy包含两个主要的成员变量:
scoped_ptr main_thread_;
scoped_ptr impl_thread_;
Proxy对象的构造函数会调用ThreadImpl::CreateForCurrentThread()初始化main_thread_,main_thread_代表当前线程。根据传入的Thread参数来初始化impl_thread_。
ThreadProxy的构造函数包含一个有效的Thread参数,它的基类Proxy用这个Thread类型的参数初始化impl_thread_,所以ThreadProxy拥有两个线程实例main_thread_和impl_thread_。
SingleThreadProxy的构造函数将一个Null传给它的基类Proxy的构造函数,所以SingleThreadProxy只包含当前线程的一个封装类main_thread_,这也是其名字的由来。
SingleThreadProxy和ThreadProxy都含有以下对象成员变量:
LayerTreeHost* layer_tree_host_;
scoped_ptr layer_tree_host_impl_;
SingleThreadProxy::Start函数中调用LayerTreeHost::CreateLayerTreeHostImpl创建LayerTreeHostImpl并将其保存在 layer_tree_host_impl_中。
ThreadProxy::InitializeImplOnImplThread调用LayerTreeHost::CreateLayerTreeHostImpl创建LayerTreeHostImpl并将其保存在 layer_tree_host_impl_中。
SingleThreadProxy和ThreadProxy持有LayerTreeHostImpl,并继承了LayerTreeHostImplClient,在构建LayerTreeHostImpl的同时将自身传给了LayerTreeHostImpl的构造函数。
SingleThreadProxy和ThreadProxy是LayerTeeHost和LayerTreeHostImpl相互协作的桥梁。
ThreadProxy中的函数,一部分是在主线程中执行,一部分是在impl 线程中执行。对于RenderWidgetCompositor包含的LayerTreeHost中创建的是ThreadProxy的实例,impl线程是RenderThreadImpl的实例。
ThreadProxy中在impl线程中执行的函数带有OnImplThread后缀。
ThreadProxy还含有以下成员变量:
scoped_ptr scheduler_on_impl_thread_;
这个变量的作用是调度impl线程中执行的动作。
ThreadProxy中调用scheduler_on_impl_thread_的接口,
scheduler_on_impl_thread_的接口调用scheduler_on_impl_thread_的ProcessScheduledActions()函数,
ProcessScheduledActions()最终又调回到ThreadProxy中ScheduledAction开头的函数。
ThreadProxy::InitializeImplOnImplThread()中调用LayerTreeHost::CreateLayerTreeHostImpl()创建了LayerTreeHostImpl.
LayerTreeHostImpl只在ThreadProxy的impl线程中调用。
这部分结构与browser进程中compositor部分类似。
render进程中的渲染完成的是包含网页内容的各个层的合成。
browser进程中compositor部分完成的是将render进程渲染好的texture合成到on-screen surface对应的back buffer上,并调用eglswapbuffer将前后buffer互换,下次屏幕刷新时候,网页内容就显示在屏幕上了。
四.接着看Render进程中控制网页渲染的核心类RenderWidgetCompositor与WebKit模块之间的关系建立
RenderWidgetCompositor与WebKit::WebViewImpl的关系建立过程
RenderWidget包含一个成员变量scoped_ptr compositor_。
RenderWidgetCompositor继承自WebKit::WebLayerTreeView,负责控制网页各个层的合成工作。
WebKit::WebViewImpl中包含一个成员变量WebLayerTreeView* m_layerTreeView,这个成员变量指向RenderWidget中创建的RenderWidgetCompositor实例。
下面的顺序图是RenderWidget创建RenderWidgetCompositor,以及RenderWidgetCompositor被保存到WebKit::WebViewImpl的成员变量WebLayerTreeView* m_layerTreeView中的过程。

WebKit之chromium进程创建过程分析_第14张图片


关键代码如下:
WebViewImpl::setIsAcceleratedCompositingActive(){
m_client->initializeLayerTreeView();
m_layerTreeView = m_client->layerTreeView();
}

五.LayeTreeHost的成员变量scoped_refptr root_layer_与WebKit中RenderLayerCompositor的成员变量OwnPtr m_rootContentLayer之间的关系建立
先给出结论,LayeTreeHost的成员变量scoped_refptr root_layer_实际指向的是PictureLayer的实例,这个实例是RenderLayerCompositor的成员变量OwnPtr m_rootContentLayer创建时创建的。
被OwnPtr m_rootContentLayer间接包含。
WebKit::RenderView::compositor()中创建了RenderLayerCompositor,并保存在m_compositor变量中,
RenderLayerCompositor中有指向创建它的RenderView的成员变量RenderView* m_renderView。 
RenderLayerCompositor::ensureRootLayer()中创建了用于不同目的的各个GraphicsLayer,其中代表content root的GraphicsLayer中存储了RenderLayer对应的RenderLayerBacking中创建的GraphicsLayer.
在RenderLayerCompositor::attachRootLayer()中将代表content root的GraphicsLayer传给了ChromeClientImpl,
并由ChromeClientImpl::attachRootGraphicsLayer()调用WebViewImpl::setRootGraphicsLayer()进一步传递给了WebKit::WebViewImpl。
所以WebKit::WebViewImpl中的成员变量 WebCore::GraphicsLayer* m_rootGraphicsLayer,保存的是RenderLayerCompositor的成员变量OwnPtr m_rootContentLayer。
WebViewImpl::setRootGraphicsLayer()中调用GraphicsLayer::platformLayer()给成员变量WebLayer* m_rootLayer赋值。
PlatformLayer* GraphicsLayer::platformLayer() const
{
    return m_transformLayer ? m_transformLayer.get() : m_layer->layer();
}
PlatformLayer.h中有如下定义:
typedef WebKit::WebLayer PlatformLayer;
前面讲过,
WebKit::GraphicsLayer包含WebKit::WebContentLayerImpl,保存在成员变量OwnPtr m_layer中;
WebKit::WebContentLayerImpl包含WebKit::WebLayerImpl,保存在成员变量scoped_ptr layer_中;
WebKit::WebLayerImpl包含cc::PictureLayer,保存在成员变量scoped_refptr layer_中;
WebKit::WebContentLayer::layer()返回的是指向WebLayer的指针。
WebKit::WebContentLayerImpl::layer()返回的是指向WebLayerImpl的指针。
所以GraphicsLayer::platformLayer()返回的是WebLayerImpl的实例.
WebViewImpl的成员变量WebLayer* m_rootLayer中保存的是WebLayerImpl的实例。
WebViewImpl::setIsAcceleratedCompositingActive()中调用了
m_layerTreeView->setRootLayer(*m_rootLayer);
实际调用的是RenderWidgetCompositor::setRootLayer(const WebKit::WebLayer& layer){
layer_tree_host_->SetRootLayer(
      static_cast(&layer)->layer());
}
RenderWidgetCompositor包含一个成员变量scoped_ptr layer_tree_host_。
前面讲过,WebLayerImpl包含cc::PictureLayer,所以设置给LayerTreeHost的是cc::PictureLayer的实例,保存在LayeTreeHost的成员变量scoped_refptr root_layer_中。
并且这个cc::PictureLayer是在WebKit::RenderLayerCompositor创建OwnPtr m_rootContentLayer时创建的,被m_rootContentLayer间接包含。
上述过程是由Document::attach()函数触发的,具体流程在renderwidgetcompositorcreated顺序图中。

三,四,五中涉及类图如下:

WebKit之chromium进程创建过程分析_第15张图片

你可能感兴趣的:(WebKit)