Commit aa274831 authored by bokan's avatar bokan Committed by Commit bot

Move viewport scrolling logic into separate class

The viewport is made up of two scrolling layers now, the inner
and outer viewport scroll layers. These layers do not follow the
usual scroll bubbling logic since they're supposed to appear as
one viewport to the user (i.e. we should rail). Forcing it to
be scrolled via LayerTreeHostImpl::ScrollBy caused that method to
become increasingly complex.

This patch creates a Viewport class that allows LTHI::ScrollBy to
call Viewport::ScrollBy and scroll the viewport as a unit. I've
tried to simplify the logic in both these methods as much as I
could without changing behavior.

BUG=443724

Review URL: https://codereview.chromium.org/986443003

Cr-Commit-Position: refs/heads/master@{#322268}
parent 170b95cf
......@@ -196,6 +196,8 @@ component("cc") {
"layers/video_layer.h",
"layers/video_layer_impl.cc",
"layers/video_layer_impl.h",
"layers/viewport.cc",
"layers/viewport.h",
"output/begin_frame_args.cc",
"output/begin_frame_args.h",
"output/bsp_tree.cc",
......
......@@ -248,6 +248,8 @@
'layers/video_layer.h',
'layers/video_layer_impl.cc',
'layers/video_layer_impl.h',
'layers/viewport.cc',
'layers/viewport.h',
'output/begin_frame_args.cc',
'output/begin_frame_args.h',
'output/bsp_tree.cc',
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/layers/viewport.h"
#include "base/logging.h"
#include "cc/input/top_controls_manager.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
// static
scoped_ptr<Viewport> Viewport::Create(
LayerTreeHostImpl* host_impl) {
return make_scoped_ptr(new Viewport(host_impl));
}
Viewport::Viewport(LayerTreeHostImpl* host_impl)
: host_impl_(host_impl) {
DCHECK(host_impl_);
}
Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
const gfx::Point& viewport_point,
bool is_wheel_scroll) {
gfx::Vector2dF content_delta = delta;
ScrollResult result;
if (ShouldTopControlsConsumeScroll(delta)) {
result.top_controls_applied_delta = ScrollTopControls(delta);
content_delta -= result.top_controls_applied_delta;
}
gfx::Vector2dF pending_content_delta = content_delta;
if (OuterScrollLayer()) {
pending_content_delta -= host_impl_->ScrollLayer(OuterScrollLayer(),
pending_content_delta,
viewport_point,
is_wheel_scroll);
}
// TODO(bokan): This shouldn't be needed but removing it causes subtle
// viewport movement during top controls manipulation.
if (!gfx::ToRoundedVector2d(pending_content_delta).IsZero()) {
pending_content_delta -= host_impl_->ScrollLayer(InnerScrollLayer(),
pending_content_delta,
viewport_point,
is_wheel_scroll);
result.unused_scroll_delta = AdjustOverscroll(pending_content_delta);
}
result.applied_delta = content_delta - pending_content_delta;
return result;
}
gfx::Vector2dF Viewport::ScrollTopControls(const gfx::Vector2dF& delta) {
gfx::Vector2dF excess_delta =
host_impl_->top_controls_manager()->ScrollBy(delta);
return delta - excess_delta;
}
bool Viewport::ShouldTopControlsConsumeScroll(
const gfx::Vector2dF& scroll_delta) const {
// Always consume if it's in the direction to show the top controls.
if (scroll_delta.y() < 0)
return true;
if (TotalScrollOffset().y() < MaxTotalScrollOffset().y())
return true;
return false;
}
gfx::Vector2dF Viewport::AdjustOverscroll(const gfx::Vector2dF& delta) const {
const float kEpsilon = 0.1f;
gfx::Vector2dF adjusted = delta;
if (std::abs(adjusted.x()) < kEpsilon)
adjusted.set_x(0.0f);
if (std::abs(adjusted.y()) < kEpsilon)
adjusted.set_y(0.0f);
// Disable overscroll on axes which are impossible to scroll.
if (host_impl_->settings().report_overscroll_only_for_scrollable_axes) {
if (std::abs(MaxTotalScrollOffset().x()) <= kEpsilon ||
!InnerScrollLayer()->user_scrollable_horizontal())
adjusted.set_x(0.0f);
if (std::abs(MaxTotalScrollOffset().y()) <= kEpsilon ||
!InnerScrollLayer()->user_scrollable_vertical())
adjusted.set_y(0.0f);
}
return adjusted;
}
gfx::ScrollOffset Viewport::MaxTotalScrollOffset() const {
gfx::ScrollOffset offset;
offset += InnerScrollLayer()->MaxScrollOffset();
if (OuterScrollLayer())
offset += OuterScrollLayer()->MaxScrollOffset();
return offset;
}
gfx::ScrollOffset Viewport::TotalScrollOffset() const {
gfx::ScrollOffset offset;
offset += InnerScrollLayer()->CurrentScrollOffset();
if (OuterScrollLayer())
offset += OuterScrollLayer()->CurrentScrollOffset();
return offset;
}
LayerImpl* Viewport::InnerScrollLayer() const {
return host_impl_->InnerViewportScrollLayer();
}
LayerImpl* Viewport::OuterScrollLayer() const {
return host_impl_->OuterViewportScrollLayer();
}
} // namespace cc
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_LAYERS_VIEWPORT_H_
#define CC_LAYERS_VIEWPORT_H_
#include "base/memory/scoped_ptr.h"
#include "cc/layers/layer_impl.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
class LayerTreeHostImpl;
// Encapsulates gesture handling logic on the viewport layers. The "viewport"
// is made up of two scrolling layers, the inner viewport (visual) and the
// outer viewport (layout) scroll layers. These layers have different scroll
// bubbling behavior from the rest of the layer tree which is encoded in this
// class.
class CC_EXPORT Viewport {
public:
struct ScrollResult {
gfx::Vector2dF applied_delta;
gfx::Vector2dF unused_scroll_delta;
gfx::Vector2dF top_controls_applied_delta;
};
static scoped_ptr<Viewport> Create(LayerTreeHostImpl* host_impl);
// Scrolls the viewport, applying the unique bubbling between the inner and
// outer viewport. Scrolls can be consumed by top controls.
ScrollResult ScrollBy(const gfx::Vector2dF& delta,
const gfx::Point& viewport_point,
bool is_wheel_scroll);
private:
explicit Viewport(LayerTreeHostImpl* host_impl);
bool ShouldTopControlsConsumeScroll(const gfx::Vector2dF& scroll_delta) const;
gfx::Vector2dF AdjustOverscroll(const gfx::Vector2dF& delta) const;
// Sends the delta to the top controls, returns the amount applied.
gfx::Vector2dF ScrollTopControls(const gfx::Vector2dF& delta);
gfx::ScrollOffset MaxTotalScrollOffset() const;
gfx::ScrollOffset TotalScrollOffset() const;
LayerImpl* InnerScrollLayer() const;
LayerImpl* OuterScrollLayer() const;
LayerTreeHostImpl* host_impl_;
DISALLOW_COPY_AND_ASSIGN(Viewport);
};
} // namespace cc
#endif // CC_LAYERS_VIEWPORT_H_
This diff is collapsed.
......@@ -73,6 +73,7 @@ class TopControlsManager;
class UIResourceBitmap;
class UIResourceRequest;
struct ScrollAndScaleSet;
class Viewport;
enum class GpuRasterizationStatus {
ON,
......@@ -524,6 +525,11 @@ class CC_EXPORT LayerTreeHostImpl
return frame_timing_tracker_.get();
}
gfx::Vector2dF ScrollLayer(LayerImpl* layer_impl,
const gfx::Vector2dF& delta,
const gfx::Point& viewport_point,
bool is_wheel_scroll);
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
......@@ -546,6 +552,11 @@ class CC_EXPORT LayerTreeHostImpl
Proxy* proxy_;
private:
gfx::Vector2dF ScrollLayerWithViewportSpaceDelta(
LayerImpl* layer_impl,
const gfx::PointF& viewport_point,
const gfx::Vector2dF& viewport_delta);
void CreateAndSetRenderer();
void CreateAndSetTileManager();
void DestroyTileManager();
......@@ -555,6 +566,8 @@ class CC_EXPORT LayerTreeHostImpl
bool IsSynchronousSingleThreaded() const;
Viewport* viewport() { return viewport_.get(); }
// Scroll by preferring to move the outer viewport first, only moving the
// inner if the outer is at its scroll extents.
void ScrollViewportBy(gfx::Vector2dF scroll_delta);
......@@ -565,14 +578,6 @@ class CC_EXPORT LayerTreeHostImpl
void AnimateScrollbars(base::TimeTicks monotonic_time);
void AnimateTopControls(base::TimeTicks monotonic_time);
bool ShouldTopControlsConsumeScroll(const gfx::Vector2dF& scroll_delta) const;
gfx::Vector2dF ScrollLayerWithViewportSpaceDelta(
LayerImpl* layer_impl,
float scale_from_viewport_to_screen_space,
const gfx::PointF& viewport_point,
const gfx::Vector2dF& viewport_delta);
void TrackDamageForAllSurfaces(
LayerImpl* root_draw_layer,
const LayerImplList& render_surface_layer_list);
......@@ -747,6 +752,8 @@ class CC_EXPORT LayerTreeHostImpl
scoped_ptr<FrameTimingTracker> frame_timing_tracker_;
scoped_ptr<Viewport> viewport_;
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment