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

Side by Side 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: spiral coverage sequence Created 4 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2010 The Chromium Authors. All rights reserved. 1 // Copyright 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/base/tiling_data.h" 5 #include "cc/base/tiling_data.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ui/gfx/geometry/rect.h" 9 #include "ui/gfx/geometry/rect.h"
10 #include "ui/gfx/geometry/vector2d.h" 10 #include "ui/gfx/geometry/vector2d.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const { 119 int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const {
120 if (num_tiles_y_ <= 1) 120 if (num_tiles_y_ <= 1)
121 return 0; 121 return 0;
122 122
123 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); 123 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0);
124 int inner_tile_size = max_texture_size_.height() - 2 * border_texels_; 124 int inner_tile_size = max_texture_size_.height() - 2 * border_texels_;
125 int y = src_position / inner_tile_size; 125 int y = src_position / inner_tile_size;
126 return std::min(std::max(y, 0), num_tiles_y_ - 1); 126 return std::min(std::max(y, 0), num_tiles_y_ - 1);
127 } 127 }
128 128
129 int TilingData::TileVirtualXIndexFromSrcCoord(int src_position) const {
130 int inner_tile_width = max_texture_size_.width() - 2 * border_texels_;
131 if (src_position < 0)
132 src_position -= inner_tile_width;
133
134 return (src_position - border_texels_) / inner_tile_width;
135 }
136
137 int TilingData::TileVirtualYIndexFromSrcCoord(int src_position) const {
138 int inner_tile_height = max_texture_size_.height() - 2 * border_texels_;
139 if (src_position < 0)
140 src_position -= inner_tile_height;
141
142 return (src_position - border_texels_) / inner_tile_height;
143 }
144
145 // TODO(prashant.n): Implement IndexRect for encapsulating indices.
146 // crbug.com/624792
147 void TilingData::TileVirtualAroundIndices(const gfx::Rect& center_rect,
148 int* around_left,
149 int* around_right,
150 int* around_top,
151 int* around_bottom) const {
152 if (center_rect.IsEmpty()) {
153 // Default around rect is assumed to be at top-left corner of tile at
154 // (0, 0).
155 *around_left = -2;
156 *around_top = -2;
157 *around_right = 0;
158 *around_bottom = 0;
159 return;
160 }
161
162 gfx::Rect tiling_rect(tiling_size());
163
164 *around_left = TileVirtualXIndexFromSrcCoord(center_rect.x());
165 *around_top = TileVirtualYIndexFromSrcCoord(center_rect.y());
166 int right_src_coord = center_rect.right() - 1;
167 *around_right = TileVirtualXIndexFromSrcCoord(right_src_coord) + 1;
168 int bottom_src_coord = center_rect.bottom() - 1;
169 *around_bottom = TileVirtualYIndexFromSrcCoord(bottom_src_coord) + 1;
170
171 // For left and top indices check if tiling size is smaller than tile size. In
172 // such case if center rect is not intersecting the tiling rect and if center
173 // rect is right (or below) to the tiling rect, then around tile index is same
174 // as the index returned by TileVirtual(X|Y)IndexFromSrcCoord().
175 if (!(num_tiles_x() == 1 && *around_left == 0 &&
176 !tiling_rect.Intersects(center_rect) &&
177 tiling_rect.right() < center_rect.x())) {
178 *around_left -= 1;
179 }
180 if (!(num_tiles_y() == 1 && *around_top == 0 &&
181 !tiling_rect.Intersects(center_rect) &&
182 tiling_rect.bottom() < center_rect.y())) {
183 *around_top -= 1;
184 }
185 }
186
129 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( 187 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds(
130 const gfx::Rect& rect) const { 188 const gfx::Rect& rect) const {
131 if (rect.IsEmpty() || has_empty_bounds()) 189 if (rect.IsEmpty() || has_empty_bounds())
132 return gfx::Rect(); 190 return gfx::Rect();
133 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) 191 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height())
134 return gfx::Rect(); 192 return gfx::Rect();
135 int index_x = TileXIndexFromSrcCoord(rect.x()); 193 int index_x = TileXIndexFromSrcCoord(rect.x());
136 int index_y = TileYIndexFromSrcCoord(rect.y()); 194 int index_y = TileYIndexFromSrcCoord(rect.y());
137 int index_right = TileXIndexFromSrcCoord(rect.right() - 1); 195 int index_right = TileXIndexFromSrcCoord(rect.right() - 1);
138 int index_bottom = TileYIndexFromSrcCoord(rect.bottom() - 1); 196 int index_bottom = TileYIndexFromSrcCoord(rect.bottom() - 1);
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 527
470 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { 528 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() {
471 done(); 529 done();
472 } 530 }
473 531
474 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( 532 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
475 const TilingData* tiling_data, 533 const TilingData* tiling_data,
476 const gfx::Rect& consider_rect, 534 const gfx::Rect& consider_rect,
477 const gfx::Rect& ignore_rect, 535 const gfx::Rect& ignore_rect,
478 const gfx::Rect& center_rect) 536 const gfx::Rect& center_rect)
479 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), 537 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
480 direction_(RIGHT),
481 delta_x_(1),
482 delta_y_(0),
483 current_step_(0),
484 horizontal_step_count_(0),
485 vertical_step_count_(0) {
486 if (!HasConsiderRect()) { 538 if (!HasConsiderRect()) {
487 done(); 539 done();
488 return; 540 return;
489 } 541 }
490 542
491 // Determine around left, such that it is between -1 and num_tiles_x. 543 if (tiling_data->max_texture_size().IsEmpty()) {
492 int around_left = 0; 544 done();
493 if (center_rect.x() < 0 || center_rect.IsEmpty()) 545 return;
494 around_left = -1;
495 else if (center_rect.x() >= tiling_data->tiling_size().width())
496 around_left = tiling_data->num_tiles_x();
497 else
498 around_left = tiling_data->TileXIndexFromSrcCoord(center_rect.x());
499
500 // Determine around top, such that it is between -1 and num_tiles_y.
501 int around_top = 0;
502 if (center_rect.y() < 0 || center_rect.IsEmpty())
503 around_top = -1;
504 else if (center_rect.y() >= tiling_data->tiling_size().height())
505 around_top = tiling_data->num_tiles_y();
506 else
507 around_top = tiling_data->TileYIndexFromSrcCoord(center_rect.y());
508
509 // Determine around right, such that it is between -1 and num_tiles_x.
510 int right_src_coord = center_rect.right() - 1;
511 int around_right = 0;
512 if (right_src_coord < 0 || center_rect.IsEmpty()) {
513 around_right = -1;
514 } else if (right_src_coord >= tiling_data->tiling_size().width()) {
515 around_right = tiling_data->num_tiles_x();
516 } else {
517 around_right = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
518 } 546 }
519 547
520 // Determine around bottom, such that it is between -1 and num_tiles_y. 548 int around_left;
521 int bottom_src_coord = center_rect.bottom() - 1; 549 int around_top;
522 int around_bottom = 0; 550 int around_right;
523 if (bottom_src_coord < 0 || center_rect.IsEmpty()) { 551 int around_bottom;
524 around_bottom = -1; 552
525 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) { 553 tiling_data->TileVirtualAroundIndices(
526 around_bottom = tiling_data->num_tiles_y(); 554 center_rect, &around_left, &around_right, &around_top, &around_bottom);
527 } else { 555
528 around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); 556 pyramid_sequence_.Init(around_left, around_right, around_top, around_bottom,
557 consider_left_, consider_right_, consider_top_,
558 consider_bottom_, ignore_left_, ignore_right_,
559 ignore_top_, ignore_bottom_,
560 tiling_data->max_texture_size().width(),
561 tiling_data->max_texture_size().height());
562
563 if (!pyramid_sequence_) {
564 done();
565 return;
529 } 566 }
530 567
531 vertical_step_count_ = around_bottom - around_top + 1; 568 index_x_ = pyramid_sequence_.index_x();
532 horizontal_step_count_ = around_right - around_left + 1; 569 index_y_ = pyramid_sequence_.index_y();
533 current_step_ = horizontal_step_count_ - 1; 570 DCHECK(in_consider_rect() && !in_ignore_rect());
571 }
534 572
535 index_x_ = around_right; 573 TilingData::SpiralDifferenceIterator::~SpiralDifferenceIterator() {}
536 index_y_ = around_bottom;
537 574
538 // The current index is the bottom right of the around rect, which is also 575 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
539 // ignored. So we have to advance. 576 const TilingData::SpiralDifferenceIterator& other) = default;
540 ++(*this); 577
541 } 578 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
579 TilingData::SpiralDifferenceIterator&& other) = default;
580
581 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
582 operator=(const TilingData::SpiralDifferenceIterator& other) = default;
583
584 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
585 operator=(TilingData::SpiralDifferenceIterator&& other) = default;
542 586
543 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: 587 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
544 operator++() { 588 operator++() {
545 int cannot_hit_consider_count = 0; 589 ++pyramid_sequence_;
546 while (cannot_hit_consider_count < 4) {
547 if (needs_direction_switch())
548 switch_direction();
549 590
550 index_x_ += delta_x_; 591 if (!pyramid_sequence_) {
551 index_y_ += delta_y_; 592 done();
552 ++current_step_; 593 return *this;
553
554 if (in_consider_rect()) {
555 cannot_hit_consider_count = 0;
556
557 if (!in_ignore_rect())
558 break;
559
560 // Steps needed to reach the very edge of the ignore rect, while remaining
561 // inside (so that the continue would take us outside).
562 int steps_to_edge = 0;
563 switch (direction_) {
564 case UP:
565 steps_to_edge = index_y_ - ignore_top_;
566 break;
567 case LEFT:
568 steps_to_edge = index_x_ - ignore_left_;
569 break;
570 case DOWN:
571 steps_to_edge = ignore_bottom_ - index_y_;
572 break;
573 case RIGHT:
574 steps_to_edge = ignore_right_ - index_x_;
575 break;
576 }
577
578 // We need to switch directions in |max_steps|.
579 int max_steps = current_step_count() - current_step_;
580
581 int steps_to_take = std::min(steps_to_edge, max_steps);
582 DCHECK_GE(steps_to_take, 0);
583
584 index_x_ += steps_to_take * delta_x_;
585 index_y_ += steps_to_take * delta_y_;
586 current_step_ += steps_to_take;
587 } else {
588 int max_steps = current_step_count() - current_step_;
589 int steps_to_take = max_steps;
590 bool can_hit_consider_rect = false;
591 switch (direction_) {
592 case UP:
593 if (valid_column() && consider_bottom_ < index_y_)
594 steps_to_take = index_y_ - consider_bottom_ - 1;
595 can_hit_consider_rect |= consider_right_ >= index_x_;
596 break;
597 case LEFT:
598 if (valid_row() && consider_right_ < index_x_)
599 steps_to_take = index_x_ - consider_right_ - 1;
600 can_hit_consider_rect |= consider_top_ <= index_y_;
601 break;
602 case DOWN:
603 if (valid_column() && consider_top_ > index_y_)
604 steps_to_take = consider_top_ - index_y_ - 1;
605 can_hit_consider_rect |= consider_left_ <= index_x_;
606 break;
607 case RIGHT:
608 if (valid_row() && consider_left_ > index_x_)
609 steps_to_take = consider_left_ - index_x_ - 1;
610 can_hit_consider_rect |= consider_bottom_ >= index_y_;
611 break;
612 }
613 steps_to_take = std::min(steps_to_take, max_steps);
614 DCHECK_GE(steps_to_take, 0);
615
616 index_x_ += steps_to_take * delta_x_;
617 index_y_ += steps_to_take * delta_y_;
618 current_step_ += steps_to_take;
619
620 if (can_hit_consider_rect)
621 cannot_hit_consider_count = 0;
622 else
623 ++cannot_hit_consider_count;
624 }
625 } 594 }
626 595
627 if (cannot_hit_consider_count >= 4) 596 index_x_ = pyramid_sequence_.index_x();
628 done(); 597 index_y_ = pyramid_sequence_.index_y();
598
599 DCHECK(in_consider_rect() && !in_ignore_rect());
629 return *this; 600 return *this;
630 } 601 }
631 602
632 bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const {
633 return current_step_ >= current_step_count();
634 }
635
636 void TilingData::SpiralDifferenceIterator::switch_direction() {
637 // Note that delta_x_ and delta_y_ always remain between -1 and 1.
638 int new_delta_x_ = delta_y_;
639 delta_y_ = -delta_x_;
640 delta_x_ = new_delta_x_;
641
642 current_step_ = 0;
643 direction_ = static_cast<Direction>((direction_ + 1) % 4);
644
645 if (direction_ == RIGHT || direction_ == LEFT) {
646 ++vertical_step_count_;
647 ++horizontal_step_count_;
648 }
649 }
650
651 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { 603 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
652 done(); 604 done();
653 } 605 }
654 606
655 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( 607 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
656 const TilingData* tiling_data, 608 const TilingData* tiling_data,
657 const gfx::Rect& consider_rect, 609 const gfx::Rect& consider_rect,
658 const gfx::Rect& ignore_rect, 610 const gfx::Rect& ignore_rect,
659 const gfx::Rect& center_rect) 611 const gfx::Rect& center_rect)
660 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), 612 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
661 around_left_(-1),
662 around_top_(-1),
663 around_right_(-1),
664 around_bottom_(-1),
665 direction_(LEFT),
666 delta_x_(-1),
667 delta_y_(0),
668 current_step_(0),
669 horizontal_step_count_(0),
670 vertical_step_count_(0) {
671 if (!HasConsiderRect()) { 613 if (!HasConsiderRect()) {
672 done(); 614 done();
673 return; 615 return;
674 } 616 }
675 617
676 // Determine around left, such that it is between -1 and num_tiles_x. 618 if (tiling_data->max_texture_size().IsEmpty()) {
677 if (center_rect.x() < 0 || center_rect.IsEmpty()) 619 done();
678 around_left_ = -1; 620 return;
679 else if (center_rect.x() >= tiling_data->tiling_size().width())
680 around_left_ = tiling_data->num_tiles_x();
681 else
682 around_left_ = tiling_data->TileXIndexFromSrcCoord(center_rect.x());
683
684 // Determine around top, such that it is between -1 and num_tiles_y.
685 if (center_rect.y() < 0 || center_rect.IsEmpty())
686 around_top_ = -1;
687 else if (center_rect.y() >= tiling_data->tiling_size().height())
688 around_top_ = tiling_data->num_tiles_y();
689 else
690 around_top_ = tiling_data->TileYIndexFromSrcCoord(center_rect.y());
691
692 // Determine around right, such that it is between -1 and num_tiles_x.
693 int right_src_coord = center_rect.right() - 1;
694 if (right_src_coord < 0 || center_rect.IsEmpty()) {
695 around_right_ = -1;
696 } else if (right_src_coord >= tiling_data->tiling_size().width()) {
697 around_right_ = tiling_data->num_tiles_x();
698 } else {
699 around_right_ = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
700 } 621 }
701 622
702 // Determine around bottom, such that it is between -1 and num_tiles_y. 623 int around_left;
703 int bottom_src_coord = center_rect.bottom() - 1; 624 int around_top;
704 if (bottom_src_coord < 0 || center_rect.IsEmpty()) { 625 int around_right;
705 around_bottom_ = -1; 626 int around_bottom;
706 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) { 627
707 around_bottom_ = tiling_data->num_tiles_y(); 628 tiling_data->TileVirtualAroundIndices(
708 } else { 629 center_rect, &around_left, &around_right, &around_top, &around_bottom);
709 around_bottom_ = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); 630
631 pyramid_sequence_.Init(around_left, around_right, around_top, around_bottom,
632 consider_left_, consider_right_, consider_top_,
633 consider_bottom_, ignore_left_, ignore_right_,
634 ignore_top_, ignore_bottom_,
635 tiling_data->max_texture_size().width(),
636 tiling_data->max_texture_size().height());
637
638 if (!pyramid_sequence_) {
639 done();
640 return;
710 } 641 }
711 642
712 // Figure out the maximum distance from the around edge to consider edge. 643 index_x_ = pyramid_sequence_.index_x();
713 int max_distance = 0; 644 index_y_ = pyramid_sequence_.index_y();
714 max_distance = std::max(max_distance, around_top_ - consider_top_); 645 DCHECK(in_consider_rect() && !in_ignore_rect());
715 max_distance = std::max(max_distance, around_left_ - consider_left_);
716 max_distance = std::max(max_distance, consider_bottom_ - around_bottom_);
717 max_distance = std::max(max_distance, consider_right_ - around_right_);
718
719 // The step count is the length of the edge (around_right_ - around_left_ + 1)
720 // plus twice the max distance to pad (to the right and to the left). This way
721 // the initial rect is the size proportional to the center, but big enough
722 // to cover the consider rect.
723 //
724 // C = consider rect
725 // A = around rect
726 // . = area of the padded around rect
727 // md = max distance (note in the picture below, there's md written vertically
728 // as well).
729 // I = initial starting position
730 //
731 // |md| |md|
732 //
733 // - ..........
734 // m ..........
735 // d ..........
736 // - CCCCCCC...
737 // CCCCAAC...
738 // CCCCAAC...
739 // - ..........
740 // m ..........
741 // d ..........
742 // - ..........I
743 vertical_step_count_ = around_bottom_ - around_top_ + 1 + 2 * max_distance;
744 horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance;
745
746 // Start with one to the right of the padded around rect.
747 index_x_ = around_right_ + max_distance + 1;
748 index_y_ = around_bottom_ + max_distance;
749
750 // The current index is outside a valid tile, so advance immediately.
751 ++(*this);
752 } 646 }
753 647
648 TilingData::ReverseSpiralDifferenceIterator::
649 ~ReverseSpiralDifferenceIterator() {}
650
651 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
652 const TilingData::ReverseSpiralDifferenceIterator& other) = default;
653
654 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
655 TilingData::ReverseSpiralDifferenceIterator&& other) = default;
656
754 TilingData::ReverseSpiralDifferenceIterator& 657 TilingData::ReverseSpiralDifferenceIterator&
755 TilingData::ReverseSpiralDifferenceIterator:: 658 TilingData::ReverseSpiralDifferenceIterator::operator=(
756 operator++() { 659 const TilingData::ReverseSpiralDifferenceIterator& other) = default;
757 while (!in_around_rect()) {
758 if (needs_direction_switch())
759 switch_direction();
760 660
761 index_x_ += delta_x_; 661 TilingData::ReverseSpiralDifferenceIterator&
762 index_y_ += delta_y_; 662 TilingData::ReverseSpiralDifferenceIterator::operator=(
763 ++current_step_; 663 TilingData::ReverseSpiralDifferenceIterator&& other) = default;
764 664
765 if (in_around_rect()) { 665 TilingData::ReverseSpiralDifferenceIterator&
766 break; 666 TilingData::ReverseSpiralDifferenceIterator::operator++() {
767 } else if (in_consider_rect()) { 667 ++pyramid_sequence_;
768 // If the tile is in the consider rect but not in ignore rect, then it's a
769 // valid tile to visit.
770 if (!in_ignore_rect())
771 break;
772 668
773 // Steps needed to reach the very edge of the ignore rect, while remaining 669 if (!pyramid_sequence_) {
774 // inside it (so that the continue would take us outside). 670 done();
775 int steps_to_edge = 0; 671 return *this;
776 switch (direction_) {
777 case UP:
778 steps_to_edge = index_y_ - ignore_top_;
779 break;
780 case LEFT:
781 steps_to_edge = index_x_ - ignore_left_;
782 break;
783 case DOWN:
784 steps_to_edge = ignore_bottom_ - index_y_;
785 break;
786 case RIGHT:
787 steps_to_edge = ignore_right_ - index_x_;
788 break;
789 }
790
791 // We need to switch directions in |max_steps|.
792 int max_steps = current_step_count() - current_step_;
793
794 int steps_to_take = std::min(steps_to_edge, max_steps);
795 DCHECK_GE(steps_to_take, 0);
796
797 index_x_ += steps_to_take * delta_x_;
798 index_y_ += steps_to_take * delta_y_;
799 current_step_ += steps_to_take;
800 } else {
801 // We're not in the consider rect.
802
803 int max_steps = current_step_count() - current_step_;
804 int steps_to_take = max_steps;
805
806 // We might hit the consider rect before needing to switch directions:
807 // update steps to take.
808 switch (direction_) {
809 case UP:
810 if (valid_column() && consider_bottom_ < index_y_)
811 steps_to_take = index_y_ - consider_bottom_ - 1;
812 break;
813 case LEFT:
814 if (valid_row() && consider_right_ < index_x_)
815 steps_to_take = index_x_ - consider_right_ - 1;
816 break;
817 case DOWN:
818 if (valid_column() && consider_top_ > index_y_)
819 steps_to_take = consider_top_ - index_y_ - 1;
820 break;
821 case RIGHT:
822 if (valid_row() && consider_left_ > index_x_)
823 steps_to_take = consider_left_ - index_x_ - 1;
824 break;
825 }
826 steps_to_take = std::min(steps_to_take, max_steps);
827 DCHECK_GE(steps_to_take, 0);
828
829 index_x_ += steps_to_take * delta_x_;
830 index_y_ += steps_to_take * delta_y_;
831 current_step_ += steps_to_take;
832 }
833 } 672 }
834 673
835 // Once we enter the around rect, we're done. 674 index_x_ = pyramid_sequence_.index_x();
836 if (in_around_rect()) 675 index_y_ = pyramid_sequence_.index_y();
837 done(); 676 DCHECK(in_consider_rect() && !in_ignore_rect());
838 return *this; 677 return *this;
839 } 678 }
840 679
841 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch()
842 const {
843 return current_step_ >= current_step_count();
844 }
845
846 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() {
847 // Note that delta_x_ and delta_y_ always remain between -1 and 1.
848 int new_delta_y_ = delta_x_;
849 delta_x_ = -delta_y_;
850 delta_y_ = new_delta_y_;
851
852 current_step_ = 0;
853 direction_ = static_cast<Direction>((direction_ + 1) % 4);
854
855 if (direction_ == UP || direction_ == DOWN) {
856 --vertical_step_count_;
857 --horizontal_step_count_;
858
859 // We should always end up in an around rect at some point.
860 // Since the direction is now vertical, we have to ensure that we will
861 // advance.
862 DCHECK_GE(horizontal_step_count_, 1);
863 DCHECK_GE(vertical_step_count_, 1);
864 }
865 }
866
867 } // namespace cc 680 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698