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

Unified Diff: cc/trees/layer_tree_impl.cc

Issue 1038173002: Refactor delegated scrolling in LayerImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove "scrollOffsetDelegate" Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
« cc/layers/layer_impl.h ('K') | « cc/trees/layer_tree_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/trees/layer_tree_impl.cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index c2edaae65d308c7b3eca5b5b5607288d99012da5..8dfa560b66ea2218facc9ca7539ac369b13e3d88 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -19,6 +19,7 @@
#include "cc/base/util.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
+#include "cc/input/layer_scroll_offset_delegate.h"
#include "cc/input/page_scale_animation.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
@@ -34,43 +35,29 @@
#include "ui/gfx/geometry/vector2d_conversions.h"
namespace cc {
-// This class exists to split the LayerScrollOffsetDelegate between the
-// InnerViewportScrollLayer and the OuterViewportScrollLayer in a manner
-// that never requires the embedder or LayerImpl to know about.
-class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate {
- public:
- LayerScrollOffsetDelegateProxy(LayerImpl* layer,
- LayerScrollOffsetDelegate* delegate,
- LayerTreeImpl* layer_tree)
- : layer_(layer), delegate_(delegate), layer_tree_impl_(layer_tree) {}
- virtual ~LayerScrollOffsetDelegateProxy() {}
-
- gfx::ScrollOffset last_set_scroll_offset() const {
- return last_set_scroll_offset_;
- }
-
- // LayerScrollOffsetDelegate implementation.
- void SetCurrentScrollOffset(const gfx::ScrollOffset& new_offset) override {
- last_set_scroll_offset_ = new_offset;
- }
- gfx::ScrollOffset GetCurrentScrollOffset() override {
- return layer_tree_impl_->GetDelegatedScrollOffset(layer_);
- }
+// This class listens to the scroll offset changes of inner and outer viewport
+// scroll layer. When they change, the root layer scroll offset delegate needs
+// to be updated accordingly.
+class LayerExternalScrollOffsetListener
+ : public LayerImpl::ExternalScrollOffsetListener {
+ public:
+ LayerExternalScrollOffsetListener(LayerScrollOffsetDelegate* delegate,
+ LayerTreeImpl* layer_tree)
+ : root_delegate_(delegate), layer_tree_impl_(layer_tree) {}
+ virtual ~LayerExternalScrollOffsetListener() {}
bool IsExternalFlingActive() const override {
- return delegate_->IsExternalFlingActive();
+ return root_delegate_->IsExternalFlingActive();
}
- void Update() const override {
- layer_tree_impl_->UpdateScrollOffsetDelegate();
+ void DidUpdateScrollOffset() const override {
+ layer_tree_impl_->UpdateRootScrollOffsetDelegate();
}
private:
- LayerImpl* layer_;
- LayerScrollOffsetDelegate* delegate_;
+ LayerScrollOffsetDelegate* root_delegate_;
LayerTreeImpl* layer_tree_impl_;
- gfx::ScrollOffset last_set_scroll_offset_;
};
LayerTreeImpl::LayerTreeImpl(
@@ -150,11 +137,10 @@ void LayerTreeImpl::GatherFrameTimingRequestIds(
void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) {
if (inner_viewport_scroll_layer_)
- inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
+ inner_viewport_scroll_layer_->SetExternalScrollOffsetListener(NULL);
if (outer_viewport_scroll_layer_)
- outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
- inner_viewport_scroll_delegate_proxy_ = nullptr;
- outer_viewport_scroll_delegate_proxy_ = nullptr;
+ outer_viewport_scroll_layer_->SetExternalScrollOffsetListener(NULL);
+ layer_scroll_offset_listener_ = nullptr;
root_layer_ = layer.Pass();
currently_scrolling_layer_ = NULL;
@@ -202,11 +188,10 @@ scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
scrolling_layer_id_from_previous_tree_ =
currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
if (inner_viewport_scroll_layer_)
- inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
+ inner_viewport_scroll_layer_->SetExternalScrollOffsetListener(NULL);
if (outer_viewport_scroll_layer_)
- outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL);
- inner_viewport_scroll_delegate_proxy_ = nullptr;
- outer_viewport_scroll_delegate_proxy_ = nullptr;
+ outer_viewport_scroll_layer_->SetExternalScrollOffsetListener(NULL);
+ layer_scroll_offset_listener_ = nullptr;
inner_viewport_scroll_layer_ = NULL;
outer_viewport_scroll_layer_ = NULL;
page_scale_layer_ = NULL;
@@ -532,16 +517,9 @@ void LayerTreeImpl::SetViewportLayersFromIds(
if (!root_layer_scroll_offset_delegate_)
return;
- inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
- new LayerScrollOffsetDelegateProxy(inner_viewport_scroll_layer_,
- root_layer_scroll_offset_delegate_,
- this));
-
- if (outer_viewport_scroll_layer_)
- outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
- new LayerScrollOffsetDelegateProxy(outer_viewport_scroll_layer_,
- root_layer_scroll_offset_delegate_,
- this));
+ layer_scroll_offset_listener_ =
+ make_scoped_ptr(new LayerExternalScrollOffsetListener(
+ root_layer_scroll_offset_delegate_, this));
}
void LayerTreeImpl::ClearViewportLayers() {
@@ -1044,11 +1022,10 @@ void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
// Make sure we remove the proxies from their layers before
// releasing them.
if (InnerViewportScrollLayer())
- InnerViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
+ InnerViewportScrollLayer()->SetExternalScrollOffsetListener(NULL);
if (OuterViewportScrollLayer())
- OuterViewportScrollLayer()->SetScrollOffsetDelegate(NULL);
- inner_viewport_scroll_delegate_proxy_ = nullptr;
- outer_viewport_scroll_delegate_proxy_ = nullptr;
+ OuterViewportScrollLayer()->SetExternalScrollOffsetListener(NULL);
+ layer_scroll_offset_listener_ = nullptr;
}
root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
@@ -1059,54 +1036,31 @@ void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
current_page_scale_factor(), min_page_scale_factor(),
max_page_scale_factor());
+ layer_scroll_offset_listener_ =
+ make_scoped_ptr(new LayerExternalScrollOffsetListener(
+ root_layer_scroll_offset_delegate_, this));
+
if (inner_viewport_scroll_layer_) {
- inner_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
- new LayerScrollOffsetDelegateProxy(InnerViewportScrollLayer(),
- root_layer_scroll_offset_delegate_,
- this));
- inner_viewport_scroll_layer_->SetScrollOffsetDelegate(
- inner_viewport_scroll_delegate_proxy_.get());
+ inner_viewport_scroll_layer_->SetExternalScrollOffsetListener(
+ layer_scroll_offset_listener_.get());
}
if (outer_viewport_scroll_layer_) {
- outer_viewport_scroll_delegate_proxy_ = make_scoped_ptr(
- new LayerScrollOffsetDelegateProxy(OuterViewportScrollLayer(),
- root_layer_scroll_offset_delegate_,
- this));
- outer_viewport_scroll_layer_->SetScrollOffsetDelegate(
- outer_viewport_scroll_delegate_proxy_.get());
+ outer_viewport_scroll_layer_->SetExternalScrollOffsetListener(
+ layer_scroll_offset_listener_.get());
}
- if (inner_viewport_scroll_layer_)
- inner_viewport_scroll_layer_->RefreshFromScrollDelegate();
- if (outer_viewport_scroll_layer_)
- outer_viewport_scroll_layer_->RefreshFromScrollDelegate();
-
- if (inner_viewport_scroll_layer_)
- UpdateScrollOffsetDelegate();
- }
-}
-
-void LayerTreeImpl::OnRootLayerDelegatedScrollOffsetChanged() {
- DCHECK(root_layer_scroll_offset_delegate_);
- if (inner_viewport_scroll_layer_) {
- inner_viewport_scroll_layer_->RefreshFromScrollDelegate();
- }
- if (outer_viewport_scroll_layer_) {
- outer_viewport_scroll_layer_->RefreshFromScrollDelegate();
+ DistributeRootScrollOffset();
}
}
-void LayerTreeImpl::UpdateScrollOffsetDelegate() {
- DCHECK(InnerViewportScrollLayer());
- DCHECK(!OuterViewportScrollLayer() || outer_viewport_scroll_delegate_proxy_);
+void LayerTreeImpl::UpdateRootScrollOffsetDelegate() {
DCHECK(root_layer_scroll_offset_delegate_);
- gfx::ScrollOffset offset =
- inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
+ gfx::ScrollOffset offset = InnerViewportScrollLayer()->CurrentScrollOffset();
if (OuterViewportScrollLayer())
- offset += outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
+ offset += OuterViewportScrollLayer()->CurrentScrollOffset();
root_layer_scroll_offset_delegate_->UpdateRootLayerState(
offset, TotalMaxScrollOffset(), ScrollableSize(),
@@ -1114,44 +1068,61 @@ void LayerTreeImpl::UpdateScrollOffsetDelegate() {
max_page_scale_factor());
}
-gfx::ScrollOffset LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) {
- DCHECK(root_layer_scroll_offset_delegate_);
- DCHECK(InnerViewportScrollLayer());
- if (layer == InnerViewportScrollLayer() && !OuterViewportScrollLayer())
- return root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
+void LayerTreeImpl::DistributeRootScrollOffset() {
+ if (!root_layer_scroll_offset_delegate_)
+ return;
+
+ gfx::ScrollOffset root_offset =
+ root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
+
+ if (!InnerViewportScrollLayer())
+ return;
+
+ if (!OuterViewportScrollLayer()) {
aelias_OOO_until_Jul13 2015/04/06 19:57:32 You can delete this block and DCHECK that an Outer
hush (inactive) 2015/04/06 23:08:03 The tests are exercising the InnerViewportScrollLa
+ InnerViewportScrollLayer()->SetExternalScrollOffsetListener(NULL);
+ InnerViewportScrollLayer()->SetCurrentScrollOffset(root_offset);
+ InnerViewportScrollLayer()->SetExternalScrollOffsetListener(
+ layer_scroll_offset_listener_.get());
+ UpdateRootScrollOffsetDelegate();
+ return;
+ }
// If we get here, we have both inner/outer viewports, and need to distribute
// the scroll offset between them.
- DCHECK(inner_viewport_scroll_delegate_proxy_);
- DCHECK(outer_viewport_scroll_delegate_proxy_);
+ // It is okay for inner and outer viewport scroll layer to have no scroll
+ // delegate at this time.
gfx::ScrollOffset inner_viewport_offset =
- inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
+ InnerViewportScrollLayer()->CurrentScrollOffset();
gfx::ScrollOffset outer_viewport_offset =
- outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
+ OuterViewportScrollLayer()->CurrentScrollOffset();
// It may be nothing has changed.
- gfx::ScrollOffset delegate_offset =
- root_layer_scroll_offset_delegate_->GetTotalScrollOffset();
- if (inner_viewport_offset + outer_viewport_offset == delegate_offset) {
- if (layer == InnerViewportScrollLayer())
- return inner_viewport_offset;
- else
- return outer_viewport_offset;
- }
+ if (inner_viewport_offset + outer_viewport_offset == root_offset)
+ return;
+
+ // Temporarily uninstall the scroll offset listeners so that the root scroll
+ // offset delegate is not thrashed back and forth when the inner and outer
+ // viewport scroll layer change their scroll offsets.
+ InnerViewportScrollLayer()->SetExternalScrollOffsetListener(NULL);
+ OuterViewportScrollLayer()->SetExternalScrollOffsetListener(NULL);
gfx::ScrollOffset max_outer_viewport_scroll_offset =
OuterViewportScrollLayer()->MaxScrollOffset();
- outer_viewport_offset = delegate_offset - inner_viewport_offset;
+ outer_viewport_offset = root_offset - inner_viewport_offset;
outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset);
outer_viewport_offset.SetToMax(gfx::ScrollOffset());
- if (layer == OuterViewportScrollLayer())
- return outer_viewport_offset;
+ OuterViewportScrollLayer()->SetCurrentScrollOffset(outer_viewport_offset);
+ inner_viewport_offset = root_offset - outer_viewport_offset;
+ InnerViewportScrollLayer()->SetCurrentScrollOffset(inner_viewport_offset);
- inner_viewport_offset = delegate_offset - outer_viewport_offset;
+ InnerViewportScrollLayer()->SetExternalScrollOffsetListener(
+ layer_scroll_offset_listener_.get());
+ OuterViewportScrollLayer()->SetExternalScrollOffsetListener(
+ layer_scroll_offset_listener_.get());
- return inner_viewport_offset;
+ UpdateRootScrollOffsetDelegate();
}
void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
« cc/layers/layer_impl.h ('K') | « cc/trees/layer_tree_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698