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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 int TilingData::TileYIndexFromSrcCoord(int src_position) const { | 87 int TilingData::TileYIndexFromSrcCoord(int src_position) const { |
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 |
| 97 int TilingData::TileAbsoluteXIndexFromSrcCoord(int src_position) const { |
| 98 int inner_tile_width = max_texture_size_.width() - 2 * border_texels_; |
| 99 if (inner_tile_width <= 0) |
| 100 return 0; |
| 101 |
| 102 int max_width = inner_tile_width * num_tiles_x_ + 2 * border_texels_; |
| 103 if (src_position >= 0 && src_position < max_width) |
| 104 return TileXIndexFromSrcCoord(src_position); |
| 105 |
| 106 if (src_position >= max_width) |
| 107 return num_tiles_x_ + (src_position - max_width) / inner_tile_width; |
| 108 |
| 109 return (src_position + 1) / inner_tile_width - 1; |
| 110 } |
| 111 |
| 112 int TilingData::TileAbsoluteYIndexFromSrcCoord(int src_position) const { |
| 113 int inner_tile_height = max_texture_size_.height() - 2 * border_texels_; |
| 114 if (inner_tile_height <= 0) |
| 115 return 0; |
| 116 |
| 117 int max_height = inner_tile_height * num_tiles_y_ + 2 * border_texels_; |
| 118 if (src_position >= 0 && src_position < max_height) |
| 119 return TileYIndexFromSrcCoord(src_position); |
| 120 |
| 121 if (src_position >= max_height) |
| 122 return num_tiles_y_ + (src_position - max_height) / inner_tile_height; |
| 123 |
| 124 return (src_position + 1) / inner_tile_height - 1; |
| 125 } |
| 126 |
95 int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const { | 127 int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const { |
96 if (num_tiles_x_ <= 1) | 128 if (num_tiles_x_ <= 1) |
97 return 0; | 129 return 0; |
98 | 130 |
99 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); | 131 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); |
100 int inner_tile_size = max_texture_size_.width() - 2 * border_texels_; | 132 int inner_tile_size = max_texture_size_.width() - 2 * border_texels_; |
101 int x = (src_position - 2 * border_texels_) / inner_tile_size; | 133 int x = (src_position - 2 * border_texels_) / inner_tile_size; |
102 return std::min(std::max(x, 0), num_tiles_x_ - 1); | 134 return std::min(std::max(x, 0), num_tiles_x_ - 1); |
103 } | 135 } |
104 | 136 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 around_bottom = -1; | 201 around_bottom = -1; |
170 } else if (bottom_src_coord >= tiling_size().height()) { | 202 } else if (bottom_src_coord >= tiling_size().height()) { |
171 around_bottom = num_tiles_y(); | 203 around_bottom = num_tiles_y(); |
172 } else { | 204 } else { |
173 around_bottom = TileYIndexFromSrcCoord(bottom_src_coord); | 205 around_bottom = TileYIndexFromSrcCoord(bottom_src_coord); |
174 } | 206 } |
175 | 207 |
176 return IndexRect(around_left, around_right, around_top, around_bottom); | 208 return IndexRect(around_left, around_right, around_top, around_bottom); |
177 } | 209 } |
178 | 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 |
179 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( | 246 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( |
180 const gfx::Rect& rect) const { | 247 const gfx::Rect& rect) const { |
181 if (rect.IsEmpty() || has_empty_bounds()) | 248 if (rect.IsEmpty() || has_empty_bounds()) |
182 return gfx::Rect(); | 249 return gfx::Rect(); |
183 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) | 250 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) |
184 return gfx::Rect(); | 251 return gfx::Rect(); |
185 int index_x = TileXIndexFromSrcCoord(rect.x()); | 252 int index_x = TileXIndexFromSrcCoord(rect.x()); |
186 int index_y = TileYIndexFromSrcCoord(rect.y()); | 253 int index_y = TileYIndexFromSrcCoord(rect.y()); |
187 int index_right = TileXIndexFromSrcCoord(rect.right() - 1); | 254 int index_right = TileXIndexFromSrcCoord(rect.right() - 1); |
188 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... |
342 return gfx::Vector2d(left, top); | 409 return gfx::Vector2d(left, top); |
343 } | 410 } |
344 | 411 |
345 void TilingData::RecomputeNumTiles() { | 412 void TilingData::RecomputeNumTiles() { |
346 num_tiles_x_ = ComputeNumTiles( | 413 num_tiles_x_ = ComputeNumTiles( |
347 max_texture_size_.width(), tiling_size_.width(), border_texels_); | 414 max_texture_size_.width(), tiling_size_.width(), border_texels_); |
348 num_tiles_y_ = ComputeNumTiles( | 415 num_tiles_y_ = ComputeNumTiles( |
349 max_texture_size_.height(), tiling_size_.height(), border_texels_); | 416 max_texture_size_.height(), tiling_size_.height(), border_texels_); |
350 } | 417 } |
351 | 418 |
| 419 bool TilingData::IsPyramidSequenceEnabled() { |
| 420 return true; |
| 421 } |
| 422 |
352 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { | 423 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { |
353 } | 424 } |
354 | 425 |
355 TilingData::Iterator::Iterator() : index_rect_(kNonPositiveQuadrantIndexRect) { | 426 TilingData::Iterator::Iterator() : index_rect_(kNonPositiveQuadrantIndexRect) { |
356 done(); | 427 done(); |
357 } | 428 } |
358 | 429 |
359 TilingData::Iterator::Iterator(const TilingData* tiling_data, | 430 TilingData::Iterator::Iterator(const TilingData* tiling_data, |
360 const gfx::Rect& consider_rect, | 431 const gfx::Rect& consider_rect, |
361 bool include_borders) | 432 bool include_borders) |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 } | 599 } |
529 | 600 |
530 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { | 601 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { |
531 done(); | 602 done(); |
532 } | 603 } |
533 | 604 |
534 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( | 605 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( |
535 const TilingData* tiling_data, | 606 const TilingData* tiling_data, |
536 const gfx::Rect& consider_rect, | 607 const gfx::Rect& consider_rect, |
537 const gfx::Rect& ignore_rect, | 608 const gfx::Rect& ignore_rect, |
538 const gfx::Rect& center_rect) | 609 const gfx::Rect& center_rect, |
539 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) { | 610 const bool use_pyramid_sequence) |
| 611 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), |
| 612 use_pyramid_sequence_(use_pyramid_sequence) { |
540 if (!HasConsiderRect()) { | 613 if (!HasConsiderRect()) { |
541 done(); | 614 done(); |
542 return; | 615 return; |
543 } | 616 } |
544 | 617 |
545 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); | 618 if (use_pyramid_sequence_) { |
546 DCHECK(around_index_rect.is_valid()); | 619 IndexRect around_index_rect = |
| 620 tiling_data->TileAroundAbsoluteIndexRect(center_rect); |
547 | 621 |
548 spiral_iterator_ = SpiralIterator(around_index_rect, consider_index_rect_, | 622 DCHECK(around_index_rect.is_valid()); |
549 ignore_index_rect_); | 623 pyramid_sequence_ = PyramidSequence( |
| 624 around_index_rect, consider_index_rect_, ignore_index_rect_, |
| 625 tiling_data->max_texture_size().width(), |
| 626 tiling_data->max_texture_size().height()); |
550 | 627 |
551 if (!spiral_iterator_) { | 628 iterator_ = pyramid_sequence_.Begin(); |
552 done(); | 629 |
553 return; | 630 if (!iterator_) { |
| 631 done(); |
| 632 return; |
| 633 } |
| 634 |
| 635 index_x_ = iterator_.index_x(); |
| 636 index_y_ = iterator_.index_y(); |
| 637 DCHECK(consider_index_rect_.Contains(index_x_, index_y_) && |
| 638 !ignore_index_rect_.Contains(index_x_, index_y_)); |
| 639 } else { |
| 640 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); |
| 641 DCHECK(around_index_rect.is_valid()); |
| 642 |
| 643 spiral_iterator_ = SpiralIterator(around_index_rect, consider_index_rect_, |
| 644 ignore_index_rect_); |
| 645 |
| 646 if (!spiral_iterator_) { |
| 647 done(); |
| 648 return; |
| 649 } |
| 650 |
| 651 index_x_ = spiral_iterator_.index_x(); |
| 652 index_y_ = spiral_iterator_.index_y(); |
554 } | 653 } |
| 654 } |
555 | 655 |
556 index_x_ = spiral_iterator_.index_x(); | 656 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( |
557 index_y_ = spiral_iterator_.index_y(); | 657 const TilingData::SpiralDifferenceIterator& other) = default; |
558 } | 658 |
| 659 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( |
| 660 TilingData::SpiralDifferenceIterator&& other) = default; |
| 661 |
| 662 TilingData::SpiralDifferenceIterator::~SpiralDifferenceIterator() {} |
| 663 |
| 664 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: |
| 665 operator=(const TilingData::SpiralDifferenceIterator& other) = default; |
| 666 |
| 667 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: |
| 668 operator=(TilingData::SpiralDifferenceIterator&& other) = default; |
559 | 669 |
560 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: | 670 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: |
561 operator++() { | 671 operator++() { |
562 ++spiral_iterator_; | 672 if (use_pyramid_sequence_) { |
| 673 ++iterator_; |
563 | 674 |
564 if (!spiral_iterator_) { | 675 if (!iterator_) { |
565 done(); | 676 done(); |
566 return *this; | 677 return *this; |
| 678 } |
| 679 |
| 680 index_x_ = iterator_.index_x(); |
| 681 index_y_ = iterator_.index_y(); |
| 682 } else { |
| 683 ++spiral_iterator_; |
| 684 |
| 685 if (!spiral_iterator_) { |
| 686 done(); |
| 687 return *this; |
| 688 } |
| 689 |
| 690 index_x_ = spiral_iterator_.index_x(); |
| 691 index_y_ = spiral_iterator_.index_y(); |
567 } | 692 } |
568 | 693 |
569 index_x_ = spiral_iterator_.index_x(); | |
570 index_y_ = spiral_iterator_.index_y(); | |
571 | |
572 return *this; | 694 return *this; |
573 } | 695 } |
574 | 696 |
575 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { | 697 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { |
576 done(); | 698 done(); |
577 } | 699 } |
578 | 700 |
579 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( | 701 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
580 const TilingData* tiling_data, | 702 const TilingData* tiling_data, |
581 const gfx::Rect& consider_rect, | 703 const gfx::Rect& consider_rect, |
582 const gfx::Rect& ignore_rect, | 704 const gfx::Rect& ignore_rect, |
583 const gfx::Rect& center_rect) | 705 const gfx::Rect& center_rect, |
584 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) { | 706 const bool use_pyramid_sequence) |
| 707 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), |
| 708 use_pyramid_sequence_(use_pyramid_sequence) { |
585 if (!HasConsiderRect()) { | 709 if (!HasConsiderRect()) { |
586 done(); | 710 done(); |
587 return; | 711 return; |
588 } | 712 } |
589 | 713 |
590 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); | 714 if (use_pyramid_sequence_) { |
591 DCHECK(around_index_rect.is_valid()); | 715 IndexRect around_index_rect = |
| 716 tiling_data->TileAroundAbsoluteIndexRect(center_rect); |
| 717 DCHECK(around_index_rect.is_valid()); |
| 718 pyramid_sequence_ = PyramidSequence( |
| 719 around_index_rect, consider_index_rect_, ignore_index_rect_, |
| 720 tiling_data->max_texture_size().width(), |
| 721 tiling_data->max_texture_size().height()); |
592 | 722 |
593 reverse_spiral_iterator_ = ReverseSpiralIterator( | 723 reverse_iterator_ = pyramid_sequence_.ReverseBegin(); |
594 around_index_rect, consider_index_rect_, ignore_index_rect_); | |
595 | 724 |
596 if (!reverse_spiral_iterator_) { | 725 if (!reverse_iterator_) { |
597 done(); | 726 done(); |
598 return; | 727 return; |
| 728 } |
| 729 |
| 730 index_x_ = reverse_iterator_.index_x(); |
| 731 index_y_ = reverse_iterator_.index_y(); |
| 732 DCHECK(consider_index_rect_.Contains(index_x_, index_y_) && |
| 733 !ignore_index_rect_.Contains(index_x_, index_y_)); |
| 734 } else { |
| 735 IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect); |
| 736 DCHECK(around_index_rect.is_valid()); |
| 737 |
| 738 reverse_spiral_iterator_ = ReverseSpiralIterator( |
| 739 around_index_rect, consider_index_rect_, ignore_index_rect_); |
| 740 |
| 741 if (!reverse_spiral_iterator_) { |
| 742 done(); |
| 743 return; |
| 744 } |
| 745 |
| 746 index_x_ = reverse_spiral_iterator_.index_x(); |
| 747 index_y_ = reverse_spiral_iterator_.index_y(); |
599 } | 748 } |
| 749 } |
600 | 750 |
601 index_x_ = reverse_spiral_iterator_.index_x(); | 751 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
602 index_y_ = reverse_spiral_iterator_.index_y(); | 752 const TilingData::ReverseSpiralDifferenceIterator& other) = default; |
603 } | 753 |
| 754 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
| 755 TilingData::ReverseSpiralDifferenceIterator&& other) = default; |
| 756 |
| 757 TilingData::ReverseSpiralDifferenceIterator:: |
| 758 ~ReverseSpiralDifferenceIterator() {} |
| 759 |
| 760 TilingData::ReverseSpiralDifferenceIterator& |
| 761 TilingData::ReverseSpiralDifferenceIterator::operator=( |
| 762 const TilingData::ReverseSpiralDifferenceIterator& other) = default; |
| 763 |
| 764 TilingData::ReverseSpiralDifferenceIterator& |
| 765 TilingData::ReverseSpiralDifferenceIterator::operator=( |
| 766 TilingData::ReverseSpiralDifferenceIterator&& other) = default; |
604 | 767 |
605 TilingData::ReverseSpiralDifferenceIterator& | 768 TilingData::ReverseSpiralDifferenceIterator& |
606 TilingData::ReverseSpiralDifferenceIterator:: | 769 TilingData::ReverseSpiralDifferenceIterator:: |
607 operator++() { | 770 operator++() { |
608 ++reverse_spiral_iterator_; | 771 if (use_pyramid_sequence_) { |
| 772 ++reverse_iterator_; |
609 | 773 |
610 if (!reverse_spiral_iterator_) { | 774 if (!reverse_iterator_) { |
611 done(); | 775 done(); |
612 return *this; | 776 return *this; |
| 777 } |
| 778 |
| 779 index_x_ = reverse_iterator_.index_x(); |
| 780 index_y_ = reverse_iterator_.index_y(); |
| 781 } else { |
| 782 ++reverse_spiral_iterator_; |
| 783 |
| 784 if (!reverse_spiral_iterator_) { |
| 785 done(); |
| 786 return *this; |
| 787 } |
| 788 |
| 789 index_x_ = reverse_spiral_iterator_.index_x(); |
| 790 index_y_ = reverse_spiral_iterator_.index_y(); |
613 } | 791 } |
614 | 792 |
615 index_x_ = reverse_spiral_iterator_.index_x(); | |
616 index_y_ = reverse_spiral_iterator_.index_y(); | |
617 | |
618 return *this; | 793 return *this; |
619 } | 794 } |
620 | 795 |
621 } // namespace cc | 796 } // namespace cc |
OLD | NEW |