diff options
author | wjmaclean@chromium.org <wjmaclean@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-29 13:54:33 +0000 |
---|---|---|
committer | wjmaclean@chromium.org <wjmaclean@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-29 13:54:33 +0000 |
commit | 610834cb98728532e1f296c77552f640f7c0ff7a (patch) | |
tree | ba2aee5588ed23c8ccfb0adf5be2ff14ddab29a4 /cc/layers | |
parent | 167f3c414c3d087653ac9d712add50b3b854fcbb (diff) | |
download | chromium_src-610834cb98728532e1f296c77552f640f7c0ff7a.zip chromium_src-610834cb98728532e1f296c77552f640f7c0ff7a.tar.gz chromium_src-610834cb98728532e1f296c77552f640f7c0ff7a.tar.bz2 |
Pinch/Zoom Infrastructure & Plumbing CL
This CL supplies the necessary changes to CC to support the
inner/outer viewport model for pinch-zoom and fixed-position
elements. The specification for these changes is contained in
the document "Layer-based Solution for Pinch Zoom / Fixed
Position".
It incorporates a change to how scrollbar parameters are
computed (removes the notion of max_scroll_offset as a
quantity set be the embedder, and instead inferred from the
relative sizes of a clip layer w.r.t. the scroll layer).
Scrollbars are generalized so that a layer may have more than
two scrollbars, and the parameters of the scrollbar are set
w.r.t. the sizes and positions of a clip and a scroll layer.
Further, changes to the scrip/scroll layer automatically
notify any attached scrollbars.
The CL also removes existing references to root_scroll_layer
from LTH, LTI and LTHI and replaces them with either
Inner/OuterViewportScrollLayer (dual-layer operation only
exists at present if the --enable-pinch-virtual-viewport flag
is specified, otherwise behavior is unchanged).
Logic is added to (i) combine scroll offsets for the two
viewports before passing it to the embedder, and (ii)
splitting any offsets received from the embedder
appropriately between the two viewports.
This CL relies on https://codereview.chromium.org/138453004/
for changes in Blink to support it.
BUG=148816
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=246812
R=aelias@chromium.org, enne@chromium.org, joi@chromium.org, piman@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/23983047
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247684 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/layers')
-rw-r--r-- | cc/layers/layer.cc | 57 | ||||
-rw-r--r-- | cc/layers/layer.h | 12 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 277 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 36 | ||||
-rw-r--r-- | cc/layers/layer_impl_unittest.cc | 76 | ||||
-rw-r--r-- | cc/layers/layer_perftest.cc | 2 | ||||
-rw-r--r-- | cc/layers/layer_position_constraint_unittest.cc | 110 | ||||
-rw-r--r-- | cc/layers/layer_unittest.cc | 3 | ||||
-rw-r--r-- | cc/layers/painted_scrollbar_layer.cc | 37 | ||||
-rw-r--r-- | cc/layers/painted_scrollbar_layer.h | 11 | ||||
-rw-r--r-- | cc/layers/painted_scrollbar_layer_impl.cc | 2 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_impl_base.cc | 53 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_impl_base.h | 24 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_interface.h | 7 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_unittest.cc | 150 | ||||
-rw-r--r-- | cc/layers/solid_color_scrollbar_layer.cc | 49 | ||||
-rw-r--r-- | cc/layers/solid_color_scrollbar_layer.h | 13 | ||||
-rw-r--r-- | cc/layers/solid_color_scrollbar_layer_impl.cc | 20 | ||||
-rw-r--r-- | cc/layers/solid_color_scrollbar_layer_impl.h | 6 |
19 files changed, 606 insertions, 339 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index f585006..c2c4041 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -16,11 +16,13 @@ #include "cc/animation/layer_animation_controller.h" #include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" +#include "cc/layers/scrollbar_layer_interface.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "third_party/skia/include/core/SkImageFilter.h" +#include "ui/gfx/geometry/vector2d_conversions.h" #include "ui/gfx/rect_conversions.h" namespace cc { @@ -39,7 +41,7 @@ Layer::Layer() ignore_set_needs_commit_(false), parent_(NULL), layer_tree_host_(NULL), - scrollable_(false), + scroll_clip_layer_(NULL), should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), user_scrollable_horizontal_(true), @@ -679,6 +681,12 @@ void Layer::RemoveClipChild(Layer* child) { void Layer::SetScrollOffset(gfx::Vector2d scroll_offset) { DCHECK(IsPropertyChangeAllowed()); + + if (layer_tree_host()) { + scroll_offset = layer_tree_host()->DistributeScrollOffsetToViewports( + scroll_offset, this); + } + if (scroll_offset_ == scroll_offset) return; scroll_offset_ = scroll_offset; @@ -700,19 +708,44 @@ void Layer::SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset) { // "this" may have been destroyed during the process. } -void Layer::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { - DCHECK(IsPropertyChangeAllowed()); - if (max_scroll_offset_ == max_scroll_offset) - return; - max_scroll_offset_ = max_scroll_offset; - SetNeedsCommit(); +// TODO(wjmaclean) We should template this and put it into LayerTreeHostCommon +// so that both Layer and LayerImpl are using the same code. In order +// to template it we should avoid calling layer_tree_host() by giving +// Layer/LayerImpl local accessors for page_scale_layer() and +// page_scale_factor(). +gfx::Vector2d Layer::MaxScrollOffset() const { + if (!scroll_clip_layer_) + return gfx::Vector2d(); + + gfx::Size scaled_scroll_bounds(bounds()); + Layer const* current_layer = this; + Layer const* page_scale_layer = layer_tree_host()->page_scale_layer(); + float scale_factor = 1.f; + do { + if (current_layer == page_scale_layer) { + scale_factor = layer_tree_host()->page_scale_factor(); + scaled_scroll_bounds.SetSize( + scale_factor * scaled_scroll_bounds.width(), + scale_factor * scaled_scroll_bounds.height()); + } + current_layer = current_layer->parent(); + } while (current_layer && current_layer != scroll_clip_layer_); + DCHECK(current_layer == scroll_clip_layer_); + + gfx::Vector2dF max_offset( + scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), + scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); + // We need the final scroll offset to be in CSS coords. + max_offset.Scale(1.f / scale_factor); + max_offset.SetToMax(gfx::Vector2dF()); + return gfx::ToFlooredVector2d(max_offset); } -void Layer::SetScrollable(bool scrollable) { +void Layer::SetScrollClipLayer(Layer* clip_layer) { DCHECK(IsPropertyChangeAllowed()); - if (scrollable_ == scrollable) + if (scroll_clip_layer_ == clip_layer) return; - scrollable_ = scrollable; + scroll_clip_layer_ = clip_layer; SetNeedsCommit(); } @@ -911,10 +944,10 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetTransform(transform_); DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly())); - layer->SetScrollable(scrollable_); + layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() + : Layer::INVALID_ID); layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); layer->set_user_scrollable_vertical(user_scrollable_vertical_); - layer->SetMaxScrollOffset(max_scroll_offset_); LayerImpl* scroll_parent = NULL; if (scroll_parent_) diff --git a/cc/layers/layer.h b/cc/layers/layer.h index df358f2..68b67e25 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -269,11 +269,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, gfx::Vector2d scroll_offset() const { return scroll_offset_; } void SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset); - void SetMaxScrollOffset(gfx::Vector2d max_scroll_offset); - gfx::Vector2d max_scroll_offset() const { return max_scroll_offset_; } + gfx::Vector2d MaxScrollOffset() const; - void SetScrollable(bool scrollable); - bool scrollable() const { return scrollable_; } + void SetScrollClipLayer(Layer* clip_layer); + bool scrollable() const { return !!scroll_clip_layer_; } void SetUserScrollable(bool horizontal, bool vertical); bool user_scrollable_horizontal() const { @@ -565,7 +564,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, gfx::Size bounds_; gfx::Vector2d scroll_offset_; - gfx::Vector2d max_scroll_offset_; + // This variable indicates which ancestor layer (if any) whose size, + // transformed relative to this layer, defines the maximum scroll offset for + // this layer. + Layer* scroll_clip_layer_; bool scrollable_ : 1; bool should_scroll_on_main_thread_ : 1; bool have_wheel_event_handlers_ : 1; diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index beb282d..64b7b39 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -27,6 +27,7 @@ #include "cc/trees/layer_tree_settings.h" #include "cc/trees/proxy.h" #include "ui/gfx/box_f.h" +#include "ui/gfx/geometry/vector2d_conversions.h" #include "ui/gfx/point_conversions.h" #include "ui/gfx/quad_f.h" #include "ui/gfx/rect_conversions.h" @@ -43,7 +44,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) anchor_point_(0.5f, 0.5f), anchor_point_z_(0.f), scroll_offset_delegate_(NULL), - scrollable_(false), + scroll_clip_layer_(NULL), should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), user_scrollable_horizontal_(true), @@ -67,9 +68,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) draw_depth_(0.f), needs_push_properties_(false), num_dependents_need_push_properties_(0), - current_draw_mode_(DRAW_MODE_NONE), - horizontal_scrollbar_layer_(NULL), - vertical_scrollbar_layer_(NULL) { + current_draw_mode_(DRAW_MODE_NONE) { DCHECK_GT(layer_id_, 0); DCHECK(layer_tree_impl_); layer_tree_impl_->RegisterLayer(this); @@ -381,7 +380,7 @@ void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { DCHECK(scrollable()); gfx::Vector2dF min_delta = -scroll_offset_; - gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; + gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_; // Clamp new_delta so that position + delta stays within scroll bounds. gfx::Vector2dF new_delta = (ScrollDelta() + scroll); new_delta.SetToMax(min_delta); @@ -389,9 +388,14 @@ gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) { gfx::Vector2dF unscrolled = ScrollDelta() + scroll - new_delta; SetScrollDelta(new_delta); + return unscrolled; } +void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { + scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); +} + void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() { // Pending tree never has sent scroll deltas DCHECK(layer_tree_impl()->IsActiveTree()); @@ -481,7 +485,8 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( return InputHandler::ScrollIgnored; } - if (max_scroll_offset_.x() <= 0 && max_scroll_offset_.y() <= 0) { + gfx::Vector2d max_scroll_offset = MaxScrollOffset(); + if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored. Technically scrollable," " but has no affordance in either direction."); @@ -552,15 +557,14 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetSublayerTransform(sublayer_transform_); layer->SetTransform(transform_); - layer->SetScrollable(scrollable_); + layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() + : Layer::INVALID_ID); layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); layer->set_user_scrollable_vertical(user_scrollable_vertical_); layer->SetScrollOffsetAndDelta( scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); layer->SetSentScrollDelta(gfx::Vector2d()); - layer->SetMaxScrollOffset(max_scroll_offset_); - LayerImpl* scroll_parent = NULL; if (scroll_parent_) scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id()); @@ -634,8 +638,8 @@ base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { result->SetDouble("Opacity", opacity()); result->SetBoolean("ContentsOpaque", contents_opaque_); - if (scrollable_) - result->SetBoolean("Scrollable", scrollable_); + if (scrollable()) + result->SetBoolean("Scrollable", true); if (have_wheel_event_handlers_) result->SetBoolean("WheelHandler", have_wheel_event_handlers_); @@ -757,6 +761,7 @@ void LayerImpl::SetBounds(gfx::Size bounds) { bounds_ = bounds; + ScrollbarParametersDidChange(); if (masks_to_bounds()) NoteLayerPropertyChangedForSubtree(); else @@ -1030,44 +1035,6 @@ void LayerImpl::CalculateContentsScale( *content_bounds = this->content_bounds(); } -void LayerImpl::UpdateScrollbarPositions() { - gfx::Vector2dF current_offset = scroll_offset_ + ScrollDelta(); - - gfx::RectF viewport(PointAtOffsetFromOrigin(current_offset), bounds_); - gfx::SizeF scrollable_size(max_scroll_offset_.x() + bounds_.width(), - max_scroll_offset_.y() + bounds_.height()); - if (horizontal_scrollbar_layer_) { - horizontal_scrollbar_layer_->SetCurrentPos(current_offset.x()); - horizontal_scrollbar_layer_->SetMaximum(max_scroll_offset_.x()); - horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio( - viewport.width() / scrollable_size.width()); - } - if (vertical_scrollbar_layer_) { - vertical_scrollbar_layer_->SetCurrentPos(current_offset.y()); - vertical_scrollbar_layer_->SetMaximum(max_scroll_offset_.y()); - vertical_scrollbar_layer_->SetVisibleToTotalLengthRatio( - viewport.height() / scrollable_size.height()); - } - - if (current_offset == last_scroll_offset_) - return; - last_scroll_offset_ = current_offset; - - if (scrollbar_animation_controller_) { - bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( - layer_tree_impl_->CurrentPhysicalTimeTicks()); - if (should_animate) - layer_tree_impl_->StartScrollbarAnimation(); - } - - // Get the current_offset_.y() value for a sanity-check on scrolling - // benchmark metrics. Specifically, we want to make sure - // BasicMouseWheelSmoothScrollGesture has proper scroll curves. - if (layer_tree_impl()->IsActiveTree()) { - TRACE_COUNTER_ID1("gpu", "scroll_offset_y", this->id(), current_offset.y()); - } -} - void LayerImpl::SetScrollOffsetDelegate( LayerScrollOffsetDelegate* scroll_offset_delegate) { // Having both a scroll parent and a scroll offset delegate is unsupported. @@ -1078,10 +1045,8 @@ void LayerImpl::SetScrollOffsetDelegate( } gfx::Vector2dF total_offset = TotalScrollOffset(); scroll_offset_delegate_ = scroll_offset_delegate; - if (scroll_offset_delegate_) { - scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); + if (scroll_offset_delegate_) scroll_offset_delegate_->SetTotalScrollOffset(total_offset); - } } bool LayerImpl::IsExternalFlingActive() const { @@ -1097,6 +1062,8 @@ void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d 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; @@ -1131,7 +1098,7 @@ void LayerImpl::SetScrollOffsetAndDelta(gfx::Vector2d scroll_offset, if (changed) { NoteLayerPropertyChangedForSubtree(); - UpdateScrollbarPositions(); + ScrollbarParametersDidChange(); } } @@ -1167,17 +1134,151 @@ void LayerImpl::DidBeginTracing() {} void LayerImpl::ReleaseResources() {} -void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { - if (max_scroll_offset_ == max_scroll_offset) +gfx::Vector2d LayerImpl::MaxScrollOffset() const { + if (!scroll_clip_layer_ || bounds().IsEmpty()) + return gfx::Vector2d(); + + LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer(); + DCHECK(this != page_scale_layer); + DCHECK(scroll_clip_layer_); + DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() || + IsContainerForFixedPositionLayers()); + + gfx::Size scaled_scroll_bounds(bounds()); + + 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()->total_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; + } + // 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()->total_page_scale_factor(); + + scaled_scroll_bounds.SetSize( + scale_factor * scaled_scroll_bounds.width(), + scale_factor * scaled_scroll_bounds.height()); + + gfx::RectF clip_rect(gfx::PointF(), scroll_clip_layer_->bounds()); + if (this == layer_tree_impl()->InnerViewportScrollLayer()) + clip_rect = + gfx::RectF(gfx::PointF(), layer_tree_impl()->ScrollableViewportSize()); + gfx::Vector2dF max_offset( + scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), + scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); + // We need the final scroll offset to be in CSS coords. + max_offset.Scale(1 / scale_factor); + max_offset.SetToMax(gfx::Vector2dF()); + return gfx::ToFlooredVector2d(max_offset); +} + +gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() { + gfx::Vector2dF max_offset = MaxScrollOffset(); + gfx::Vector2dF old_offset = TotalScrollOffset(); + gfx::Vector2dF clamped_offset = old_offset; + + clamped_offset.SetToMin(max_offset); + clamped_offset.SetToMax(gfx::Vector2d()); + gfx::Vector2dF delta = clamped_offset - old_offset; + if (!delta.IsZero()) + ScrollBy(delta); + + return delta; +} + +void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, + LayerImpl* scrollbar_clip_layer) const { + DCHECK(scrollbar_layer); + LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer(); + + DCHECK(this != page_scale_layer); + DCHECK(scrollbar_clip_layer); + DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() + || IsContainerForFixedPositionLayers()); + gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds()); + + // See comment in MaxScrollOffset() regarding the use of the content layer + // bounds here. + gfx::RectF scroll_rect(gfx::PointF(), bounds()); + + if (scroll_rect.size().IsEmpty()) return; - max_scroll_offset_ = max_scroll_offset; - if (scroll_offset_delegate_) - scroll_offset_delegate_->SetMaxScrollOffset(max_scroll_offset_); + // TODO(wjmaclean) This computation is nearly identical to the one in + // MaxScrollOffset. Find some way to combine these. + gfx::Vector2dF 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(); + if (current_layer == page_scale_layer) { + DCHECK(layer_transform.IsIdentity()); + float scale_factor = layer_tree_impl()->total_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::Vector2dF new_offset = + 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()->total_page_scale_factor()); + + scrollbar_layer->SetVerticalAdjust(layer_tree_impl()->VerticalAdjust(this)); + if (scrollbar_layer->orientation() == HORIZONTAL) { + float visible_ratio = clip_rect.width() / scroll_rect.width(); + scrollbar_layer->SetCurrentPos(current_offset.x()); + scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); + scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); + } else { + float visible_ratio = clip_rect.height() / scroll_rect.height(); + scrollbar_layer->SetCurrentPos(current_offset.y()); + scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height()); + scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); + } layer_tree_impl()->set_needs_update_draw_properties(); - UpdateScrollbarPositions(); - SetNeedsPushProperties(); + // TODO(wjmaclean) Should the rest of this function be deleted? + // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars should + // activate for every scroll on the main frame, not just the scrolls that move + // the pinch virtual viewport (i.e. trigger from either inner or outer + // viewport). + if (scrollbar_animation_controller_) { + bool should_animate = scrollbar_animation_controller_->DidScrollUpdate( + layer_tree_impl_->CurrentPhysicalTimeTicks()); + if (should_animate) + layer_tree_impl_->StartScrollbarAnimation(); + } } void LayerImpl::DidBecomeActive() { @@ -1186,8 +1287,7 @@ void LayerImpl::DidBecomeActive() { return; } - bool need_scrollbar_animation_controller = horizontal_scrollbar_layer_ || - vertical_scrollbar_layer_; + bool need_scrollbar_animation_controller = scrollable() && scrollbars_; if (!need_scrollbar_animation_controller) { scrollbar_animation_controller_.reset(); return; @@ -1221,18 +1321,51 @@ void LayerImpl::DidBecomeActive() { } } -void LayerImpl::SetHorizontalScrollbarLayer( - ScrollbarLayerImplBase* scrollbar_layer) { - horizontal_scrollbar_layer_ = scrollbar_layer; - if (horizontal_scrollbar_layer_) - horizontal_scrollbar_layer_->set_scroll_layer_id(id()); +void LayerImpl::ClearScrollbars() { + if (!scrollbars_) + return; + + scrollbars_.reset(NULL); +} + +void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) { + DCHECK(layer); + DCHECK(!scrollbars_ || scrollbars_->find(layer) == scrollbars_->end()); + if (!scrollbars_) + scrollbars_.reset(new ScrollbarSet()); + + scrollbars_->insert(layer); +} + +void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) { + DCHECK(scrollbars_); + DCHECK(layer); + DCHECK(scrollbars_->find(layer) != scrollbars_->end()); + + scrollbars_->erase(layer); + if (scrollbars_->empty()) + scrollbars_.reset(); +} + +bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const { + if (!scrollbars_) + return false; + + for (ScrollbarSet::iterator it = scrollbars_->begin(); + it != scrollbars_->end(); ++it) + if ((*it)->orientation() == orientation) + return true; + + return false; } -void LayerImpl::SetVerticalScrollbarLayer( - ScrollbarLayerImplBase* scrollbar_layer) { - vertical_scrollbar_layer_ = scrollbar_layer; - if (vertical_scrollbar_layer_) - vertical_scrollbar_layer_->set_scroll_layer_id(id()); +void LayerImpl::ScrollbarParametersDidChange() { + if (!scrollbars_) + return; + + for (ScrollbarSet::iterator it = scrollbars_->begin(); + it != scrollbars_->end(); ++it) + (*it)->ScrollbarParametersDidChange(); } void LayerImpl::SetNeedsPushProperties() { diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 66fa84b..ec2977b 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -367,8 +367,10 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, const gfx::Vector2dF& scroll_delta); gfx::Vector2d scroll_offset() const { return scroll_offset_; } - void SetMaxScrollOffset(gfx::Vector2d max_scroll_offset); - gfx::Vector2d max_scroll_offset() const { return max_scroll_offset_; } + gfx::Vector2d MaxScrollOffset() const; + gfx::Vector2dF ClampScrollToMaxScrollOffset(); + void SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, + LayerImpl* scrollbar_clip_layer) const; void SetScrollDelta(const gfx::Vector2dF& scroll_delta); gfx::Vector2dF ScrollDelta() const; @@ -382,8 +384,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, // initial scroll gfx::Vector2dF ScrollBy(const gfx::Vector2dF& scroll); - void SetScrollable(bool scrollable) { scrollable_ = scrollable; } - bool scrollable() const { return scrollable_; } + void SetScrollClipLayer(int scroll_clip_layer_id); + bool scrollable() const { return !!scroll_clip_layer_; } void set_user_scrollable_horizontal(bool scrollable) { user_scrollable_horizontal_ = scrollable; @@ -477,14 +479,15 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, return scrollbar_animation_controller_.get(); } - void SetHorizontalScrollbarLayer(ScrollbarLayerImplBase* scrollbar_layer); - ScrollbarLayerImplBase* horizontal_scrollbar_layer() { - return horizontal_scrollbar_layer_; - } - - void SetVerticalScrollbarLayer(ScrollbarLayerImplBase* scrollbar_layer); - ScrollbarLayerImplBase* vertical_scrollbar_layer() { - return vertical_scrollbar_layer_; + typedef std::set<ScrollbarLayerImplBase*> ScrollbarSet; + ScrollbarSet* scrollbars() { return scrollbars_.get(); } + void ClearScrollbars(); + void AddScrollbar(ScrollbarLayerImplBase* layer); + void RemoveScrollbar(ScrollbarLayerImplBase* layer); + bool HasScrollbar(ScrollbarOrientation orientation) const; + void ScrollbarParametersDidChange(); + int clip_height() { + return scroll_clip_layer_ ? scroll_clip_layer_->bounds().height() : 0; } gfx::Rect LayerRectToContentRect(const gfx::RectF& layer_rect) const; @@ -542,8 +545,6 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, private: void NoteLayerPropertyChangedForDescendantsInternal(); - void UpdateScrollbarPositions(); - virtual const char* LayerTypeAsString() const; // Properties internal to LayerImpl @@ -576,6 +577,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, gfx::Size bounds_; gfx::Vector2d scroll_offset_; LayerScrollOffsetDelegate* scroll_offset_delegate_; + LayerImpl* scroll_clip_layer_; bool scrollable_ : 1; bool should_scroll_on_main_thread_ : 1; bool have_wheel_event_handlers_ : 1; @@ -618,7 +620,6 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, gfx::Vector2dF scroll_delta_; gfx::Vector2d sent_scroll_delta_; - gfx::Vector2d max_scroll_offset_; gfx::Vector2dF last_scroll_offset_; // The global depth value of the center of the layer. This value is used @@ -654,10 +655,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, // Manages scrollbars for this layer scoped_ptr<ScrollbarAnimationController> scrollbar_animation_controller_; - // Weak pointers to this layer's scrollbars, if it has them. Updated during - // tree synchronization. - ScrollbarLayerImplBase* horizontal_scrollbar_layer_; - ScrollbarLayerImplBase* vertical_scrollbar_layer_; + scoped_ptr<ScrollbarSet> scrollbars_; ScopedPtrVector<CopyOutputRequest> copy_requests_; diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index f38809f..1dc36dd3 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc @@ -94,28 +94,32 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { FakeImplProxy proxy; FakeLayerTreeHostImpl host_impl(&proxy); EXPECT_TRUE(host_impl.InitializeRenderer(CreateFakeOutputSurface())); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); - - scoped_ptr<LayerImpl> scroll_parent = + scoped_ptr<LayerImpl> root_clip = + LayerImpl::Create(host_impl.active_tree(), 1); + scoped_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl.active_tree(), 2); - LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 3).get(); + LayerImpl* root = root_ptr.get(); + root_clip->AddChild(root_ptr.Pass()); + scoped_ptr<LayerImpl> scroll_parent = + LayerImpl::Create(host_impl.active_tree(), 3); + LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 4).get(); std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>(); scroll_children->insert(scroll_child); - scroll_children->insert(root.get()); + scroll_children->insert(root); scoped_ptr<LayerImpl> clip_parent = - LayerImpl::Create(host_impl.active_tree(), 4); - LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 5).get(); + LayerImpl::Create(host_impl.active_tree(), 5); + LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 6).get(); std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>(); clip_children->insert(clip_child); - clip_children->insert(root.get()); + clip_children->insert(root); - root->AddChild(LayerImpl::Create(host_impl.active_tree(), 6)); + root->AddChild(LayerImpl::Create(host_impl.active_tree(), 7)); LayerImpl* child = root->children()[0]; - child->AddChild(LayerImpl::Create(host_impl.active_tree(), 7)); + child->AddChild(LayerImpl::Create(host_impl.active_tree(), 8)); LayerImpl* grand_child = child->children()[0]; - root->SetScrollable(true); + root->SetScrollClipLayer(root_clip->id()); // Adding children is an internal operation and should not mark layers as // changed. @@ -142,8 +146,7 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { // they are used. EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( root->SetUpdateRect(arbitrary_rect_f)); - EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetMaxScrollOffset(arbitrary_vector2d)); + EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size)); // Changing these properties affects the entire subtree of layers. EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetAnchorPoint(arbitrary_point_f)); @@ -151,11 +154,11 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(FilterOperations())); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( - root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 8))); + root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 9))); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( - root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 9))); + root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 10))); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPosition(arbitrary_point_f)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPreserves3d(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( @@ -257,15 +260,18 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { FakeImplProxy proxy; FakeLayerTreeHostImpl host_impl(&proxy); EXPECT_TRUE(host_impl.InitializeRenderer(CreateFakeOutputSurface())); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); - root->SetScrollable(true); + scoped_ptr<LayerImpl> root_clip = + LayerImpl::Create(host_impl.active_tree(), 1); + root_clip->AddChild(LayerImpl::Create(host_impl.active_tree(), 2)); + LayerImpl* root = root_clip->children()[0]; + root->SetScrollClipLayer(root_clip->id()); gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f); float arbitrary_number = 0.352f; gfx::Size arbitrary_size = gfx::Size(111, 222); gfx::Point arbitrary_point = gfx::Point(333, 444); gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222); - gfx::Vector2d large_vector2d = gfx::Vector2d(1000, 1000); + gfx::Size large_size = gfx::Size(1000, 1000); gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size); gfx::RectF arbitrary_rect_f = gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f)); @@ -283,9 +289,9 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetFilters(arbitrary_filters)); // Related scrolling functions. - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetMaxScrollOffset(large_vector2d)); + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->SetBounds(large_size)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( - root->SetMaxScrollOffset(large_vector2d)); + root->SetBounds(large_size)); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->ScrollBy(arbitrary_vector2d)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->ScrollBy(gfx::Vector2d())); root->SetScrollDelta(gfx::Vector2d(0, 0)); @@ -391,10 +397,20 @@ class LayerImplScrollTest : public testing::Test { LayerImplScrollTest() : host_impl_(&proxy_), root_id_(7) { host_impl_.active_tree() ->SetRootLayer(LayerImpl::Create(host_impl_.active_tree(), root_id_)); - host_impl_.active_tree()->root_layer()->SetScrollable(true); + host_impl_.active_tree()->root_layer()->AddChild( + LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1)); + layer()->SetScrollClipLayer(root_id_); + // Set the max scroll offset by noting that the root layer has bounds (1,1), + // thus whatever bounds are set for the layer will be the max scroll + // offset plus 1 in each direction. + host_impl_.active_tree()->root_layer()->SetBounds(gfx::Size(1, 1)); + gfx::Vector2d max_scroll_offset(51, 81); + layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y())); } - LayerImpl* layer() { return host_impl_.active_tree()->root_layer(); } + LayerImpl* layer() { + return host_impl_.active_tree()->root_layer()->children()[0]; + } private: FakeImplProxy proxy_; @@ -405,8 +421,6 @@ class LayerImplScrollTest : public testing::Test { TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) { // Test that LayerImpl::ScrollBy only affects ScrollDelta and total scroll // offset is bounded by the range [0, max scroll offset]. - gfx::Vector2d max_scroll_offset(50, 80); - layer()->SetMaxScrollOffset(max_scroll_offset); EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->TotalScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset()); @@ -426,9 +440,7 @@ TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) { } TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset()); @@ -472,9 +484,7 @@ class ScrollDelegateIgnore : public LayerScrollOffsetDelegate { }; TEST_F(LayerImplScrollTest, ScrollByWithIgnoringDelegate) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset()); @@ -525,9 +535,7 @@ class ScrollDelegateAccept : public LayerScrollOffsetDelegate { }; TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset()); @@ -559,12 +567,10 @@ TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) { } TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); gfx::Vector2dF scroll_delta(20.5f, 8.5f); gfx::Vector2d sent_scroll_delta(12, -3); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); layer()->ScrollBy(scroll_delta); layer()->SetSentScrollDelta(sent_scroll_delta); @@ -583,12 +589,10 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) { } TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); gfx::Vector2d sent_scroll_delta(12, -3); gfx::Vector2dF fixed_offset(32, 12); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); ScrollDelegateIgnore delegate; delegate.set_fixed_offset(fixed_offset); @@ -607,12 +611,10 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) { } TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); gfx::Vector2d sent_scroll_delta(12, -3); gfx::Vector2dF scroll_delta(20.5f, 8.5f); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); ScrollDelegateAccept delegate; layer()->SetScrollOffsetDelegate(&delegate); @@ -633,12 +635,10 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) { // The user-scrollability breaks for zoomed-in pages. So disable this. // http://crbug.com/322223 TEST_F(LayerImplScrollTest, DISABLED_ScrollUserUnscrollableLayer) { - gfx::Vector2d max_scroll_offset(50, 80); gfx::Vector2d scroll_offset(10, 5); gfx::Vector2dF scroll_delta(20.5f, 8.5f); layer()->set_user_scrollable_vertical(false); - layer()->SetMaxScrollOffset(max_scroll_offset); layer()->SetScrollOffset(scroll_offset); gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta); diff --git a/cc/layers/layer_perftest.cc b/cc/layers/layer_perftest.cc index 32e99fe..865453d 100644 --- a/cc/layers/layer_perftest.cc +++ b/cc/layers/layer_perftest.cc @@ -80,7 +80,7 @@ TEST_F(LayerPerfTest, PushPropertiesTo) { test_layer->SetDoubleSided(double_sided); test_layer->SetHideLayerAndSubtree(hide_layer_and_subtree); test_layer->SetMasksToBounds(masks_to_bounds); - test_layer->SetScrollable(scrollable); + test_layer->SetScrollClipLayer(scrollable ? test_layer : NULL); test_layer->PushPropertiesTo(impl_layer.get()); anchor_point_z += 0.01f; diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc index 57e4c1d..3557f7f 100644 --- a/cc/layers/layer_position_constraint_unittest.cc +++ b/cc/layers/layer_position_constraint_unittest.cc @@ -39,13 +39,14 @@ void ExecuteCalculateDrawProperties(LayerImpl* root_layer, bool can_use_lcd_text) { gfx::Transform identity_matrix; std::vector<LayerImpl*> dummy_render_surface_layer_list; + LayerImpl* scroll_layer = root_layer->children()[0]; gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - // We are probably not testing what is intended if the root_layer bounds are + // We are probably not testing what is intended if the scroll_layer bounds are // empty. - DCHECK(!root_layer->bounds().IsEmpty()); + DCHECK(!scroll_layer->bounds().IsEmpty()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root_layer, device_viewport_size, &dummy_render_surface_layer_list); inputs.device_scale_factor = device_scale_factor; @@ -66,6 +67,7 @@ class LayerPositionConstraintTest : public testing::Test { LayerPositionConstraintTest() : host_impl_(&proxy_) { root_ = CreateTreeForTest(); + scroll_ = root_->children()[0]; fixed_to_top_left_.set_is_fixed_position(true); fixed_to_bottom_right_.set_is_fixed_position(true); fixed_to_bottom_right_.set_is_fixed_to_right_edge(true); @@ -74,6 +76,8 @@ class LayerPositionConstraintTest : public testing::Test { scoped_ptr<LayerImpl> CreateTreeForTest() { scoped_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_.active_tree(), 42); + scoped_ptr<LayerImpl> scroll_layer = LayerImpl::Create(host_impl_.active_tree(), 1); scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl_.active_tree(), 2); @@ -85,8 +89,9 @@ class LayerPositionConstraintTest : public testing::Test { gfx::Transform IdentityMatrix; gfx::PointF anchor; gfx::PointF position; - gfx::Size bounds(100, 100); - SetLayerPropertiesForTesting(root.get(), + gfx::Size bounds(200, 200); + gfx::Size clip_bounds(100, 100); + SetLayerPropertiesForTesting(scroll_layer.get(), IdentityMatrix, IdentityMatrix, anchor, @@ -115,16 +120,15 @@ class LayerPositionConstraintTest : public testing::Test { bounds, false); - root->SetMaxScrollOffset(gfx::Vector2d(100, 100)); - root->SetScrollable(true); - child->SetMaxScrollOffset(gfx::Vector2d(100, 100)); - child->SetScrollable(true); - grand_child->SetMaxScrollOffset(gfx::Vector2d(100, 100)); - grand_child->SetScrollable(true); + root->SetBounds(clip_bounds); + scroll_layer->SetScrollClipLayer(root->id()); + child->SetScrollClipLayer(root->id()); + grand_child->SetScrollClipLayer(root->id()); grand_child->AddChild(great_grand_child.Pass()); child->AddChild(grand_child.Pass()); - root->AddChild(child.Pass()); + scroll_layer->AddChild(child.Pass()); + root->AddChild(scroll_layer.Pass()); return root.Pass(); } @@ -133,6 +137,7 @@ class LayerPositionConstraintTest : public testing::Test { FakeImplProxy proxy_; FakeLayerTreeHostImpl host_impl_; scoped_ptr<LayerImpl> root_; + LayerImpl* scroll_; LayerPositionConstraint fixed_to_top_left_; LayerPositionConstraint fixed_to_bottom_right_; @@ -142,7 +147,7 @@ TEST_F(LayerPositionConstraintTest, ScrollCompensationForFixedPositionLayerWithDirectContainer) { // This test checks for correct scroll compensation when the fixed-position // container is the direct parent of the fixed-position layer. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; child->SetIsContainerForFixedPositionLayers(true); @@ -210,7 +215,7 @@ TEST_F(LayerPositionConstraintTest, // Transforms are in general non-commutative; using something like a // non-uniform scale helps to verify that translations and non-uniform scales // are applied in the correct order. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; // This scale will cause child and grand_child to be effectively 200 x 800 @@ -282,7 +287,7 @@ TEST_F(LayerPositionConstraintTest, ScrollCompensationForFixedPositionLayerWithDistantContainer) { // This test checks for correct scroll compensation when the fixed-position // container is NOT the direct parent of the fixed-position layer. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; LayerImpl* great_grand_child = grand_child->children()[0]; @@ -362,7 +367,7 @@ TEST_F(LayerPositionConstraintTest, // container is NOT the direct parent of the fixed-position layer, and the // hierarchy has various transforms that have to be processed in the correct // order. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; LayerImpl* great_grand_child = grand_child->children()[0]; @@ -474,7 +479,7 @@ TEST_F(LayerPositionConstraintTest, // container is NOT the direct parent of the fixed-position layer, and the // hierarchy has various transforms that have to be processed in the correct // order. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; LayerImpl* great_grand_child = grand_child->children()[0]; @@ -585,7 +590,7 @@ TEST_F(LayerPositionConstraintTest, // container contributes to a different render surface than the fixed-position // layer. In this case, the surface draw transforms also have to be accounted // for when checking the scroll delta. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; LayerImpl* great_grand_child = grand_child->children()[0]; @@ -709,7 +714,7 @@ TEST_F(LayerPositionConstraintTest, // layer, with additional render surfaces in-between. This checks that the // conversion to ancestor surfaces is accumulated properly in the final matrix // transform. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; LayerImpl* great_grand_child = grand_child->children()[0]; @@ -896,7 +901,7 @@ TEST_F(LayerPositionConstraintTest, // should be treated like a layer that contributes to a render target, and // that render target is completely irrelevant; it should not affect the // scroll compensation. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; child->SetIsContainerForFixedPositionLayers(true); @@ -974,7 +979,7 @@ TEST_F(LayerPositionConstraintTest, // This test checks the scenario where a fixed-position layer also happens to // be a container itself for a descendant fixed position layer. In particular, // the layer should not accidentally be fixed to itself. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; child->SetIsContainerForFixedPositionLayers(true); @@ -1034,67 +1039,6 @@ TEST_F(LayerPositionConstraintTest, } TEST_F(LayerPositionConstraintTest, - ScrollCompensationForFixedPositionLayerThatHasNoContainer) { - // This test checks scroll compensation when a fixed-position layer does not - // find any ancestor that is a "containerForFixedPositionLayers". In this - // situation, the layer should be fixed to the root layer. - LayerImpl* child = root_->children()[0]; - LayerImpl* grand_child = child->children()[0]; - - gfx::Transform rotation_by_z; - rotation_by_z.RotateAboutZAxis(90.0); - - root_->SetTransform(rotation_by_z); - grand_child->SetPositionConstraint(fixed_to_top_left_); - - // Case 1: root scroll delta of 0, 0 - root_->SetScrollDelta(gfx::Vector2d(0, 0)); - ExecuteCalculateDrawProperties(root_.get()); - - gfx::Transform identity_matrix; - - EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, child->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, - grand_child->draw_transform()); - - // Case 2: root scroll delta of 10, 10 - root_->SetScrollDelta(gfx::Vector2d(10, 20)); - ExecuteCalculateDrawProperties(root_.get()); - - gfx::Transform expected_child_transform; - expected_child_transform.Translate(-10.0, -20.0); - expected_child_transform.PreconcatTransform(rotation_by_z); - - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, - child->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, - grand_child->draw_transform()); - - // Case 3: fixed-container size delta of 20, 20 - root_->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); - ExecuteCalculateDrawProperties(root_.get()); - - // Top-left fixed-position layer should not be affected by container size. - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, - child->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, - grand_child->draw_transform()); - - // Case 4: Bottom-right fixed-position layer. - grand_child->SetPositionConstraint(fixed_to_bottom_right_); - ExecuteCalculateDrawProperties(root_.get()); - - gfx::Transform expected_grand_child_transform; - expected_grand_child_transform.Translate(-20.0, 20.0); - expected_grand_child_transform.PreconcatTransform(rotation_by_z); - - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, - child->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, - grand_child->draw_transform()); -} - -TEST_F(LayerPositionConstraintTest, ScrollCompensationForFixedWithinFixedWithSameContainer) { // This test checks scroll compensation for a fixed-position layer that is // inside of another fixed-position layer and both share the same container. @@ -1102,7 +1046,7 @@ TEST_F(LayerPositionConstraintTest, // the scroll compensation, and the child fixed-position layer does not // need to compensate further. - LayerImpl* child = root_->children()[0]; + LayerImpl* child = scroll_->children()[0]; LayerImpl* grand_child = child->children()[0]; LayerImpl* great_grand_child = grand_child->children()[0]; @@ -1161,7 +1105,7 @@ TEST_F(LayerPositionConstraintTest, // position containers. In this situation, the child fixed-position element // would still have to compensate with respect to its container. - LayerImpl* container1 = root_->children()[0]; + LayerImpl* container1 = scroll_->children()[0]; LayerImpl* fixed_to_container1 = container1->children()[0]; LayerImpl* container2 = fixed_to_container1->children()[0]; diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index 55f5616..aa7e205a 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc @@ -551,7 +551,8 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetSublayerTransform( gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(true)); + // We can use any layer pointer here since we aren't syncing for real. + EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollClipLayer(test_layer.get())); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset( gfx::Vector2d(10, 10))); diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc index 4466d58..2a68650 100644 --- a/cc/layers/painted_scrollbar_layer.cc +++ b/cc/layers/painted_scrollbar_layer.cc @@ -28,16 +28,17 @@ scoped_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create( scoped_ptr<Scrollbar> scrollbar, - int scroll_layer_id) { + Layer* scroll_layer) { return make_scoped_refptr( - new PaintedScrollbarLayer(scrollbar.Pass(), scroll_layer_id)); + new PaintedScrollbarLayer(scrollbar.Pass(), scroll_layer)); } PaintedScrollbarLayer::PaintedScrollbarLayer( scoped_ptr<Scrollbar> scrollbar, - int scroll_layer_id) + Layer* scroll_layer) : scrollbar_(scrollbar.Pass()), - scroll_layer_id_(scroll_layer_id), + scroll_layer_(scroll_layer), + clip_layer_(NULL), thumb_thickness_(scrollbar_->ThumbThickness()), thumb_length_(scrollbar_->ThumbLength()), is_overlay_(scrollbar_->IsOverlay()), @@ -49,14 +50,22 @@ PaintedScrollbarLayer::PaintedScrollbarLayer( PaintedScrollbarLayer::~PaintedScrollbarLayer() {} int PaintedScrollbarLayer::ScrollLayerId() const { - return scroll_layer_id_; + return scroll_layer_->id(); } -void PaintedScrollbarLayer::SetScrollLayerId(int id) { - if (id == scroll_layer_id_) +void PaintedScrollbarLayer::SetScrollLayer(scoped_refptr<Layer> layer) { + if (layer == scroll_layer_) return; - scroll_layer_id_ = id; + scroll_layer_ = layer; + SetNeedsFullTreeSync(); +} + +void PaintedScrollbarLayer::SetClipLayer(scoped_refptr<Layer> layer) { + if (layer == clip_layer_) + return; + + clip_layer_ = layer; SetNeedsFullTreeSync(); } @@ -109,6 +118,8 @@ void PaintedScrollbarLayer::CalculateContentsScale( void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { ContentsScalingLayer::PushPropertiesTo(layer); + PushScrollClipPropertiesTo(layer); + PaintedScrollbarLayerImpl* scrollbar_layer = static_cast<PaintedScrollbarLayerImpl*>(layer); @@ -136,6 +147,16 @@ ScrollbarLayerInterface* PaintedScrollbarLayer::ToScrollbarLayer() { return this; } +void PaintedScrollbarLayer::PushScrollClipPropertiesTo(LayerImpl* layer) { + PaintedScrollbarLayerImpl* scrollbar_layer = + static_cast<PaintedScrollbarLayerImpl*>(layer); + + scrollbar_layer->SetScrollLayerById(scroll_layer_ ? scroll_layer_->id() + : Layer::INVALID_ID); + scrollbar_layer->SetClipLayerById(clip_layer_ ? clip_layer_->id() + : Layer::INVALID_ID); +} + void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { // When the LTH is set to null or has changed, then this layer should remove // all of its associated resources. diff --git a/cc/layers/painted_scrollbar_layer.h b/cc/layers/painted_scrollbar_layer.h index c24c0aa..0b84451 100644 --- a/cc/layers/painted_scrollbar_layer.h +++ b/cc/layers/painted_scrollbar_layer.h @@ -24,14 +24,15 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, static scoped_refptr<PaintedScrollbarLayer> Create( scoped_ptr<Scrollbar> scrollbar, - int scroll_layer_id); + Layer* scroll_layer); virtual bool OpacityCanAnimateOnImplThread() const OVERRIDE; virtual ScrollbarLayerInterface* ToScrollbarLayer() OVERRIDE; // ScrollbarLayerInterface virtual int ScrollLayerId() const OVERRIDE; - virtual void SetScrollLayerId(int id) OVERRIDE; + virtual void SetScrollLayer(scoped_refptr<Layer> layer) OVERRIDE; + virtual void SetClipLayer(scoped_refptr<Layer> layer) OVERRIDE; virtual ScrollbarOrientation orientation() const OVERRIDE; @@ -40,6 +41,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, const OcclusionTracker* occlusion) OVERRIDE; virtual void SetLayerTreeHost(LayerTreeHost* host) OVERRIDE; virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE; + virtual void PushScrollClipPropertiesTo(LayerImpl* layer) OVERRIDE; virtual void CalculateContentsScale(float ideal_contents_scale, float device_scale_factor, float page_scale_factor, @@ -49,7 +51,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, gfx::Size* content_bounds) OVERRIDE; protected: - PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id); + PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, Layer* scroll_layer); virtual ~PaintedScrollbarLayer(); // For unit tests @@ -79,7 +81,8 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, ScrollbarPart part); scoped_ptr<Scrollbar> scrollbar_; - int scroll_layer_id_; + scoped_refptr<Layer> scroll_layer_; + scoped_refptr<Layer> clip_layer_; // Snapshot of properties taken in UpdateThumbAndTrackGeometry and used in // PushPropertiesTo. diff --git a/cc/layers/painted_scrollbar_layer_impl.cc b/cc/layers/painted_scrollbar_layer_impl.cc index d67fbe4..2af722d 100644 --- a/cc/layers/painted_scrollbar_layer_impl.cc +++ b/cc/layers/painted_scrollbar_layer_impl.cc @@ -29,7 +29,7 @@ PaintedScrollbarLayerImpl::PaintedScrollbarLayerImpl( LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation) - : ScrollbarLayerImplBase(tree_impl, id, orientation, false), + : ScrollbarLayerImplBase(tree_impl, id, orientation, false, false), track_ui_resource_id_(0), thumb_ui_resource_id_(0), thumb_thickness_(0), diff --git a/cc/layers/scrollbar_layer_impl_base.cc b/cc/layers/scrollbar_layer_impl_base.cc index 55f46f5..22583a1 100644 --- a/cc/layers/scrollbar_layer_impl_base.cc +++ b/cc/layers/scrollbar_layer_impl_base.cc @@ -5,7 +5,7 @@ #include "cc/layers/scrollbar_layer_impl_base.h" #include <algorithm> -#include "cc/layers/layer.h" +#include "cc/trees/layer_tree_impl.h" #include "ui/gfx/rect_conversions.h" namespace cc { @@ -14,10 +14,12 @@ ScrollbarLayerImplBase::ScrollbarLayerImplBase( LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation, - bool is_left_side_vertical_scrollbar) + bool is_left_side_vertical_scrollbar, + bool is_overlay) : LayerImpl(tree_impl, id), - scroll_layer_id_(Layer::INVALID_ID), - is_overlay_scrollbar_(false), + scroll_layer_(NULL), + clip_layer_(NULL), + is_overlay_scrollbar_(is_overlay), thumb_thickness_scale_factor_(1.f), current_pos_(0.f), maximum_(0), @@ -26,14 +28,50 @@ ScrollbarLayerImplBase::ScrollbarLayerImplBase( vertical_adjust_(0.f), visible_to_total_length_ratio_(1.f) {} +ScrollbarLayerImplBase::~ScrollbarLayerImplBase() { +} + void ScrollbarLayerImplBase::PushPropertiesTo(LayerImpl* layer) { LayerImpl::PushPropertiesTo(layer); + DCHECK(layer->ToScrollbarLayer()); + layer->ToScrollbarLayer()->set_is_overlay_scrollbar(is_overlay_scrollbar_); + PushScrollClipPropertiesTo(layer); +} + +void ScrollbarLayerImplBase::PushScrollClipPropertiesTo(LayerImpl* layer) { + DCHECK(layer->ToScrollbarLayer()); + layer->ToScrollbarLayer()->SetScrollLayerById(ScrollLayerId()); + layer->ToScrollbarLayer()->SetClipLayerById(ClipLayerId()); } ScrollbarLayerImplBase* ScrollbarLayerImplBase::ToScrollbarLayer() { return this; } +void ScrollbarLayerImplBase::SetScrollLayerById(int id) { + LayerImpl* scroll_layer = layer_tree_impl()->LayerById(id); + if (scroll_layer_ == scroll_layer) + return; + + if (scroll_layer_) + scroll_layer_->RemoveScrollbar(this); + scroll_layer_ = scroll_layer; + if (scroll_layer_) + scroll_layer_->AddScrollbar(this); +} + +void ScrollbarLayerImplBase::SetClipLayerById(int id) { + LayerImpl* clip_layer = layer_tree_impl()->LayerById(id); + if (clip_layer_ == clip_layer) + return; + + if (clip_layer_) + clip_layer_->RemoveScrollbar(this); + clip_layer_ = clip_layer; + if (clip_layer_) + clip_layer_->AddScrollbar(this); +} + gfx::Rect ScrollbarLayerImplBase::ScrollbarLayerRectToContentRect( const gfx::RectF& layer_rect) const { // Don't intersect with the bounds as in LayerRectToContentRect() because @@ -177,4 +215,11 @@ gfx::Rect ScrollbarLayerImplBase::ComputeThumbQuadRect() const { return ScrollbarLayerRectToContentRect(thumb_rect); } +void ScrollbarLayerImplBase::ScrollbarParametersDidChange() { + if (!clip_layer_ || !scroll_layer_) + return; + + scroll_layer_->SetScrollbarPosition(this, clip_layer_); +} + } // namespace cc diff --git a/cc/layers/scrollbar_layer_impl_base.h b/cc/layers/scrollbar_layer_impl_base.h index 6bba749..e7a2fc7 100644 --- a/cc/layers/scrollbar_layer_impl_base.h +++ b/cc/layers/scrollbar_layer_impl_base.h @@ -7,6 +7,7 @@ #include "cc/base/cc_export.h" #include "cc/input/scrollbar.h" +#include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" namespace cc { @@ -15,8 +16,16 @@ class LayerTreeImpl; class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { public: - int ScrollLayerId() const { return scroll_layer_id_; } - void set_scroll_layer_id(int id) { scroll_layer_id_ = id; } + int ScrollLayerId() const { + return scroll_layer_ ? scroll_layer_->id() : Layer::INVALID_ID; + } + void ClearScrollLayer() { scroll_layer_ = NULL; } + void SetScrollLayerById(int id); + int ClipLayerId() const { + return clip_layer_ ? clip_layer_->id() : Layer::INVALID_ID; + } + void ClearClipLayer() { clip_layer_ = NULL; } + void SetClipLayerById(int id); float current_pos() const { return current_pos_; } void SetCurrentPos(float current_pos); @@ -37,6 +46,7 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE; virtual ScrollbarLayerImplBase* ToScrollbarLayer() OVERRIDE; + void PushScrollClipPropertiesTo(LayerImpl* layer); void SetVisibleToTotalLengthRatio(float ratio); virtual gfx::Rect ComputeThumbQuadRect() const; @@ -46,12 +56,15 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { } void SetThumbThicknessScaleFactor(float thumb_thickness_scale_factor); + void ScrollbarParametersDidChange(); + protected: ScrollbarLayerImplBase(LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation, - bool is_left_side_vertical_scrollbar); - virtual ~ScrollbarLayerImplBase() {} + bool is_left_side_vertical_scrollbar, + bool is_overlay); + virtual ~ScrollbarLayerImplBase(); gfx::Rect ScrollbarLayerRectToContentRect(const gfx::RectF& layer_rect) const; @@ -69,7 +82,8 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { virtual bool IsThumbResizable() const = 0; private: - int scroll_layer_id_; + LayerImpl* scroll_layer_; + LayerImpl* clip_layer_; bool is_overlay_scrollbar_; float thumb_thickness_scale_factor_; diff --git a/cc/layers/scrollbar_layer_interface.h b/cc/layers/scrollbar_layer_interface.h index bbb0da6..3a66963 100644 --- a/cc/layers/scrollbar_layer_interface.h +++ b/cc/layers/scrollbar_layer_interface.h @@ -10,10 +10,15 @@ namespace cc { +class Layer; +class LayerImpl; + class CC_EXPORT ScrollbarLayerInterface { public: virtual int ScrollLayerId() const = 0; - virtual void SetScrollLayerId(int id) = 0; + virtual void SetScrollLayer(scoped_refptr<Layer> layer) = 0; + virtual void SetClipLayer(scoped_refptr<Layer> layer) = 0; + virtual void PushScrollClipPropertiesTo(LayerImpl* layer) = 0; virtual ScrollbarOrientation orientation() const = 0; diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 4fab625..3de091f 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc @@ -45,9 +45,9 @@ LayerImpl* LayerImplForScrollAreaAndScrollbar( const bool kIsLeftSideVerticalScrollbar = false; child2 = SolidColorScrollbarLayer::Create( scrollbar->Orientation(), thumb_thickness, - kIsLeftSideVerticalScrollbar, child1->id()); + kIsLeftSideVerticalScrollbar, child1.get()); } else { - child2 = PaintedScrollbarLayer::Create(scrollbar.Pass(), child1->id()); + child2 = PaintedScrollbarLayer::Create(scrollbar.Pass(), child1.get()); } layer_tree_root->AddChild(child1); layer_tree_root->InsertChild(child2, reverse_order ? 0 : 1); @@ -66,7 +66,8 @@ TEST(ScrollbarLayerTest, ResolveScrollLayerPointer) { static_cast<PaintedScrollbarLayerImpl*>( layer_impl_tree_root->children()[1]); - EXPECT_EQ(cc_child1->horizontal_scrollbar_layer(), cc_child2); + EXPECT_EQ(cc_child1->scrollbars()->size(), 1UL); + EXPECT_EQ(*(cc_child1->scrollbars()->begin()), cc_child2); } TEST(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) { @@ -80,7 +81,8 @@ TEST(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) { layer_impl_tree_root->children()[0]); LayerImpl* cc_child2 = layer_impl_tree_root->children()[1]; - EXPECT_EQ(cc_child2->horizontal_scrollbar_layer(), cc_child1); + EXPECT_EQ(cc_child2->scrollbars()->size(), 1UL); + EXPECT_EQ(*(cc_child2->scrollbars()->begin()), cc_child1); } TEST(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { @@ -121,19 +123,24 @@ TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) { scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); scoped_refptr<Layer> layer_tree_root = Layer::Create(); + scoped_refptr<Layer> scroll_layer = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<Layer> scrollbar_layer = - PaintedScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); + PaintedScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root.get()); - layer_tree_root->SetScrollable(true); - layer_tree_root->SetScrollOffset(gfx::Vector2d(10, 20)); - layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(30, 50)); - layer_tree_root->SetBounds(gfx::Size(100, 200)); + // Choose bounds to give max_scroll_offset = (30, 50). + layer_tree_root->SetBounds(gfx::Size(70, 150)); + scroll_layer->SetScrollClipLayer(layer_tree_root.get()); + scroll_layer->SetScrollOffset(gfx::Vector2d(10, 20)); + scroll_layer->SetBounds(gfx::Size(100, 200)); content_layer->SetBounds(gfx::Size(100, 200)); host->SetRootLayer(layer_tree_root); - layer_tree_root->AddChild(content_layer); + layer_tree_root->AddChild(scroll_layer); + scroll_layer->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); + scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer); + scrollbar_layer->ToScrollbarLayer()->SetClipLayer(layer_tree_root); layer_tree_root->SavePaintProperties(); content_layer->SavePaintProperties(); @@ -147,10 +154,11 @@ TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) { EXPECT_EQ(10.f, cc_scrollbar_layer->current_pos()); EXPECT_EQ(30, cc_scrollbar_layer->maximum()); - layer_tree_root->SetScrollOffset(gfx::Vector2d(100, 200)); - layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(300, 500)); - layer_tree_root->SetBounds(gfx::Size(1000, 2000)); + layer_tree_root->SetBounds(gfx::Size(700, 1500)); layer_tree_root->SavePaintProperties(); + scroll_layer->SetBounds(gfx::Size(1000, 2000)); + scroll_layer->SetScrollOffset(gfx::Vector2d(100, 200)); + scroll_layer->SavePaintProperties(); content_layer->SetBounds(gfx::Size(1000, 2000)); content_layer->SavePaintProperties(); @@ -163,65 +171,73 @@ TEST(PaintedScrollbarLayerTest, ScrollOffsetSynchronization) { EXPECT_EQ(100.f, cc_scrollbar_layer->current_pos()); EXPECT_EQ(300, cc_scrollbar_layer->maximum()); - layer_impl_tree_root->ScrollBy(gfx::Vector2d(12, 34)); + LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0]; + scroll_layer_impl->ScrollBy(gfx::Vector2d(12, 34)); EXPECT_EQ(112.f, cc_scrollbar_layer->current_pos()); EXPECT_EQ(300, cc_scrollbar_layer->maximum()); } +#define UPDATE_AND_EXTRACT_LAYER_POINTERS() \ + do { \ + scrollbar_layer->UpdateThumbAndTrackGeometry(); \ + root_clip_layer_impl = host->CommitAndCreateLayerImplTree(); \ + root_layer_impl = root_clip_layer_impl->children()[0]; \ + scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( \ + root_layer_impl->children()[1]); \ + scrollbar_layer_impl->ScrollbarParametersDidChange(); \ + } while (false) + TEST(ScrollbarLayerTest, ThumbRect) { scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_refptr<Layer> root_clip_layer = Layer::Create(); scoped_refptr<Layer> root_layer = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer = - FakePaintedScrollbarLayer::Create(false, true, root_layer->id()); + FakePaintedScrollbarLayer::Create(false, true, root_layer.get()); - root_layer->SetScrollable(true); - root_layer->SetMaxScrollOffset(gfx::Vector2d(80, 0)); + root_layer->SetScrollClipLayer(root_clip_layer.get()); + // Give the root-clip a size that will result in MaxScrollOffset = (80, 0). + root_clip_layer->SetBounds(gfx::Size(20, 50)); root_layer->SetBounds(gfx::Size(100, 50)); content_layer->SetBounds(gfx::Size(100, 50)); - host->SetRootLayer(root_layer); + host->SetRootLayer(root_clip_layer); + root_clip_layer->AddChild(root_layer); root_layer->AddChild(content_layer); root_layer->AddChild(scrollbar_layer); root_layer->SetScrollOffset(gfx::Vector2d(0, 0)); scrollbar_layer->SetBounds(gfx::Size(70, 10)); + scrollbar_layer->SetScrollLayer(root_layer.get()); + scrollbar_layer->SetClipLayer(root_clip_layer.get()); scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10)); scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10)); scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); scrollbar_layer->fake_scrollbar()->set_thumb_length(4); scrollbar_layer->UpdateThumbAndTrackGeometry(); + LayerImpl* root_clip_layer_impl = NULL; LayerImpl* root_layer_impl = NULL; PaintedScrollbarLayerImpl* scrollbar_layer_impl = NULL; // Thumb is at the edge of the scrollbar (should be inset to // the start of the track within the scrollbar layer's // position). - scrollbar_layer->UpdateThumbAndTrackGeometry(); - root_layer_impl = host->CommitAndCreateLayerImplTree(); - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - root_layer_impl->children()[1]); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); EXPECT_EQ(gfx::Rect(10, 0, 4, 10).ToString(), scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); // Under-scroll (thumb position should clamp and be unchanged). root_layer->SetScrollOffset(gfx::Vector2d(-5, 0)); - scrollbar_layer->UpdateThumbAndTrackGeometry(); - root_layer_impl = host->CommitAndCreateLayerImplTree(); - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - root_layer_impl->children()[1]); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); EXPECT_EQ(gfx::Rect(10, 0, 4, 10).ToString(), scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); // Over-scroll (thumb position should clamp on the far side). root_layer->SetScrollOffset(gfx::Vector2d(85, 0)); - scrollbar_layer->UpdateThumbAndTrackGeometry(); - root_layer_impl = host->CommitAndCreateLayerImplTree(); - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - root_layer_impl->children()[1]); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); EXPECT_EQ(gfx::Rect(56, 0, 4, 10).ToString(), scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); @@ -229,10 +245,7 @@ TEST(ScrollbarLayerTest, ThumbRect) { scrollbar_layer->fake_scrollbar()->set_thumb_thickness(4); scrollbar_layer->fake_scrollbar()->set_thumb_length(6); - scrollbar_layer->UpdateThumbAndTrackGeometry(); - root_layer_impl = host->CommitAndCreateLayerImplTree(); - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - root_layer_impl->children()[1]); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); EXPECT_EQ(gfx::Rect(54, 0, 6, 4).ToString(), scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); @@ -241,10 +254,7 @@ TEST(ScrollbarLayerTest, ThumbRect) { scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(30, 10)); scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10)); - scrollbar_layer->UpdateThumbAndTrackGeometry(); - root_layer_impl = host->CommitAndCreateLayerImplTree(); - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - root_layer_impl->children()[1]); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); EXPECT_EQ(gfx::Rect(44, 0, 6, 4).ToString(), scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); @@ -253,10 +263,7 @@ TEST(ScrollbarLayerTest, ThumbRect) { // position). scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 12, 50, 6)); - scrollbar_layer->UpdateThumbAndTrackGeometry(); - root_layer_impl = host->CommitAndCreateLayerImplTree(); - scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - root_layer_impl->children()[1]); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); EXPECT_EQ(gfx::Rect(44, 0, 6, 4).ToString(), scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); } @@ -332,22 +339,40 @@ TEST(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { FakeLayerTreeHost::Create(layer_tree_settings); scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); - LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - host.get(), scrollbar.Pass(), false, true, kThumbThickness); + + { + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + scoped_refptr<Layer> scroll_layer = Layer::Create(); + scroll_layer->SetScrollClipLayer(layer_tree_root); + scoped_refptr<Layer> child1 = Layer::Create(); + scoped_refptr<Layer> child2; + const bool kIsLeftSideVerticalScrollbar = false; + child2 = SolidColorScrollbarLayer::Create( + scrollbar->Orientation(), kThumbThickness, + kIsLeftSideVerticalScrollbar, child1.get()); + child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer); + child2->ToScrollbarLayer()->SetClipLayer(layer_tree_root); + scroll_layer->AddChild(child1); + scroll_layer->InsertChild(child2, 1); + layer_tree_root->AddChild(scroll_layer); + host->SetRootLayer(layer_tree_root); + } + LayerImpl* layer_impl_tree_root = host->CommitAndCreateLayerImplTree(); + LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0]; + ScrollbarLayerImplBase* scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( - layer_impl_tree_root->children()[1]); + scroll_layer_impl->children()[1]); + + // Choose layer bounds to give max_scroll_offset = (8, 8). + layer_impl_tree_root->SetBounds(gfx::Size(2, 2)); + scroll_layer_impl->SetBounds(gfx::Size(10, 10)); + scroll_layer_impl->ScrollBy(gfx::Vector2dF(4.f, 0.f)); scrollbar_layer_impl->SetBounds(gfx::Size(kTrackLength, kThumbThickness)); scrollbar_layer_impl->SetCurrentPos(4.f); scrollbar_layer_impl->SetMaximum(8); - layer_impl_tree_root->SetScrollable(true); - layer_impl_tree_root->SetHorizontalScrollbarLayer(scrollbar_layer_impl); - layer_impl_tree_root->SetMaxScrollOffset(gfx::Vector2d(8, 8)); - layer_impl_tree_root->SetBounds(gfx::Size(2, 2)); - layer_impl_tree_root->ScrollBy(gfx::Vector2dF(4.f, 0.f)); - { MockQuadCuller quad_culler; AppendQuadsData data; @@ -368,13 +393,14 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { const int kThumbThickness = 3; const bool kIsLeftSideVerticalScrollbar = false; + const bool kIsOverlayScrollbar = false; horizontal_scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), 1, HORIZONTAL, kThumbThickness, - kIsLeftSideVerticalScrollbar); + kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); vertical_scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), 2, VERTICAL, kThumbThickness, - kIsLeftSideVerticalScrollbar); + kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); } protected: @@ -456,16 +482,17 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest { void SetScrollbarBounds(gfx::Size bounds) { bounds_ = bounds; } virtual void BeginTest() OVERRIDE { + scroll_layer_ = Layer::Create(); + layer_tree_host()->root_layer()->AddChild(scroll_layer_); + scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); - scrollbar_layer_ = PaintedScrollbarLayer::Create(scrollbar.Pass(), 1); + scrollbar_layer_ = + PaintedScrollbarLayer::Create(scrollbar.Pass(), scroll_layer_.get()); + scrollbar_layer_->SetScrollLayer(scroll_layer_); scrollbar_layer_->SetLayerTreeHost(layer_tree_host()); scrollbar_layer_->SetBounds(bounds_); layer_tree_host()->root_layer()->AddChild(scrollbar_layer_); - scroll_layer_ = Layer::Create(); - scrollbar_layer_->SetScrollLayerId(scroll_layer_->id()); - layer_tree_host()->root_layer()->AddChild(scroll_layer_); - PostSetNeedsCommitToMainThread(); } @@ -584,10 +611,10 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { SolidColorScrollbarLayer::Create(scrollbar->Orientation(), kThumbThickness, kIsLeftSideVerticalScrollbar, - layer_tree_root->id()); + layer_tree_root.get()); } else { scrollbar_layer = PaintedScrollbarLayer::Create(scrollbar.Pass(), - layer_tree_root->id()); + layer_tree_root.get()); } layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); @@ -597,7 +624,6 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { scrollbar_layer->SetIsDrawable(true); scrollbar_layer->SetBounds(gfx::Size(100, 100)); layer_tree_root->SetScrollOffset(gfx::Vector2d(10, 20)); - layer_tree_root->SetMaxScrollOffset(gfx::Vector2d(30, 50)); layer_tree_root->SetBounds(gfx::Size(100, 200)); content_layer->SetBounds(gfx::Size(100, 200)); scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200); @@ -664,7 +690,7 @@ class ScaledScrollbarLayerTestResourceCreation : public testing::Test { scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer = - FakePaintedScrollbarLayer::Create(false, true, layer_tree_root->id()); + FakePaintedScrollbarLayer::Create(false, true, layer_tree_root.get()); layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); diff --git a/cc/layers/solid_color_scrollbar_layer.cc b/cc/layers/solid_color_scrollbar_layer.cc index d9ed922..196b7e8 100644 --- a/cc/layers/solid_color_scrollbar_layer.cc +++ b/cc/layers/solid_color_scrollbar_layer.cc @@ -12,29 +12,35 @@ namespace cc { scoped_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { + const bool kIsOverlayScrollbar = true; return SolidColorScrollbarLayerImpl::Create( - tree_impl, id(), orientation(), thumb_thickness_, - is_left_side_vertical_scrollbar_).PassAs<LayerImpl>(); + tree_impl, + id(), + orientation(), + thumb_thickness_, + is_left_side_vertical_scrollbar_, + kIsOverlayScrollbar).PassAs<LayerImpl>(); } scoped_refptr<SolidColorScrollbarLayer> SolidColorScrollbarLayer::Create( ScrollbarOrientation orientation, int thumb_thickness, bool is_left_side_vertical_scrollbar, - int scroll_layer_id) { + Layer* scroll_layer) { return make_scoped_refptr(new SolidColorScrollbarLayer( orientation, thumb_thickness, is_left_side_vertical_scrollbar, - scroll_layer_id)); + scroll_layer)); } SolidColorScrollbarLayer::SolidColorScrollbarLayer( ScrollbarOrientation orientation, int thumb_thickness, bool is_left_side_vertical_scrollbar, - int scroll_layer_id) - : scroll_layer_id_(scroll_layer_id), + Layer* scroll_layer) + : scroll_layer_(scroll_layer), + clip_layer_(NULL), orientation_(orientation), thumb_thickness_(thumb_thickness), is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) {} @@ -45,19 +51,42 @@ ScrollbarLayerInterface* SolidColorScrollbarLayer::ToScrollbarLayer() { return this; } +void SolidColorScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { + Layer::PushPropertiesTo(layer); + PushScrollClipPropertiesTo(layer); +} + +void SolidColorScrollbarLayer::PushScrollClipPropertiesTo(LayerImpl* layer) { + SolidColorScrollbarLayerImpl* scrollbar_layer = + static_cast<SolidColorScrollbarLayerImpl*>(layer); + + scrollbar_layer->SetScrollLayerById(scroll_layer_ ? scroll_layer_->id() + : Layer::INVALID_ID); + scrollbar_layer->SetClipLayerById(clip_layer_ ? clip_layer_->id() + : Layer::INVALID_ID); +} + bool SolidColorScrollbarLayer::OpacityCanAnimateOnImplThread() const { return true; } int SolidColorScrollbarLayer::ScrollLayerId() const { - return scroll_layer_id_; + return scroll_layer_->id(); +} + +void SolidColorScrollbarLayer::SetScrollLayer(scoped_refptr<Layer> layer) { + if (layer == scroll_layer_) + return; + + scroll_layer_ = layer; + SetNeedsFullTreeSync(); } -void SolidColorScrollbarLayer::SetScrollLayerId(int id) { - if (id == scroll_layer_id_) +void SolidColorScrollbarLayer::SetClipLayer(scoped_refptr<Layer> layer) { + if (layer == clip_layer_) return; - scroll_layer_id_ = id; + clip_layer_ = layer; SetNeedsFullTreeSync(); } diff --git a/cc/layers/solid_color_scrollbar_layer.h b/cc/layers/solid_color_scrollbar_layer.h index 9c0dc1e..a954af1 100644 --- a/cc/layers/solid_color_scrollbar_layer.h +++ b/cc/layers/solid_color_scrollbar_layer.h @@ -21,15 +21,19 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, ScrollbarOrientation orientation, int thumb_thickness, bool is_left_side_vertical_scrollbar, - int scroll_layer_id); + Layer* scroll_layer); // Layer overrides. virtual bool OpacityCanAnimateOnImplThread() const OVERRIDE; virtual ScrollbarLayerInterface* ToScrollbarLayer() OVERRIDE; + virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE; + virtual void PushScrollClipPropertiesTo(LayerImpl* layer) OVERRIDE; + // ScrollbarLayerInterface virtual int ScrollLayerId() const OVERRIDE; - virtual void SetScrollLayerId(int id) OVERRIDE; + virtual void SetScrollLayer(scoped_refptr<Layer> layer) OVERRIDE; + virtual void SetClipLayer(scoped_refptr<Layer> layer) OVERRIDE; virtual ScrollbarOrientation orientation() const OVERRIDE; @@ -37,11 +41,12 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, SolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumb_thickness, bool is_left_side_vertical_scrollbar, - int scroll_layer_id); + Layer* scroll_layer); virtual ~SolidColorScrollbarLayer(); private: - int scroll_layer_id_; + scoped_refptr<Layer> scroll_layer_; + scoped_refptr<Layer> clip_layer_; ScrollbarOrientation orientation_; int thumb_thickness_; bool is_left_side_vertical_scrollbar_; diff --git a/cc/layers/solid_color_scrollbar_layer_impl.cc b/cc/layers/solid_color_scrollbar_layer_impl.cc index 5c63203..34351ce 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl.cc +++ b/cc/layers/solid_color_scrollbar_layer_impl.cc @@ -15,19 +15,24 @@ scoped_ptr<SolidColorScrollbarLayerImpl> SolidColorScrollbarLayerImpl::Create( int id, ScrollbarOrientation orientation, int thumb_thickness, - bool is_left_side_vertical_scrollbar) { + bool is_left_side_vertical_scrollbar, + bool is_overlay) { return make_scoped_ptr(new SolidColorScrollbarLayerImpl( tree_impl, id, orientation, thumb_thickness, - is_left_side_vertical_scrollbar)); + is_left_side_vertical_scrollbar, is_overlay)); } SolidColorScrollbarLayerImpl::~SolidColorScrollbarLayerImpl() {} scoped_ptr<LayerImpl> SolidColorScrollbarLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return SolidColorScrollbarLayerImpl::Create( - tree_impl, id(), orientation(), thumb_thickness_, - is_left_side_vertical_scrollbar()).PassAs<LayerImpl>(); + return SolidColorScrollbarLayerImpl::Create(tree_impl, + id(), + orientation(), + thumb_thickness_, + is_left_side_vertical_scrollbar(), + is_overlay_scrollbar()) + .PassAs<LayerImpl>(); } SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl( @@ -35,9 +40,10 @@ SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl( int id, ScrollbarOrientation orientation, int thumb_thickness, - bool is_left_side_vertical_scrollbar) + bool is_left_side_vertical_scrollbar, + bool is_overlay) : ScrollbarLayerImplBase(tree_impl, id, orientation, - is_left_side_vertical_scrollbar), + is_left_side_vertical_scrollbar, is_overlay), thumb_thickness_(thumb_thickness), color_(tree_impl->settings().solid_color_scrollbar_color) {} diff --git a/cc/layers/solid_color_scrollbar_layer_impl.h b/cc/layers/solid_color_scrollbar_layer_impl.h index b725ed5..205496a 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl.h +++ b/cc/layers/solid_color_scrollbar_layer_impl.h @@ -17,7 +17,8 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { int id, ScrollbarOrientation orientation, int thumb_thickness, - bool is_left_side_vertical_scrollbar); + bool is_left_side_vertical_scrollbar, + bool is_overlay); virtual ~SolidColorScrollbarLayerImpl(); // LayerImpl overrides. @@ -34,7 +35,8 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { int id, ScrollbarOrientation orientation, int thumb_thickness, - bool is_left_side_vertical_scrollbar); + bool is_left_side_vertical_scrollbar, + bool is_overlay); // ScrollbarLayerImplBase implementation. virtual int ThumbThickness() const OVERRIDE; |