站在老罗的肩膀上:https://blog.csdn.net/luoshengyang/article/details/51216442
调用ProxyImpl::ScheduledActionCommit请求Compositor线程将刚刚绘制好的CC Layer Tree同步为CC Pending Layer Tree,如下所示:
void ProxyImpl::ScheduledActionCommit() {
...
host_impl_->BeginCommit();
blocked_main_commit().layer_tree_host->FinishCommitOnImplThread(
host_impl_.get());
...
if (commit_completion_waits_for_activation_) {
...
commit_completion_waits_for_activation_ = false;
activation_completion_event_ = commit_completion_event_;
} else {
commit_completion_event_->Signal();
}
commit_completion_event_ = nullptr;
scheduler_->DidCommit();
// Delay this step until afer the main thread has been released as it's
// often a good bit of work to update the tree and prepare the new frame.
host_impl_->CommitComplete();
SetInputThrottledUntilCommitOnImpl(false);
next_frame_is_newly_committed_frame_ = true;
}
首先调用这个LayerTreeHostImpl::BeginCommit创建一个空的CC Pending Layer Tree。
void LayerTreeHostImpl::BeginCommit() {
if (!CommitToActiveTree())
CreatePendingTree();
}
调用它的成员函数LayerTreeHost::FinishCommitOnImplThread将刚刚绘制好的CC Layer Tree同步到前面创建的CC Pending Layer Tree中去。
void LayerTreeHost::FinishCommitOnImplThread(
LayerTreeHostImpl* host_impl) {
LayerTreeImpl* sync_tree = host_impl->sync_tree();
...
if (needs_full_tree_sync_)
TreeSynchronizer::SynchronizeTrees(root_layer(), sync_tree);
..
{
PushPropertyTreesTo(sync_tree);
PushSurfaceRangesTo(sync_tree);
TreeSynchronizer::PushLayerProperties(this, sync_tree);
PushLayerTreePropertiesTo(sync_tree);
PushLayerTreeHostPropertiesTo(host_impl);
sync_tree->PassSwapPromises(swap_promise_manager_.TakeSwapPromises());
sync_tree->set_ui_resource_request_queue(
ui_resource_manager_->TakeUIResourcesRequests());
// This must happen after synchronizing property trees and after pushing
// properties, which updates the clobber_active_value flag.
// TODO(pdr): Enforce this comment with DCHECKS and a lifecycle state.
sync_tree->property_trees()->scroll_tree.PushScrollUpdatesFromMainThread(
property_trees(), sync_tree);
sync_tree->UpdatePropertyTreeAnimationFromMainThread();
..
mutator_host_->PushPropertiesTo(host_impl->mutator_host());
sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing);
}
// Transfer image decode requests to the impl thread.
for (auto& request : queued_image_decodes_) {
int next_id = s_image_decode_sequence_number.GetNext();
pending_image_decodes_[next_id] = std::move(request.second);
host_impl->QueueImageDecode(next_id, std::move(request.first));
}
queued_image_decodes_.clear();
micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
property_trees_.ResetAllChangeTracking();
}
判断成员变量needs_full_tree_sync_的值是否等于true。如果等于true,那么就说明CC Layer Tree的结构发生了变化,也就是增加了Layer,或者减少了Layer。在这种情况下,就需要将CC Layer Tree的结构同步到CC Pending Layer Tree中去。这是通过调用TreeSynchronizer::SynchronizeTrees实现的。
template <typename LayerTreeType>
void SynchronizeTreesInternal(LayerTreeType* source_tree,
LayerTreeImpl* tree_impl,
PropertyTrees* property_trees) {
/* using OwnedLayerImplList = std::vector<std::unique_ptr<LayerImpl>>; */
std::unique_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers());
OwnedLayerImplMap old_layer_map;
for (auto& it : *old_layers) {
old_layer_map[it->id()] = std::move(it);
}
PushLayerList(&old_layer_map, source_tree, tree_impl);
for (int id : property_trees->effect_tree.mask_layer_ids()) {
std::unique_ptr<LayerImpl> layer_impl(ReuseOrCreateLayerImpl(
&old_layer_map, source_tree->LayerById(id), tree_impl));
tree_impl->AddLayer(std::move(layer_impl));
}
}
template <typename LayerTreeType>
void PushLayerList(OwnedLayerImplMap* old_layers,
LayerTreeType* host,
LayerTreeImpl* tree_impl) {
tree_impl->ClearLayerList();
for (auto* layer : *host) {
std::unique_ptr<LayerImpl> layer_impl(
ReuseOrCreateLayerImpl(old_layers, layer, tree_impl));
tree_impl->AddToLayerList(layer_impl.get());
tree_impl->AddLayer(std::move(layer_impl));
}
tree_impl->OnCanDrawStateChangedForTree();
}
同步过程:host指向对象PictureLayer, 通过operator++遍历整个CC Layer Tree。
template <typename LayerType>
LayerListIterator<LayerType>& LayerListIterator<LayerType>::operator++() {
// case 0: done
if (!current_layer_)
return *this;
// case 1: descend.
if (!Children(current_layer_).empty()) {
current_layer_ = ChildAt(current_layer_, 0);
list_indices_.push_back(0);
return *this;
}
for (LayerType* parent = Parent(current_layer_); parent;
parent = Parent(parent)) {
// We now try and advance in some list of siblings.
// case 2: Advance to a sibling.
if (list_indices_.back() + 1 < Children(parent).size()) {
++list_indices_.back();
current_layer_ = ChildAt(parent, list_indices_.back());
return *this;
}
// We need to ascend. We will pop an index off the stack.
list_indices_.pop_back();
}
current_layer_ = nullptr;
return *this;
}
然后同步CC Layer Tree的PropertyTrees。
调用ThreadProxy类的成员函数blocked_main可以获得一个MainThreadOrBlockedMainThread对象。在Render进程启用了Impl Side Painting特性的情况下,当这个MainThreadOrBlockedMainThread对象的成员变量commit_waits_for_activation等于true时,表示CC Layer Tree中的某些Layer请求Compositor线程一直阻塞Main线程,直到前面创建的CC Pending Layer Tree完成光栅化并且激活为CC Active Layer Tree之后,再唤醒Main线程。这些Layer有一个特点,就是不需要Compositor线程为它们执行光栅化操作,例如Texture Layer,本身的内容就是已经光栅化好了的。
如果需要阻塞Main线程到CC Pending Layer Tree激活为CC Active Layer Tree之后,那么ThreadProxy类的成员函数ScheduledActionCommit就会将保存在前面获得的CompositorThreadOnly对象的成员变量commit_completion_event中的Completion Event转移到另外一个成员变量completion_event_for_commit_held_on_tree_acti