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 #include <limits> | 9 #include <limits> |
10 #include <set> | 10 #include <set> |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 int skewport_extrapolation_limit_in_content_pixels) | 50 int skewport_extrapolation_limit_in_content_pixels) |
51 : max_tiles_for_interest_area_(max_tiles_for_interest_area), | 51 : max_tiles_for_interest_area_(max_tiles_for_interest_area), |
52 skewport_target_time_in_seconds_(skewport_target_time_in_seconds), | 52 skewport_target_time_in_seconds_(skewport_target_time_in_seconds), |
53 skewport_extrapolation_limit_in_content_pixels_( | 53 skewport_extrapolation_limit_in_content_pixels_( |
54 skewport_extrapolation_limit_in_content_pixels), | 54 skewport_extrapolation_limit_in_content_pixels), |
55 contents_scale_(contents_scale), | 55 contents_scale_(contents_scale), |
56 client_(client), | 56 client_(client), |
57 raster_source_(raster_source), | 57 raster_source_(raster_source), |
58 resolution_(NON_IDEAL_RESOLUTION), | 58 resolution_(NON_IDEAL_RESOLUTION), |
59 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), | 59 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), |
60 last_impl_frame_time_in_seconds_(0.0), | |
61 can_require_tiles_for_activation_(false), | 60 can_require_tiles_for_activation_(false), |
62 current_content_to_screen_scale_(0.f), | 61 current_content_to_screen_scale_(0.f), |
63 has_visible_rect_tiles_(false), | 62 has_visible_rect_tiles_(false), |
64 has_skewport_rect_tiles_(false), | 63 has_skewport_rect_tiles_(false), |
65 has_soon_border_rect_tiles_(false), | 64 has_soon_border_rect_tiles_(false), |
66 has_eventually_rect_tiles_(false) { | 65 has_eventually_rect_tiles_(false) { |
67 DCHECK(!raster_source->IsSolidColor()); | 66 DCHECK(!raster_source->IsSolidColor()); |
68 gfx::Size content_bounds = gfx::ToCeiledSize( | 67 gfx::Size content_bounds = gfx::ToCeiledSize( |
69 gfx::ScaleSize(raster_source_->GetSize(), contents_scale)); | 68 gfx::ScaleSize(raster_source_->GetSize(), contents_scale)); |
70 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 69 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 if (recycled_twin) | 522 if (recycled_twin) |
524 recycled_twin->RemoveTileAt(it->first.first, it->first.second, nullptr); | 523 recycled_twin->RemoveTileAt(it->first.first, it->first.second, nullptr); |
525 } | 524 } |
526 tiles_.clear(); | 525 tiles_.clear(); |
527 } | 526 } |
528 | 527 |
529 gfx::Rect PictureLayerTiling::ComputeSkewport( | 528 gfx::Rect PictureLayerTiling::ComputeSkewport( |
530 double current_frame_time_in_seconds, | 529 double current_frame_time_in_seconds, |
531 const gfx::Rect& visible_rect_in_content_space) const { | 530 const gfx::Rect& visible_rect_in_content_space) const { |
532 gfx::Rect skewport = visible_rect_in_content_space; | 531 gfx::Rect skewport = visible_rect_in_content_space; |
533 if (last_impl_frame_time_in_seconds_ == 0.0) | 532 if (skewport.IsEmpty()) |
534 return skewport; | 533 return skewport; |
535 | 534 |
536 double time_delta = | 535 if (visible_rect_history_[1].frame_time_in_seconds == 0.0) |
537 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_; | 536 return skewport; |
| 537 |
| 538 double time_delta = current_frame_time_in_seconds - |
| 539 visible_rect_history_[1].frame_time_in_seconds; |
538 if (time_delta == 0.0) | 540 if (time_delta == 0.0) |
539 return skewport; | 541 return skewport; |
540 | 542 |
541 double extrapolation_multiplier = | 543 double extrapolation_multiplier = |
542 skewport_target_time_in_seconds_ / time_delta; | 544 skewport_target_time_in_seconds_ / time_delta; |
543 | 545 |
544 int old_x = last_visible_rect_in_content_space_.x(); | 546 int old_x = visible_rect_history_[1].visible_rect_in_content_space.x(); |
545 int old_y = last_visible_rect_in_content_space_.y(); | 547 int old_y = visible_rect_history_[1].visible_rect_in_content_space.y(); |
546 int old_right = last_visible_rect_in_content_space_.right(); | 548 int old_right = |
547 int old_bottom = last_visible_rect_in_content_space_.bottom(); | 549 visible_rect_history_[1].visible_rect_in_content_space.right(); |
| 550 int old_bottom = |
| 551 visible_rect_history_[1].visible_rect_in_content_space.bottom(); |
548 | 552 |
549 int new_x = visible_rect_in_content_space.x(); | 553 int new_x = visible_rect_in_content_space.x(); |
550 int new_y = visible_rect_in_content_space.y(); | 554 int new_y = visible_rect_in_content_space.y(); |
551 int new_right = visible_rect_in_content_space.right(); | 555 int new_right = visible_rect_in_content_space.right(); |
552 int new_bottom = visible_rect_in_content_space.bottom(); | 556 int new_bottom = visible_rect_in_content_space.bottom(); |
553 | 557 |
554 // Compute the maximum skewport based on | 558 // Compute the maximum skewport based on |
555 // |skewport_extrapolation_limit_in_content_pixels_|. | 559 // |skewport_extrapolation_limit_in_content_pixels_|. |
556 gfx::Rect max_skewport = skewport; | 560 gfx::Rect max_skewport = skewport; |
557 max_skewport.Inset(-skewport_extrapolation_limit_in_content_pixels_, | 561 max_skewport.Inset(-skewport_extrapolation_limit_in_content_pixels_, |
558 -skewport_extrapolation_limit_in_content_pixels_); | 562 -skewport_extrapolation_limit_in_content_pixels_); |
559 | 563 |
560 // Inset the skewport by the needed adjustment. | 564 // Inset the skewport by the needed adjustment. |
561 skewport.Inset(extrapolation_multiplier * (new_x - old_x), | 565 skewport.Inset(extrapolation_multiplier * (new_x - old_x), |
562 extrapolation_multiplier * (new_y - old_y), | 566 extrapolation_multiplier * (new_y - old_y), |
563 extrapolation_multiplier * (old_right - new_right), | 567 extrapolation_multiplier * (old_right - new_right), |
564 extrapolation_multiplier * (old_bottom - new_bottom)); | 568 extrapolation_multiplier * (old_bottom - new_bottom)); |
565 | 569 |
566 // Clip the skewport to |max_skewport|. | 570 // Ensure that visible rect is contained in the skewport. |
| 571 skewport.Union(visible_rect_in_content_space); |
| 572 |
| 573 // Clip the skewport to |max_skewport|. This needs to happen after the |
| 574 // union in case intersecting would have left the empty rect. |
567 skewport.Intersect(max_skewport); | 575 skewport.Intersect(max_skewport); |
568 | 576 |
569 // Finally, ensure that visible rect is contained in the skewport. | |
570 skewport.Union(visible_rect_in_content_space); | |
571 return skewport; | 577 return skewport; |
572 } | 578 } |
573 | 579 |
574 bool PictureLayerTiling::ComputeTilePriorityRects( | 580 bool PictureLayerTiling::ComputeTilePriorityRects( |
575 const gfx::Rect& viewport_in_layer_space, | 581 const gfx::Rect& viewport_in_layer_space, |
576 float ideal_contents_scale, | 582 float ideal_contents_scale, |
577 double current_frame_time_in_seconds, | 583 double current_frame_time_in_seconds, |
578 const Occlusion& occlusion_in_layer_space) { | 584 const Occlusion& occlusion_in_layer_space) { |
579 if (!NeedsUpdateForFrameAtTimeAndViewport(current_frame_time_in_seconds, | 585 if (!NeedsUpdateForFrameAtTimeAndViewport(current_frame_time_in_seconds, |
580 viewport_in_layer_space)) { | 586 viewport_in_layer_space)) { |
581 // This should never be zero for the purposes of has_ever_been_updated(). | 587 // This should never be zero for the purposes of has_ever_been_updated(). |
582 DCHECK_NE(current_frame_time_in_seconds, 0.0); | 588 DCHECK_NE(current_frame_time_in_seconds, 0.0); |
583 return false; | 589 return false; |
584 } | 590 } |
585 | 591 |
586 gfx::Rect visible_rect_in_content_space = | 592 gfx::Rect visible_rect_in_content_space = |
587 gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_); | 593 gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_); |
588 | 594 |
589 if (tiling_size().IsEmpty()) { | 595 if (tiling_size().IsEmpty()) { |
590 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 596 UpdateVisibleRectHistory(current_frame_time_in_seconds, |
| 597 visible_rect_in_content_space); |
591 last_viewport_in_layer_space_ = viewport_in_layer_space; | 598 last_viewport_in_layer_space_ = viewport_in_layer_space; |
592 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | |
593 return false; | 599 return false; |
594 } | 600 } |
595 | 601 |
596 // Calculate the skewport. | 602 // Calculate the skewport. |
597 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | 603 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, |
598 visible_rect_in_content_space); | 604 visible_rect_in_content_space); |
599 DCHECK(skewport.Contains(visible_rect_in_content_space)); | 605 DCHECK(skewport.Contains(visible_rect_in_content_space)); |
600 | 606 |
601 // Calculate the eventually/live tiles rect. | 607 // Calculate the eventually/live tiles rect. |
602 gfx::Size tile_size = tiling_data_.max_texture_size(); | 608 gfx::Size tile_size = tiling_data_.max_texture_size(); |
(...skipping 11 matching lines...) Expand all Loading... |
614 << "tiling_size: " << tiling_size().ToString() | 620 << "tiling_size: " << tiling_size().ToString() |
615 << " eventually_rect: " << eventually_rect.ToString(); | 621 << " eventually_rect: " << eventually_rect.ToString(); |
616 | 622 |
617 // Calculate the soon border rect. | 623 // Calculate the soon border rect. |
618 float content_to_screen_scale = ideal_contents_scale / contents_scale_; | 624 float content_to_screen_scale = ideal_contents_scale / contents_scale_; |
619 gfx::Rect soon_border_rect = visible_rect_in_content_space; | 625 gfx::Rect soon_border_rect = visible_rect_in_content_space; |
620 float border = CalculateSoonBorderDistance(visible_rect_in_content_space, | 626 float border = CalculateSoonBorderDistance(visible_rect_in_content_space, |
621 content_to_screen_scale); | 627 content_to_screen_scale); |
622 soon_border_rect.Inset(-border, -border, -border, -border); | 628 soon_border_rect.Inset(-border, -border, -border, -border); |
623 | 629 |
624 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 630 UpdateVisibleRectHistory(current_frame_time_in_seconds, |
| 631 visible_rect_in_content_space); |
625 last_viewport_in_layer_space_ = viewport_in_layer_space; | 632 last_viewport_in_layer_space_ = viewport_in_layer_space; |
626 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | |
627 | 633 |
628 SetLiveTilesRect(eventually_rect); | 634 SetLiveTilesRect(eventually_rect); |
629 UpdateTilePriorityRects( | 635 UpdateTilePriorityRects( |
630 content_to_screen_scale, visible_rect_in_content_space, skewport, | 636 content_to_screen_scale, visible_rect_in_content_space, skewport, |
631 soon_border_rect, eventually_rect, occlusion_in_layer_space); | 637 soon_border_rect, eventually_rect, occlusion_in_layer_space); |
632 return true; | 638 return true; |
633 } | 639 } |
634 | 640 |
635 void PictureLayerTiling::UpdateTilePriorityRects( | 641 void PictureLayerTiling::UpdateTilePriorityRects( |
636 float content_to_screen_scale, | 642 float content_to_screen_scale, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 if (IsTileOccluded(tile)) | 805 if (IsTileOccluded(tile)) |
800 return false; | 806 return false; |
801 | 807 |
802 return true; | 808 return true; |
803 } | 809 } |
804 | 810 |
805 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { | 811 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { |
806 WhichTree tree = client_->GetTree(); | 812 WhichTree tree = client_->GetTree(); |
807 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; | 813 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; |
808 | 814 |
809 UpdateTilePriorityForTree(tile, tree); | 815 tile->SetPriority(tree, ComputePriorityForTile(tile)); |
| 816 UpdateRequiredStateForTile(tile, tree); |
810 | 817 |
811 const PictureLayerTiling* twin_tiling = | 818 const PictureLayerTiling* twin_tiling = |
812 client_->GetPendingOrActiveTwinTiling(this); | 819 client_->GetPendingOrActiveTwinTiling(this); |
813 if (!tile->is_shared() || !twin_tiling) { | 820 if (!tile->is_shared() || !twin_tiling) { |
814 tile->SetPriority(twin_tree, TilePriority()); | 821 tile->SetPriority(twin_tree, TilePriority()); |
815 tile->set_is_occluded(twin_tree, false); | 822 tile->set_is_occluded(twin_tree, false); |
816 if (twin_tree == PENDING_TREE) | 823 if (twin_tree == PENDING_TREE) |
817 tile->set_required_for_activation(false); | 824 tile->set_required_for_activation(false); |
818 else | 825 else |
819 tile->set_required_for_draw(false); | 826 tile->set_required_for_draw(false); |
820 return; | 827 return; |
821 } | 828 } |
822 | 829 |
823 twin_tiling->UpdateTilePriorityForTree(tile, twin_tree); | 830 tile->SetPriority(twin_tree, twin_tiling->ComputePriorityForTile(tile)); |
| 831 twin_tiling->UpdateRequiredStateForTile(tile, twin_tree); |
824 } | 832 } |
825 | 833 |
826 void PictureLayerTiling::UpdateTilePriorityForTree(Tile* tile, | 834 void PictureLayerTiling::UpdateRequiredStateForTile(Tile* tile, |
827 WhichTree tree) const { | 835 WhichTree tree) const { |
828 // TODO(vmpstr): This code should return the priority instead of setting it on | 836 if (tile->priority(tree).priority_bin == TilePriority::NOW) { |
829 // the tile. This should be a part of the change to move tile priority from | |
830 // tiles into iterators. | |
831 TilePriority::PriorityBin max_tile_priority_bin = | |
832 client_->GetMaxTilePriorityBin(); | |
833 | |
834 DCHECK_EQ(TileAt(tile->tiling_i_index(), tile->tiling_j_index()), tile); | |
835 gfx::Rect tile_bounds = | |
836 tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); | |
837 | |
838 if (max_tile_priority_bin <= TilePriority::NOW && | |
839 current_visible_rect_.Intersects(tile_bounds)) { | |
840 tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0)); | |
841 if (tree == PENDING_TREE) { | 837 if (tree == PENDING_TREE) { |
842 tile->set_required_for_activation( | 838 tile->set_required_for_activation( |
843 IsTileRequiredForActivationIfVisible(tile)); | 839 IsTileRequiredForActivationIfVisible(tile)); |
844 } else { | 840 } else { |
845 tile->set_required_for_draw(IsTileRequiredForDrawIfVisible(tile)); | 841 tile->set_required_for_draw(IsTileRequiredForDrawIfVisible(tile)); |
846 } | 842 } |
847 tile->set_is_occluded(tree, IsTileOccluded(tile)); | 843 tile->set_is_occluded(tree, IsTileOccluded(tile)); |
848 return; | 844 return; |
849 } | 845 } |
850 | 846 |
| 847 // Non-NOW bin tiles are not required or occluded. |
851 if (tree == PENDING_TREE) | 848 if (tree == PENDING_TREE) |
852 tile->set_required_for_activation(false); | 849 tile->set_required_for_activation(false); |
853 else | 850 else |
854 tile->set_required_for_draw(false); | 851 tile->set_required_for_draw(false); |
855 tile->set_is_occluded(tree, false); | 852 tile->set_is_occluded(tree, false); |
| 853 } |
| 854 |
| 855 TilePriority PictureLayerTiling::ComputePriorityForTile( |
| 856 const Tile* tile) const { |
| 857 // TODO(vmpstr): See if this can be moved to iterators. |
| 858 TilePriority::PriorityBin max_tile_priority_bin = |
| 859 client_->GetMaxTilePriorityBin(); |
| 860 |
| 861 DCHECK_EQ(TileAt(tile->tiling_i_index(), tile->tiling_j_index()), tile); |
| 862 gfx::Rect tile_bounds = |
| 863 tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); |
| 864 |
| 865 if (max_tile_priority_bin <= TilePriority::NOW && |
| 866 current_visible_rect_.Intersects(tile_bounds)) { |
| 867 return TilePriority(resolution_, TilePriority::NOW, 0); |
| 868 } |
856 | 869 |
857 DCHECK_GT(current_content_to_screen_scale_, 0.f); | 870 DCHECK_GT(current_content_to_screen_scale_, 0.f); |
858 float distance_to_visible = | 871 float distance_to_visible = |
859 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * | 872 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * |
860 current_content_to_screen_scale_; | 873 current_content_to_screen_scale_; |
861 | 874 |
862 if (max_tile_priority_bin <= TilePriority::SOON && | 875 if (max_tile_priority_bin <= TilePriority::SOON && |
863 (current_soon_border_rect_.Intersects(tile_bounds) || | 876 (current_soon_border_rect_.Intersects(tile_bounds) || |
864 current_skewport_rect_.Intersects(tile_bounds))) { | 877 current_skewport_rect_.Intersects(tile_bounds))) { |
865 tile->SetPriority( | 878 return TilePriority(resolution_, TilePriority::SOON, distance_to_visible); |
866 tree, | |
867 TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); | |
868 return; | |
869 } | 879 } |
870 | 880 |
871 tile->SetPriority( | 881 return TilePriority(resolution_, TilePriority::EVENTUALLY, |
872 tree, | 882 distance_to_visible); |
873 TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible)); | |
874 } | 883 } |
875 | 884 |
876 void PictureLayerTiling::GetAllTilesForTracing( | 885 void PictureLayerTiling::GetAllTilesAndPrioritiesForTracing( |
877 std::set<const Tile*>* tiles) const { | 886 std::map<const Tile*, TilePriority>* tile_map) const { |
878 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 887 const PictureLayerTiling* twin_tiling = |
879 tiles->insert(it->second.get()); | 888 client_->GetPendingOrActiveTwinTiling(this); |
| 889 for (const auto& tile_pair : tiles_) { |
| 890 const Tile* tile = tile_pair.second.get(); |
| 891 const TilePriority& priority = ComputePriorityForTile(tile); |
| 892 const TilePriority& twin_priority = |
| 893 twin_tiling ? twin_tiling->ComputePriorityForTile(tile) |
| 894 : TilePriority(); |
| 895 |
| 896 // Store combined priority. |
| 897 (*tile_map)[tile] = TilePriority(priority, twin_priority); |
| 898 } |
880 } | 899 } |
881 | 900 |
882 void PictureLayerTiling::AsValueInto( | 901 void PictureLayerTiling::AsValueInto( |
883 base::trace_event::TracedValue* state) const { | 902 base::trace_event::TracedValue* state) const { |
884 state->SetInteger("num_tiles", tiles_.size()); | 903 state->SetInteger("num_tiles", tiles_.size()); |
885 state->SetDouble("content_scale", contents_scale_); | 904 state->SetDouble("content_scale", contents_scale_); |
| 905 MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); |
| 906 MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state); |
| 907 MathUtil::AddToTracedValue("soon_rect", current_soon_border_rect_, state); |
| 908 MathUtil::AddToTracedValue("eventually_rect", current_eventually_rect_, |
| 909 state); |
886 MathUtil::AddToTracedValue("tiling_size", tiling_size(), state); | 910 MathUtil::AddToTracedValue("tiling_size", tiling_size(), state); |
887 } | 911 } |
888 | 912 |
889 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 913 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |
890 size_t amount = 0; | 914 size_t amount = 0; |
891 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 915 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
892 const Tile* tile = it->second.get(); | 916 const Tile* tile = it->second.get(); |
893 amount += tile->GPUMemoryUsageInBytes(); | 917 amount += tile->GPUMemoryUsageInBytes(); |
894 } | 918 } |
895 return amount; | 919 return amount; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 break; | 1064 break; |
1041 } | 1065 } |
1042 | 1066 |
1043 gfx::Rect result(origin_x, origin_y, width, height); | 1067 gfx::Rect result(origin_x, origin_y, width, height); |
1044 if (cache) | 1068 if (cache) |
1045 cache->previous_result = result; | 1069 cache->previous_result = result; |
1046 return result; | 1070 return result; |
1047 } | 1071 } |
1048 | 1072 |
1049 } // namespace cc | 1073 } // namespace cc |
OLD | NEW |