Chromium Code Reviews| 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 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 | 814 |
| 810 // Store the value for the next time ShouldAdjustRasterScale is called. | 815 // Store the value for the next time ShouldAdjustRasterScale is called. |
| 811 raster_source_scale_was_animating_ = animating_transform_to_screen; | 816 raster_source_scale_was_animating_ = animating_transform_to_screen; |
| 812 | 817 |
| 813 if (!change_target_tiling) | 818 if (!change_target_tiling) |
| 814 return; | 819 return; |
| 815 | 820 |
| 816 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) | 821 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) |
| 817 return; | 822 return; |
| 818 | 823 |
| 819 raster_page_scale_ = ideal_page_scale_; | 824 RecalculateRasterScales(animating_transform_to_screen); |
| 820 raster_device_scale_ = ideal_device_scale_; | |
| 821 raster_source_scale_ = ideal_source_scale_; | |
| 822 | |
| 823 CalculateRasterContentsScale(animating_transform_to_screen, | |
| 824 &raster_contents_scale_, | |
| 825 &low_res_raster_contents_scale_); | |
| 826 | 825 |
| 827 PictureLayerTiling* high_res = NULL; | 826 PictureLayerTiling* high_res = NULL; |
| 828 PictureLayerTiling* low_res = NULL; | 827 PictureLayerTiling* low_res = NULL; |
| 829 | 828 |
| 830 PictureLayerTiling* previous_low_res = NULL; | 829 PictureLayerTiling* previous_low_res = NULL; |
| 831 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | 830 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
| 832 PictureLayerTiling* tiling = tilings_->tiling_at(i); | 831 PictureLayerTiling* tiling = tilings_->tiling_at(i); |
| 833 if (tiling->contents_scale() == raster_contents_scale_) | 832 if (tiling->contents_scale() == raster_contents_scale_) |
| 834 high_res = tiling; | 833 high_res = tiling; |
| 835 if (tiling->contents_scale() == low_res_raster_contents_scale_) | 834 if (tiling->contents_scale() == low_res_raster_contents_scale_) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 849 | 848 |
| 850 // Only create new low res tilings when the transform is static. This | 849 // Only create new low res tilings when the transform is static. This |
| 851 // prevents wastefully creating a paired low res tiling for every new high res | 850 // prevents wastefully creating a paired low res tiling for every new high res |
| 852 // tiling during a pinch or a CSS animation. | 851 // tiling during a pinch or a CSS animation. |
| 853 bool is_pinching = layer_tree_impl()->PinchGestureActive(); | 852 bool is_pinching = layer_tree_impl()->PinchGestureActive(); |
| 854 if (!is_pinching && !animating_transform_to_screen && !low_res && | 853 if (!is_pinching && !animating_transform_to_screen && !low_res && |
| 855 low_res != high_res) | 854 low_res != high_res) |
| 856 low_res = AddTiling(low_res_raster_contents_scale_); | 855 low_res = AddTiling(low_res_raster_contents_scale_); |
| 857 | 856 |
| 858 high_res->set_resolution(HIGH_RESOLUTION); | 857 high_res->set_resolution(HIGH_RESOLUTION); |
| 859 if (!low_res) | |
| 860 low_res = previous_low_res; | |
| 861 if (low_res && low_res != high_res) | 858 if (low_res && low_res != high_res) |
| 862 low_res->set_resolution(LOW_RESOLUTION); | 859 low_res->set_resolution(LOW_RESOLUTION); |
| 860 else if (!low_res && previous_low_res) | |
|
enne (OOO)
2013/11/21 23:58:51
Could you also check that previous_low_res != high
epenner
2013/11/22 00:07:39
Sorry, this isn't rebased yet but I handled that (
| |
| 861 previous_low_res->set_resolution(LOW_RESOLUTION); | |
| 863 | 862 |
| 864 SanityCheckTilingState(); | 863 SanityCheckTilingState(); |
| 865 } | 864 } |
| 866 | 865 |
| 867 bool PictureLayerImpl::ShouldAdjustRasterScale( | 866 bool PictureLayerImpl::ShouldAdjustRasterScale( |
| 868 bool animating_transform_to_screen) const { | 867 bool animating_transform_to_screen) const { |
| 869 // TODO(danakj): Adjust raster source scale closer to ideal source scale at | 868 // TODO(danakj): Adjust raster source scale closer to ideal source scale at |
| 870 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending | 869 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending |
| 871 // tree. This will allow CSS scale changes to get re-rastered at an | 870 // tree. This will allow CSS scale changes to get re-rastered at an |
| 872 // appropriate rate. | 871 // appropriate rate. |
| 873 | 872 |
| 874 if (raster_source_scale_was_animating_ && !animating_transform_to_screen) | 873 if (raster_source_scale_was_animating_ && !animating_transform_to_screen) |
| 875 return true; | 874 return true; |
| 876 | 875 |
| 877 bool is_pinching = layer_tree_impl()->PinchGestureActive(); | 876 bool is_pinching = layer_tree_impl()->PinchGestureActive(); |
| 878 if (is_pinching && raster_page_scale_) { | 877 if (is_pinching && raster_page_scale_) { |
| 879 // If the page scale diverges too far during pinch, change raster target to | 878 // We change our raster scale when it is: |
| 880 // the current page scale. | 879 // - Higher than ideal (need a lower-res tiling available) |
| 881 float ratio = PositiveRatio(ideal_page_scale_, raster_page_scale_); | 880 // - Too far from ideal (need a higher-res tiling available) |
| 882 if (ratio >= kMaxScaleRatioDuringPinch) | 881 float ratio = ideal_page_scale_ / raster_page_scale_; |
| 882 if (raster_page_scale_ > ideal_page_scale_ || | |
| 883 ratio > kMaxScaleRatioDuringPinch) | |
| 883 return true; | 884 return true; |
| 884 } | 885 } |
| 885 | 886 |
| 886 if (!is_pinching) { | 887 if (!is_pinching) { |
| 887 // When not pinching, match the ideal page scale factor. | 888 // When not pinching, match the ideal page scale factor. |
| 888 if (raster_page_scale_ != ideal_page_scale_) | 889 if (raster_page_scale_ != ideal_page_scale_) |
| 889 return true; | 890 return true; |
| 890 } | 891 } |
| 891 | 892 |
| 892 // Always match the ideal device scale factor. | 893 // Always match the ideal device scale factor. |
| 893 if (raster_device_scale_ != ideal_device_scale_) | 894 if (raster_device_scale_ != ideal_device_scale_) |
| 894 return true; | 895 return true; |
| 895 | 896 |
| 896 return false; | 897 return false; |
| 897 } | 898 } |
| 898 | 899 |
| 899 void PictureLayerImpl::CalculateRasterContentsScale( | 900 float PictureLayerImpl::SnappedContentsScale(float scale) { |
| 900 bool animating_transform_to_screen, | 901 // If a tiling exists within the max snapping ratio, snap to its scale. |
| 901 float* raster_contents_scale, | 902 float snapped_contents_scale = scale; |
| 902 float* low_res_raster_contents_scale) const { | 903 float snapped_ratio = kSnapToExistingTilingRatio; |
| 903 *raster_contents_scale = ideal_contents_scale_; | 904 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
| 905 float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale(); | |
| 906 float ratio = PositiveRatio(tiling_contents_scale, scale); | |
| 907 if (ratio < snapped_ratio) { | |
| 908 snapped_contents_scale = tiling_contents_scale; | |
| 909 snapped_ratio = ratio; | |
| 910 } | |
| 911 } | |
| 912 return snapped_contents_scale; | |
| 913 } | |
| 914 | |
| 915 void PictureLayerImpl::RecalculateRasterScales( | |
| 916 bool animating_transform_to_screen) { | |
| 917 raster_device_scale_ = ideal_device_scale_; | |
| 918 raster_source_scale_ = ideal_source_scale_; | |
| 919 | |
| 920 bool is_pinching = layer_tree_impl()->PinchGestureActive(); | |
| 921 if (!is_pinching) { | |
| 922 // When not pinching, we use ideal scale: | |
| 923 raster_page_scale_ = ideal_page_scale_; | |
| 924 raster_contents_scale_ = ideal_contents_scale_; | |
| 925 } else { | |
| 926 // See ShouldAdjustRasterScale: | |
| 927 // - When zooming out, preemptively create new tiling at lower resolution. | |
| 928 // - When zooming in, approximate ideal using multiple of kMaxScaleRatio. | |
| 929 bool zooming_out = raster_page_scale_ > ideal_page_scale_; | |
| 930 float desired_contents_scale = | |
|
epenner
2013/11/21 23:53:53
Actually, I think this might be quite good enough.
enne (OOO)
2013/11/22 00:01:02
Yeah. If you want to make this more robust in a f
| |
| 931 zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch | |
| 932 : raster_contents_scale_ * kMaxScaleRatioDuringPinch; | |
| 933 raster_contents_scale_ = SnappedContentsScale(desired_contents_scale); | |
| 934 raster_page_scale_ = raster_contents_scale_ / raster_device_scale_; | |
| 935 } | |
| 904 | 936 |
| 905 // Don't allow animating CSS scales to drop below 1. This is needed because | 937 // Don't allow animating CSS scales to drop below 1. This is needed because |
| 906 // changes in raster source scale aren't handled. See the comment in | 938 // changes in raster source scale aren't handled. See the comment in |
| 907 // ShouldAdjustRasterScale. | 939 // ShouldAdjustRasterScale. |
| 908 if (animating_transform_to_screen) { | 940 if (animating_transform_to_screen) { |
| 909 *raster_contents_scale = std::max( | 941 raster_contents_scale_ = std::max( |
| 910 *raster_contents_scale, 1.f * ideal_page_scale_ * ideal_device_scale_); | 942 raster_contents_scale_, 1.f * ideal_page_scale_ * ideal_device_scale_); |
| 911 } | 943 } |
| 912 | 944 |
| 913 // If this layer would only create one tile at this content scale, | 945 // If this layer would only create one tile at this content scale, |
| 914 // don't create a low res tiling. | 946 // don't create a low res tiling. |
| 915 gfx::Size content_bounds = | 947 gfx::Size content_bounds = |
| 916 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), *raster_contents_scale)); | 948 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_)); |
| 917 gfx::Size tile_size = CalculateTileSize(content_bounds); | 949 gfx::Size tile_size = CalculateTileSize(content_bounds); |
| 918 if (tile_size.width() >= content_bounds.width() && | 950 if (tile_size.width() >= content_bounds.width() && |
| 919 tile_size.height() >= content_bounds.height()) { | 951 tile_size.height() >= content_bounds.height()) { |
| 920 *low_res_raster_contents_scale = *raster_contents_scale; | 952 low_res_raster_contents_scale_ = raster_contents_scale_; |
| 921 return; | 953 return; |
| 922 } | 954 } |
| 923 | 955 |
| 924 float low_res_factor = | 956 float low_res_factor = |
| 925 layer_tree_impl()->settings().low_res_contents_scale_factor; | 957 layer_tree_impl()->settings().low_res_contents_scale_factor; |
| 926 *low_res_raster_contents_scale = std::max( | 958 low_res_raster_contents_scale_ = std::max( |
| 927 *raster_contents_scale * low_res_factor, | 959 raster_contents_scale_ * low_res_factor, |
| 928 MinimumContentsScale()); | 960 MinimumContentsScale()); |
| 929 } | 961 } |
| 930 | 962 |
| 931 void PictureLayerImpl::CleanUpTilingsOnActiveLayer( | 963 void PictureLayerImpl::CleanUpTilingsOnActiveLayer( |
| 932 std::vector<PictureLayerTiling*> used_tilings) { | 964 std::vector<PictureLayerTiling*> used_tilings) { |
| 933 DCHECK(layer_tree_impl()->IsActiveTree()); | 965 DCHECK(layer_tree_impl()->IsActiveTree()); |
| 934 | 966 |
| 935 float min_acceptable_high_res_scale = std::min( | 967 float min_acceptable_high_res_scale = std::min( |
| 936 raster_contents_scale_, ideal_contents_scale_); | 968 raster_contents_scale_, ideal_contents_scale_); |
| 937 float max_acceptable_high_res_scale = std::max( | 969 float max_acceptable_high_res_scale = std::max( |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1094 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const { | 1126 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const { |
| 1095 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded(); | 1127 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded(); |
| 1096 return tilings_->GPUMemoryUsageInBytes(); | 1128 return tilings_->GPUMemoryUsageInBytes(); |
| 1097 } | 1129 } |
| 1098 | 1130 |
| 1099 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { | 1131 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) { |
| 1100 benchmark->RunOnLayer(this); | 1132 benchmark->RunOnLayer(this); |
| 1101 } | 1133 } |
| 1102 | 1134 |
| 1103 } // namespace cc | 1135 } // namespace cc |
| OLD | NEW |