| 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 |