diff options
author | jbedley@chromium.org <jbedley@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-08 19:19:27 +0000 |
---|---|---|
committer | jbedley@chromium.org <jbedley@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-08 19:19:27 +0000 |
commit | 417cf159b43920636dda2eaeaa09535bf5936835 (patch) | |
tree | b31ee416b0df8f63c89fd204ff00575c7b082475 /cc | |
parent | 48a3f945385be773e5f0005c3cdaefbb62076efa (diff) | |
download | chromium_src-417cf159b43920636dda2eaeaa09535bf5936835.zip chromium_src-417cf159b43920636dda2eaeaa09535bf5936835.tar.gz chromium_src-417cf159b43920636dda2eaeaa09535bf5936835.tar.bz2 |
Track occlusion per tree on Tile.
Currently, the Tile class has one is_occluded bool. Give Tile two
occluded bools, one for each tree, so that the same tile can have
different occlusion on each tree.
This patch is an alternative to
https://codereview.chromium.org/343463004/ which also tracks occlusion
per tree, but stores occlusion info on TilePriority rather than Tile.
BUG=178971
Review URL: https://codereview.chromium.org/374653003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281788 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 11 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 118 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 2 | ||||
-rw-r--r-- | cc/resources/tile.cc | 3 | ||||
-rw-r--r-- | cc/resources/tile.h | 9 |
5 files changed, 127 insertions, 16 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 481536b..bb2896f 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -878,7 +878,7 @@ bool PictureLayerImpl::MarkVisibleTilesAsRequired( continue; // If the tile is occluded, don't mark it as required for activation. - if (tile->is_occluded()) + if (tile->is_occluded(PENDING_TREE)) continue; // If the missing region doesn't cover it, this tile is fully @@ -1456,7 +1456,7 @@ PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator( IteratorType index = stages_[current_stage_].iterator_type; TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; if (!iterators_[index] || iterators_[index].get_type() != tile_type || - (*iterators_[index])->is_occluded()) + (*iterators_[index])->is_occluded(tree)) ++(*this); } @@ -1469,6 +1469,9 @@ PictureLayerImpl::LayerRasterTileIterator::operator bool() const { PictureLayerImpl::LayerRasterTileIterator& PictureLayerImpl::LayerRasterTileIterator:: operator++() { + WhichTree tree = + layer_->layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; + IteratorType index = stages_[current_stage_].iterator_type; TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; @@ -1477,7 +1480,7 @@ operator++() { ++iterators_[index]; while (iterators_[index] && iterators_[index].get_type() == tile_type && - (*iterators_[index])->is_occluded()) + (*iterators_[index])->is_occluded(tree)) ++iterators_[index]; if (iterators_[index] && iterators_[index].get_type() == tile_type) @@ -1491,7 +1494,7 @@ operator++() { tile_type = stages_[current_stage_].tile_type; if (iterators_[index] && iterators_[index].get_type() == tile_type && - !(*iterators_[index])->is_occluded()) + !(*iterators_[index])->is_occluded(tree)) break; ++current_stage_; } diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 401df7e..2258655 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -2848,7 +2848,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, Tile* tile = *it; // Occluded tiles should not be iterated over. - EXPECT_FALSE(tile->is_occluded()); + EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); // Some tiles may not be visible (i.e. outside the viewport). The rest are // visible and at least partially unoccluded, verified by the above expect. @@ -2877,7 +2877,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, ++it) { Tile* tile = *it; - EXPECT_FALSE(tile->is_occluded()); + EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); bool tile_is_visible = tile->content_rect().Intersects(pending_layer_->visible_content_rect()); @@ -2898,7 +2898,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, ++it) { Tile* tile = *it; - EXPECT_FALSE(tile->is_occluded()); + EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); bool tile_is_visible = tile->content_rect().Intersects(pending_layer_->visible_content_rect()); @@ -2940,7 +2940,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, const Tile* tile = *iter; // Fully occluded tiles are not required for activation. - if (tile->is_occluded()) { + if (tile->is_occluded(PENDING_TREE)) { EXPECT_FALSE(tile->required_for_activation()); occluded_tile_count++; } @@ -2973,7 +2973,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, continue; const Tile* tile = *iter; - if (tile->is_occluded()) { + if (tile->is_occluded(PENDING_TREE)) { EXPECT_FALSE(tile->required_for_activation()); occluded_tile_count++; } @@ -3009,7 +3009,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, continue; const Tile* tile = *iter; - if (tile->is_occluded()) { + if (tile->is_occluded(PENDING_TREE)) { EXPECT_FALSE(tile->required_for_activation()); occluded_tile_count++; } @@ -3070,7 +3070,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { occluded_tile_count = 0; for (size_t i = 0; i < tiles.size(); ++i) { - if (tiles[i]->is_occluded()) { + if (tiles[i]->is_occluded(PENDING_TREE)) { gfx::Rect scaled_content_rect = ScaleToEnclosingRect( tiles[i]->content_rect(), 1.0f / tiles[i]->contents_scale()); EXPECT_GE(scaled_content_rect.x(), occluding_layer_position.x()); @@ -3100,5 +3100,109 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { EXPECT_EQ(tiling_count, 5); } + +TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { + gfx::Size tile_size(102, 102); + gfx::Size layer_bounds(1000, 1000); + gfx::Size viewport_size(1000, 1000); + gfx::Point occluding_layer_position(310, 0); + gfx::Rect invalidation_rect(230, 230, 102, 102); + + scoped_refptr<FakePicturePileImpl> pending_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + scoped_refptr<FakePicturePileImpl> active_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); + SetupTrees(pending_pile, active_pile); + + // Partially occlude the active layer. + active_layer_->AddChild(LayerImpl::Create(host_impl_.active_tree(), 2)); + LayerImpl* layer1 = active_layer_->children()[0]; + layer1->SetBounds(layer_bounds); + layer1->SetContentBounds(layer_bounds); + layer1->SetDrawsContent(true); + layer1->SetContentsOpaque(true); + layer1->SetPosition(occluding_layer_position); + + // Partially invalidate the pending layer. + pending_layer_->set_invalidation(invalidation_rect); + + host_impl_.SetViewportSize(viewport_size); + + active_layer_->CreateDefaultTilingsAndTiles(); + pending_layer_->CreateDefaultTilingsAndTiles(); + + for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) { + PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i); + + for (PictureLayerTiling::CoverageIterator iter( + tiling, + pending_layer_->contents_scale_x(), + gfx::Rect(layer_bounds)); + iter; + ++iter) { + if (!*iter) + continue; + const Tile* tile = *iter; + + // All tiles are unoccluded on the pending tree. + EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); + + Tile* twin_tile = + pending_layer_->GetTwinTiling(tiling)->TileAt(iter.i(), iter.j()); + gfx::Rect scaled_content_rect = ScaleToEnclosingRect( + tile->content_rect(), 1.0f / tile->contents_scale()); + + if (scaled_content_rect.Intersects(invalidation_rect)) { + // Tiles inside the invalidation rect are only on the pending tree. + EXPECT_NE(tile, twin_tile); + + // Unshared tiles should be unoccluded on the active tree by default. + EXPECT_FALSE(tile->is_occluded(ACTIVE_TREE)); + } else { + // Tiles outside the invalidation rect are shared between both trees. + EXPECT_EQ(tile, twin_tile); + // Shared tiles are occluded on the active tree iff they lie beneath the + // occluding layer. + EXPECT_EQ(tile->is_occluded(ACTIVE_TREE), + scaled_content_rect.x() >= occluding_layer_position.x()); + } + } + } + + for (size_t i = 0; i < active_layer_->num_tilings(); ++i) { + PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i); + + for (PictureLayerTiling::CoverageIterator iter( + tiling, + active_layer_->contents_scale_x(), + gfx::Rect(layer_bounds)); + iter; + ++iter) { + if (!*iter) + continue; + const Tile* tile = *iter; + + Tile* twin_tile = + active_layer_->GetTwinTiling(tiling)->TileAt(iter.i(), iter.j()); + gfx::Rect scaled_content_rect = ScaleToEnclosingRect( + tile->content_rect(), 1.0f / tile->contents_scale()); + + // Since we've already checked the shared tiles, only consider tiles in + // the invalidation rect. + if (scaled_content_rect.Intersects(invalidation_rect)) { + // Tiles inside the invalidation rect are only on the active tree. + EXPECT_NE(tile, twin_tile); + + // Unshared tiles should be unoccluded on the pending tree by default. + EXPECT_FALSE(tile->is_occluded(PENDING_TREE)); + + // Unshared tiles are occluded on the active tree iff they lie beneath + // the occluding layer. + EXPECT_EQ(tile->is_occluded(ACTIVE_TREE), + scaled_content_rect.x() >= occluding_layer_position.x()); + } + } + } +} } // namespace } // namespace cc diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 1101f23..914cf54 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -495,7 +495,7 @@ void PictureLayerTiling::UpdateTilePriorities( is_occluded = occlusion_tracker->Occluded( render_target, tile_query_rect, draw_transform); } - tile->set_is_occluded(is_occluded); + tile->set_is_occluded(tree, is_occluded); } // Assign soon priority to skewport tiles. diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc index 781d008..48a10db 100644 --- a/cc/resources/tile.cc +++ b/cc/resources/tile.cc @@ -30,12 +30,13 @@ Tile::Tile(TileManager* tile_manager, content_rect_(content_rect), contents_scale_(contents_scale), opaque_rect_(opaque_rect), - is_occluded_(false), layer_id_(layer_id), source_frame_number_(source_frame_number), flags_(flags), id_(s_next_id_++) { set_picture_pile(picture_pile); + for (int i = 0; i < NUM_TREES; i++) + is_occluded_[i] = false; } Tile::~Tile() { diff --git a/cc/resources/tile.h b/cc/resources/tile.h index 29acf80..716ea99 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -128,8 +128,11 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { return managed_state_.tile_versions[mode]; } - void set_is_occluded(bool is_occluded) { is_occluded_ = is_occluded; } - bool is_occluded() const { return is_occluded_; } + void set_is_occluded(WhichTree tree, bool is_occluded) { + is_occluded_[tree] = is_occluded; + } + + bool is_occluded(WhichTree tree) const { return is_occluded_[tree]; } private: friend class TileManager; @@ -160,7 +163,7 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { gfx::Rect content_rect_; float contents_scale_; gfx::Rect opaque_rect_; - bool is_occluded_; + bool is_occluded_[NUM_TREES]; TilePriority priority_[NUM_TREES]; ManagedTileState managed_state_; |