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

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: review 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
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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 658
659 current_step_ = 0; 659 current_step_ = 0;
660 direction_ = static_cast<Direction>((direction_ + 1) % 4); 660 direction_ = static_cast<Direction>((direction_ + 1) % 4);
661 661
662 if (direction_ == RIGHT || direction_ == LEFT) { 662 if (direction_ == RIGHT || direction_ == LEFT) {
663 ++vertical_step_count_; 663 ++vertical_step_count_;
664 ++horizontal_step_count_; 664 ++horizontal_step_count_;
665 } 665 }
666 } 666 }
667 667
668 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator()
669 : BaseIterator(nullptr) {
670 done();
671 }
672
673 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
674 const TilingData* tiling_data,
675 const gfx::Rect& consider_rect,
676 const gfx::Rect& ignore_rect,
677 const gfx::Rect& center_rect)
678 : BaseIterator(tiling_data),
679 consider_left_(-1),
680 consider_top_(-1),
681 consider_right_(-1),
682 consider_bottom_(-1),
683 around_left_(-1),
684 around_top_(-1),
685 around_right_(-1),
686 around_bottom_(-1),
687 ignore_left_(-1),
688 ignore_top_(-1),
689 ignore_right_(-1),
690 ignore_bottom_(-1),
691 direction_(LEFT),
692 delta_x_(-1),
693 delta_y_(0),
694 current_step_(0),
695 horizontal_step_count_(0),
696 vertical_step_count_(0) {
697 if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
698 done();
699 return;
700 }
701
702 gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size());
703 gfx::Rect consider(consider_rect);
704 gfx::Rect ignore(ignore_rect);
705 gfx::Rect center(center_rect);
706 consider.Intersect(tiling_bounds_rect);
707 ignore.Intersect(tiling_bounds_rect);
708 if (consider.IsEmpty()) {
709 done();
710 return;
711 }
712
713 consider_left_ = tiling_data_->TileXIndexFromSrcCoord(consider.x());
714 consider_top_ = tiling_data_->TileYIndexFromSrcCoord(consider.y());
715 consider_right_ = tiling_data_->TileXIndexFromSrcCoord(consider.right() - 1);
716 consider_bottom_ =
717 tiling_data_->TileYIndexFromSrcCoord(consider.bottom() - 1);
718
719 if (!ignore.IsEmpty()) {
720 ignore_left_ = tiling_data_->TileXIndexFromSrcCoord(ignore.x());
721 ignore_top_ = tiling_data_->TileYIndexFromSrcCoord(ignore.y());
722 ignore_right_ = tiling_data_->TileXIndexFromSrcCoord(ignore.right() - 1);
723 ignore_bottom_ = tiling_data_->TileYIndexFromSrcCoord(ignore.bottom() - 1);
724
725 // Clamp ignore indices to consider indices.
726 ignore_left_ = std::max(ignore_left_, consider_left_);
727 ignore_top_ = std::max(ignore_top_, consider_top_);
728 ignore_right_ = std::min(ignore_right_, consider_right_);
729 ignore_bottom_ = std::min(ignore_bottom_, consider_bottom_);
730 }
731
732 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ &&
733 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) {
734 done();
735 return;
736 }
737
738 // Determine around left, such that it is between -1 and num_tiles_x.
739 if (center.x() < 0 || center.IsEmpty())
740 around_left_ = -1;
741 else if (center.x() >= tiling_data->tiling_size().width())
742 around_left_ = tiling_data->num_tiles_x();
743 else
744 around_left_ = tiling_data->TileXIndexFromSrcCoord(center.x());
745
746 // Determine around top, such that it is between -1 and num_tiles_y.
747 if (center.y() < 0 || center.IsEmpty())
748 around_top_ = -1;
749 else if (center.y() >= tiling_data->tiling_size().height())
750 around_top_ = tiling_data->num_tiles_y();
751 else
752 around_top_ = tiling_data->TileYIndexFromSrcCoord(center.y());
753
754 // Determine around right, such that it is between -1 and num_tiles_x.
755 int right_src_coord = center.right() - 1;
756 if (right_src_coord < 0 || center.IsEmpty()) {
757 around_right_ = -1;
758 } else if (right_src_coord >= tiling_data->tiling_size().width()) {
759 around_right_ = tiling_data->num_tiles_x();
760 } else {
761 around_right_ = tiling_data->TileXIndexFromSrcCoord(right_src_coord);
762 }
763
764 // Determine around bottom, such that it is between -1 and num_tiles_y.
765 int bottom_src_coord = center.bottom() - 1;
766 if (bottom_src_coord < 0 || center.IsEmpty()) {
767 around_bottom_ = -1;
768 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) {
769 around_bottom_ = tiling_data->num_tiles_y();
770 } else {
771 around_bottom_ = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
772 }
773
774 // Figure out the maximum distance from the around edge to consider edge.
775 int max_distance = 0;
776 max_distance = std::max(max_distance, around_top_ - consider_top_);
777 max_distance = std::max(max_distance, around_left_ - consider_left_);
778 max_distance = std::max(max_distance, consider_bottom_ - around_bottom_);
779 max_distance = std::max(max_distance, consider_right_ - around_right_);
780
781 // The step count is the length of the edge (around_right_ - around_left_ + 1)
782 // plus twice the max distance to pad (to the right and to the left). This way
783 // the initial rect is the size proportional to the center, but big enough
784 // to cover the consider rect.
785 //
786 // C = consider rect
787 // A = around rect
788 // . = area of the padded around rect
789 // md = max distance
790 // I = initial starting position
791 //
792 // |md| |md|
793 // -..........
794 // m..........
795 // d..........
796 // -CCCCCCC...
797 // CCCCAAC...
798 // CCCCAAC...
799 // -..........
800 // m..........
801 // d..........
802 // -..........I
ajuma 2014/10/15 17:56:52 The vertical |md| had me confused for a bit, think
vmpstr 2014/10/15 18:10:46 Ya, sorry about that :P I've added some spaces, se
ajuma 2014/10/15 18:21:27 Yes, looks better now.
803 vertical_step_count_ = around_bottom_ - around_top_ + 1 + 2 * max_distance;
804 horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance;
805
806 // Start with one to the right of the padded around rect.
807 index_x_ = around_right_ + max_distance + 1;
808 index_y_ = around_bottom_ + max_distance;
809
810 // The current index is outside a valid tile, so advance immediately.
811 ++(*this);
812 }
813
814 TilingData::ReverseSpiralDifferenceIterator&
815 TilingData::ReverseSpiralDifferenceIterator::
816 operator++() {
817 while (!in_around_rect()) {
818 if (needs_direction_switch())
819 switch_direction();
820
821 index_x_ += delta_x_;
822 index_y_ += delta_y_;
823 ++current_step_;
824
825 if (in_around_rect()) {
826 break;
827 } else if (in_consider_rect()) {
828 // If the tile is in the consider rect but not in ignore rect, then it's a
829 // valid tile to visit.
830 if (!in_ignore_rect())
831 break;
832
833 // Steps needed to reach the very edge of the ignore rect, while remaining
834 // inside it (so that the continue would take us outside).
835 int steps_to_edge = 0;
836 switch (direction_) {
837 case UP:
838 steps_to_edge = index_y_ - ignore_top_;
839 break;
840 case LEFT:
841 steps_to_edge = index_x_ - ignore_left_;
842 break;
843 case DOWN:
844 steps_to_edge = ignore_bottom_ - index_y_;
845 break;
846 case RIGHT:
847 steps_to_edge = ignore_right_ - index_x_;
848 break;
849 }
850
851 // We need to switch directions in |max_steps|.
852 int max_steps = current_step_count() - current_step_;
853
854 int steps_to_take = std::min(steps_to_edge, max_steps);
ajuma 2014/10/15 17:56:52 Why doesn't this need to take delta_x_ or delta_y_
vmpstr 2014/10/15 18:10:46 Yeah, delta_x_ and delta_y_ are always less than o
ajuma 2014/10/15 18:21:27 Possibly, though I'm not quite sure what that to c
vmpstr 2014/10/18 19:43:12 Done.
855 DCHECK_GE(steps_to_take, 0);
856
857 index_x_ += steps_to_take * delta_x_;
858 index_y_ += steps_to_take * delta_y_;
859 current_step_ += steps_to_take;
860 } else {
861 // We're not in the consider rect.
862
863 int max_steps = current_step_count() - current_step_;
864 int steps_to_take = max_steps;
865
866 // We might hit the consider rect before needing to switch directions:
867 // update steps to take.
868 switch (direction_) {
869 case UP:
870 if (valid_column() && consider_bottom_ < index_y_)
871 steps_to_take = index_y_ - consider_bottom_ - 1;
872 break;
873 case LEFT:
874 if (valid_row() && consider_right_ < index_x_)
875 steps_to_take = index_x_ - consider_right_ - 1;
876 break;
877 case DOWN:
878 if (valid_column() && consider_top_ > index_y_)
879 steps_to_take = consider_top_ - index_y_ - 1;
880 break;
881 case RIGHT:
882 if (valid_row() && consider_left_ > index_x_)
883 steps_to_take = consider_left_ - index_x_ - 1;
884 break;
885 }
886 steps_to_take = std::min(steps_to_take, max_steps);
887 DCHECK_GE(steps_to_take, 0);
888
889 index_x_ += steps_to_take * delta_x_;
890 index_y_ += steps_to_take * delta_y_;
891 current_step_ += steps_to_take;
892 }
893 }
894
895 // Once we enter the around rect, we're done.
896 if (in_around_rect())
897 done();
898 return *this;
899 }
900
901 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch()
902 const {
903 return current_step_ >= current_step_count();
904 }
905
906 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() {
907 int new_delta_y_ = delta_x_;
908 delta_x_ = -delta_y_;
909 delta_y_ = new_delta_y_;
910
911 current_step_ = 0;
912 direction_ = static_cast<Direction>((direction_ + 1) % 4);
913
914 if (direction_ == UP || direction_ == DOWN) {
915 --vertical_step_count_;
916 --horizontal_step_count_;
917
918 // We should always end up in an around rect at some point.
919 // Since the direction is now vertical, we have to ensure that we will
920 // advance.
921 DCHECK_GE(horizontal_step_count_, 1);
922 DCHECK_GE(vertical_step_count_, 1);
923 }
924 }
925
668 } // namespace cc 926 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698