Chromium Code Reviews| Index: cc/layers/layer_impl.cc |
| diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc |
| index 281a3ae411a624d9a35a94adde9b4f6fff3dd5e1..557ceacf81281df4912018a60e919f81c86209d3 100644 |
| --- a/cc/layers/layer_impl.cc |
| +++ b/cc/layers/layer_impl.cc |
| @@ -34,7 +34,13 @@ |
| #include "ui/gfx/geometry/vector2d_conversions.h" |
| namespace cc { |
| -LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) |
| +LayerImpl::LayerImpl(LayerTreeImpl* layer_impl, int id) |
| + : LayerImpl(layer_impl, id, new LayerImpl::SyncedScrollOffset) { |
| +} |
| + |
| +LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, |
| + int id, |
| + scoped_refptr<SyncedScrollOffset> scroll_offset) |
| : parent_(nullptr), |
| scroll_parent_(nullptr), |
| clip_parent_(nullptr), |
| @@ -42,6 +48,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) |
| replica_layer_id_(-1), |
| layer_id_(id), |
| layer_tree_impl_(tree_impl), |
| + scroll_offset_(scroll_offset), |
| scroll_offset_delegate_(nullptr), |
| scroll_clip_layer_(nullptr), |
| should_scroll_on_main_thread_(false), |
| @@ -346,18 +353,8 @@ void LayerImpl::GetContentsResourceId(ResourceProvider::ResourceId* resource_id, |
| *resource_id = 0; |
| } |
| -void LayerImpl::SetSentScrollDelta(const gfx::Vector2dF& sent_scroll_delta) { |
| - // Pending tree never has sent scroll deltas |
| - DCHECK(layer_tree_impl()->IsActiveTree()); |
| - |
| - if (sent_scroll_delta_ == sent_scroll_delta) |
| - return; |
| - |
| - sent_scroll_delta_ = sent_scroll_delta; |
| -} |
| - |
| gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { |
| - gfx::Vector2dF adjusted_scroll = scroll; |
| + gfx::ScrollOffset adjusted_scroll(scroll); |
| if (layer_tree_impl()->settings().use_pinch_virtual_viewport) { |
| if (!user_scrollable_horizontal_) |
| adjusted_scroll.set_x(0); |
| @@ -365,17 +362,14 @@ gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { |
| adjusted_scroll.set_y(0); |
| } |
| DCHECK(scrollable()); |
| - gfx::Vector2dF min_delta = -ScrollOffsetToVector2dF(scroll_offset_); |
| - gfx::Vector2dF max_delta = MaxScrollOffset().DeltaFrom(scroll_offset_); |
| - // Clamp new_delta so that position + delta stays within scroll bounds. |
| - gfx::Vector2dF new_delta = (ScrollDelta() + adjusted_scroll); |
| - new_delta.SetToMax(min_delta); |
| - new_delta.SetToMin(max_delta); |
| - gfx::Vector2dF unscrolled = |
| - ScrollDelta() + scroll - new_delta; |
| - SetScrollDelta(new_delta); |
| + gfx::ScrollOffset old_offset = CurrentScrollOffset(); |
| + gfx::ScrollOffset new_offset = |
| + ClampScrollOffsetToLimits(old_offset + adjusted_scroll); |
| + SetScrollOffsetOnActiveTree(new_offset); |
| - return unscrolled; |
| + gfx::ScrollOffset unscrolled = |
| + old_offset + gfx::ScrollOffset(scroll) - new_offset; |
| + return gfx::Vector2dF(unscrolled.x(), unscrolled.y()); |
| } |
| void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { |
| @@ -388,41 +382,8 @@ bool LayerImpl::user_scrollable(ScrollbarOrientation orientation) const { |
| } |
| void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { |
| - if (sent_scroll_delta_.IsZero()) |
| - return; |
| - |
| - // Pending tree never has sent scroll deltas |
| DCHECK(layer_tree_impl()->IsActiveTree()); |
| - |
| - // The combination of pending tree and aborted commits with impl scrolls |
| - // shouldn't happen; we don't know how to update its deltas correctly. |
| - DCHECK(!layer_tree_impl()->FindPendingTreeLayerById(id())); |
| - |
| - // Apply sent scroll deltas to scroll position / scroll delta as if the |
| - // main thread had applied them and then committed those values. |
| - SetScrollOffsetAndDelta( |
| - scroll_offset_ + gfx::ScrollOffset(sent_scroll_delta_), |
| - ScrollDelta() - sent_scroll_delta_); |
| - SetSentScrollDelta(gfx::Vector2dF()); |
| -} |
| - |
| -void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() { |
| - // Only the pending tree can have missing scrolls. |
| - DCHECK(layer_tree_impl()->IsPendingTree()); |
| - if (!scrollable()) |
| - return; |
| - |
| - // Pending tree should never have sent scroll deltas. |
| - DCHECK(sent_scroll_delta().IsZero()); |
| - |
| - LayerImpl* active_twin = layer_tree_impl()->FindActiveTreeLayerById(id()); |
| - if (active_twin) { |
| - // Scrolls that happens after begin frame (where the sent scroll delta |
| - // comes from) and commit need to be applied to the pending tree |
| - // so that it is up to date with the total scroll. |
| - SetScrollDelta(active_twin->ScrollDelta() - |
| - active_twin->sent_scroll_delta()); |
| - } |
| + scroll_offset_->AbortCommit(); |
| } |
| InputHandler::ScrollStatus LayerImpl::TryScroll( |
| @@ -501,7 +462,7 @@ skia::RefPtr<SkPicture> LayerImpl::GetPicture() { |
| } |
| scoped_ptr<LayerImpl> LayerImpl::CreateLayerImpl(LayerTreeImpl* tree_impl) { |
| - return LayerImpl::Create(tree_impl, layer_id_); |
| + return LayerImpl::Create(tree_impl, layer_id_, scroll_offset_); |
| } |
| void LayerImpl::PushPropertiesTo(LayerImpl* layer) { |
| @@ -541,12 +502,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { |
| layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); |
| layer->set_user_scrollable_vertical(user_scrollable_vertical_); |
| - // Save the difference but clear the sent delta so that we don't subtract |
| - // it again in SetScrollOffsetAndDelta's pending twin mirroring logic. |
| - gfx::Vector2dF remaining_delta = |
| - layer->ScrollDelta() - layer->sent_scroll_delta(); |
| - layer->SetSentScrollDelta(gfx::Vector2dF()); |
| - layer->SetScrollOffsetAndDelta(scroll_offset_, remaining_delta); |
| + layer->PushScrollOffset(nullptr); |
| layer->Set3dSortingContextId(sorting_context_id_); |
| layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_); |
| @@ -752,8 +708,8 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() { |
| num_dependents_need_push_properties_ = 0; |
| } |
| -gfx::ScrollOffset LayerImpl::ScrollOffsetForAnimation() const { |
| - return TotalScrollOffset(); |
| +gfx::ScrollOffset LayerImpl::ScrollOffsetForAnimation() { |
| + return CurrentScrollOffset(); |
| } |
| void LayerImpl::OnFilterAnimated(const FilterOperations& filters) { |
| @@ -771,11 +727,11 @@ void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { |
| void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) { |
| // Only layers in the active tree should need to do anything here, since |
| // layers in the pending tree will find out about these changes as a |
| - // result of the call to SetScrollDelta. |
| + // result of the shared SyncedProperty. |
| if (!IsActive()) |
| return; |
| - SetScrollDelta(scroll_offset.DeltaFrom(scroll_offset_)); |
| + SetScrollOffsetOnActiveTree(scroll_offset); |
| layer_tree_impl_->DidAnimateScrollOffset(); |
| } |
| @@ -1084,11 +1040,9 @@ void LayerImpl::SetScrollOffsetDelegate( |
| ScrollOffsetDelegate* scroll_offset_delegate) { |
| // Having both a scroll parent and a scroll offset delegate is unsupported. |
| DCHECK(!scroll_parent_); |
| - if (!scroll_offset_delegate && scroll_offset_delegate_) { |
| - scroll_delta_ = scroll_offset_delegate_->GetTotalScrollOffset().DeltaFrom( |
| - scroll_offset_); |
| - } |
| - gfx::ScrollOffset total_offset = TotalScrollOffset(); |
| + if (!scroll_offset_delegate && scroll_offset_delegate_) |
| + scroll_offset_->SetCurrent(scroll_offset_delegate_->GetTotalScrollOffset()); |
| + gfx::ScrollOffset total_offset = CurrentScrollOffset(); |
| scroll_offset_delegate_ = scroll_offset_delegate; |
| if (scroll_offset_delegate_) |
| scroll_offset_delegate_->SetTotalScrollOffset(total_offset); |
| @@ -1099,74 +1053,53 @@ bool LayerImpl::IsExternalFlingActive() const { |
| scroll_offset_delegate_->IsExternalFlingActive(); |
| } |
| -void LayerImpl::DidScroll() { |
| - NoteLayerPropertyChangedForSubtree(); |
| - ScrollbarParametersDidChange(false); |
| +void LayerImpl::SetScrollOffsetOnActiveTree( |
| + const gfx::ScrollOffset& scroll_offset) { |
| + DCHECK(IsActive()); |
| + if (scroll_offset_->SetCurrent(scroll_offset)) |
| + DidUpdateScrollOffset(); |
| } |
| -void LayerImpl::SetScrollOffset(const gfx::ScrollOffset& scroll_offset) { |
| - SetScrollOffsetAndDelta(scroll_offset, ScrollDelta()); |
| +void LayerImpl::PushScrollOffsetFromMainThread( |
| + const gfx::ScrollOffset& scroll_offset) { |
| + PushScrollOffset(&scroll_offset); |
| } |
| -void LayerImpl::SetScrollOffsetAndDelta(const gfx::ScrollOffset& scroll_offset, |
| - const gfx::Vector2dF& scroll_delta) { |
| - bool changed = false; |
| - |
| - last_scroll_offset_ = scroll_offset; |
| - |
| - if (scroll_offset_ != scroll_offset) { |
| - changed = true; |
| - scroll_offset_ = scroll_offset; |
| - |
| - if (scroll_offset_delegate_) |
| - scroll_offset_delegate_->SetTotalScrollOffset(TotalScrollOffset()); |
| +void LayerImpl::RefreshScrollDelegate() { |
| + if (scroll_offset_delegate_) { |
| + SetScrollOffsetOnActiveTree( |
| + gfx::ScrollOffset(scroll_offset_delegate_->GetTotalScrollOffset())); |
| } |
| +} |
| - if (ScrollDelta() != scroll_delta) { |
| - changed = true; |
| - if (layer_tree_impl()->IsActiveTree()) { |
| - LayerImpl* pending_twin = |
| - layer_tree_impl()->FindPendingTreeLayerById(id()); |
| - if (pending_twin) { |
| - // The pending twin can't mirror the scroll delta of the active |
| - // layer. Although the delta - sent scroll delta difference is |
| - // identical for both twins, the sent scroll delta for the pending |
| - // layer is zero, as anything that has been sent has been baked |
| - // into the layer's position/scroll offset as a part of commit. |
| - DCHECK(pending_twin->sent_scroll_delta().IsZero()); |
| - pending_twin->SetScrollDelta(scroll_delta - sent_scroll_delta()); |
| - } |
| - } |
| +gfx::ScrollOffset LayerImpl::CurrentScrollOffset() { |
| + RefreshScrollDelegate(); |
|
enne (OOO)
2015/01/16 23:25:14
Is there a better place to do this? "CurrentScroll
aelias_OOO_until_Jul13
2015/01/30 05:52:30
Fixed. I added "RefreshFromScrollDelegate()" call
|
| + return scroll_offset_->Current(IsActive()); |
| +} |
| - if (scroll_offset_delegate_) { |
| - scroll_offset_delegate_->SetTotalScrollOffset( |
| - ScrollOffsetWithDelta(scroll_offset_, scroll_delta)); |
| - } else { |
| - scroll_delta_ = scroll_delta; |
| - } |
| +void LayerImpl::PushScrollOffset(const gfx::ScrollOffset* scroll_offset) { |
| + DCHECK(scroll_offset || IsActive()); |
| + bool changed = false; |
| + if (scroll_offset) { |
| + DCHECK(!IsActive() || !layer_tree_impl_->settings().impl_side_painting); |
| + changed |= scroll_offset_->PushFromMainThread(*scroll_offset); |
| } |
| + if (IsActive()) |
| + changed |= scroll_offset_->PushPendingToActive(); |
| - if (changed) { |
| - if (scroll_offset_delegate_) |
| - scroll_offset_delegate_->Update(); |
| - DidScroll(); |
| - } |
| + if (changed) |
| + DidUpdateScrollOffset(); |
| } |
| -gfx::Vector2dF LayerImpl::ScrollDelta() const { |
| +void LayerImpl::DidUpdateScrollOffset() { |
| if (scroll_offset_delegate_) { |
| - return scroll_offset_delegate_->GetTotalScrollOffset().DeltaFrom( |
| - scroll_offset_); |
| + scroll_offset_delegate_->SetTotalScrollOffset( |
| + scroll_offset_->Current(IsActive())); |
| + scroll_offset_delegate_->Update(); |
| } |
| - return scroll_delta_; |
| -} |
| - |
| -void LayerImpl::SetScrollDelta(const gfx::Vector2dF& scroll_delta) { |
| - SetScrollOffsetAndDelta(scroll_offset_, scroll_delta); |
| -} |
| -gfx::ScrollOffset LayerImpl::TotalScrollOffset() const { |
| - return ScrollOffsetWithDelta(scroll_offset_, ScrollDelta()); |
| + NoteLayerPropertyChangedForSubtree(); |
| + ScrollbarParametersDidChange(false); |
| } |
| void LayerImpl::SetDoubleSided(bool double_sided) { |
| @@ -1196,39 +1129,16 @@ gfx::ScrollOffset LayerImpl::MaxScrollOffset() const { |
| DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || |
| IsContainerForFixedPositionLayers()); |
| - gfx::SizeF scaled_scroll_bounds(BoundsForScrolling()); |
| - |
| float scale_factor = 1.f; |
| for (LayerImpl const* current_layer = this; |
| current_layer != scroll_clip_layer_; |
| current_layer = current_layer->parent()) { |
| - DCHECK(current_layer); |
| - float current_layer_scale = 1.f; |
| - |
| - const gfx::Transform& layer_transform = current_layer->transform(); |
| - if (current_layer == page_scale_layer) { |
| - DCHECK(layer_transform.IsIdentity()); |
| - current_layer_scale = layer_tree_impl()->current_page_scale_factor(); |
| - } else { |
| - // TODO(wjmaclean) Should we allow for translation too? |
| - DCHECK(layer_transform.IsScale2d()); |
| - gfx::Vector2dF layer_scale = layer_transform.Scale2d(); |
| - // TODO(wjmaclean) Allow for non-isotropic scales. |
| - DCHECK(layer_scale.x() == layer_scale.y()); |
| - current_layer_scale = layer_scale.x(); |
| - } |
| - |
| - scale_factor *= current_layer_scale; |
| + if (current_layer == page_scale_layer) |
| + scale_factor = layer_tree_impl()->current_page_scale_factor(); |
| } |
| - // TODO(wjmaclean) Once we move to a model where the two-viewport model is |
| - // turned on in all builds, remove the next two lines. For now however, the |
| - // page scale layer may coincide with the clip layer, and so this is |
| - // necessary. |
| - if (page_scale_layer == scroll_clip_layer_) |
| - scale_factor *= layer_tree_impl()->current_page_scale_factor(); |
| - |
| - scaled_scroll_bounds.SetSize(scale_factor * scaled_scroll_bounds.width(), |
| - scale_factor * scaled_scroll_bounds.height()); |
| + |
| + gfx::SizeF scaled_scroll_bounds = |
| + gfx::ToFlooredSize(gfx::ScaleSize(BoundsForScrolling(), scale_factor)); |
| scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds); |
| gfx::ScrollOffset max_offset( |
| @@ -1240,17 +1150,19 @@ gfx::ScrollOffset LayerImpl::MaxScrollOffset() const { |
| return max_offset; |
| } |
| -gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { |
| - gfx::ScrollOffset max_offset = MaxScrollOffset(); |
| - gfx::ScrollOffset old_offset = TotalScrollOffset(); |
| - gfx::ScrollOffset clamped_offset = old_offset; |
| +gfx::ScrollOffset LayerImpl::ClampScrollOffsetToLimits( |
| + gfx::ScrollOffset offset) const { |
| + offset.SetToMin(MaxScrollOffset()); |
| + offset.SetToMax(gfx::ScrollOffset()); |
| + return offset; |
| +} |
| - clamped_offset.SetToMin(max_offset); |
| - clamped_offset.SetToMax(gfx::ScrollOffset()); |
| +gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { |
| + gfx::ScrollOffset old_offset = CurrentScrollOffset(); |
| + gfx::ScrollOffset clamped_offset = ClampScrollOffsetToLimits(old_offset); |
| gfx::Vector2dF delta = clamped_offset.DeltaFrom(old_offset); |
| if (!delta.IsZero()) |
| ScrollBy(delta); |
| - |
| return delta; |
| } |
| @@ -1272,37 +1184,17 @@ void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, |
| if (scroll_rect.size().IsEmpty()) |
| return; |
| - // TODO(wjmaclean) This computation is nearly identical to the one in |
| - // MaxScrollOffset. Find some way to combine these. |
| gfx::ScrollOffset current_offset; |
| for (LayerImpl const* current_layer = this; |
| current_layer != scrollbar_clip_layer; |
| current_layer = current_layer->parent()) { |
| - DCHECK(current_layer); |
| - const gfx::Transform& layer_transform = current_layer->transform(); |
| + current_offset += scroll_offset_->Current(IsActive()); |
| if (current_layer == page_scale_layer) { |
| - DCHECK(layer_transform.IsIdentity()); |
| float scale_factor = layer_tree_impl()->current_page_scale_factor(); |
| current_offset.Scale(scale_factor); |
| scroll_rect.Scale(scale_factor); |
| - } else { |
| - DCHECK(layer_transform.IsScale2d()); |
| - gfx::Vector2dF layer_scale = layer_transform.Scale2d(); |
| - DCHECK(layer_scale.x() == layer_scale.y()); |
| - gfx::ScrollOffset new_offset = ScrollOffsetWithDelta( |
| - current_layer->scroll_offset(), current_layer->ScrollDelta()); |
| - new_offset.Scale(layer_scale.x(), layer_scale.y()); |
| - current_offset += new_offset; |
| } |
| } |
| - // TODO(wjmaclean) Once we move to a model where the two-viewport model is |
| - // turned on in all builds, remove the next two lines. For now however, the |
| - // page scale layer may coincide with the clip layer, and so this is |
| - // necessary. |
| - if (page_scale_layer == scrollbar_clip_layer) { |
| - scroll_rect.Scale(layer_tree_impl()->current_page_scale_factor()); |
| - current_offset.Scale(layer_tree_impl()->current_page_scale_factor()); |
| - } |
| bool scrollbar_needs_animation = false; |
| scrollbar_needs_animation |= scrollbar_layer->SetVerticalAdjust( |
| @@ -1466,7 +1358,10 @@ void LayerImpl::AsValueInto(base::debug::TracedValue* state) const { |
| state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes()); |
| state->BeginArray("scroll_offset"); |
| - MathUtil::AddToTracedValue(scroll_offset_, state); |
| + MathUtil::AddToTracedValue(scroll_offset_ |
| + ? scroll_offset_->Current(IsActive()) |
| + : gfx::ScrollOffset(), |
| + state); |
| state->EndArray(); |
| state->BeginArray("transform_origin"); |