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

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

Issue 2350563002: cc: Implement IndexRect for encapsulating tile indices. (Closed)
Patch Set: review comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/base/tiling_data.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 The Chromium Authors. All rights reserved. 1 // Copyright 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/base/tiling_data.h" 5 #include "cc/base/tiling_data.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ui/gfx/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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/base/tiling_data.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698