| 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
|
|
|