| Index: cc/trees/layer_tree_host_impl.cc
|
| diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
|
| index ff79b2575e512d745cce617312d0381105eafeb8..ed16264cd3cd8c21c5c699e62aa347ce3bac4fab 100644
|
| --- a/cc/trees/layer_tree_host_impl.cc
|
| +++ b/cc/trees/layer_tree_host_impl.cc
|
| @@ -734,6 +734,92 @@ DrawMode LayerTreeHostImpl::GetDrawMode() const {
|
| }
|
| }
|
|
|
| +static double FindClosestInSortedArray(double start,
|
| + double target,
|
| + const std::vector<SnapPoint>& array) {
|
| + int size = array.size();
|
| + if (size <= 0)
|
| + return target;
|
| +
|
| + int large_area_cnt = 0;
|
| +
|
| + if (target >= start) {
|
| + // First, find the index of the snap point that's closest
|
| + // to start point.
|
| + double snap_point = array[0].offset;
|
| + double delta = target - snap_point;
|
| + int i = 0;
|
| + for (; i < size; ++i) {
|
| + if (array[i].offset >= start)
|
| + break;
|
| + if (array[i].is_start)
|
| + ++large_area_cnt;
|
| + if (array[i].is_end)
|
| + --large_area_cnt;
|
| + snap_point = array[i].offset;
|
| + delta = target - snap_point;
|
| + }
|
| + if (i >= size)
|
| + return target;
|
| +
|
| + for (int j = i; j < size; ++j) {
|
| + if (array[j].offset >= target) {
|
| + if (large_area_cnt > 0)
|
| + return target;
|
| + if (array[j].offset - target < delta)
|
| + return array[j].offset;
|
| + return snap_point;
|
| + }
|
| + if (array[j].must_snap && start != target)
|
| + return array[j].offset;
|
| + if (array[j].is_start)
|
| + ++large_area_cnt;
|
| + if (array[j].is_end)
|
| + --large_area_cnt;
|
| + snap_point = array[j].offset;
|
| + delta = target - snap_point;
|
| + }
|
| + }
|
| +
|
| + if (target < start) {
|
| + double snap_point = array[size - 1].offset;
|
| + double delta = snap_point - target;
|
| + int i = size - 1;
|
| + for (; i >= 0; --i) {
|
| + if (array[i].offset <= start)
|
| + break;
|
| + if (array[i].is_end)
|
| + ++large_area_cnt;
|
| + if (array[i].is_start)
|
| + --large_area_cnt;
|
| + snap_point = array[i].offset;
|
| + delta = snap_point - target;
|
| + }
|
| + if (i < 0)
|
| + return target;
|
| +
|
| + for (int j = i; j >= 0; --j) {
|
| + if (array[j].offset <= target) {
|
| + if (large_area_cnt > 0)
|
| + return target;
|
| + if (target - array[j].offset < delta)
|
| + return array[j].offset;
|
| + return snap_point;
|
| + }
|
| + if (array[j].must_snap)
|
| + return array[j].offset;
|
| + if (array[j].is_end)
|
| + ++large_area_cnt;
|
| + if (array[j].is_start)
|
| + --large_area_cnt;
|
| + snap_point = array[j].offset;
|
| + delta = snap_point - target;
|
| + }
|
| + }
|
| +
|
| + return target;
|
| +}
|
| +
|
| static void AppendQuadsToFillScreen(
|
| const gfx::Rect& root_scroll_layer_rect,
|
| RenderPass* target_render_pass,
|
| @@ -3220,6 +3306,7 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollSingleNode(
|
| void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node,
|
| ScrollState* scroll_state) {
|
| DCHECK(scroll_node && scroll_state);
|
| +
|
| gfx::Point viewport_point(scroll_state->position_x(),
|
| scroll_state->position_y());
|
| const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y());
|
| @@ -3290,6 +3377,36 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node,
|
| scroll_state->set_current_native_scrolling_node(scroll_node);
|
| }
|
|
|
| +void LayerTreeHostImpl::FindSnappedOffset(
|
| + gfx::Vector2dF* snapped_offset,
|
| + const gfx::Vector2dF& original_offset) {
|
| + ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
|
| + ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
|
| +
|
| + LayerImpl* layer =
|
| + active_tree()->FindActiveTreeLayerById(scroll_node->owning_layer_id);
|
| + float scale_factor = active_tree()->current_page_scale_factor();
|
| + gfx::Vector2dF scaled = original_offset;
|
| + scaled.Scale(1.f / scale_factor);
|
| +
|
| + gfx::ScrollOffset current_offset =
|
| + scroll_tree.current_scroll_offset(scroll_node->owning_layer_id);
|
| + gfx::ScrollOffset expected_offset =
|
| + current_offset - gfx::ScrollOffset(scaled);
|
| + std::vector<SnapPoint> horizontal = layer->snap_offsets_horizontal();
|
| + std::vector<SnapPoint> vertical = layer->snap_offsets_vertical();
|
| + double snapped_x = FindClosestInSortedArray(current_offset.x(),
|
| + expected_offset.x(), horizontal);
|
| + double snapped_y = FindClosestInSortedArray(current_offset.y(),
|
| + expected_offset.y(), vertical);
|
| + expected_offset.set_x(snapped_x);
|
| + expected_offset.set_y(snapped_y);
|
| + expected_offset = current_offset - expected_offset;
|
| + snapped_offset->set_x(expected_offset.x());
|
| + snapped_offset->set_y(expected_offset.y());
|
| + snapped_offset->Scale(scale_factor);
|
| +}
|
| +
|
| void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) {
|
| // TODO(majidvp): in Blink we compute scroll chain only at scroll begin which
|
| // is not the case here. We eventually want to have the same behaviour on both
|
| @@ -3414,6 +3531,14 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
|
| return scroll_result;
|
| }
|
|
|
| +void LayerTreeHostImpl::SnapAfterGestureScroll(const gfx::Point& scroll_point) {
|
| + gfx::Vector2dF snap_offset, original_offset;
|
| + FindSnappedOffset(&snap_offset, original_offset);
|
| + ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
|
| + ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
|
| + ScrollAnimationCreate(scroll_node, -snap_offset, base::TimeDelta());
|
| +}
|
| +
|
| void LayerTreeHostImpl::RequestUpdateForSynchronousInputHandler() {
|
| UpdateRootLayerStateForSynchronousInputHandler();
|
| }
|
|
|