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

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: tild Created 4 years, 6 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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 } 460 }
461 } 461 }
462 462
463 if (index_y_ > consider_bottom_) 463 if (index_y_ > consider_bottom_)
464 done(); 464 done();
465 } 465 }
466 466
467 return *this; 467 return *this;
468 } 468 }
469 469
470 TilingData::LDSequence::LDSequence(PyramidSequence traversal_seq,
471 PyramidSequence level_seq,
472 bool swapped,
473 int distance)
474 : traversal_seq_(traversal_seq), swapped_(swapped) {
475 LevelDistance level_distance;
476 level_distance.distance = 0;
477 int coverage = level_seq.GetCoverage();
478 for (int i = 0; i < coverage; ++i, level_distance.distance += distance) {
479 level_distance.level = level_seq.GetCurrent();
480 level_distances_.push_back(level_distance);
481 level_seq.Advance();
482 }
483
484 if (IsValid())
485 Reset();
486 }
487
488 TilingData::LDSequence::LDSequence(const TilingData::LDSequence& other) =
489 default;
490
491 TilingData::LDSequence::~LDSequence() = default;
492
493 int TilingData::LDSequence::GetIndexX() const {
494 return swapped_ ? current_level_index_ : current_seq_index_;
495 }
496
497 int TilingData::LDSequence::GetIndexY() const {
498 return swapped_ ? current_seq_index_ : current_level_index_;
499 }
500
501 int TilingData::LDSequence::GetTopDistance() {
502 DCHECK(level_distances_.size());
503 return level_distances_.front().distance;
504 }
505
506 bool TilingData::LDSequence::Advance() {
507 traversal_seq_.Advance();
508 if (!traversal_seq_.within_bounds()) {
509 level_distances_.erase(level_distances_.begin());
510 if (IsValid())
511 Reset();
512
513 return false;
514 }
515
516 current_seq_index_ = traversal_seq_.GetCurrent();
517 return true;
518 }
519
520 void TilingData::LDSequence::Reset() {
521 DCHECK(level_distances_.size());
522 current_seq_index_ = traversal_seq_.GetCurrent();
523 current_level_index_ = level_distances_.front().level;
524 }
525
470 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { 526 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() {
471 done(); 527 done();
472 } 528 }
473 529
474 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( 530 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
475 const TilingData* tiling_data, 531 const TilingData* tiling_data,
476 const gfx::Rect& consider_rect, 532 const gfx::Rect& consider_rect,
477 const gfx::Rect& ignore_rect, 533 const gfx::Rect& ignore_rect,
478 const gfx::Rect& center_rect) 534 const gfx::Rect& center_rect)
479 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), 535 : 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()) { 536 if (!HasConsiderRect()) {
487 done(); 537 done();
488 return; 538 return;
489 } 539 }
490 540
541 num_tiles_x_ = tiling_data->num_tiles_x();
542 num_tiles_y_ = tiling_data->num_tiles_y();
491 // Determine around left, such that it is between -1 and num_tiles_x. 543 // Determine around left, such that it is between -1 and num_tiles_x.
492 int around_left = 0; 544 int around_left = 0;
493 if (center_rect.x() < 0 || center_rect.IsEmpty()) 545 if (center_rect.x() < 0 || center_rect.IsEmpty())
494 around_left = -1; 546 around_left = -1;
495 else if (center_rect.x() >= tiling_data->tiling_size().width()) 547 else if (center_rect.x() >= tiling_data->tiling_size().width())
496 around_left = tiling_data->num_tiles_x(); 548 around_left = tiling_data->num_tiles_x();
497 else 549 else
498 around_left = tiling_data->TileXIndexFromSrcCoord(center_rect.x()); 550 around_left = tiling_data->TileXIndexFromSrcCoord(center_rect.x());
499 551
500 // Determine around top, such that it is between -1 and num_tiles_y. 552 // Determine around top, such that it is between -1 and num_tiles_y.
(...skipping 20 matching lines...) Expand all
521 int bottom_src_coord = center_rect.bottom() - 1; 573 int bottom_src_coord = center_rect.bottom() - 1;
522 int around_bottom = 0; 574 int around_bottom = 0;
523 if (bottom_src_coord < 0 || center_rect.IsEmpty()) { 575 if (bottom_src_coord < 0 || center_rect.IsEmpty()) {
524 around_bottom = -1; 576 around_bottom = -1;
525 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) { 577 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) {
526 around_bottom = tiling_data->num_tiles_y(); 578 around_bottom = tiling_data->num_tiles_y();
527 } else { 579 } else {
528 around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); 580 around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord);
529 } 581 }
530 582
531 vertical_step_count_ = around_bottom - around_top + 1; 583 int left_levels = around_left - consider_left_ + 1;
532 horizontal_step_count_ = around_right - around_left + 1; 584 int right_levels = consider_right_ - around_right + 1;
533 current_step_ = horizontal_step_count_ - 1; 585 int top_levels = around_top - consider_top_ + 1;
586 int bottom_levels = consider_bottom_ - around_bottom + 1;
534 587
535 index_x_ = around_right; 588 int width = tiling_data->max_texture_size().width();
536 index_y_ = around_bottom; 589 int height = tiling_data->max_texture_size().height();
590 int hypotenuse = std::sqrt(width * width + height * height); // support sp/dp
537 591
538 // The current index is the bottom right of the around rect, which is also 592 // U
539 // ignored. So we have to advance. 593 int start = around_bottom - 1;
594 int end = around_top + 1;
595 if (right_levels > 0 && valid_row(start) && valid_row(end)) {
596 ld_sequences_.push_back(TilingData::LDSequence(
597 PyramidSequence(PyramidSequence::Type::BACKWARD, start, end,
598 right_levels),
599 PyramidSequence(PyramidSequence::Type::FORWARD, around_right,
600 consider_right_, 1),
601 true, width));
602 }
603
604 // UL
vmpstr 2016/06/16 18:28:58 Expand comments please.
605 if (right_levels > 0 && top_levels > 0 && valid_column(around_right)) {
606 ld_sequences_.push_back(TilingData::LDSequence(
607 PyramidSequence(PyramidSequence::Type::DIAGONAL_FORWARD, around_right,
608 around_right, std::min(right_levels, top_levels)),
609 PyramidSequence(PyramidSequence::Type::BACKWARD, around_top,
610 consider_top_, 1),
611 false, hypotenuse));
612 }
613
614 // L
615 start = around_right - 1;
616 end = around_left + 1;
617 if (top_levels > 0 && valid_column(start) && valid_column(end)) {
618 ld_sequences_.push_back(
619 TilingData::LDSequence(PyramidSequence(PyramidSequence::Type::BACKWARD,
620 start, end, top_levels),
621 PyramidSequence(PyramidSequence::Type::BACKWARD,
622 around_top, consider_top_, 1),
623 false, height));
624 }
625
626 // LD
627 if (top_levels > 0 && left_levels > 0 && valid_column(around_left)) {
628 ld_sequences_.push_back(TilingData::LDSequence(
629 PyramidSequence(PyramidSequence::Type::DIAGONAL_BACKWARD, around_left,
630 around_left, std::min(top_levels, left_levels)),
631 PyramidSequence(PyramidSequence::Type::BACKWARD, around_top,
632 consider_top_, 1),
633 false, hypotenuse));
634 }
635
636 // D
637 start = around_top + 1;
638 end = around_bottom - 1;
639 if (left_levels > 0 && valid_row(start) && valid_row(end)) {
640 ld_sequences_.push_back(
641 TilingData::LDSequence(PyramidSequence(PyramidSequence::Type::FORWARD,
642 start, end, left_levels),
643 PyramidSequence(PyramidSequence::Type::BACKWARD,
644 around_left, consider_left_, 1),
645 true, width));
646 }
647
648 // DR
649 if (left_levels > 0 && bottom_levels > 0 && valid_column(around_left)) {
650 ld_sequences_.push_back(TilingData::LDSequence(
651 PyramidSequence(PyramidSequence::Type::DIAGONAL_BACKWARD, around_left,
652 around_left, std::min(left_levels, bottom_levels)),
653 PyramidSequence(PyramidSequence::Type::FORWARD, around_bottom,
654 consider_bottom_, 1),
655 false, hypotenuse));
656 }
657
658 // R
659 start = around_left + 1;
660 end = around_right - 1;
661 if (bottom_levels > 0 && valid_column(start) && valid_column(end)) {
662 ld_sequences_.push_back(TilingData::LDSequence(
663 PyramidSequence(PyramidSequence::Type::FORWARD, start, end,
664 bottom_levels),
665 PyramidSequence(PyramidSequence::Type::FORWARD, around_bottom,
666 consider_bottom_, 1),
667 false, height));
668 }
669
670 // RU
671 if (bottom_levels > 0 && right_levels > 0 && valid_column(around_right)) {
672 ld_sequences_.push_back(TilingData::LDSequence(
673 PyramidSequence(PyramidSequence::Type::DIAGONAL_FORWARD, around_right,
674 around_right, std::min(bottom_levels, right_levels)),
675 PyramidSequence(PyramidSequence::Type::FORWARD, around_bottom,
676 consider_bottom_, 1),
677 false, hypotenuse));
678 }
679
680 // Point to valid ld sequence.
681 current_ld_seq = GetNextLDSequence();
682
683 if (current_ld_seq == ld_sequences_.end()) {
684 done();
685 return;
686 }
687
688 // Point to valid indices or finish.
540 ++(*this); 689 ++(*this);
541 } 690 }
542 691
692 TilingData::SpiralDifferenceIterator::~SpiralDifferenceIterator() = default;
693
543 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator:: 694 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
544 operator++() { 695 operator++() {
545 int cannot_hit_consider_count = 0; 696 while (true) {
546 while (cannot_hit_consider_count < 4) { 697 if (current_ld_seq == ld_sequences_.end()) {
547 if (needs_direction_switch()) 698 done();
548 switch_direction(); 699 break; // Finished.
700 }
549 701
550 index_x_ += delta_x_; 702 DCHECK(current_ld_seq->IsValid());
551 index_y_ += delta_y_; 703 index_x_ = current_ld_seq->GetIndexX();
552 ++current_step_; 704 index_y_ = current_ld_seq->GetIndexY();
553 705
554 if (in_consider_rect()) { 706 if (in_consider_rect() && !in_ignore_rect())
555 cannot_hit_consider_count = 0; 707 break; // Got it.
556 708
557 if (!in_ignore_rect()) 709 if (!current_ld_seq->Advance())
558 break; 710 current_ld_seq = GetNextLDSequence();
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 } 711 }
626
627 if (cannot_hit_consider_count >= 4)
628 done();
629 return *this; 712 return *this;
630 } 713 }
631 714
632 bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const { 715 TilingData::LDSequence::List::iterator
633 return current_step_ >= current_step_count(); 716 TilingData::SpiralDifferenceIterator::GetNextLDSequence() {
634 } 717 ld_sequences_.erase(std::remove_if(ld_sequences_.begin(), ld_sequences_.end(),
718 [](const TilingData::LDSequence& path) {
719 return !path.IsValid();
720 }),
721 ld_sequences_.end());
635 722
636 void TilingData::SpiralDifferenceIterator::switch_direction() { 723 if (!ld_sequences_.size())
637 // Note that delta_x_ and delta_y_ always remain between -1 and 1. 724 return ld_sequences_.end();
638 int new_delta_x_ = delta_y_;
639 delta_y_ = -delta_x_;
640 delta_x_ = new_delta_x_;
641 725
642 current_step_ = 0; 726 TilingData::LDSequence::List::iterator min_distance_ld_seq_it =
643 direction_ = static_cast<Direction>((direction_ + 1) % 4); 727 ld_sequences_.begin();
644 728
645 if (direction_ == RIGHT || direction_ == LEFT) { 729 for (TilingData::LDSequence::List::iterator it = ld_sequences_.begin();
646 ++vertical_step_count_; 730 it != ld_sequences_.end(); ++it) {
647 ++horizontal_step_count_; 731 int distance = it->GetTopDistance();
732 if (distance == 0)
733 return it;
734
735 if (min_distance_ld_seq_it->GetTopDistance() > distance)
736 min_distance_ld_seq_it = it;
648 } 737 }
738
739 return min_distance_ld_seq_it;
649 } 740 }
650 741
651 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { 742 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
652 done(); 743 done();
653 } 744 }
654 745
655 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( 746 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
656 const TilingData* tiling_data, 747 const TilingData* tiling_data,
657 const gfx::Rect& consider_rect, 748 const gfx::Rect& consider_rect,
658 const gfx::Rect& ignore_rect, 749 const gfx::Rect& ignore_rect,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 949
859 // We should always end up in an around rect at some point. 950 // 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 951 // Since the direction is now vertical, we have to ensure that we will
861 // advance. 952 // advance.
862 DCHECK_GE(horizontal_step_count_, 1); 953 DCHECK_GE(horizontal_step_count_, 1);
863 DCHECK_GE(vertical_step_count_, 1); 954 DCHECK_GE(vertical_step_count_, 1);
864 } 955 }
865 } 956 }
866 957
867 } // namespace cc 958 } // namespace cc
OLDNEW
« cc/base/tiling_data.h ('K') | « cc/base/tiling_data.h ('k') | cc/cc.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698