Layer Tree同步为Pending Layer Tree

站在老罗的肩膀上: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_activation中,以便在CC Pending Layer Tree

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值