Update from https://crrev.com/308331

Fix ui/compositor/compositor.(h|cpp) based on http://crrev.com/738983002

Fix sky/engine based on current Blink code

R=qsr@chromium.org

Review URL: https://codereview.chromium.org/812543002
diff --git a/cc/resources/tiling_set_eviction_queue.cc b/cc/resources/tiling_set_eviction_queue.cc
index 8c5ff52..18f659e 100644
--- a/cc/resources/tiling_set_eviction_queue.cc
+++ b/cc/resources/tiling_set_eviction_queue.cc
@@ -2,38 +2,53 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <utility>
+
 #include "cc/resources/tiling_set_eviction_queue.h"
 
 namespace cc {
 
 TilingSetEvictionQueue::TilingSetEvictionQueue()
     : tiling_set_(nullptr),
+      tree_(ACTIVE_TREE),
       tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
-      current_category_(PictureLayerTiling::EVENTUALLY),
+      skip_all_shared_tiles_(false),
+      skip_shared_out_of_order_tiles_(false),
+      processing_soon_border_rect_(false),
+      processing_tiling_with_required_for_activation_tiles_(false),
+      tiling_index_with_required_for_activation_tiles_(0u),
+      current_priority_bin_(TilePriority::EVENTUALLY),
       current_tiling_index_(0u),
       current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
-      current_eviction_tile_(nullptr),
-      eviction_tiles_(nullptr),
-      next_eviction_tile_index_(0u) {
+      current_eviction_tile_(nullptr) {
 }
 
 TilingSetEvictionQueue::TilingSetEvictionQueue(
     PictureLayerTilingSet* tiling_set,
-    TreePriority tree_priority)
+    TreePriority tree_priority,
+    bool skip_shared_out_of_order_tiles)
     : tiling_set_(tiling_set),
+      tree_(tiling_set->client()->GetTree()),
       tree_priority_(tree_priority),
-      current_category_(PictureLayerTiling::EVENTUALLY),
+      skip_all_shared_tiles_(
+          skip_shared_out_of_order_tiles &&
+          tree_priority == (tree_ == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY
+                                                 : SMOOTHNESS_TAKES_PRIORITY)),
+      skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles),
+      processing_soon_border_rect_(false),
+      processing_tiling_with_required_for_activation_tiles_(false),
+      tiling_index_with_required_for_activation_tiles_(0u),
+      current_priority_bin_(TilePriority::EVENTUALLY),
       current_tiling_index_(0u),
       current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
-      current_eviction_tile_(nullptr),
-      eviction_tiles_(nullptr),
-      next_eviction_tile_index_(0u) {
-  DCHECK(tiling_set_);
-
+      current_eviction_tile_(nullptr) {
   // Early out if the layer has no tilings.
   if (!tiling_set_->num_tilings())
     return;
 
+  tiling_index_with_required_for_activation_tiles_ =
+      TilingIndexWithRequiredForActivationTiles();
+
   current_tiling_index_ = CurrentTilingRange().start - 1u;
   AdvanceToNextValidTiling();
 }
@@ -62,60 +77,132 @@
   return current_eviction_tile_;
 }
 
-bool TilingSetEvictionQueue::AdvanceToNextCategory() {
-  // Advance to the next category. This is done only after all tiling range
-  // types within the previous category have been gone through.
-  DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES);
-
-  switch (current_category_) {
-    case PictureLayerTiling::EVENTUALLY:
-      current_category_ =
-          PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION;
-      return true;
-    case PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
-      current_category_ = PictureLayerTiling::SOON;
-      return true;
-    case PictureLayerTiling::SOON:
-      current_category_ = PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION;
-      return true;
-    case PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION:
-      current_category_ = PictureLayerTiling::NOW;
-      return true;
-    case PictureLayerTiling::NOW:
-      current_category_ = PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION;
-      return true;
-    case PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION:
-      return false;
-  }
-  NOTREACHED();
-  return false;
-}
-
 bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() {
-  // Advance to the next eviction tile within the current category and tiling.
-  // This is done while advancing to a new tiling (in which case the next
-  // eviction tile index is 0) and while popping the current tile (in which
-  // case the next eviction tile index is greater than 0).
-  DCHECK_EQ(next_eviction_tile_index_ > 0, current_eviction_tile_ != nullptr);
+  // Advance to the next eviction tile within the current priority bin and
+  // tiling. This is done while advancing to a new tiling and while popping
+  // the current tile.
 
-  while (next_eviction_tile_index_ < eviction_tiles_->size()) {
-    Tile* tile = (*eviction_tiles_)[next_eviction_tile_index_];
-    ++next_eviction_tile_index_;
-    if (tile->HasResources()) {
+  bool required_for_activation =
+      processing_tiling_with_required_for_activation_tiles_;
+
+  for (;;) {
+    while (spiral_iterator_) {
+      std::pair<int, int> next_index = spiral_iterator_.index();
+      Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second);
+      ++spiral_iterator_;
+      if (!tile || !tile->HasResources())
+        continue;
+      if (skip_all_shared_tiles_ && tile->is_shared())
+        continue;
+      current_tiling_->UpdateTileAndTwinPriority(tile);
+      if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
+        continue;
+      if (tile->required_for_activation() != required_for_activation)
+        continue;
       current_eviction_tile_ = tile;
       return true;
     }
+    if (processing_soon_border_rect_) {
+      // Advance from soon border rect to skewport rect.
+      processing_soon_border_rect_ = false;
+      if (current_tiling_->has_skewport_rect_tiles_) {
+        spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
+            &current_tiling_->tiling_data_,
+            current_tiling_->current_skewport_rect_,
+            current_tiling_->current_visible_rect_,
+            current_tiling_->current_visible_rect_);
+        continue;
+      }
+    }
+    break;
+  }
+
+  TilePriority::PriorityBin max_tile_priority_bin =
+      current_tiling_->client_->GetMaxTilePriorityBin();
+  while (visible_iterator_) {
+    std::pair<int, int> next_index = visible_iterator_.index();
+    Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second);
+    ++visible_iterator_;
+    if (!tile || !tile->HasResources())
+      continue;
+    if (skip_all_shared_tiles_ && tile->is_shared())
+      continue;
+    // If the max tile priority is not NOW, updated priorities for tiles
+    // returned by the visible iterator will not have NOW (but EVENTUALLY)
+    // priority bin and cannot therefore be required for activation tiles nor
+    // occluded NOW tiles in the current tiling.
+    if (max_tile_priority_bin <= TilePriority::NOW) {
+      // If the current tiling is a pending tree tiling, required for
+      // activation tiles can be detected without updating tile priorities.
+      if (tree_ == PENDING_TREE &&
+          current_tiling_->IsTileRequiredForActivationIfVisible(tile) !=
+              required_for_activation) {
+        continue;
+      }
+      // Unoccluded NOW tiles should be evicted (and thus returned) only after
+      // all occluded NOW tiles.
+      if (!current_tiling_->IsTileOccluded(tile)) {
+        unoccluded_now_tiles_.push_back(tile);
+        continue;
+      }
+    }
+    current_tiling_->UpdateTileAndTwinPriority(tile);
+    if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
+      continue;
+    if (tile->required_for_activation() != required_for_activation)
+      continue;
+    current_eviction_tile_ = tile;
+    return true;
+  }
+
+  while (!unoccluded_now_tiles_.empty()) {
+    // All (unoccluded) NOW tiles have the same priority bin (NOW) and the same
+    // distance to visible (0.0), so it does not matter that tiles are popped
+    // in reversed (FILO) order.
+    Tile* tile = unoccluded_now_tiles_.back();
+    unoccluded_now_tiles_.pop_back();
+    DCHECK(tile);
+    if (!tile->HasResources())
+      continue;
+    current_tiling_->UpdateTileAndTwinPriority(tile);
+    if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
+      continue;
+    if (tile->required_for_activation() != required_for_activation)
+      continue;
+    current_eviction_tile_ = tile;
+    return true;
   }
 
   current_eviction_tile_ = nullptr;
   return false;
 }
 
+bool TilingSetEvictionQueue::AdvanceToNextPriorityBin() {
+  // Advance to the next priority bin. This is done only after all tiling range
+  // types (including the required for activation tiling) within the previous
+  // priority bin have been gone through.
+  DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES);
+
+  switch (current_priority_bin_) {
+    case TilePriority::EVENTUALLY:
+      current_priority_bin_ = TilePriority::SOON;
+      return true;
+    case TilePriority::SOON:
+      current_priority_bin_ = TilePriority::NOW;
+      return true;
+    case TilePriority::NOW:
+      return false;
+  }
+  NOTREACHED();
+  return false;
+}
+
 bool TilingSetEvictionQueue::AdvanceToNextTilingRangeType() {
-  // Advance to the next tiling range type within the current category or to
-  // the first tiling range type within the next category. This is done only
-  // after all tilings within the previous tiling range type have been gone
-  // through.
+  // Advance to the next tiling range type within the current priority bin, to
+  // the required for activation tiling range type within the current priority
+  // bin or to the first tiling range type within the next priority bin. This
+  // is done only after all tilings within the previous tiling range type have
+  // been gone through.
   DCHECK_EQ(current_tiling_index_, CurrentTilingRange().end);
 
   switch (current_tiling_range_type_) {
@@ -133,7 +220,15 @@
       current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
       return true;
     case PictureLayerTilingSet::HIGH_RES:
-      if (!AdvanceToNextCategory())
+      if (!processing_tiling_with_required_for_activation_tiles_ &&
+          tiling_index_with_required_for_activation_tiles_ <
+              tiling_set_->num_tilings()) {
+        processing_tiling_with_required_for_activation_tiles_ = true;
+        return true;
+      }
+      processing_tiling_with_required_for_activation_tiles_ = false;
+
+      if (!AdvanceToNextPriorityBin())
         return false;
 
       current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
@@ -145,10 +240,10 @@
 
 bool TilingSetEvictionQueue::AdvanceToNextValidTiling() {
   // Advance to the next tiling within current tiling range type or to
-  // the first tiling within the next tiling range type or category until
+  // the first tiling within the next tiling range type or priority bin until
   // the next eviction tile is found. This is done only after all eviction
-  // tiles within the previous tiling within the current category and tiling
-  // range type have been gone through.
+  // tiles within the previous tiling within the current priority bin and
+  // tiling range type have been gone through.
   DCHECK(!current_eviction_tile_);
   DCHECK_NE(current_tiling_index_, CurrentTilingRange().end);
 
@@ -159,18 +254,54 @@
         return false;
       current_tiling_index_ = CurrentTilingRange().start;
     }
+    current_tiling_ = tiling_set_->tiling_at(CurrentTilingIndex());
 
-    PictureLayerTiling* tiling = tiling_set_->tiling_at(CurrentTilingIndex());
-    eviction_tiles_ =
-        tiling->GetEvictionTiles(tree_priority_, current_category_);
-    next_eviction_tile_index_ = 0u;
-    if (AdvanceToNextEvictionTile())
-      return true;
+    switch (current_priority_bin_) {
+      case TilePriority::EVENTUALLY:
+        if (current_tiling_->has_eventually_rect_tiles_) {
+          spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
+              &current_tiling_->tiling_data_,
+              current_tiling_->current_eventually_rect_,
+              current_tiling_->current_skewport_rect_,
+              current_tiling_->current_soon_border_rect_);
+          if (AdvanceToNextEvictionTile())
+            return true;
+        }
+        break;
+      case TilePriority::SOON:
+        if (current_tiling_->has_skewport_rect_tiles_ ||
+            current_tiling_->has_soon_border_rect_tiles_) {
+          processing_soon_border_rect_ = true;
+          if (current_tiling_->has_soon_border_rect_tiles_)
+            spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
+                &current_tiling_->tiling_data_,
+                current_tiling_->current_soon_border_rect_,
+                current_tiling_->current_skewport_rect_,
+                current_tiling_->current_visible_rect_);
+          if (AdvanceToNextEvictionTile())
+            return true;
+        }
+        break;
+      case TilePriority::NOW:
+        if (current_tiling_->has_visible_rect_tiles_) {
+          visible_iterator_ =
+              TilingData::Iterator(&current_tiling_->tiling_data_,
+                                   current_tiling_->current_visible_rect_,
+                                   false /* include_borders */);
+          if (AdvanceToNextEvictionTile())
+            return true;
+        }
+        break;
+    }
   }
 }
 
 PictureLayerTilingSet::TilingRange
 TilingSetEvictionQueue::CurrentTilingRange() const {
+  if (processing_tiling_with_required_for_activation_tiles_)
+    return PictureLayerTilingSet::TilingRange(
+        tiling_index_with_required_for_activation_tiles_,
+        tiling_index_with_required_for_activation_tiles_ + 1);
   return tiling_set_->GetTilingRange(current_tiling_range_type_);
 }
 
@@ -194,4 +325,77 @@
   return 0;
 }
 
+bool TilingSetEvictionQueue::IsSharedOutOfOrderTile(const Tile* tile) const {
+  if (!tile->is_shared())
+    return false;
+
+  switch (tree_priority_) {
+    case SMOOTHNESS_TAKES_PRIORITY:
+      DCHECK_EQ(ACTIVE_TREE, tree_);
+      return false;
+    case NEW_CONTENT_TAKES_PRIORITY:
+      DCHECK_EQ(PENDING_TREE, tree_);
+      return false;
+    case SAME_PRIORITY_FOR_BOTH_TREES:
+      break;
+    case NUM_TREE_PRIORITIES:
+      NOTREACHED();
+      break;
+  }
+
+  // The priority for tile priority of a shared tile will be a combined
+  // priority thus return shared tiles from a higher priority tree as
+  // it is out of order for a lower priority tree.
+  WhichTree twin_tree = tree_ == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
+  const TilePriority& priority = tile->priority(tree_);
+  const TilePriority& twin_priority = tile->priority(twin_tree);
+  if (priority.priority_bin != twin_priority.priority_bin)
+    return priority.priority_bin > twin_priority.priority_bin;
+  const bool occluded = tile->is_occluded(tree_);
+  const bool twin_occluded = tile->is_occluded(twin_tree);
+  if (occluded != twin_occluded)
+    return occluded;
+  if (priority.distance_to_visible != twin_priority.distance_to_visible)
+    return priority.distance_to_visible > twin_priority.distance_to_visible;
+
+  // If priorities are the same, it does not matter which tree returns
+  // the tile. Let's pick the pending tree.
+  return tree_ != PENDING_TREE;
 }
+
+size_t TilingSetEvictionQueue::TilingIndexWithRequiredForActivationTiles()
+    const {
+  // Returns the tiling index of the tiling with requuired for activation tiles.
+  // If no such tiling exists, returns the past-the-last index (num_tilings).
+  size_t num_tilings = tiling_set_->num_tilings();
+
+  if (tree_ == PENDING_TREE) {
+    // For the pending tree, the tiling with required for activation tiles is
+    // the high res one.
+    PictureLayerTilingSet::TilingRange high_res_tiling_range =
+        tiling_set_->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
+    if (high_res_tiling_range.start != high_res_tiling_range.end)
+      return high_res_tiling_range.start;
+  } else {
+    DCHECK_EQ(ACTIVE_TREE, tree_);
+    // Only pending tree tiles can be required for activation. They can appear
+    // also in the active tree only if they are shared. If we skip all shared
+    // tiles, there is no need to find them as they will not be returned.
+    if (skip_all_shared_tiles_)
+      return num_tilings;
+
+    // For the active tree, the tiling with required for activation tiles is
+    // the one whose twin tiling is the high res pending tiling.
+    for (size_t i = 0; i < num_tilings; ++i) {
+      const PictureLayerTiling* tiling = tiling_set_->tiling_at(i);
+      const PictureLayerTiling* pending_tiling =
+          tiling_set_->client()->GetPendingOrActiveTwinTiling(tiling);
+      if (pending_tiling && pending_tiling->resolution() == HIGH_RESOLUTION)
+        return i;
+    }
+  }
+
+  return num_tilings;
+}
+
+}  // namespace cc