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

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

Issue 183123004: cc: Added a spiral difference iterator to tiling data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase + comments Created 6 years, 9 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 | Annotate | Revision Log
« 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 void TilingData::SetHasBorderTexels(bool has_border_texels) { 61 void TilingData::SetHasBorderTexels(bool has_border_texels) {
62 border_texels_ = has_border_texels ? 1 : 0; 62 border_texels_ = has_border_texels ? 1 : 0;
63 RecomputeNumTiles(); 63 RecomputeNumTiles();
64 } 64 }
65 65
66 void TilingData::SetBorderTexels(int border_texels) { 66 void TilingData::SetBorderTexels(int border_texels) {
67 border_texels_ = border_texels; 67 border_texels_ = border_texels;
68 RecomputeNumTiles(); 68 RecomputeNumTiles();
69 } 69 }
70 70
71 std::pair<int, int> TilingData::UnclampedFirstBorderTileIndexFromSrcCoord(
72 int x,
73 int y) const {
74 int inner_tile_width = max_texture_size_.width() - 2 * border_texels_;
75 int result_x = (x - 2 * border_texels_) / inner_tile_width;
76
77 int inner_tile_height = max_texture_size_.height() - 2 * border_texels_;
78 int result_y = (y - 2 * border_texels_) / inner_tile_height;
79
80 return std::make_pair(result_x, result_y);
81 }
82
83 std::pair<int, int> TilingData::UnclampedLastBorderTileIndexFromSrcCoord(
84 int x,
85 int y) const {
86 int inner_tile_width = max_texture_size_.width() - 2 * border_texels_;
87 int result_x = x / inner_tile_width;
88
89 int inner_tile_height = max_texture_size_.height() - 2 * border_texels_;
90 int result_y = y / inner_tile_height;
91
92 return std::make_pair(result_x, result_y);
93 }
94
71 int TilingData::TileXIndexFromSrcCoord(int src_position) const { 95 int TilingData::TileXIndexFromSrcCoord(int src_position) const {
72 if (num_tiles_x_ <= 1) 96 if (num_tiles_x_ <= 1)
73 return 0; 97 return 0;
74 98
75 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); 99 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0);
76 int x = (src_position - border_texels_) / 100 int x = (src_position - border_texels_) /
77 (max_texture_size_.width() - 2 * border_texels_); 101 (max_texture_size_.width() - 2 * border_texels_);
78 return std::min(std::max(x, 0), num_tiles_x_ - 1); 102 return std::min(std::max(x, 0), num_tiles_x_ - 1);
79 } 103 }
80 104
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 426 }
403 } 427 }
404 428
405 if (index_y_ > consider_bottom_) 429 if (index_y_ > consider_bottom_)
406 done(); 430 done();
407 } 431 }
408 432
409 return *this; 433 return *this;
410 } 434 }
411 435
436 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
437 const TilingData* tiling_data,
438 const gfx::Rect& consider_rect,
439 const gfx::Rect& ignore_rect,
440 const gfx::Rect& center_rect)
441 : BaseIterator(tiling_data),
442 consider_left_(-1),
443 consider_top_(-1),
444 consider_right_(-1),
445 consider_bottom_(-1),
446 ignore_left_(-1),
447 ignore_top_(-1),
448 ignore_right_(-1),
449 ignore_bottom_(-1),
450 direction_(RIGHT),
451 delta_x_(1),
452 delta_y_(0),
453 current_step_(0),
454 horizontal_step_count_(0),
455 vertical_step_count_(0) {
456 if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
457 done();
458 return;
459 }
460
461 gfx::Rect bounds(tiling_data_->total_size());
462 gfx::Rect consider(consider_rect);
463 gfx::Rect ignore(ignore_rect);
464 gfx::Rect center(center_rect);
465 consider.Intersect(bounds);
466 ignore.Intersect(bounds);
467 if (consider.IsEmpty()) {
468 done();
469 return;
470 }
471
472 consider_left_ =
473 tiling_data_->FirstBorderTileXIndexFromSrcCoord(consider.x());
474 consider_top_ = tiling_data_->FirstBorderTileYIndexFromSrcCoord(consider.y());
475 consider_right_ =
476 tiling_data_->LastBorderTileXIndexFromSrcCoord(consider.right() - 1);
477 consider_bottom_ =
478 tiling_data_->LastBorderTileYIndexFromSrcCoord(consider.bottom() - 1);
479
480 if (!ignore.IsEmpty()) {
481 ignore_left_ = tiling_data_->FirstBorderTileXIndexFromSrcCoord(ignore.x());
482 ignore_top_ = tiling_data_->FirstBorderTileYIndexFromSrcCoord(ignore.y());
483 ignore_right_ =
484 tiling_data_->LastBorderTileXIndexFromSrcCoord(ignore.right() - 1);
485 ignore_bottom_ =
486 tiling_data_->LastBorderTileYIndexFromSrcCoord(ignore.bottom() - 1);
487
488 // Clamp ignore indices to consider indices.
489 ignore_left_ = std::max(ignore_left_, consider_left_);
490 ignore_top_ = std::max(ignore_top_, consider_top_);
491 ignore_right_ = std::min(ignore_right_, consider_right_);
492 ignore_bottom_ = std::min(ignore_bottom_, consider_bottom_);
493 }
494
495 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ &&
496 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) {
497 done();
498 return;
499 }
500
501 std::pair<int, int> around_left_top =
502 tiling_data->UnclampedFirstBorderTileIndexFromSrcCoord(center.x(),
503 center.y());
504 std::pair<int, int> around_right_bottom =
505 tiling_data->UnclampedLastBorderTileIndexFromSrcCoord(
506 center.right() - 1, center.bottom() - 1);
507
508 if (center.IsEmpty()) {
509 around_left_top = std::make_pair(-1, -1);
510 around_right_bottom = std::make_pair(-1, -1);
511 }
512
513 int around_left = std::max(
514 -1, std::min(tiling_data_->num_tiles_x(), around_left_top.first));
515 int around_top = std::max(
516 -1, std::min(tiling_data_->num_tiles_y(), around_left_top.second));
517 int around_right = std::max(
518 -1, std::min(tiling_data_->num_tiles_x(), around_right_bottom.first));
519 int around_bottom = std::max(
520 -1, std::min(tiling_data_->num_tiles_y(), around_right_bottom.second));
521
522 vertical_step_count_ = around_bottom - around_top + 1;
523 horizontal_step_count_ = around_right - around_left + 1;
524 current_step_ = horizontal_step_count_ - 1;
525
526 index_x_ = around_right;
527 index_y_ = around_bottom;
528
529 // The current index is the bottom right of the around rect, which is also
530 // ignored. So we have to advance.
531 ++(*this);
532 }
533
534 TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
535 operator++() {
536 int cannot_hit_consider_count = 0;
537 while (cannot_hit_consider_count < 4) {
538 if (needs_direction_switch())
539 switch_direction();
540
541 index_x_ += delta_x_;
542 index_y_ += delta_y_;
543 ++current_step_;
544
545 if (in_consider_rect()) {
546 cannot_hit_consider_count = 0;
547
548 if (!in_ignore_rect())
549 break;
550
551 // Steps needed to reach the very edge of the ignore rect, while remaining
552 // inside (so that the continue would take us outside).
553 int steps_to_edge = 0;
554 switch (direction_) {
555 case UP:
556 steps_to_edge = index_y_ - ignore_top_;
557 break;
558 case LEFT:
559 steps_to_edge = index_x_ - ignore_left_;
560 break;
561 case DOWN:
562 steps_to_edge = ignore_bottom_ - index_y_;
563 break;
564 case RIGHT:
565 steps_to_edge = ignore_right_ - index_x_;
566 break;
567 }
568
569 // We need to switch directions in |max_steps|.
570 int max_steps = current_step_count() - current_step_;
571
572 int steps_to_take = std::min(steps_to_edge, max_steps);
573 DCHECK_GE(steps_to_take, 0);
574
575 index_x_ += steps_to_take * delta_x_;
576 index_y_ += steps_to_take * delta_y_;
577 current_step_ += steps_to_take;
578 } else {
579 int max_steps = current_step_count() - current_step_;
580 int steps_to_take = max_steps;
581 bool can_hit_consider_rect = false;
582 switch (direction_) {
583 case UP:
584 if (valid_column() && consider_bottom_ < index_y_)
585 steps_to_take = index_y_ - consider_bottom_ - 1;
586 can_hit_consider_rect |= consider_right_ >= index_x_;
587 break;
588 case LEFT:
589 if (valid_row() && consider_right_ < index_x_)
590 steps_to_take = index_x_ - consider_right_ - 1;
591 can_hit_consider_rect |= consider_top_ <= index_y_;
592 break;
593 case DOWN:
594 if (valid_column() && consider_top_ > index_y_)
595 steps_to_take = consider_top_ - index_y_ - 1;
596 can_hit_consider_rect |= consider_left_ <= index_x_;
597 break;
598 case RIGHT:
599 if (valid_row() && consider_left_ > index_x_)
600 steps_to_take = consider_left_ - index_x_ - 1;
601 can_hit_consider_rect |= consider_bottom_ >= index_y_;
602 break;
603 }
604 steps_to_take = std::min(steps_to_take, max_steps);
605 DCHECK_GE(steps_to_take, 0);
606
607 index_x_ += steps_to_take * delta_x_;
608 index_y_ += steps_to_take * delta_y_;
609 current_step_ += steps_to_take;
610
611 if (can_hit_consider_rect)
612 cannot_hit_consider_count = 0;
613 else
614 ++cannot_hit_consider_count;
615 }
616 }
617
618 if (cannot_hit_consider_count >= 4)
619 done();
620 return *this;
621 }
622
623 bool TilingData::SpiralDifferenceIterator::needs_direction_switch() const {
624 return current_step_ >= current_step_count();
625 }
626
627 void TilingData::SpiralDifferenceIterator::switch_direction() {
628 int new_delta_x_ = delta_y_;
629 delta_y_ = -delta_x_;
630 delta_x_ = new_delta_x_;
631
632 current_step_ = 0;
633 direction_ = static_cast<Direction>((direction_ + 1) % 4);
634
635 if (direction_ == RIGHT || direction_ == LEFT) {
636 ++vertical_step_count_;
637 ++horizontal_step_count_;
638 }
639 }
640
412 } // namespace cc 641 } // 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