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 |