GPU workaround to simulate Out of Memory errors with large textures
[chromium-blink-merge.git] / cc / layers / viewport.cc
blob944f1bbd3cfc45012f17cfcca4173faf164cb3ae
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/layers/viewport.h"
7 #include "base/logging.h"
8 #include "cc/input/top_controls_manager.h"
9 #include "cc/trees/layer_tree_host_impl.h"
10 #include "cc/trees/layer_tree_impl.h"
11 #include "ui/gfx/geometry/vector2d_conversions.h"
12 #include "ui/gfx/geometry/vector2d_f.h"
14 namespace cc {
16 // static
17 scoped_ptr<Viewport> Viewport::Create(
18 LayerTreeHostImpl* host_impl) {
19 return make_scoped_ptr(new Viewport(host_impl));
22 Viewport::Viewport(LayerTreeHostImpl* host_impl)
23 : host_impl_(host_impl) {
24 DCHECK(host_impl_);
27 Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
28 const gfx::Point& viewport_point,
29 bool is_wheel_scroll) {
30 gfx::Vector2dF content_delta = delta;
31 ScrollResult result;
33 if (ShouldTopControlsConsumeScroll(delta)) {
34 result.top_controls_applied_delta = ScrollTopControls(delta);
35 content_delta -= result.top_controls_applied_delta;
38 gfx::Vector2dF pending_content_delta = content_delta;
40 if (OuterScrollLayer()) {
41 pending_content_delta -= host_impl_->ScrollLayer(OuterScrollLayer(),
42 pending_content_delta,
43 viewport_point,
44 is_wheel_scroll);
47 // TODO(bokan): This shouldn't be needed but removing it causes subtle
48 // viewport movement during top controls manipulation.
49 if (!gfx::ToRoundedVector2d(pending_content_delta).IsZero()) {
50 pending_content_delta -= host_impl_->ScrollLayer(InnerScrollLayer(),
51 pending_content_delta,
52 viewport_point,
53 is_wheel_scroll);
54 result.unused_scroll_delta = AdjustOverscroll(pending_content_delta);
58 result.applied_delta = content_delta - pending_content_delta;
59 return result;
62 gfx::Vector2dF Viewport::ScrollTopControls(const gfx::Vector2dF& delta) {
63 gfx::Vector2dF excess_delta =
64 host_impl_->top_controls_manager()->ScrollBy(delta);
66 return delta - excess_delta;
69 bool Viewport::ShouldTopControlsConsumeScroll(
70 const gfx::Vector2dF& scroll_delta) const {
71 // Always consume if it's in the direction to show the top controls.
72 if (scroll_delta.y() < 0)
73 return true;
75 if (TotalScrollOffset().y() < MaxTotalScrollOffset().y())
76 return true;
78 return false;
81 gfx::Vector2dF Viewport::AdjustOverscroll(const gfx::Vector2dF& delta) const {
82 const float kEpsilon = 0.1f;
83 gfx::Vector2dF adjusted = delta;
85 if (std::abs(adjusted.x()) < kEpsilon)
86 adjusted.set_x(0.0f);
87 if (std::abs(adjusted.y()) < kEpsilon)
88 adjusted.set_y(0.0f);
90 // Disable overscroll on axes which are impossible to scroll.
91 if (host_impl_->settings().report_overscroll_only_for_scrollable_axes) {
92 if (std::abs(MaxTotalScrollOffset().x()) <= kEpsilon ||
93 !InnerScrollLayer()->user_scrollable_horizontal())
94 adjusted.set_x(0.0f);
95 if (std::abs(MaxTotalScrollOffset().y()) <= kEpsilon ||
96 !InnerScrollLayer()->user_scrollable_vertical())
97 adjusted.set_y(0.0f);
100 return adjusted;
103 gfx::ScrollOffset Viewport::MaxTotalScrollOffset() const {
104 gfx::ScrollOffset offset;
106 offset += InnerScrollLayer()->MaxScrollOffset();
108 if (OuterScrollLayer())
109 offset += OuterScrollLayer()->MaxScrollOffset();
111 return offset;
114 gfx::ScrollOffset Viewport::TotalScrollOffset() const {
115 gfx::ScrollOffset offset;
117 offset += InnerScrollLayer()->CurrentScrollOffset();
119 if (OuterScrollLayer())
120 offset += OuterScrollLayer()->CurrentScrollOffset();
122 return offset;
125 LayerImpl* Viewport::InnerScrollLayer() const {
126 return host_impl_->InnerViewportScrollLayer();
129 LayerImpl* Viewport::OuterScrollLayer() const {
130 return host_impl_->OuterViewportScrollLayer();
133 } // namespace cc