Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4318)

Unified Diff: cc/resources/tiling_set_eviction_queue.cc

Issue 736753002: cc: Implement geometry-based tile eviction (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/resources/tiling_set_eviction_queue.cc
diff --git a/cc/resources/tiling_set_eviction_queue.cc b/cc/resources/tiling_set_eviction_queue.cc
index 8c5ff52f127099626c584429508b404d4ffce5e1..18f659ed53719e85778ff251d620949d8dcdc07c 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 @@ const Tile* TilingSetEvictionQueue::Top() const {
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);
+bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() {
+ // 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.
- 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 required_for_activation =
+ processing_tiling_with_required_for_activation_tiles_;
-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);
-
- while (next_eviction_tile_index_ < eviction_tiles_->size()) {
- Tile* tile = (*eviction_tiles_)[next_eviction_tile_index_];
- ++next_eviction_tile_index_;
- if (tile->HasResources()) {
+ 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 @@ bool TilingSetEvictionQueue::AdvanceToNextTilingRangeType() {
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::AdvanceToNextTilingRangeType() {
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 @@ bool TilingSetEvictionQueue::AdvanceToNextValidTiling() {
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 @@ size_t TilingSetEvictionQueue::CurrentTilingIndex() const {
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_);
vmpstr 2014/12/11 18:35:03 I know we can do this because of skip_all_shared_t
+ 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
« cc/resources/tiling_set_eviction_queue.h ('K') | « cc/resources/tiling_set_eviction_queue.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698