当前位置:首页 > Chromium网页Layer Tree创建过程分析
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void LayerTreeHost::InitializeProxy(scoped_ptr
proxy_ = proxy.Pass(); proxy_->Start(); }
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host.cc中。
LayerTreeHost类的成员函数InitializeProxy首先将参数proxy描述的一个ThreadProxy对象保存在成员变量proxy_中,接着再调用上述ThreadProxy对象的成员函数Start对它进行启动,如下所示:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void ThreadProxy::Start() { ......
CompletionEvent completion;
Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE,
base::Bind(&ThreadProxy::InitializeImplOnImplThread, base::Unretained(this), &completion)); completion.Wait();
main_thread_weak_ptr_ = main().weak_factory.GetWeakPtr();
main().started = true; }
这个函数定义在文件external/chromium_org/cc/trees/thread_proxy.cc中。
ThreadProxy类的成员函数Start主要是向Compositor线程的消息队列发送了一个Task,并且等待这个Task完成。这个Task绑定了ThreadProxy类的成员函数InitializeImplOnImplThread,因此接下来ThreadProxy类的成员函数InitializeImplOnImplThread就会在Compositor线程中执行,如下所示:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { ......
impl().layer_tree_host_impl =
layer_tree_host()->CreateLayerTreeHostImpl(this);
SchedulerSettings scheduler_settings(layer_tree_host()->settings()); impl().scheduler = Scheduler::Create(this,
scheduler_settings,
impl().layer_tree_host_id, ImplThreadTaskRunner()); ......
impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr(); completion->Signal(); }
这个函数定义在文件external/chromium_org/cc/trees/thread_proxy.cc中。
ThreadProxy类的成员函数InitializeImplOnImplThread主要是做了三件事情。
第一件事情是调用前面创建的LayerTreeHost对象的成员函数CreateLayerTreeHostImpl函数创建了一个LayerTreeHostImpl对象,并且保存在内部的一个CompositorThreadOnly对象的成员变量layer_tree_host_impl中。前面创建的LayerTreeHost对象可以通过调用成员函数layer_tree_host获得。内部的CompositorThreadOnly对象可以通过调用成员函数impl获得。创建出来的LayerTreeHostImpl对象以后负责管理CC Pending Layer Tree和CC Active Layer Tree。
第二件事情是调用Scheduler类的静态成员函数Create创建了一个Scheduler对象。这个Scheduler对象以后就负责在Main线程与Compositor线程之间调度渲染工作。
第三件事情是将参数completion描述的Completion Event设置为有信号,这样正在等待的Main线程就可以唤醒继续执行其它工作了。
接下来我们继续分析LayerTreeHost类的成员函数CreateLayerTreeHostImpl创建LayerTreeHostImpl对象的过程,如下所示:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
scoped_ptr
scoped_ptr
proxy_.get(),
rendering_stats_instrumentation_.get(), shared_bitmap_manager_, id_);
host_impl->SetUseGpuRasterization(UseGpuRasterization()); ......
return host_impl.Pass(); }
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host.cc中。
LayerTreeHost类的成员函数CreateLayerTreeHostImpl首先是调用LayerTreeHostImpl类的静态成员函数Create创建了一个LayerTreeHostImpl对象,接着再调用这个
LayerTreeHostImpl对象的成员函数SetUseGpuRasterization设置它是否使用GPU光栅化。
LayerTreeHostImpl对象的创建过程,即LayerTreeHostImpl类的构造函数的实现,如下所示:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 LayerTreeHostImpl::LayerTreeHostImpl( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy,
RenderingStatsInstrumentation* rendering_stats_instrumentation, SharedBitmapManager* manager, int id)
: client_(client), proxy_(proxy), ...... {
.......
// LTHI always has an active tree.
active_tree_ = LayerTreeImpl::create(this); ...... }
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host_impl.cc中。 从前面的调用过程可以知道,参数client和proxy指向的是同一个ThreadProxy对象,它们分别保存在LayerTreeHostImpl类的成员变量client_和proxy_中。LayerTreeHostImpl类的构造函数接下来还调用LayerTreeImpl类的静态成员函数create创建了一个Active Layer Tree。注意,这时候Pending Layer Tree还没有创建,等到要将Layer Tree内容同步到Pending Layer Tree的时候才会创建。
回到LayerTreeHost类的成员函数CreateLayerTreeHostImpl,它创建了一个LayerTreeHostImpl对象之后,接下来调用另外一个成员函数UseGpuRasterization获取Render进程是否要采用GPU光栅化的信息,如下所示:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 bool LayerTreeHost::UseGpuRasterization() const { if (settings_.gpu_rasterization_forced) { return true;
} else if (settings_.gpu_rasterization_enabled) { return has_gpu_rasterization_trigger_ &&
content_is_suitable_for_gpu_rasterization_; } else {
return false; } }
这个函数定义在文件external/chromium_org/cc/trees/layer_tree_host.cc中。
当Render进程设置了\和\启动选项时,LayerTreeHost类的成员变量settings_指向的LayerTreeSettings对象的成员变量gpu_rasterization_forced的值就会等于true,这时候就会强制使用GPU光栅化。
当Render进程设置了\启动选项时,LayerTreeHost类的成员变量settings_指向的LayerTreeSettings对象的成员变量gpu_rasterization_enabled的值就会等于true,这时候是否使用GPU光栅化取决于LayerTreeHost类另外两个成员变量has_gpu_rasterization_trigger_和content_is_suitable_for_gpu_rasterization_。当这两个成员变量的值均等于true的时候,就会使作GPU光栅化。
LayerTreeHost类的成员变量has_gpu_rasterization_trigger_的值由WebKit间接调用LayerTreeHost类的成员函数SetHasGpuRasterizationTrigger进行设置,这一点可以参考WebViewImpl类的成员函数updatePageDefinedViewportConstraints,主要是与网页的Viewport大小以及当前的缩放因子有关。LayerTreeHost类的成员变量content_is_suitable_for_gpu_rasterization_的值由Skia决定,后者根据当前要绘制的内容决定的,例如,如果要绘制的内容包含太多的凹多边形,并且这些凹多边形使用了反锯齿效果,那么就会禁用GPU光栅化。这一点可以参考SkPicturePlayback类的成员函数suitableForGpuRasterization。
在其它情况下,都是禁止使用GPU光栅化的。在目前的版本中,Render进程设置了\和\启动选项,因此会强制使用GPU光栅化。在以后的文章中,我们都是假设Chromium是使用GPU光栅化的。
再回到LayerTreeHost类的成员函数CreateLayerTreeHostImpl,它获得Render进程是否要采用GPU光栅化的信息之后,就会设置给前面创建的LayerTreeHostImpl对象,这是通过调用LayerTreeHostImpl类的成员函数SetUseGpuRasterization如下所示:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void LayerTreeHostImpl::SetUseGpuRasterization(bool use_gpu) { if (use_gpu == use_gpu_rasterization_) return;
use_gpu_rasterization_ = use_gpu; ReleaseTreeResources();
// Replace existing tile manager with another one that uses appropriate // rasterizer.
if (tile_manager_) {
DestroyTileManager();
CreateAndSetTileManager();
共分享92篇相关文档