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

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: tild Created 4 years, 6 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
« cc/base/tiling_data.h ('K') | « cc/base/tiling_data.h ('k') | cc/cc.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/base/tiling_data.cc
diff --git a/cc/base/tiling_data.cc b/cc/base/tiling_data.cc
index c1f1098c47c6248e864fb2287b04dcd41c3c4cc6..32a31630213a0dcd599272576810fa2a0a6b9071 100644
--- a/cc/base/tiling_data.cc
+++ b/cc/base/tiling_data.cc
@@ -467,6 +467,62 @@ TilingData::DifferenceIterator& TilingData::DifferenceIterator::operator++() {
return *this;
}
+TilingData::LDSequence::LDSequence(PyramidSequence traversal_seq,
+ PyramidSequence level_seq,
+ bool swapped,
+ int distance)
+ : traversal_seq_(traversal_seq), swapped_(swapped) {
+ LevelDistance level_distance;
+ level_distance.distance = 0;
+ int coverage = level_seq.GetCoverage();
+ for (int i = 0; i < coverage; ++i, level_distance.distance += distance) {
+ level_distance.level = level_seq.GetCurrent();
+ level_distances_.push_back(level_distance);
+ level_seq.Advance();
+ }
+
+ if (IsValid())
+ Reset();
+}
+
+TilingData::LDSequence::LDSequence(const TilingData::LDSequence& other) =
+ default;
+
+TilingData::LDSequence::~LDSequence() = default;
+
+int TilingData::LDSequence::GetIndexX() const {
+ return swapped_ ? current_level_index_ : current_seq_index_;
+}
+
+int TilingData::LDSequence::GetIndexY() const {
+ return swapped_ ? current_seq_index_ : current_level_index_;
+}
+
+int TilingData::LDSequence::GetTopDistance() {
+ DCHECK(level_distances_.size());
+ return level_distances_.front().distance;
+}
+
+bool TilingData::LDSequence::Advance() {
+ traversal_seq_.Advance();
+ if (!traversal_seq_.within_bounds()) {
+ level_distances_.erase(level_distances_.begin());
+ if (IsValid())
+ Reset();
+
+ return false;
+ }
+
+ current_seq_index_ = traversal_seq_.GetCurrent();
+ return true;
+}
+
+void TilingData::LDSequence::Reset() {
+ DCHECK(level_distances_.size());
+ current_seq_index_ = traversal_seq_.GetCurrent();
+ current_level_index_ = level_distances_.front().level;
+}
+
TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() {
done();
}
@@ -476,18 +532,14 @@ 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;
}
+ num_tiles_x_ = tiling_data->num_tiles_x();
+ num_tiles_y_ = tiling_data->num_tiles_y();
// 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())
@@ -528,124 +580,163 @@ TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
}
- vertical_step_count_ = around_bottom - around_top + 1;
- horizontal_step_count_ = around_right - around_left + 1;
- current_step_ = horizontal_step_count_ - 1;
+ int left_levels = around_left - consider_left_ + 1;
+ int right_levels = consider_right_ - around_right + 1;
+ int top_levels = around_top - consider_top_ + 1;
+ int bottom_levels = consider_bottom_ - around_bottom + 1;
+
+ int width = tiling_data->max_texture_size().width();
+ int height = tiling_data->max_texture_size().height();
+ int hypotenuse = std::sqrt(width * width + height * height); // support sp/dp
+
+ // U
+ int start = around_bottom - 1;
+ int end = around_top + 1;
+ if (right_levels > 0 && valid_row(start) && valid_row(end)) {
+ ld_sequences_.push_back(TilingData::LDSequence(
+ PyramidSequence(PyramidSequence::Type::BACKWARD, start, end,
+ right_levels),
+ PyramidSequence(PyramidSequence::Type::FORWARD, around_right,
+ consider_right_, 1),
+ true, width));
+ }
- index_x_ = around_right;
- index_y_ = around_bottom;
+ // UL
vmpstr 2016/06/16 18:28:58 Expand comments please.
+ if (right_levels > 0 && top_levels > 0 && valid_column(around_right)) {
+ ld_sequences_.push_back(TilingData::LDSequence(
+ PyramidSequence(PyramidSequence::Type::DIAGONAL_FORWARD, around_right,
+ around_right, std::min(right_levels, top_levels)),
+ PyramidSequence(PyramidSequence::Type::BACKWARD, around_top,
+ consider_top_, 1),
+ false, hypotenuse));
+ }
- // The current index is the bottom right of the around rect, which is also
- // ignored. So we have to advance.
- ++(*this);
-}
+ // L
+ start = around_right - 1;
+ end = around_left + 1;
+ if (top_levels > 0 && valid_column(start) && valid_column(end)) {
+ ld_sequences_.push_back(
+ TilingData::LDSequence(PyramidSequence(PyramidSequence::Type::BACKWARD,
+ start, end, top_levels),
+ PyramidSequence(PyramidSequence::Type::BACKWARD,
+ around_top, consider_top_, 1),
+ false, height));
+ }
-TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
-operator++() {
- int cannot_hit_consider_count = 0;
- while (cannot_hit_consider_count < 4) {
- if (needs_direction_switch())
- switch_direction();
+ // LD
+ if (top_levels > 0 && left_levels > 0 && valid_column(around_left)) {
+ ld_sequences_.push_back(TilingData::LDSequence(
+ PyramidSequence(PyramidSequence::Type::DIAGONAL_BACKWARD, around_left,
+ around_left, std::min(top_levels, left_levels)),
+ PyramidSequence(PyramidSequence::Type::BACKWARD, around_top,
+ consider_top_, 1),
+ false, hypotenuse));
+ }
- index_x_ += delta_x_;
- index_y_ += delta_y_;
- ++current_step_;
+ // D
+ start = around_top + 1;
+ end = around_bottom - 1;
+ if (left_levels > 0 && valid_row(start) && valid_row(end)) {
+ ld_sequences_.push_back(
+ TilingData::LDSequence(PyramidSequence(PyramidSequence::Type::FORWARD,
+ start, end, left_levels),
+ PyramidSequence(PyramidSequence::Type::BACKWARD,
+ around_left, consider_left_, 1),
+ true, width));
+ }
- if (in_consider_rect()) {
- cannot_hit_consider_count = 0;
+ // DR
+ if (left_levels > 0 && bottom_levels > 0 && valid_column(around_left)) {
+ ld_sequences_.push_back(TilingData::LDSequence(
+ PyramidSequence(PyramidSequence::Type::DIAGONAL_BACKWARD, around_left,
+ around_left, std::min(left_levels, bottom_levels)),
+ PyramidSequence(PyramidSequence::Type::FORWARD, around_bottom,
+ consider_bottom_, 1),
+ false, hypotenuse));
+ }
- if (!in_ignore_rect())
- break;
+ // R
+ start = around_left + 1;
+ end = around_right - 1;
+ if (bottom_levels > 0 && valid_column(start) && valid_column(end)) {
+ ld_sequences_.push_back(TilingData::LDSequence(
+ PyramidSequence(PyramidSequence::Type::FORWARD, start, end,
+ bottom_levels),
+ PyramidSequence(PyramidSequence::Type::FORWARD, around_bottom,
+ consider_bottom_, 1),
+ false, height));
+ }
- // 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;
- }
+ // RU
+ if (bottom_levels > 0 && right_levels > 0 && valid_column(around_right)) {
+ ld_sequences_.push_back(TilingData::LDSequence(
+ PyramidSequence(PyramidSequence::Type::DIAGONAL_FORWARD, around_right,
+ around_right, std::min(bottom_levels, right_levels)),
+ PyramidSequence(PyramidSequence::Type::FORWARD, around_bottom,
+ consider_bottom_, 1),
+ false, hypotenuse));
+ }
- // We need to switch directions in |max_steps|.
- int max_steps = current_step_count() - current_step_;
+ // Point to valid ld sequence.
+ current_ld_seq = GetNextLDSequence();
- int steps_to_take = std::min(steps_to_edge, max_steps);
- DCHECK_GE(steps_to_take, 0);
+ if (current_ld_seq == ld_sequences_.end()) {
+ done();
+ return;
+ }
- 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);
+ // Point to valid indices or finish.
+ ++(*this);
+}
- index_x_ += steps_to_take * delta_x_;
- index_y_ += steps_to_take * delta_y_;
- current_step_ += steps_to_take;
+TilingData::SpiralDifferenceIterator::~SpiralDifferenceIterator() = default;
- if (can_hit_consider_rect)
- cannot_hit_consider_count = 0;
- else
- ++cannot_hit_consider_count;
+TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
+operator++() {
+ while (true) {
+ if (current_ld_seq == ld_sequences_.end()) {
+ done();
+ break; // Finished.
}
- }
- if (cannot_hit_consider_count >= 4)
- done();
+ DCHECK(current_ld_seq->IsValid());
+ index_x_ = current_ld_seq->GetIndexX();
+ index_y_ = current_ld_seq->GetIndexY();
+
+ if (in_consider_rect() && !in_ignore_rect())
+ break; // Got it.
+
+ if (!current_ld_seq->Advance())
+ current_ld_seq = GetNextLDSequence();
+ }
return *this;
}
-bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const {
- return current_step_ >= current_step_count();
-}
+TilingData::LDSequence::List::iterator
+TilingData::SpiralDifferenceIterator::GetNextLDSequence() {
+ ld_sequences_.erase(std::remove_if(ld_sequences_.begin(), ld_sequences_.end(),
+ [](const TilingData::LDSequence& path) {
+ return !path.IsValid();
+ }),
+ ld_sequences_.end());
-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 (!ld_sequences_.size())
+ return ld_sequences_.end();
- current_step_ = 0;
- direction_ = static_cast<Direction>((direction_ + 1) % 4);
+ TilingData::LDSequence::List::iterator min_distance_ld_seq_it =
+ ld_sequences_.begin();
+
+ for (TilingData::LDSequence::List::iterator it = ld_sequences_.begin();
+ it != ld_sequences_.end(); ++it) {
+ int distance = it->GetTopDistance();
+ if (distance == 0)
+ return it;
- if (direction_ == RIGHT || direction_ == LEFT) {
- ++vertical_step_count_;
- ++horizontal_step_count_;
+ if (min_distance_ld_seq_it->GetTopDistance() > distance)
+ min_distance_ld_seq_it = it;
}
+
+ return min_distance_ld_seq_it;
}
TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
« cc/base/tiling_data.h ('K') | « cc/base/tiling_data.h ('k') | cc/cc.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698