#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/proxy.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.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"
-#include "ui/gfx/size_conversions.h"
namespace cc {
LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id)
- : parent_(NULL),
- scroll_parent_(NULL),
- clip_parent_(NULL),
+ : parent_(nullptr),
+ scroll_parent_(nullptr),
+ clip_parent_(nullptr),
mask_layer_id_(-1),
replica_layer_id_(-1),
layer_id_(id),
layer_tree_impl_(tree_impl),
- scroll_offset_delegate_(NULL),
- scroll_clip_layer_(NULL),
+ scroll_offset_delegate_(nullptr),
+ scroll_clip_layer_(nullptr),
should_scroll_on_main_thread_(false),
have_wheel_event_handlers_(false),
have_scroll_event_handlers_(false),
return ret.Pass();
}
}
- return scoped_ptr<LayerImpl>();
+ return nullptr;
}
void LayerImpl::SetParent(LayerImpl* parent) {
}
void LayerImpl::ClearRenderSurface() {
- draw_properties_.render_surface.reset();
+ draw_properties_.render_surface = nullptr;
}
void LayerImpl::ClearRenderSurfaceLayerList() {
return RenderPassId(0, 0);
}
-ResourceProvider::ResourceId LayerImpl::ContentsResourceId() const {
+void LayerImpl::GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
+ gfx::Size* resource_size) const {
NOTREACHED();
- return 0;
+ *resource_id = 0;
}
-void LayerImpl::SetSentScrollDelta(const gfx::Vector2d& sent_scroll_delta) {
+void LayerImpl::SetSentScrollDelta(const gfx::Vector2dF& sent_scroll_delta) {
// Pending tree never has sent scroll deltas
DCHECK(layer_tree_impl()->IsActiveTree());
}
gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) {
+ gfx::Vector2dF adjusted_scroll = scroll;
+ if (layer_tree_impl()->settings().use_pinch_virtual_viewport) {
+ if (!user_scrollable_horizontal_)
+ adjusted_scroll.set_x(0);
+ if (!user_scrollable_vertical_)
+ adjusted_scroll.set_y(0);
+ }
DCHECK(scrollable());
- gfx::Vector2dF min_delta = -scroll_offset_;
- gfx::Vector2dF max_delta = MaxScrollOffset() - scroll_offset_;
+ gfx::Vector2dF min_delta = -ScrollOffsetToVector2dF(scroll_offset_);
+ gfx::Vector2dF max_delta = MaxScrollOffset().DeltaFrom(scroll_offset_);
// Clamp new_delta so that position + delta stays within scroll bounds.
- gfx::Vector2dF new_delta = (ScrollDelta() + scroll);
+ gfx::Vector2dF new_delta = (ScrollDelta() + adjusted_scroll);
new_delta.SetToMax(min_delta);
new_delta.SetToMin(max_delta);
gfx::Vector2dF unscrolled =
scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id);
}
+bool LayerImpl::user_scrollable(ScrollbarOrientation orientation) const {
+ return (orientation == HORIZONTAL) ? user_scrollable_horizontal_
+ : user_scrollable_vertical_;
+}
+
void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() {
+ if (sent_scroll_delta_.IsZero())
+ return;
+
// Pending tree never has sent scroll deltas
DCHECK(layer_tree_impl()->IsActiveTree());
+ // The combination of pending tree and aborted commits with impl scrolls
+ // shouldn't happen; we don't know how to update its deltas correctly.
+ DCHECK(!layer_tree_impl()->FindPendingTreeLayerById(id()));
+
// Apply sent scroll deltas to scroll position / scroll delta as if the
// main thread had applied them and then committed those values.
- //
- // This function should not change the total scroll offset; it just shifts
- // some of the scroll delta to the scroll offset. Therefore, adjust these
- // variables directly rather than calling the scroll offset delegate to
- // avoid sending it multiple spurious calls.
- //
- // Because of the way scroll delta is calculated with a delegate, this will
- // leave the total scroll offset unchanged on this layer regardless of
- // whether a delegate is being used.
- scroll_offset_ += sent_scroll_delta_;
- scroll_delta_ -= sent_scroll_delta_;
- sent_scroll_delta_ = gfx::Vector2d();
+ SetScrollOffsetAndDelta(
+ scroll_offset_ + gfx::ScrollOffset(sent_scroll_delta_),
+ ScrollDelta() - sent_scroll_delta_);
+ SetSentScrollDelta(gfx::Vector2dF());
}
void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() {
return InputHandler::ScrollIgnored;
}
- gfx::Vector2d max_scroll_offset = MaxScrollOffset();
+ gfx::ScrollOffset max_scroll_offset = MaxScrollOffset();
if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0) {
TRACE_EVENT0("cc",
"LayerImpl::tryScroll: Ignored. Technically scrollable,"
// it again in SetScrollOffsetAndDelta's pending twin mirroring logic.
gfx::Vector2dF remaining_delta =
layer->ScrollDelta() - layer->sent_scroll_delta();
- layer->SetSentScrollDelta(gfx::Vector2d());
+ layer->SetSentScrollDelta(gfx::Vector2dF());
layer->SetScrollOffsetAndDelta(scroll_offset_, remaining_delta);
layer->Set3dSortingContextId(sorting_context_id_);
layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_);
- LayerImpl* scroll_parent = NULL;
+ LayerImpl* scroll_parent = nullptr;
if (scroll_parent_) {
scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
DCHECK(scroll_parent);
}
layer->SetScrollChildren(scroll_children);
} else {
- layer->SetScrollChildren(NULL);
+ layer->SetScrollChildren(nullptr);
}
- LayerImpl* clip_parent = NULL;
+ LayerImpl* clip_parent = nullptr;
if (clip_parent_) {
clip_parent = layer->layer_tree_impl()->LayerById(
clip_parent_->id());
clip_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
layer->SetClipChildren(clip_children);
} else {
- layer->SetClipChildren(NULL);
+ layer->SetClipChildren(nullptr);
}
layer->PassCopyRequests(©_requests_);
// Reset any state that should be cleared for the next update.
stacking_order_changed_ = false;
- update_rect_ = gfx::RectF();
+ update_rect_ = gfx::Rect();
needs_push_properties_ = false;
num_dependents_need_push_properties_ = 0;
}
float scale = layer_tree_impl()->page_scale_factor();
gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->bounds_delta();
+
+ // In virtual-viewport mode, we don't need to compensate for pinch zoom or
+ // scale since the fixed container is the outer viewport, which sits below
+ // the page scale.
+ if (layer_tree_impl()->settings().use_pinch_virtual_viewport)
+ return delta_from_scroll;
+
delta_from_scroll.Scale(1.f / scale);
// The delta-from-pinch component requires some explanation: A viewport of
void LayerImpl::ResetAllChangeTrackingForSubtree() {
layer_property_changed_ = false;
- update_rect_ = gfx::RectF();
+ update_rect_ = gfx::Rect();
damage_rect_ = gfx::RectF();
if (draw_properties_.render_surface)
num_dependents_need_push_properties_ = 0;
}
-gfx::Vector2dF LayerImpl::ScrollOffsetForAnimation() const {
+gfx::ScrollOffset LayerImpl::ScrollOffsetForAnimation() const {
return TotalScrollOffset();
}
SetTransform(transform);
}
-void LayerImpl::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) {
+void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) {
// Only layers in the active tree should need to do anything here, since
// layers in the pending tree will find out about these changes as a
// result of the call to SetScrollDelta.
if (!IsActive())
return;
- SetScrollDelta(scroll_offset - scroll_offset_);
+ SetScrollDelta(scroll_offset.DeltaFrom(scroll_offset_));
layer_tree_impl_->DidAnimateScrollOffset();
}
return layer_tree_impl_->IsActiveTree();
}
-// TODO(aelias): Convert so that bounds returns SizeF.
gfx::Size LayerImpl::bounds() const {
- return gfx::ToCeiledSize(gfx::SizeF(bounds_.width() + bounds_delta_.x(),
- bounds_.height() + bounds_delta_.y()));
+ gfx::Vector2d delta = gfx::ToCeiledVector2d(bounds_delta_);
+ return gfx::Size(bounds_.width() + delta.x(),
+ bounds_.height() + delta.y());
+}
+
+gfx::SizeF LayerImpl::BoundsForScrolling() const {
+ return gfx::SizeF(bounds_.width() + bounds_delta_.x(),
+ bounds_.height() + bounds_delta_.y());
}
void LayerImpl::SetBounds(const gfx::Size& bounds) {
bounds_ = bounds;
- ScrollbarParametersDidChange();
+ ScrollbarParametersDidChange(true);
if (masks_to_bounds())
NoteLayerPropertyChangedForSubtree();
else
bounds_delta_ = bounds_delta;
- ScrollbarParametersDidChange();
+ ScrollbarParametersDidChange(true);
if (masks_to_bounds())
NoteLayerPropertyChangedForSubtree();
else
}
ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() {
- return NULL;
+ return nullptr;
}
void LayerImpl::SetDrawsContent(bool draws_content) {
return transform_animation && transform_animation->is_impl_only();
}
-void LayerImpl::SetUpdateRect(const gfx::RectF& update_rect) {
+void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) {
update_rect_ = update_rect;
SetNeedsPushProperties();
}
// Having both a scroll parent and a scroll offset delegate is unsupported.
DCHECK(!scroll_parent_);
if (!scroll_offset_delegate && scroll_offset_delegate_) {
- scroll_delta_ =
- scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_;
+ scroll_delta_ = scroll_offset_delegate_->GetTotalScrollOffset().DeltaFrom(
+ scroll_offset_);
}
- gfx::Vector2dF total_offset = TotalScrollOffset();
+ gfx::ScrollOffset total_offset = TotalScrollOffset();
scroll_offset_delegate_ = scroll_offset_delegate;
if (scroll_offset_delegate_)
scroll_offset_delegate_->SetTotalScrollOffset(total_offset);
scroll_offset_delegate_->IsExternalFlingActive();
}
-void LayerImpl::SetScrollOffset(const gfx::Vector2d& scroll_offset) {
+void LayerImpl::DidScroll() {
+ NoteLayerPropertyChangedForSubtree();
+ ScrollbarParametersDidChange(false);
+}
+
+void LayerImpl::SetScrollOffset(const gfx::ScrollOffset& scroll_offset) {
SetScrollOffsetAndDelta(scroll_offset, ScrollDelta());
}
-void LayerImpl::SetScrollOffsetAndDelta(const gfx::Vector2d& scroll_offset,
+void LayerImpl::SetScrollOffsetAndDelta(const gfx::ScrollOffset& scroll_offset,
const gfx::Vector2dF& scroll_delta) {
bool changed = false;
}
if (scroll_offset_delegate_) {
- scroll_offset_delegate_->SetTotalScrollOffset(scroll_offset_ +
- scroll_delta);
+ scroll_offset_delegate_->SetTotalScrollOffset(
+ ScrollOffsetWithDelta(scroll_offset_, scroll_delta));
} else {
scroll_delta_ = scroll_delta;
}
}
if (changed) {
- NoteLayerPropertyChangedForSubtree();
- ScrollbarParametersDidChange();
+ if (scroll_offset_delegate_)
+ scroll_offset_delegate_->Update();
+ DidScroll();
}
}
gfx::Vector2dF LayerImpl::ScrollDelta() const {
- if (scroll_offset_delegate_)
- return scroll_offset_delegate_->GetTotalScrollOffset() - scroll_offset_;
+ if (scroll_offset_delegate_) {
+ return scroll_offset_delegate_->GetTotalScrollOffset().DeltaFrom(
+ scroll_offset_);
+ }
return scroll_delta_;
}
SetScrollOffsetAndDelta(scroll_offset_, scroll_delta);
}
-gfx::Vector2dF LayerImpl::TotalScrollOffset() const {
- return scroll_offset_ + ScrollDelta();
+gfx::ScrollOffset LayerImpl::TotalScrollOffset() const {
+ return ScrollOffsetWithDelta(scroll_offset_, ScrollDelta());
}
void LayerImpl::SetDoubleSided(bool double_sided) {
void LayerImpl::ReleaseResources() {}
-gfx::Vector2d LayerImpl::MaxScrollOffset() const {
+gfx::ScrollOffset LayerImpl::MaxScrollOffset() const {
if (!scroll_clip_layer_ || bounds().IsEmpty())
- return gfx::Vector2d();
+ return gfx::ScrollOffset();
LayerImpl const* page_scale_layer = layer_tree_impl()->page_scale_layer();
DCHECK(this != page_scale_layer);
DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() ||
IsContainerForFixedPositionLayers());
- gfx::SizeF scaled_scroll_bounds(bounds());
+ gfx::SizeF scaled_scroll_bounds(BoundsForScrolling());
float scale_factor = 1.f;
for (LayerImpl const* current_layer = this;
scale_factor * scaled_scroll_bounds.height());
scaled_scroll_bounds = gfx::ToFlooredSize(scaled_scroll_bounds);
- gfx::Vector2dF max_offset(
+ gfx::ScrollOffset 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);
+ max_offset.SetToMax(gfx::ScrollOffset());
+ return max_offset;
}
gfx::Vector2dF LayerImpl::ClampScrollToMaxScrollOffset() {
- gfx::Vector2dF max_offset = MaxScrollOffset();
- gfx::Vector2dF old_offset = TotalScrollOffset();
- gfx::Vector2dF clamped_offset = old_offset;
+ gfx::ScrollOffset max_offset = MaxScrollOffset();
+ gfx::ScrollOffset old_offset = TotalScrollOffset();
+ gfx::ScrollOffset clamped_offset = old_offset;
clamped_offset.SetToMin(max_offset);
- clamped_offset.SetToMax(gfx::Vector2d());
- gfx::Vector2dF delta = clamped_offset - old_offset;
+ clamped_offset.SetToMax(gfx::ScrollOffset());
+ gfx::Vector2dF delta = clamped_offset.DeltaFrom(old_offset);
if (!delta.IsZero())
ScrollBy(delta);
}
void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer,
- LayerImpl* scrollbar_clip_layer) const {
+ LayerImpl* scrollbar_clip_layer,
+ bool on_resize) const {
DCHECK(scrollbar_layer);
LayerImpl* page_scale_layer = layer_tree_impl()->page_scale_layer();
DCHECK(scrollbar_clip_layer);
DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() ||
IsContainerForFixedPositionLayers());
- gfx::RectF clip_rect(gfx::PointF(), scrollbar_clip_layer->bounds());
+ gfx::RectF clip_rect(gfx::PointF(),
+ scrollbar_clip_layer->BoundsForScrolling());
// See comment in MaxScrollOffset() regarding the use of the content layer
// bounds here.
- gfx::RectF scroll_rect(gfx::PointF(), bounds());
+ gfx::RectF scroll_rect(gfx::PointF(), BoundsForScrolling());
if (scroll_rect.size().IsEmpty())
return;
// TODO(wjmaclean) This computation is nearly identical to the one in
// MaxScrollOffset. Find some way to combine these.
- gfx::Vector2dF current_offset;
+ gfx::ScrollOffset current_offset;
for (LayerImpl const* current_layer = this;
current_layer != scrollbar_clip_layer;
current_layer = current_layer->parent()) {
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();
+ gfx::ScrollOffset new_offset = ScrollOffsetWithDelta(
+ current_layer->scroll_offset(), current_layer->ScrollDelta());
new_offset.Scale(layer_scale.x(), layer_scale.y());
current_offset += new_offset;
}
layer_tree_impl()->min_page_scale_factor()) ||
!layer_tree_impl()->settings().use_pinch_zoom_scrollbars);
if (is_animatable_scrollbar)
- scrollbar_animation_controller_->DidScrollUpdate();
+ scrollbar_animation_controller_->DidScrollUpdate(on_resize);
}
}
}
bool need_scrollbar_animation_controller = scrollable() && scrollbars_;
if (!need_scrollbar_animation_controller) {
- scrollbar_animation_controller_.reset();
+ scrollbar_animation_controller_ = nullptr;
return;
}
if (!scrollbars_)
return;
- scrollbars_.reset(NULL);
+ scrollbars_.reset(nullptr);
}
void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) {
scrollbars_->erase(layer);
if (scrollbars_->empty())
- scrollbars_.reset();
+ scrollbars_ = nullptr;
}
bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const {
return false;
}
-void LayerImpl::ScrollbarParametersDidChange() {
+void LayerImpl::ScrollbarParametersDidChange(bool on_resize) {
if (!scrollbars_)
return;
for (ScrollbarSet::iterator it = scrollbars_->begin();
it != scrollbars_->end();
- ++it)
- (*it)->ScrollbarParametersDidChange();
+ ++it) {
+ bool is_scroll_layer = (*it)->ScrollLayerId() == layer_id_;
+ bool scroll_layer_resized = is_scroll_layer && on_resize;
+ (*it)->ScrollbarParametersDidChange(scroll_layer_resized);
+ }
}
void LayerImpl::SetNeedsPushProperties() {
scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(str));
if (debug_info_value->IsType(base::Value::TYPE_DICTIONARY)) {
- base::DictionaryValue* dictionary_value = NULL;
+ base::DictionaryValue* dictionary_value = nullptr;
bool converted_to_dictionary =
debug_info_value->GetAsDictionary(&dictionary_value);
DCHECK(converted_to_dictionary);
void LayerImpl::NotifyAnimationFinished(
base::TimeTicks monotonic_time,
- Animation::TargetProperty target_property) {
+ Animation::TargetProperty target_property,
+ int group) {
if (target_property == Animation::ScrollOffset)
layer_tree_impl_->InputScrollAnimationFinished();
}