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

Side by Side Diff: cc/picture_layer_tiling.cc

Issue 12287027: cc: Compute the inflated rect to cover a fixed number of tiles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use sqrt(double) for android Created 7 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « cc/picture_layer_tiling.h ('k') | cc/picture_layer_tiling_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/picture_layer_tiling.h" 5 #include "cc/picture_layer_tiling.h"
6 6
7 #include <cmath>
8
7 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
8 #include "cc/math_util.h" 10 #include "cc/math_util.h"
9 #include "ui/gfx/point_conversions.h" 11 #include "ui/gfx/point_conversions.h"
10 #include "ui/gfx/rect_conversions.h" 12 #include "ui/gfx/rect_conversions.h"
11 #include "ui/gfx/safe_integer_conversions.h" 13 #include "ui/gfx/safe_integer_conversions.h"
12 #include "ui/gfx/size_conversions.h" 14 #include "ui/gfx/size_conversions.h"
13 15
14 namespace cc { 16 namespace cc {
15 17
16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( 18 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 if (last_impl_frame_time_ != 0 && 386 if (last_impl_frame_time_ != 0 &&
385 last_layer_bounds == current_layer_bounds && 387 last_layer_bounds == current_layer_bounds &&
386 last_layer_content_bounds == current_layer_content_bounds && 388 last_layer_content_bounds == current_layer_content_bounds &&
387 last_layer_contents_scale == current_layer_contents_scale) { 389 last_layer_contents_scale == current_layer_contents_scale) {
388 time_delta = current_frame_time - last_impl_frame_time_; 390 time_delta = current_frame_time - last_impl_frame_time_;
389 } 391 }
390 392
391 gfx::Rect viewport_in_content_space = 393 gfx::Rect viewport_in_content_space =
392 gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space, 394 gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
393 contents_scale_)); 395 contents_scale_));
394 gfx::Rect inflated_rect = viewport_in_content_space; 396
395 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace / 397 static const int64 kMaxTilesForPrioritizedRect = 80;
nduca 2013/02/16 22:30:59 Should we put this by where the old constant lived
danakj 2013/02/18 19:26:20 Right, I feel like asking 3 people would get you 3
396 std::max(contents_scale_, 1.f); 398
397 inflated_rect.Inset( 399 gfx::Size tile_size = tiling_data_.max_texture_size();
398 -adjusted_inset, 400 int64 prioritized_rect_area = kMaxTilesForPrioritizedRect *
399 -adjusted_inset, 401 tile_size.width() * tile_size.height();
400 -adjusted_inset, 402
401 -adjusted_inset); 403 gfx::Rect prioritized_rect = ExpandRectEquallyToAreaBoundedBy(
402 inflated_rect.Intersect(ContentRect()); 404 viewport_in_content_space,
405 prioritized_rect_area,
406 ContentRect());
407 DCHECK(ContentRect().Contains(prioritized_rect));
403 408
404 // Iterate through all of the tiles that were live last frame but will 409 // Iterate through all of the tiles that were live last frame but will
405 // not be live this frame, and mark them as being dead. 410 // not be live this frame, and mark them as being dead.
406 for (TilingData::DifferenceIterator iter(&tiling_data_, 411 for (TilingData::DifferenceIterator iter(&tiling_data_,
407 last_prioritized_rect_, 412 last_prioritized_rect_,
408 inflated_rect); 413 prioritized_rect);
409 iter; 414 iter;
410 ++iter) { 415 ++iter) {
411 TileMap::iterator find = tiles_.find(iter.index()); 416 TileMap::iterator find = tiles_.find(iter.index());
412 if (find == tiles_.end()) 417 if (find == tiles_.end())
413 continue; 418 continue;
414 419
415 TilePriority priority; 420 TilePriority priority;
416 DCHECK(!priority.is_live); 421 DCHECK(!priority.is_live);
417 Tile* tile = find->second.get(); 422 Tile* tile = find->second.get();
418 tile->set_priority(tree, priority); 423 tile->set_priority(tree, priority);
419 } 424 }
420 last_prioritized_rect_ = inflated_rect; 425 last_prioritized_rect_ = prioritized_rect;
421 426
422 gfx::Rect view_rect(device_viewport); 427 gfx::Rect view_rect(device_viewport);
423 float current_scale = current_layer_contents_scale / contents_scale_; 428 float current_scale = current_layer_contents_scale / contents_scale_;
424 float last_scale = last_layer_contents_scale / contents_scale_; 429 float last_scale = last_layer_contents_scale / contents_scale_;
425 430
426 // Fast path tile priority calculation when both transforms are translations. 431 // Fast path tile priority calculation when both transforms are translations.
427 if (last_screen_transform.IsIdentityOrTranslation() && 432 if (last_screen_transform.IsIdentityOrTranslation() &&
428 current_screen_transform.IsIdentityOrTranslation()) 433 current_screen_transform.IsIdentityOrTranslation())
429 { 434 {
430 gfx::Vector2dF current_offset( 435 gfx::Vector2dF current_offset(
431 current_screen_transform.matrix().get(0, 3), 436 current_screen_transform.matrix().get(0, 3),
432 current_screen_transform.matrix().get(1, 3)); 437 current_screen_transform.matrix().get(1, 3));
433 gfx::Vector2dF last_offset( 438 gfx::Vector2dF last_offset(
434 last_screen_transform.matrix().get(0, 3), 439 last_screen_transform.matrix().get(0, 3),
435 last_screen_transform.matrix().get(1, 3)); 440 last_screen_transform.matrix().get(1, 3));
436 441
437 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); 442 for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
438 iter; ++iter) { 443 iter; ++iter) {
439 TileMap::iterator find = tiles_.find(iter.index()); 444 TileMap::iterator find = tiles_.find(iter.index());
440 if (find == tiles_.end()) 445 if (find == tiles_.end())
441 continue; 446 continue;
442 Tile* tile = find->second.get(); 447 Tile* tile = find->second.get();
443 448
444 gfx::Rect tile_bounds = 449 gfx::Rect tile_bounds =
445 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 450 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
446 gfx::RectF current_screen_rect = gfx::ScaleRect( 451 gfx::RectF current_screen_rect = gfx::ScaleRect(
447 tile_bounds, 452 tile_bounds,
(...skipping 12 matching lines...) Expand all
460 last_screen_rect, current_screen_rect, time_delta, view_rect); 465 last_screen_rect, current_screen_rect, time_delta, view_rect);
461 TilePriority priority( 466 TilePriority priority(
462 resolution_, 467 resolution_,
463 time_to_visible_in_seconds, 468 time_to_visible_in_seconds,
464 distance_to_visible_in_pixels); 469 distance_to_visible_in_pixels);
465 if (store_screen_space_quads_on_tiles) 470 if (store_screen_space_quads_on_tiles)
466 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); 471 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect));
467 tile->set_priority(tree, priority); 472 tile->set_priority(tree, priority);
468 } 473 }
469 } else { 474 } else {
470 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); 475 for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
471 iter; ++iter) { 476 iter; ++iter) {
472 TileMap::iterator find = tiles_.find(iter.index()); 477 TileMap::iterator find = tiles_.find(iter.index());
473 if (find == tiles_.end()) 478 if (find == tiles_.end())
474 continue; 479 continue;
475 Tile* tile = find->second.get(); 480 Tile* tile = find->second.get();
476 481
477 gfx::Rect tile_bounds = 482 gfx::Rect tile_bounds =
478 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 483 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
479 gfx::RectF current_layer_content_rect = gfx::ScaleRect( 484 gfx::RectF current_layer_content_rect = gfx::ScaleRect(
480 tile_bounds, 485 tile_bounds,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 537
533 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { 538 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
534 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 539 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
535 state->SetInteger("num_tiles", tiles_.size()); 540 state->SetInteger("num_tiles", tiles_.size());
536 state->SetDouble("content_scale", contents_scale_); 541 state->SetDouble("content_scale", contents_scale_);
537 state->Set("content_bounds", 542 state->Set("content_bounds",
538 MathUtil::asValue(ContentRect().size()).release()); 543 MathUtil::asValue(ContentRect().size()).release());
539 return state.PassAs<base::Value>(); 544 return state.PassAs<base::Value>();
540 } 545 }
541 546
547 namespace {
548
549 int ComputeOffsetToExpand4EdgesEqually(int old_width,
550 int old_height,
551 int64 target_area) {
552 // We need to expand the rect in 4 directions, we can compute the
553 // amount to expand along each axis with a quadratic equation:
554 // (old_w + add) * (old_h + add) = target_area
555 // old_w * old_h + old_w * add + add * old_h + add * add = target_area
556 // add^2 + add * (old_w + old_h) - target_area + old_w * old_h = 0
557 // Therefore, we solve the quadratic equation with:
558 // a = 1
559 // b = old_w + old_h
560 // c = -target_area + old_w * old_h
561 int a = 1;
562 int64 b = old_width + old_height;
563 int64 c = -target_area + old_width * old_height;
564 int sqrt_part = std::sqrt(b * b - 4.0 * a * c);
565 int add_each_axis = (-b + sqrt_part) / 2 / a;
566 return add_each_axis / 2;
567 }
568
569 int ComputeOffsetToExpand3EdgesEqually(int old_width,
570 int old_height,
571 int64 target_area,
572 bool left_complete,
573 bool top_complete,
574 bool right_complete,
575 bool bottom_complete) {
576 // We need to expand the rect in three directions, so we will have to
577 // expand along one axis twice as much as the other. Otherwise, this
578 // is very similar to the case where we expand in all 4 directions.
579
580 if (left_complete || right_complete) {
581 // Expanding twice as much vertically as horizontally.
582 // (old_w + add) * (old_h + add*2) = target_area
583 // old_w * old_h + old_w * add*2 + add * old_h + add * add*2 = target_area
584 // (add^2)*2 + add * (old_w*2 + old_h) - target_area + old_w * old_h = 0
585 // Therefore, we solve the quadratic equation with:
586 // a = 2
587 // b = old_w*2 + old_h
588 // c = -target_area + old_w * old_h
589 int a = 2;
590 int64 b = old_width * 2 + old_height;
591 int64 c = -target_area + old_width * old_height;
592 int sqrt_part = std::sqrt(b * b - 4.0 * a * c);
593 int add_each_direction = (-b + sqrt_part) / 2 / a;
594 return add_each_direction;
595 } else {
596 // Expanding twice as much horizontally as vertically.
597 // (old_w + add*2) * (old_h + add) = target_area
598 // old_w * old_h + old_w * add + add*2 * old_h + add*2 * add = target_area
599 // (add^2)*2 + add * (old_w + old_h*2) - target_area + old_w * old_h = 0
600 // Therefore, we solve the quadratic equation with:
601 // a = 2
602 // b = old_w + old_h*2
603 // c = -target_area + old_w * old_h
604 int a = 2;
605 int64 b = old_width + old_height * 2;
606 int64 c = -target_area + old_width * old_height;
607 int sqrt_part = std::sqrt(b * b - 4.0 * a * c);
608 int add_each_direction = (-b + sqrt_part) / 2 / a;
609 return add_each_direction;
610 }
611 }
612
613 int ComputeOffsetToExpand2EdgesEqually(int old_width,
614 int old_height,
615 int64 target_area,
616 bool left_complete,
617 bool top_complete,
618 bool right_complete,
619 bool bottom_complete) {
620 // We need to expand the rect along two directions. If the two directions
621 // are opposite from each other then we only need to compute a distance
622 // along a single axis.
623 if (left_complete && right_complete) {
624 // Expanding along the vertical axis only:
625 // old_w * (old_h + add) = target_area
626 // old_w * old_h + old_w * add = target_area
627 // add_vertically = (target_area - old_w * old_h) / old_w
628 int add_vertically = target_area / old_width - old_height;
629 return add_vertically / 2;
630 } else if (top_complete && bottom_complete) {
631 // Expanding along the horizontal axis only:
632 // (old_w + add) * old_h = target_area
633 // old_w * old_h + add * old_h = target_area
634 // add_horizontally = (target_area - old_w * old_h) / old_h
635 int add_horizontally = target_area / old_height - old_width;
636 return add_horizontally / 2;
637 } else {
638 // If we need to expand along both horizontal and vertical axes, we can use
639 // the same result as if we were expanding all four edges. But we apply the
640 // offset computed for opposing edges to a single edge.
641 int add_each_direction = ComputeOffsetToExpand4EdgesEqually(
642 old_width, old_height, target_area);
643 return add_each_direction * 2;
644 }
645 }
646
647 int ComputeOffsetToExpand1Edge(int old_width,
648 int old_height,
649 int64 target_area,
650 bool left_complete,
651 bool top_complete,
652 bool right_complete,
653 bool bottom_complete) {
654 // We need to expand the rect in a single direction, so we are either
655 // moving just a verical edge, or just a horizontal edge.
656 if (!top_complete || !bottom_complete) {
657 // Moving a vertical edge:
658 // old_w * (old_h + add) = target_area
659 // old_w * old_h + old_w * add = target_area
660 // add_vertically = (target_area - old_w * old_h) / old_w
661 int add_vertically = target_area / old_width - old_height;
662 return add_vertically;
663 } else {
664 // Moving a horizontal edge:
665 // (old_w + add) * old_h = target_area
666 // old_w * old_h + add * old_h = target_area
667 // add_horizontally = (target_area - old_w * old_h) / old_h
668 int add_horizontally = target_area / old_height - old_width;
669 return add_horizontally;
670 }
671 }
672
673 } // namespace
674
675 // static
676 gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
677 gfx::Rect starting_rect,
678 int64 target_area,
679 gfx::Rect bounding_rect) {
680
681 bool left_complete = false;
682 bool top_complete = false;
683 bool right_complete = false;
684 bool bottom_complete = false;
685 int num_edges_complete = 0;
686
687 gfx::Rect working_rect = starting_rect;
688 for (int i = 0; i < 4; ++i) {
689 if (num_edges_complete != i)
690 continue;
691 int offset_for_each_edge = 0;
692 switch (num_edges_complete) {
693 case 0:
694 offset_for_each_edge = ComputeOffsetToExpand4EdgesEqually(
695 working_rect.width(),
696 working_rect.height(),
697 target_area);
698 break;
699 case 1:
700 offset_for_each_edge = ComputeOffsetToExpand3EdgesEqually(
701 working_rect.width(),
702 working_rect.height(),
703 target_area,
704 left_complete,
705 top_complete,
706 right_complete,
707 bottom_complete);
708 break;
709 case 2:
710 offset_for_each_edge = ComputeOffsetToExpand2EdgesEqually(
711 working_rect.width(),
712 working_rect.height(),
713 target_area,
714 left_complete,
715 top_complete,
716 right_complete,
717 bottom_complete);
718 break;
719 case 3:
720 offset_for_each_edge = ComputeOffsetToExpand1Edge(
721 working_rect.width(),
722 working_rect.height(),
723 target_area,
724 left_complete,
725 top_complete,
726 right_complete,
727 bottom_complete);
728 }
729
730 working_rect.Inset((left_complete ? 0 : -offset_for_each_edge),
731 (top_complete ? 0 : -offset_for_each_edge),
732 (right_complete ? 0 : -offset_for_each_edge),
733 (bottom_complete ? 0 : -offset_for_each_edge));
734
735 if (bounding_rect.Contains(working_rect))
736 return working_rect;
737 working_rect.Intersect(bounding_rect);
738
739 if (working_rect.x() == bounding_rect.x()) left_complete = true;
740 if (working_rect.y() == bounding_rect.y()) top_complete = true;
741 if (working_rect.right() == bounding_rect.right()) right_complete = true;
742 if (working_rect.bottom() == bounding_rect.bottom()) bottom_complete = true;
743
744 num_edges_complete = (left_complete ? 1 : 0) +
745 (top_complete ? 1 : 0) +
746 (right_complete ? 1 : 0) +
747 (bottom_complete ? 1 : 0);
748 if (num_edges_complete == 4)
749 return working_rect;
750 }
751
752 NOTREACHED();
753 return starting_rect;
754 }
755
542 } // namespace cc 756 } // namespace cc
OLDNEW
« no previous file with comments | « cc/picture_layer_tiling.h ('k') | cc/picture_layer_tiling_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698