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

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

Issue 2350563002: cc: Implement IndexRect for encapsulating tile indices. (Closed)
Patch Set: build break 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
« cc/base/index_rect.h ('K') | « 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 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
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
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_(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
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
OLDNEW
« cc/base/index_rect.h ('K') | « cc/base/tiling_data.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698