| 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/geometry/rect.h" | 9 #include "ui/gfx/geometry/rect.h" |
| 10 #include "ui/gfx/geometry/vector2d.h" | 10 #include "ui/gfx/geometry/vector2d.h" |
| 11 | 11 |
| 12 namespace cc { | 12 namespace cc { |
| 13 | 13 |
| 14 namespace { |
| 15 // IndexRect which is at left top corner of the positive quadrant. |
| 16 const IndexRect kNonPositiveQuadrantIndexRect(-1, -1, -1, -1); |
| 17 } |
| 18 |
| 14 static int ComputeNumTiles(int max_texture_size, | 19 static int ComputeNumTiles(int max_texture_size, |
| 15 int total_size, | 20 int total_size, |
| 16 int border_texels) { | 21 int border_texels) { |
| 17 if (max_texture_size - 2 * border_texels <= 0) | 22 if (max_texture_size - 2 * border_texels <= 0) |
| 18 return total_size > 0 && max_texture_size >= total_size ? 1 : 0; | 23 return total_size > 0 && max_texture_size >= total_size ? 1 : 0; |
| 19 | 24 |
| 20 int num_tiles = std::max(1, | 25 int num_tiles = std::max(1, |
| 21 1 + (total_size - 1 - 2 * border_texels) / | 26 1 + (total_size - 1 - 2 * border_texels) / |
| 22 (max_texture_size - 2 * border_texels)); | 27 (max_texture_size - 2 * border_texels)); |
| 23 return total_size > 0 ? num_tiles : 0; | 28 return total_size > 0 ? num_tiles : 0; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 void TilingData::RecomputeNumTiles() { | 294 void TilingData::RecomputeNumTiles() { |
| 290 num_tiles_x_ = ComputeNumTiles( | 295 num_tiles_x_ = ComputeNumTiles( |
| 291 max_texture_size_.width(), tiling_size_.width(), border_texels_); | 296 max_texture_size_.width(), tiling_size_.width(), border_texels_); |
| 292 num_tiles_y_ = ComputeNumTiles( | 297 num_tiles_y_ = ComputeNumTiles( |
| 293 max_texture_size_.height(), tiling_size_.height(), border_texels_); | 298 max_texture_size_.height(), tiling_size_.height(), border_texels_); |
| 294 } | 299 } |
| 295 | 300 |
| 296 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { | 301 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { |
| 297 } | 302 } |
| 298 | 303 |
| 299 TilingData::Iterator::Iterator() { | 304 TilingData::Iterator::Iterator() : index_rect_(kNonPositiveQuadrantIndexRect) { |
| 300 done(); | 305 done(); |
| 301 } | 306 } |
| 302 | 307 |
| 303 TilingData::Iterator::Iterator(const TilingData* tiling_data, | 308 TilingData::Iterator::Iterator(const TilingData* tiling_data, |
| 304 const gfx::Rect& consider_rect, | 309 const gfx::Rect& consider_rect, |
| 305 bool include_borders) | 310 bool include_borders) |
| 306 : left_(-1), right_(-1), bottom_(-1) { | 311 : index_rect_(kNonPositiveQuadrantIndexRect) { |
| 307 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { | 312 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { |
| 308 done(); | 313 done(); |
| 309 return; | 314 return; |
| 310 } | 315 } |
| 311 | 316 |
| 312 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); | 317 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); |
| 313 gfx::Rect rect(consider_rect); | 318 gfx::Rect rect(consider_rect); |
| 314 rect.Intersect(tiling_bounds_rect); | 319 rect.Intersect(tiling_bounds_rect); |
| 315 | 320 |
| 316 gfx::Rect top_left_tile; | 321 gfx::Rect top_left_tile; |
| 317 if (include_borders) { | 322 if (include_borders) { |
| 318 index_x_ = tiling_data->FirstBorderTileXIndexFromSrcCoord(rect.x()); | 323 index_x_ = tiling_data->FirstBorderTileXIndexFromSrcCoord(rect.x()); |
| 319 index_y_ = tiling_data->FirstBorderTileYIndexFromSrcCoord(rect.y()); | 324 index_y_ = tiling_data->FirstBorderTileYIndexFromSrcCoord(rect.y()); |
| 320 right_ = tiling_data->LastBorderTileXIndexFromSrcCoord(rect.right() - 1); | 325 index_rect_ = IndexRect( |
| 321 bottom_ = tiling_data->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1); | 326 index_x_, |
| 327 tiling_data->LastBorderTileXIndexFromSrcCoord(rect.right() - 1), |
| 328 index_y_, |
| 329 tiling_data->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1)); |
| 330 DCHECK(index_rect_.is_valid()); |
| 322 top_left_tile = tiling_data->TileBoundsWithBorder(index_x_, index_y_); | 331 top_left_tile = tiling_data->TileBoundsWithBorder(index_x_, index_y_); |
| 323 } else { | 332 } else { |
| 324 index_x_ = tiling_data->TileXIndexFromSrcCoord(rect.x()); | 333 index_x_ = tiling_data->TileXIndexFromSrcCoord(rect.x()); |
| 325 index_y_ = tiling_data->TileYIndexFromSrcCoord(rect.y()); | 334 index_y_ = tiling_data->TileYIndexFromSrcCoord(rect.y()); |
| 326 right_ = tiling_data->TileXIndexFromSrcCoord(rect.right() - 1); | 335 index_rect_ = IndexRect( |
| 327 bottom_ = tiling_data->TileYIndexFromSrcCoord(rect.bottom() - 1); | 336 index_x_, tiling_data->TileXIndexFromSrcCoord(rect.right() - 1), |
| 337 index_y_, tiling_data->TileYIndexFromSrcCoord(rect.bottom() - 1)); |
| 338 DCHECK(index_rect_.is_valid()); |
| 328 top_left_tile = tiling_data->TileBounds(index_x_, index_y_); | 339 top_left_tile = tiling_data->TileBounds(index_x_, index_y_); |
| 329 } | 340 } |
| 330 left_ = index_x_; | |
| 331 | 341 |
| 332 // Index functions always return valid indices, so explicitly check | 342 // Index functions always return valid indices, so explicitly check |
| 333 // for non-intersecting rects. | 343 // for non-intersecting rects. |
| 334 if (!top_left_tile.Intersects(rect)) | 344 if (!top_left_tile.Intersects(rect)) |
| 335 done(); | 345 done(); |
| 336 } | 346 } |
| 337 | 347 |
| 338 TilingData::Iterator& TilingData::Iterator::operator++() { | 348 TilingData::Iterator& TilingData::Iterator::operator++() { |
| 339 if (!*this) | 349 if (!*this) |
| 340 return *this; | 350 return *this; |
| 341 | 351 |
| 342 index_x_++; | 352 index_x_++; |
| 343 if (index_x_ > right_) { | 353 if (index_x_ > index_rect_.right()) { |
| 344 index_x_ = left_; | 354 index_x_ = index_rect_.left(); |
| 345 index_y_++; | 355 index_y_++; |
| 346 if (index_y_ > bottom_) | 356 if (index_y_ > index_rect_.bottom()) |
| 347 done(); | 357 done(); |
| 348 } | 358 } |
| 349 | 359 |
| 350 return *this; | 360 return *this; |
| 351 } | 361 } |
| 352 | 362 |
| 353 TilingData::BaseDifferenceIterator::BaseDifferenceIterator() { | 363 TilingData::BaseDifferenceIterator::BaseDifferenceIterator() |
| 364 : consider_index_rect_(kNonPositiveQuadrantIndexRect), |
| 365 ignore_index_rect_(kNonPositiveQuadrantIndexRect) { |
| 354 done(); | 366 done(); |
| 355 } | 367 } |
| 356 | 368 |
| 357 TilingData::BaseDifferenceIterator::BaseDifferenceIterator( | 369 TilingData::BaseDifferenceIterator::BaseDifferenceIterator( |
| 358 const TilingData* tiling_data, | 370 const TilingData* tiling_data, |
| 359 const gfx::Rect& consider_rect, | 371 const gfx::Rect& consider_rect, |
| 360 const gfx::Rect& ignore_rect) | 372 const gfx::Rect& ignore_rect) |
| 361 : consider_left_(-1), | 373 : consider_index_rect_(kNonPositiveQuadrantIndexRect), |
| 362 consider_top_(-1), | 374 ignore_index_rect_(kNonPositiveQuadrantIndexRect) { |
| 363 consider_right_(-1), | |
| 364 consider_bottom_(-1), | |
| 365 ignore_left_(-1), | |
| 366 ignore_top_(-1), | |
| 367 ignore_right_(-1), | |
| 368 ignore_bottom_(-1) { | |
| 369 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { | 375 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { |
| 370 done(); | 376 done(); |
| 371 return; | 377 return; |
| 372 } | 378 } |
| 373 | 379 |
| 374 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); | 380 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); |
| 375 gfx::Rect consider(consider_rect); | 381 gfx::Rect consider(consider_rect); |
| 376 consider.Intersect(tiling_bounds_rect); | 382 consider.Intersect(tiling_bounds_rect); |
| 377 | 383 |
| 378 if (consider.IsEmpty()) { | 384 if (consider.IsEmpty()) { |
| 379 done(); | 385 done(); |
| 380 return; | 386 return; |
| 381 } | 387 } |
| 382 | 388 |
| 383 consider_left_ = tiling_data->TileXIndexFromSrcCoord(consider.x()); | 389 consider_index_rect_ = |
| 384 consider_top_ = tiling_data->TileYIndexFromSrcCoord(consider.y()); | 390 IndexRect(tiling_data->TileXIndexFromSrcCoord(consider.x()), |
| 385 consider_right_ = tiling_data->TileXIndexFromSrcCoord(consider.right() - 1); | 391 tiling_data->TileXIndexFromSrcCoord(consider.right() - 1), |
| 386 consider_bottom_ = tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1); | 392 tiling_data->TileYIndexFromSrcCoord(consider.y()), |
| 393 tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1)); |
| 394 DCHECK(consider_index_rect_.is_valid()); |
| 387 | 395 |
| 388 gfx::Rect ignore(ignore_rect); | 396 gfx::Rect ignore(ignore_rect); |
| 389 ignore.Intersect(tiling_bounds_rect); | 397 ignore.Intersect(tiling_bounds_rect); |
| 390 | 398 |
| 391 if (!ignore.IsEmpty()) { | 399 if (!ignore.IsEmpty()) { |
| 392 ignore_left_ = tiling_data->TileXIndexFromSrcCoord(ignore.x()); | 400 ignore_index_rect_ = |
| 393 ignore_top_ = tiling_data->TileYIndexFromSrcCoord(ignore.y()); | 401 IndexRect(tiling_data->TileXIndexFromSrcCoord(ignore.x()), |
| 394 ignore_right_ = tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1); | 402 tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1), |
| 395 ignore_bottom_ = tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1); | 403 tiling_data->TileYIndexFromSrcCoord(ignore.y()), |
| 404 tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1)); |
| 405 DCHECK(ignore_index_rect_.is_valid()); |
| 396 | 406 |
| 397 // Clamp ignore indices to consider indices. | 407 // Clamp ignore indices to consider indices. |
| 398 ignore_left_ = std::max(ignore_left_, consider_left_); | 408 ignore_index_rect_.ClampTo(consider_index_rect_); |
| 399 ignore_top_ = std::max(ignore_top_, consider_top_); | |
| 400 ignore_right_ = std::min(ignore_right_, consider_right_); | |
| 401 ignore_bottom_ = std::min(ignore_bottom_, consider_bottom_); | |
| 402 | 409 |
| 403 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ && | 410 // If ignore rect is invalid, reset. |
| 404 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) { | 411 if (!ignore_index_rect_.is_valid()) |
| 405 consider_left_ = consider_top_ = consider_right_ = consider_bottom_ = -1; | 412 ignore_index_rect_ = kNonPositiveQuadrantIndexRect; |
| 413 |
| 414 if (ignore_index_rect_ == consider_index_rect_) { |
| 415 consider_index_rect_ = kNonPositiveQuadrantIndexRect; |
| 406 done(); | 416 done(); |
| 407 return; | 417 return; |
| 408 } | 418 } |
| 409 } | 419 } |
| 410 } | 420 } |
| 411 | 421 |
| 412 bool TilingData::BaseDifferenceIterator::HasConsiderRect() const { | 422 bool TilingData::BaseDifferenceIterator::HasConsiderRect() const { |
| 413 // Consider indices are either all valid or all equal to -1. | 423 // Consider indices are either all valid or all equal to -1. |
| 414 DCHECK((0 <= consider_left_ && consider_left_ <= consider_right_ && | 424 DCHECK(consider_index_rect_.is_in_positive_quadrant() || |
| 415 0 <= consider_top_ && consider_top_ <= consider_bottom_) || | 425 consider_index_rect_ == kNonPositiveQuadrantIndexRect); |
| 416 (consider_left_ == -1 && consider_top_ == -1 && | 426 return consider_index_rect_.left() != -1; |
| 417 consider_right_ == -1 && consider_bottom_ == -1)); | |
| 418 return consider_left_ != -1; | |
| 419 } | 427 } |
| 420 | 428 |
| 421 TilingData::DifferenceIterator::DifferenceIterator() { | 429 TilingData::DifferenceIterator::DifferenceIterator() { |
| 422 } | 430 } |
| 423 | 431 |
| 424 TilingData::DifferenceIterator::DifferenceIterator( | 432 TilingData::DifferenceIterator::DifferenceIterator( |
| 425 const TilingData* tiling_data, | 433 const TilingData* tiling_data, |
| 426 const gfx::Rect& consider_rect, | 434 const gfx::Rect& consider_rect, |
| 427 const gfx::Rect& ignore_rect) | 435 const gfx::Rect& ignore_rect) |
| 428 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) { | 436 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) { |
| 429 if (!HasConsiderRect()) { | 437 if (!HasConsiderRect()) { |
| 430 done(); | 438 done(); |
| 431 return; | 439 return; |
| 432 } | 440 } |
| 433 | 441 |
| 434 index_x_ = consider_left_; | 442 index_x_ = consider_index_rect_.left(); |
| 435 index_y_ = consider_top_; | 443 index_y_ = consider_index_rect_.top(); |
| 436 | 444 |
| 437 if (in_ignore_rect()) | 445 if (ignore_index_rect_.Contains(index_x_, index_y_)) |
| 438 ++(*this); | 446 ++(*this); |
| 439 } | 447 } |
| 440 | 448 |
| 441 TilingData::DifferenceIterator& TilingData::DifferenceIterator::operator++() { | 449 TilingData::DifferenceIterator& TilingData::DifferenceIterator::operator++() { |
| 442 if (!*this) | 450 if (!*this) |
| 443 return *this; | 451 return *this; |
| 444 | 452 |
| 445 index_x_++; | 453 index_x_++; |
| 446 if (in_ignore_rect()) | 454 if (ignore_index_rect_.Contains(index_x_, index_y_)) |
| 447 index_x_ = ignore_right_ + 1; | 455 index_x_ = ignore_index_rect_.right() + 1; |
| 448 | 456 |
| 449 if (index_x_ > consider_right_) { | 457 if (index_x_ > consider_index_rect_.right()) { |
| 450 index_x_ = consider_left_; | 458 index_x_ = consider_index_rect_.left(); |
| 451 index_y_++; | 459 index_y_++; |
| 452 | 460 |
| 453 if (in_ignore_rect()) { | 461 if (ignore_index_rect_.Contains(index_x_, index_y_)) { |
| 454 index_x_ = ignore_right_ + 1; | 462 index_x_ = ignore_index_rect_.right() + 1; |
| 455 // If the ignore rect spans the whole consider rect horizontally, then | 463 // If the ignore rect spans the whole consider rect horizontally, then |
| 456 // ignore_right + 1 will be out of bounds. | 464 // ignore_right + 1 will be out of bounds. |
| 457 if (in_ignore_rect() || index_x_ > consider_right_) { | 465 if (ignore_index_rect_.Contains(index_x_, index_y_) || |
| 458 index_y_ = ignore_bottom_ + 1; | 466 index_x_ > consider_index_rect_.right()) { |
| 459 index_x_ = consider_left_; | 467 index_y_ = ignore_index_rect_.bottom() + 1; |
| 468 index_x_ = consider_index_rect_.left(); |
| 460 } | 469 } |
| 461 } | 470 } |
| 462 | 471 |
| 463 if (index_y_ > consider_bottom_) | 472 if (index_y_ > consider_index_rect_.bottom()) |
| 464 done(); | 473 done(); |
| 465 } | 474 } |
| 466 | 475 |
| 467 return *this; | 476 return *this; |
| 468 } | 477 } |
| 469 | 478 |
| 470 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { | 479 TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() { |
| 471 done(); | 480 done(); |
| 472 } | 481 } |
| 473 | 482 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 operator++() { | 553 operator++() { |
| 545 int cannot_hit_consider_count = 0; | 554 int cannot_hit_consider_count = 0; |
| 546 while (cannot_hit_consider_count < 4) { | 555 while (cannot_hit_consider_count < 4) { |
| 547 if (needs_direction_switch()) | 556 if (needs_direction_switch()) |
| 548 switch_direction(); | 557 switch_direction(); |
| 549 | 558 |
| 550 index_x_ += delta_x_; | 559 index_x_ += delta_x_; |
| 551 index_y_ += delta_y_; | 560 index_y_ += delta_y_; |
| 552 ++current_step_; | 561 ++current_step_; |
| 553 | 562 |
| 554 if (in_consider_rect()) { | 563 if (consider_index_rect_.Contains(index_x_, index_y_)) { |
| 555 cannot_hit_consider_count = 0; | 564 cannot_hit_consider_count = 0; |
| 556 | 565 |
| 557 if (!in_ignore_rect()) | 566 if (!ignore_index_rect_.Contains(index_x_, index_y_)) |
| 558 break; | 567 break; |
| 559 | 568 |
| 560 // Steps needed to reach the very edge of the ignore rect, while remaining | 569 // Steps needed to reach the very edge of the ignore rect, while remaining |
| 561 // inside (so that the continue would take us outside). | 570 // inside (so that the continue would take us outside). |
| 562 int steps_to_edge = 0; | 571 int steps_to_edge = 0; |
| 563 switch (direction_) { | 572 switch (direction_) { |
| 564 case UP: | 573 case UP: |
| 565 steps_to_edge = index_y_ - ignore_top_; | 574 steps_to_edge = index_y_ - ignore_index_rect_.top(); |
| 566 break; | 575 break; |
| 567 case LEFT: | 576 case LEFT: |
| 568 steps_to_edge = index_x_ - ignore_left_; | 577 steps_to_edge = index_x_ - ignore_index_rect_.left(); |
| 569 break; | 578 break; |
| 570 case DOWN: | 579 case DOWN: |
| 571 steps_to_edge = ignore_bottom_ - index_y_; | 580 steps_to_edge = ignore_index_rect_.bottom() - index_y_; |
| 572 break; | 581 break; |
| 573 case RIGHT: | 582 case RIGHT: |
| 574 steps_to_edge = ignore_right_ - index_x_; | 583 steps_to_edge = ignore_index_rect_.right() - index_x_; |
| 575 break; | 584 break; |
| 576 } | 585 } |
| 577 | 586 |
| 578 // We need to switch directions in |max_steps|. | 587 // We need to switch directions in |max_steps|. |
| 579 int max_steps = current_step_count() - current_step_; | 588 int max_steps = current_step_count() - current_step_; |
| 580 | 589 |
| 581 int steps_to_take = std::min(steps_to_edge, max_steps); | 590 int steps_to_take = std::min(steps_to_edge, max_steps); |
| 582 DCHECK_GE(steps_to_take, 0); | 591 DCHECK_GE(steps_to_take, 0); |
| 583 | 592 |
| 584 index_x_ += steps_to_take * delta_x_; | 593 index_x_ += steps_to_take * delta_x_; |
| 585 index_y_ += steps_to_take * delta_y_; | 594 index_y_ += steps_to_take * delta_y_; |
| 586 current_step_ += steps_to_take; | 595 current_step_ += steps_to_take; |
| 587 } else { | 596 } else { |
| 588 int max_steps = current_step_count() - current_step_; | 597 int max_steps = current_step_count() - current_step_; |
| 589 int steps_to_take = max_steps; | 598 int steps_to_take = max_steps; |
| 590 bool can_hit_consider_rect = false; | 599 bool can_hit_consider_rect = false; |
| 591 switch (direction_) { | 600 switch (direction_) { |
| 592 case UP: | 601 case UP: |
| 593 if (valid_column() && consider_bottom_ < index_y_) | 602 if (consider_index_rect_.valid_column(index_x_) && |
| 594 steps_to_take = index_y_ - consider_bottom_ - 1; | 603 consider_index_rect_.bottom() < index_y_) |
| 595 can_hit_consider_rect |= consider_right_ >= index_x_; | 604 steps_to_take = index_y_ - consider_index_rect_.bottom() - 1; |
| 605 can_hit_consider_rect |= consider_index_rect_.right() >= index_x_; |
| 596 break; | 606 break; |
| 597 case LEFT: | 607 case LEFT: |
| 598 if (valid_row() && consider_right_ < index_x_) | 608 if (consider_index_rect_.valid_row(index_y_) && |
| 599 steps_to_take = index_x_ - consider_right_ - 1; | 609 consider_index_rect_.right() < index_x_) |
| 600 can_hit_consider_rect |= consider_top_ <= index_y_; | 610 steps_to_take = index_x_ - consider_index_rect_.right() - 1; |
| 611 can_hit_consider_rect |= consider_index_rect_.top() <= index_y_; |
| 601 break; | 612 break; |
| 602 case DOWN: | 613 case DOWN: |
| 603 if (valid_column() && consider_top_ > index_y_) | 614 if (consider_index_rect_.valid_column(index_x_) && |
| 604 steps_to_take = consider_top_ - index_y_ - 1; | 615 consider_index_rect_.top() > index_y_) |
| 605 can_hit_consider_rect |= consider_left_ <= index_x_; | 616 steps_to_take = consider_index_rect_.top() - index_y_ - 1; |
| 617 can_hit_consider_rect |= consider_index_rect_.left() <= index_x_; |
| 606 break; | 618 break; |
| 607 case RIGHT: | 619 case RIGHT: |
| 608 if (valid_row() && consider_left_ > index_x_) | 620 if (consider_index_rect_.valid_row(index_y_) && |
| 609 steps_to_take = consider_left_ - index_x_ - 1; | 621 consider_index_rect_.left() > index_x_) |
| 610 can_hit_consider_rect |= consider_bottom_ >= index_y_; | 622 steps_to_take = consider_index_rect_.left() - index_x_ - 1; |
| 623 can_hit_consider_rect |= consider_index_rect_.bottom() >= index_y_; |
| 611 break; | 624 break; |
| 612 } | 625 } |
| 613 steps_to_take = std::min(steps_to_take, max_steps); | 626 steps_to_take = std::min(steps_to_take, max_steps); |
| 614 DCHECK_GE(steps_to_take, 0); | 627 DCHECK_GE(steps_to_take, 0); |
| 615 | 628 |
| 616 index_x_ += steps_to_take * delta_x_; | 629 index_x_ += steps_to_take * delta_x_; |
| 617 index_y_ += steps_to_take * delta_y_; | 630 index_y_ += steps_to_take * delta_y_; |
| 618 current_step_ += steps_to_take; | 631 current_step_ += steps_to_take; |
| 619 | 632 |
| 620 if (can_hit_consider_rect) | 633 if (can_hit_consider_rect) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 641 | 654 |
| 642 current_step_ = 0; | 655 current_step_ = 0; |
| 643 direction_ = static_cast<Direction>((direction_ + 1) % 4); | 656 direction_ = static_cast<Direction>((direction_ + 1) % 4); |
| 644 | 657 |
| 645 if (direction_ == RIGHT || direction_ == LEFT) { | 658 if (direction_ == RIGHT || direction_ == LEFT) { |
| 646 ++vertical_step_count_; | 659 ++vertical_step_count_; |
| 647 ++horizontal_step_count_; | 660 ++horizontal_step_count_; |
| 648 } | 661 } |
| 649 } | 662 } |
| 650 | 663 |
| 651 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() { | 664 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() |
| 665 : around_index_rect_(kNonPositiveQuadrantIndexRect) { |
| 652 done(); | 666 done(); |
| 653 } | 667 } |
| 654 | 668 |
| 655 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( | 669 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( |
| 656 const TilingData* tiling_data, | 670 const TilingData* tiling_data, |
| 657 const gfx::Rect& consider_rect, | 671 const gfx::Rect& consider_rect, |
| 658 const gfx::Rect& ignore_rect, | 672 const gfx::Rect& ignore_rect, |
| 659 const gfx::Rect& center_rect) | 673 const gfx::Rect& center_rect) |
| 660 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), | 674 : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect), |
| 661 around_left_(-1), | 675 around_index_rect_(kNonPositiveQuadrantIndexRect), |
| 662 around_top_(-1), | |
| 663 around_right_(-1), | |
| 664 around_bottom_(-1), | |
| 665 direction_(LEFT), | 676 direction_(LEFT), |
| 666 delta_x_(-1), | 677 delta_x_(-1), |
| 667 delta_y_(0), | 678 delta_y_(0), |
| 668 current_step_(0), | 679 current_step_(0), |
| 669 horizontal_step_count_(0), | 680 horizontal_step_count_(0), |
| 670 vertical_step_count_(0) { | 681 vertical_step_count_(0) { |
| 671 if (!HasConsiderRect()) { | 682 if (!HasConsiderRect()) { |
| 672 done(); | 683 done(); |
| 673 return; | 684 return; |
| 674 } | 685 } |
| 675 | 686 |
| 687 int around_left = 0; |
| 676 // Determine around left, such that it is between -1 and num_tiles_x. | 688 // Determine around left, such that it is between -1 and num_tiles_x. |
| 677 if (center_rect.x() < 0 || center_rect.IsEmpty()) | 689 if (center_rect.x() < 0 || center_rect.IsEmpty()) |
| 678 around_left_ = -1; | 690 around_left = -1; |
| 679 else if (center_rect.x() >= tiling_data->tiling_size().width()) | 691 else if (center_rect.x() >= tiling_data->tiling_size().width()) |
| 680 around_left_ = tiling_data->num_tiles_x(); | 692 around_left = tiling_data->num_tiles_x(); |
| 681 else | 693 else |
| 682 around_left_ = tiling_data->TileXIndexFromSrcCoord(center_rect.x()); | 694 around_left = tiling_data->TileXIndexFromSrcCoord(center_rect.x()); |
| 683 | 695 |
| 684 // Determine around top, such that it is between -1 and num_tiles_y. | 696 // Determine around top, such that it is between -1 and num_tiles_y. |
| 697 int around_top = 0; |
| 685 if (center_rect.y() < 0 || center_rect.IsEmpty()) | 698 if (center_rect.y() < 0 || center_rect.IsEmpty()) |
| 686 around_top_ = -1; | 699 around_top = -1; |
| 687 else if (center_rect.y() >= tiling_data->tiling_size().height()) | 700 else if (center_rect.y() >= tiling_data->tiling_size().height()) |
| 688 around_top_ = tiling_data->num_tiles_y(); | 701 around_top = tiling_data->num_tiles_y(); |
| 689 else | 702 else |
| 690 around_top_ = tiling_data->TileYIndexFromSrcCoord(center_rect.y()); | 703 around_top = tiling_data->TileYIndexFromSrcCoord(center_rect.y()); |
| 691 | 704 |
| 692 // Determine around right, such that it is between -1 and num_tiles_x. | 705 // Determine around right, such that it is between -1 and num_tiles_x. |
| 706 int around_right = 0; |
| 693 int right_src_coord = center_rect.right() - 1; | 707 int right_src_coord = center_rect.right() - 1; |
| 694 if (right_src_coord < 0 || center_rect.IsEmpty()) { | 708 if (right_src_coord < 0 || center_rect.IsEmpty()) { |
| 695 around_right_ = -1; | 709 around_right = -1; |
| 696 } else if (right_src_coord >= tiling_data->tiling_size().width()) { | 710 } else if (right_src_coord >= tiling_data->tiling_size().width()) { |
| 697 around_right_ = tiling_data->num_tiles_x(); | 711 around_right = tiling_data->num_tiles_x(); |
| 698 } else { | 712 } else { |
| 699 around_right_ = tiling_data->TileXIndexFromSrcCoord(right_src_coord); | 713 around_right = tiling_data->TileXIndexFromSrcCoord(right_src_coord); |
| 700 } | 714 } |
| 701 | 715 |
| 702 // Determine around bottom, such that it is between -1 and num_tiles_y. | 716 // Determine around bottom, such that it is between -1 and num_tiles_y. |
| 717 int around_bottom = 0; |
| 703 int bottom_src_coord = center_rect.bottom() - 1; | 718 int bottom_src_coord = center_rect.bottom() - 1; |
| 704 if (bottom_src_coord < 0 || center_rect.IsEmpty()) { | 719 if (bottom_src_coord < 0 || center_rect.IsEmpty()) { |
| 705 around_bottom_ = -1; | 720 around_bottom = -1; |
| 706 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) { | 721 } else if (bottom_src_coord >= tiling_data->tiling_size().height()) { |
| 707 around_bottom_ = tiling_data->num_tiles_y(); | 722 around_bottom = tiling_data->num_tiles_y(); |
| 708 } else { | 723 } else { |
| 709 around_bottom_ = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); | 724 around_bottom = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); |
| 710 } | 725 } |
| 711 | 726 |
| 727 around_index_rect_ = |
| 728 IndexRect(around_left, around_right, around_top, around_bottom); |
| 729 DCHECK(around_index_rect_.is_valid()); |
| 730 |
| 712 // Figure out the maximum distance from the around edge to consider edge. | 731 // Figure out the maximum distance from the around edge to consider edge. |
| 713 int max_distance = 0; | 732 int max_distance = 0; |
| 714 max_distance = std::max(max_distance, around_top_ - consider_top_); | 733 max_distance = std::max( |
| 715 max_distance = std::max(max_distance, around_left_ - consider_left_); | 734 max_distance, around_index_rect_.top() - consider_index_rect_.top()); |
| 716 max_distance = std::max(max_distance, consider_bottom_ - around_bottom_); | 735 max_distance = std::max( |
| 717 max_distance = std::max(max_distance, consider_right_ - around_right_); | 736 max_distance, around_index_rect_.left() - consider_index_rect_.left()); |
| 737 max_distance = std::max(max_distance, consider_index_rect_.bottom() - |
| 738 around_index_rect_.bottom()); |
| 739 max_distance = std::max( |
| 740 max_distance, consider_index_rect_.right() - around_index_rect_.right()); |
| 718 | 741 |
| 719 // The step count is the length of the edge (around_right_ - around_left_ + 1) | 742 // The step count is the length of the edge |
| 720 // plus twice the max distance to pad (to the right and to the left). This way | 743 // (around_index_rect_.num_indices_x()) plus twice the max distance to pad |
| 721 // the initial rect is the size proportional to the center, but big enough | 744 // (to the right and to the left). This way the initial rect is the size |
| 722 // to cover the consider rect. | 745 // proportional to the center, but big enough to cover the consider rect. |
| 723 // | 746 // |
| 724 // C = consider rect | 747 // C = consider rect |
| 725 // A = around rect | 748 // A = around rect |
| 726 // . = area of the padded around rect | 749 // . = area of the padded around rect |
| 727 // md = max distance (note in the picture below, there's md written vertically | 750 // md = max distance (note in the picture below, there's md written vertically |
| 728 // as well). | 751 // as well). |
| 729 // I = initial starting position | 752 // I = initial starting position |
| 730 // | 753 // |
| 731 // |md| |md| | 754 // |md| |md| |
| 732 // | 755 // |
| 733 // - .......... | 756 // - .......... |
| 734 // m .......... | 757 // m .......... |
| 735 // d .......... | 758 // d .......... |
| 736 // - CCCCCCC... | 759 // - CCCCCCC... |
| 737 // CCCCAAC... | 760 // CCCCAAC... |
| 738 // CCCCAAC... | 761 // CCCCAAC... |
| 739 // - .......... | 762 // - .......... |
| 740 // m .......... | 763 // m .......... |
| 741 // d .......... | 764 // d .......... |
| 742 // - ..........I | 765 // - ..........I |
| 743 vertical_step_count_ = around_bottom_ - around_top_ + 1 + 2 * max_distance; | 766 vertical_step_count_ = around_index_rect_.num_indices_y() + 2 * max_distance; |
| 744 horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance; | 767 horizontal_step_count_ = |
| 768 around_index_rect_.num_indices_x() + 2 * max_distance; |
| 745 | 769 |
| 746 // Start with one to the right of the padded around rect. | 770 // Start with one to the right of the padded around rect. |
| 747 index_x_ = around_right_ + max_distance + 1; | 771 index_x_ = around_index_rect_.right() + max_distance + 1; |
| 748 index_y_ = around_bottom_ + max_distance; | 772 index_y_ = around_index_rect_.bottom() + max_distance; |
| 749 | 773 |
| 750 // The current index is outside a valid tile, so advance immediately. | 774 // The current index is outside a valid tile, so advance immediately. |
| 751 ++(*this); | 775 ++(*this); |
| 752 } | 776 } |
| 753 | 777 |
| 754 TilingData::ReverseSpiralDifferenceIterator& | 778 TilingData::ReverseSpiralDifferenceIterator& |
| 755 TilingData::ReverseSpiralDifferenceIterator:: | 779 TilingData::ReverseSpiralDifferenceIterator:: |
| 756 operator++() { | 780 operator++() { |
| 757 while (!in_around_rect()) { | 781 while (!around_index_rect_.Contains(index_x_, index_y_)) { |
| 758 if (needs_direction_switch()) | 782 if (needs_direction_switch()) |
| 759 switch_direction(); | 783 switch_direction(); |
| 760 | 784 |
| 761 index_x_ += delta_x_; | 785 index_x_ += delta_x_; |
| 762 index_y_ += delta_y_; | 786 index_y_ += delta_y_; |
| 763 ++current_step_; | 787 ++current_step_; |
| 764 | 788 |
| 765 if (in_around_rect()) { | 789 if (around_index_rect_.Contains(index_x_, index_y_)) { |
| 766 break; | 790 break; |
| 767 } else if (in_consider_rect()) { | 791 } else if (consider_index_rect_.Contains(index_x_, index_y_)) { |
| 768 // If the tile is in the consider rect but not in ignore rect, then it's a | 792 // If the tile is in the consider rect but not in ignore rect, then it's a |
| 769 // valid tile to visit. | 793 // valid tile to visit. |
| 770 if (!in_ignore_rect()) | 794 if (!ignore_index_rect_.Contains(index_x_, index_y_)) |
| 771 break; | 795 break; |
| 772 | 796 |
| 773 // Steps needed to reach the very edge of the ignore rect, while remaining | 797 // Steps needed to reach the very edge of the ignore rect, while remaining |
| 774 // inside it (so that the continue would take us outside). | 798 // inside it (so that the continue would take us outside). |
| 775 int steps_to_edge = 0; | 799 int steps_to_edge = 0; |
| 776 switch (direction_) { | 800 switch (direction_) { |
| 777 case UP: | 801 case UP: |
| 778 steps_to_edge = index_y_ - ignore_top_; | 802 steps_to_edge = index_y_ - ignore_index_rect_.top(); |
| 779 break; | 803 break; |
| 780 case LEFT: | 804 case LEFT: |
| 781 steps_to_edge = index_x_ - ignore_left_; | 805 steps_to_edge = index_x_ - ignore_index_rect_.left(); |
| 782 break; | 806 break; |
| 783 case DOWN: | 807 case DOWN: |
| 784 steps_to_edge = ignore_bottom_ - index_y_; | 808 steps_to_edge = ignore_index_rect_.bottom() - index_y_; |
| 785 break; | 809 break; |
| 786 case RIGHT: | 810 case RIGHT: |
| 787 steps_to_edge = ignore_right_ - index_x_; | 811 steps_to_edge = ignore_index_rect_.right() - index_x_; |
| 788 break; | 812 break; |
| 789 } | 813 } |
| 790 | 814 |
| 791 // We need to switch directions in |max_steps|. | 815 // We need to switch directions in |max_steps|. |
| 792 int max_steps = current_step_count() - current_step_; | 816 int max_steps = current_step_count() - current_step_; |
| 793 | 817 |
| 794 int steps_to_take = std::min(steps_to_edge, max_steps); | 818 int steps_to_take = std::min(steps_to_edge, max_steps); |
| 795 DCHECK_GE(steps_to_take, 0); | 819 DCHECK_GE(steps_to_take, 0); |
| 796 | 820 |
| 797 index_x_ += steps_to_take * delta_x_; | 821 index_x_ += steps_to_take * delta_x_; |
| 798 index_y_ += steps_to_take * delta_y_; | 822 index_y_ += steps_to_take * delta_y_; |
| 799 current_step_ += steps_to_take; | 823 current_step_ += steps_to_take; |
| 800 } else { | 824 } else { |
| 801 // We're not in the consider rect. | 825 // We're not in the consider rect. |
| 802 | 826 |
| 803 int max_steps = current_step_count() - current_step_; | 827 int max_steps = current_step_count() - current_step_; |
| 804 int steps_to_take = max_steps; | 828 int steps_to_take = max_steps; |
| 805 | 829 |
| 806 // We might hit the consider rect before needing to switch directions: | 830 // We might hit the consider rect before needing to switch directions: |
| 807 // update steps to take. | 831 // update steps to take. |
| 808 switch (direction_) { | 832 switch (direction_) { |
| 809 case UP: | 833 case UP: |
| 810 if (valid_column() && consider_bottom_ < index_y_) | 834 if (consider_index_rect_.valid_column(index_x_) && |
| 811 steps_to_take = index_y_ - consider_bottom_ - 1; | 835 consider_index_rect_.bottom() < index_y_) |
| 836 steps_to_take = index_y_ - consider_index_rect_.bottom() - 1; |
| 812 break; | 837 break; |
| 813 case LEFT: | 838 case LEFT: |
| 814 if (valid_row() && consider_right_ < index_x_) | 839 if (consider_index_rect_.valid_row(index_y_) && |
| 815 steps_to_take = index_x_ - consider_right_ - 1; | 840 consider_index_rect_.right() < index_x_) |
| 841 steps_to_take = index_x_ - consider_index_rect_.right() - 1; |
| 816 break; | 842 break; |
| 817 case DOWN: | 843 case DOWN: |
| 818 if (valid_column() && consider_top_ > index_y_) | 844 if (consider_index_rect_.valid_column(index_x_) && |
| 819 steps_to_take = consider_top_ - index_y_ - 1; | 845 consider_index_rect_.top() > index_y_) |
| 846 steps_to_take = consider_index_rect_.top() - index_y_ - 1; |
| 820 break; | 847 break; |
| 821 case RIGHT: | 848 case RIGHT: |
| 822 if (valid_row() && consider_left_ > index_x_) | 849 if (consider_index_rect_.valid_row(index_y_) && |
| 823 steps_to_take = consider_left_ - index_x_ - 1; | 850 consider_index_rect_.left() > index_x_) |
| 851 steps_to_take = consider_index_rect_.left() - index_x_ - 1; |
| 824 break; | 852 break; |
| 825 } | 853 } |
| 826 steps_to_take = std::min(steps_to_take, max_steps); | 854 steps_to_take = std::min(steps_to_take, max_steps); |
| 827 DCHECK_GE(steps_to_take, 0); | 855 DCHECK_GE(steps_to_take, 0); |
| 828 | 856 |
| 829 index_x_ += steps_to_take * delta_x_; | 857 index_x_ += steps_to_take * delta_x_; |
| 830 index_y_ += steps_to_take * delta_y_; | 858 index_y_ += steps_to_take * delta_y_; |
| 831 current_step_ += steps_to_take; | 859 current_step_ += steps_to_take; |
| 832 } | 860 } |
| 833 } | 861 } |
| 834 | 862 |
| 835 // Once we enter the around rect, we're done. | 863 // Once we enter the around rect, we're done. |
| 836 if (in_around_rect()) | 864 if (around_index_rect_.Contains(index_x_, index_y_)) |
| 837 done(); | 865 done(); |
| 838 return *this; | 866 return *this; |
| 839 } | 867 } |
| 840 | 868 |
| 841 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch() | 869 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch() |
| 842 const { | 870 const { |
| 843 return current_step_ >= current_step_count(); | 871 return current_step_ >= current_step_count(); |
| 844 } | 872 } |
| 845 | 873 |
| 846 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() { | 874 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 858 | 886 |
| 859 // We should always end up in an around rect at some point. | 887 // 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 | 888 // Since the direction is now vertical, we have to ensure that we will |
| 861 // advance. | 889 // advance. |
| 862 DCHECK_GE(horizontal_step_count_, 1); | 890 DCHECK_GE(horizontal_step_count_, 1); |
| 863 DCHECK_GE(vertical_step_count_, 1); | 891 DCHECK_GE(vertical_step_count_, 1); |
| 864 } | 892 } |
| 865 } | 893 } |
| 866 | 894 |
| 867 } // namespace cc | 895 } // namespace cc |
| OLD | NEW |