Chromium Code Reviews| Index: cc/trees/layer_tree_impl.cc |
| diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc |
| index c48a09a23aeef1fc77c547dce2e9afc284ea3257..b4023c3819eecbddc579ab1771b02cf78fd7826a 100644 |
| --- a/cc/trees/layer_tree_impl.cc |
| +++ b/cc/trees/layer_tree_impl.cc |
| @@ -549,12 +549,9 @@ bool LayerTreeImpl::UpdateDrawProperties() { |
| render_surface_layer_list_.clear(); |
| { |
| - TRACE_EVENT2("cc", |
| - "LayerTreeImpl::UpdateDrawProperties", |
| - "IsActive", |
| - IsActiveTree(), |
| - "SourceFrameNumber", |
| - source_frame_number_); |
| + TRACE_EVENT2( |
| + "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties", |
| + "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_); |
| LayerImpl* page_scale_layer = |
| page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer(); |
| bool can_render_to_separate_surface = |
| @@ -577,66 +574,100 @@ bool LayerTreeImpl::UpdateDrawProperties() { |
| } |
| { |
| - TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateTilePriorities", "IsActive", |
| - IsActiveTree(), "SourceFrameNumber", |
| - source_frame_number_); |
| - scoped_ptr<OcclusionTracker<LayerImpl>> occlusion_tracker; |
| - if (settings().use_occlusion_for_tile_prioritization) { |
| - occlusion_tracker.reset(new OcclusionTracker<LayerImpl>( |
| - root_layer()->render_surface()->content_rect())); |
| - occlusion_tracker->set_minimum_tracking_size( |
| - settings().minimum_occlusion_tracking_size); |
| - } |
| - |
| - bool resourceless_software_draw = (layer_tree_host_impl_->GetDrawMode() == |
| - DRAW_MODE_RESOURCELESS_SOFTWARE); |
| + TRACE_EVENT2("cc", "LayerTreeImpl::UpdateDrawProperties::Occlusion", |
| + "IsActive", IsActiveTree(), "SourceFrameNumber", |
| + source_frame_number_); |
| + OcclusionTracker<LayerImpl> occlusion_tracker( |
| + root_layer()->render_surface()->content_rect()); |
| + occlusion_tracker.set_minimum_tracking_size( |
| + settings().minimum_occlusion_tracking_size); |
| // LayerIterator is used here instead of CallFunctionForSubtree to only |
| // UpdateTilePriorities on layers that will be visible (and thus have valid |
| // draw properties) and not because any ordering is required. |
| - typedef LayerIterator<LayerImpl> LayerIteratorType; |
| - LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_); |
| - size_t layers_updated_count = 0; |
| - bool tile_priorities_updated = false; |
| - for (LayerIteratorType it = |
| - LayerIteratorType::Begin(&render_surface_layer_list_); |
| - it != end; |
| - ++it) { |
| - if (occlusion_tracker) |
| - occlusion_tracker->EnterLayer(it); |
| - |
| - LayerImpl* layer = *it; |
| - const Occlusion& occlusion_in_content_space = |
| - occlusion_tracker ? occlusion_tracker->GetCurrentOcclusionForLayer( |
| - layer->draw_transform()) |
| - : Occlusion(); |
| + auto end = LayerIterator<LayerImpl>::End(&render_surface_layer_list_); |
| + for (auto it = LayerIterator<LayerImpl>::Begin(&render_surface_layer_list_); |
| + it != end; ++it) { |
| + occlusion_tracker.EnterLayer(it); |
| + |
| + // There are very few render targets so this should be cheap to do for |
| + // each layer instead of something more complicated. |
| + bool inside_replica = false; |
| + LayerImpl* layer = it->render_target(); |
| + while (layer) { |
| + if (layer->render_target()->has_replica()) |
| + inside_replica = true; |
|
enne (OOO)
2015/02/13 18:26:24
And break? or while (layer && !inside_replica?)
danakj
2015/02/13 18:33:27
oh ya. i had a forloop that broke on inside_replic
danakj
2015/02/13 21:12:28
Done.
|
| + layer = layer->render_target()->parent(); |
| + } |
| + |
| + // Don't use occlusion if a layer will appear in a replica, since the |
| + // tile raster code does not know how to look for the replica and would |
| + // consider it occluded even though the replica is visible. |
| + // Since occlusion is only used for browser compositor (i.e. |
| + // use_occlusion_for_tile_prioritization) and it won't use replicas, |
| + // this should matter not. |
| if (it.represents_itself()) { |
| - tile_priorities_updated |= layer->UpdateTiles( |
| - occlusion_in_content_space, resourceless_software_draw); |
| - ++layers_updated_count; |
| + Occlusion occlusion = |
| + inside_replica ? Occlusion() |
| + : occlusion_tracker.GetCurrentOcclusionForLayer( |
| + it->draw_transform()); |
| + it->draw_properties().occlusion_in_content_space = occlusion; |
| } |
| - if (!it.represents_contributing_render_surface()) { |
| - if (occlusion_tracker) |
| - occlusion_tracker->LeaveLayer(it); |
| - continue; |
| + if (it.represents_contributing_render_surface()) { |
| + // Surfaces aren't used by the tile raster code, so they can have |
| + // occlusion regardless of replicas. |
| + Occlusion occlusion = |
| + occlusion_tracker.GetCurrentOcclusionForContributingSurface( |
| + it->render_surface()->draw_transform()); |
| + it->render_surface()->set_occlusion_in_content_space(occlusion); |
| + // Masks are used to draw the contributing surface, so should have |
| + // the same occlusion as the surface (nothing inside the surface |
| + // occludes them). |
| + if (LayerImpl* mask = it->mask_layer()) { |
| + Occlusion mask_occlusion = |
| + inside_replica |
| + ? Occlusion() |
| + : occlusion_tracker.GetCurrentOcclusionForContributingSurface( |
| + it->render_surface()->draw_transform() * |
| + it->draw_transform()); |
| + mask->draw_properties().occlusion_in_content_space = mask_occlusion; |
|
enne (OOO)
2015/02/13 18:26:24
Can you point me at tests verifying that masks are
danakj
2015/02/13 18:33:27
we dont. it uses the draw transform of the owning
enne (OOO)
2015/02/13 18:38:33
Ok, I looked at the test and looked at this closel
|
| + } |
| + if (LayerImpl* replica = it->replica_layer()) { |
| + if (LayerImpl* mask = replica->mask_layer()) |
| + mask->draw_properties().occlusion_in_content_space = Occlusion(); |
| + } |
| } |
| - if (layer->mask_layer()) { |
| - tile_priorities_updated |= layer->mask_layer()->UpdateTiles( |
| - occlusion_in_content_space, resourceless_software_draw); |
| - ++layers_updated_count; |
| - } |
| - if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { |
| - tile_priorities_updated |= |
| - layer->replica_layer()->mask_layer()->UpdateTiles( |
| - occlusion_in_content_space, resourceless_software_draw); |
| - ++layers_updated_count; |
| - } |
| + occlusion_tracker.LeaveLayer(it); |
| + } |
| + |
| + unoccluded_screen_space_region_ = |
| + occlusion_tracker.ComputeVisibleRegionInScreen(); |
| + } |
| - if (occlusion_tracker) |
| - occlusion_tracker->LeaveLayer(it); |
| + { |
| + TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateDrawProperties::UpdateTiles", |
| + "IsActive", IsActiveTree(), "SourceFrameNumber", |
| + source_frame_number_); |
| + const bool resourceless_software_draw = |
| + (layer_tree_host_impl_->GetDrawMode() == |
| + DRAW_MODE_RESOURCELESS_SOFTWARE); |
| + static const Occlusion kEmptyOcclusion; |
| + size_t layers_updated_count = 0; |
| + bool tile_priorities_updated = false; |
| + for (PictureLayerImpl* layer : picture_layers_) { |
| + // TODO(danakj): Remove this to fix crbug.com/446751 |
| + if (!layer->IsDrawnRenderSurfaceLayerListMember()) |
| + continue; |
| + ++layers_updated_count; |
| + const Occlusion& occlusion = |
| + settings().use_occlusion_for_tile_prioritization |
| + ? layer->draw_properties().occlusion_in_content_space |
| + : kEmptyOcclusion; |
| + tile_priorities_updated |= |
| + layer->UpdateTiles(occlusion, resourceless_software_draw); |
| } |
| if (tile_priorities_updated) |
| @@ -657,6 +688,13 @@ const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const { |
| return render_surface_layer_list_; |
| } |
| +const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const { |
| + // If this assert triggers, then the render_surface_layer_list_ is dirty, so |
| + // the unoccluded_screen_space_region_ is not valid anymore. |
| + DCHECK(!needs_update_draw_properties_); |
| + return unoccluded_screen_space_region_; |
| +} |
| + |
| gfx::Size LayerTreeImpl::ScrollableSize() const { |
| LayerImpl* root_scroll_layer = OuterViewportScrollLayer() |
| ? OuterViewportScrollLayer() |