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

Side by Side Diff: cc/base/tiling_data.cc

Issue 645173004: cc: Add ReverseSpiralDifferenceIterator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase + comment Created 6 years, 2 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
« no previous file with comments | « cc/base/tiling_data.h ('k') | cc/base/tiling_data_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/rect.h" 9 #include "ui/gfx/rect.h"
10 #include "ui/gfx/vector2d.h" 10 #include "ui/gfx/vector2d.h"
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ && 503 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ &&
504 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) { 504 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) {
505 done(); 505 done();
506 return; 506 return;
507 } 507 }
508 508
509 // Determine around left, such that it is between -1 and num_tiles_x. 509 // Determine around left, such that it is between -1 and num_tiles_x.
510 int around_left = 0; 510 int around_left = 0;
511 if (center.x() < 0 || center.IsEmpty()) 511 if (center.x() < 0 || center.IsEmpty())
512 around_left = -1; 512 around_left = -1;
513 else if (center.x() > tiling_data->tiling_size().width()) 513 else if (center.x() >= tiling_data->tiling_size().width())
514 around_left = tiling_data->num_tiles_x(); 514 around_left = tiling_data->num_tiles_x();
515 else 515 else
516 around_left = tiling_data->TileXIndexFromSrcCoord(center.x()); 516 around_left = tiling_data->TileXIndexFromSrcCoord(center.x());
517 517
518 // Determine around top, such that it is between -1 and num_tiles_y. 518 // Determine around top, such that it is between -1 and num_tiles_y.
519 int around_top = 0; 519 int around_top = 0;
520 if (center.y() < 0 || center.IsEmpty()) 520 if (center.y() < 0 || center.IsEmpty())
521 around_top = -1; 521 around_top = -1;
522 else if (center.y() > tiling_data->tiling_size().height()) 522 else if (center.y() >= tiling_data->tiling_size().height())
523 around_top = tiling_data->num_tiles_y(); 523 around_top = tiling_data->num_tiles_y();
524 else 524 else
525 around_top = tiling_data->TileYIndexFromSrcCoord(center.y()); 525 around_top = tiling_data->TileYIndexFromSrcCoord(center.y());
526 526
527 // Determine around right, such that it is between -1 and num_tiles_x. 527 // Determine around right, such that it is between -1 and num_tiles_x.
528 int right_src_coord = center.right() - 1; 528 int right_src_coord = center.right() - 1;
529 int around_right = 0; 529 int around_right = 0;
530 if (right_src_coord < 0 || center.IsEmpty()) { 530 if (right_src_coord < 0 || center.IsEmpty()) {
531 around_right = -1; 531 around_right = -1;
532 } else if (right_src_coord > tiling_data->tiling_size().width()) { 532 } else if (right_src_coord >= tiling_data->tiling_size().width()) {
533 around_right = tiling_data->num_tiles_x(); 533 around_right = tiling_data->num_tiles_x();
534 } else { 534 } else {
535 around_right = tiling_data->TileXIndexFromSrcCoord(right_src_coord); 535 around_right = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
536 } 536 }
537 537
538 // Determine around bottom, such that it is between -1 and num_tiles_y. 538 // Determine around bottom, such that it is between -1 and num_tiles_y.
539 int bottom_src_coord = center.bottom() - 1; 539 int bottom_src_coord = center.bottom() - 1;
540 int around_bottom = 0; 540 int around_bottom = 0;
541 if (bottom_src_coord < 0 || center.IsEmpty()) { 541 if (bottom_src_coord < 0 || center.IsEmpty()) {
542 around_bottom = -1; 542 around_bottom = -1;
543 } else if (bottom_src_coord > tiling_data->tiling_size().height()) { 543 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) {
544 around_bottom = tiling_data->num_tiles_y(); 544 around_bottom = tiling_data->num_tiles_y();
545 } else { 545 } else {
546 around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); 546 around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
547 } 547 }
548 548
549 vertical_step_count_ = around_bottom - around_top + 1; 549 vertical_step_count_ = around_bottom - around_top + 1;
550 horizontal_step_count_ = around_right - around_left + 1; 550 horizontal_step_count_ = around_right - around_left + 1;
551 current_step_ = horizontal_step_count_ - 1; 551 current_step_ = horizontal_step_count_ - 1;
552 552
553 index_x_ = around_right; 553 index_x_ = around_right;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 if (cannot_hit_consider_count >= 4) 645 if (cannot_hit_consider_count >= 4)
646 done(); 646 done();
647 return *this; 647 return *this;
648 } 648 }
649 649
650 bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const { 650 bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const {
651 return current_step_ >= current_step_count(); 651 return current_step_ >= current_step_count();
652 } 652 }
653 653
654 void TilingData::SpiralDifferenceIterator::switch_direction() { 654 void TilingData::SpiralDifferenceIterator::switch_direction() {
655 // Note that delta_x_ and delta_y_ always remain between -1 and 1.
655 int new_delta_x_ = delta_y_; 656 int new_delta_x_ = delta_y_;
656 delta_y_ = -delta_x_; 657 delta_y_ = -delta_x_;
657 delta_x_ = new_delta_x_; 658 delta_x_ = new_delta_x_;
658 659
659 current_step_ = 0; 660 current_step_ = 0;
660 direction_ = static_cast<Direction>((direction_ + 1) % 4); 661 direction_ = static_cast<Direction>((direction_ + 1) % 4);
661 662
662 if (direction_ == RIGHT || direction_ == LEFT) { 663 if (direction_ == RIGHT || direction_ == LEFT) {
663 ++vertical_step_count_; 664 ++vertical_step_count_;
664 ++horizontal_step_count_; 665 ++horizontal_step_count_;
665 } 666 }
666 } 667 }
667 668
669 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator()
670 : BaseIterator(nullptr) {
671 done();
672 }
673
674 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
675 const TilingData* tiling_data,
676 const gfx::Rect& consider_rect,
677 const gfx::Rect& ignore_rect,
678 const gfx::Rect& center_rect)
679 : BaseIterator(tiling_data),
680 consider_left_(-1),
681 consider_top_(-1),
682 consider_right_(-1),
683 consider_bottom_(-1),
684 around_left_(-1),
685 around_top_(-1),
686 around_right_(-1),
687 around_bottom_(-1),
688 ignore_left_(-1),
689 ignore_top_(-1),
690 ignore_right_(-1),
691 ignore_bottom_(-1),
692 direction_(LEFT),
693 delta_x_(-1),
694 delta_y_(0),
695 current_step_(0),
696 horizontal_step_count_(0),
697 vertical_step_count_(0) {
698 if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
699 done();
700 return;
701 }
702
703 gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size());
704 gfx::Rect consider(consider_rect);
705 gfx::Rect ignore(ignore_rect);
706 gfx::Rect center(center_rect);
707 consider.Intersect(tiling_bounds_rect);
708 ignore.Intersect(tiling_bounds_rect);
709 if (consider.IsEmpty()) {
710 done();
711 return;
712 }
713
714 consider_left_ = tiling_data_->TileXIndexFromSrcCoord(consider.x());
715 consider_top_ = tiling_data_->TileYIndexFromSrcCoord(consider.y());
716 consider_right_ = tiling_data_->TileXIndexFromSrcCoord(consider.right() - 1);
717 consider_bottom_ =
718 tiling_data_->TileYIndexFromSrcCoord(consider.bottom() - 1);
719
720 if (!ignore.IsEmpty()) {
721 ignore_left_ = tiling_data_->TileXIndexFromSrcCoord(ignore.x());
722 ignore_top_ = tiling_data_->TileYIndexFromSrcCoord(ignore.y());
723 ignore_right_ = tiling_data_->TileXIndexFromSrcCoord(ignore.right() - 1);
724 ignore_bottom_ = tiling_data_->TileYIndexFromSrcCoord(ignore.bottom() - 1);
725
726 // Clamp ignore indices to consider indices.
727 ignore_left_ = std::max(ignore_left_, consider_left_);
728 ignore_top_ = std::max(ignore_top_, consider_top_);
729 ignore_right_ = std::min(ignore_right_, consider_right_);
730 ignore_bottom_ = std::min(ignore_bottom_, consider_bottom_);
731 }
732
733 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ &&
734 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) {
735 done();
736 return;
737 }
738
739 // Determine around left, such that it is between -1 and num_tiles_x.
740 if (center.x() < 0 || center.IsEmpty())
741 around_left_ = -1;
742 else if (center.x() >= tiling_data->tiling_size().width())
743 around_left_ = tiling_data->num_tiles_x();
744 else
745 around_left_ = tiling_data->TileXIndexFromSrcCoord(center.x());
746
747 // Determine around top, such that it is between -1 and num_tiles_y.
748 if (center.y() < 0 || center.IsEmpty())
749 around_top_ = -1;
750 else if (center.y() >= tiling_data->tiling_size().height())
751 around_top_ = tiling_data->num_tiles_y();
752 else
753 around_top_ = tiling_data->TileYIndexFromSrcCoord(center.y());
754
755 // Determine around right, such that it is between -1 and num_tiles_x.
756 int right_src_coord = center.right() - 1;
757 if (right_src_coord < 0 || center.IsEmpty()) {
758 around_right_ = -1;
759 } else if (right_src_coord >= tiling_data->tiling_size().width()) {
760 around_right_ = tiling_data->num_tiles_x();
761 } else {
762 around_right_ = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
763 }
764
765 // Determine around bottom, such that it is between -1 and num_tiles_y.
766 int bottom_src_coord = center.bottom() - 1;
767 if (bottom_src_coord < 0 || center.IsEmpty()) {
768 around_bottom_ = -1;
769 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) {
770 around_bottom_ = tiling_data->num_tiles_y();
771 } else {
772 around_bottom_ = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
773 }
774
775 // Figure out the maximum distance from the around edge to consider edge.
776 int max_distance = 0;
777 max_distance = std::max(max_distance, around_top_ - consider_top_);
778 max_distance = std::max(max_distance, around_left_ - consider_left_);
779 max_distance = std::max(max_distance, consider_bottom_ - around_bottom_);
780 max_distance = std::max(max_distance, consider_right_ - around_right_);
781
782 // The step count is the length of the edge (around_right_ - around_left_ + 1)
783 // plus twice the max distance to pad (to the right and to the left). This way
784 // the initial rect is the size proportional to the center, but big enough
785 // to cover the consider rect.
786 //
787 // C = consider rect
788 // A = around rect
789 // . = area of the padded around rect
790 // md = max distance (note in the picture below, there's md written vertically
791 // as well).
792 // I = initial starting position
793 //
794 // |md| |md|
795 //
796 // - ..........
797 // m ..........
798 // d ..........
799 // - CCCCCCC...
800 // CCCCAAC...
801 // CCCCAAC...
802 // - ..........
803 // m ..........
804 // d ..........
805 // - ..........I
806 vertical_step_count_ = around_bottom_ - around_top_ + 1 + 2 * max_distance;
807 horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance;
808
809 // Start with one to the right of the padded around rect.
810 index_x_ = around_right_ + max_distance + 1;
811 index_y_ = around_bottom_ + max_distance;
812
813 // The current index is outside a valid tile, so advance immediately.
814 ++(*this);
815 }
816
817 TilingData::ReverseSpiralDifferenceIterator&
818 TilingData::ReverseSpiralDifferenceIterator::
819 operator++() {
820 while (!in_around_rect()) {
821 if (needs_direction_switch())
822 switch_direction();
823
824 index_x_ += delta_x_;
825 index_y_ += delta_y_;
826 ++current_step_;
827
828 if (in_around_rect()) {
829 break;
830 } else if (in_consider_rect()) {
831 // If the tile is in the consider rect but not in ignore rect, then it's a
832 // valid tile to visit.
833 if (!in_ignore_rect())
834 break;
835
836 // Steps needed to reach the very edge of the ignore rect, while remaining
837 // inside it (so that the continue would take us outside).
838 int steps_to_edge = 0;
839 switch (direction_) {
840 case UP:
841 steps_to_edge = index_y_ - ignore_top_;
842 break;
843 case LEFT:
844 steps_to_edge = index_x_ - ignore_left_;
845 break;
846 case DOWN:
847 steps_to_edge = ignore_bottom_ - index_y_;
848 break;
849 case RIGHT:
850 steps_to_edge = ignore_right_ - index_x_;
851 break;
852 }
853
854 // We need to switch directions in |max_steps|.
855 int max_steps = current_step_count() - current_step_;
856
857 int steps_to_take = std::min(steps_to_edge, max_steps);
858 DCHECK_GE(steps_to_take, 0);
859
860 index_x_ += steps_to_take * delta_x_;
861 index_y_ += steps_to_take * delta_y_;
862 current_step_ += steps_to_take;
863 } else {
864 // We're not in the consider rect.
865
866 int max_steps = current_step_count() - current_step_;
867 int steps_to_take = max_steps;
868
869 // We might hit the consider rect before needing to switch directions:
870 // update steps to take.
871 switch (direction_) {
872 case UP:
873 if (valid_column() && consider_bottom_ < index_y_)
874 steps_to_take = index_y_ - consider_bottom_ - 1;
875 break;
876 case LEFT:
877 if (valid_row() && consider_right_ < index_x_)
878 steps_to_take = index_x_ - consider_right_ - 1;
879 break;
880 case DOWN:
881 if (valid_column() && consider_top_ > index_y_)
882 steps_to_take = consider_top_ - index_y_ - 1;
883 break;
884 case RIGHT:
885 if (valid_row() && consider_left_ > index_x_)
886 steps_to_take = consider_left_ - index_x_ - 1;
887 break;
888 }
889 steps_to_take = std::min(steps_to_take, max_steps);
890 DCHECK_GE(steps_to_take, 0);
891
892 index_x_ += steps_to_take * delta_x_;
893 index_y_ += steps_to_take * delta_y_;
894 current_step_ += steps_to_take;
895 }
896 }
897
898 // Once we enter the around rect, we're done.
899 if (in_around_rect())
900 done();
901 return *this;
902 }
903
904 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch()
905 const {
906 return current_step_ >= current_step_count();
907 }
908
909 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() {
910 // Note that delta_x_ and delta_y_ always remain between -1 and 1.
911 int new_delta_y_ = delta_x_;
912 delta_x_ = -delta_y_;
913 delta_y_ = new_delta_y_;
914
915 current_step_ = 0;
916 direction_ = static_cast<Direction>((direction_ + 1) % 4);
917
918 if (direction_ == UP || direction_ == DOWN) {
919 --vertical_step_count_;
920 --horizontal_step_count_;
921
922 // We should always end up in an around rect at some point.
923 // Since the direction is now vertical, we have to ensure that we will
924 // advance.
925 DCHECK_GE(horizontal_step_count_, 1);
926 DCHECK_GE(vertical_step_count_, 1);
927 }
928 }
929
668 } // namespace cc 930 } // namespace cc
OLDNEW
« no previous file with comments | « cc/base/tiling_data.h ('k') | cc/base/tiling_data_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698