站在老罗的肩膀上:https://blog.csdn.net/luoshengyang/article/details/50941980
网页的Graphics Layer Tree是根据Paint Layer Tree创建的,而Graphics Layer Tree与CC模块创建的Layer Tree的节点是一一对应的关系,如图1所示:
图1 Graphics Layer Tree与CC Layer Tree的关系
也就是说,每一个Graphics Layer都对应有一个CC Layer。不过,Graphics Layer与CC Layer不是直接的一一对应的,它们是透过另外两个Layer才对应起来的,如图2所示:
图2 Graphics Layer与CC Layer的对应关系
中间的两个Layer分别是WebContentLayerImpl和WebLayerImpl,它们是属于Content层的对象。Graphics Layer与CC Layer的对应关系,是在Graphics Layer的创建过程中建立起来的,接下来我们就通过源码分析这种对应关系的建立过程。
GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client)
: client_(client),
... {
...
layer_ = cc::PictureLayer::Create(this);
layer_->SetIsDrawable(draws_content_ && contents_visible_);
layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr());
}
Graphics Layer通过GraphicsLayer::AddChild形成父子关系的(从而形成Graphics Layer Tree),如下所示:
void GraphicsLayer::AddChild(GraphicsLayer* child_layer) {
AddChildInternal(child_layer);
UpdateChildList();
}
首先调用成员函数AddChildInternal将参数childLayer描述的一个Graphics Layer作为当前正在处理的Graphics Layer的子Graphics Layer,如下所示:
void GraphicsLayer::AddChildInternal(GraphicsLayer* child_layer) {
...
if (child_layer->Parent())
child_layer->RemoveFromParent();
child_layer->SetParent(this);
children_.push_back(child_layer);
}
这一步执行完成后,Graphics Layer之间就建立了父子关系。回到GraphicsLayer类的成员函数AddChild中,它接下来还会调用另外一个成员函数UpdateChildList,用来在CC Layer之间建立父子关系,从而形CC Layer Tree。
void GraphicsLayer::UpdateChildList() {
// child_host point to PictureLayer
cc::Layer* child_host = layer_.get();
child_host->RemoveAllChildren();
...
for (size_t i = 0; i < children_.size(); ++i)
child_host->AddChild(children_[i]->CcLayer());
for (size_t i = 0; i < link_highlights_.size(); ++i)
child_host->AddChild(link_highlights_[i]->Layer());
}
其中child_host指向的是当前Graphics Layer对应的一个PictureLayer对象,并把它所有的Child Graphics Layer对应的PictureLayer调用AddChild添加到它的子节点,AddChild调用InsertChild实现如下
void Layer::AddChild(scoped_refptr<Layer> child) {
InsertChild(child, inputs_.children.size());
}
void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) {
DCHECK(IsPropertyChangeAllowed());
child->RemoveFromParent();
AddDrawableDescendants(child->NumDescendantsThatDrawContent() +
(child->DrawsContent() ? 1 : 0));
child->SetParent(this);
child->SetSubtreePropertyChanged();
index = std::min(index, inputs_.children.size());
inputs_.children.insert(inputs_.children.begin() + index, child);
SetNeedsFullTreeSync();
}
Layer类的成员函数InsertChild所做的第一件事情是将当前正在处理的Picture Layer设置为参数child描述的Pictrue Layer的父Picture Layer,并且将参数child描述的Pictrue Layer保存在当前正在处理的Picture Layer的子Picture Layer列表中。Layer类的成员函数InsertChild所做的第二件事情是调用另外一个成员函数SetNeedsFullTreeSync发出一个通知,要在CC Layer Tree与CC Pending Layer Tree之间做一个Tree结构同步。
Layer类的成员函数SetNeedsFullTreeSync的实现如下所示:
void Layer::SetNeeds