Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: cc/layers/picture_layer_impl.cc

Issue 367833003: cc: Start using raster/eviction iterators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include <limits>
9 9
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 LayerTreeImpl* tree_impl) { 79 LayerTreeImpl* tree_impl) {
80 return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>(); 80 return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
81 } 81 }
82 82
83 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { 83 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
84 // It's possible this layer was never drawn or updated (e.g. because it was 84 // It's possible this layer was never drawn or updated (e.g. because it was
85 // a descendant of an opacity 0 layer). 85 // a descendant of an opacity 0 layer).
86 DoPostCommitInitializationIfNeeded(); 86 DoPostCommitInitializationIfNeeded();
87 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); 87 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
88 88
89 // We have already synced the important bits from the the active layer, and
90 // we will soon swap out its tilings and use them for recycling. However,
91 // there are now tiles in this layer's tilings that were unref'd and replaced
92 // with new tiles (due to invalidation). This resets all active priorities on
93 // the to-be-recycled tiling to ensure replaced tiles don't linger and take
94 // memory (due to a stale 'active' priority).
95 if (layer_impl->tilings_)
96 layer_impl->tilings_->DidBecomeRecycled();
97
98 LayerImpl::PushPropertiesTo(base_layer); 89 LayerImpl::PushPropertiesTo(base_layer);
99 90
100 // When the pending tree pushes to the active tree, the pending twin 91 // When the pending tree pushes to the active tree, the pending twin
101 // disappears. 92 // disappears.
102 layer_impl->twin_layer_ = NULL; 93 layer_impl->twin_layer_ = NULL;
103 twin_layer_ = NULL; 94 twin_layer_ = NULL;
104 95
105 layer_impl->SetIsMask(is_mask_); 96 layer_impl->SetIsMask(is_mask_);
106 layer_impl->pile_ = pile_; 97 layer_impl->pile_ = pile_;
107 98
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 float width; 205 float width;
215 if (*iter && iter->IsReadyToDraw()) { 206 if (*iter && iter->IsReadyToDraw()) {
216 ManagedTileState::TileVersion::Mode mode = 207 ManagedTileState::TileVersion::Mode mode =
217 iter->GetTileVersionForDrawing().mode(); 208 iter->GetTileVersionForDrawing().mode();
218 if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) { 209 if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
219 color = DebugColors::SolidColorTileBorderColor(); 210 color = DebugColors::SolidColorTileBorderColor();
220 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl()); 211 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
221 } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) { 212 } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
222 color = DebugColors::PictureTileBorderColor(); 213 color = DebugColors::PictureTileBorderColor();
223 width = DebugColors::PictureTileBorderWidth(layer_tree_impl()); 214 width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
224 } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) { 215 } else if (iter.resolution() == HIGH_RESOLUTION) {
225 color = DebugColors::HighResTileBorderColor(); 216 color = DebugColors::HighResTileBorderColor();
226 width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); 217 width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
227 } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) { 218 } else if (iter.resolution() == LOW_RESOLUTION) {
228 color = DebugColors::LowResTileBorderColor(); 219 color = DebugColors::LowResTileBorderColor();
229 width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); 220 width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
230 } else if (iter->contents_scale() > max_contents_scale) { 221 } else if (iter->contents_scale() > max_contents_scale) {
231 color = DebugColors::ExtraHighResTileBorderColor(); 222 color = DebugColors::ExtraHighResTileBorderColor();
232 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); 223 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
233 } else { 224 } else {
234 color = DebugColors::ExtraLowResTileBorderColor(); 225 color = DebugColors::ExtraLowResTileBorderColor();
235 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl()); 226 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
236 } 227 }
237 } else { 228 } else {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 345 }
355 346
356 append_quads_data->num_missing_tiles++; 347 append_quads_data->num_missing_tiles++;
357 append_quads_data->had_incomplete_tile = true; 348 append_quads_data->had_incomplete_tile = true;
358 append_quads_data->approximated_visible_content_area += 349 append_quads_data->approximated_visible_content_area +=
359 visible_geometry_rect.width() * visible_geometry_rect.height(); 350 visible_geometry_rect.width() * visible_geometry_rect.height();
360 ++missing_tile_count; 351 ++missing_tile_count;
361 continue; 352 continue;
362 } 353 }
363 354
364 if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) { 355 if (iter.resolution() != HIGH_RESOLUTION) {
365 append_quads_data->approximated_visible_content_area += 356 append_quads_data->approximated_visible_content_area +=
366 visible_geometry_rect.width() * visible_geometry_rect.height(); 357 visible_geometry_rect.width() * visible_geometry_rect.height();
367 } 358 }
368 359
369 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling()) 360 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
370 seen_tilings.push_back(iter.CurrentTiling()); 361 seen_tilings.push_back(iter.CurrentTiling());
371 } 362 }
372 363
373 if (missing_tile_count) { 364 if (missing_tile_count) {
374 TRACE_EVENT_INSTANT2("cc", 365 TRACE_EVENT_INSTANT2("cc",
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 DCHECK(raster_source_scale_); 419 DCHECK(raster_source_scale_);
429 DCHECK(raster_contents_scale_); 420 DCHECK(raster_contents_scale_);
430 DCHECK(low_res_raster_contents_scale_); 421 DCHECK(low_res_raster_contents_scale_);
431 422
432 was_screen_space_transform_animating_ = 423 was_screen_space_transform_animating_ =
433 draw_properties().screen_space_transform_is_animating; 424 draw_properties().screen_space_transform_is_animating;
434 425
435 should_update_tile_priorities_ = true; 426 should_update_tile_priorities_ = true;
436 427
437 UpdateTilePriorities(occlusion_tracker); 428 UpdateTilePriorities(occlusion_tracker);
438
439 if (layer_tree_impl()->IsPendingTree())
440 MarkVisibleResourcesAsRequired();
441 } 429 }
442 430
443 void PictureLayerImpl::UpdateTilePriorities( 431 void PictureLayerImpl::UpdateTilePriorities(
444 const OcclusionTracker<LayerImpl>* occlusion_tracker) { 432 const OcclusionTracker<LayerImpl>* occlusion_tracker) {
445 TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities"); 433 TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities");
446 434
447 double current_frame_time_in_seconds = 435 double current_frame_time_in_seconds =
448 (layer_tree_impl()->CurrentFrameTimeTicks() - 436 (layer_tree_impl()->CurrentFrameTimeTicks() -
449 base::TimeTicks()).InSecondsF(); 437 base::TimeTicks()).InSecondsF();
450 438
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() * 581 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() *
594 layer_tree_impl()->settings().skewport_target_time_multiplier; 582 layer_tree_impl()->settings().skewport_target_time_multiplier;
595 } 583 }
596 584
597 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const { 585 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
598 return layer_tree_impl() 586 return layer_tree_impl()
599 ->settings() 587 ->settings()
600 .skewport_extrapolation_limit_in_content_pixels; 588 .skewport_extrapolation_limit_in_content_pixels;
601 } 589 }
602 590
591 bool PictureLayerImpl::RequiresHighResToDraw() const {
592 const PictureLayerImpl* layer = this;
593 if (GetTree() == PENDING_TREE)
594 layer = twin_layer_;
595
596 if (layer)
597 return layer->layer_tree_impl()->RequiresHighResToDraw();
598 return false;
599 }
600
603 gfx::Size PictureLayerImpl::CalculateTileSize( 601 gfx::Size PictureLayerImpl::CalculateTileSize(
604 const gfx::Size& content_bounds) const { 602 const gfx::Size& content_bounds) const {
605 if (is_mask_) { 603 if (is_mask_) {
606 int max_size = layer_tree_impl()->MaxTextureSize(); 604 int max_size = layer_tree_impl()->MaxTextureSize();
607 return gfx::Size( 605 return gfx::Size(
608 std::min(max_size, content_bounds.width()), 606 std::min(max_size, content_bounds.width()),
609 std::min(max_size, content_bounds.height())); 607 std::min(max_size, content_bounds.height()));
610 } 608 }
611 609
612 int max_texture_size = 610 int max_texture_size =
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 740
743 const ManagedTileState::TileVersion& tile_version = 741 const ManagedTileState::TileVersion& tile_version =
744 iter->GetTileVersionForDrawing(); 742 iter->GetTileVersionForDrawing();
745 if (!tile_version.IsReadyToDraw() || 743 if (!tile_version.IsReadyToDraw() ||
746 tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE) 744 tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
747 return 0; 745 return 0;
748 746
749 return tile_version.get_resource_id(); 747 return tile_version.get_resource_id();
750 } 748 }
751 749
752 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
753 DCHECK(layer_tree_impl()->IsPendingTree());
754 DCHECK(ideal_contents_scale_);
755 DCHECK_GT(tilings_->num_tilings(), 0u);
756
757 // The goal of this function is to find the minimum set of tiles that need to
758 // be ready to draw in order to activate without flashing content from a
759 // higher res on the active tree to a lower res on the pending tree.
760
761 // First, early out for layers with no visible content.
762 if (visible_content_rect().IsEmpty())
763 return;
764
765 gfx::Rect rect(visible_content_rect());
766
767 float min_acceptable_scale =
768 std::min(raster_contents_scale_, ideal_contents_scale_);
769
770 if (PictureLayerImpl* twin = twin_layer_) {
771 float twin_min_acceptable_scale =
772 std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
773 // Ignore 0 scale in case CalculateContentsScale() has never been
774 // called for active twin.
775 if (twin_min_acceptable_scale != 0.0f) {
776 min_acceptable_scale =
777 std::min(min_acceptable_scale, twin_min_acceptable_scale);
778 }
779 }
780
781 PictureLayerTiling* high_res = NULL;
782 PictureLayerTiling* low_res = NULL;
783
784 // First pass: ready to draw tiles in acceptable but non-ideal tilings are
785 // marked as required for activation so that their textures are not thrown
786 // away; any non-ready tiles are not marked as required.
787 Region missing_region = rect;
788 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
789 PictureLayerTiling* tiling = tilings_->tiling_at(i);
790 DCHECK(tiling->has_ever_been_updated());
791
792 if (tiling->resolution() == LOW_RESOLUTION) {
793 DCHECK(!low_res) << "There can only be one low res tiling";
794 low_res = tiling;
795 }
796 if (tiling->contents_scale() < min_acceptable_scale)
797 continue;
798 if (tiling->resolution() == HIGH_RESOLUTION) {
799 DCHECK(!high_res) << "There can only be one high res tiling";
800 high_res = tiling;
801 continue;
802 }
803 for (PictureLayerTiling::CoverageIterator iter(tiling,
804 contents_scale_x(),
805 rect);
806 iter;
807 ++iter) {
808 if (!*iter || !iter->IsReadyToDraw())
809 continue;
810
811 missing_region.Subtract(iter.geometry_rect());
812 iter->MarkRequiredForActivation();
813 }
814 }
815 DCHECK(high_res) << "There must be one high res tiling";
816
817 // If these pointers are null (because no twin, no matching tiling, or the
818 // simpification just below), then high res tiles will be required to fill any
819 // holes left by the first pass above. If the pointers are valid, then this
820 // layer is allowed to skip any tiles that are not ready on its twin.
821 const PictureLayerTiling* twin_high_res = NULL;
822 const PictureLayerTiling* twin_low_res = NULL;
823
824 if (twin_layer_) {
825 // As a simplification, only allow activating to skip twin tiles that the
826 // active layer is also missing when both this layer and its twin have
827 // "simple" sets of tilings: only 2 tilings (high and low) or only 1 high
828 // res tiling. This avoids having to iterate/track coverage of non-ideal
829 // tilings during the last draw call on the active layer.
830 if (tilings_->num_tilings() <= 2 &&
831 twin_layer_->tilings_->num_tilings() <= tilings_->num_tilings()) {
832 twin_low_res = low_res ? GetTwinTiling(low_res) : NULL;
833 twin_high_res = high_res ? GetTwinTiling(high_res) : NULL;
834 }
835
836 // If this layer and its twin have different transforms, then don't compare
837 // them and only allow activating to high res tiles, since tiles on each
838 // layer will be in different places on screen.
839 if (twin_layer_->layer_tree_impl()->RequiresHighResToDraw() ||
840 bounds() != twin_layer_->bounds() ||
841 draw_properties().screen_space_transform !=
842 twin_layer_->draw_properties().screen_space_transform) {
843 twin_high_res = NULL;
844 twin_low_res = NULL;
845 }
846 }
847
848 // As a second pass, mark as required any visible high res tiles not filled in
849 // by acceptable non-ideal tiles from the first pass.
850 if (MarkVisibleTilesAsRequired(
851 high_res, twin_high_res, contents_scale_x(), rect, missing_region)) {
852 // As an optional third pass, if a high res tile was skipped because its
853 // twin was also missing, then fall back to mark low res tiles as required
854 // in case the active twin is substituting those for missing high res
855 // content. Only suitable, when low res is enabled.
856 if (low_res) {
857 MarkVisibleTilesAsRequired(
858 low_res, twin_low_res, contents_scale_x(), rect, missing_region);
859 }
860 }
861 }
862
863 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
864 PictureLayerTiling* tiling,
865 const PictureLayerTiling* optional_twin_tiling,
866 float contents_scale,
867 const gfx::Rect& rect,
868 const Region& missing_region) const {
869 bool twin_had_missing_tile = false;
870 for (PictureLayerTiling::CoverageIterator iter(tiling,
871 contents_scale,
872 rect);
873 iter;
874 ++iter) {
875 Tile* tile = *iter;
876 // A null tile (i.e. missing recording) can just be skipped.
877 if (!tile)
878 continue;
879
880 // If the tile is occluded, don't mark it as required for activation.
881 if (tile->is_occluded())
882 continue;
883
884 // If the missing region doesn't cover it, this tile is fully
885 // covered by acceptable tiles at other scales.
886 if (!missing_region.Intersects(iter.geometry_rect()))
887 continue;
888
889 // If the twin tile doesn't exist (i.e. missing recording or so far away
890 // that it is outside the visible tile rect) or this tile is shared between
891 // with the twin, then this tile isn't required to prevent flashing.
892 if (optional_twin_tiling) {
893 Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
894 if (!twin_tile || twin_tile == tile) {
895 twin_had_missing_tile = true;
896 continue;
897 }
898 }
899
900 tile->MarkRequiredForActivation();
901 }
902 return twin_had_missing_tile;
903 }
904
905 void PictureLayerImpl::DoPostCommitInitialization() { 750 void PictureLayerImpl::DoPostCommitInitialization() {
906 DCHECK(needs_post_commit_initialization_); 751 DCHECK(needs_post_commit_initialization_);
907 DCHECK(layer_tree_impl()->IsPendingTree()); 752 DCHECK(layer_tree_impl()->IsPendingTree());
908 753
909 if (!tilings_) 754 if (!tilings_)
910 tilings_.reset(new PictureLayerTilingSet(this, bounds())); 755 tilings_.reset(new PictureLayerTilingSet(this, bounds()));
911 756
912 DCHECK(!twin_layer_); 757 DCHECK(!twin_layer_);
913 twin_layer_ = static_cast<PictureLayerImpl*>( 758 twin_layer_ = static_cast<PictureLayerImpl*>(
914 layer_tree_impl()->FindActiveTreeLayerById(id())); 759 layer_tree_impl()->FindActiveTreeLayerById(id()));
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 return iterator_index_ < iterators_.size(); 1474 return iterator_index_ < iterators_.size();
1630 } 1475 }
1631 1476
1632 bool PictureLayerImpl::LayerEvictionTileIterator::IsCorrectType( 1477 bool PictureLayerImpl::LayerEvictionTileIterator::IsCorrectType(
1633 PictureLayerTiling::TilingEvictionTileIterator* it) const { 1478 PictureLayerTiling::TilingEvictionTileIterator* it) const {
1634 return it->get_type() == iteration_stage_ && 1479 return it->get_type() == iteration_stage_ &&
1635 (**it)->required_for_activation() == required_for_activation_; 1480 (**it)->required_for_activation() == required_for_activation_;
1636 } 1481 }
1637 1482
1638 } // namespace cc 1483 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698