Index: cc/trees/layer_tree_impl.cc |
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc |
index 80ccf14d7ba303bdda932fea2d83e842240bfc25..4093c425eb19541fc3a05651e0318a13c1313eed 100644 |
--- a/cc/trees/layer_tree_impl.cc |
+++ b/cc/trees/layer_tree_impl.cc |
@@ -4,6 +4,7 @@ |
#include "cc/trees/layer_tree_impl.h" |
+#include <algorithm> |
#include <limits> |
#include <set> |
@@ -76,6 +77,7 @@ class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate { |
LayerTreeImpl::LayerTreeImpl( |
LayerTreeHostImpl* layer_tree_host_impl, |
scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, |
+ scoped_refptr<SyncedTopControls> top_controls_shown_ratio, |
scoped_refptr<SyncedElasticOverscroll> elastic_overscroll) |
: layer_tree_host_impl_(layer_tree_host_impl), |
source_frame_number_(-1), |
@@ -102,9 +104,7 @@ LayerTreeImpl::LayerTreeImpl( |
render_surface_layer_list_id_(0), |
top_controls_shrink_blink_size_(false), |
top_controls_height_(0), |
- top_controls_content_offset_(0), |
- top_controls_delta_(0), |
- sent_top_controls_delta_(0) { |
+ top_controls_shown_ratio_(top_controls_shown_ratio) { |
} |
LayerTreeImpl::~LayerTreeImpl() { |
@@ -210,20 +210,10 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { |
target_tree->PassSwapPromises(&swap_promise_list_); |
- // Track the change in top controls height to offset the top_controls_delta |
- // properly. This is so that the top controls offset will be maintained |
- // across height changes. |
- float top_controls_height_delta = |
- target_tree->top_controls_height_ - top_controls_height_; |
- |
- target_tree->top_controls_shrink_blink_size_ = |
- top_controls_shrink_blink_size_; |
- target_tree->top_controls_height_ = top_controls_height_; |
- target_tree->top_controls_content_offset_ = top_controls_content_offset_; |
- target_tree->top_controls_delta_ = target_tree->top_controls_delta_ - |
- target_tree->sent_top_controls_delta_ - |
- top_controls_height_delta; |
- target_tree->sent_top_controls_delta_ = 0.f; |
+ target_tree->set_top_controls_shrink_blink_size( |
+ top_controls_shrink_blink_size_); |
+ target_tree->set_top_controls_height(top_controls_height_); |
+ target_tree->PushTopControls(nullptr); |
// Active tree already shares the page_scale_factor object with pending |
// tree so only the limits need to be provided. |
@@ -364,6 +354,48 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor, |
DidUpdatePageScale(); |
} |
+void LayerTreeImpl::set_top_controls_shrink_blink_size(bool shrink) { |
+ if (top_controls_shrink_blink_size_ == shrink) |
+ return; |
+ |
+ top_controls_shrink_blink_size_ = shrink; |
+ if (IsActiveTree()) |
+ layer_tree_host_impl_->UpdateViewportContainerSizes(); |
+} |
+ |
+void LayerTreeImpl::set_top_controls_height(float top_controls_height) { |
+ if (top_controls_height_ == top_controls_height) |
+ return; |
+ |
+ top_controls_height_ = top_controls_height; |
+ if (IsActiveTree()) |
+ layer_tree_host_impl_->UpdateViewportContainerSizes(); |
+} |
+ |
+bool LayerTreeImpl::SetCurrentTopControlsShownRatio(float ratio) { |
+ ratio = std::max(ratio, 0.f); |
+ ratio = std::min(ratio, 1.f); |
+ return top_controls_shown_ratio_->SetCurrent(ratio); |
+} |
+ |
+void LayerTreeImpl::PushTopControlsFromMainThread( |
+ float top_controls_shown_ratio) { |
+ PushTopControls(&top_controls_shown_ratio); |
+} |
+ |
+void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) { |
+ DCHECK(top_controls_shown_ratio || IsActiveTree()); |
+ |
+ if (top_controls_shown_ratio) { |
+ DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree()); |
+ top_controls_shown_ratio_->PushFromMainThread(*top_controls_shown_ratio); |
+ } |
+ if (IsActiveTree()) { |
+ if (top_controls_shown_ratio_->PushPendingToActive()) |
+ layer_tree_host_impl_->DidChangeTopControlsPosition(); |
+ } |
+} |
+ |
bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor, |
float max_page_scale_factor) { |
if (min_page_scale_factor == min_page_scale_factor_ && |
@@ -451,12 +483,9 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { |
DCHECK(IsActiveTree()); |
page_scale_factor()->AbortCommit(); |
+ top_controls_shown_ratio()->AbortCommit(); |
elastic_overscroll()->AbortCommit(); |
- top_controls_content_offset_ += sent_top_controls_delta_; |
- top_controls_delta_ -= sent_top_controls_delta_; |
- sent_top_controls_delta_ = 0.f; |
- |
if (!root_layer()) |
return; |
@@ -520,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 = |
@@ -548,66 +574,93 @@ 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 && !inside_replica) { |
+ if (layer->render_target()->has_replica()) |
+ inside_replica = true; |
+ 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; |
+ } |
+ 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); |
+ size_t layers_updated_count = 0; |
+ bool tile_priorities_updated = false; |
+ for (PictureLayerImpl* layer : picture_layers_) { |
+ if (!layer->IsDrawnRenderSurfaceLayerListMember()) |
+ continue; |
+ ++layers_updated_count; |
+ tile_priorities_updated |= layer->UpdateTiles(resourceless_software_draw); |
} |
if (tile_priorities_updated) |
@@ -628,6 +681,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() |
@@ -739,6 +799,10 @@ const LayerTreeSettings& LayerTreeImpl::settings() const { |
return layer_tree_host_impl_->settings(); |
} |
+const LayerTreeDebugState& LayerTreeImpl::debug_state() const { |
+ return layer_tree_host_impl_->debug_state(); |
+} |
+ |
const RendererCapabilitiesImpl& LayerTreeImpl::GetRendererCapabilities() const { |
return layer_tree_host_impl_->GetRendererCapabilities(); |
} |
@@ -775,6 +839,14 @@ gfx::Size LayerTreeImpl::device_viewport_size() const { |
return layer_tree_host_impl_->device_viewport_size(); |
} |
+float LayerTreeImpl::device_scale_factor() const { |
+ return layer_tree_host_impl_->device_scale_factor(); |
+} |
+ |
+DebugRectHistory* LayerTreeImpl::debug_rect_history() const { |
+ return layer_tree_host_impl_->debug_rect_history(); |
+} |
+ |
bool LayerTreeImpl::IsActiveTree() const { |
return layer_tree_host_impl_->active_tree() == this; |
} |
@@ -882,18 +954,6 @@ void LayerTreeImpl::SetNeedsRedraw() { |
layer_tree_host_impl_->SetNeedsRedraw(); |
} |
-const LayerTreeDebugState& LayerTreeImpl::debug_state() const { |
- return layer_tree_host_impl_->debug_state(); |
-} |
- |
-float LayerTreeImpl::device_scale_factor() const { |
- return layer_tree_host_impl_->device_scale_factor(); |
-} |
- |
-DebugRectHistory* LayerTreeImpl::debug_rect_history() const { |
- return layer_tree_host_impl_->debug_rect_history(); |
-} |
- |
AnimationRegistrar* LayerTreeImpl::animationRegistrar() const { |
return layer_tree_host_impl_->animation_registrar(); |
} |
@@ -912,7 +972,7 @@ void LayerTreeImpl::GetAllTilesForTracing(std::set<const Tile*>* tiles) const { |
} |
} |
-void LayerTreeImpl::AsValueInto(base::debug::TracedValue* state) const { |
+void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const { |
TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl", this); |
state->SetInteger("source_frame_number", source_frame_number_); |
@@ -1120,6 +1180,19 @@ void LayerTreeImpl::ProcessUIResourceRequestQueue() { |
layer_tree_host_impl_->SetNeedsCommit(); |
} |
+void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) { |
+ DCHECK(std::find(picture_layers_.begin(), picture_layers_.end(), layer) == |
+ picture_layers_.end()); |
+ picture_layers_.push_back(layer); |
+} |
+ |
+void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { |
+ std::vector<PictureLayerImpl*>::iterator it = |
+ std::find(picture_layers_.begin(), picture_layers_.end(), layer); |
+ DCHECK(it != picture_layers_.end()); |
+ picture_layers_.erase(it); |
+} |
+ |
void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) { |
// Only the active tree needs to know about layers with copy requests, as |
// they are aborted if not serviced during draw. |
@@ -1532,14 +1605,6 @@ void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* start, |
} |
} |
-void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) { |
- layer_tree_host_impl_->RegisterPictureLayerImpl(layer); |
-} |
- |
-void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { |
- layer_tree_host_impl_->UnregisterPictureLayerImpl(layer); |
-} |
- |
void LayerTreeImpl::InputScrollAnimationFinished() { |
layer_tree_host_impl_->ScrollEnd(); |
} |