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 const IndexRect kOutOfBoundsIndexRect(-1, -1, -1, -1); | |
vmpstr
2016/09/19 18:01:11
This is technically a valid index rect, should we
prashant.n
2016/09/20 02:04:58
As per current implementation of spiral iterator,
| |
16 } | |
17 | |
14 static int ComputeNumTiles(int max_texture_size, | 18 static int ComputeNumTiles(int max_texture_size, |
15 int total_size, | 19 int total_size, |
16 int border_texels) { | 20 int border_texels) { |
17 if (max_texture_size - 2 * border_texels <= 0) | 21 if (max_texture_size - 2 * border_texels <= 0) |
18 return total_size > 0 && max_texture_size >= total_size ? 1 : 0; | 22 return total_size > 0 && max_texture_size >= total_size ? 1 : 0; |
19 | 23 |
20 int num_tiles = std::max(1, | 24 int num_tiles = std::max(1, |
21 1 + (total_size - 1 - 2 * border_texels) / | 25 1 + (total_size - 1 - 2 * border_texels) / |
22 (max_texture_size - 2 * border_texels)); | 26 (max_texture_size - 2 * border_texels)); |
23 return total_size > 0 ? num_tiles : 0; | 27 return total_size > 0 ? num_tiles : 0; |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 void TilingData::RecomputeNumTiles() { | 293 void TilingData::RecomputeNumTiles() { |
290 num_tiles_x_ = ComputeNumTiles( | 294 num_tiles_x_ = ComputeNumTiles( |
291 max_texture_size_.width(), tiling_size_.width(), border_texels_); | 295 max_texture_size_.width(), tiling_size_.width(), border_texels_); |
292 num_tiles_y_ = ComputeNumTiles( | 296 num_tiles_y_ = ComputeNumTiles( |
293 max_texture_size_.height(), tiling_size_.height(), border_texels_); | 297 max_texture_size_.height(), tiling_size_.height(), border_texels_); |
294 } | 298 } |
295 | 299 |
296 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { | 300 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { |
297 } | 301 } |
298 | 302 |
299 TilingData::Iterator::Iterator() { | 303 TilingData::Iterator::Iterator() : index_rect_(kOutOfBoundsIndexRect) { |
300 done(); | 304 done(); |
301 } | 305 } |
302 | 306 |
303 TilingData::Iterator::Iterator(const TilingData* tiling_data, | 307 TilingData::Iterator::Iterator(const TilingData* tiling_data, |
304 const gfx::Rect& consider_rect, | 308 const gfx::Rect& consider_rect, |
305 bool include_borders) | 309 bool include_borders) |
306 : left_(-1), right_(-1), bottom_(-1) { | 310 : index_rect_(kOutOfBoundsIndexRect) { |
307 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { | 311 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { |
308 done(); | 312 done(); |
309 return; | 313 return; |
310 } | 314 } |
311 | 315 |
312 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); | 316 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); |
313 gfx::Rect rect(consider_rect); | 317 gfx::Rect rect(consider_rect); |
314 rect.Intersect(tiling_bounds_rect); | 318 rect.Intersect(tiling_bounds_rect); |
315 | 319 |
316 gfx::Rect top_left_tile; | 320 gfx::Rect top_left_tile; |
317 if (include_borders) { | 321 if (include_borders) { |
318 index_x_ = tiling_data->FirstBorderTileXIndexFromSrcCoord(rect.x()); | 322 index_x_ = tiling_data->FirstBorderTileXIndexFromSrcCoord(rect.x()); |
319 index_y_ = tiling_data->FirstBorderTileYIndexFromSrcCoord(rect.y()); | 323 index_y_ = tiling_data->FirstBorderTileYIndexFromSrcCoord(rect.y()); |
320 right_ = tiling_data->LastBorderTileXIndexFromSrcCoord(rect.right() - 1); | 324 index_rect_ = IndexRect( |
321 bottom_ = tiling_data->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1); | 325 index_x_, |
326 tiling_data->LastBorderTileXIndexFromSrcCoord(rect.right() - 1), | |
327 index_y_, | |
328 tiling_data->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1)); | |
329 DCHECK(index_rect_.is_valid()); | |
322 top_left_tile = tiling_data->TileBoundsWithBorder(index_x_, index_y_); | 330 top_left_tile = tiling_data->TileBoundsWithBorder(index_x_, index_y_); |
323 } else { | 331 } else { |
324 index_x_ = tiling_data->TileXIndexFromSrcCoord(rect.x()); | 332 index_x_ = tiling_data->TileXIndexFromSrcCoord(rect.x()); |
325 index_y_ = tiling_data->TileYIndexFromSrcCoord(rect.y()); | 333 index_y_ = tiling_data->TileYIndexFromSrcCoord(rect.y()); |
326 right_ = tiling_data->TileXIndexFromSrcCoord(rect.right() - 1); | 334 index_rect_ = IndexRect( |
327 bottom_ = tiling_data->TileYIndexFromSrcCoord(rect.bottom() - 1); | 335 index_x_, tiling_data->TileXIndexFromSrcCoord(rect.right() - 1), |
336 index_y_, tiling_data->TileYIndexFromSrcCoord(rect.bottom() - 1)); | |
337 DCHECK(index_rect_.is_valid()); | |
328 top_left_tile = tiling_data->TileBounds(index_x_, index_y_); | 338 top_left_tile = tiling_data->TileBounds(index_x_, index_y_); |
329 } | 339 } |
330 left_ = index_x_; | |
331 | 340 |
332 // Index functions always return valid indices, so explicitly check | 341 // Index functions always return valid indices, so explicitly check |
333 // for non-intersecting rects. | 342 // for non-intersecting rects. |
334 if (!top_left_tile.Intersects(rect)) | 343 if (!top_left_tile.Intersects(rect)) |
335 done(); | 344 done(); |
336 } | 345 } |
337 | 346 |
338 TilingData::Iterator& TilingData::Iterator::operator++() { | 347 TilingData::Iterator& TilingData::Iterator::operator++() { |
339 if (!*this) | 348 if (!*this) |
340 return *this; | 349 return *this; |
341 | 350 |
342 index_x_++; | 351 index_x_++; |
343 if (index_x_ > right_) { | 352 if (index_x_ > index_rect_.right()) { |
344 index_x_ = left_; | 353 index_x_ = index_rect_.left(); |
345 index_y_++; | 354 index_y_++; |
346 if (index_y_ > bottom_) | 355 if (index_y_ > index_rect_.bottom()) |
347 done(); | 356 done(); |
348 } | 357 } |
349 | 358 |
350 return *this; | 359 return *this; |
351 } | 360 } |
352 | 361 |
353 TilingData::BaseDifferenceIterator::BaseDifferenceIterator() { | 362 TilingData::BaseDifferenceIterator::BaseDifferenceIterator() |
363 : consider_index_rect_(kOutOfBoundsIndexRect), | |
364 ignore_index_rect_(kOutOfBoundsIndexRect) { | |
354 done(); | 365 done(); |
355 } | 366 } |
356 | 367 |
357 TilingData::BaseDifferenceIterator::BaseDifferenceIterator( | 368 TilingData::BaseDifferenceIterator::BaseDifferenceIterator( |
358 const TilingData* tiling_data, | 369 const TilingData* tiling_data, |
359 const gfx::Rect& consider_rect, | 370 const gfx::Rect& consider_rect, |
360 const gfx::Rect& ignore_rect) | 371 const gfx::Rect& ignore_rect) |
361 : consider_left_(-1), | 372 : consider_index_rect_(kOutOfBoundsIndexRect), |
362 consider_top_(-1), | 373 ignore_index_rect_(kOutOfBoundsIndexRect) { |
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) { | 374 if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) { |
370 done(); | 375 done(); |
371 return; | 376 return; |
372 } | 377 } |
373 | 378 |
374 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); | 379 gfx::Rect tiling_bounds_rect(tiling_data->tiling_size()); |
375 gfx::Rect consider(consider_rect); | 380 gfx::Rect consider(consider_rect); |
376 consider.Intersect(tiling_bounds_rect); | 381 consider.Intersect(tiling_bounds_rect); |
377 | 382 |
378 if (consider.IsEmpty()) { | 383 if (consider.IsEmpty()) { |
379 done(); | 384 done(); |
380 return; | 385 return; |
381 } | 386 } |
382 | 387 |
383 consider_left_ = tiling_data->TileXIndexFromSrcCoord(consider.x()); | 388 consider_index_rect_ = |
384 consider_top_ = tiling_data->TileYIndexFromSrcCoord(consider.y()); | 389 IndexRect(tiling_data->TileXIndexFromSrcCoord(consider.x()), |
385 consider_right_ = tiling_data->TileXIndexFromSrcCoord(consider.right() - 1); | 390 tiling_data->TileXIndexFromSrcCoord(consider.right() - 1), |
386 consider_bottom_ = tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1); | 391 tiling_data->TileYIndexFromSrcCoord(consider.y()), |
392 tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1)); | |
393 DCHECK(consider_index_rect_.is_valid()); | |
387 | 394 |
388 gfx::Rect ignore(ignore_rect); | 395 gfx::Rect ignore(ignore_rect); |
389 ignore.Intersect(tiling_bounds_rect); | 396 ignore.Intersect(tiling_bounds_rect); |
390 | 397 |
391 if (!ignore.IsEmpty()) { | 398 if (!ignore.IsEmpty()) { |
392 ignore_left_ = tiling_data->TileXIndexFromSrcCoord(ignore.x()); | 399 ignore_index_rect_ = |
393 ignore_top_ = tiling_data->TileYIndexFromSrcCoord(ignore.y()); | 400 IndexRect(tiling_data->TileXIndexFromSrcCoord(ignore.x()), |
394 ignore_right_ = tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1); | 401 tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1), |
395 ignore_bottom_ = tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1); | 402 tiling_data->TileYIndexFromSrcCoord(ignore.y()), |
403 tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1)); | |
404 DCHECK(ignore_index_rect_.is_valid()); | |
396 | 405 |
397 // Clamp ignore indices to consider indices. | 406 // Clamp ignore indices to consider indices. |
398 ignore_left_ = std::max(ignore_left_, consider_left_); | 407 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 | 408 |
403 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ && | 409 // If ignore rect is invalid, reset. |
404 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) { | 410 if (!ignore_index_rect_.is_valid()) |
405 consider_left_ = consider_top_ = consider_right_ = consider_bottom_ = -1; | 411 ignore_index_rect_ = kOutOfBoundsIndexRect; |
412 | |
413 if (ignore_index_rect_ == consider_index_rect_) { | |
414 consider_index_rect_ = kOutOfBoundsIndexRect; | |
406 done(); | 415 done(); |
407 return; | 416 return; |
408 } | 417 } |
409 } | 418 } |
410 } | 419 } |
411 | 420 |
412 bool TilingData::BaseDifferenceIterator::HasConsiderRect() const { | 421 bool TilingData::BaseDifferenceIterator::HasConsiderRect() const { |
413 // Consider indices are either all valid or all equal to -1. | 422 // Consider indices are either all valid or all equal to -1. |
414 DCHECK((0 <= consider_left_ && consider_left_ <= consider_right_ && | 423 DCHECK( |
415 0 <= consider_top_ && consider_top_ <= consider_bottom_) || | 424 (0 <= consider_index_rect_.left() && 0 <= consider_index_rect_.top()) || |
vmpstr
2016/09/19 18:01:11
i think this has to be
consider_index_rect_.left
prashant.n
2016/09/20 02:04:58
We use DCHECK(is_valid()) after the object is cons
| |
416 (consider_left_ == -1 && consider_top_ == -1 && | 425 (consider_index_rect_ == kOutOfBoundsIndexRect)); |
417 consider_right_ == -1 && consider_bottom_ == -1)); | 426 return consider_index_rect_.left() != -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_(kOutOfBoundsIndexRect) { | |
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_(kOutOfBoundsIndexRect), |
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 (around_index_rect_.width()) |
720 // plus twice the max distance to pad (to the right and to the left). This way | 743 // plus twice the max distance to pad (to the right and to the left). This way |
721 // the initial rect is the size proportional to the center, but big enough | 744 // the initial rect is the size proportional to the center, but big enough |
722 // to cover the consider rect. | 745 // 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_.height() + 2 * max_distance; |
744 horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance; | 767 horizontal_step_count_ = around_index_rect_.width() + 2 * max_distance; |
745 | 768 |
746 // Start with one to the right of the padded around rect. | 769 // Start with one to the right of the padded around rect. |
747 index_x_ = around_right_ + max_distance + 1; | 770 index_x_ = around_index_rect_.right() + max_distance + 1; |
748 index_y_ = around_bottom_ + max_distance; | 771 index_y_ = around_index_rect_.bottom() + max_distance; |
749 | 772 |
750 // The current index is outside a valid tile, so advance immediately. | 773 // The current index is outside a valid tile, so advance immediately. |
751 ++(*this); | 774 ++(*this); |
752 } | 775 } |
753 | 776 |
754 TilingData::ReverseSpiralDifferenceIterator& | 777 TilingData::ReverseSpiralDifferenceIterator& |
755 TilingData::ReverseSpiralDifferenceIterator:: | 778 TilingData::ReverseSpiralDifferenceIterator:: |
756 operator++() { | 779 operator++() { |
757 while (!in_around_rect()) { | 780 while (!around_index_rect_.Contains(index_x_, index_y_)) { |
758 if (needs_direction_switch()) | 781 if (needs_direction_switch()) |
759 switch_direction(); | 782 switch_direction(); |
760 | 783 |
761 index_x_ += delta_x_; | 784 index_x_ += delta_x_; |
762 index_y_ += delta_y_; | 785 index_y_ += delta_y_; |
763 ++current_step_; | 786 ++current_step_; |
764 | 787 |
765 if (in_around_rect()) { | 788 if (around_index_rect_.Contains(index_x_, index_y_)) { |
766 break; | 789 break; |
767 } else if (in_consider_rect()) { | 790 } 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 | 791 // If the tile is in the consider rect but not in ignore rect, then it's a |
769 // valid tile to visit. | 792 // valid tile to visit. |
770 if (!in_ignore_rect()) | 793 if (!ignore_index_rect_.Contains(index_x_, index_y_)) |
771 break; | 794 break; |
772 | 795 |
773 // Steps needed to reach the very edge of the ignore rect, while remaining | 796 // Steps needed to reach the very edge of the ignore rect, while remaining |
774 // inside it (so that the continue would take us outside). | 797 // inside it (so that the continue would take us outside). |
775 int steps_to_edge = 0; | 798 int steps_to_edge = 0; |
776 switch (direction_) { | 799 switch (direction_) { |
777 case UP: | 800 case UP: |
778 steps_to_edge = index_y_ - ignore_top_; | 801 steps_to_edge = index_y_ - ignore_index_rect_.top(); |
779 break; | 802 break; |
780 case LEFT: | 803 case LEFT: |
781 steps_to_edge = index_x_ - ignore_left_; | 804 steps_to_edge = index_x_ - ignore_index_rect_.left(); |
782 break; | 805 break; |
783 case DOWN: | 806 case DOWN: |
784 steps_to_edge = ignore_bottom_ - index_y_; | 807 steps_to_edge = ignore_index_rect_.bottom() - index_y_; |
785 break; | 808 break; |
786 case RIGHT: | 809 case RIGHT: |
787 steps_to_edge = ignore_right_ - index_x_; | 810 steps_to_edge = ignore_index_rect_.right() - index_x_; |
788 break; | 811 break; |
789 } | 812 } |
790 | 813 |
791 // We need to switch directions in |max_steps|. | 814 // We need to switch directions in |max_steps|. |
792 int max_steps = current_step_count() - current_step_; | 815 int max_steps = current_step_count() - current_step_; |
793 | 816 |
794 int steps_to_take = std::min(steps_to_edge, max_steps); | 817 int steps_to_take = std::min(steps_to_edge, max_steps); |
795 DCHECK_GE(steps_to_take, 0); | 818 DCHECK_GE(steps_to_take, 0); |
796 | 819 |
797 index_x_ += steps_to_take * delta_x_; | 820 index_x_ += steps_to_take * delta_x_; |
798 index_y_ += steps_to_take * delta_y_; | 821 index_y_ += steps_to_take * delta_y_; |
799 current_step_ += steps_to_take; | 822 current_step_ += steps_to_take; |
800 } else { | 823 } else { |
801 // We're not in the consider rect. | 824 // We're not in the consider rect. |
802 | 825 |
803 int max_steps = current_step_count() - current_step_; | 826 int max_steps = current_step_count() - current_step_; |
804 int steps_to_take = max_steps; | 827 int steps_to_take = max_steps; |
805 | 828 |
806 // We might hit the consider rect before needing to switch directions: | 829 // We might hit the consider rect before needing to switch directions: |
807 // update steps to take. | 830 // update steps to take. |
808 switch (direction_) { | 831 switch (direction_) { |
809 case UP: | 832 case UP: |
810 if (valid_column() && consider_bottom_ < index_y_) | 833 if (consider_index_rect_.valid_column(index_x_) && |
811 steps_to_take = index_y_ - consider_bottom_ - 1; | 834 consider_index_rect_.bottom() < index_y_) |
835 steps_to_take = index_y_ - consider_index_rect_.bottom() - 1; | |
812 break; | 836 break; |
813 case LEFT: | 837 case LEFT: |
814 if (valid_row() && consider_right_ < index_x_) | 838 if (consider_index_rect_.valid_row(index_y_) && |
815 steps_to_take = index_x_ - consider_right_ - 1; | 839 consider_index_rect_.right() < index_x_) |
840 steps_to_take = index_x_ - consider_index_rect_.right() - 1; | |
816 break; | 841 break; |
817 case DOWN: | 842 case DOWN: |
818 if (valid_column() && consider_top_ > index_y_) | 843 if (consider_index_rect_.valid_column(index_x_) && |
819 steps_to_take = consider_top_ - index_y_ - 1; | 844 consider_index_rect_.top() > index_y_) |
845 steps_to_take = consider_index_rect_.top() - index_y_ - 1; | |
820 break; | 846 break; |
821 case RIGHT: | 847 case RIGHT: |
822 if (valid_row() && consider_left_ > index_x_) | 848 if (consider_index_rect_.valid_row(index_y_) && |
823 steps_to_take = consider_left_ - index_x_ - 1; | 849 consider_index_rect_.left() > index_x_) |
850 steps_to_take = consider_index_rect_.left() - index_x_ - 1; | |
824 break; | 851 break; |
825 } | 852 } |
826 steps_to_take = std::min(steps_to_take, max_steps); | 853 steps_to_take = std::min(steps_to_take, max_steps); |
827 DCHECK_GE(steps_to_take, 0); | 854 DCHECK_GE(steps_to_take, 0); |
828 | 855 |
829 index_x_ += steps_to_take * delta_x_; | 856 index_x_ += steps_to_take * delta_x_; |
830 index_y_ += steps_to_take * delta_y_; | 857 index_y_ += steps_to_take * delta_y_; |
831 current_step_ += steps_to_take; | 858 current_step_ += steps_to_take; |
832 } | 859 } |
833 } | 860 } |
834 | 861 |
835 // Once we enter the around rect, we're done. | 862 // Once we enter the around rect, we're done. |
836 if (in_around_rect()) | 863 if (around_index_rect_.Contains(index_x_, index_y_)) |
837 done(); | 864 done(); |
838 return *this; | 865 return *this; |
839 } | 866 } |
840 | 867 |
841 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch() | 868 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch() |
842 const { | 869 const { |
843 return current_step_ >= current_step_count(); | 870 return current_step_ >= current_step_count(); |
844 } | 871 } |
845 | 872 |
846 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() { | 873 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() { |
(...skipping 11 matching lines...) Expand all Loading... | |
858 | 885 |
859 // We should always end up in an around rect at some point. | 886 // 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 | 887 // Since the direction is now vertical, we have to ensure that we will |
861 // advance. | 888 // advance. |
862 DCHECK_GE(horizontal_step_count_, 1); | 889 DCHECK_GE(horizontal_step_count_, 1); |
863 DCHECK_GE(vertical_step_count_, 1); | 890 DCHECK_GE(vertical_step_count_, 1); |
864 } | 891 } |
865 } | 892 } |
866 | 893 |
867 } // namespace cc | 894 } // namespace cc |
OLD | NEW |