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 "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 Loading... |
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(int x, |
| 72 int y) |
| 73 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(int x, |
| 84 int y) |
| 85 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 Loading... |
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 |
OLD | NEW |