effect_tree_layer_list_iterator.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "cc/layers/effect_tree_layer_list_iterator.h"
  5. #include "base/notreached.h"
  6. namespace cc {
  7. EffectTreeLayerListIterator::EffectTreeLayerListIterator(
  8. LayerTreeImpl* layer_tree_impl)
  9. : state_(EffectTreeLayerListIterator::State::END),
  10. layer_list_iterator_(layer_tree_impl->rbegin()),
  11. current_effect_tree_index_(kInvalidPropertyNodeId),
  12. next_effect_tree_index_(kInvalidPropertyNodeId),
  13. lowest_common_effect_tree_ancestor_index_(kInvalidPropertyNodeId),
  14. layer_tree_impl_(layer_tree_impl),
  15. effect_tree_(&layer_tree_impl->property_trees()->effect_tree_mutable()) {
  16. // Find the front-most drawn layer.
  17. while (layer_list_iterator_ != layer_tree_impl->rend() &&
  18. !(*layer_list_iterator_)->contributes_to_drawn_render_surface()) {
  19. ++layer_list_iterator_;
  20. }
  21. // If there are no drawn layers, start at the root render surface, if it
  22. // exists.
  23. if (layer_list_iterator_ == layer_tree_impl->rend()) {
  24. DCHECK(effect_tree_->size() > kContentsRootPropertyNodeId);
  25. state_ = State::TARGET_SURFACE;
  26. current_effect_tree_index_ = kContentsRootPropertyNodeId;
  27. } else {
  28. state_ = State::LAYER;
  29. current_effect_tree_index_ =
  30. (*layer_list_iterator_)->render_target_effect_tree_index();
  31. next_effect_tree_index_ = current_effect_tree_index_;
  32. lowest_common_effect_tree_ancestor_index_ = current_effect_tree_index_;
  33. }
  34. }
  35. EffectTreeLayerListIterator::EffectTreeLayerListIterator(
  36. const EffectTreeLayerListIterator& iterator) = default;
  37. EffectTreeLayerListIterator::~EffectTreeLayerListIterator() = default;
  38. void EffectTreeLayerListIterator::operator++() {
  39. switch (state_) {
  40. case State::LAYER:
  41. // Find the next drawn layer.
  42. ++layer_list_iterator_;
  43. while (layer_list_iterator_ != layer_tree_impl_->rend() &&
  44. !(*layer_list_iterator_)->contributes_to_drawn_render_surface()) {
  45. ++layer_list_iterator_;
  46. }
  47. if (layer_list_iterator_ == layer_tree_impl_->rend()) {
  48. next_effect_tree_index_ = kInvalidPropertyNodeId;
  49. lowest_common_effect_tree_ancestor_index_ = kInvalidPropertyNodeId;
  50. state_ = State::TARGET_SURFACE;
  51. break;
  52. }
  53. next_effect_tree_index_ =
  54. (*layer_list_iterator_)->render_target_effect_tree_index();
  55. // If the next drawn layer has a different target effect tree index, check
  56. // for surfaces whose contributors have all been visited.
  57. if (next_effect_tree_index_ != current_effect_tree_index_) {
  58. lowest_common_effect_tree_ancestor_index_ =
  59. effect_tree_->LowestCommonAncestorWithRenderSurface(
  60. current_effect_tree_index_, next_effect_tree_index_);
  61. // If the current layer's target effect node is an ancestor of the next
  62. // layer's target effect node, then the current effect node still has
  63. // more contributors that need to be visited. Otherwise, all
  64. // contributors have been visited, so we visit the node's surface next.
  65. if (current_effect_tree_index_ ==
  66. lowest_common_effect_tree_ancestor_index_) {
  67. current_effect_tree_index_ = next_effect_tree_index_;
  68. lowest_common_effect_tree_ancestor_index_ = next_effect_tree_index_;
  69. } else {
  70. state_ = State::TARGET_SURFACE;
  71. }
  72. }
  73. break;
  74. case State::TARGET_SURFACE:
  75. if (current_effect_tree_index_ == kContentsRootPropertyNodeId) {
  76. current_effect_tree_index_ = kInvalidPropertyNodeId;
  77. state_ = State::END;
  78. DCHECK(next_effect_tree_index_ == kInvalidPropertyNodeId);
  79. DCHECK(layer_list_iterator_ == layer_tree_impl_->rend());
  80. } else {
  81. state_ = State::CONTRIBUTING_SURFACE;
  82. }
  83. break;
  84. case State::CONTRIBUTING_SURFACE:
  85. DCHECK(current_effect_tree_index_ !=
  86. lowest_common_effect_tree_ancestor_index_);
  87. // Step towards the lowest common ancestor.
  88. current_effect_tree_index_ =
  89. effect_tree_->Node(current_effect_tree_index_)->target_id;
  90. if (current_effect_tree_index_ == next_effect_tree_index_) {
  91. state_ = State::LAYER;
  92. } else if (current_effect_tree_index_ ==
  93. lowest_common_effect_tree_ancestor_index_) {
  94. // In this case, we know that more content contributes to the current
  95. // effect node (since the next effect node is a descendant), so we're
  96. // not yet ready to visit it as a target surface. The same holds for all
  97. // effect nodes on the path from the current node to the next effect
  98. // tree node.
  99. state_ = State::LAYER;
  100. current_effect_tree_index_ = next_effect_tree_index_;
  101. lowest_common_effect_tree_ancestor_index_ = next_effect_tree_index_;
  102. } else {
  103. // In this case, the lowest common ancestor is a proper ancestor of the
  104. // current effect node. This means that all contributors to the current
  105. // effect node have been visited, so we're ready to visit it as a target
  106. // surface.
  107. state_ = State::TARGET_SURFACE;
  108. }
  109. break;
  110. case State::END:
  111. NOTREACHED();
  112. }
  113. }
  114. } // namespace cc