OLD | NEW |
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 "base/command_line.h" |
| 10 #include "cc/base/switches.h" |
9 #include "ui/gfx/geometry/rect.h" | 11 #include "ui/gfx/geometry/rect.h" |
10 #include "ui/gfx/geometry/rect_f.h" | 12 #include "ui/gfx/geometry/rect_f.h" |
11 #include "ui/gfx/geometry/vector2d.h" | 13 #include "ui/gfx/geometry/vector2d.h" |
12 | 14 |
13 namespace cc { | 15 namespace cc { |
14 | 16 |
15 namespace { | 17 namespace { |
16 // IndexRect which is at left top corner of the positive quadrant. | 18 // IndexRect which is at left top corner of the positive quadrant. |
17 const IndexRect kNonPositiveQuadrantIndexRect(-1, -1, -1, -1); | 19 const IndexRect kNonPositiveQuadrantIndexRect(-1, -1, -1, -1); |
18 } | 20 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 if (num_tiles_y_ <= 1) | 88 if (num_tiles_y_ <= 1) |
87 return 0; | 89 return 0; |
88 | 90 |
89 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); | 91 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); |
90 int y = (src_position - border_texels_) / | 92 int y = (src_position - border_texels_) / |
91 (max_texture_size_.height() - 2 * border_texels_); | 93 (max_texture_size_.height() - 2 * border_texels_); |
92 return std::min(std::max(y, 0), num_tiles_y_ - 1); | 94 return std::min(std::max(y, 0), num_tiles_y_ - 1); |
93 } | 95 } |
94 | 96 |
95 int TilingData::TileAbsoluteXIndexFromSrcCoord(int src_position) const { | 97 int TilingData::TileAbsoluteXIndexFromSrcCoord(int src_position) const { |
96 int inner_tile_width = max_texture_size_.width() - 2 * border_texels_; | 98 int inner_tile_width = max_texture_size_.width() - 2 * border_texels_; |
97 if (inner_tile_width <= 0) | 99 if (inner_tile_width <= 0) |
98 return 0; | 100 return 0; |
99 | 101 |
100 int max_width = inner_tile_width * num_tiles_x_ + 2 * border_texels_; | 102 int max_width = inner_tile_width * num_tiles_x_ + 2 * border_texels_; |
101 if (src_position >= 0 && src_position < max_width) | 103 if (src_position >= 0 && src_position < max_width) |
102 return TileXIndexFromSrcCoord(src_position); | 104 return TileXIndexFromSrcCoord(src_position); |
103 | 105 |
104 if (src_position >= max_width) | 106 if (src_position >= max_width) |
105 return num_tiles_x_ + (src_position - max_width) / inner_tile_width; | 107 return num_tiles_x_ + (src_position - max_width) / inner_tile_width; |
106 | 108 |
107 return (src_position + 1) / inner_tile_width - 1; | 109 return (src_position + 1) / inner_tile_width - 1; |
108 } | 110 } |
109 | 111 |
110 int TilingData::TileAbsoluteYIndexFromSrcCoord(int src_position) const { | 112 int TilingData::TileAbsoluteYIndexFromSrcCoord(int src_position) const { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 around_bottom = -1; | 201 around_bottom = -1; |
200 } else if (bottom_src_coord >= tiling_size().height()) { | 202 } else if (bottom_src_coord >= tiling_size().height()) { |
201 around_bottom = num_tiles_y(); | 203 around_bottom = num_tiles_y(); |
202 } else { | 204 } else { |
203 around_bottom = TileYIndexFromSrcCoord(bottom_src_coord); | 205 around_bottom = TileYIndexFromSrcCoord(bottom_src_coord); |
204 } | 206 } |
205 | 207 |
206 return IndexRect(around_left, around_right, around_top, around_bottom); | 208 return IndexRect(around_left, around_right, around_top, around_bottom); |
207 } | 209 } |
208 | 210 |
| 211 IndexRect TilingData::TileAroundAbsoluteIndexRect( |
| 212 const gfx::Rect& center_rect) const { |
| 213 if (center_rect.IsEmpty()) { |
| 214 // Default around rect is assumed to be at top-left corner of tile at |
| 215 // (0, 0). |
| 216 return IndexRect(-2, 0, -2, 0); |
| 217 } |
| 218 |
| 219 gfx::Rect tiling_rect(tiling_size()); |
| 220 |
| 221 int around_left = TileAbsoluteXIndexFromSrcCoord(center_rect.x()); |
| 222 int around_top = TileAbsoluteYIndexFromSrcCoord(center_rect.y()); |
| 223 int right_src_coord = center_rect.right() - 1; |
| 224 int around_right = TileAbsoluteXIndexFromSrcCoord(right_src_coord) + 1; |
| 225 int bottom_src_coord = center_rect.bottom() - 1; |
| 226 int around_bottom = TileAbsoluteYIndexFromSrcCoord(bottom_src_coord) + 1; |
| 227 |
| 228 // For left and top indices check if tiling size is smaller than tile size. In |
| 229 // such case if center rect is not intersecting the tiling rect and if center |
| 230 // rect is right (or below) to the tiling rect, then around tile index is same |
| 231 // as the index returned by TileAbsolute(X|Y)IndexFromSrcCoord(). |
| 232 if (!(num_tiles_x() == 1 && around_left == 0 && |
| 233 !tiling_rect.Intersects(center_rect) && |
| 234 tiling_rect.right() < center_rect.x())) { |
| 235 around_left -= 1; |
| 236 } |
| 237 if (!(num_tiles_y() == 1 && around_top == 0 && |
| 238 !tiling_rect.Intersects(center_rect) && |
| 239 tiling_rect.bottom() < center_rect.y())) { |
| 240 around_top -= 1; |
| 241 } |
| 242 |
| 243 return IndexRect(around_left, around_right, around_top, around_bottom); |
| 244 } |
| 245 |
209 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( | 246 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( |
210 const gfx::Rect& rect) const { | 247 const gfx::Rect& rect) const { |
211 if (rect.IsEmpty() || has_empty_bounds()) | 248 if (rect.IsEmpty() || has_empty_bounds()) |
212 return gfx::Rect(); | 249 return gfx::Rect(); |
213 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) | 250 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) |
214 return gfx::Rect(); | 251 return gfx::Rect(); |
215 int index_x = TileXIndexFromSrcCoord(rect.x()); | 252 int index_x = TileXIndexFromSrcCoord(rect.x()); |
216 int index_y = TileYIndexFromSrcCoord(rect.y()); | 253 int index_y = TileYIndexFromSrcCoord(rect.y()); |
217 int index_right = TileXIndexFromSrcCoord(rect.right() - 1); | 254 int index_right = TileXIndexFromSrcCoord(rect.right() - 1); |
218 int index_bottom = TileYIndexFromSrcCoord(rect.bottom() - 1); | 255 int index_bottom = TileYIndexFromSrcCoord(rect.bottom() - 1); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 return gfx::Vector2d(left, top); | 409 return gfx::Vector2d(left, top); |
373 } | 410 } |
374 | 411 |
375 void TilingData::RecomputeNumTiles() { | 412 void TilingData::RecomputeNumTiles() { |
376 num_tiles_x_ = ComputeNumTiles( | 413 num_tiles_x_ = ComputeNumTiles( |
377 max_texture_size_.width(), tiling_size_.width(), border_texels_); | 414 max_texture_size_.width(), tiling_size_.width(), border_texels_); |
378 num_tiles_y_ = ComputeNumTiles( | 415 num_tiles_y_ = ComputeNumTiles( |
379 max_texture_size_.height(), tiling_size_.height(), border_texels_); | 416 max_texture_size_.height(), tiling_size_.height(), border_texels_); |
380 } | 417 } |
381 | 418 |
| 419 bool TilingData::IsPyramidSequenceEnabled() { |
| 420 static bool enabled = base::CommandLine::ForCurrentProcess() |
| 421 ->GetSwitchValueASCII(switches::kTilingIterator) |
| 422 .compare("pyramid-sequence") == 0; |
| 423 return enabled; |
| 424 } |
| 425 |
382 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { | 426 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { |
383 } | 427 } |
384 | 428 |
385 TilingData::Iterator::Iterator() : index_rect_(kNonPositiveQuadrantIndexRect) { | 429 TilingData::Iterator::Iterator() : index_rect_(kNonPositiveQuadrantIndexRect) { |
386 done(); | 430 done(); |
387 } | 431 } |
388 | 432 |
389 TilingData::Iterator::Iterator(const TilingData* tiling_data, | 433 TilingData::Iterator::Iterator(const TilingData* tiling_data, |
390 const gfx::Rect& consider_rect, | 434 const gfx::Rect& consider_rect, |
391 bool include_borders) | 435 bool include_borders) |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 } | 602 } |
559 | 603 |
560 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { | 604 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { |
561 done(); | 605 done(); |
562 } | 606 } |
563 | 607 |
564 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( | 608 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( |
565 const TilingData* tiling_data, | 609 const TilingData* tiling_data, |
566 const gfx::Rect& consider_rect, | 610 const gfx::Rect& consider_rect, |
567 const gfx::Rect& ignore_rect, | 611 const gfx::Rect& ignore_rect, |
568 const gfx::Rect& center_rect) | 612 const gfx::Rect& center_rect, |
569 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) { | 613 const bool use_pyramid_sequence) |
| 614 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), |
| 615 use_pyramid_sequence_(use_pyramid_sequence) { |
570 if (!HasConsiderRect()) { | 616 if (!HasConsiderRect()) { |
571 done(); | 617 done(); |
572 return; | 618 return; |
573 } | 619 } |
574 | 620 |
575 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); | 621 if (use_pyramid_sequence_) { |
576 DCHECK(around_index_rect.is_valid()); | 622 IndexRect around_index_rect = |
| 623 tiling_data->TileAroundAbsoluteIndexRect(center_rect); |
577 | 624 |
578 spiral_iterator_ = SpiralIterator(around_index_rect, consider_index_rect_, | 625 DCHECK(around_index_rect.is_valid()); |
579 ignore_index_rect_); | 626 pyramid_sequence_ = PyramidSequence( |
| 627 around_index_rect, consider_index_rect_, ignore_index_rect_, |
| 628 tiling_data->max_texture_size().width(), |
| 629 tiling_data->max_texture_size().height()); |
580 | 630 |
581 if (!spiral_iterator_) { | 631 iterator_ = pyramid_sequence_.Begin(); |
582 done(); | 632 |
583 return; | 633 if (!iterator_) { |
| 634 done(); |
| 635 return; |
| 636 } |
| 637 |
| 638 index_x_ = iterator_.index_x(); |
| 639 index_y_ = iterator_.index_y(); |
| 640 DCHECK(consider_index_rect_.Contains(index_x_, index_y_) && |
| 641 !ignore_index_rect_.Contains(index_x_, index_y_)); |
| 642 } else { |
| 643 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); |
| 644 DCHECK(around_index_rect.is_valid()); |
| 645 |
| 646 spiral_iterator_ = SpiralIterator(around_index_rect, consider_index_rect_, |
| 647 ignore_index_rect_); |
| 648 |
| 649 if (!spiral_iterator_) { |
| 650 done(); |
| 651 return; |
| 652 } |
| 653 |
| 654 index_x_ = spiral_iterator_.index_x(); |
| 655 index_y_ = spiral_iterator_.index_y(); |
584 } | 656 } |
| 657 } |
585 | 658 |
586 index_x_ = spiral_iterator_.index_x(); | 659 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( |
587 index_y_ = spiral_iterator_.index_y(); | 660 const TilingData::SpiralDifferenceIterator& other) = default; |
588 } | 661 |
| 662 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( |
| 663 TilingData::SpiralDifferenceIterator&& other) = default; |
| 664 |
| 665 TilingData::SpiralDifferenceIterator::~SpiralDifferenceIterator() {} |
| 666 |
| 667 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: |
| 668 operator=(const TilingData::SpiralDifferenceIterator& other) = default; |
| 669 |
| 670 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: |
| 671 operator=(TilingData::SpiralDifferenceIterator&& other) = default; |
589 | 672 |
590 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: | 673 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: |
591 operator++() { | 674 operator++() { |
592 ++spiral_iterator_; | 675 if (use_pyramid_sequence_) { |
| 676 ++iterator_; |
593 | 677 |
594 if (!spiral_iterator_) { | 678 if (!iterator_) { |
595 done(); | 679 done(); |
596 return *this; | 680 return *this; |
| 681 } |
| 682 |
| 683 index_x_ = iterator_.index_x(); |
| 684 index_y_ = iterator_.index_y(); |
| 685 } else { |
| 686 ++spiral_iterator_; |
| 687 |
| 688 if (!spiral_iterator_) { |
| 689 done(); |
| 690 return *this; |
| 691 } |
| 692 |
| 693 index_x_ = spiral_iterator_.index_x(); |
| 694 index_y_ = spiral_iterator_.index_y(); |
597 } | 695 } |
598 | 696 |
599 index_x_ = spiral_iterator_.index_x(); | |
600 index_y_ = spiral_iterator_.index_y(); | |
601 | |
602 return *this; | 697 return *this; |
603 } | 698 } |
604 | 699 |
605 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { | 700 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { |
606 done(); | 701 done(); |
607 } | 702 } |
608 | 703 |
609 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( | 704 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
610 const TilingData* tiling_data, | 705 const TilingData* tiling_data, |
611 const gfx::Rect& consider_rect, | 706 const gfx::Rect& consider_rect, |
612 const gfx::Rect& ignore_rect, | 707 const gfx::Rect& ignore_rect, |
613 const gfx::Rect& center_rect) | 708 const gfx::Rect& center_rect, |
614 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) { | 709 const bool use_pyramid_sequence) |
| 710 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), |
| 711 use_pyramid_sequence_(use_pyramid_sequence) { |
615 if (!HasConsiderRect()) { | 712 if (!HasConsiderRect()) { |
616 done(); | 713 done(); |
617 return; | 714 return; |
618 } | 715 } |
619 | 716 |
620 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); | 717 if (use_pyramid_sequence_) { |
621 DCHECK(around_index_rect.is_valid()); | 718 IndexRect around_index_rect = |
| 719 tiling_data->TileAroundAbsoluteIndexRect(center_rect); |
| 720 DCHECK(around_index_rect.is_valid()); |
| 721 pyramid_sequence_ = PyramidSequence( |
| 722 around_index_rect, consider_index_rect_, ignore_index_rect_, |
| 723 tiling_data->max_texture_size().width(), |
| 724 tiling_data->max_texture_size().height()); |
622 | 725 |
623 reverse_spiral_iterator_ = ReverseSpiralIterator( | 726 reverse_iterator_ = pyramid_sequence_.ReverseBegin(); |
624 around_index_rect, consider_index_rect_, ignore_index_rect_); | |
625 | 727 |
626 if (!reverse_spiral_iterator_) { | 728 if (!reverse_iterator_) { |
627 done(); | 729 done(); |
628 return; | 730 return; |
| 731 } |
| 732 |
| 733 index_x_ = reverse_iterator_.index_x(); |
| 734 index_y_ = reverse_iterator_.index_y(); |
| 735 DCHECK(consider_index_rect_.Contains(index_x_, index_y_) && |
| 736 !ignore_index_rect_.Contains(index_x_, index_y_)); |
| 737 } else { |
| 738 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); |
| 739 DCHECK(around_index_rect.is_valid()); |
| 740 |
| 741 reverse_spiral_iterator_ = ReverseSpiralIterator( |
| 742 around_index_rect, consider_index_rect_, ignore_index_rect_); |
| 743 |
| 744 if (!reverse_spiral_iterator_) { |
| 745 done(); |
| 746 return; |
| 747 } |
| 748 |
| 749 index_x_ = reverse_spiral_iterator_.index_x(); |
| 750 index_y_ = reverse_spiral_iterator_.index_y(); |
629 } | 751 } |
| 752 } |
630 | 753 |
631 index_x_ = reverse_spiral_iterator_.index_x(); | 754 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
632 index_y_ = reverse_spiral_iterator_.index_y(); | 755 const TilingData::ReverseSpiralDifferenceIterator& other) = default; |
633 } | 756 |
| 757 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
| 758 TilingData::ReverseSpiralDifferenceIterator&& other) = default; |
| 759 |
| 760 TilingData::ReverseSpiralDifferenceIterator:: |
| 761 ~ReverseSpiralDifferenceIterator() {} |
| 762 |
| 763 TilingData::ReverseSpiralDifferenceIterator& |
| 764 TilingData::ReverseSpiralDifferenceIterator::operator=( |
| 765 const TilingData::ReverseSpiralDifferenceIterator& other) = default; |
| 766 |
| 767 TilingData::ReverseSpiralDifferenceIterator& |
| 768 TilingData::ReverseSpiralDifferenceIterator::operator=( |
| 769 TilingData::ReverseSpiralDifferenceIterator&& other) = default; |
634 | 770 |
635 TilingData::ReverseSpiralDifferenceIterator& | 771 TilingData::ReverseSpiralDifferenceIterator& |
636 TilingData::ReverseSpiralDifferenceIterator:: | 772 TilingData::ReverseSpiralDifferenceIterator:: |
637 operator++() { | 773 operator++() { |
638 ++reverse_spiral_iterator_; | 774 if (use_pyramid_sequence_) { |
| 775 ++reverse_iterator_; |
639 | 776 |
640 if (!reverse_spiral_iterator_) { | 777 if (!reverse_iterator_) { |
641 done(); | 778 done(); |
642 return *this; | 779 return *this; |
| 780 } |
| 781 |
| 782 index_x_ = reverse_iterator_.index_x(); |
| 783 index_y_ = reverse_iterator_.index_y(); |
| 784 } else { |
| 785 ++reverse_spiral_iterator_; |
| 786 |
| 787 if (!reverse_spiral_iterator_) { |
| 788 done(); |
| 789 return *this; |
| 790 } |
| 791 |
| 792 index_x_ = reverse_spiral_iterator_.index_x(); |
| 793 index_y_ = reverse_spiral_iterator_.index_y(); |
643 } | 794 } |
644 | 795 |
645 index_x_ = reverse_spiral_iterator_.index_x(); | |
646 index_y_ = reverse_spiral_iterator_.index_y(); | |
647 | |
648 return *this; | 796 return *this; |
649 } | 797 } |
650 | 798 |
651 } // namespace cc | 799 } // namespace cc |
OLD | NEW |