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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <cmath> | 11 #include <cmath> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <set> | 13 #include <set> |
| 14 | 14 |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 17 #include "base/trace_event/trace_event_argument.h" | 17 #include "base/trace_event/trace_event_argument.h" |
| 18 #include "cc/base/math_util.h" | 18 #include "cc/base/math_util.h" |
| 19 #include "cc/base/scale_translate2d.h" | |
| 19 #include "cc/debug/debug_colors.h" | 20 #include "cc/debug/debug_colors.h" |
| 20 #include "cc/debug/micro_benchmark_impl.h" | 21 #include "cc/debug/micro_benchmark_impl.h" |
| 21 #include "cc/debug/traced_value.h" | 22 #include "cc/debug/traced_value.h" |
| 22 #include "cc/layers/append_quads_data.h" | 23 #include "cc/layers/append_quads_data.h" |
| 23 #include "cc/layers/solid_color_layer_impl.h" | 24 #include "cc/layers/solid_color_layer_impl.h" |
| 24 #include "cc/output/begin_frame_args.h" | 25 #include "cc/output/begin_frame_args.h" |
| 25 #include "cc/quads/debug_border_draw_quad.h" | 26 #include "cc/quads/debug_border_draw_quad.h" |
| 26 #include "cc/quads/picture_draw_quad.h" | 27 #include "cc/quads/picture_draw_quad.h" |
| 27 #include "cc/quads/solid_color_draw_quad.h" | 28 #include "cc/quads/solid_color_draw_quad.h" |
| 28 #include "cc/quads/tile_draw_quad.h" | 29 #include "cc/quads/tile_draw_quad.h" |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 width = DebugColors::OOMTileBorderWidth(layer_tree_impl()); | 266 width = DebugColors::OOMTileBorderWidth(layer_tree_impl()); |
| 266 } else if (iter->draw_info().has_compressed_resource()) { | 267 } else if (iter->draw_info().has_compressed_resource()) { |
| 267 color = DebugColors::CompressedTileBorderColor(); | 268 color = DebugColors::CompressedTileBorderColor(); |
| 268 width = DebugColors::CompressedTileBorderWidth(layer_tree_impl()); | 269 width = DebugColors::CompressedTileBorderWidth(layer_tree_impl()); |
| 269 } else if (iter.resolution() == HIGH_RESOLUTION) { | 270 } else if (iter.resolution() == HIGH_RESOLUTION) { |
| 270 color = DebugColors::HighResTileBorderColor(); | 271 color = DebugColors::HighResTileBorderColor(); |
| 271 width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); | 272 width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); |
| 272 } else if (iter.resolution() == LOW_RESOLUTION) { | 273 } else if (iter.resolution() == LOW_RESOLUTION) { |
| 273 color = DebugColors::LowResTileBorderColor(); | 274 color = DebugColors::LowResTileBorderColor(); |
| 274 width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); | 275 width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); |
| 275 } else if (iter->contents_scale() > max_contents_scale) { | 276 } else if (iter->contents_transform().pre_scale() > |
| 277 max_contents_scale) { | |
| 276 color = DebugColors::ExtraHighResTileBorderColor(); | 278 color = DebugColors::ExtraHighResTileBorderColor(); |
| 277 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); | 279 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); |
| 278 } else { | 280 } else { |
| 279 color = DebugColors::ExtraLowResTileBorderColor(); | 281 color = DebugColors::ExtraLowResTileBorderColor(); |
| 280 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl()); | 282 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl()); |
| 281 } | 283 } |
| 282 } else { | 284 } else { |
| 283 color = DebugColors::MissingTileBorderColor(); | 285 color = DebugColors::MissingTileBorderColor(); |
| 284 width = DebugColors::MissingTileBorderWidth(layer_tree_impl()); | 286 width = DebugColors::MissingTileBorderWidth(layer_tree_impl()); |
| 285 } | 287 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 switch (draw_info.mode()) { | 335 switch (draw_info.mode()) { |
| 334 case TileDrawInfo::RESOURCE_MODE: { | 336 case TileDrawInfo::RESOURCE_MODE: { |
| 335 gfx::RectF texture_rect = iter.texture_rect(); | 337 gfx::RectF texture_rect = iter.texture_rect(); |
| 336 | 338 |
| 337 // The raster_contents_scale_ is the best scale that the layer is | 339 // The raster_contents_scale_ is the best scale that the layer is |
| 338 // trying to produce, even though it may not be ideal. Since that's | 340 // trying to produce, even though it may not be ideal. Since that's |
| 339 // the best the layer can promise in the future, consider those as | 341 // the best the layer can promise in the future, consider those as |
| 340 // complete. But if a tile is ideal scale, we don't want to consider | 342 // complete. But if a tile is ideal scale, we don't want to consider |
| 341 // it incomplete and trying to replace it with a tile at a worse | 343 // it incomplete and trying to replace it with a tile at a worse |
| 342 // scale. | 344 // scale. |
| 343 if (iter->contents_scale() != raster_contents_scale_ && | 345 if (iter->contents_transform().pre_scale() != |
| 344 iter->contents_scale() != ideal_contents_scale_ && | 346 raster_contents_scale_ && |
| 347 iter->contents_transform().pre_scale() != ideal_contents_scale_ && | |
| 345 geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { | 348 geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { |
| 346 append_quads_data->num_incomplete_tiles++; | 349 append_quads_data->num_incomplete_tiles++; |
| 347 } | 350 } |
| 348 | 351 |
| 349 TileDrawQuad* quad = | 352 TileDrawQuad* quad = |
| 350 render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); | 353 render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); |
| 351 quad->SetNew(shared_quad_state, geometry_rect, opaque_rect, | 354 quad->SetNew(shared_quad_state, geometry_rect, opaque_rect, |
| 352 visible_geometry_rect, draw_info.resource_id(), | 355 visible_geometry_rect, draw_info.resource_id(), |
| 353 texture_rect, draw_info.resource_size(), | 356 texture_rect, draw_info.resource_size(), |
| 354 draw_info.contents_swizzled(), nearest_neighbor_); | 357 draw_info.contents_swizzled(), nearest_neighbor_); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 | 642 |
| 640 DCHECK(!RasterSourceUsesLCDText()); | 643 DCHECK(!RasterSourceUsesLCDText()); |
| 641 } | 644 } |
| 642 | 645 |
| 643 bool PictureLayerImpl::RasterSourceUsesLCDText() const { | 646 bool PictureLayerImpl::RasterSourceUsesLCDText() const { |
| 644 return raster_source_ ? raster_source_->CanUseLCDText() | 647 return raster_source_ ? raster_source_->CanUseLCDText() |
| 645 : layer_tree_impl()->settings().can_use_lcd_text; | 648 : layer_tree_impl()->settings().can_use_lcd_text; |
| 646 } | 649 } |
| 647 | 650 |
| 648 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { | 651 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { |
| 649 if (layer_tree_impl()->IsActiveTree()) { | 652 if (layer_tree_impl()->IsActiveTree()) |
| 650 gfx::Rect layer_damage_rect = gfx::ScaleToEnclosingRect( | 653 AddDamageRect(tile->enclosing_layer_rect()); |
| 651 tile->content_rect(), 1.f / tile->contents_scale()); | |
| 652 AddDamageRect(layer_damage_rect); | |
| 653 } | |
| 654 if (tile->draw_info().NeedsRaster()) { | 654 if (tile->draw_info().NeedsRaster()) { |
| 655 PictureLayerTiling* tiling = | 655 PictureLayerTiling* tiling = |
| 656 tilings_->FindTilingWithScale(tile->contents_scale()); | 656 tilings_->FindTilingWithScale(tile->contents_transform().pre_scale()); |
|
enne (OOO)
2016/08/29 20:21:19
This is also wrong and needs to take into account
| |
| 657 if (tiling) | 657 if (tiling) { |
| 658 DCHECK_EQ(tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()), | |
| 659 tile); | |
| 658 tiling->set_all_tiles_done(false); | 660 tiling->set_all_tiles_done(false); |
| 661 } | |
| 659 } | 662 } |
| 660 } | 663 } |
| 661 | 664 |
| 662 void PictureLayerImpl::DidBeginTracing() { | 665 void PictureLayerImpl::DidBeginTracing() { |
| 663 raster_source_->DidBeginTracing(); | 666 raster_source_->DidBeginTracing(); |
| 664 } | 667 } |
| 665 | 668 |
| 666 void PictureLayerImpl::ReleaseResources() { | 669 void PictureLayerImpl::ReleaseResources() { |
| 667 // Recreate tilings with new settings, since some of those might change when | 670 // Recreate tilings with new settings, since some of those might change when |
| 668 // we release resources. | 671 // we release resources. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer()) | 719 if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer()) |
| 717 return &twin_layer->invalidation_; | 720 return &twin_layer->invalidation_; |
| 718 return nullptr; | 721 return nullptr; |
| 719 } | 722 } |
| 720 | 723 |
| 721 const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling( | 724 const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling( |
| 722 const PictureLayerTiling* tiling) const { | 725 const PictureLayerTiling* tiling) const { |
| 723 PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer(); | 726 PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer(); |
| 724 if (!twin_layer) | 727 if (!twin_layer) |
| 725 return nullptr; | 728 return nullptr; |
| 726 return twin_layer->tilings_->FindTilingWithScale(tiling->contents_scale()); | 729 const PictureLayerTiling* twin_tiling = |
| 730 twin_layer->tilings_->FindTilingWithScale( | |
|
enne (OOO)
2016/08/29 20:21:19
I think this you need to be more explicit here in
| |
| 731 tiling->contents_transform().pre_scale()); | |
| 732 return twin_tiling && | |
| 733 twin_tiling->contents_transform() == | |
| 734 tiling->contents_transform() | |
| 735 ? twin_tiling | |
| 736 : nullptr; | |
| 727 } | 737 } |
| 728 | 738 |
| 729 bool PictureLayerImpl::RequiresHighResToDraw() const { | 739 bool PictureLayerImpl::RequiresHighResToDraw() const { |
| 730 return layer_tree_impl()->RequiresHighResToDraw(); | 740 return layer_tree_impl()->RequiresHighResToDraw(); |
| 731 } | 741 } |
| 732 | 742 |
| 733 gfx::Rect PictureLayerImpl::GetEnclosingRectInTargetSpace() const { | 743 gfx::Rect PictureLayerImpl::GetEnclosingRectInTargetSpace() const { |
| 734 return GetScaledEnclosingRectInTargetSpace(MaximumTilingContentsScale()); | 744 return GetScaledEnclosingRectInTargetSpace(MaximumTilingContentsScale()); |
| 735 } | 745 } |
| 736 | 746 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 862 } | 872 } |
| 863 | 873 |
| 864 void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) { | 874 void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) { |
| 865 if (nearest_neighbor_ == nearest_neighbor) | 875 if (nearest_neighbor_ == nearest_neighbor) |
| 866 return; | 876 return; |
| 867 | 877 |
| 868 nearest_neighbor_ = nearest_neighbor; | 878 nearest_neighbor_ = nearest_neighbor; |
| 869 NoteLayerPropertyChanged(); | 879 NoteLayerPropertyChanged(); |
| 870 } | 880 } |
| 871 | 881 |
| 872 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) { | 882 PictureLayerTiling* PictureLayerImpl::AddTiling( |
| 883 const ScaleTranslate2d& contents_transform) { | |
| 873 DCHECK(CanHaveTilings()); | 884 DCHECK(CanHaveTilings()); |
| 874 DCHECK_GE(contents_scale, MinimumContentsScale()); | 885 DCHECK_GE(contents_transform.pre_scale(), MinimumContentsScale()); |
| 875 DCHECK_LE(contents_scale, MaximumContentsScale()); | 886 DCHECK_LE(contents_transform.pre_scale(), MaximumContentsScale()); |
| 876 DCHECK(raster_source_->HasRecordings()); | 887 DCHECK(raster_source_->HasRecordings()); |
| 877 return tilings_->AddTiling(contents_scale, raster_source_); | 888 return tilings_->AddTiling(contents_transform, raster_source_); |
| 878 } | 889 } |
| 879 | 890 |
| 880 void PictureLayerImpl::RemoveAllTilings() { | 891 void PictureLayerImpl::RemoveAllTilings() { |
| 881 tilings_->RemoveAllTilings(); | 892 tilings_->RemoveAllTilings(); |
| 882 // If there are no tilings, then raster scales are no longer meaningful. | 893 // If there are no tilings, then raster scales are no longer meaningful. |
| 883 ResetRasterScale(); | 894 ResetRasterScale(); |
| 884 } | 895 } |
| 885 | 896 |
| 886 void PictureLayerImpl::AddTilingsForRasterScale() { | 897 void PictureLayerImpl::AddTilingsForRasterScale() { |
| 887 // Reset all resolution enums on tilings, we'll be setting new values in this | 898 // Reset all resolution enums on tilings, we'll be setting new values in this |
| 888 // function. | 899 // function. |
| 889 tilings_->MarkAllTilingsNonIdeal(); | 900 tilings_->MarkAllTilingsNonIdeal(); |
| 890 | 901 |
| 891 PictureLayerTiling* high_res = | 902 PictureLayerTiling* high_res = |
| 892 tilings_->FindTilingWithScale(raster_contents_scale_); | 903 tilings_->FindTilingWithScale(raster_contents_scale_); |
|
enne (OOO)
2016/08/29 20:21:18
Here is another case where I think FindTilingWithS
| |
| 893 if (!high_res) { | 904 if (!high_res) { |
| 905 gfx::Vector2dF raster_translation = | |
| 906 CalculateRasterTranslation(raster_contents_scale_); | |
| 894 // We always need a high res tiling, so create one if it doesn't exist. | 907 // We always need a high res tiling, so create one if it doesn't exist. |
| 895 high_res = AddTiling(raster_contents_scale_); | 908 high_res = |
| 909 AddTiling(ScaleTranslate2d(raster_contents_scale_, raster_translation)); | |
| 896 } else if (high_res->may_contain_low_resolution_tiles()) { | 910 } else if (high_res->may_contain_low_resolution_tiles()) { |
| 897 // If the tiling we find here was LOW_RESOLUTION previously, it may not be | 911 // If the tiling we find here was LOW_RESOLUTION previously, it may not be |
| 898 // fully rastered, so destroy the old tiles. | 912 // fully rastered, so destroy the old tiles. |
| 899 high_res->Reset(); | 913 high_res->Reset(); |
| 900 // Reset the flag now that we'll make it high res, it will have fully | 914 // Reset the flag now that we'll make it high res, it will have fully |
| 901 // rastered content. | 915 // rastered content. |
| 902 high_res->reset_may_contain_low_resolution_tiles(); | 916 high_res->reset_may_contain_low_resolution_tiles(); |
| 903 } | 917 } |
| 904 high_res->set_resolution(HIGH_RESOLUTION); | 918 high_res->set_resolution(HIGH_RESOLUTION); |
| 905 | 919 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 987 tilings_->FindTilingWithScale(low_res_raster_contents_scale_); | 1001 tilings_->FindTilingWithScale(low_res_raster_contents_scale_); |
| 988 DCHECK(!low_res || low_res->resolution() != HIGH_RESOLUTION); | 1002 DCHECK(!low_res || low_res->resolution() != HIGH_RESOLUTION); |
| 989 | 1003 |
| 990 // Only create new low res tilings when the transform is static. This | 1004 // Only create new low res tilings when the transform is static. This |
| 991 // prevents wastefully creating a paired low res tiling for every new high | 1005 // prevents wastefully creating a paired low res tiling for every new high |
| 992 // res tiling during a pinch or a CSS animation. | 1006 // res tiling during a pinch or a CSS animation. |
| 993 bool is_pinching = layer_tree_impl()->PinchGestureActive(); | 1007 bool is_pinching = layer_tree_impl()->PinchGestureActive(); |
| 994 bool is_animating = draw_properties().screen_space_transform_is_animating; | 1008 bool is_animating = draw_properties().screen_space_transform_is_animating; |
| 995 if (!is_pinching && !is_animating) { | 1009 if (!is_pinching && !is_animating) { |
| 996 if (!low_res) | 1010 if (!low_res) |
| 997 low_res = AddTiling(low_res_raster_contents_scale_); | 1011 low_res = AddTiling( |
| 1012 ScaleTranslate2d(low_res_raster_contents_scale_, gfx::Vector2dF())); | |
| 998 low_res->set_resolution(LOW_RESOLUTION); | 1013 low_res->set_resolution(LOW_RESOLUTION); |
| 999 } | 1014 } |
| 1000 } | 1015 } |
| 1001 | 1016 |
| 1017 gfx::Vector2dF PictureLayerImpl::CalculateRasterTranslation( | |
| 1018 float raster_scale) { | |
| 1019 // Do not align if the layer is animating, as we don't plan to re-raster | |
| 1020 // during animation. Aligning to the first frame will only introduce extra | |
| 1021 // aliasing error. | |
| 1022 if (draw_properties().screen_space_transform_is_animating) | |
| 1023 return gfx::Vector2dF(); | |
| 1024 | |
| 1025 // Can't align by just translation if the draw transform contains more than | |
| 1026 // scale and translation. e.g. rotation, perspective, etc... | |
| 1027 gfx::Transform draw_transform = DrawTransform(); | |
| 1028 if (!draw_transform.IsScaleOrTranslation()) | |
| 1029 return gfx::Vector2dF(); | |
| 1030 | |
| 1031 // It is only useful to align the content space to the target space if their | |
| 1032 // relative pixel ratio is some small rational number. Currently we only | |
| 1033 // align if the relative pixel ratio is 1:1. | |
| 1034 // Good match if the maximum alignment error on a layer of size 10000px | |
| 1035 // does not exceed 0.001px. | |
| 1036 static constexpr float kErrorThreshold = 0.0000001f; | |
| 1037 if (std::abs(draw_transform.matrix().getFloat(0, 0) - raster_scale) > | |
| 1038 kErrorThreshold || | |
| 1039 std::abs(draw_transform.matrix().getFloat(1, 1) - raster_scale) > | |
| 1040 kErrorThreshold) | |
| 1041 return gfx::Vector2dF(); | |
| 1042 | |
| 1043 // Extract the fractional part of layer origin in the target space. | |
| 1044 float origin_x = draw_transform.matrix().getFloat(0, 3); | |
| 1045 float origin_y = draw_transform.matrix().getFloat(1, 3); | |
| 1046 return gfx::Vector2dF(origin_x - floorf(origin_x), | |
| 1047 origin_y - floorf(origin_y)); | |
| 1048 } | |
| 1049 | |
| 1002 void PictureLayerImpl::RecalculateRasterScales() { | 1050 void PictureLayerImpl::RecalculateRasterScales() { |
| 1003 if (is_directly_composited_image_) { | 1051 if (is_directly_composited_image_) { |
| 1004 if (!raster_source_scale_) | 1052 if (!raster_source_scale_) |
| 1005 raster_source_scale_ = 1.f; | 1053 raster_source_scale_ = 1.f; |
| 1006 | 1054 |
| 1007 float min_scale = MinimumContentsScale(); | 1055 float min_scale = MinimumContentsScale(); |
| 1008 float max_scale = std::max(1.f, MinimumContentsScale()); | 1056 float max_scale = std::max(1.f, MinimumContentsScale()); |
| 1009 float clamped_ideal_source_scale_ = | 1057 float clamped_ideal_source_scale_ = |
| 1010 std::max(min_scale, std::min(ideal_source_scale_, max_scale)); | 1058 std::max(min_scale, std::min(ideal_source_scale_, max_scale)); |
| 1011 | 1059 |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 bool PictureLayerImpl::IsOnActiveOrPendingTree() const { | 1395 bool PictureLayerImpl::IsOnActiveOrPendingTree() const { |
| 1348 return !layer_tree_impl()->IsRecycleTree(); | 1396 return !layer_tree_impl()->IsRecycleTree(); |
| 1349 } | 1397 } |
| 1350 | 1398 |
| 1351 bool PictureLayerImpl::HasValidTilePriorities() const { | 1399 bool PictureLayerImpl::HasValidTilePriorities() const { |
| 1352 return IsOnActiveOrPendingTree() && | 1400 return IsOnActiveOrPendingTree() && |
| 1353 is_drawn_render_surface_layer_list_member(); | 1401 is_drawn_render_surface_layer_list_member(); |
| 1354 } | 1402 } |
| 1355 | 1403 |
| 1356 } // namespace cc | 1404 } // namespace cc |
| OLD | NEW |