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 if (starting_rect.IsEmpty()) | 562 if (starting_rect.IsEmpty()) |
543 return starting_rect; | 563 return starting_rect; |
544 | 564 |
545 DCHECK(!bounding_rect.IsEmpty()); | 565 DCHECK(!bounding_rect.IsEmpty()); |
546 DCHECK_GT(target_area, 0); | 566 DCHECK_GT(target_area, 0); |
547 | 567 |
548 gfx::Rect rect = IntersectRects(starting_rect, bounding_rect); | 568 // Expand the starting rect to cover target_area. |
549 if (rect.IsEmpty()) | 569 int delta = ComputeExpansionDelta( |
| 570 2, 2, starting_rect.width(), starting_rect.height(), target_area); |
| 571 gfx::Rect expanded_starting_rect = starting_rect; |
| 572 expanded_starting_rect.Inset(-delta, -delta); |
| 573 |
| 574 gfx::Rect rect = IntersectRects(expanded_starting_rect, bounding_rect); |
| 575 if (rect.IsEmpty()) { |
| 576 // The starting_rect and bounding_rect are far away. |
550 return rect; | 577 return rect; |
| 578 } |
| 579 if (rect == expanded_starting_rect) { |
| 580 // The expanded starting rect already covers target_area on bounding_rect. |
| 581 return rect; |
| 582 } |
| 583 |
| 584 // Continue to expand rect to let it cover target_area. |
551 | 585 |
552 // These values will be updated by the loop and uses as the output. | 586 // These values will be updated by the loop and uses as the output. |
553 int origin_x = rect.x(); | 587 int origin_x = rect.x(); |
554 int origin_y = rect.y(); | 588 int origin_y = rect.y(); |
555 int width = rect.width(); | 589 int width = rect.width(); |
556 int height = rect.height(); | 590 int height = rect.height(); |
557 | 591 |
558 // In the beginning we will consider 2 edges in each dimension. | 592 // In the beginning we will consider 2 edges in each dimension. |
559 int num_y_edges = 2; | 593 int num_y_edges = 2; |
560 int num_x_edges = 2; | 594 int num_x_edges = 2; |
(...skipping 16 matching lines...) Expand all Loading... |
577 for (int event_index = 0; event_index < 4; event_index++) { | 611 for (int event_index = 0; event_index < 4; event_index++) { |
578 const EdgeEvent& event = events[event_index]; | 612 const EdgeEvent& event = events[event_index]; |
579 | 613 |
580 // Early out if our distance to event is 0. | 614 // Early out if our distance to event is 0. |
581 // This optimization is not required for correctness. | 615 // This optimization is not required for correctness. |
582 if (event.distance == 0) { | 616 if (event.distance == 0) { |
583 --*event.num_edges; | 617 --*event.num_edges; |
584 continue; | 618 continue; |
585 } | 619 } |
586 | 620 |
587 // Compute coefficients for the quadraic equation. | 621 int delta = ComputeExpansionDelta( |
588 int a = num_y_edges * num_x_edges; | 622 num_x_edges, num_y_edges, width, height, target_area); |
589 int b = num_y_edges * width + num_x_edges * height; | |
590 int c = width * height - target_area; | |
591 | |
592 // Compute the delta for our edges using the quadratic equation. | |
593 int delta = a == 0 ? -c / b : | |
594 (-b + static_cast<int>(std::sqrt(b * b - 4.0 * a * c))) / (2 * a); | |
595 | 623 |
596 // Clamp delta to our event distance. | 624 // Clamp delta to our event distance. |
597 if (delta > event.distance) | 625 if (delta > event.distance) |
598 delta = event.distance; | 626 delta = event.distance; |
599 | 627 |
600 // Adjust the edge count for this kind of edge. | 628 // Adjust the edge count for this kind of edge. |
601 --*event.num_edges; | 629 --*event.num_edges; |
602 | 630 |
603 // Apply the delta to the edges and edge events. | 631 // Apply the delta to the edges and edge events. |
604 for (int i = event_index; i < 4; i++) { | 632 for (int i = event_index; i < 4; i++) { |
(...skipping 18 matching lines...) Expand all Loading... |
623 | 651 |
624 // If our delta is less then our event distance, we're done. | 652 // If our delta is less then our event distance, we're done. |
625 if (delta < event.distance) | 653 if (delta < event.distance) |
626 break; | 654 break; |
627 } | 655 } |
628 | 656 |
629 return gfx::Rect(origin_x, origin_y, width, height); | 657 return gfx::Rect(origin_x, origin_y, width, height); |
630 } | 658 } |
631 | 659 |
632 } // namespace cc | 660 } // namespace cc |
OLD | NEW |