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/layers/picture_layer_impl.h" | 5 #include "cc/layers/picture_layer_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> |
8 | 9 |
9 #include "base/time/time.h" | 10 #include "base/time/time.h" |
10 #include "cc/base/math_util.h" | 11 #include "cc/base/math_util.h" |
11 #include "cc/base/util.h" | 12 #include "cc/base/util.h" |
12 #include "cc/debug/debug_colors.h" | 13 #include "cc/debug/debug_colors.h" |
13 #include "cc/debug/micro_benchmark_impl.h" | 14 #include "cc/debug/micro_benchmark_impl.h" |
14 #include "cc/debug/traced_value.h" | 15 #include "cc/debug/traced_value.h" |
15 #include "cc/layers/append_quads_data.h" | 16 #include "cc/layers/append_quads_data.h" |
16 #include "cc/layers/quad_sink.h" | 17 #include "cc/layers/quad_sink.h" |
17 #include "cc/quads/checkerboard_draw_quad.h" | 18 #include "cc/quads/checkerboard_draw_quad.h" |
18 #include "cc/quads/debug_border_draw_quad.h" | 19 #include "cc/quads/debug_border_draw_quad.h" |
19 #include "cc/quads/picture_draw_quad.h" | 20 #include "cc/quads/picture_draw_quad.h" |
20 #include "cc/quads/solid_color_draw_quad.h" | 21 #include "cc/quads/solid_color_draw_quad.h" |
21 #include "cc/quads/tile_draw_quad.h" | 22 #include "cc/quads/tile_draw_quad.h" |
22 #include "cc/resources/tile_manager.h" | 23 #include "cc/resources/tile_manager.h" |
23 #include "cc/trees/layer_tree_impl.h" | 24 #include "cc/trees/layer_tree_impl.h" |
24 #include "ui/gfx/quad_f.h" | 25 #include "ui/gfx/quad_f.h" |
25 #include "ui/gfx/rect_conversions.h" | 26 #include "ui/gfx/rect_conversions.h" |
26 #include "ui/gfx/size_conversions.h" | 27 #include "ui/gfx/size_conversions.h" |
27 | 28 |
28 namespace { | 29 namespace { |
29 const float kMaxScaleRatioDuringPinch = 2.0f; | 30 const float kMaxScaleRatioDuringPinch = 2.0f; |
| 31 |
| 32 // When creating a new tiling during pinch, snap to an existing |
| 33 // tiling's scale if the desired scale is within this ratio. |
| 34 const float kSnapToExistingTilingRatio = 0.2f; |
30 } | 35 } |
31 | 36 |
32 namespace cc { | 37 namespace cc { |
33 | 38 |
34 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) | 39 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) |
35 : LayerImpl(tree_impl, id), | 40 : LayerImpl(tree_impl, id), |
36 twin_layer_(NULL), | 41 twin_layer_(NULL), |
37 pile_(PicturePileImpl::Create()), | 42 pile_(PicturePileImpl::Create()), |
38 last_content_scale_(0), | 43 last_content_scale_(0), |
39 is_mask_(false), | 44 is_mask_(false), |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 | 826 |
822 // Store the value for the next time ShouldAdjustRasterScale is called. | 827 // Store the value for the next time ShouldAdjustRasterScale is called. |
823 raster_source_scale_was_animating_ = animating_transform_to_screen; | 828 raster_source_scale_was_animating_ = animating_transform_to_screen; |
824 | 829 |
825 if (!change_target_tiling) | 830 if (!change_target_tiling) |
826 return; | 831 return; |
827 | 832 |
828 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) | 833 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) |
829 return; | 834 return; |
830 | 835 |
831 raster_page_scale_ = ideal_page_scale_; | 836 RecalculateRasterScales(animating_transform_to_screen); |
832 raster_device_scale_ = ideal_device_scale_; | |
833 raster_source_scale_ = ideal_source_scale_; | |
834 | |
835 CalculateRasterContentsScale(animating_transform_to_screen, | |
836 &raster_contents_scale_, | |
837 &low_res_raster_contents_scale_); | |
838 | 837 |
839 PictureLayerTiling* high_res = NULL; | 838 PictureLayerTiling* high_res = NULL; |
840 PictureLayerTiling* low_res = NULL; | 839 PictureLayerTiling* low_res = NULL; |
841 | 840 |
842 PictureLayerTiling* previous_low_res = NULL; | 841 PictureLayerTiling* previous_low_res = NULL; |
843 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | 842 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
844 PictureLayerTiling* tiling = tilings_->tiling_at(i); | 843 PictureLayerTiling* tiling = tilings_->tiling_at(i); |
845 if (tiling->contents_scale() == raster_contents_scale_) | 844 if (tiling->contents_scale() == raster_contents_scale_) |
846 high_res = tiling; | 845 high_res = tiling; |
847 if (tiling->contents_scale() == low_res_raster_contents_scale_) | 846 if (tiling->contents_scale() == low_res_raster_contents_scale_) |
(...skipping 12 matching lines...) Expand all Loading... |
860 } | 859 } |
861 | 860 |
862 // Only create new low res tilings when the transform is static. This | 861 // Only create new low res tilings when the transform is static. This |
863 // prevents wastefully creating a paired low res tiling for every new high res | 862 // prevents wastefully creating a paired low res tiling for every new high res |
864 // tiling during a pinch or a CSS animation. | 863 // tiling during a pinch or a CSS animation. |
865 bool is_pinching = layer_tree_impl()->PinchGestureActive(); | 864 bool is_pinching = layer_tree_impl()->PinchGestureActive(); |
866 if (!is_pinching && !animating_transform_to_screen && !low_res && | 865 if (!is_pinching && !animating_transform_to_screen && !low_res && |
867 low_res != high_res) | 866 low_res != high_res) |
868 low_res = AddTiling(low_res_raster_contents_scale_); | 867 low_res = AddTiling(low_res_raster_contents_scale_); |
869 | 868 |
870 high_res->set_resolution(HIGH_RESOLUTION); | 869 // Set low-res if we have one. |
871 if (!low_res) | 870 if (!low_res) |
872 low_res = previous_low_res; | 871 low_res = previous_low_res; |
873 if (low_res && low_res != high_res) | 872 if (low_res && low_res != high_res) |
874 low_res->set_resolution(LOW_RESOLUTION); | 873 low_res->set_resolution(LOW_RESOLUTION); |
875 | 874 |
| 875 // Make sure we always have one high-res (even if high == low). |
| 876 high_res->set_resolution(HIGH_RESOLUTION); |
| 877 |
876 SanityCheckTilingState(); | 878 SanityCheckTilingState(); |
877 } | 879 } |
878 | 880 |
879 bool PictureLayerImpl::ShouldAdjustRasterScale( | 881 bool PictureLayerImpl::ShouldAdjustRasterScale( |
880 bool animating_transform_to_screen) const { | 882 bool animating_transform_to_screen) const { |
881 // TODO(danakj): Adjust raster source scale closer to ideal source scale at | 883 // TODO(danakj): Adjust raster source scale closer to ideal source scale at |
882 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending | 884 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending |
883 // tree. This will allow CSS scale changes to get re-rastered at an | 885 // tree. This will allow CSS scale changes to get re-rastered at an |
884 // appropriate rate. | 886 // appropriate rate. |
885 | 887 |
886 if (raster_source_scale_was_animating_ && !animating_transform_to_screen) | 888 if (raster_source_scale_was_animating_ && !animating_transform_to_screen) |
887 return true; | 889 return true; |
888 | 890 |
889 bool is_pinching = layer_tree_impl()->PinchGestureActive(); | 891 bool is_pinching = layer_tree_impl()->PinchGestureActive(); |
890 if (is_pinching && raster_page_scale_) { | 892 if (is_pinching && raster_page_scale_) { |
891 // If the page scale diverges too far during pinch, change raster target to | 893 // We change our raster scale when it is: |
892 // the current page scale. | 894 // - Higher than ideal (need a lower-res tiling available) |
893 float ratio = PositiveRatio(ideal_page_scale_, raster_page_scale_); | 895 // - Too far from ideal (need a higher-res tiling available) |
894 if (ratio >= kMaxScaleRatioDuringPinch) | 896 float ratio = ideal_page_scale_ / raster_page_scale_; |
| 897 if (raster_page_scale_ > ideal_page_scale_ || |
| 898 ratio > kMaxScaleRatioDuringPinch) |
895 return true; | 899 return true; |
896 } | 900 } |
897 | 901 |
898 if (!is_pinching) { | 902 if (!is_pinching) { |
899 // When not pinching, match the ideal page scale factor. | 903 // When not pinching, match the ideal page scale factor. |
900 if (raster_page_scale_ != ideal_page_scale_) | 904 if (raster_page_scale_ != ideal_page_scale_) |
901 return true; | 905 return true; |
902 } | 906 } |
903 | 907 |
904 // Always match the ideal device scale factor. | 908 // Always match the ideal device scale factor. |
905 if (raster_device_scale_ != ideal_device_scale_) | 909 if (raster_device_scale_ != ideal_device_scale_) |
906 return true; | 910 return true; |
907 | 911 |
908 return false; | 912 return false; |
909 } | 913 } |
910 | 914 |
911 void PictureLayerImpl::CalculateRasterContentsScale( | 915 float PictureLayerImpl::SnappedContentsScale(float scale) { |
912 bool animating_transform_to_screen, | 916 // If a tiling exists within the max snapping ratio, snap to its scale. |
913 float* raster_contents_scale, | 917 float snapped_contents_scale = scale; |
914 float* low_res_raster_contents_scale) const { | 918 float snapped_ratio = kSnapToExistingTilingRatio; |
915 *raster_contents_scale = ideal_contents_scale_; | 919 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
| 920 float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale(); |
| 921 float ratio = PositiveRatio(tiling_contents_scale, scale); |
| 922 if (ratio < snapped_ratio) { |
| 923 snapped_contents_scale = tiling_contents_scale; |
| 924 snapped_ratio = ratio; |
| 925 } |
| 926 } |
| 927 return snapped_contents_scale; |
| 928 } |
| 929 |
| 930 void PictureLayerImpl::RecalculateRasterScales( |
| 931 bool animating_transform_to_screen) { |
| 932 raster_device_scale_ = ideal_device_scale_; |
| 933 raster_source_scale_ = ideal_source_scale_; |
| 934 |
| 935 bool is_pinching = layer_tree_impl()->PinchGestureActive(); |
| 936 if (!is_pinching) { |
| 937 // When not pinching, we use ideal scale: |
| 938 raster_page_scale_ = ideal_page_scale_; |
| 939 raster_contents_scale_ = ideal_contents_scale_; |
| 940 } else { |
| 941 // See ShouldAdjustRasterScale: |
| 942 // - When zooming out, preemptively create new tiling at lower resolution. |
| 943 // - When zooming in, approximate ideal using multiple of kMaxScaleRatio. |
| 944 bool zooming_out = raster_page_scale_ > ideal_page_scale_; |
| 945 float desired_contents_scale = |
| 946 zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch |
| 947 : raster_contents_scale_ * kMaxScaleRatioDuringPinch; |
| 948 raster_contents_scale_ = SnappedContentsScale(desired_contents_scale); |
| 949 raster_page_scale_ = raster_contents_scale_ / raster_device_scale_; |
| 950 } |
916 | 951 |
917 // Don't allow animating CSS scales to drop below 1. This is needed because | 952 // Don't allow animating CSS scales to drop below 1. This is needed because |
918 // changes in raster source scale aren't handled. See the comment in | 953 // changes in raster source scale aren't handled. See the comment in |
919 // ShouldAdjustRasterScale. | 954 // ShouldAdjustRasterScale. |
920 if (animating_transform_to_screen) { | 955 if (animating_transform_to_screen) { |
921 *raster_contents_scale = std::max( | 956 raster_contents_scale_ = std::max( |
922 *raster_contents_scale, 1.f * ideal_page_scale_ * ideal_device_scale_); | 957 raster_contents_scale_, 1.f * ideal_page_scale_ * ideal_device_scale_); |
923 } | 958 } |
924 | 959 |
925 // If this layer would only create one tile at this content scale, | 960 // If this layer would only create one tile at this content scale, |
926 // don't create a low res tiling. | 961 // don't create a low res tiling. |
927 gfx::Size content_bounds = | 962 gfx::Size content_bounds = |
928 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), *raster_contents_scale)); | 963 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_)); |
929 gfx::Size tile_size = CalculateTileSize(content_bounds); | 964 gfx::Size tile_size = CalculateTileSize(content_bounds); |
930 if (tile_size.width() >= content_bounds.width() && | 965 if (tile_size.width() >= content_bounds.width() && |
931 tile_size.height() >= content_bounds.height()) { | 966 tile_size.height() >= content_bounds.height()) { |
932 *low_res_raster_contents_scale = *raster_contents_scale; | 967 low_res_raster_contents_scale_ = raster_contents_scale_; |
933 return; | 968 return; |
934 } | 969 } |
935 | 970 |
936 float low_res_factor = | 971 float low_res_factor = |
937 layer_tree_impl()->settings().low_res_contents_scale_factor; | 972 layer_tree_impl()->settings().low_res_contents_scale_factor; |
938 *low_res_raster_contents_scale = std::max( | 973 low_res_raster_contents_scale_ = std::max( |
939 *raster_contents_scale * low_res_factor, | 974 raster_contents_scale_ * low_res_factor, |
940 MinimumContentsScale()); | 975 MinimumContentsScale()); |
941 } | 976 } |
942 | 977 |
943 void PictureLayerImpl::CleanUpTilingsOnActiveLayer( | 978 void PictureLayerImpl::CleanUpTilingsOnActiveLayer( |
944 std::vector<PictureLayerTiling*> used_tilings) { | 979 std::vector<PictureLayerTiling*> used_tilings) { |
945 DCHECK(layer_tree_impl()->IsActiveTree()); | 980 DCHECK(layer_tree_impl()->IsActiveTree()); |
946 if (tilings_->num_tilings() == 0) | 981 if (tilings_->num_tilings() == 0) |
947 return; | 982 return; |
948 | 983 |
949 float min_acceptable_high_res_scale = std::min( | 984 float min_acceptable_high_res_scale = std::min( |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const { | 1144 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const { |
1110 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded(); | 1145 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded(); |
1111 return tilings_->GPUMemoryUsageInBytes(); | 1146 return tilings_->GPUMemoryUsageInBytes(); |
1112 } | 1147 } |
1113 | 1148 |
1114 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { | 1149 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { |
1115 benchmark->RunOnLayer(this); | 1150 benchmark->RunOnLayer(this); |
1116 } | 1151 } |
1117 | 1152 |
1118 } // namespace cc | 1153 } // namespace cc |
OLD | NEW |