OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/resources/picture_layer_tiling.h" | 5 #include "cc/resources/picture_layer_tiling.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 | 520 |
521 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { | 521 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |
522 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 522 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
523 state->SetInteger("num_tiles", tiles_.size()); | 523 state->SetInteger("num_tiles", tiles_.size()); |
524 state->SetDouble("content_scale", contents_scale_); | 524 state->SetDouble("content_scale", contents_scale_); |
525 state->Set("content_bounds", | 525 state->Set("content_bounds", |
526 MathUtil::AsValue(ContentRect().size()).release()); | 526 MathUtil::AsValue(ContentRect().size()).release()); |
527 return state.PassAs<base::Value>(); | 527 return state.PassAs<base::Value>(); |
528 } | 528 } |
529 | 529 |
| 530 namespace { |
| 531 |
530 // This struct represents an event at which the expending rect intersects | 532 // This struct represents an event at which the expending rect intersects |
531 // one of its boundaries. 4 intersection events will occur during expansion. | 533 // one of its boundaries. 4 intersection events will occur during expansion. |
532 struct EdgeEvent { | 534 struct EdgeEvent { |
533 enum { BOTTOM, TOP, LEFT, RIGHT } edge; | 535 enum { BOTTOM, TOP, LEFT, RIGHT } edge; |
534 int* num_edges; | 536 int* num_edges; |
535 int distance; | 537 int distance; |
536 }; | 538 }; |
537 | 539 |
| 540 // Compute the delta to expand from edges to cover target_area. |
| 541 int ComputeExpansionDelta(int num_x_edges, int num_y_edges, |
| 542 int width, int height, |
| 543 int64 target_area) { |
| 544 // Compute coefficients for the quadratic equation: |
| 545 // a*x^2 + b*x + c = 0 |
| 546 int a = num_y_edges * num_x_edges; |
| 547 int b = num_y_edges * width + num_x_edges * height; |
| 548 int64 c = static_cast<int64>(width) * height - target_area; |
| 549 |
| 550 // Compute the delta for our edges using the quadratic equation. |
| 551 return a == 0 ? -c / b : |
| 552 (-b + static_cast<int>( |
| 553 std::sqrt(static_cast<int64>(b) * b - 4.0 * a * c))) / (2 * a); |
| 554 } |
| 555 |
| 556 } // namespace |
| 557 |
538 gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( | 558 gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( |
539 gfx::Rect starting_rect, | 559 gfx::Rect starting_rect, |
540 int64 target_area, | 560 int64 target_area, |
541 gfx::Rect bounding_rect) { | 561 gfx::Rect bounding_rect) { |
542 DCHECK(!starting_rect.IsEmpty()); | 562 DCHECK(!starting_rect.IsEmpty()); |
543 DCHECK(!bounding_rect.IsEmpty()); | 563 DCHECK(!bounding_rect.IsEmpty()); |
544 DCHECK_GT(target_area, 0); | 564 DCHECK_GT(target_area, 0); |
545 | 565 |
546 gfx::Rect rect = IntersectRects(starting_rect, bounding_rect); | 566 // Expand the starting rect to cover target_area. |
547 if (rect.IsEmpty()) | 567 int delta = ComputeExpansionDelta( |
| 568 2, 2, starting_rect.width(), starting_rect.height(), target_area); |
| 569 gfx::Rect expanded_starting_rect = starting_rect; |
| 570 expanded_starting_rect.Inset(-delta, -delta); |
| 571 |
| 572 gfx::Rect rect = IntersectRects(expanded_starting_rect, bounding_rect); |
| 573 if (rect.IsEmpty()) { |
| 574 // The starting_rect and bounding_rect are far away. |
548 return rect; | 575 return rect; |
| 576 } |
| 577 if (rect == expanded_starting_rect) { |
| 578 // The expanded starting rect already covers target_area on bounding_rect. |
| 579 return rect; |
| 580 } |
| 581 |
| 582 // Continue to expand rect to let it cover target_area. |
549 | 583 |
550 // These values will be updated by the loop and uses as the output. | 584 // These values will be updated by the loop and uses as the output. |
551 int origin_x = rect.x(); | 585 int origin_x = rect.x(); |
552 int origin_y = rect.y(); | 586 int origin_y = rect.y(); |
553 int width = rect.width(); | 587 int width = rect.width(); |
554 int height = rect.height(); | 588 int height = rect.height(); |
555 | 589 |
556 // In the beginning we will consider 2 edges in each dimension. | 590 // In the beginning we will consider 2 edges in each dimension. |
557 int num_y_edges = 2; | 591 int num_y_edges = 2; |
558 int num_x_edges = 2; | 592 int num_x_edges = 2; |
(...skipping 16 matching lines...) Expand all Loading... |
575 for (int event_index = 0; event_index < 4; event_index++) { | 609 for (int event_index = 0; event_index < 4; event_index++) { |
576 const EdgeEvent& event = events[event_index]; | 610 const EdgeEvent& event = events[event_index]; |
577 | 611 |
578 // Early out if our distance to event is 0. | 612 // Early out if our distance to event is 0. |
579 // This optimization is not required for correctness. | 613 // This optimization is not required for correctness. |
580 if (event.distance == 0) { | 614 if (event.distance == 0) { |
581 --*event.num_edges; | 615 --*event.num_edges; |
582 continue; | 616 continue; |
583 } | 617 } |
584 | 618 |
585 // Compute coefficients for the quadraic equation. | 619 int delta = ComputeExpansionDelta( |
586 int a = num_y_edges * num_x_edges; | 620 num_x_edges, num_y_edges, width, height, target_area); |
587 int b = num_y_edges * width + num_x_edges * height; | |
588 int c = width * height - target_area; | |
589 | |
590 // Compute the delta for our edges using the quadratic equation. | |
591 int delta = a == 0 ? -c / b : | |
592 (-b + static_cast<int>(std::sqrt(b * b - 4.0 * a * c))) / (2 * a); | |
593 | 621 |
594 // Clamp delta to our event distance. | 622 // Clamp delta to our event distance. |
595 if (delta > event.distance) | 623 if (delta > event.distance) |
596 delta = event.distance; | 624 delta = event.distance; |
597 | 625 |
598 // Adjust the edge count for this kind of edge. | 626 // Adjust the edge count for this kind of edge. |
599 --*event.num_edges; | 627 --*event.num_edges; |
600 | 628 |
601 // Apply the delta to the edges and edge events. | 629 // Apply the delta to the edges and edge events. |
602 for (int i = event_index; i < 4; i++) { | 630 for (int i = event_index; i < 4; i++) { |
(...skipping 18 matching lines...) Expand all Loading... |
621 | 649 |
622 // If our delta is less then our event distance, we're done. | 650 // If our delta is less then our event distance, we're done. |
623 if (delta < event.distance) | 651 if (delta < event.distance) |
624 break; | 652 break; |
625 } | 653 } |
626 | 654 |
627 return gfx::Rect(origin_x, origin_y, width, height); | 655 return gfx::Rect(origin_x, origin_y, width, height); |
628 } | 656 } |
629 | 657 |
630 } // namespace cc | 658 } // namespace cc |
OLD | NEW |