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 |