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

Unified Diff: cc/base/tiling_data.cc

Issue 2352393002: cc: Detach spiral iterator implementation to separate file. (Closed)
Patch Set: review comments Created 4 years, 3 months 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/base/tiling_data.cc
diff --git a/cc/base/tiling_data.cc b/cc/base/tiling_data.cc
index d328dfdd3f0fe30398ef33cded94effba5252976..98397e55ccfbb918b117e8c260ce088da6eabb9e 100644
--- a/cc/base/tiling_data.cc
+++ b/cc/base/tiling_data.cc
@@ -131,6 +131,50 @@ int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const {
return std::min(std::max(y, 0), num_tiles_y_ - 1);
}
+IndexRect TilingData::TileAroundIndexRect(const gfx::Rect& center_rect) const {
+ int around_left = 0;
+ // Determine around left, such that it is between -1 and num_tiles_x.
+ if (center_rect.x() < 0 || center_rect.IsEmpty())
+ around_left = -1;
+ else if (center_rect.x() >= tiling_size().width())
+ around_left = num_tiles_x();
+ else
+ around_left = TileXIndexFromSrcCoord(center_rect.x());
+
+ // Determine around top, such that it is between -1 and num_tiles_y.
+ int around_top = 0;
+ if (center_rect.y() < 0 || center_rect.IsEmpty())
+ around_top = -1;
+ else if (center_rect.y() >= tiling_size().height())
+ around_top = num_tiles_y();
+ else
+ around_top = TileYIndexFromSrcCoord(center_rect.y());
+
+ // Determine around right, such that it is between -1 and num_tiles_x.
+ int around_right = 0;
+ int right_src_coord = center_rect.right() - 1;
+ if (right_src_coord < 0 || center_rect.IsEmpty()) {
+ around_right = -1;
+ } else if (right_src_coord >= tiling_size().width()) {
+ around_right = num_tiles_x();
+ } else {
+ around_right = TileXIndexFromSrcCoord(right_src_coord);
+ }
+
+ // Determine around bottom, such that it is between -1 and num_tiles_y.
+ int around_bottom = 0;
+ int bottom_src_coord = center_rect.bottom() - 1;
+ if (bottom_src_coord < 0 || center_rect.IsEmpty()) {
+ around_bottom = -1;
+ } else if (bottom_src_coord >= tiling_size().height()) {
+ around_bottom = num_tiles_y();
+ } else {
+ around_bottom = TileYIndexFromSrcCoord(bottom_src_coord);
+ }
+
+ return IndexRect(around_left, around_right, around_top, around_bottom);
+}
+
gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds(
const gfx::Rect& rect) const {
if (rect.IsEmpty() || has_empty_bounds())
@@ -485,184 +529,43 @@ TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
const gfx::Rect& consider_rect,
const gfx::Rect& ignore_rect,
const gfx::Rect& center_rect)
- : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect),
- direction_(RIGHT),
- delta_x_(1),
- delta_y_(0),
- current_step_(0),
- horizontal_step_count_(0),
- vertical_step_count_(0) {
+ : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
if (!HasConsiderRect()) {
done();
return;
}
- // Determine around left, such that it is between -1 and num_tiles_x.
- int around_left = 0;
- if (center_rect.x() < 0 || center_rect.IsEmpty())
- around_left = -1;
- else if (center_rect.x() >= tiling_data->tiling_size().width())
- around_left = tiling_data->num_tiles_x();
- else
- around_left = tiling_data->TileXIndexFromSrcCoord(center_rect.x());
+ IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect);
+ DCHECK(around_index_rect.is_valid());
- // Determine around top, such that it is between -1 and num_tiles_y.
- int around_top = 0;
- if (center_rect.y() < 0 || center_rect.IsEmpty())
- around_top = -1;
- else if (center_rect.y() >= tiling_data->tiling_size().height())
- around_top = tiling_data->num_tiles_y();
- else
- around_top = tiling_data->TileYIndexFromSrcCoord(center_rect.y());
+ spiral_iterator_ = SpiralIterator(around_index_rect, consider_index_rect_,
+ ignore_index_rect_);
- // Determine around right, such that it is between -1 and num_tiles_x.
- int right_src_coord = center_rect.right() - 1;
- int around_right = 0;
- if (right_src_coord < 0 || center_rect.IsEmpty()) {
- around_right = -1;
- } else if (right_src_coord >= tiling_data->tiling_size().width()) {
- around_right = tiling_data->num_tiles_x();
- } else {
- around_right = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
- }
-
- // Determine around bottom, such that it is between -1 and num_tiles_y.
- int bottom_src_coord = center_rect.bottom() - 1;
- int around_bottom = 0;
- if (bottom_src_coord < 0 || center_rect.IsEmpty()) {
- around_bottom = -1;
- } else if (bottom_src_coord >= tiling_data->tiling_size().height()) {
- around_bottom = tiling_data->num_tiles_y();
- } else {
- around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
+ if (!spiral_iterator_) {
+ done();
+ return;
}
- vertical_step_count_ = around_bottom - around_top + 1;
- horizontal_step_count_ = around_right - around_left + 1;
- current_step_ = horizontal_step_count_ - 1;
-
- index_x_ = around_right;
- index_y_ = around_bottom;
-
- // The current index is the bottom right of the around rect, which is also
- // ignored. So we have to advance.
- ++(*this);
+ index_x_ = spiral_iterator_.index_x();
+ index_y_ = spiral_iterator_.index_y();
}
TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
operator++() {
- int cannot_hit_consider_count = 0;
- while (cannot_hit_consider_count < 4) {
- if (needs_direction_switch())
- switch_direction();
-
- index_x_ += delta_x_;
- index_y_ += delta_y_;
- ++current_step_;
-
- if (consider_index_rect_.Contains(index_x_, index_y_)) {
- cannot_hit_consider_count = 0;
-
- if (!ignore_index_rect_.Contains(index_x_, index_y_))
- break;
-
- // Steps needed to reach the very edge of the ignore rect, while remaining
- // inside (so that the continue would take us outside).
- int steps_to_edge = 0;
- switch (direction_) {
- case UP:
- steps_to_edge = index_y_ - ignore_index_rect_.top();
- break;
- case LEFT:
- steps_to_edge = index_x_ - ignore_index_rect_.left();
- break;
- case DOWN:
- steps_to_edge = ignore_index_rect_.bottom() - index_y_;
- break;
- case RIGHT:
- steps_to_edge = ignore_index_rect_.right() - index_x_;
- break;
- }
-
- // We need to switch directions in |max_steps|.
- int max_steps = current_step_count() - current_step_;
-
- int steps_to_take = std::min(steps_to_edge, max_steps);
- DCHECK_GE(steps_to_take, 0);
-
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
- } else {
- int max_steps = current_step_count() - current_step_;
- int steps_to_take = max_steps;
- bool can_hit_consider_rect = false;
- switch (direction_) {
- case UP:
- if (consider_index_rect_.valid_column(index_x_) &&
- consider_index_rect_.bottom() < index_y_)
- steps_to_take = index_y_ - consider_index_rect_.bottom() - 1;
- can_hit_consider_rect |= consider_index_rect_.right() >= index_x_;
- break;
- case LEFT:
- if (consider_index_rect_.valid_row(index_y_) &&
- consider_index_rect_.right() < index_x_)
- steps_to_take = index_x_ - consider_index_rect_.right() - 1;
- can_hit_consider_rect |= consider_index_rect_.top() <= index_y_;
- break;
- case DOWN:
- if (consider_index_rect_.valid_column(index_x_) &&
- consider_index_rect_.top() > index_y_)
- steps_to_take = consider_index_rect_.top() - index_y_ - 1;
- can_hit_consider_rect |= consider_index_rect_.left() <= index_x_;
- break;
- case RIGHT:
- if (consider_index_rect_.valid_row(index_y_) &&
- consider_index_rect_.left() > index_x_)
- steps_to_take = consider_index_rect_.left() - index_x_ - 1;
- can_hit_consider_rect |= consider_index_rect_.bottom() >= index_y_;
- break;
- }
- steps_to_take = std::min(steps_to_take, max_steps);
- DCHECK_GE(steps_to_take, 0);
-
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
+ ++spiral_iterator_;
- if (can_hit_consider_rect)
- cannot_hit_consider_count = 0;
- else
- ++cannot_hit_consider_count;
- }
- }
-
- if (cannot_hit_consider_count >= 4)
+ if (!spiral_iterator_) {
done();
- return *this;
-}
-
-bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const {
- return current_step_ >= current_step_count();
-}
-
-void TilingData::SpiralDifferenceIterator::switch_direction() {
- // Note that delta_x_ and delta_y_ always remain between -1 and 1.
- int new_delta_x_ = delta_y_;
- delta_y_ = -delta_x_;
- delta_x_ = new_delta_x_;
+ return *this;
+ }
- current_step_ = 0;
- direction_ = static_cast<Direction>((direction_ + 1) % 4);
+ index_x_ = spiral_iterator_.index_x();
+ index_y_ = spiral_iterator_.index_y();
- if (direction_ == RIGHT || direction_ == LEFT) {
- ++vertical_step_count_;
- ++horizontal_step_count_;
- }
+ return *this;
}
-TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator()
- : around_index_rect_(kNonPositiveQuadrantIndexRect) {
+TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
done();
}
@@ -671,225 +574,41 @@ TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
const gfx::Rect& consider_rect,
const gfx::Rect& ignore_rect,
const gfx::Rect& center_rect)
- : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect),
- around_index_rect_(kNonPositiveQuadrantIndexRect),
- direction_(LEFT),
- delta_x_(-1),
- delta_y_(0),
- current_step_(0),
- horizontal_step_count_(0),
- vertical_step_count_(0) {
+ : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
if (!HasConsiderRect()) {
done();
return;
}
- int around_left = 0;
- // Determine around left, such that it is between -1 and num_tiles_x.
- if (center_rect.x() < 0 || center_rect.IsEmpty())
- around_left = -1;
- else if (center_rect.x() >= tiling_data->tiling_size().width())
- around_left = tiling_data->num_tiles_x();
- else
- around_left = tiling_data->TileXIndexFromSrcCoord(center_rect.x());
+ IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect);
+ DCHECK(around_index_rect.is_valid());
- // Determine around top, such that it is between -1 and num_tiles_y.
- int around_top = 0;
- if (center_rect.y() < 0 || center_rect.IsEmpty())
- around_top = -1;
- else if (center_rect.y() >= tiling_data->tiling_size().height())
- around_top = tiling_data->num_tiles_y();
- else
- around_top = tiling_data->TileYIndexFromSrcCoord(center_rect.y());
+ reverse_spiral_iterator_ = ReverseSpiralIterator(
+ around_index_rect, consider_index_rect_, ignore_index_rect_);
- // Determine around right, such that it is between -1 and num_tiles_x.
- int around_right = 0;
- int right_src_coord = center_rect.right() - 1;
- if (right_src_coord < 0 || center_rect.IsEmpty()) {
- around_right = -1;
- } else if (right_src_coord >= tiling_data->tiling_size().width()) {
- around_right = tiling_data->num_tiles_x();
- } else {
- around_right = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
- }
-
- // Determine around bottom, such that it is between -1 and num_tiles_y.
- int around_bottom = 0;
- int bottom_src_coord = center_rect.bottom() - 1;
- if (bottom_src_coord < 0 || center_rect.IsEmpty()) {
- around_bottom = -1;
- } else if (bottom_src_coord >= tiling_data->tiling_size().height()) {
- around_bottom = tiling_data->num_tiles_y();
- } else {
- around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
+ if (!reverse_spiral_iterator_) {
+ done();
+ return;
}
- around_index_rect_ =
- IndexRect(around_left, around_right, around_top, around_bottom);
- DCHECK(around_index_rect_.is_valid());
-
- // Figure out the maximum distance from the around edge to consider edge.
- int max_distance = 0;
- max_distance = std::max(
- max_distance, around_index_rect_.top() - consider_index_rect_.top());
- max_distance = std::max(
- max_distance, around_index_rect_.left() - consider_index_rect_.left());
- max_distance = std::max(max_distance, consider_index_rect_.bottom() -
- around_index_rect_.bottom());
- max_distance = std::max(
- max_distance, consider_index_rect_.right() - around_index_rect_.right());
-
- // The step count is the length of the edge
- // (around_index_rect_.num_indices_x()) plus twice the max distance to pad
- // (to the right and to the left). This way the initial rect is the size
- // proportional to the center, but big enough to cover the consider rect.
- //
- // C = consider rect
- // A = around rect
- // . = area of the padded around rect
- // md = max distance (note in the picture below, there's md written vertically
- // as well).
- // I = initial starting position
- //
- // |md| |md|
- //
- // - ..........
- // m ..........
- // d ..........
- // - CCCCCCC...
- // CCCCAAC...
- // CCCCAAC...
- // - ..........
- // m ..........
- // d ..........
- // - ..........I
- vertical_step_count_ = around_index_rect_.num_indices_y() + 2 * max_distance;
- horizontal_step_count_ =
- around_index_rect_.num_indices_x() + 2 * max_distance;
-
- // Start with one to the right of the padded around rect.
- index_x_ = around_index_rect_.right() + max_distance + 1;
- index_y_ = around_index_rect_.bottom() + max_distance;
-
- // The current index is outside a valid tile, so advance immediately.
- ++(*this);
+ index_x_ = reverse_spiral_iterator_.index_x();
+ index_y_ = reverse_spiral_iterator_.index_y();
}
TilingData::ReverseSpiralDifferenceIterator&
TilingData::ReverseSpiralDifferenceIterator::
operator++() {
- while (!around_index_rect_.Contains(index_x_, index_y_)) {
- if (needs_direction_switch())
- switch_direction();
-
- index_x_ += delta_x_;
- index_y_ += delta_y_;
- ++current_step_;
-
- if (around_index_rect_.Contains(index_x_, index_y_)) {
- break;
- } else if (consider_index_rect_.Contains(index_x_, index_y_)) {
- // If the tile is in the consider rect but not in ignore rect, then it's a
- // valid tile to visit.
- if (!ignore_index_rect_.Contains(index_x_, index_y_))
- break;
-
- // Steps needed to reach the very edge of the ignore rect, while remaining
- // inside it (so that the continue would take us outside).
- int steps_to_edge = 0;
- switch (direction_) {
- case UP:
- steps_to_edge = index_y_ - ignore_index_rect_.top();
- break;
- case LEFT:
- steps_to_edge = index_x_ - ignore_index_rect_.left();
- break;
- case DOWN:
- steps_to_edge = ignore_index_rect_.bottom() - index_y_;
- break;
- case RIGHT:
- steps_to_edge = ignore_index_rect_.right() - index_x_;
- break;
- }
+ ++reverse_spiral_iterator_;
- // We need to switch directions in |max_steps|.
- int max_steps = current_step_count() - current_step_;
-
- int steps_to_take = std::min(steps_to_edge, max_steps);
- DCHECK_GE(steps_to_take, 0);
-
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
- } else {
- // We're not in the consider rect.
-
- int max_steps = current_step_count() - current_step_;
- int steps_to_take = max_steps;
-
- // We might hit the consider rect before needing to switch directions:
- // update steps to take.
- switch (direction_) {
- case UP:
- if (consider_index_rect_.valid_column(index_x_) &&
- consider_index_rect_.bottom() < index_y_)
- steps_to_take = index_y_ - consider_index_rect_.bottom() - 1;
- break;
- case LEFT:
- if (consider_index_rect_.valid_row(index_y_) &&
- consider_index_rect_.right() < index_x_)
- steps_to_take = index_x_ - consider_index_rect_.right() - 1;
- break;
- case DOWN:
- if (consider_index_rect_.valid_column(index_x_) &&
- consider_index_rect_.top() > index_y_)
- steps_to_take = consider_index_rect_.top() - index_y_ - 1;
- break;
- case RIGHT:
- if (consider_index_rect_.valid_row(index_y_) &&
- consider_index_rect_.left() > index_x_)
- steps_to_take = consider_index_rect_.left() - index_x_ - 1;
- break;
- }
- steps_to_take = std::min(steps_to_take, max_steps);
- DCHECK_GE(steps_to_take, 0);
-
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
- }
- }
-
- // Once we enter the around rect, we're done.
- if (around_index_rect_.Contains(index_x_, index_y_))
+ if (!reverse_spiral_iterator_) {
done();
- return *this;
-}
-
-bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch()
- const {
- return current_step_ >= current_step_count();
-}
-
-void TilingData::ReverseSpiralDifferenceIterator::switch_direction() {
- // Note that delta_x_ and delta_y_ always remain between -1 and 1.
- int new_delta_y_ = delta_x_;
- delta_x_ = -delta_y_;
- delta_y_ = new_delta_y_;
-
- current_step_ = 0;
- direction_ = static_cast<Direction>((direction_ + 1) % 4);
+ return *this;
+ }
- if (direction_ == UP || direction_ == DOWN) {
- --vertical_step_count_;
- --horizontal_step_count_;
+ index_x_ = reverse_spiral_iterator_.index_x();
+ index_y_ = reverse_spiral_iterator_.index_y();
- // We should always end up in an around rect at some point.
- // Since the direction is now vertical, we have to ensure that we will
- // advance.
- DCHECK_GE(horizontal_step_count_, 1);
- DCHECK_GE(vertical_step_count_, 1);
- }
+ return *this;
}
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698