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

Unified Diff: cc/base/tiling_data.cc

Issue 2067213002: cc: Implement tile iteration order based on pyramid sequence. [old] Base URL: https://chromium.googlesource.com/chromium/src.git@tiling_data_fix
Patch Set: for review Created 4 years, 5 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 9e34f2c098d760c2bcc5043dd653231c6c9d9d32..40a64208715ad81c373bc25f9decddc5efbf2b28 100644
--- a/cc/base/tiling_data.cc
+++ b/cc/base/tiling_data.cc
@@ -123,6 +123,21 @@ int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const {
return std::min(std::max(y, 0), num_tiles_y_ - 1);
}
+int TilingData::TileRealXIndexFromSrcCoord(int src_position) const {
+ if (src_position < 0)
+ src_position -= borderless_max_texture_size_.width();
+
+ return (src_position - border_texels_) / borderless_max_texture_size_.width();
+}
+
+int TilingData::TileRealYIndexFromSrcCoord(int src_position) const {
+ if (src_position < 0)
+ src_position -= borderless_max_texture_size_.height();
+
+ return (src_position - border_texels_) /
+ borderless_max_texture_size_.height();
+}
+
gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds(
const gfx::Rect& rect) const {
if (rect.IsEmpty() || has_empty_bounds())
@@ -476,176 +491,80 @@ 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());
-
- // 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());
-
- // 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);
+ if (tiling_data->max_texture_size().IsEmpty()) {
+ done();
+ return;
}
- // Determine around bottom, such that it is between -1 and num_tiles_y.
- int bottom_src_coord = center_rect.bottom() - 1;
+ // Default around rect is assumed to be at top-left corner of top-left
+ // tile index.
+ int around_left = -2;
+ int around_top = -2;
+ int around_right = 0;
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 (!center_rect.IsEmpty()) {
+ around_left = tiling_data->TileRealXIndexFromSrcCoord(center_rect.x()) - 1;
+ around_top = tiling_data->TileRealYIndexFromSrcCoord(center_rect.y()) - 1;
+ int right_src_coord = center_rect.right() - 1;
+ around_right = tiling_data->TileRealXIndexFromSrcCoord(right_src_coord) + 1;
+ int bottom_src_coord = center_rect.bottom() - 1;
+ around_bottom =
+ tiling_data->TileRealYIndexFromSrcCoord(bottom_src_coord) + 1;
}
- vertical_step_count_ = around_bottom - around_top + 1;
- horizontal_step_count_ = around_right - around_left + 1;
- current_step_ = horizontal_step_count_ - 1;
+ pyramid_sequence_.Init(around_left, around_right, around_top, around_bottom,
+ consider_left_, consider_right_, consider_top_,
+ consider_bottom_, ignore_left_, ignore_right_,
+ ignore_top_, ignore_bottom_,
+ tiling_data->max_texture_size().width(),
+ tiling_data->max_texture_size().height());
- index_x_ = around_right;
- index_y_ = around_bottom;
+ if (pyramid_sequence_.IsTraversed()) {
+ done();
+ return;
+ }
- // The current index is the bottom right of the around rect, which is also
- // ignored. So we have to advance.
- ++(*this);
+ index_x_ = pyramid_sequence_.GetCurrentIndexX();
+ index_y_ = pyramid_sequence_.GetCurrentIndexY();
+ DCHECK(in_consider_rect() && !in_ignore_rect());
}
-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 (in_consider_rect()) {
- cannot_hit_consider_count = 0;
-
- if (!in_ignore_rect())
- 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_top_;
- break;
- case LEFT:
- steps_to_edge = index_x_ - ignore_left_;
- break;
- case DOWN:
- steps_to_edge = ignore_bottom_ - index_y_;
- break;
- case RIGHT:
- steps_to_edge = ignore_right_ - index_x_;
- break;
- }
+TilingData::SpiralDifferenceIterator::~SpiralDifferenceIterator() {}
- // 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 (valid_column() && consider_bottom_ < index_y_)
- steps_to_take = index_y_ - consider_bottom_ - 1;
- can_hit_consider_rect |= consider_right_ >= index_x_;
- break;
- case LEFT:
- if (valid_row() && consider_right_ < index_x_)
- steps_to_take = index_x_ - consider_right_ - 1;
- can_hit_consider_rect |= consider_top_ <= index_y_;
- break;
- case DOWN:
- if (valid_column() && consider_top_ > index_y_)
- steps_to_take = consider_top_ - index_y_ - 1;
- can_hit_consider_rect |= consider_left_ <= index_x_;
- break;
- case RIGHT:
- if (valid_row() && consider_left_ > index_x_)
- steps_to_take = consider_left_ - index_x_ - 1;
- can_hit_consider_rect |= consider_bottom_ >= index_y_;
- break;
- }
- steps_to_take = std::min(steps_to_take, max_steps);
- DCHECK_GE(steps_to_take, 0);
+TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
+ const TilingData::SpiralDifferenceIterator& other) = default;
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
+TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
+ TilingData::SpiralDifferenceIterator&& other) = default;
- if (can_hit_consider_rect)
- cannot_hit_consider_count = 0;
- else
- ++cannot_hit_consider_count;
- }
- }
+TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
+operator=(const TilingData::SpiralDifferenceIterator& other) = default;
- if (cannot_hit_consider_count >= 4)
- done();
- return *this;
-}
+TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
+operator=(TilingData::SpiralDifferenceIterator&& other) = default;
-bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const {
- return current_step_ >= current_step_count();
-}
+TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
+operator++() {
+ pyramid_sequence_.Advance();
+ pyramid_sequence_.UpdateCurrent();
-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_;
+ if (pyramid_sequence_.IsTraversed()) {
+ done();
+ return *this;
+ }
- current_step_ = 0;
- direction_ = static_cast<Direction>((direction_ + 1) % 4);
+ index_x_ = pyramid_sequence_.GetCurrentIndexX();
+ index_y_ = pyramid_sequence_.GetCurrentIndexY();
- if (direction_ == RIGHT || direction_ == LEFT) {
- ++vertical_step_count_;
- ++horizontal_step_count_;
- }
+ DCHECK(in_consider_rect() && !in_ignore_rect());
+ return *this;
}
TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
@@ -657,211 +576,85 @@ 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_left_(-1),
- around_top_(-1),
- around_right_(-1),
- around_bottom_(-1),
- 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;
}
- // 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());
-
- // Determine around top, such that it is between -1 and num_tiles_y.
- 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());
-
- // Determine around right, such that it is between -1 and num_tiles_x.
- 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 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 (tiling_data->max_texture_size().IsEmpty()) {
+ done();
+ return;
}
- // Figure out the maximum distance from the around edge to consider edge.
- int max_distance = 0;
- max_distance = std::max(max_distance, around_top_ - consider_top_);
- max_distance = std::max(max_distance, around_left_ - consider_left_);
- max_distance = std::max(max_distance, consider_bottom_ - around_bottom_);
- max_distance = std::max(max_distance, consider_right_ - around_right_);
-
- // The step count is the length of the edge (around_right_ - around_left_ + 1)
- // 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_bottom_ - around_top_ + 1 + 2 * max_distance;
- horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance;
-
- // Start with one to the right of the padded around rect.
- index_x_ = around_right_ + max_distance + 1;
- index_y_ = around_bottom_ + max_distance;
-
- // The current index is outside a valid tile, so advance immediately.
- ++(*this);
-}
+ // Default around rect is assumed to be at top-left corner of top-left
+ // tile index.
+ int around_left = -2;
+ int around_top = -2;
+ int around_right = 0;
+ int around_bottom = 0;
-TilingData::ReverseSpiralDifferenceIterator&
- TilingData::ReverseSpiralDifferenceIterator::
- operator++() {
- while (!in_around_rect()) {
- if (needs_direction_switch())
- switch_direction();
-
- index_x_ += delta_x_;
- index_y_ += delta_y_;
- ++current_step_;
-
- if (in_around_rect()) {
- break;
- } else if (in_consider_rect()) {
- // If the tile is in the consider rect but not in ignore rect, then it's a
- // valid tile to visit.
- if (!in_ignore_rect())
- 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_top_;
- break;
- case LEFT:
- steps_to_edge = index_x_ - ignore_left_;
- break;
- case DOWN:
- steps_to_edge = ignore_bottom_ - index_y_;
- break;
- case RIGHT:
- steps_to_edge = ignore_right_ - index_x_;
- break;
- }
+ // TODO(prashant.n): Implement IndexRect for encapsulating indices. Implement
+ // function in TilingData for getting IndexRect from the given Rect object.
+ // crbug.com/624792
+ if (!center_rect.IsEmpty()) {
+ around_left = tiling_data->TileRealXIndexFromSrcCoord(center_rect.x()) - 1;
+ around_top = tiling_data->TileRealYIndexFromSrcCoord(center_rect.y()) - 1;
+ int right_src_coord = center_rect.right() - 1;
+ around_right = tiling_data->TileRealXIndexFromSrcCoord(right_src_coord) + 1;
+ int bottom_src_coord = center_rect.bottom() - 1;
+ around_bottom =
+ tiling_data->TileRealYIndexFromSrcCoord(bottom_src_coord) + 1;
+ }
- // 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 (valid_column() && consider_bottom_ < index_y_)
- steps_to_take = index_y_ - consider_bottom_ - 1;
- break;
- case LEFT:
- if (valid_row() && consider_right_ < index_x_)
- steps_to_take = index_x_ - consider_right_ - 1;
- break;
- case DOWN:
- if (valid_column() && consider_top_ > index_y_)
- steps_to_take = consider_top_ - index_y_ - 1;
- break;
- case RIGHT:
- if (valid_row() && consider_left_ > index_x_)
- steps_to_take = consider_left_ - index_x_ - 1;
- break;
- }
- steps_to_take = std::min(steps_to_take, max_steps);
- DCHECK_GE(steps_to_take, 0);
+ pyramid_sequence_.Init(around_left, around_right, around_top, around_bottom,
+ consider_left_, consider_right_, consider_top_,
+ consider_bottom_, ignore_left_, ignore_right_,
+ ignore_top_, ignore_bottom_,
+ tiling_data->max_texture_size().width(),
+ tiling_data->max_texture_size().height());
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
- }
+ if (pyramid_sequence_.IsTraversed()) {
+ done();
+ return;
}
- // Once we enter the around rect, we're done.
- if (in_around_rect())
- done();
- return *this;
+ index_x_ = pyramid_sequence_.GetCurrentIndexX();
+ index_y_ = pyramid_sequence_.GetCurrentIndexY();
+ DCHECK(in_consider_rect() && !in_ignore_rect());
}
-bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch()
- const {
- return current_step_ >= current_step_count();
-}
+TilingData::ReverseSpiralDifferenceIterator::
+ ~ReverseSpiralDifferenceIterator() {}
-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_;
+TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
+ const TilingData::ReverseSpiralDifferenceIterator& other) = default;
- current_step_ = 0;
- direction_ = static_cast<Direction>((direction_ + 1) % 4);
+TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
+ TilingData::ReverseSpiralDifferenceIterator&& other) = default;
- if (direction_ == UP || direction_ == DOWN) {
- --vertical_step_count_;
- --horizontal_step_count_;
+TilingData::ReverseSpiralDifferenceIterator&
+TilingData::ReverseSpiralDifferenceIterator::operator=(
+ const TilingData::ReverseSpiralDifferenceIterator& other) = default;
- // 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);
+TilingData::ReverseSpiralDifferenceIterator&
+TilingData::ReverseSpiralDifferenceIterator::operator=(
+ TilingData::ReverseSpiralDifferenceIterator&& other) = default;
+
+TilingData::ReverseSpiralDifferenceIterator&
+ TilingData::ReverseSpiralDifferenceIterator::operator++() {
+ pyramid_sequence_.Advance();
+ pyramid_sequence_.UpdateCurrent();
+
+ if (pyramid_sequence_.IsTraversed()) {
+ done();
+ return *this;
}
+
+ index_x_ = pyramid_sequence_.GetCurrentIndexX();
+ index_y_ = pyramid_sequence_.GetCurrentIndexY();
+ DCHECK(in_consider_rect() && !in_ignore_rect());
+ return *this;
}
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698