blob: 6fbc7b9df6d684f2daee02c967c6e06c07242e55 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// Copyright 2011 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.
4
[email protected]556fd292013-03-18 08:03:045#include "cc/trees/layer_tree_host_impl.h"
[email protected]94f206c12012-08-25 00:09:146
avi02a4d172015-12-21 06:14:367#include <stddef.h>
8
danakj7b08e2862014-10-27 20:29:599#include <algorithm>
[email protected]ac7c7f52012-11-08 06:26:5010#include <cmath>
boliu7097ee5b2015-12-17 03:16:0911#include <utility>
[email protected]ac7c7f52012-11-08 06:26:5012
[email protected]59cb7b352012-10-30 06:45:4813#include "base/bind.h"
[email protected]65bfd9972012-10-19 03:39:3714#include "base/command_line.h"
skyostil0fd1dad2015-04-13 20:11:4815#include "base/location.h"
danakj60bc3bc2016-04-09 00:24:4816#include "base/memory/ptr_util.h"
gab39cb4ed72016-05-11 17:45:1917#include "base/threading/thread_task_runner_handle.h"
loysoe926437dd2016-01-14 22:55:3018#include "cc/animation/animation_events.h"
loyso2b91c082016-01-06 00:38:3819#include "cc/animation/animation_host.h"
20#include "cc/animation/animation_id_provider.h"
danakjb56d7d82015-08-28 19:28:5921#include "cc/animation/transform_operations.h"
[email protected]681ccff2013-03-18 06:13:5222#include "cc/base/math_util.h"
danakj35904762016-01-21 20:49:4023#include "cc/input/main_thread_scrolling_reason.h"
bokan915bf352014-10-02 21:57:1424#include "cc/input/page_scale_animation.h"
loyso455b4f602016-02-24 02:59:4225#include "cc/input/scrollbar_animation_controller_thinning.h"
[email protected]3052b10f2013-03-18 07:41:2126#include "cc/input/top_controls_manager.h"
[email protected]3d609bb2014-02-01 01:10:2327#include "cc/layers/append_quads_data.h"
[email protected]cc3cfaa2013-03-18 09:05:5228#include "cc/layers/heads_up_display_layer_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5229#include "cc/layers/layer_impl.h"
[email protected]3a83478b2013-08-22 20:55:1730#include "cc/layers/painted_scrollbar_layer_impl.h"
[email protected]50761e92013-03-29 20:51:2831#include "cc/layers/render_surface_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5232#include "cc/layers/solid_color_layer_impl.h"
[email protected]e6e7f292014-04-24 22:23:0333#include "cc/layers/solid_color_scrollbar_layer_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5234#include "cc/layers/texture_layer_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5235#include "cc/layers/video_layer_impl.h"
bokan499dd082015-06-24 15:35:1936#include "cc/layers/viewport.h"
[email protected]df3c24c92013-06-19 03:54:3537#include "cc/output/begin_frame_args.h"
[email protected]7f0d825f2013-03-18 07:24:3038#include "cc/output/compositor_frame_metadata.h"
[email protected]ea468c6c2013-09-10 08:25:1139#include "cc/output/copy_output_request.h"
40#include "cc/output/copy_output_result.h"
[email protected]7f0d825f2013-03-18 07:24:3041#include "cc/output/gl_renderer.h"
jamesrf313a212015-03-16 21:27:3742#include "cc/output/latency_info_swap_promise.h"
[email protected]89e82672013-03-18 07:50:5643#include "cc/quads/render_pass_draw_quad.h"
44#include "cc/quads/solid_color_draw_quad.h"
45#include "cc/quads/texture_draw_quad.h"
46#include "cc/quads/tile_draw_quad.h"
[email protected]101441ce2012-10-16 01:45:0347#include "cc/test/animation_test_common.h"
[email protected]04c5900d2014-08-18 13:38:3648#include "cc/test/begin_frame_args_test.h"
[email protected]222c6782013-09-05 22:24:4949#include "cc/test/fake_layer_tree_host_impl.h"
ajumad9432e32015-11-30 19:43:4450#include "cc/test/fake_mask_layer_impl.h"
[email protected]a46f32932012-12-07 21:43:1651#include "cc/test/fake_output_surface.h"
[email protected]0634cdd42013-08-16 00:46:0952#include "cc/test/fake_output_surface_client.h"
[email protected]46b79d52013-09-07 04:29:2953#include "cc/test/fake_picture_layer_impl.h"
vmpstr41d68f882016-03-30 01:20:2354#include "cc/test/fake_raster_source.h"
[email protected]d993b602013-01-04 02:08:1255#include "cc/test/fake_video_frame_provider.h"
[email protected]101441ce2012-10-16 01:45:0356#include "cc/test/geometry_test_utils.h"
senorblancofb88a4e2015-05-08 17:28:4157#include "cc/test/gpu_rasterization_enabled_settings.h"
[email protected]101441ce2012-10-16 01:45:0358#include "cc/test/layer_test_common.h"
awoloszyne83f28c2014-12-22 15:40:0059#include "cc/test/layer_tree_test.h"
danakjf33ceec2016-07-20 20:04:4560#include "cc/test/test_delegating_output_surface.h"
reveman22dd9292014-10-13 20:52:0561#include "cc/test/test_gpu_memory_buffer_manager.h"
[email protected]4e2eb352014-03-20 17:25:4562#include "cc/test/test_shared_bitmap_manager.h"
reveman34b7a1522015-03-23 20:27:4763#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5964#include "cc/test/test_web_graphics_context_3d.h"
trchendba8b1502016-07-08 09:47:0165#include "cc/trees/effect_node.h"
danakj94b7e4f2016-07-20 01:49:3866#include "cc/trees/layer_tree_host_common.h"
[email protected]556fd292013-03-18 08:03:0467#include "cc/trees/layer_tree_impl.h"
68#include "cc/trees/single_thread_proxy.h"
trchendba8b1502016-07-08 09:47:0169#include "cc/trees/transform_node.h"
[email protected]59cb7b352012-10-30 06:45:4870#include "media/base/media.h"
[email protected]7f0c53db2012-10-02 00:23:1871#include "testing/gmock/include/gmock/gmock.h"
72#include "testing/gtest/include/gtest/gtest.h"
[email protected]7bc1c512014-01-23 01:15:2773#include "third_party/skia/include/core/SkMallocPixelRef.h"
heejin.r.chungd28506ba2014-10-23 16:36:2074#include "ui/gfx/geometry/rect_conversions.h"
75#include "ui/gfx/geometry/size_conversions.h"
76#include "ui/gfx/geometry/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1477
boliu7097ee5b2015-12-17 03:16:0978#define EXPECT_SCOPED(statements) \
79 { \
80 SCOPED_TRACE(""); \
81 statements; \
82 }
83
[email protected]94f206c12012-08-25 00:09:1484using ::testing::Mock;
85using ::testing::Return;
86using ::testing::AnyNumber;
87using ::testing::AtLeast;
88using ::testing::_;
[email protected]568285b2013-01-07 23:19:1989using media::VideoFrame;
[email protected]94f206c12012-08-25 00:09:1490
[email protected]ba565742012-11-10 09:29:4891namespace cc {
[email protected]94f206c12012-08-25 00:09:1492namespace {
93
[email protected]c2d0c5a2013-02-26 04:43:3694class LayerTreeHostImplTest : public testing::Test,
[email protected]9bdcfd642012-11-14 21:24:2695 public LayerTreeHostImplClient {
[email protected]aa043632013-03-25 03:39:4296 public:
97 LayerTreeHostImplTest()
khushalsagarb7db1fe2015-11-12 00:51:2798 : task_runner_provider_(base::ThreadTaskRunnerHandle::Get()),
khushalsagarb64b360d2015-10-21 19:25:1699 always_main_thread_blocked_(&task_runner_provider_),
[email protected]aa043632013-03-25 03:39:42100 on_can_draw_state_changed_called_(false),
[email protected]4f48f6e2013-08-27 06:33:38101 did_notify_ready_to_activate_(false),
[email protected]aa043632013-03-25 03:39:42102 did_request_commit_(false),
103 did_request_redraw_(false),
danakja18e826a2015-12-03 00:27:03104 did_request_next_frame_(false),
vmiura59ea9b4042014-12-09 20:50:39105 did_request_prepare_tiles_(false),
rouslanf7ebd8832015-01-22 01:54:14106 did_complete_page_scale_animation_(false),
danakjaecfcfba2016-09-07 22:33:18107 reduce_memory_result_(true) {
chcunninghamfd11b3c2015-06-09 02:09:42108 media::InitializeMediaLibrary();
[email protected]aa043632013-03-25 03:39:42109 }
[email protected]1c0c9bc2012-10-08 22:41:48110
[email protected]ce2e8112013-11-28 07:44:36111 LayerTreeSettings DefaultSettings() {
[email protected]96baf3e2012-10-22 23:09:55112 LayerTreeSettings settings;
[email protected]aa043632013-03-25 03:39:42113 settings.minimum_occlusion_tracking_size = gfx::Size();
jbaumanc5be44c2014-11-20 22:17:12114 settings.renderer_settings.texture_id_allocation_chunk_size = 1;
senorblanco8d1b3ac2015-05-05 00:14:26115 settings.gpu_rasterization_enabled = true;
weiliangc365a6fe2016-05-12 19:32:31116 settings.verify_clip_tree_calculations = true;
jaydasika7de66e952016-07-01 01:36:48117 settings.verify_transform_tree_calculations = true;
ericrk9151705c2016-07-26 19:53:16118 settings.renderer_settings.buffer_to_texture_target_map =
119 DefaultBufferToTextureTargetMapForTesting();
[email protected]ce2e8112013-11-28 07:44:36120 return settings;
121 }
[email protected]94f206c12012-08-25 00:09:14122
danakjaeb95062014-11-14 01:35:36123 void SetUp() override {
[email protected]ce2e8112013-11-28 07:44:36124 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
[email protected]aa043632013-03-25 03:39:42125 }
[email protected]94f206c12012-08-25 00:09:14126
danakjee6547a22016-07-01 20:41:50127 void TearDown() override {
128 if (host_impl_)
129 host_impl_->ReleaseOutputSurface();
130 }
[email protected]94f206c12012-08-25 00:09:14131
dcheng716bedf2014-10-21 09:51:08132 void DidLoseOutputSurfaceOnImplThread() override {}
enne19c108582016-04-14 03:35:32133 void SetBeginFrameSource(BeginFrameSource* source) override {}
dcheng716bedf2014-10-21 09:51:08134 void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override {}
dcheng716bedf2014-10-21 09:51:08135 void DidSwapBuffersCompleteOnImplThread() override {}
136 void OnCanDrawStateChanged(bool can_draw) override {
[email protected]aa043632013-03-25 03:39:42137 on_can_draw_state_changed_called_ = true;
138 }
dcheng716bedf2014-10-21 09:51:08139 void NotifyReadyToActivate() override {
[email protected]4f48f6e2013-08-27 06:33:38140 did_notify_ready_to_activate_ = true;
[email protected]fc20d142014-07-01 00:49:15141 host_impl_->ActivateSyncTree();
[email protected]aa043632013-03-25 03:39:42142 }
ernstmdfac03e2014-11-11 20:18:05143 void NotifyReadyToDraw() override {}
dcheng716bedf2014-10-21 09:51:08144 void SetNeedsRedrawOnImplThread() override { did_request_redraw_ = true; }
145 void SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) override {
[email protected]aa043632013-03-25 03:39:42146 did_request_redraw_ = true;
147 }
danakja18e826a2015-12-03 00:27:03148 void SetNeedsOneBeginImplFrameOnImplThread() override {
149 did_request_next_frame_ = true;
150 }
vmiura59ea9b4042014-12-09 20:50:39151 void SetNeedsPrepareTilesOnImplThread() override {
152 did_request_prepare_tiles_ = true;
[email protected]c48536a52013-09-14 00:02:08153 }
dcheng716bedf2014-10-21 09:51:08154 void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; }
sunnyps7d073dc2015-04-16 23:29:12155 void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {}
dcheng716bedf2014-10-21 09:51:08156 void PostAnimationEventsToMainThreadOnImplThread(
danakj60bc3bc2016-04-09 00:24:48157 std::unique_ptr<AnimationEvents> events) override {}
dcheng716bedf2014-10-21 09:51:08158 bool IsInsideDraw() override { return false; }
159 void RenewTreePriority() override {}
sunnypsae4316a2015-02-25 00:54:58160 void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
dcheng716bedf2014-10-21 09:51:08161 base::TimeDelta delay) override {
sunnypsae4316a2015-02-25 00:54:58162 animation_task_ = task;
163 requested_animation_delay_ = delay;
[email protected]930ff43b2014-05-02 05:24:00164 }
dcheng716bedf2014-10-21 09:51:08165 void DidActivateSyncTree() override {}
brianderson68749812015-07-07 22:39:39166 void WillPrepareTiles() override {}
vmiura59ea9b4042014-12-09 20:50:39167 void DidPrepareTiles() override {}
rouslanf7ebd8832015-01-22 01:54:14168 void DidCompletePageScaleAnimationOnImplThread() override {
169 did_complete_page_scale_animation_ = true;
170 }
boliu7097ee5b2015-12-17 03:16:09171 void OnDrawForOutputSurface(bool resourceless_software_draw) override {
danakj60bc3bc2016-04-09 00:24:48172 std::unique_ptr<LayerTreeHostImpl::FrameData> frame(
boliu7097ee5b2015-12-17 03:16:09173 new LayerTreeHostImpl::FrameData);
danakj74af409e2016-07-01 00:41:48174 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(frame.get()));
boliu7097ee5b2015-12-17 03:16:09175 last_on_draw_render_passes_.clear();
176 RenderPass::CopyAll(frame->render_passes, &last_on_draw_render_passes_);
danakjaecfcfba2016-09-07 22:33:18177 host_impl_->DrawLayers(frame.get());
boliu7097ee5b2015-12-17 03:16:09178 host_impl_->DidDrawAllLayers(*frame);
boliu7097ee5b2015-12-17 03:16:09179 last_on_draw_frame_ = std::move(frame);
180 }
[email protected]aa043632013-03-25 03:39:42181
182 void set_reduce_memory_result(bool reduce_memory_result) {
183 reduce_memory_result_ = reduce_memory_result;
184 }
185
dtrainorcb7779b82014-12-04 01:08:02186 virtual bool CreateHostImpl(const LayerTreeSettings& settings,
danakj60bc3bc2016-04-09 00:24:48187 std::unique_ptr<OutputSurface> output_surface) {
danakja18e826a2015-12-03 00:27:03188 return CreateHostImplWithTaskRunnerProvider(
189 settings, std::move(output_surface), &task_runner_provider_);
190 }
191
192 virtual bool CreateHostImplWithTaskRunnerProvider(
193 const LayerTreeSettings& settings,
danakj60bc3bc2016-04-09 00:24:48194 std::unique_ptr<OutputSurface> output_surface,
danakja18e826a2015-12-03 00:27:03195 TaskRunnerProvider* task_runner_provider) {
danakjee6547a22016-07-01 20:41:50196 if (host_impl_)
197 host_impl_->ReleaseOutputSurface();
reveman34b7a1522015-03-23 20:27:47198 host_impl_ = LayerTreeHostImpl::Create(
danakja18e826a2015-12-03 00:27:03199 settings, this, task_runner_provider, &stats_instrumentation_,
danakjcf610582015-06-16 22:48:56200 &shared_bitmap_manager_, &gpu_memory_buffer_manager_,
loysoab32ee72016-06-08 03:33:18201 &task_graph_runner_,
202 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
danakja04855a2015-11-18 20:39:10203 output_surface_ = std::move(output_surface);
sievers71c62dd52015-10-07 01:44:39204 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:43205 bool init = host_impl_->InitializeRenderer(output_surface_.get());
[email protected]18ce59702013-04-09 04:58:40206 host_impl_->SetViewportSize(gfx::Size(10, 10));
bokan0c33a092015-07-29 18:27:56207 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
mithro0bdb49d2015-05-27 13:08:01208 // Set the BeginFrameArgs so that methods which use it are able to.
danakj12e2f6e2015-08-19 22:25:44209 host_impl_->WillBeginImplFrame(CreateBeginFrameArgsForTesting(
210 BEGINFRAME_FROM_HERE,
211 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
212 host_impl_->DidFinishImplFrame();
loyso2b91c082016-01-06 00:38:38213
loyso9556c732016-03-11 07:54:58214 timeline_ =
215 AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
216 host_impl_->animation_host()->AddAnimationTimeline(timeline_);
loyso2b91c082016-01-06 00:38:38217
[email protected]ce2e8112013-11-28 07:44:36218 return init;
[email protected]aa043632013-03-25 03:39:42219 }
220
danakj60bc3bc2016-04-09 00:24:48221 void SetupRootLayerImpl(std::unique_ptr<LayerImpl> root) {
[email protected]aa043632013-03-25 03:39:42222 root->SetPosition(gfx::PointF());
223 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:42224 root->SetDrawsContent(true);
danakj64767d902015-06-19 00:10:43225 root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
jaydasika6b5a32bf2016-04-22 21:56:36226 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:59227 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
[email protected]aa043632013-03-25 03:39:42228 }
229
sunxdb7e79432016-03-09 21:13:42230 static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) {
sunxdc044b11a2016-03-16 16:23:20231 gfx::ScrollOffset delta =
232 layer_impl->layer_tree_impl()
233 ->property_trees()
234 ->scroll_tree.GetScrollOffsetDeltaForTesting(layer_impl->id());
235 return gfx::Vector2dF(delta.x(), delta.y());
sunxdb7e79432016-03-09 21:13:42236 }
237
sunxdb2e13c92016-04-23 01:00:05238 static void ExpectClearedScrollDeltasRecursive(LayerImpl* root) {
239 for (auto* layer : *root->layer_tree_impl())
240 ASSERT_EQ(ScrollDelta(layer), gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:42241 }
242
tdresser99977952015-07-02 19:49:18243 static ::testing::AssertionResult ScrollInfoContains(
244 const ScrollAndScaleSet& scroll_info,
245 int id,
246 const gfx::Vector2d& scroll_delta) {
[email protected]aa043632013-03-25 03:39:42247 int times_encountered = 0;
248
249 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
250 if (scroll_info.scrolls[i].layer_id != id)
251 continue;
tdresser99977952015-07-02 19:49:18252
253 if (scroll_delta != scroll_info.scrolls[i].scroll_delta) {
254 return ::testing::AssertionFailure()
255 << "Expected " << scroll_delta.ToString() << ", not "
256 << scroll_info.scrolls[i].scroll_delta.ToString();
257 }
[email protected]aa043632013-03-25 03:39:42258 times_encountered++;
259 }
260
bokan4222c272016-07-18 17:24:54261 if (id == scroll_info.inner_viewport_scroll.layer_id) {
262 if (scroll_delta != scroll_info.inner_viewport_scroll.scroll_delta) {
263 return ::testing::AssertionFailure()
264 << "Expected " << scroll_delta.ToString() << ", not "
265 << scroll_info.inner_viewport_scroll.scroll_delta.ToString();
266 }
267 times_encountered++;
268 }
269
tdresser99977952015-07-02 19:49:18270 if (times_encountered != 1)
271 return ::testing::AssertionFailure() << "No layer found with id " << id;
272 return ::testing::AssertionSuccess();
[email protected]aa043632013-03-25 03:39:42273 }
274
275 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
276 int times_encountered = 0;
277
278 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
279 if (scroll_info.scrolls[i].layer_id != id)
280 continue;
281 times_encountered++;
282 }
283
284 ASSERT_EQ(0, times_encountered);
285 }
286
[email protected]7d1b07e2013-10-01 17:31:30287 LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl,
[email protected]64348ea2014-01-29 22:58:26288 const gfx::Size& content_size) {
hush33370e12015-04-07 03:49:50289 // Create both an inner viewport scroll layer and an outer viewport scroll
290 // layer. The MaxScrollOffset of the outer viewport scroll layer will be
291 // 0x0, so the scrolls will be applied directly to the inner viewport.
292 const int kOuterViewportClipLayerId = 116;
293 const int kOuterViewportScrollLayerId = 117;
294 const int kContentLayerId = 118;
[email protected]adeda572014-01-31 00:49:47295 const int kInnerViewportScrollLayerId = 2;
296 const int kInnerViewportClipLayerId = 4;
297 const int kPageScaleLayerId = 5;
hush33370e12015-04-07 03:49:50298
danakj60bc3bc2016-04-09 00:24:48299 std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
[email protected]aa043632013-03-25 03:39:42300 root->SetBounds(content_size);
[email protected]aa043632013-03-25 03:39:42301 root->SetPosition(gfx::PointF());
jaydasika6b5a32bf2016-04-22 21:56:36302 root->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:42303
danakj60bc3bc2016-04-09 00:24:48304 std::unique_ptr<LayerImpl> inner_scroll =
[email protected]adeda572014-01-31 00:49:47305 LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId);
jaydasikaca2605e2016-04-23 02:52:52306 inner_scroll->test_properties()->is_container_for_fixed_position_layers =
307 true;
sunxdb7e79432016-03-09 21:13:42308 inner_scroll->layer_tree_impl()
309 ->property_trees()
310 ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(),
311 gfx::ScrollOffset());
[email protected]adeda572014-01-31 00:49:47312
danakj60bc3bc2016-04-09 00:24:48313 std::unique_ptr<LayerImpl> inner_clip =
[email protected]adeda572014-01-31 00:49:47314 LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
hush33370e12015-04-07 03:49:50315 inner_clip->SetBounds(
[email protected]adeda572014-01-31 00:49:47316 gfx::Size(content_size.width() / 2, content_size.height() / 2));
317
danakj60bc3bc2016-04-09 00:24:48318 std::unique_ptr<LayerImpl> page_scale =
[email protected]adeda572014-01-31 00:49:47319 LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
320
hush33370e12015-04-07 03:49:50321 inner_scroll->SetScrollClipLayer(inner_clip->id());
322 inner_scroll->SetBounds(content_size);
hush33370e12015-04-07 03:49:50323 inner_scroll->SetPosition(gfx::PointF());
324
danakj60bc3bc2016-04-09 00:24:48325 std::unique_ptr<LayerImpl> outer_clip =
hush33370e12015-04-07 03:49:50326 LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
327 outer_clip->SetBounds(content_size);
jaydasikaca2605e2016-04-23 02:52:52328 outer_clip->test_properties()->is_container_for_fixed_position_layers =
329 true;
hush33370e12015-04-07 03:49:50330
danakj60bc3bc2016-04-09 00:24:48331 std::unique_ptr<LayerImpl> outer_scroll =
hush33370e12015-04-07 03:49:50332 LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
333 outer_scroll->SetScrollClipLayer(outer_clip->id());
sunxdb7e79432016-03-09 21:13:42334 outer_scroll->layer_tree_impl()
335 ->property_trees()
336 ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
337 gfx::ScrollOffset());
hush33370e12015-04-07 03:49:50338 outer_scroll->SetBounds(content_size);
hush33370e12015-04-07 03:49:50339 outer_scroll->SetPosition(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29340
danakj60bc3bc2016-04-09 00:24:48341 std::unique_ptr<LayerImpl> contents =
hush33370e12015-04-07 03:49:50342 LayerImpl::Create(layer_tree_impl, kContentLayerId);
[email protected]aa043632013-03-25 03:39:42343 contents->SetDrawsContent(true);
344 contents->SetBounds(content_size);
[email protected]aa043632013-03-25 03:39:42345 contents->SetPosition(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29346
jaydasika89f7b5a2016-06-22 02:08:39347 outer_scroll->test_properties()->AddChild(std::move(contents));
348 outer_clip->test_properties()->AddChild(std::move(outer_scroll));
349 inner_scroll->test_properties()->AddChild(std::move(outer_clip));
350 page_scale->test_properties()->AddChild(std::move(inner_scroll));
351 inner_clip->test_properties()->AddChild(std::move(page_scale));
352 root->test_properties()->AddChild(std::move(inner_clip));
[email protected]35a99a12013-05-09 23:52:29353
jaydasikabf1875a2016-06-28 03:39:59354 layer_tree_impl->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:48355 layer_tree_impl->BuildPropertyTreesForTesting();
[email protected]adeda572014-01-31 00:49:47356 layer_tree_impl->SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18357 Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId,
hush33370e12015-04-07 03:49:50358 kOuterViewportScrollLayerId);
[email protected]adeda572014-01-31 00:49:47359
hush33370e12015-04-07 03:49:50360 layer_tree_impl->DidBecomeActive();
361 return layer_tree_impl->InnerViewportScrollLayer();
[email protected]7d1b07e2013-10-01 17:31:30362 }
363
[email protected]64348ea2014-01-29 22:58:26364 LayerImpl* SetupScrollAndContentsLayers(const gfx::Size& content_size) {
[email protected]7d1b07e2013-10-01 17:31:30365 LayerImpl* scroll_layer = CreateScrollAndContentsLayers(
366 host_impl_->active_tree(), content_size);
[email protected]aa043632013-03-25 03:39:42367 host_impl_->active_tree()->DidBecomeActive();
[email protected]35a99a12013-05-09 23:52:29368 return scroll_layer;
[email protected]aa043632013-03-25 03:39:42369 }
370
bokan499dd082015-06-24 15:35:19371 // Sets up a typical virtual viewport setup with one child content layer.
372 // Returns a pointer to the content layer.
373 LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size,
374 const gfx::Size& content_size) {
375 // CreateScrollAndContentsLayers makes the outer viewport unscrollable and
376 // the inner a different size from the outer. We'll reuse its layer
377 // hierarchy but adjust the sizing to our needs.
378 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
379
jaydasikafc66cfb2016-06-10 04:34:22380 LayerImpl* content_layer = host_impl_->OuterViewportScrollLayer()
381 ->test_properties()
382 ->children.back();
bokan499dd082015-06-24 15:35:19383 content_layer->SetBounds(content_size);
384 host_impl_->OuterViewportScrollLayer()->SetBounds(content_size);
385
jaydasikaf419bf72016-06-15 10:21:21386 LayerImpl* outer_clip =
387 host_impl_->OuterViewportScrollLayer()->test_properties()->parent;
bokan499dd082015-06-24 15:35:19388 outer_clip->SetBounds(viewport_size);
389
jaydasikaf419bf72016-06-15 10:21:21390 LayerImpl* inner_clip_layer = host_impl_->InnerViewportScrollLayer()
391 ->test_properties()
392 ->parent->test_properties()
393 ->parent;
bokan499dd082015-06-24 15:35:19394 inner_clip_layer->SetBounds(viewport_size);
395 host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size);
vollickef2ae922016-06-29 17:54:27396
397 // Needs to happen before building property trees as the latter propagates
398 // these element ids to property tree nodes.
399 host_impl_->active_tree()->SetElementIdsForTesting();
danakj74af409e2016-07-01 00:41:48400 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan499dd082015-06-24 15:35:19401
402 host_impl_->SetViewportSize(viewport_size);
403 host_impl_->active_tree()->DidBecomeActive();
404
405 return content_layer;
406 }
407
danakj60bc3bc2016-04-09 00:24:48408 std::unique_ptr<LayerImpl> CreateScrollableLayer(int id,
409 const gfx::Size& size,
410 LayerImpl* clip_layer) {
[email protected]adeda572014-01-31 00:49:47411 DCHECK(clip_layer);
412 DCHECK(id != clip_layer->id());
danakj60bc3bc2016-04-09 00:24:48413 std::unique_ptr<LayerImpl> layer =
[email protected]aa043632013-03-25 03:39:42414 LayerImpl::Create(host_impl_->active_tree(), id);
[email protected]adeda572014-01-31 00:49:47415 layer->SetScrollClipLayer(clip_layer->id());
[email protected]aa043632013-03-25 03:39:42416 layer->SetDrawsContent(true);
417 layer->SetBounds(size);
[email protected]adeda572014-01-31 00:49:47418 clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2));
danakja04855a2015-11-18 20:39:10419 return layer;
[email protected]aa043632013-03-25 03:39:42420 }
421
danakj60bc3bc2016-04-09 00:24:48422 std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) {
tdresserebe6e34c2016-02-10 18:46:06423 ScrollStateData scroll_state_data;
424 scroll_state_data.is_beginning = true;
bokan578ff4a2016-04-12 21:54:05425 scroll_state_data.position_x = point.x();
426 scroll_state_data.position_y = point.y();
danakj60bc3bc2016-04-09 00:24:48427 std::unique_ptr<ScrollState> scroll_state(
428 new ScrollState(scroll_state_data));
tdresserebe6e34c2016-02-10 18:46:06429 return scroll_state;
majidvp944a8cd2016-01-12 21:05:18430 }
431
danakj60bc3bc2016-04-09 00:24:48432 std::unique_ptr<ScrollState> UpdateState(const gfx::Point& point,
433 const gfx::Vector2dF& delta) {
tdresserebe6e34c2016-02-10 18:46:06434 ScrollStateData scroll_state_data;
435 scroll_state_data.delta_x = delta.x();
436 scroll_state_data.delta_y = delta.y();
bokan578ff4a2016-04-12 21:54:05437 scroll_state_data.position_x = point.x();
438 scroll_state_data.position_y = point.y();
danakj60bc3bc2016-04-09 00:24:48439 std::unique_ptr<ScrollState> scroll_state(
440 new ScrollState(scroll_state_data));
tdresserebe6e34c2016-02-10 18:46:06441 return scroll_state;
majidvp944a8cd2016-01-12 21:05:18442 }
443
danakj60bc3bc2016-04-09 00:24:48444 std::unique_ptr<ScrollState> EndState() {
tdresserebe6e34c2016-02-10 18:46:06445 ScrollStateData scroll_state_data;
446 scroll_state_data.is_ending = true;
danakj60bc3bc2016-04-09 00:24:48447 std::unique_ptr<ScrollState> scroll_state(
448 new ScrollState(scroll_state_data));
tdresserebe6e34c2016-02-10 18:46:06449 return scroll_state;
majidvp944a8cd2016-01-12 21:05:18450 }
451
[email protected]fbe89f72013-05-21 07:24:24452 void DrawFrame() {
[email protected]aa043632013-03-25 03:39:42453 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:48454 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:45455 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:42456 host_impl_->DidDrawAllLayers(frame);
[email protected]aa043632013-03-25 03:39:42457 }
458
459 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor);
460 void pinch_zoom_pan_viewport_test(float device_scale_factor);
461 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor);
462 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
463 float device_scale_factor);
464
[email protected]bf1cfd9a2013-09-26 05:43:02465 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
466
loyso2b91c082016-01-06 00:38:38467 scoped_refptr<AnimationTimeline> timeline() { return timeline_; }
468
[email protected]aa043632013-03-25 03:39:42469 protected:
danakj60bc3bc2016-04-09 00:24:48470 virtual std::unique_ptr<OutputSurface> CreateOutputSurface() {
danakjf33ceec2016-07-20 20:04:45471 return FakeOutputSurface::CreateDelegating3d();
[email protected]aa043632013-03-25 03:39:42472 }
473
474 void DrawOneFrame() {
475 LayerTreeHostImpl::FrameData frame_data;
danakj74af409e2016-07-01 00:41:48476 host_impl_->PrepareToDraw(&frame_data);
[email protected]aa043632013-03-25 03:39:42477 host_impl_->DidDrawAllLayers(frame_data);
478 }
479
sunxdb7e79432016-03-09 21:13:42480 static void SetScrollOffsetDelta(LayerImpl* layer_impl,
481 const gfx::Vector2dF& delta) {
sunxdc044b11a2016-03-16 16:23:20482 if (layer_impl->layer_tree_impl()
483 ->property_trees()
484 ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
485 delta))
486 layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
487 layer_impl->id(), layer_impl->transform_tree_index());
sunxdb7e79432016-03-09 21:13:42488 }
489
ymalik99740e852016-04-07 04:18:13490 void BeginImplFrameAndAnimate(BeginFrameArgs begin_frame_args,
491 base::TimeTicks frame_time) {
492 begin_frame_args.frame_time = frame_time;
493 host_impl_->WillBeginImplFrame(begin_frame_args);
494 host_impl_->Animate();
495 host_impl_->UpdateAnimationState(true);
496 host_impl_->DidFinishImplFrame();
497 }
498
khushalsagarb7db1fe2015-11-12 00:51:27499 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]aa043632013-03-25 03:39:42500 DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
501
danakjcf610582015-06-16 22:48:56502 TestSharedBitmapManager shared_bitmap_manager_;
503 TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
504 TestTaskGraphRunner task_graph_runner_;
danakj60bc3bc2016-04-09 00:24:48505 std::unique_ptr<OutputSurface> output_surface_;
506 std::unique_ptr<LayerTreeHostImpl> host_impl_;
[email protected]aa043632013-03-25 03:39:42507 FakeRenderingStatsInstrumentation stats_instrumentation_;
508 bool on_can_draw_state_changed_called_;
[email protected]4f48f6e2013-08-27 06:33:38509 bool did_notify_ready_to_activate_;
[email protected]aa043632013-03-25 03:39:42510 bool did_request_commit_;
511 bool did_request_redraw_;
danakja18e826a2015-12-03 00:27:03512 bool did_request_next_frame_;
vmiura59ea9b4042014-12-09 20:50:39513 bool did_request_prepare_tiles_;
rouslanf7ebd8832015-01-22 01:54:14514 bool did_complete_page_scale_animation_;
[email protected]aa043632013-03-25 03:39:42515 bool reduce_memory_result_;
sunnypsae4316a2015-02-25 00:54:58516 base::Closure animation_task_;
517 base::TimeDelta requested_animation_delay_;
danakj60bc3bc2016-04-09 00:24:48518 std::unique_ptr<LayerTreeHostImpl::FrameData> last_on_draw_frame_;
boliu7097ee5b2015-12-17 03:16:09519 RenderPassList last_on_draw_render_passes_;
loyso2b91c082016-01-06 00:38:38520 scoped_refptr<AnimationTimeline> timeline_;
[email protected]aa043632013-03-25 03:39:42521};
522
loysoce3bb822015-07-08 02:40:47523// A test fixture for new animation timelines tests.
524class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest {
525 public:
526 void SetUp() override {
loyso0940d412016-03-14 01:30:31527 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
loysoce3bb822015-07-08 02:40:47528 }
529};
530
[email protected]6133cc232013-07-30 18:47:07531TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
boliu7097ee5b2015-12-17 03:16:09532 // Note: It is not possible to disable the renderer once it has been set,
533 // so we do not need to test that disabling the renderer notifies us
534 // that can_draw changed.
535 EXPECT_FALSE(host_impl_->CanDraw());
536 on_can_draw_state_changed_called_ = false;
537
538 // Set up the root layer, which allows us to draw.
539 SetupScrollAndContentsLayers(gfx::Size(100, 100));
540 EXPECT_TRUE(host_impl_->CanDraw());
541 EXPECT_TRUE(on_can_draw_state_changed_called_);
542 on_can_draw_state_changed_called_ = false;
543
544 // Toggle the root layer to make sure it toggles can_draw
jaydasikabf1875a2016-06-28 03:39:59545 host_impl_->active_tree()->SetRootLayerForTesting(nullptr);
rockot2176f922016-06-08 19:18:32546 host_impl_->active_tree()->DetachLayers();
boliu7097ee5b2015-12-17 03:16:09547 EXPECT_FALSE(host_impl_->CanDraw());
548 EXPECT_TRUE(on_can_draw_state_changed_called_);
549 on_can_draw_state_changed_called_ = false;
550
551 SetupScrollAndContentsLayers(gfx::Size(100, 100));
552 EXPECT_TRUE(host_impl_->CanDraw());
553 EXPECT_TRUE(on_can_draw_state_changed_called_);
554 on_can_draw_state_changed_called_ = false;
555
556 // Toggle the device viewport size to make sure it toggles can_draw.
557 host_impl_->SetViewportSize(gfx::Size());
558 EXPECT_FALSE(host_impl_->CanDraw());
559 EXPECT_TRUE(on_can_draw_state_changed_called_);
560 on_can_draw_state_changed_called_ = false;
561
562 host_impl_->SetViewportSize(gfx::Size(100, 100));
563 EXPECT_TRUE(host_impl_->CanDraw());
564 EXPECT_TRUE(on_can_draw_state_changed_called_);
565 on_can_draw_state_changed_called_ = false;
[email protected]6133cc232013-07-30 18:47:07566}
567
boliu7097ee5b2015-12-17 03:16:09568TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) {
danakjf446a072014-09-27 21:55:48569 CreateHostImpl(DefaultSettings(),
danakj6021ec32016-07-22 22:16:08570 FakeOutputSurface::CreateDelegatingSoftware());
boliu7097ee5b2015-12-17 03:16:09571 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:48572 host_impl_->active_tree()->BuildPropertyTreesForTesting();
573
boliu7097ee5b2015-12-17 03:16:09574 EXPECT_TRUE(host_impl_->CanDraw());
575 host_impl_->SetViewportSize(gfx::Size());
576 EXPECT_FALSE(host_impl_->CanDraw());
[email protected]6133cc232013-07-30 18:47:07577
boliu7097ee5b2015-12-17 03:16:09578 FakeOutputSurface* fake_output_surface =
579 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
580 EXPECT_EQ(fake_output_surface->num_sent_frames(), 0u);
581 gfx::Transform identity;
582 gfx::Rect viewport(100, 100);
583 const bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:59584 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:09585 ASSERT_EQ(fake_output_surface->num_sent_frames(), 1u);
586 EXPECT_EQ(gfx::SizeF(100.f, 100.f),
fsamueld63137a2016-06-24 23:39:51587 fake_output_surface->last_sent_frame()->metadata.root_layer_size);
[email protected]6133cc232013-07-30 18:47:07588}
589
[email protected]aa043632013-03-25 03:39:42590TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) {
jaydasikabf1875a2016-06-28 03:39:59591 ASSERT_FALSE(host_impl_->active_tree()->root_layer_for_testing());
[email protected]94f206c12012-08-25 00:09:14592
danakj60bc3bc2016-04-09 00:24:48593 std::unique_ptr<ScrollAndScaleSet> scroll_info =
594 host_impl_->ProcessScrollDeltas();
[email protected]aa043632013-03-25 03:39:42595 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
[email protected]94f206c12012-08-25 00:09:14596}
597
[email protected]aa043632013-03-25 03:39:42598TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
599 {
danakj60bc3bc2016-04-09 00:24:48600 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:42601 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika89f7b5a2016-06-22 02:08:39602 root->test_properties()->AddChild(
603 LayerImpl::Create(host_impl_->active_tree(), 2));
604 root->test_properties()->AddChild(
605 LayerImpl::Create(host_impl_->active_tree(), 3));
606 root->test_properties()->children[1]->test_properties()->AddChild(
[email protected]aa043632013-03-25 03:39:42607 LayerImpl::Create(host_impl_->active_tree(), 4));
jaydasika89f7b5a2016-06-22 02:08:39608 root->test_properties()->children[1]->test_properties()->AddChild(
[email protected]aa043632013-03-25 03:39:42609 LayerImpl::Create(host_impl_->active_tree(), 5));
jaydasikafc66cfb2016-06-10 04:34:22610 root->test_properties()
611 ->children[1]
612 ->test_properties()
613 ->children[0]
jaydasika89f7b5a2016-06-22 02:08:39614 ->test_properties()
jaydasikafc66cfb2016-06-10 04:34:22615 ->AddChild(LayerImpl::Create(host_impl_->active_tree(), 6));
jaydasikabf1875a2016-06-28 03:39:59616 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
[email protected]aa043632013-03-25 03:39:42617 }
danakj74af409e2016-07-01 00:41:48618 LayerImpl* root = *host_impl_->active_tree()->begin();
[email protected]94f206c12012-08-25 00:09:14619
[email protected]aa043632013-03-25 03:39:42620 ExpectClearedScrollDeltasRecursive(root);
[email protected]0ede3bb2012-12-09 09:14:39621
danakj60bc3bc2016-04-09 00:24:48622 std::unique_ptr<ScrollAndScaleSet> scroll_info;
[email protected]aa043632013-03-25 03:39:42623
624 scroll_info = host_impl_->ProcessScrollDeltas();
625 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
626 ExpectClearedScrollDeltasRecursive(root);
627
628 scroll_info = host_impl_->ProcessScrollDeltas();
629 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
630 ExpectClearedScrollDeltasRecursive(root);
[email protected]94f206c12012-08-25 00:09:14631}
632
[email protected]aa043632013-03-25 03:39:42633TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
miletusf57925d2014-10-01 19:38:13634 gfx::ScrollOffset scroll_offset(20, 30);
[email protected]aa043632013-03-25 03:39:42635 gfx::Vector2d scroll_delta(11, -15);
sunxd676696572016-01-07 16:28:30636
danakj74af409e2016-07-01 00:41:48637 auto root_clip_owned = LayerImpl::Create(host_impl_->active_tree(), 2);
638 auto* root_clip = root_clip_owned.get();
639 auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1);
640 auto* root = root_owned.get();
641
642 root_clip->SetBounds(gfx::Size(10, 10));
643 root_clip->test_properties()->AddChild(std::move(root_owned));
644 root->SetBounds(gfx::Size(110, 110));
645 root->SetScrollClipLayer(root_clip->id());
646 root->layer_tree_impl()
647 ->property_trees()
648 ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->id(), scroll_offset);
649 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip_owned));
650 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:14651
danakj60bc3bc2016-04-09 00:24:48652 std::unique_ptr<ScrollAndScaleSet> scroll_info;
[email protected]94f206c12012-08-25 00:09:14653
danakj74af409e2016-07-01 00:41:48654 root->ScrollBy(scroll_delta);
[email protected]aa043632013-03-25 03:39:42655 scroll_info = host_impl_->ProcessScrollDeltas();
656 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
tdresser99977952015-07-02 19:49:18657 EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), scroll_delta));
[email protected]94f206c12012-08-25 00:09:14658
[email protected]aa043632013-03-25 03:39:42659 gfx::Vector2d scroll_delta2(-5, 27);
660 root->ScrollBy(scroll_delta2);
661 scroll_info = host_impl_->ProcessScrollDeltas();
662 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
tdresser99977952015-07-02 19:49:18663 EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
664 scroll_delta + scroll_delta2));
[email protected]aa043632013-03-25 03:39:42665
666 root->ScrollBy(gfx::Vector2d());
667 scroll_info = host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:18668 EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
669 scroll_delta + scroll_delta2));
[email protected]94f206c12012-08-25 00:09:14670}
671
[email protected]aa043632013-03-25 03:39:42672TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
673 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:48674 host_impl_->active_tree()->BuildPropertyTreesForTesting();
675
[email protected]18ce59702013-04-09 04:58:40676 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36677 DrawFrame();
[email protected]94f206c12012-08-25 00:09:14678
tdresser81e84c672016-01-18 23:21:22679 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
680 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
681 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40682 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22683 status.main_thread_scrolling_reasons);
684
[email protected]edcc1a12014-05-06 01:26:39685 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
ericrk7c030992015-02-20 01:39:38686 InputHandler::WHEEL));
majidvp944a8cd2016-01-12 21:05:18687 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
[email protected]edcc1a12014-05-06 01:26:39688 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
ericrk7c030992015-02-20 01:39:38689 InputHandler::WHEEL));
majidvp944a8cd2016-01-12 21:05:18690 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:49691 host_impl_->ClearCurrentlyScrollingLayerForTesting();
[email protected]edcc1a12014-05-06 01:26:39692 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
ericrk7c030992015-02-20 01:39:38693 InputHandler::WHEEL));
[email protected]aa043632013-03-25 03:39:42694 EXPECT_TRUE(did_request_redraw_);
695 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:14696}
697
jdduke16dde6e2014-10-24 00:22:56698TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) {
699 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:48700 host_impl_->active_tree()->BuildPropertyTreesForTesting();
701
jdduke16dde6e2014-10-24 00:22:56702 host_impl_->SetViewportSize(gfx::Size(50, 50));
703 DrawFrame();
704
tdresser81e84c672016-01-18 23:21:22705 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
706 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
707 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40708 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22709 status.main_thread_scrolling_reasons);
710
jdduke16dde6e2014-10-24 00:22:56711 EXPECT_FALSE(host_impl_->IsActivelyScrolling());
majidvp944a8cd2016-01-12 21:05:18712 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
jdduke16dde6e2014-10-24 00:22:56713 EXPECT_TRUE(host_impl_->IsActivelyScrolling());
majidvp944a8cd2016-01-12 21:05:18714 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:49715 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke16dde6e2014-10-24 00:22:56716 EXPECT_FALSE(host_impl_->IsActivelyScrolling());
717}
718
[email protected]aa043632013-03-25 03:39:42719TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
720 // We should not crash when trying to scroll an empty layer tree.
tdresser81e84c672016-01-18 23:21:22721 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
722 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
723 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40724 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22725 status.main_thread_scrolling_reasons);
[email protected]94f206c12012-08-25 00:09:14726}
727
[email protected]aa043632013-03-25 03:39:42728TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
danakj60bc3bc2016-04-09 00:24:48729 std::unique_ptr<TestWebGraphicsContext3D> context_owned =
[email protected]0634cdd42013-08-16 00:46:09730 TestWebGraphicsContext3D::Create();
[email protected]c9addd12013-12-08 22:43:26731 context_owned->set_context_lost(true);
[email protected]0634cdd42013-08-16 00:46:09732
[email protected]ce2e8112013-11-28 07:44:36733 // Initialization will fail.
danakjf33ceec2016-07-20 20:04:45734 EXPECT_FALSE(CreateHostImpl(
735 DefaultSettings(),
736 FakeOutputSurface::CreateDelegating3d(std::move(context_owned))));
[email protected]a90aa702012-11-07 04:48:24737
[email protected]aa043632013-03-25 03:39:42738 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:14739
[email protected]aa043632013-03-25 03:39:42740 // We should not crash when trying to scroll after the renderer initialization
741 // fails.
tdresser81e84c672016-01-18 23:21:22742 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
743 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
744 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40745 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22746 status.main_thread_scrolling_reasons);
[email protected]94f206c12012-08-25 00:09:14747}
748
[email protected]aa043632013-03-25 03:39:42749TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
[email protected]35a99a12013-05-09 23:52:29750 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40751 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36752 DrawFrame();
[email protected]a9710962012-11-14 20:11:02753
[email protected]aa043632013-03-25 03:39:42754 // We should not crash if the tree is replaced while we are scrolling.
tdresser81e84c672016-01-18 23:21:22755 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:18756 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:22757 InputHandler::WHEEL)
758 .thread);
rockot2176f922016-06-08 19:18:32759 host_impl_->active_tree()->DetachLayers();
[email protected]aa043632013-03-25 03:39:42760
[email protected]35a99a12013-05-09 23:52:29761 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42762
763 // We should still be scrolling, because the scrolled layer also exists in the
764 // new tree.
765 gfx::Vector2d scroll_delta(0, 10);
majidvp944a8cd2016-01-12 21:05:18766 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
767 host_impl_->ScrollEnd(EndState().get());
danakj60bc3bc2016-04-09 00:24:48768 std::unique_ptr<ScrollAndScaleSet> scroll_info =
769 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:18770 EXPECT_TRUE(
771 ScrollInfoContains(*scroll_info, scroll_layer->id(), scroll_delta));
[email protected]aa043632013-03-25 03:39:42772}
773
rbyers18779d822015-02-05 06:22:06774TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) {
[email protected]aa043632013-03-25 03:39:42775 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40776 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36777 DrawFrame();
[email protected]aa043632013-03-25 03:39:42778
dtapuskae7dd21de2016-06-09 13:41:56779 // Wheel handlers determine whether mouse events block scroll.
dtapuskaf206a40d2016-02-05 21:36:02780 host_impl_->active_tree()->set_event_listener_properties(
781 EventListenerClass::kMouseWheel, EventListenerProperties::kBlocking);
dtapuskae7dd21de2016-06-09 13:41:56782 EXPECT_EQ(
783 EventListenerProperties::kBlocking,
784 host_impl_->GetEventListenerProperties(EventListenerClass::kMouseWheel));
785
786 // But they don't influence the actual handling of the scroll gestures.
dtapuskacd4231232016-01-28 19:18:11787 InputHandler::ScrollStatus status =
788 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:22789 InputHandler::WHEEL);
tdresser81e84c672016-01-18 23:21:22790 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40791 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22792 status.main_thread_scrolling_reasons);
majidvp944a8cd2016-01-12 21:05:18793 host_impl_->ScrollEnd(EndState().get());
rbyers18779d822015-02-05 06:22:06794}
795
796TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) {
797 LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100));
798 host_impl_->SetViewportSize(gfx::Size(50, 50));
799 DrawFrame();
jaydasikabf1875a2016-06-28 03:39:59800 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
rbyers18779d822015-02-05 06:22:06801
802 LayerImpl* child = 0;
803 {
danakj60bc3bc2016-04-09 00:24:48804 std::unique_ptr<LayerImpl> child_layer =
rbyers18779d822015-02-05 06:22:06805 LayerImpl::Create(host_impl_->active_tree(), 6);
806 child = child_layer.get();
807 child_layer->SetDrawsContent(true);
808 child_layer->SetPosition(gfx::PointF(0, 20));
809 child_layer->SetBounds(gfx::Size(50, 50));
jaydasika89f7b5a2016-06-22 02:08:39810 scroll->test_properties()->AddChild(std::move(child_layer));
danakj74af409e2016-07-01 00:41:48811 host_impl_->active_tree()->BuildPropertyTreesForTesting();
rbyers18779d822015-02-05 06:22:06812 }
813
814 // Touch handler regions determine whether touch events block scroll.
815 root->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
rbyers18779d822015-02-05 06:22:06816 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10)));
817
818 // But they don't influence the actual handling of the scroll gestures.
tdresser81e84c672016-01-18 23:21:22819 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
dtapuska40e8aff2016-03-11 21:45:03820 BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22821 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40822 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22823 status.main_thread_scrolling_reasons);
majidvp944a8cd2016-01-12 21:05:18824 host_impl_->ScrollEnd(EndState().get());
rbyers18779d822015-02-05 06:22:06825
rbyers18779d822015-02-05 06:22:06826 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
dtapuskacd4231232016-01-28 19:18:11827 root->SetTouchEventHandlerRegion(gfx::Rect());
rbyers18779d822015-02-05 06:22:06828 EXPECT_FALSE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
dtapuskacd4231232016-01-28 19:18:11829 child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
rbyers18779d822015-02-05 06:22:06830 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
831}
832
[email protected]7c45d8152013-04-23 18:27:21833TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) {
834 SetupScrollAndContentsLayers(gfx::Size(100, 100));
835 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36836 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21837
838 // Ignore the fling since no layer is being scrolled
tdresser81e84c672016-01-18 23:21:22839 InputHandler::ScrollStatus status = host_impl_->FlingScrollBegin();
840 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40841 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22842 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21843
844 // Start scrolling a layer
tdresser81e84c672016-01-18 23:21:22845 status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:03846 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22847 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40848 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22849 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21850
851 // Now the fling should go ahead since we've started scrolling a layer
tdresser81e84c672016-01-18 23:21:22852 status = host_impl_->FlingScrollBegin();
853 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40854 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22855 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21856}
857
858TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) {
859 SetupScrollAndContentsLayers(gfx::Size(100, 100));
860 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36861 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21862
863 // Ignore the fling since no layer is being scrolled
tdresser81e84c672016-01-18 23:21:22864 InputHandler::ScrollStatus status = host_impl_->FlingScrollBegin();
865 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40866 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22867 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21868
869 // Start scrolling a layer
tdresser81e84c672016-01-18 23:21:22870 status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
871 InputHandler::WHEEL);
872 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40873 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22874 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21875
876 // Now the fling should go ahead since we've started scrolling a layer
tdresser81e84c672016-01-18 23:21:22877 status = host_impl_->FlingScrollBegin();
878 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40879 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22880 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21881}
882
883TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) {
884 SetupScrollAndContentsLayers(gfx::Size(100, 100));
885 host_impl_->SetViewportSize(gfx::Size(50, 50));
jaydasikabf1875a2016-06-28 03:39:59886 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]7c45d8152013-04-23 18:27:21887
tdresser81e84c672016-01-18 23:21:22888 root->set_main_thread_scrolling_reasons(
danakj35904762016-01-21 20:49:40889 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
danakj74af409e2016-07-01 00:41:48890 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]7c45d8152013-04-23 18:27:21891
sunxdd1abacf2016-02-16 22:08:30892 DrawFrame();
893
[email protected]7c45d8152013-04-23 18:27:21894 // Start scrolling a layer
tdresser81e84c672016-01-18 23:21:22895 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
dtapuska40e8aff2016-03-11 21:45:03896 BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22897 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:40898 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:22899 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21900
901 // The fling should be ignored since there's no layer being scrolled impl-side
tdresser81e84c672016-01-18 23:21:22902 status = host_impl_->FlingScrollBegin();
903 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40904 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22905 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21906}
907
[email protected]aa043632013-03-25 03:39:42908TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
909 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40910 host_impl_->SetViewportSize(gfx::Size(50, 50));
jaydasikabf1875a2016-06-28 03:39:59911 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]aa043632013-03-25 03:39:42912
tdresser81e84c672016-01-18 23:21:22913 root->set_main_thread_scrolling_reasons(
danakj35904762016-01-21 20:49:40914 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
danakj74af409e2016-07-01 00:41:48915 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxdd1abacf2016-02-16 22:08:30916 DrawFrame();
[email protected]aa043632013-03-25 03:39:42917
tdresser81e84c672016-01-18 23:21:22918 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
919 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
920 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:40921 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:22922 status.main_thread_scrolling_reasons);
923
924 status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:03925 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22926 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:40927 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:22928 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:42929}
930
sunxd0b34eb52016-04-13 01:13:39931TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) {
932 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
933 gfx::Size content_size = gfx::Size(360, 600);
934 gfx::Size scroll_content_size = gfx::Size(345, 3800);
935 gfx::Size scrollbar_size = gfx::Size(15, 600);
936
937 host_impl_->SetViewportSize(content_size);
938 std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
939 root->SetBounds(content_size);
940 root->SetPosition(gfx::PointF());
941
942 std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2);
943 clip->SetBounds(content_size);
944 clip->SetPosition(gfx::PointF());
945
946 std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
947 scroll->SetBounds(scroll_content_size);
948 scroll->SetScrollClipLayer(clip->id());
949 scroll->SetDrawsContent(true);
950
951 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
952 SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0,
953 false, true);
954 scrollbar->SetBounds(scrollbar_size);
955 scrollbar->SetPosition(gfx::PointF(345, 0));
956 scrollbar->SetScrollLayerId(scroll->id());
sunxd0b34eb52016-04-13 01:13:39957 scrollbar->SetDrawsContent(true);
jaydasikaab317e02016-06-01 00:53:18958 scrollbar->test_properties()->opacity = 1.f;
sunxd0b34eb52016-04-13 01:13:39959
960 std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5);
961 squash1->SetBounds(gfx::Size(140, 300));
962 squash1->SetPosition(gfx::PointF(220, 0));
963 squash1->SetDrawsContent(true);
964
965 std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6);
966 squash2->SetBounds(gfx::Size(140, 300));
967 squash2->SetPosition(gfx::PointF(220, 300));
968 squash2->SetDrawsContent(true);
969
jaydasika89f7b5a2016-06-22 02:08:39970 scroll->test_properties()->AddChild(std::move(squash2));
971 clip->test_properties()->AddChild(std::move(scroll));
972 clip->test_properties()->AddChild(std::move(scrollbar));
973 clip->test_properties()->AddChild(std::move(squash1));
974 root->test_properties()->AddChild(std::move(clip));
sunxd0b34eb52016-04-13 01:13:39975
jaydasikabf1875a2016-06-28 03:39:59976 layer_tree_impl->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:48977 layer_tree_impl->BuildPropertyTreesForTesting();
sunxd0b34eb52016-04-13 01:13:39978 layer_tree_impl->DidBecomeActive();
979
980 // The point hits squash1 layer and also scroll layer, because scroll layer is
981 // not an ancestor of squash1 layer, we cannot scroll on impl thread.
982 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
983 BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL);
984 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
985 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
986 status.main_thread_scrolling_reasons);
987
988 // The point hits squash1 layer and also scrollbar layer.
989 status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(),
990 InputHandler::WHEEL);
991 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
992 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
993 status.main_thread_scrolling_reasons);
994
995 // The point hits squash2 layer and also scroll layer, because scroll layer is
996 // an ancestor of squash2 layer, we should scroll on impl.
997 status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(),
998 InputHandler::WHEEL);
999 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
1000}
1001
[email protected]aa043632013-03-25 03:39:421002TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
1003 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:401004 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:421005
jaydasikabf1875a2016-06-28 03:39:591006 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]aa043632013-03-25 03:39:421007 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
1008
danakj74af409e2016-07-01 00:41:481009 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ce2e8112013-11-28 07:44:361010 DrawFrame();
[email protected]aa043632013-03-25 03:39:421011
1012 // All scroll types inside the non-fast scrollable region should fail.
tdresser81e84c672016-01-18 23:21:221013 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
1014 BeginState(gfx::Point(25, 25)).get(), InputHandler::WHEEL);
1015 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:401016 EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
tdresser81e84c672016-01-18 23:21:221017 status.main_thread_scrolling_reasons);
[email protected]edcc1a12014-05-06 01:26:391018 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
ericrk7c030992015-02-20 01:39:381019 InputHandler::WHEEL));
tdresser81e84c672016-01-18 23:21:221020
1021 status = host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(),
dtapuska40e8aff2016-03-11 21:45:031022 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:221023 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:401024 EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
tdresser81e84c672016-01-18 23:21:221025 status.main_thread_scrolling_reasons);
dtapuska40e8aff2016-03-11 21:45:031026 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1027 gfx::Point(25, 25), InputHandler::TOUCHSCREEN));
[email protected]aa043632013-03-25 03:39:421028
1029 // All scroll types outside this region should succeed.
tdresser81e84c672016-01-18 23:21:221030 status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
1031 InputHandler::WHEEL);
1032 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401033 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221034 status.main_thread_scrolling_reasons);
1035
dtapuska40e8aff2016-03-11 21:45:031036 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
1037 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
majidvp944a8cd2016-01-12 21:05:181038 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
dtapuska40e8aff2016-03-11 21:45:031039 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1040 gfx::Point(25, 25), InputHandler::TOUCHSCREEN));
majidvp944a8cd2016-01-12 21:05:181041 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:491042 host_impl_->ClearCurrentlyScrollingLayerForTesting();
dtapuska40e8aff2016-03-11 21:45:031043 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1044 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
tdresser81e84c672016-01-18 23:21:221045
1046 status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
dtapuska40e8aff2016-03-11 21:45:031047 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:221048 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401049 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221050 status.main_thread_scrolling_reasons);
dtapuska40e8aff2016-03-11 21:45:031051 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
1052 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
majidvp944a8cd2016-01-12 21:05:181053 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
1054 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:491055 host_impl_->ClearCurrentlyScrollingLayerForTesting();
dtapuska40e8aff2016-03-11 21:45:031056 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1057 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
[email protected]aa043632013-03-25 03:39:421058}
1059
1060TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
1061 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:401062 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:421063
danakj74af409e2016-07-01 00:41:481064 LayerImpl* root = *host_impl_->active_tree()->begin();
[email protected]aa043632013-03-25 03:39:421065 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
1066 root->SetPosition(gfx::PointF(-25.f, 0.f));
jaydasikad7dea632015-11-06 04:40:121067 root->SetDrawsContent(true);
[email protected]aa043632013-03-25 03:39:421068
danakj74af409e2016-07-01 00:41:481069 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ce2e8112013-11-28 07:44:361070 DrawFrame();
[email protected]aa043632013-03-25 03:39:421071
1072 // This point would fall into the non-fast scrollable region except that we've
1073 // moved the layer down by 25 pixels.
tdresser81e84c672016-01-18 23:21:221074 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
1075 BeginState(gfx::Point(40, 10)).get(), InputHandler::WHEEL);
1076 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401077 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221078 status.main_thread_scrolling_reasons);
1079
[email protected]edcc1a12014-05-06 01:26:391080 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
ericrk7c030992015-02-20 01:39:381081 InputHandler::WHEEL));
majidvp944a8cd2016-01-12 21:05:181082 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 1)).get());
1083 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:421084
1085 // This point is still inside the non-fast region.
tdresser81e84c672016-01-18 23:21:221086 status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
1087 InputHandler::WHEEL);
1088 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:401089 EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
tdresser81e84c672016-01-18 23:21:221090 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:421091}
1092
[email protected]f161ca9e2014-04-01 13:57:011093TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) {
dtapuskaf024e552016-02-03 01:19:461094 SetupScrollAndContentsLayers(gfx::Size(200, 200));
1095 EXPECT_FALSE(host_impl_->active_tree()->have_scroll_event_handlers());
[email protected]f161ca9e2014-04-01 13:57:011096 host_impl_->SetViewportSize(gfx::Size(50, 50));
1097 DrawFrame();
1098
1099 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181100 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:031101 InputHandler::TOUCHSCREEN);
[email protected]f161ca9e2014-04-01 13:57:011102 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181103 host_impl_->ScrollEnd(EndState().get());
[email protected]f161ca9e2014-04-01 13:57:011104 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
1105}
1106
1107TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) {
dtapuskaf024e552016-02-03 01:19:461108 SetupScrollAndContentsLayers(gfx::Size(200, 200));
1109 host_impl_->active_tree()->set_have_scroll_event_handlers(true);
[email protected]f161ca9e2014-04-01 13:57:011110 host_impl_->SetViewportSize(gfx::Size(50, 50));
1111 DrawFrame();
1112
1113 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181114 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:031115 InputHandler::TOUCHSCREEN);
[email protected]f161ca9e2014-04-01 13:57:011116 EXPECT_TRUE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181117 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:491118 host_impl_->ClearCurrentlyScrollingLayerForTesting();
[email protected]f161ca9e2014-04-01 13:57:011119 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
1120}
1121
[email protected]aa043632013-03-25 03:39:421122TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
1123 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:401124 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:421125
[email protected]ce2e8112013-11-28 07:44:361126 DrawFrame();
[email protected]aa043632013-03-25 03:39:421127
tdresser81e84c672016-01-18 23:21:221128 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
dtapuska40e8aff2016-03-11 21:45:031129 BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:221130 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401131 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221132 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:421133
1134 // Trying to scroll to the left/top will not succeed.
ccameron36d091f2014-11-07 03:18:501135 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:181136 host_impl_->ScrollBy(
1137 UpdateState(gfx::Point(), gfx::Vector2d(-10, 0)).get())
1138 .did_scroll);
ccameron36d091f2014-11-07 03:18:501139 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:181140 host_impl_->ScrollBy(
1141 UpdateState(gfx::Point(), gfx::Vector2d(0, -10)).get())
1142 .did_scroll);
ccameron36d091f2014-11-07 03:18:501143 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:181144 host_impl_->ScrollBy(
1145 UpdateState(gfx::Point(), gfx::Vector2d(-10, -10)).get())
1146 .did_scroll);
[email protected]aa043632013-03-25 03:39:421147
1148 // Scrolling to the right/bottom will succeed.
ccameron36d091f2014-11-07 03:18:501149 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181150 host_impl_->ScrollBy(
1151 UpdateState(gfx::Point(), gfx::Vector2d(10, 0)).get())
1152 .did_scroll);
ccameron36d091f2014-11-07 03:18:501153 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181154 host_impl_->ScrollBy(
1155 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
1156 .did_scroll);
ccameron36d091f2014-11-07 03:18:501157 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181158 host_impl_->ScrollBy(
1159 UpdateState(gfx::Point(), gfx::Vector2d(10, 10)).get())
1160 .did_scroll);
[email protected]aa043632013-03-25 03:39:421161
1162 // Scrolling to left/top will now succeed.
ccameron36d091f2014-11-07 03:18:501163 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181164 host_impl_->ScrollBy(
1165 UpdateState(gfx::Point(), gfx::Vector2d(-10, 0)).get())
1166 .did_scroll);
ccameron36d091f2014-11-07 03:18:501167 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181168 host_impl_->ScrollBy(
1169 UpdateState(gfx::Point(), gfx::Vector2d(0, -10)).get())
1170 .did_scroll);
ccameron36d091f2014-11-07 03:18:501171 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181172 host_impl_->ScrollBy(
1173 UpdateState(gfx::Point(), gfx::Vector2d(-10, -10)).get())
1174 .did_scroll);
[email protected]aa043632013-03-25 03:39:421175
1176 // Scrolling diagonally against an edge will succeed.
ccameron36d091f2014-11-07 03:18:501177 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181178 host_impl_->ScrollBy(
1179 UpdateState(gfx::Point(), gfx::Vector2d(10, -10)).get())
1180 .did_scroll);
ccameron36d091f2014-11-07 03:18:501181 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181182 host_impl_->ScrollBy(
1183 UpdateState(gfx::Point(), gfx::Vector2d(-10, 0)).get())
1184 .did_scroll);
ccameron36d091f2014-11-07 03:18:501185 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181186 host_impl_->ScrollBy(
1187 UpdateState(gfx::Point(), gfx::Vector2d(-10, 10)).get())
1188 .did_scroll);
[email protected]aa043632013-03-25 03:39:421189
1190 // Trying to scroll more than the available space will also succeed.
ccameron36d091f2014-11-07 03:18:501191 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181192 host_impl_->ScrollBy(
1193 UpdateState(gfx::Point(), gfx::Vector2d(5000, 5000)).get())
1194 .did_scroll);
[email protected]aa043632013-03-25 03:39:421195}
1196
1197TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) {
1198 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
[email protected]18ce59702013-04-09 04:58:401199 host_impl_->SetViewportSize(gfx::Size(100, 1000));
[email protected]aa043632013-03-25 03:39:421200
[email protected]ce2e8112013-11-28 07:44:361201 DrawFrame();
[email protected]aa043632013-03-25 03:39:421202
tdresser81e84c672016-01-18 23:21:221203 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181204 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:221205 InputHandler::WHEEL)
1206 .thread);
[email protected]aa043632013-03-25 03:39:421207
aeliasa57c40d122015-10-08 00:20:091208 // Trying to scroll if not user_scrollable_vertical will fail.
1209 host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(false);
danakj74af409e2016-07-01 00:41:481210 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd2668bea62016-03-17 00:49:471211 DrawFrame();
[email protected]aa043632013-03-25 03:39:421212 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491213 gfx::Point(), SCROLL_FORWARD));
[email protected]aa043632013-03-25 03:39:421214 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491215 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:421216
aeliasa57c40d122015-10-08 00:20:091217 host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(true);
danakj74af409e2016-07-01 00:41:481218 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd2668bea62016-03-17 00:49:471219 DrawFrame();
[email protected]aa043632013-03-25 03:39:421220 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491221 gfx::Point(), SCROLL_FORWARD));
[email protected]adeda572014-01-31 00:49:471222 EXPECT_FLOAT_EQ(875.f,
sunxdb7e79432016-03-09 21:13:421223 ScrollDelta(host_impl_->InnerViewportScrollLayer()).y());
[email protected]aa043632013-03-25 03:39:421224 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491225 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:421226}
1227
aeliasaf915a882014-10-14 04:12:041228TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
[email protected]59a7d552013-10-22 03:36:431229 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
1230 host_impl_->SetViewportSize(gfx::Size(100, 100));
1231
1232 gfx::Size overflow_size(400, 400);
jaydasikafc66cfb2016-06-10 04:34:221233 ASSERT_EQ(1u, scroll_layer->test_properties()->children.size());
1234 LayerImpl* overflow = scroll_layer->test_properties()->children[0];
[email protected]59a7d552013-10-22 03:36:431235 overflow->SetBounds(overflow_size);
jaydasikaf419bf72016-06-15 10:21:211236 overflow->SetScrollClipLayer(
1237 scroll_layer->test_properties()->parent->test_properties()->parent->id());
sunxdb7e79432016-03-09 21:13:421238 overflow->layer_tree_impl()
1239 ->property_trees()
1240 ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->id(),
1241 gfx::ScrollOffset());
[email protected]59a7d552013-10-22 03:36:431242 overflow->SetPosition(gfx::PointF());
danakj74af409e2016-07-01 00:41:481243 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]59a7d552013-10-22 03:36:431244
[email protected]ce2e8112013-11-28 07:44:361245 DrawFrame();
[email protected]59a7d552013-10-22 03:36:431246 gfx::Point scroll_position(10, 10);
1247
tdresser81e84c672016-01-18 23:21:221248 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181249 host_impl_->ScrollBegin(BeginState(scroll_position).get(),
tdresser81e84c672016-01-18 23:21:221250 InputHandler::WHEEL)
1251 .thread);
aeliasf998da82015-02-03 01:40:511252 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
1253 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431254
1255 gfx::Vector2dF scroll_delta(10, 10);
majidvp944a8cd2016-01-12 21:05:181256 host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
1257 host_impl_->ScrollEnd(EndState().get());
aeliasf998da82015-02-03 01:40:511258 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
1259 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431260
1261 overflow->set_user_scrollable_horizontal(false);
danakj74af409e2016-07-01 00:41:481262 host_impl_->active_tree()->BuildPropertyTreesForTesting();
1263
sunxd2668bea62016-03-17 00:49:471264 DrawFrame();
[email protected]59a7d552013-10-22 03:36:431265
tdresser81e84c672016-01-18 23:21:221266 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181267 host_impl_->ScrollBegin(BeginState(scroll_position).get(),
tdresser81e84c672016-01-18 23:21:221268 InputHandler::WHEEL)
1269 .thread);
aeliasf998da82015-02-03 01:40:511270 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
1271 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431272
majidvp944a8cd2016-01-12 21:05:181273 host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
1274 host_impl_->ScrollEnd(EndState().get());
tdressera3b162b82015-09-29 17:51:431275 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset());
aeliasf998da82015-02-03 01:40:511276 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431277
1278 overflow->set_user_scrollable_vertical(false);
danakj74af409e2016-07-01 00:41:481279 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd2668bea62016-03-17 00:49:471280 DrawFrame();
[email protected]59a7d552013-10-22 03:36:431281
tdresser81e84c672016-01-18 23:21:221282 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181283 host_impl_->ScrollBegin(BeginState(scroll_position).get(),
tdresser81e84c672016-01-18 23:21:221284 InputHandler::WHEEL)
1285 .thread);
tdressera3b162b82015-09-29 17:51:431286 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset());
aeliasf998da82015-02-03 01:40:511287 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431288
majidvp944a8cd2016-01-12 21:05:181289 host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
1290 host_impl_->ScrollEnd(EndState().get());
tdressera3b162b82015-09-29 17:51:431291 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), scroll_layer->CurrentScrollOffset());
aeliasf998da82015-02-03 01:40:511292 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431293}
1294
danakjb56d7d82015-08-28 19:28:591295TEST_F(LayerTreeHostImplTest, AnimationSchedulingPendingTree) {
danakja18e826a2015-12-03 00:27:031296 EXPECT_FALSE(host_impl_->CommitToActiveTree());
1297
danakjb56d7d82015-08-28 19:28:591298 host_impl_->SetViewportSize(gfx::Size(50, 50));
1299
1300 host_impl_->CreatePendingTree();
danakj74af409e2016-07-01 00:41:481301 auto root_owned = LayerImpl::Create(host_impl_->pending_tree(), 1);
1302 auto* root = root_owned.get();
1303 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned));
danakjb56d7d82015-08-28 19:28:591304 root->SetBounds(gfx::Size(50, 50));
jaydasika6b5a32bf2016-04-22 21:56:361305 root->test_properties()->force_render_surface = true;
danakjb56d7d82015-08-28 19:28:591306
jaydasika89f7b5a2016-06-22 02:08:391307 root->test_properties()->AddChild(
1308 LayerImpl::Create(host_impl_->pending_tree(), 2));
jaydasikafc66cfb2016-06-10 04:34:221309 LayerImpl* child = root->test_properties()->children[0];
danakjb56d7d82015-08-28 19:28:591310 child->SetBounds(gfx::Size(10, 10));
1311 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1312 child->SetDrawsContent(true);
vollickef2ae922016-06-29 17:54:271313
1314 host_impl_->pending_tree()->SetElementIdsForTesting();
1315
1316 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 10.0,
1317 3, 0);
danakjb56d7d82015-08-28 19:28:591318
danakja18e826a2015-12-03 00:27:031319 EXPECT_FALSE(did_request_next_frame_);
danakjb56d7d82015-08-28 19:28:591320 EXPECT_FALSE(did_request_redraw_);
1321 EXPECT_FALSE(did_request_commit_);
1322
danakj4923440542015-10-29 19:34:531323 host_impl_->AnimatePendingTreeAfterCommit();
danakjb56d7d82015-08-28 19:28:591324
danakj4923440542015-10-29 19:34:531325 // An animation exists on the pending layer. Doing
1326 // AnimatePendingTreeAfterCommit() requests another frame.
danakjb56d7d82015-08-28 19:28:591327 // In reality, animations without has_set_start_time() == true do not need to
1328 // be continuously ticked on the pending tree, so it should not request
1329 // another animation frame here. But we currently do so blindly if any
1330 // animation exists.
danakja18e826a2015-12-03 00:27:031331 EXPECT_TRUE(did_request_next_frame_);
danakjb56d7d82015-08-28 19:28:591332 // The pending tree with an animation does not need to draw after animating.
1333 EXPECT_FALSE(did_request_redraw_);
1334 EXPECT_FALSE(did_request_commit_);
1335
danakja18e826a2015-12-03 00:27:031336 did_request_next_frame_ = false;
danakjb56d7d82015-08-28 19:28:591337 did_request_redraw_ = false;
1338 did_request_commit_ = false;
1339
1340 host_impl_->ActivateSyncTree();
1341
1342 // When the animation activates, we should request another animation frame
1343 // to keep the animation moving.
danakja18e826a2015-12-03 00:27:031344 EXPECT_TRUE(did_request_next_frame_);
danakjb56d7d82015-08-28 19:28:591345 // On activation we don't need to request a redraw for the animation,
1346 // activating will draw on its own when it's ready.
1347 EXPECT_FALSE(did_request_redraw_);
1348 EXPECT_FALSE(did_request_commit_);
1349}
1350
1351TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) {
danakja18e826a2015-12-03 00:27:031352 EXPECT_FALSE(host_impl_->CommitToActiveTree());
1353
danakjb56d7d82015-08-28 19:28:591354 host_impl_->SetViewportSize(gfx::Size(50, 50));
1355
jaydasikabf1875a2016-06-28 03:39:591356 host_impl_->active_tree()->SetRootLayerForTesting(
danakjb56d7d82015-08-28 19:28:591357 LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:481358 LayerImpl* root = *host_impl_->active_tree()->begin();
danakjb56d7d82015-08-28 19:28:591359 root->SetBounds(gfx::Size(50, 50));
jaydasika6b5a32bf2016-04-22 21:56:361360 root->test_properties()->force_render_surface = true;
danakjb56d7d82015-08-28 19:28:591361
jaydasika89f7b5a2016-06-22 02:08:391362 root->test_properties()->AddChild(
1363 LayerImpl::Create(host_impl_->active_tree(), 2));
jaydasikafc66cfb2016-06-10 04:34:221364 LayerImpl* child = root->test_properties()->children[0];
danakjb56d7d82015-08-28 19:28:591365 child->SetBounds(gfx::Size(10, 10));
1366 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1367 child->SetDrawsContent(true);
danakjee6547a22016-07-01 20:41:501368 host_impl_->active_tree()->BuildPropertyTreesForTesting();
vollickef2ae922016-06-29 17:54:271369 host_impl_->active_tree()->SetElementIdsForTesting();
1370
danakjb56d7d82015-08-28 19:28:591371 // Add a translate from 6,7 to 8,9.
1372 TransformOperations start;
1373 start.AppendTranslate(6.f, 7.f, 0.f);
1374 TransformOperations end;
1375 end.AppendTranslate(8.f, 9.f, 0.f);
vollickef2ae922016-06-29 17:54:271376 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 4.0,
1377 start, end);
danakjb56d7d82015-08-28 19:28:591378
1379 base::TimeTicks now = base::TimeTicks::Now();
1380 host_impl_->WillBeginImplFrame(
1381 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
1382
danakja18e826a2015-12-03 00:27:031383 // TODO(crbug.com/551134): We always request a new frame and a draw for
1384 // animations that are on the pending tree, but we don't need to do that
1385 // unless they are waiting for some future time to start.
1386 EXPECT_TRUE(did_request_next_frame_);
1387 EXPECT_TRUE(did_request_redraw_);
danakjb56d7d82015-08-28 19:28:591388 EXPECT_FALSE(did_request_commit_);
danakja18e826a2015-12-03 00:27:031389 did_request_next_frame_ = false;
danakjb56d7d82015-08-28 19:28:591390 did_request_redraw_ = false;
1391 did_request_commit_ = false;
1392
danakja18e826a2015-12-03 00:27:031393 host_impl_->ActivateAnimations();
1394
1395 // On activating an animation, we should request another frame so that we'll
1396 // continue ticking the animation.
1397 EXPECT_TRUE(did_request_next_frame_);
1398 EXPECT_FALSE(did_request_redraw_);
1399 EXPECT_FALSE(did_request_commit_);
1400 did_request_next_frame_ = false;
1401 did_request_redraw_ = false;
1402 did_request_commit_ = false;
1403
1404 // The next frame after activating, we'll tick the animation again.
danakjb56d7d82015-08-28 19:28:591405 host_impl_->Animate();
1406
1407 // An animation exists on the active layer. Doing Animate() requests another
1408 // frame after the current one.
danakja18e826a2015-12-03 00:27:031409 EXPECT_TRUE(did_request_next_frame_);
danakj4923440542015-10-29 19:34:531410 // The animation should cause us to draw at the frame's deadline.
1411 EXPECT_TRUE(did_request_redraw_);
danakjb56d7d82015-08-28 19:28:591412 EXPECT_FALSE(did_request_commit_);
1413}
1414
danakja18e826a2015-12-03 00:27:031415TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) {
1416 FakeImplTaskRunnerProvider provider(nullptr);
1417 CreateHostImplWithTaskRunnerProvider(DefaultSettings(), CreateOutputSurface(),
1418 &provider);
1419 EXPECT_TRUE(host_impl_->CommitToActiveTree());
1420
1421 host_impl_->SetViewportSize(gfx::Size(50, 50));
1422
danakj74af409e2016-07-01 00:41:481423 auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1);
1424 auto* root = root_owned.get();
1425 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned));
danakja18e826a2015-12-03 00:27:031426 root->SetBounds(gfx::Size(50, 50));
1427 root->SetHasRenderSurface(true);
1428
danakj74af409e2016-07-01 00:41:481429 auto child_owned = LayerImpl::Create(host_impl_->active_tree(), 2);
1430 auto* child = child_owned.get();
1431 root->test_properties()->AddChild(std::move(child_owned));
danakja18e826a2015-12-03 00:27:031432 child->SetBounds(gfx::Size(10, 10));
1433 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1434 child->SetDrawsContent(true);
vollickef2ae922016-06-29 17:54:271435
1436 host_impl_->active_tree()->SetElementIdsForTesting();
1437
1438 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 10.0,
1439 3, 0);
danakja18e826a2015-12-03 00:27:031440
1441 // Set up the property trees so that UpdateDrawProperties will work in
1442 // CommitComplete below.
1443 LayerImplList list;
1444 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
ajuma0adb5902016-04-28 16:32:381445 root, gfx::Size(50, 50), &list);
sunxdb365de02016-04-28 20:32:571446 LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
danakja18e826a2015-12-03 00:27:031447
1448 EXPECT_FALSE(did_request_next_frame_);
1449 EXPECT_FALSE(did_request_redraw_);
1450 EXPECT_FALSE(did_request_commit_);
1451
1452 host_impl_->CommitComplete();
1453
1454 // Animations on the active tree should be started and ticked, and a new frame
1455 // should be requested to continue ticking them.
1456 EXPECT_TRUE(did_request_next_frame_);
1457 EXPECT_TRUE(did_request_redraw_);
1458 EXPECT_FALSE(did_request_commit_);
1459
1460 // Delete the LayerTreeHostImpl before the TaskRunnerProvider goes away.
danakjee6547a22016-07-01 20:41:501461 host_impl_->ReleaseOutputSurface();
danakja18e826a2015-12-03 00:27:031462 host_impl_ = nullptr;
1463}
1464
loyso638ef702016-06-07 02:51:571465TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) {
1466 host_impl_->SetViewportSize(gfx::Size(50, 50));
1467
jaydasikabf1875a2016-06-28 03:39:591468 host_impl_->active_tree()->SetRootLayerForTesting(
loyso638ef702016-06-07 02:51:571469 LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:481470 LayerImpl* root = *host_impl_->active_tree()->begin();
loyso638ef702016-06-07 02:51:571471 root->SetBounds(gfx::Size(50, 50));
1472
jaydasika89f7b5a2016-06-22 02:08:391473 root->test_properties()->AddChild(
1474 LayerImpl::Create(host_impl_->active_tree(), 2));
jaydasikafc66cfb2016-06-10 04:34:221475 LayerImpl* child = root->test_properties()->children[0];
loyso638ef702016-06-07 02:51:571476 child->SetBounds(gfx::Size(10, 10));
1477 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1478 child->SetDrawsContent(true);
1479
danakjee6547a22016-07-01 20:41:501480 host_impl_->active_tree()->BuildPropertyTreesForTesting();
vollickef2ae922016-06-29 17:54:271481 host_impl_->active_tree()->SetElementIdsForTesting();
1482
loyso638ef702016-06-07 02:51:571483 // Add a translate animation.
1484 TransformOperations start;
1485 start.AppendTranslate(6.f, 7.f, 0.f);
1486 TransformOperations end;
1487 end.AppendTranslate(8.f, 9.f, 0.f);
vollickef2ae922016-06-29 17:54:271488 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 4.0,
1489 start, end);
loyso638ef702016-06-07 02:51:571490
1491 base::TimeTicks now = base::TimeTicks::Now();
1492 host_impl_->WillBeginImplFrame(
1493 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
1494 EXPECT_TRUE(did_request_next_frame_);
1495 did_request_next_frame_ = false;
1496
1497 host_impl_->ActivateAnimations();
1498 // On activating an animation, we should request another frame so that we'll
1499 // continue ticking the animation.
1500 EXPECT_TRUE(did_request_next_frame_);
1501 did_request_next_frame_ = false;
1502
1503 // The next frame after activating, we'll tick the animation again.
1504 host_impl_->Animate();
1505 // An animation exists on the active layer. Doing Animate() requests another
1506 // frame after the current one.
1507 EXPECT_TRUE(did_request_next_frame_);
1508 did_request_next_frame_ = false;
1509
1510 // Destroy layer, unregister animation target (element).
jaydasikaf419bf72016-06-15 10:21:211511 child->test_properties()->parent = nullptr;
jaydasika89f7b5a2016-06-22 02:08:391512 root->test_properties()->RemoveChild(child);
loyso638ef702016-06-07 02:51:571513 child = nullptr;
1514
1515 // Doing Animate() doesn't request another frame after the current one.
1516 host_impl_->Animate();
1517 EXPECT_FALSE(did_request_next_frame_);
1518
1519 host_impl_->Animate();
1520 EXPECT_FALSE(did_request_next_frame_);
1521}
1522
vmpstre1564a52015-11-24 19:43:151523class MissingTilesLayer : public LayerImpl {
1524 public:
1525 MissingTilesLayer(LayerTreeImpl* layer_tree_impl, int id)
1526 : LayerImpl(layer_tree_impl, id), has_missing_tiles_(true) {}
1527
1528 void set_has_missing_tiles(bool has_missing_tiles) {
1529 has_missing_tiles_ = has_missing_tiles;
1530 }
1531
1532 void AppendQuads(RenderPass* render_pass,
1533 AppendQuadsData* append_quads_data) override {
1534 append_quads_data->num_missing_tiles += has_missing_tiles_;
1535 }
1536
1537 private:
1538 bool has_missing_tiles_;
1539};
1540
danakja18e826a2015-12-03 00:27:031541TEST_F(LayerTreeHostImplTest, AnimationMarksLayerNotReady) {
vmpstre1564a52015-11-24 19:43:151542 host_impl_->SetViewportSize(gfx::Size(50, 50));
1543
jaydasikabf1875a2016-06-28 03:39:591544 host_impl_->active_tree()->SetRootLayerForTesting(
vmpstre1564a52015-11-24 19:43:151545 LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:481546 LayerImpl* root = *host_impl_->active_tree()->begin();
vmpstre1564a52015-11-24 19:43:151547 root->SetBounds(gfx::Size(50, 50));
1548 root->SetHasRenderSurface(true);
1549
jaydasika89f7b5a2016-06-22 02:08:391550 root->test_properties()->AddChild(std::unique_ptr<MissingTilesLayer>(
vmpstre1564a52015-11-24 19:43:151551 new MissingTilesLayer(host_impl_->active_tree(), 2)));
1552 MissingTilesLayer* child =
jaydasikafc66cfb2016-06-10 04:34:221553 static_cast<MissingTilesLayer*>(root->test_properties()->children[0]);
vmpstre1564a52015-11-24 19:43:151554 child->SetBounds(gfx::Size(10, 10));
1555 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1556 child->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481557 host_impl_->active_tree()->BuildPropertyTreesForTesting();
vmpstre1564a52015-11-24 19:43:151558
vollickef2ae922016-06-29 17:54:271559 host_impl_->active_tree()->SetElementIdsForTesting();
1560
vmpstre1564a52015-11-24 19:43:151561 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1562
1563 // Add a translate from 6,7 to 8,9.
1564 TransformOperations start;
1565 start.AppendTranslate(6.f, 7.f, 0.f);
1566 TransformOperations end;
1567 end.AppendTranslate(8.f, 9.f, 0.f);
vollickef2ae922016-06-29 17:54:271568 int animation_id = AddAnimatedTransformToElementWithPlayer(
1569 child->element_id(), timeline(), 4.0, start, end);
vmpstre1564a52015-11-24 19:43:151570
1571 base::TimeTicks now = base::TimeTicks::Now();
1572 host_impl_->WillBeginImplFrame(
1573 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
1574
1575 host_impl_->ActivateAnimations();
1576 host_impl_->Animate();
1577
1578 EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation());
1579
vmpstre1564a52015-11-24 19:43:151580 host_impl_->ResetRequiresHighResToDraw();
1581
1582 // Child layer has an animating transform but missing tiles.
1583 FakeLayerTreeHostImpl::FrameData frame;
1584 DrawResult result = host_impl_->PrepareToDraw(&frame);
1585 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result);
1586 host_impl_->DidDrawAllLayers(frame);
1587
1588 child->set_has_missing_tiles(false);
1589
1590 // Child layer has an animating and no missing tiles.
1591 result = host_impl_->PrepareToDraw(&frame);
1592 EXPECT_EQ(DRAW_SUCCESS, result);
1593 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1594 host_impl_->DidDrawAllLayers(frame);
1595
1596 // Remove the animation.
1597 child->set_has_missing_tiles(true);
vollickef2ae922016-06-29 17:54:271598 RemoveAnimationFromElementWithExistingPlayer(child->element_id(), timeline(),
1599 animation_id);
vmpstre1564a52015-11-24 19:43:151600 child->draw_properties().screen_space_transform_is_animating = false;
1601
1602 // Child layer doesn't have an animation, but was never ready since the last
1603 // time it animated (and has missing tiles).
1604 result = host_impl_->PrepareToDraw(&frame);
1605 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result);
1606 EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation());
1607 host_impl_->DidDrawAllLayers(frame);
1608
1609 child->set_has_missing_tiles(false);
1610
1611 // Child layer doesn't have an animation and all tiles are ready.
1612 result = host_impl_->PrepareToDraw(&frame);
1613 EXPECT_EQ(DRAW_SUCCESS, result);
1614 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1615 host_impl_->DidDrawAllLayers(frame);
1616
1617 child->set_has_missing_tiles(true);
1618
1619 // Child layer doesn't have an animation, and was ready at least once since
1620 // the last time it animated.
1621 result = host_impl_->PrepareToDraw(&frame);
1622 EXPECT_EQ(DRAW_SUCCESS, result);
1623 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1624 host_impl_->DidDrawAllLayers(frame);
1625}
1626
[email protected]aa043632013-03-25 03:39:421627TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
[email protected]35a99a12013-05-09 23:52:291628 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:481629 host_impl_->active_tree()->BuildPropertyTreesForTesting();
1630
[email protected]18ce59702013-04-09 04:58:401631 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:361632 DrawFrame();
[email protected]aa043632013-03-25 03:39:421633
[email protected]adeda572014-01-31 00:49:471634 EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer());
[email protected]fef74fd2014-02-27 06:28:171635 LayerImpl* container_layer = scroll_layer->scroll_clip_layer();
bokancccfde72014-10-08 15:15:221636 EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
[email protected]aa043632013-03-25 03:39:421637
1638 float min_page_scale = 1.f, max_page_scale = 4.f;
[email protected]fef74fd2014-02-27 06:28:171639 float page_scale_factor = 1.f;
[email protected]aa043632013-03-25 03:39:421640
1641 // The impl-based pinch zoom should adjust the max scroll position.
1642 {
aelias58eec0812014-12-04 01:04:401643 host_impl_->active_tree()->PushPageScaleFromMainThread(
[email protected]fef74fd2014-02-27 06:28:171644 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:501645 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
sunxdb7e79432016-03-09 21:13:421646 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:421647
1648 float page_scale_delta = 2.f;
[email protected]fef74fd2014-02-27 06:28:171649
majidvp944a8cd2016-01-12 21:05:181650 host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
dtapuska40e8aff2016-03-11 21:45:031651 InputHandler::TOUCHSCREEN);
[email protected]adeda572014-01-31 00:49:471652 host_impl_->PinchGestureBegin();
[email protected]aa043632013-03-25 03:39:421653 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
1654 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181655 host_impl_->ScrollEnd(EndState().get());
danakja18e826a2015-12-03 00:27:031656 EXPECT_FALSE(did_request_next_frame_);
[email protected]aa043632013-03-25 03:39:421657 EXPECT_TRUE(did_request_redraw_);
1658 EXPECT_TRUE(did_request_commit_);
bokancccfde72014-10-08 15:15:221659 EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
[email protected]aa043632013-03-25 03:39:421660
danakj60bc3bc2016-04-09 00:24:481661 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:421662 host_impl_->ProcessScrollDeltas();
1663 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
1664
miletusf57925d2014-10-01 19:38:131665 EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(),
[email protected]adeda572014-01-31 00:49:471666 scroll_layer->MaxScrollOffset().ToString());
[email protected]aa043632013-03-25 03:39:421667 }
1668
1669 // Scrolling after a pinch gesture should always be in local space. The
lanweid17d0742014-12-01 18:58:521670 // scroll deltas have the page scale factor applied.
[email protected]aa043632013-03-25 03:39:421671 {
aelias58eec0812014-12-04 01:04:401672 host_impl_->active_tree()->PushPageScaleFromMainThread(
[email protected]fef74fd2014-02-27 06:28:171673 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:501674 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
sunxdb7e79432016-03-09 21:13:421675 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:421676
1677 float page_scale_delta = 2.f;
majidvp944a8cd2016-01-12 21:05:181678 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:031679 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:421680 host_impl_->PinchGestureBegin();
1681 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
1682 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181683 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:421684
1685 gfx::Vector2d scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:221686 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181687 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:221688 InputHandler::WHEEL)
1689 .thread);
majidvp944a8cd2016-01-12 21:05:181690 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
1691 host_impl_->ScrollEnd(EndState().get());
[email protected]a9710962012-11-14 20:11:021692
danakj60bc3bc2016-04-09 00:24:481693 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:421694 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:181695 EXPECT_TRUE(ScrollInfoContains(
1696 *scroll_info.get(), scroll_layer->id(),
1697 gfx::Vector2d(0, scroll_delta.y() / page_scale_delta)));
[email protected]aa043632013-03-25 03:39:421698 }
[email protected]a9710962012-11-14 20:11:021699}
1700
bokaneaee880f2015-08-04 18:01:071701TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
1702 LayerTreeSettings settings = DefaultSettings();
bokaneaee880f2015-08-04 18:01:071703 CreateHostImpl(settings,
1704 CreateOutputSurface());
1705 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 4.f);
1706
1707 const gfx::Size content_size(1000, 1000);
1708 const gfx::Size viewport_size(500, 500);
1709 CreateBasicVirtualViewportLayers(viewport_size, content_size);
1710
1711 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121712 outer_scroll_layer->SetDrawsContent(true);
bokaneaee880f2015-08-04 18:01:071713 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121714 inner_scroll_layer->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481715 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokaneaee880f2015-08-04 18:01:071716
1717 EXPECT_VECTOR_EQ(
1718 gfx::Vector2dF(500, 500),
1719 outer_scroll_layer->MaxScrollOffset());
1720
majidvp944a8cd2016-01-12 21:05:181721 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031722 InputHandler::TOUCHSCREEN);
bokaneaee880f2015-08-04 18:01:071723 host_impl_->PinchGestureBegin();
1724 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
1725 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181726 host_impl_->ScrollEnd(EndState().get());
bokaneaee880f2015-08-04 18:01:071727
1728 // Sanity check - we're zoomed in, starting from the origin.
1729 EXPECT_VECTOR_EQ(
1730 gfx::Vector2dF(0, 0),
1731 outer_scroll_layer->CurrentScrollOffset());
1732 EXPECT_VECTOR_EQ(
1733 gfx::Vector2dF(0, 0),
1734 inner_scroll_layer->CurrentScrollOffset());
1735
1736 // Scroll down - only the inner viewport should scroll.
majidvp944a8cd2016-01-12 21:05:181737 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
dtapuska40e8aff2016-03-11 21:45:031738 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181739 host_impl_->ScrollBy(
1740 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
1741 host_impl_->ScrollEnd(EndState().get());
bokaneaee880f2015-08-04 18:01:071742
1743 EXPECT_VECTOR_EQ(
1744 gfx::Vector2dF(50, 50),
1745 inner_scroll_layer->CurrentScrollOffset());
1746 EXPECT_VECTOR_EQ(
1747 gfx::Vector2dF(0, 0),
1748 outer_scroll_layer->CurrentScrollOffset());
1749
1750 // Scroll down - outer viewport should start scrolling after the inner is at
1751 // its maximum.
majidvp944a8cd2016-01-12 21:05:181752 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
dtapuska40e8aff2016-03-11 21:45:031753 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181754 host_impl_->ScrollBy(
1755 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get());
1756 host_impl_->ScrollEnd(EndState().get());
bokaneaee880f2015-08-04 18:01:071757
1758 EXPECT_VECTOR_EQ(
1759 gfx::Vector2dF(250, 250),
1760 inner_scroll_layer->CurrentScrollOffset());
1761 EXPECT_VECTOR_EQ(
1762 gfx::Vector2dF(300, 300),
1763 outer_scroll_layer->CurrentScrollOffset());
1764}
1765
bokan49c85a922015-10-07 21:08:031766// Make sure scrolls smaller than a unit applied to the viewport don't get
1767// dropped. crbug.com/539334.
1768TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) {
1769 LayerTreeSettings settings = DefaultSettings();
1770 CreateHostImpl(settings, CreateOutputSurface());
1771 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
1772
1773 const gfx::Size content_size(1000, 1000);
1774 const gfx::Size viewport_size(500, 500);
1775 CreateBasicVirtualViewportLayers(viewport_size, content_size);
1776
1777 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121778 outer_scroll_layer->SetDrawsContent(true);
bokan49c85a922015-10-07 21:08:031779 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121780 inner_scroll_layer->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481781 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan49c85a922015-10-07 21:08:031782
1783 // Sanity checks.
1784 EXPECT_VECTOR_EQ(
1785 gfx::Vector2dF(500, 500),
1786 outer_scroll_layer->MaxScrollOffset());
1787 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset());
1788 EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll_layer->CurrentScrollOffset());
1789
bokan49c85a922015-10-07 21:08:031790 // Scroll only the layout viewport.
majidvp944a8cd2016-01-12 21:05:181791 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031792 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181793 host_impl_->ScrollBy(
1794 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(0.125f, 0.125f)).get());
bokan49c85a922015-10-07 21:08:031795 EXPECT_VECTOR2DF_EQ(
1796 gfx::Vector2dF(0.125f, 0.125f),
1797 outer_scroll_layer->CurrentScrollOffset());
1798 EXPECT_VECTOR2DF_EQ(
1799 gfx::Vector2dF(0, 0),
1800 inner_scroll_layer->CurrentScrollOffset());
majidvp944a8cd2016-01-12 21:05:181801 host_impl_->ScrollEnd(EndState().get());
bokan49c85a922015-10-07 21:08:031802
1803 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
1804
1805 // Now that we zoomed in, the scroll should be applied to the inner viewport.
majidvp944a8cd2016-01-12 21:05:181806 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031807 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181808 host_impl_->ScrollBy(
1809 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(0.5f, 0.5f)).get());
bokan49c85a922015-10-07 21:08:031810 EXPECT_VECTOR2DF_EQ(
1811 gfx::Vector2dF(0.125f, 0.125f),
1812 outer_scroll_layer->CurrentScrollOffset());
1813 EXPECT_VECTOR2DF_EQ(
1814 gfx::Vector2dF(0.25f, 0.25f),
1815 inner_scroll_layer->CurrentScrollOffset());
majidvp944a8cd2016-01-12 21:05:181816 host_impl_->ScrollEnd(EndState().get());
bokan49c85a922015-10-07 21:08:031817}
1818
bokan32f1b902015-08-12 22:25:321819// Tests that scrolls during a pinch gesture (i.e. "two-finger" scrolls) work
1820// as expected. That is, scrolling during a pinch should bubble from the inner
1821// to the outer viewport.
1822TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
bokan9e5569612015-06-09 18:41:201823 LayerTreeSettings settings = DefaultSettings();
bokan9e5569612015-06-09 18:41:201824 CreateHostImpl(settings,
1825 CreateOutputSurface());
bokan0c33a092015-07-29 18:27:561826 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
bokan9e5569612015-06-09 18:41:201827
bokan499dd082015-06-24 15:35:191828 const gfx::Size content_size(1000, 1000);
1829 const gfx::Size viewport_size(500, 500);
1830 CreateBasicVirtualViewportLayers(viewport_size, content_size);
bokan9e5569612015-06-09 18:41:201831
bokan9e5569612015-06-09 18:41:201832 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121833 outer_scroll_layer->SetDrawsContent(true);
bokan499dd082015-06-24 15:35:191834 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121835 inner_scroll_layer->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481836 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan9e5569612015-06-09 18:41:201837
1838 EXPECT_VECTOR_EQ(
bokan499dd082015-06-24 15:35:191839 gfx::Vector2dF(500, 500),
bokan9e5569612015-06-09 18:41:201840 outer_scroll_layer->MaxScrollOffset());
1841
majidvp944a8cd2016-01-12 21:05:181842 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031843 InputHandler::TOUCHSCREEN);
bokan9e5569612015-06-09 18:41:201844 host_impl_->PinchGestureBegin();
bokan9e5569612015-06-09 18:41:201845
bokan32f1b902015-08-12 22:25:321846 host_impl_->PinchGestureUpdate(2, gfx::Point(250, 250));
1847 EXPECT_VECTOR_EQ(
1848 gfx::Vector2dF(0, 0),
1849 outer_scroll_layer->CurrentScrollOffset());
1850 EXPECT_VECTOR_EQ(
1851 gfx::Vector2dF(125, 125),
1852 inner_scroll_layer->CurrentScrollOffset());
1853
1854 // Needed so that the pinch is accounted for in draw properties.
1855 DrawFrame();
1856
majidvp944a8cd2016-01-12 21:05:181857 host_impl_->ScrollBy(
1858 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(10.f, 10.f)).get());
bokan9e5569612015-06-09 18:41:201859 EXPECT_VECTOR_EQ(
1860 gfx::Vector2dF(0, 0),
1861 outer_scroll_layer->CurrentScrollOffset());
1862 EXPECT_VECTOR_EQ(
bokan499dd082015-06-24 15:35:191863 gfx::Vector2dF(130, 130),
bokan9e5569612015-06-09 18:41:201864 inner_scroll_layer->CurrentScrollOffset());
bokan32f1b902015-08-12 22:25:321865
1866 DrawFrame();
1867
majidvp944a8cd2016-01-12 21:05:181868 host_impl_->ScrollBy(
1869 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(400.f, 400.f)).get());
bokan32f1b902015-08-12 22:25:321870 EXPECT_VECTOR_EQ(
1871 gfx::Vector2dF(80, 80),
1872 outer_scroll_layer->CurrentScrollOffset());
1873 EXPECT_VECTOR_EQ(
1874 gfx::Vector2dF(250, 250),
1875 inner_scroll_layer->CurrentScrollOffset());
1876
1877 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181878 host_impl_->ScrollEnd(EndState().get());
bokan9e5569612015-06-09 18:41:201879}
1880
bokan499dd082015-06-24 15:35:191881// Tests the "snapping" of pinch-zoom gestures to the screen edge. That is, when
1882// a pinch zoom is anchored within a certain margin of the screen edge, we
1883// should assume the user means to scroll into the edge of the screen.
1884TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) {
1885 LayerTreeSettings settings = DefaultSettings();
bokan499dd082015-06-24 15:35:191886 CreateHostImpl(settings,
1887 CreateOutputSurface());
bokan0c33a092015-07-29 18:27:561888 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
bokan499dd082015-06-24 15:35:191889
1890 const gfx::Size content_size(1000, 1000);
1891 const gfx::Size viewport_size(500, 500);
1892 CreateBasicVirtualViewportLayers(viewport_size, content_size);
1893
1894 int offsetFromEdge = Viewport::kPinchZoomSnapMarginDips - 5;
1895 gfx::Point anchor(viewport_size.width() - offsetFromEdge,
1896 viewport_size.height() - offsetFromEdge);
1897
1898 // Pinch in within the margins. The scroll should stay exactly locked to the
1899 // bottom and right.
dtapuska40e8aff2016-03-11 21:45:031900 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191901 host_impl_->PinchGestureBegin();
1902 host_impl_->PinchGestureUpdate(2, anchor);
1903 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181904 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191905
1906 EXPECT_VECTOR_EQ(
1907 gfx::Vector2dF(250, 250),
1908 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1909
1910 // Reset.
1911 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
sunxdb7e79432016-03-09 21:13:421912 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d());
1913 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d());
bokan499dd082015-06-24 15:35:191914
1915 // Pinch in within the margins. The scroll should stay exactly locked to the
1916 // top and left.
1917 anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
dtapuska40e8aff2016-03-11 21:45:031918 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191919 host_impl_->PinchGestureBegin();
1920 host_impl_->PinchGestureUpdate(2, anchor);
1921 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181922 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191923
1924 EXPECT_VECTOR_EQ(
1925 gfx::Vector2dF(0, 0),
1926 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1927
1928 // Reset.
1929 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
sunxdb7e79432016-03-09 21:13:421930 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d());
1931 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d());
bokan499dd082015-06-24 15:35:191932
1933 // Pinch in just outside the margin. There should be no snapping.
1934 offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
1935 anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
dtapuska40e8aff2016-03-11 21:45:031936 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191937 host_impl_->PinchGestureBegin();
1938 host_impl_->PinchGestureUpdate(2, anchor);
1939 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181940 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191941
1942 EXPECT_VECTOR_EQ(
1943 gfx::Vector2dF(50, 50),
1944 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1945
1946 // Reset.
1947 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
sunxdb7e79432016-03-09 21:13:421948 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d());
1949 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d());
bokan499dd082015-06-24 15:35:191950
1951 // Pinch in just outside the margin. There should be no snapping.
1952 offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
1953 anchor = gfx::Point(viewport_size.width() - offsetFromEdge,
1954 viewport_size.height() - offsetFromEdge);
dtapuska40e8aff2016-03-11 21:45:031955 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191956 host_impl_->PinchGestureBegin();
1957 host_impl_->PinchGestureUpdate(2, anchor);
1958 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181959 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191960
1961 EXPECT_VECTOR_EQ(
1962 gfx::Vector2dF(200, 200),
1963 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1964}
1965
bokan74efa332015-05-20 19:50:071966TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
bokan499dd082015-06-24 15:35:191967 const gfx::Size content_size(200, 200);
1968 const gfx::Size viewport_size(100, 100);
1969 CreateBasicVirtualViewportLayers(viewport_size, content_size);
bokan74efa332015-05-20 19:50:071970
bokan74efa332015-05-20 19:50:071971 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
bokan499dd082015-06-24 15:35:191972 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
bokan74efa332015-05-20 19:50:071973
1974 // Zoom into the page by a 2X factor
1975 float min_page_scale = 1.f, max_page_scale = 4.f;
1976 float page_scale_factor = 2.f;
1977 host_impl_->active_tree()->PushPageScaleFromMainThread(
1978 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:501979 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
bokan74efa332015-05-20 19:50:071980
bokan1f01388f2015-09-15 20:55:541981 // Scroll by a small amount, there should be no bubbling to the outer
bokan74efa332015-05-20 19:50:071982 // viewport.
majidvp944a8cd2016-01-12 21:05:181983 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
1984 InputHandler::WHEEL);
1985 host_impl_->ScrollBy(
1986 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(10.f, 20.f)).get());
1987 host_impl_->ScrollEnd(EndState().get());
bokan74efa332015-05-20 19:50:071988
1989 EXPECT_VECTOR_EQ(
1990 gfx::Vector2dF(5, 10),
bokan1f01388f2015-09-15 20:55:541991 inner_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:071992 EXPECT_VECTOR_EQ(
1993 gfx::Vector2dF(),
bokan1f01388f2015-09-15 20:55:541994 outer_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:071995
bokan1f01388f2015-09-15 20:55:541996 // Scroll by the inner viewport's max scroll extent, the remainder
1997 // should bubble up to the outer viewport.
majidvp944a8cd2016-01-12 21:05:181998 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
1999 InputHandler::WHEEL);
2000 host_impl_->ScrollBy(
2001 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
2002 host_impl_->ScrollEnd(EndState().get());
bokan74efa332015-05-20 19:50:072003
2004 EXPECT_VECTOR_EQ(
bokan1f01388f2015-09-15 20:55:542005 gfx::Vector2dF(50, 50),
2006 inner_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:072007 EXPECT_VECTOR_EQ(
2008 gfx::Vector2dF(5, 10),
bokan1f01388f2015-09-15 20:55:542009 outer_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:072010
bokan1f01388f2015-09-15 20:55:542011 // Scroll by the outer viewport's max scroll extent, it should all go to the
2012 // outer viewport.
majidvp944a8cd2016-01-12 21:05:182013 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
2014 InputHandler::WHEEL);
2015 host_impl_->ScrollBy(
2016 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(190.f, 180.f)).get());
2017 host_impl_->ScrollEnd(EndState().get());
bokan74efa332015-05-20 19:50:072018
2019 EXPECT_VECTOR_EQ(
2020 gfx::Vector2dF(100, 100),
2021 outer_scroll_layer->CurrentScrollOffset());
2022 EXPECT_VECTOR_EQ(
2023 gfx::Vector2dF(50, 50),
2024 inner_scroll_layer->CurrentScrollOffset());
2025}
2026
[email protected]dab0a422014-08-13 16:09:462027TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
2028 ui::LatencyInfo latency_info;
miletus45effdc42015-08-05 00:29:182029 latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
2030 1234);
danakj60bc3bc2016-04-09 00:24:482031 std::unique_ptr<SwapPromise> swap_promise(
[email protected]dab0a422014-08-13 16:09:462032 new LatencyInfoSwapPromise(latency_info));
2033
2034 SetupScrollAndContentsLayers(gfx::Size(100, 100));
tdresser81e84c672016-01-18 23:21:222035 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:032036 host_impl_
2037 ->ScrollBegin(BeginState(gfx::Point()).get(),
2038 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:222039 .thread);
majidvp944a8cd2016-01-12 21:05:182040 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
danakja04855a2015-11-18 20:39:102041 host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(
2042 std::move(swap_promise));
majidvp944a8cd2016-01-12 21:05:182043 host_impl_->ScrollEnd(EndState().get());
[email protected]dab0a422014-08-13 16:09:462044
danakj60bc3bc2016-04-09 00:24:482045 std::unique_ptr<ScrollAndScaleSet> scroll_info =
2046 host_impl_->ProcessScrollDeltas();
[email protected]dab0a422014-08-13 16:09:462047 EXPECT_EQ(1u, scroll_info->swap_promises.size());
miletus45effdc42015-08-05 00:29:182048 EXPECT_EQ(latency_info.trace_id(), scroll_info->swap_promises[0]->TraceId());
[email protected]dab0a422014-08-13 16:09:462049}
2050
tdressera3b162b82015-09-29 17:51:432051// Test that scrolls targeting a layer with a non-null scroll_parent() don't
2052// bubble up.
2053TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
bokan79ab8af2015-06-11 14:01:152054 LayerImpl* viewport_scroll =
2055 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2056 host_impl_->SetViewportSize(gfx::Size(50, 50));
2057
2058 // Set up two scrolling children of the root, one of which is a scroll parent
tdressera3b162b82015-09-29 17:51:432059 // to the other. Scrolls shouldn't bubbling from the child.
bokan79ab8af2015-06-11 14:01:152060 LayerImpl *parent;
2061 LayerImpl *child;
2062 LayerImpl *child_clip;
2063
danakj60bc3bc2016-04-09 00:24:482064 std::unique_ptr<LayerImpl> scroll_parent_clip =
bokan79ab8af2015-06-11 14:01:152065 LayerImpl::Create(host_impl_->active_tree(), 6);
danakj60bc3bc2016-04-09 00:24:482066 std::unique_ptr<LayerImpl> scroll_parent =
2067 CreateScrollableLayer(7, gfx::Size(10, 10), scroll_parent_clip.get());
bokan79ab8af2015-06-11 14:01:152068 parent = scroll_parent.get();
jaydasika89f7b5a2016-06-22 02:08:392069 scroll_parent_clip->test_properties()->AddChild(std::move(scroll_parent));
bokan79ab8af2015-06-11 14:01:152070
jaydasika89f7b5a2016-06-22 02:08:392071 viewport_scroll->test_properties()->AddChild(std::move(scroll_parent_clip));
bokan79ab8af2015-06-11 14:01:152072
danakj60bc3bc2016-04-09 00:24:482073 std::unique_ptr<LayerImpl> scroll_child_clip =
bokan79ab8af2015-06-11 14:01:152074 LayerImpl::Create(host_impl_->active_tree(), 8);
danakj60bc3bc2016-04-09 00:24:482075 std::unique_ptr<LayerImpl> scroll_child =
2076 CreateScrollableLayer(9, gfx::Size(10, 10), scroll_child_clip.get());
bokan79ab8af2015-06-11 14:01:152077 child = scroll_child.get();
danakja2fdbc702015-10-20 23:05:242078 scroll_child->SetPosition(gfx::PointF(20.f, 20.f));
jaydasika89f7b5a2016-06-22 02:08:392079 scroll_child_clip->test_properties()->AddChild(std::move(scroll_child));
bokan79ab8af2015-06-11 14:01:152080
2081 child_clip = scroll_child_clip.get();
jaydasika89f7b5a2016-06-22 02:08:392082 viewport_scroll->test_properties()->AddChild(std::move(scroll_child_clip));
bokan79ab8af2015-06-11 14:01:152083
jaydasika1c0a27d42016-04-28 01:54:562084 child_clip->test_properties()->scroll_parent = parent;
danakj60bc3bc2016-04-09 00:24:482085 std::unique_ptr<std::set<LayerImpl*>> scroll_children(
2086 new std::set<LayerImpl*>);
jaydasikab5a1a8c2015-09-29 18:38:492087 scroll_children->insert(child_clip);
jaydasika1c0a27d42016-04-28 01:54:562088 parent->test_properties()->scroll_children.reset(scroll_children.release());
danakj74af409e2016-07-01 00:41:482089 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan79ab8af2015-06-11 14:01:152090
2091 DrawFrame();
2092
2093 {
majidvp944a8cd2016-01-12 21:05:182094 host_impl_->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
dtapuska40e8aff2016-03-11 21:45:032095 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:182096 host_impl_->ScrollBy(
2097 UpdateState(gfx::Point(21, 21), gfx::Vector2d(5, 5)).get());
2098 host_impl_->ScrollBy(
2099 UpdateState(gfx::Point(21, 21), gfx::Vector2d(100, 100)).get());
2100 host_impl_->ScrollEnd(EndState().get());
bokan79ab8af2015-06-11 14:01:152101
2102 // The child should be fully scrolled by the first ScrollBy.
2103 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), child->CurrentScrollOffset());
2104
tdressera3b162b82015-09-29 17:51:432105 // The scroll_parent shouldn't receive the second ScrollBy.
2106 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), parent->CurrentScrollOffset());
bokan79ab8af2015-06-11 14:01:152107
2108 // The viewport shouldn't have been scrolled at all.
2109 EXPECT_VECTOR_EQ(
2110 gfx::Vector2dF(0, 0),
2111 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
2112 EXPECT_VECTOR_EQ(
2113 gfx::Vector2dF(0, 0),
2114 host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset());
2115 }
2116
2117 {
majidvp944a8cd2016-01-12 21:05:182118 host_impl_->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
dtapuska40e8aff2016-03-11 21:45:032119 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:182120 host_impl_->ScrollBy(
2121 UpdateState(gfx::Point(21, 21), gfx::Vector2d(3, 4)).get());
2122 host_impl_->ScrollBy(
2123 UpdateState(gfx::Point(21, 21), gfx::Vector2d(2, 1)).get());
2124 host_impl_->ScrollBy(
2125 UpdateState(gfx::Point(21, 21), gfx::Vector2d(2, 1)).get());
2126 host_impl_->ScrollBy(
2127 UpdateState(gfx::Point(21, 21), gfx::Vector2d(2, 1)).get());
2128 host_impl_->ScrollEnd(EndState().get());
bokan79ab8af2015-06-11 14:01:152129
tdressera3b162b82015-09-29 17:51:432130 // The ScrollBy's should scroll the parent to its extent.
bokan79ab8af2015-06-11 14:01:152131 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), parent->CurrentScrollOffset());
2132
tdressera3b162b82015-09-29 17:51:432133 // The viewport shouldn't receive any scroll delta.
bokan79ab8af2015-06-11 14:01:152134 EXPECT_VECTOR_EQ(
tdressera3b162b82015-09-29 17:51:432135 gfx::Vector2dF(0, 0),
bokan79ab8af2015-06-11 14:01:152136 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
2137 EXPECT_VECTOR_EQ(
2138 gfx::Vector2dF(0, 0),
2139 host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset());
2140 }
2141}
2142
2143
[email protected]aa043632013-03-25 03:39:422144TEST_F(LayerTreeHostImplTest, PinchGesture) {
2145 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:402146 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:362147 DrawFrame();
[email protected]be782f52013-03-23 21:36:142148
[email protected]adeda572014-01-31 00:49:472149 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
[email protected]aa043632013-03-25 03:39:422150 DCHECK(scroll_layer);
[email protected]be782f52013-03-23 21:36:142151
[email protected]aa043632013-03-25 03:39:422152 float min_page_scale = 1.f;
2153 float max_page_scale = 4.f;
[email protected]be782f52013-03-23 21:36:142154
[email protected]aa043632013-03-25 03:39:422155 // Basic pinch zoom in gesture
2156 {
aelias58eec0812014-12-04 01:04:402157 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422158 max_page_scale);
sunxdb7e79432016-03-09 21:13:422159 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]be782f52013-03-23 21:36:142160
[email protected]aa043632013-03-25 03:39:422161 float page_scale_delta = 2.f;
majidvp944a8cd2016-01-12 21:05:182162 host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
dtapuska40e8aff2016-03-11 21:45:032163 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422164 host_impl_->PinchGestureBegin();
2165 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
2166 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182167 host_impl_->ScrollEnd(EndState().get());
danakja18e826a2015-12-03 00:27:032168 EXPECT_FALSE(did_request_next_frame_);
[email protected]aa043632013-03-25 03:39:422169 EXPECT_TRUE(did_request_redraw_);
2170 EXPECT_TRUE(did_request_commit_);
[email protected]be782f52013-03-23 21:36:142171
danakj60bc3bc2016-04-09 00:24:482172 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422173 host_impl_->ProcessScrollDeltas();
2174 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
2175 }
2176
2177 // Zoom-in clamping
2178 {
aelias58eec0812014-12-04 01:04:402179 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422180 max_page_scale);
sunxdb7e79432016-03-09 21:13:422181 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:422182 float page_scale_delta = 10.f;
2183
majidvp944a8cd2016-01-12 21:05:182184 host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
dtapuska40e8aff2016-03-11 21:45:032185 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422186 host_impl_->PinchGestureBegin();
2187 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
2188 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182189 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422190
danakj60bc3bc2016-04-09 00:24:482191 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422192 host_impl_->ProcessScrollDeltas();
2193 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale);
2194 }
2195
2196 // Zoom-out clamping
2197 {
aelias58eec0812014-12-04 01:04:402198 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422199 max_page_scale);
sunxdb7e79432016-03-09 21:13:422200 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202201 scroll_layer->layer_tree_impl()
2202 ->property_trees()
2203 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422204 scroll_layer->layer_tree_impl()
2205 ->property_trees()
2206 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2207 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]aa043632013-03-25 03:39:422208
2209 float page_scale_delta = 0.1f;
majidvp944a8cd2016-01-12 21:05:182210 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:032211 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422212 host_impl_->PinchGestureBegin();
2213 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
2214 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182215 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422216
danakj60bc3bc2016-04-09 00:24:482217 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422218 host_impl_->ProcessScrollDeltas();
2219 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
2220
2221 EXPECT_TRUE(scroll_info->scrolls.empty());
2222 }
2223
2224 // Two-finger panning should not happen based on pinch events only
2225 {
aelias58eec0812014-12-04 01:04:402226 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422227 max_page_scale);
sunxdb7e79432016-03-09 21:13:422228 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202229 scroll_layer->layer_tree_impl()
2230 ->property_trees()
2231 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422232 scroll_layer->layer_tree_impl()
2233 ->property_trees()
2234 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2235 scroll_layer->id(), gfx::ScrollOffset(20, 20));
[email protected]aa043632013-03-25 03:39:422236
2237 float page_scale_delta = 1.f;
majidvp944a8cd2016-01-12 21:05:182238 host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
dtapuska40e8aff2016-03-11 21:45:032239 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422240 host_impl_->PinchGestureBegin();
2241 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
2242 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
2243 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182244 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422245
danakj60bc3bc2016-04-09 00:24:482246 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422247 host_impl_->ProcessScrollDeltas();
2248 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
2249 EXPECT_TRUE(scroll_info->scrolls.empty());
2250 }
2251
2252 // Two-finger panning should work with interleaved scroll events
2253 {
aelias58eec0812014-12-04 01:04:402254 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422255 max_page_scale);
sunxdb7e79432016-03-09 21:13:422256 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202257 scroll_layer->layer_tree_impl()
2258 ->property_trees()
2259 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422260 scroll_layer->layer_tree_impl()
2261 ->property_trees()
2262 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2263 scroll_layer->id(), gfx::ScrollOffset(20, 20));
[email protected]aa043632013-03-25 03:39:422264
2265 float page_scale_delta = 1.f;
majidvp944a8cd2016-01-12 21:05:182266 host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
dtapuska40e8aff2016-03-11 21:45:032267 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422268 host_impl_->PinchGestureBegin();
2269 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
majidvp944a8cd2016-01-12 21:05:182270 host_impl_->ScrollBy(
2271 UpdateState(gfx::Point(10, 10), gfx::Vector2d(-10, -10)).get());
[email protected]aa043632013-03-25 03:39:422272 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
2273 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182274 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422275
danakj60bc3bc2016-04-09 00:24:482276 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422277 host_impl_->ProcessScrollDeltas();
2278 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
tdresser99977952015-07-02 19:49:182279 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2280 gfx::Vector2d(-10, -10)));
[email protected]aa043632013-03-25 03:39:422281 }
[email protected]9ec24df2013-08-09 23:32:572282
2283 // Two-finger panning should work when starting fully zoomed out.
2284 {
aelias58eec0812014-12-04 01:04:402285 host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f);
sunxdb7e79432016-03-09 21:13:422286 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202287 scroll_layer->layer_tree_impl()
2288 ->property_trees()
2289 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422290 scroll_layer->layer_tree_impl()
2291 ->property_trees()
2292 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
2293 gfx::ScrollOffset(0, 0));
[email protected]9ec24df2013-08-09 23:32:572294
majidvp944a8cd2016-01-12 21:05:182295 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
dtapuska40e8aff2016-03-11 21:45:032296 InputHandler::TOUCHSCREEN);
[email protected]9ec24df2013-08-09 23:32:572297 host_impl_->PinchGestureBegin();
2298 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
2299 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
bokan1f01388f2015-09-15 20:55:542300
2301 // Needed so layer transform includes page scale.
2302 DrawFrame();
2303
majidvp944a8cd2016-01-12 21:05:182304 host_impl_->ScrollBy(
2305 UpdateState(gfx::Point(0, 0), gfx::Vector2d(10, 10)).get());
[email protected]9ec24df2013-08-09 23:32:572306 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
2307 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182308 host_impl_->ScrollEnd(EndState().get());
[email protected]9ec24df2013-08-09 23:32:572309
danakj60bc3bc2016-04-09 00:24:482310 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]9ec24df2013-08-09 23:32:572311 host_impl_->ProcessScrollDeltas();
2312 EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
tdresser99977952015-07-02 19:49:182313 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
bokan1f01388f2015-09-15 20:55:542314 gfx::Vector2d(10, 10)));
[email protected]9ec24df2013-08-09 23:32:572315 }
[email protected]be782f52013-03-23 21:36:142316}
2317
[email protected]aa043632013-03-25 03:39:422318TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
2319 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:402320 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:362321 DrawFrame();
[email protected]df8f44f2013-01-08 08:00:312322
[email protected]adeda572014-01-31 00:49:472323 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
[email protected]aa043632013-03-25 03:39:422324 DCHECK(scroll_layer);
[email protected]df8f44f2013-01-08 08:00:312325
[email protected]aa043632013-03-25 03:39:422326 float min_page_scale = 0.5f;
2327 float max_page_scale = 4.f;
2328 base::TimeTicks start_time = base::TimeTicks() +
2329 base::TimeDelta::FromSeconds(1);
2330 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
2331 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2332 base::TimeTicks end_time = start_time + duration;
[email protected]aa043632013-03-25 03:39:422333
danakj12e2f6e2015-08-19 22:25:442334 BeginFrameArgs begin_frame_args =
2335 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2336
[email protected]aa043632013-03-25 03:39:422337 // Non-anchor zoom-in
2338 {
aelias58eec0812014-12-04 01:04:402339 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422340 max_page_scale);
sunxdb7e79432016-03-09 21:13:422341 scroll_layer->layer_tree_impl()
2342 ->property_trees()
2343 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2344 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]aa043632013-03-25 03:39:422345
[email protected]c2321962014-04-28 19:16:422346 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032347 did_request_next_frame_ = false;
bokanfcdbc182014-11-21 21:53:332348 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482349 std::unique_ptr<PendingPageScaleAnimation>(
2350 new PendingPageScaleAnimation(gfx::Vector2d(), false, 2.f,
2351 duration)));
bokan915bf352014-10-02 21:57:142352 host_impl_->ActivateSyncTree();
[email protected]43b8f982014-04-30 21:24:332353 EXPECT_FALSE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032354 EXPECT_TRUE(did_request_next_frame_);
[email protected]43b8f982014-04-30 21:24:332355
2356 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032357 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442358 begin_frame_args.frame_time = start_time;
2359 host_impl_->WillBeginImplFrame(begin_frame_args);
2360 host_impl_->Animate();
[email protected]34e1b512013-09-26 17:32:332361 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032362 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442363 host_impl_->DidFinishImplFrame();
[email protected]34e1b512013-09-26 17:32:332364
2365 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032366 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442367 begin_frame_args.frame_time = halfway_through_animation;
2368 host_impl_->WillBeginImplFrame(begin_frame_args);
2369 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422370 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032371 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442372 host_impl_->DidFinishImplFrame();
[email protected]34e1b512013-09-26 17:32:332373
2374 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032375 did_request_next_frame_ = false;
[email protected]34e1b512013-09-26 17:32:332376 did_request_commit_ = false;
danakj12e2f6e2015-08-19 22:25:442377 begin_frame_args.frame_time = end_time;
2378 host_impl_->WillBeginImplFrame(begin_frame_args);
2379 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422380 EXPECT_TRUE(did_request_commit_);
danakja18e826a2015-12-03 00:27:032381 EXPECT_FALSE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442382 host_impl_->DidFinishImplFrame();
[email protected]aa043632013-03-25 03:39:422383
danakj60bc3bc2016-04-09 00:24:482384 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422385 host_impl_->ProcessScrollDeltas();
2386 EXPECT_EQ(scroll_info->page_scale_delta, 2);
tdresser99977952015-07-02 19:49:182387 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2388 gfx::Vector2d(-50, -50)));
[email protected]aa043632013-03-25 03:39:422389 }
2390
danakj12e2f6e2015-08-19 22:25:442391 start_time += base::TimeDelta::FromSeconds(10);
2392 halfway_through_animation += base::TimeDelta::FromSeconds(10);
2393 end_time += base::TimeDelta::FromSeconds(10);
2394
[email protected]aa043632013-03-25 03:39:422395 // Anchor zoom-out
2396 {
aelias58eec0812014-12-04 01:04:402397 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422398 max_page_scale);
sunxdb7e79432016-03-09 21:13:422399 scroll_layer->layer_tree_impl()
2400 ->property_trees()
2401 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2402 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]aa043632013-03-25 03:39:422403
[email protected]43b8f982014-04-30 21:24:332404 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032405 did_request_next_frame_ = false;
bokanfcdbc182014-11-21 21:53:332406 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482407 std::unique_ptr<PendingPageScaleAnimation>(
2408 new PendingPageScaleAnimation(gfx::Vector2d(25, 25), true,
2409 min_page_scale, duration)));
bokan915bf352014-10-02 21:57:142410 host_impl_->ActivateSyncTree();
[email protected]43b8f982014-04-30 21:24:332411 EXPECT_FALSE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032412 EXPECT_TRUE(did_request_next_frame_);
[email protected]43b8f982014-04-30 21:24:332413
[email protected]34e1b512013-09-26 17:32:332414 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032415 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442416 begin_frame_args.frame_time = start_time;
2417 host_impl_->WillBeginImplFrame(begin_frame_args);
2418 host_impl_->Animate();
[email protected]34e1b512013-09-26 17:32:332419 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032420 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442421 host_impl_->DidFinishImplFrame();
[email protected]34e1b512013-09-26 17:32:332422
2423 did_request_redraw_ = false;
2424 did_request_commit_ = false;
danakja18e826a2015-12-03 00:27:032425 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442426 begin_frame_args.frame_time = end_time;
2427 host_impl_->WillBeginImplFrame(begin_frame_args);
2428 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422429 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032430 EXPECT_FALSE(did_request_next_frame_);
[email protected]aa043632013-03-25 03:39:422431 EXPECT_TRUE(did_request_commit_);
danakj12e2f6e2015-08-19 22:25:442432 host_impl_->DidFinishImplFrame();
[email protected]aa043632013-03-25 03:39:422433
danakj60bc3bc2016-04-09 00:24:482434 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422435 host_impl_->ProcessScrollDeltas();
2436 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
2437 // Pushed to (0,0) via clamping against contents layer size.
tdresser99977952015-07-02 19:49:182438 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2439 gfx::Vector2d(-50, -50)));
[email protected]aa043632013-03-25 03:39:422440 }
[email protected]df8f44f2013-01-08 08:00:312441}
2442
[email protected]aa043632013-03-25 03:39:422443TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
2444 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:402445 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:362446 DrawFrame();
[email protected]1c0c9bc2012-10-08 22:41:482447
[email protected]adeda572014-01-31 00:49:472448 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
[email protected]aa043632013-03-25 03:39:422449 DCHECK(scroll_layer);
[email protected]1c0c9bc2012-10-08 22:41:482450
[email protected]aa043632013-03-25 03:39:422451 float min_page_scale = 0.5f;
2452 float max_page_scale = 4.f;
2453 base::TimeTicks start_time = base::TimeTicks() +
2454 base::TimeDelta::FromSeconds(1);
2455 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
2456 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2457 base::TimeTicks end_time = start_time + duration;
[email protected]1c0c9bc2012-10-08 22:41:482458
danakj12e2f6e2015-08-19 22:25:442459 BeginFrameArgs begin_frame_args =
2460 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2461
[email protected]aa043632013-03-25 03:39:422462 // Anchor zoom with unchanged page scale should not change scroll or scale.
2463 {
aelias58eec0812014-12-04 01:04:402464 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422465 max_page_scale);
sunxdb7e79432016-03-09 21:13:422466 scroll_layer->layer_tree_impl()
2467 ->property_trees()
2468 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2469 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]c60279472013-01-30 12:10:512470
bokanfcdbc182014-11-21 21:53:332471 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482472 std::unique_ptr<PendingPageScaleAnimation>(
2473 new PendingPageScaleAnimation(gfx::Vector2d(), true, 1.f,
2474 duration)));
bokan915bf352014-10-02 21:57:142475 host_impl_->ActivateSyncTree();
danakj12e2f6e2015-08-19 22:25:442476 begin_frame_args.frame_time = start_time;
2477 host_impl_->WillBeginImplFrame(begin_frame_args);
2478 host_impl_->Animate();
2479 host_impl_->DidFinishImplFrame();
2480
2481 begin_frame_args.frame_time = halfway_through_animation;
2482 host_impl_->WillBeginImplFrame(begin_frame_args);
2483 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422484 EXPECT_TRUE(did_request_redraw_);
danakj12e2f6e2015-08-19 22:25:442485 host_impl_->DidFinishImplFrame();
2486
2487 begin_frame_args.frame_time = end_time;
2488 host_impl_->WillBeginImplFrame(begin_frame_args);
2489 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422490 EXPECT_TRUE(did_request_commit_);
danakj12e2f6e2015-08-19 22:25:442491 host_impl_->DidFinishImplFrame();
[email protected]c60279472013-01-30 12:10:512492
danakj60bc3bc2016-04-09 00:24:482493 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422494 host_impl_->ProcessScrollDeltas();
2495 EXPECT_EQ(scroll_info->page_scale_delta, 1);
2496 ExpectNone(*scroll_info, scroll_layer->id());
2497 }
[email protected]1c0c9bc2012-10-08 22:41:482498}
2499
bokan915bf352014-10-02 21:57:142500TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
2501 host_impl_->CreatePendingTree();
bokan0c33a092015-07-29 18:27:562502 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
bokan915bf352014-10-02 21:57:142503 CreateScrollAndContentsLayers(
2504 host_impl_->pending_tree(),
2505 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:482506 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
bokan915bf352014-10-02 21:57:142507 host_impl_->ActivateSyncTree();
2508 DrawFrame();
2509
2510 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
2511 DCHECK(scroll_layer);
2512
2513 float min_page_scale = 0.5f;
2514 float max_page_scale = 4.f;
aelias58eec0812014-12-04 01:04:402515 host_impl_->sync_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
bokan915bf352014-10-02 21:57:142516 max_page_scale);
2517 host_impl_->ActivateSyncTree();
2518
2519 base::TimeTicks start_time = base::TimeTicks() +
2520 base::TimeDelta::FromSeconds(1);
2521 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
aelias74c39352014-10-14 03:48:142522 base::TimeTicks third_through_animation = start_time + duration / 3;
bokan915bf352014-10-02 21:57:142523 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2524 base::TimeTicks end_time = start_time + duration;
2525 float target_scale = 2.f;
2526
danakj12e2f6e2015-08-19 22:25:442527 BeginFrameArgs begin_frame_args =
2528 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2529
sunxdb7e79432016-03-09 21:13:422530 scroll_layer->layer_tree_impl()
2531 ->property_trees()
2532 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
2533 gfx::ScrollOffset(50, 50));
bokan915bf352014-10-02 21:57:142534
2535 // Make sure TakePageScaleAnimation works properly.
bokanfcdbc182014-11-21 21:53:332536
2537 host_impl_->sync_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482538 std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
2539 gfx::Vector2d(), false, target_scale, duration)));
2540 std::unique_ptr<PendingPageScaleAnimation> psa =
bokanfcdbc182014-11-21 21:53:332541 host_impl_->sync_tree()->TakePendingPageScaleAnimation();
2542 EXPECT_EQ(target_scale, psa->scale);
2543 EXPECT_EQ(duration, psa->duration);
2544 EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePendingPageScaleAnimation());
bokan915bf352014-10-02 21:57:142545
2546 // Recreate the PSA. Nothing should happen here since the tree containing the
2547 // PSA hasn't been activated yet.
2548 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032549 did_request_next_frame_ = false;
bokanfcdbc182014-11-21 21:53:332550 host_impl_->sync_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482551 std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
2552 gfx::Vector2d(), false, target_scale, duration)));
danakj12e2f6e2015-08-19 22:25:442553 begin_frame_args.frame_time = halfway_through_animation;
2554 host_impl_->WillBeginImplFrame(begin_frame_args);
2555 host_impl_->Animate();
danakja18e826a2015-12-03 00:27:032556 EXPECT_FALSE(did_request_next_frame_);
bokan915bf352014-10-02 21:57:142557 EXPECT_FALSE(did_request_redraw_);
danakj12e2f6e2015-08-19 22:25:442558 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142559
2560 // Activate the sync tree. This should cause the animation to become enabled.
2561 // It should also clear the pointer on the sync tree.
2562 host_impl_->ActivateSyncTree();
bokanfcdbc182014-11-21 21:53:332563 EXPECT_EQ(nullptr,
2564 host_impl_->sync_tree()->TakePendingPageScaleAnimation().get());
bokan915bf352014-10-02 21:57:142565 EXPECT_FALSE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032566 EXPECT_TRUE(did_request_next_frame_);
bokan915bf352014-10-02 21:57:142567
danakj12e2f6e2015-08-19 22:25:442568 start_time += base::TimeDelta::FromSeconds(10);
2569 third_through_animation += base::TimeDelta::FromSeconds(10);
2570 halfway_through_animation += base::TimeDelta::FromSeconds(10);
2571 end_time += base::TimeDelta::FromSeconds(10);
2572
bokan915bf352014-10-02 21:57:142573 // From here on, make sure the animation runs as normal.
2574 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032575 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442576 begin_frame_args.frame_time = start_time;
2577 host_impl_->WillBeginImplFrame(begin_frame_args);
2578 host_impl_->Animate();
bokan915bf352014-10-02 21:57:142579 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032580 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442581 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142582
2583 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032584 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442585 begin_frame_args.frame_time = third_through_animation;
2586 host_impl_->WillBeginImplFrame(begin_frame_args);
2587 host_impl_->Animate();
aelias74c39352014-10-14 03:48:142588 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032589 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442590 host_impl_->DidFinishImplFrame();
aelias74c39352014-10-14 03:48:142591
2592 // Another activation shouldn't have any effect on the animation.
2593 host_impl_->ActivateSyncTree();
2594
2595 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032596 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442597 begin_frame_args.frame_time = halfway_through_animation;
2598 host_impl_->WillBeginImplFrame(begin_frame_args);
2599 host_impl_->Animate();
bokan915bf352014-10-02 21:57:142600 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032601 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442602 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142603
2604 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032605 did_request_next_frame_ = false;
bokan915bf352014-10-02 21:57:142606 did_request_commit_ = false;
danakj12e2f6e2015-08-19 22:25:442607 begin_frame_args.frame_time = end_time;
2608 host_impl_->WillBeginImplFrame(begin_frame_args);
2609 host_impl_->Animate();
bokan915bf352014-10-02 21:57:142610 EXPECT_TRUE(did_request_commit_);
danakja18e826a2015-12-03 00:27:032611 EXPECT_FALSE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442612 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142613
danakj60bc3bc2016-04-09 00:24:482614 std::unique_ptr<ScrollAndScaleSet> scroll_info =
bokan915bf352014-10-02 21:57:142615 host_impl_->ProcessScrollDeltas();
2616 EXPECT_EQ(scroll_info->page_scale_delta, target_scale);
tdresser99977952015-07-02 19:49:182617 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2618 gfx::Vector2d(-50, -50)));
bokan915bf352014-10-02 21:57:142619}
2620
rouslanf7ebd8832015-01-22 01:54:142621TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
2622 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2623 host_impl_->SetViewportSize(gfx::Size(50, 50));
2624 DrawFrame();
2625
2626 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
2627 DCHECK(scroll_layer);
2628
2629 base::TimeTicks start_time =
2630 base::TimeTicks() + base::TimeDelta::FromSeconds(1);
2631 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
2632 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2633 base::TimeTicks end_time = start_time + duration;
2634
danakj12e2f6e2015-08-19 22:25:442635 BeginFrameArgs begin_frame_args =
2636 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2637
rouslanf7ebd8832015-01-22 01:54:142638 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
sunxdb7e79432016-03-09 21:13:422639 scroll_layer->layer_tree_impl()
2640 ->property_trees()
2641 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
2642 gfx::ScrollOffset(50, 50));
rouslanf7ebd8832015-01-22 01:54:142643
2644 did_complete_page_scale_animation_ = false;
2645 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482646 std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
rouslanf7ebd8832015-01-22 01:54:142647 gfx::Vector2d(), false, 2.f, duration)));
2648 host_impl_->ActivateSyncTree();
danakj12e2f6e2015-08-19 22:25:442649 begin_frame_args.frame_time = start_time;
2650 host_impl_->WillBeginImplFrame(begin_frame_args);
2651 host_impl_->Animate();
rouslanf7ebd8832015-01-22 01:54:142652 EXPECT_FALSE(did_complete_page_scale_animation_);
danakj12e2f6e2015-08-19 22:25:442653 host_impl_->DidFinishImplFrame();
rouslanf7ebd8832015-01-22 01:54:142654
danakj12e2f6e2015-08-19 22:25:442655 begin_frame_args.frame_time = halfway_through_animation;
2656 host_impl_->WillBeginImplFrame(begin_frame_args);
2657 host_impl_->Animate();
rouslanf7ebd8832015-01-22 01:54:142658 EXPECT_FALSE(did_complete_page_scale_animation_);
danakj12e2f6e2015-08-19 22:25:442659 host_impl_->DidFinishImplFrame();
rouslanf7ebd8832015-01-22 01:54:142660
danakj12e2f6e2015-08-19 22:25:442661 begin_frame_args.frame_time = end_time;
2662 host_impl_->WillBeginImplFrame(begin_frame_args);
2663 host_impl_->Animate();
rouslanf7ebd8832015-01-22 01:54:142664 EXPECT_TRUE(did_complete_page_scale_animation_);
danakj12e2f6e2015-08-19 22:25:442665 host_impl_->DidFinishImplFrame();
rouslanf7ebd8832015-01-22 01:54:142666}
2667
sunxdcfccd1b32016-02-11 00:54:202668TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByBoundsDelta) {
2669 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2670 host_impl_->SetViewportSize(gfx::Size(50, 50));
2671 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
danakj74af409e2016-07-01 00:41:482672 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxdcfccd1b32016-02-11 00:54:202673 DrawFrame();
2674
2675 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
2676 LayerImpl* inner_container = inner_scroll->scroll_clip_layer();
2677 DCHECK(inner_scroll);
2678 DCHECK(inner_container);
2679 EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset());
2680
2681 inner_container->SetBoundsDelta(gfx::Vector2dF(15.f, 15.f));
2682 inner_scroll->SetBoundsDelta(gfx::Vector2dF(7.f, 7.f));
2683 EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset());
2684
2685 inner_container->SetBoundsDelta(gfx::Vector2dF());
2686 inner_scroll->SetBoundsDelta(gfx::Vector2dF());
2687 inner_scroll->SetBounds(gfx::Size());
danakj74af409e2016-07-01 00:41:482688 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxdcfccd1b32016-02-11 00:54:202689 DrawFrame();
2690
2691 inner_scroll->SetBoundsDelta(gfx::Vector2dF(60.f, 60.f));
2692 EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset());
2693}
2694
[email protected]21c9dee72013-06-15 01:20:052695class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
2696 public:
2697 LayerTreeHostImplOverridePhysicalTime(
2698 const LayerTreeSettings& settings,
2699 LayerTreeHostImplClient* client,
khushalsagarb64b360d2015-10-21 19:25:162700 TaskRunnerProvider* task_runner_provider,
[email protected]4e2eb352014-03-20 17:25:452701 SharedBitmapManager* manager,
danakjcf610582015-06-16 22:48:562702 TaskGraphRunner* task_graph_runner,
[email protected]21c9dee72013-06-15 01:20:052703 RenderingStatsInstrumentation* rendering_stats_instrumentation)
2704 : LayerTreeHostImpl(settings,
2705 client,
khushalsagarb64b360d2015-10-21 19:25:162706 task_runner_provider,
[email protected]a7f35682013-10-22 23:05:572707 rendering_stats_instrumentation,
[email protected]4e2eb352014-03-20 17:25:452708 manager,
danakjcf610582015-06-16 22:48:562709 nullptr,
2710 task_graph_runner,
loysoab32ee72016-06-08 03:33:182711 AnimationHost::CreateForTesting(ThreadInstance::IMPL),
[email protected]dbe759a2013-12-02 19:23:022712 0) {}
[email protected]21c9dee72013-06-15 01:20:052713
dcheng716bedf2014-10-21 09:51:082714 BeginFrameArgs CurrentBeginFrameArgs() const override {
mithro06d1f3bf2014-12-02 02:19:152715 return CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE,
2716 fake_current_physical_time_);
[email protected]21c9dee72013-06-15 01:20:052717 }
2718
2719 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) {
2720 fake_current_physical_time_ = fake_now;
2721 }
2722
2723 private:
2724 base::TimeTicks fake_current_physical_time_;
2725};
2726
sunnyps102dbf692015-03-07 02:17:462727class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
2728 protected:
2729 void SetupLayers(LayerTreeSettings settings) {
danakjee6547a22016-07-01 20:41:502730 host_impl_->ReleaseOutputSurface();
2731 host_impl_ = nullptr;
2732
sunnyps102dbf692015-03-07 02:17:462733 gfx::Size content_size(100, 100);
[email protected]e6e7f292014-04-24 22:23:032734
sunnyps102dbf692015-03-07 02:17:462735 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =
danakjcf610582015-06-16 22:48:562736 new LayerTreeHostImplOverridePhysicalTime(
khushalsagarb64b360d2015-10-21 19:25:162737 settings, this, &task_runner_provider_, &shared_bitmap_manager_,
danakjcf610582015-06-16 22:48:562738 &task_graph_runner_, &stats_instrumentation_);
danakj60bc3bc2016-04-09 00:24:482739 host_impl_ = base::WrapUnique(host_impl_override_time);
revemand180dfc32015-09-24 00:19:432740 output_surface_ = CreateOutputSurface();
sievers71c62dd52015-10-07 01:44:392741 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:432742 host_impl_->InitializeRenderer(output_surface_.get());
[email protected]21c9dee72013-06-15 01:20:052743
bokan1f86d8f2015-07-30 16:08:542744 SetupScrollAndContentsLayers(content_size);
2745 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
2746 host_impl_->SetViewportSize(
2747 gfx::Size(content_size.width() / 2, content_size.height() / 2));
[email protected]21c9dee72013-06-15 01:20:052748
danakj60bc3bc2016-04-09 00:24:482749 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
bokan1f86d8f2015-07-30 16:08:542750 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 400,
sunnyps102dbf692015-03-07 02:17:462751 VERTICAL, 10, 0, false, true);
jaydasikaab317e02016-06-01 00:53:182752 scrollbar->test_properties()->opacity = 0.f;
2753 EXPECT_FLOAT_EQ(0.f, scrollbar->test_properties()->opacity);
[email protected]cdc07002013-09-06 22:33:462754
aeliasa57c40d122015-10-08 00:20:092755 LayerImpl* scroll = host_impl_->active_tree()->OuterViewportScrollLayer();
2756 LayerImpl* root = host_impl_->active_tree()->InnerViewportContainerLayer();
2757 scrollbar->SetScrollLayerId(scroll->id());
jaydasika89f7b5a2016-06-22 02:08:392758 root->test_properties()->AddChild(std::move(scrollbar));
danakj74af409e2016-07-01 00:41:482759 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunnyps102dbf692015-03-07 02:17:462760 host_impl_->active_tree()->DidBecomeActive();
2761 DrawFrame();
2762 }
sunnypsae4316a2015-02-25 00:54:582763
sunnyps102dbf692015-03-07 02:17:462764 void RunTest(LayerTreeSettings::ScrollbarAnimator animator) {
weiliangc8f4ef0d2015-11-27 00:15:552765 LayerTreeSettings settings = DefaultSettings();
sunnyps102dbf692015-03-07 02:17:462766 settings.scrollbar_animator = animator;
2767 settings.scrollbar_fade_delay_ms = 20;
2768 settings.scrollbar_fade_duration_ms = 20;
[email protected]21c9dee72013-06-15 01:20:052769
eseckler025a0202016-08-05 09:16:122770 // If no animator is set, scrollbar won't show and no animation is expected.
2771 bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR;
2772
sunnyps102dbf692015-03-07 02:17:462773 SetupLayers(settings);
[email protected]21c9dee72013-06-15 01:20:052774
abhishek.ka7215854d2015-05-26 06:13:172775 base::TimeTicks fake_now = base::TimeTicks::Now();
sataya.m68d7d9b42014-09-22 16:01:592776
eseckler025a0202016-08-05 09:16:122777 if (expecting_animations) {
2778 // A task will be posted to fade the initial scrollbar.
2779 EXPECT_FALSE(did_request_next_frame_);
2780 EXPECT_FALSE(did_request_redraw_);
2781 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2782 requested_animation_delay_ = base::TimeDelta();
2783 animation_task_ = base::Closure();
2784 } else {
2785 EXPECT_FALSE(did_request_next_frame_);
2786 EXPECT_FALSE(did_request_redraw_);
2787 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2788 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2789 }
sunnypsae4316a2015-02-25 00:54:582790
sunnyps102dbf692015-03-07 02:17:462791 // If no scroll happened during a scroll gesture, it should have no effect.
majidvp944a8cd2016-01-12 21:05:182792 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
2793 InputHandler::WHEEL);
2794 host_impl_->ScrollEnd(EndState().get());
danakja18e826a2015-12-03 00:27:032795 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462796 EXPECT_FALSE(did_request_redraw_);
2797 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2798 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2799
danakja18e826a2015-12-03 00:27:032800 // Before the scrollbar animation exists, we should not get redraws.
2801 BeginFrameArgs begin_frame_args =
2802 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2803 host_impl_->WillBeginImplFrame(begin_frame_args);
2804 host_impl_->Animate();
2805 EXPECT_FALSE(did_request_next_frame_);
2806 did_request_next_frame_ = false;
2807 EXPECT_FALSE(did_request_redraw_);
2808 did_request_redraw_ = false;
2809 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2810 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2811 host_impl_->DidFinishImplFrame();
2812
sunnyps102dbf692015-03-07 02:17:462813 // After a scroll, a scrollbar animation should be scheduled about 20ms from
2814 // now.
majidvp944a8cd2016-01-12 21:05:182815 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
2816 InputHandler::WHEEL);
2817 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get());
danakja18e826a2015-12-03 00:27:032818 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462819 EXPECT_TRUE(did_request_redraw_);
2820 did_request_redraw_ = false;
2821 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2822 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2823
majidvp944a8cd2016-01-12 21:05:182824 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:492825 host_impl_->ClearCurrentlyScrollingLayerForTesting();
danakja18e826a2015-12-03 00:27:032826 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462827 EXPECT_FALSE(did_request_redraw_);
eseckler025a0202016-08-05 09:16:122828 if (expecting_animations) {
2829 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
2830 requested_animation_delay_);
2831 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2832 } else {
2833 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2834 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2835 }
sunnyps102dbf692015-03-07 02:17:462836
eseckler025a0202016-08-05 09:16:122837 if (expecting_animations) {
2838 // Before the scrollbar animation begins, we should not get redraws.
2839 begin_frame_args =
2840 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2841 host_impl_->WillBeginImplFrame(begin_frame_args);
2842 host_impl_->Animate();
2843 EXPECT_FALSE(did_request_next_frame_);
2844 did_request_next_frame_ = false;
2845 EXPECT_FALSE(did_request_redraw_);
2846 did_request_redraw_ = false;
2847 host_impl_->DidFinishImplFrame();
danakja18e826a2015-12-03 00:27:032848
eseckler025a0202016-08-05 09:16:122849 // Start the scrollbar animation.
2850 fake_now += requested_animation_delay_;
2851 requested_animation_delay_ = base::TimeDelta();
2852 animation_task_.Run();
2853 animation_task_ = base::Closure();
2854 EXPECT_TRUE(did_request_next_frame_);
2855 did_request_next_frame_ = false;
2856 EXPECT_FALSE(did_request_redraw_);
sunnyps102dbf692015-03-07 02:17:462857
eseckler025a0202016-08-05 09:16:122858 // After the scrollbar animation begins, we should start getting redraws.
2859 begin_frame_args =
2860 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2861 host_impl_->WillBeginImplFrame(begin_frame_args);
2862 host_impl_->Animate();
2863 EXPECT_TRUE(did_request_next_frame_);
2864 did_request_next_frame_ = false;
2865 EXPECT_TRUE(did_request_redraw_);
2866 did_request_redraw_ = false;
2867 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2868 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2869 host_impl_->DidFinishImplFrame();
2870 }
sunnyps102dbf692015-03-07 02:17:462871
2872 // Setting the scroll offset outside a scroll should also cause the
2873 // scrollbar to appear and to schedule a scrollbar animation.
sunxdb7e79432016-03-09 21:13:422874 if (host_impl_->active_tree()
2875 ->property_trees()
2876 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2877 host_impl_->InnerViewportScrollLayer()->id(),
2878 gfx::ScrollOffset(5, 5)))
sunxdc044b11a2016-03-16 16:23:202879 host_impl_->active_tree()->DidUpdateScrollOffset(
2880 host_impl_->InnerViewportScrollLayer()->id(),
2881 host_impl_->InnerViewportScrollLayer()->transform_tree_index());
danakja18e826a2015-12-03 00:27:032882 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462883 EXPECT_FALSE(did_request_redraw_);
eseckler025a0202016-08-05 09:16:122884 if (expecting_animations) {
2885 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
2886 requested_animation_delay_);
2887 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2888 requested_animation_delay_ = base::TimeDelta();
2889 animation_task_ = base::Closure();
2890 } else {
2891 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2892 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2893 }
sunnyps102dbf692015-03-07 02:17:462894
eseckler025a0202016-08-05 09:16:122895 if (expecting_animations) {
2896 // Scrolling should have stopped the animation, so we should not be
2897 // getting redraws.
2898 begin_frame_args =
2899 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2900 host_impl_->WillBeginImplFrame(begin_frame_args);
2901 host_impl_->Animate();
2902 EXPECT_FALSE(did_request_next_frame_);
2903 did_request_next_frame_ = false;
2904 EXPECT_FALSE(did_request_redraw_);
2905 did_request_redraw_ = false;
2906 host_impl_->DidFinishImplFrame();
2907 }
danakja18e826a2015-12-03 00:27:032908
sunnyps102dbf692015-03-07 02:17:462909 // Scrollbar animation is not triggered unnecessarily.
majidvp944a8cd2016-01-12 21:05:182910 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
2911 InputHandler::WHEEL);
2912 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(5, 0)).get());
danakja18e826a2015-12-03 00:27:032913 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462914 EXPECT_TRUE(did_request_redraw_);
2915 did_request_redraw_ = false;
2916 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2917 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2918
majidvp944a8cd2016-01-12 21:05:182919 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:492920 host_impl_->ClearCurrentlyScrollingLayerForTesting();
danakja18e826a2015-12-03 00:27:032921 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462922 EXPECT_FALSE(did_request_redraw_);
2923 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2924 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2925
2926 // Changing page scale triggers scrollbar animation.
2927 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
danakj5ad246cd2015-09-12 01:04:502928 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.1f);
danakja18e826a2015-12-03 00:27:032929 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462930 EXPECT_FALSE(did_request_redraw_);
eseckler025a0202016-08-05 09:16:122931 if (expecting_animations) {
2932 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
2933 requested_animation_delay_);
2934 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2935 requested_animation_delay_ = base::TimeDelta();
2936 animation_task_ = base::Closure();
2937 } else {
2938 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2939 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2940 }
sunnyps102dbf692015-03-07 02:17:462941 }
2942};
2943
2944TEST_F(LayerTreeHostImplTestScrollbarAnimation, LinearFade) {
2945 RunTest(LayerTreeSettings::LINEAR_FADE);
[email protected]21c9dee72013-06-15 01:20:052946}
2947
sunnyps102dbf692015-03-07 02:17:462948TEST_F(LayerTreeHostImplTestScrollbarAnimation, Thinning) {
2949 RunTest(LayerTreeSettings::THINNING);
[email protected]e6e7f292014-04-24 22:23:032950}
2951
eseckler025a0202016-08-05 09:16:122952TEST_F(LayerTreeHostImplTestScrollbarAnimation, NoAnimator) {
2953 RunTest(LayerTreeSettings::NO_ANIMATOR);
2954}
2955
jaydasika4f290d82015-09-18 20:25:212956class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
2957 protected:
2958 void RunTest(LayerTreeSettings::ScrollbarAnimator animator) {
weiliangc8f4ef0d2015-11-27 00:15:552959 LayerTreeSettings settings = DefaultSettings();
jaydasika4f290d82015-09-18 20:25:212960 settings.scrollbar_animator = animator;
2961 settings.scrollbar_fade_delay_ms = 20;
2962 settings.scrollbar_fade_duration_ms = 20;
jaydasika4f290d82015-09-18 20:25:212963 gfx::Size content_size(100, 100);
2964
eseckler025a0202016-08-05 09:16:122965 // If no animator is set, scrollbar won't show and no animation is expected.
2966 bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR;
2967
jaydasika4f290d82015-09-18 20:25:212968 CreateHostImpl(settings, CreateOutputSurface());
2969 host_impl_->CreatePendingTree();
2970 CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size);
danakj60bc3bc2016-04-09 00:24:482971 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
jaydasika4f290d82015-09-18 20:25:212972 SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400,
2973 VERTICAL, 10, 0, false, true);
jaydasikaab317e02016-06-01 00:53:182974 scrollbar->test_properties()->opacity = 0.f;
aeliasa57c40d122015-10-08 00:20:092975 LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer();
jaydasika52c00182016-06-02 08:57:172976 LayerImpl* container =
2977 host_impl_->pending_tree()->InnerViewportContainerLayer();
aeliasa57c40d122015-10-08 00:20:092978 scrollbar->SetScrollLayerId(scroll->id());
jaydasika89f7b5a2016-06-22 02:08:392979 container->test_properties()->AddChild(std::move(scrollbar));
jaydasika4f290d82015-09-18 20:25:212980 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
danakj74af409e2016-07-01 00:41:482981 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasika4f290d82015-09-18 20:25:212982 host_impl_->ActivateSyncTree();
2983
jaydasika52c00182016-06-02 08:57:172984 LayerImpl* active_scrollbar_layer =
2985 host_impl_->active_tree()->LayerById(400);
jaydasika4f290d82015-09-18 20:25:212986
2987 EffectNode* active_tree_node =
2988 host_impl_->active_tree()->property_trees()->effect_tree.Node(
jaydasika52c00182016-06-02 08:57:172989 active_scrollbar_layer->effect_tree_index());
2990 EXPECT_FLOAT_EQ(active_scrollbar_layer->Opacity(),
trchendba8b1502016-07-08 09:47:012991 active_tree_node->opacity);
jaydasika4f290d82015-09-18 20:25:212992
eseckler025a0202016-08-05 09:16:122993 if (expecting_animations) {
2994 host_impl_->ScrollbarAnimationControllerForId(scroll->id())
2995 ->DidMouseMoveNear(0);
2996 } else {
2997 EXPECT_EQ(nullptr,
2998 host_impl_->ScrollbarAnimationControllerForId(scroll->id()));
2999 }
majidvp944a8cd2016-01-12 21:05:183000 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
3001 InputHandler::WHEEL);
3002 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get());
3003 host_impl_->ScrollEnd(EndState().get());
jaydasika4f290d82015-09-18 20:25:213004 host_impl_->CreatePendingTree();
jaydasika52c00182016-06-02 08:57:173005 // To test the case where the effect tree index of scrollbar layer changes,
3006 // we force the container layer to create a render surface.
3007 container = host_impl_->pending_tree()->InnerViewportContainerLayer();
3008 container->test_properties()->force_render_surface = true;
3009 container->SetBounds(gfx::Size(10, 10));
danakj74af409e2016-07-01 00:41:483010 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasika52c00182016-06-02 08:57:173011
3012 LayerImpl* pending_scrollbar_layer =
3013 host_impl_->pending_tree()->LayerById(400);
eseckler025a0202016-08-05 09:16:123014 pending_scrollbar_layer->SetNeedsPushProperties();
jaydasika4f290d82015-09-18 20:25:213015 EffectNode* pending_tree_node =
3016 host_impl_->pending_tree()->property_trees()->effect_tree.Node(
jaydasika52c00182016-06-02 08:57:173017 pending_scrollbar_layer->effect_tree_index());
jaydasikaae9b7a02016-05-19 16:12:523018 host_impl_->pending_tree()
3019 ->property_trees()
3020 ->always_use_active_tree_opacity_effect_ids.push_back(400);
eseckler025a0202016-08-05 09:16:123021 if (expecting_animations) {
3022 EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity);
3023 EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity());
3024 } else {
3025 EXPECT_FLOAT_EQ(0.f, active_tree_node->opacity);
3026 EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity());
3027 }
trchendba8b1502016-07-08 09:47:013028 EXPECT_FLOAT_EQ(0.f, pending_tree_node->opacity);
jaydasika4f290d82015-09-18 20:25:213029 host_impl_->ActivateSyncTree();
3030 active_tree_node =
3031 host_impl_->active_tree()->property_trees()->effect_tree.Node(
jaydasika52c00182016-06-02 08:57:173032 active_scrollbar_layer->effect_tree_index());
eseckler025a0202016-08-05 09:16:123033 if (expecting_animations) {
3034 EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity);
3035 EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity());
3036 } else {
3037 EXPECT_FLOAT_EQ(0.f, active_tree_node->opacity);
3038 EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity());
3039 }
jaydasika4f290d82015-09-18 20:25:213040 }
3041};
3042
3043TEST_F(LayerTreeHostImplTestScrollbarOpacity, LinearFade) {
3044 RunTest(LayerTreeSettings::LINEAR_FADE);
3045}
3046
3047TEST_F(LayerTreeHostImplTestScrollbarOpacity, Thinning) {
3048 RunTest(LayerTreeSettings::THINNING);
3049}
3050
eseckler025a0202016-08-05 09:16:123051TEST_F(LayerTreeHostImplTestScrollbarOpacity, NoAnimator) {
3052 RunTest(LayerTreeSettings::NO_ANIMATOR);
3053}
3054
aelias14d87e0c2015-11-04 00:12:503055TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) {
weiliangc8f4ef0d2015-11-27 00:15:553056 LayerTreeSettings settings = DefaultSettings();
aelias14d87e0c2015-11-04 00:12:503057 CreateHostImpl(settings, CreateOutputSurface());
3058
3059 gfx::Size inner_viewport_size(315, 200);
3060 gfx::Size outer_viewport_size(300, 200);
3061 gfx::Size content_size(1000, 1000);
3062
3063 const int horiz_id = 11;
3064 const int child_clip_id = 14;
3065 const int child_scroll_id = 15;
3066
3067 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
3068 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3069 inner_viewport_size);
3070 host_impl_->active_tree()->OuterViewportContainerLayer()->SetBounds(
3071 outer_viewport_size);
3072 LayerImpl* root_scroll =
3073 host_impl_->active_tree()->OuterViewportScrollLayer();
danakj60bc3bc2016-04-09 00:24:483074 std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar =
aelias14d87e0c2015-11-04 00:12:503075 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id,
3076 HORIZONTAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483077 std::unique_ptr<LayerImpl> child =
aelias14d87e0c2015-11-04 00:12:503078 LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
3079 child->SetBounds(content_size);
danakj60bc3bc2016-04-09 00:24:483080 std::unique_ptr<LayerImpl> child_clip =
aelias14d87e0c2015-11-04 00:12:503081 LayerImpl::Create(host_impl_->active_tree(), child_clip_id);
3082 child->SetBounds(inner_viewport_size);
3083
3084 horiz_scrollbar->SetScrollLayerId(root_scroll->id());
3085
3086 EXPECT_EQ(300, horiz_scrollbar->clip_layer_length());
3087}
3088
aeliasa57c40d122015-10-08 00:20:093089TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
weiliangc8f4ef0d2015-11-27 00:15:553090 LayerTreeSettings settings = DefaultSettings();
aeliasa57c40d122015-10-08 00:20:093091 settings.scrollbar_animator = LayerTreeSettings::LINEAR_FADE;
3092 settings.scrollbar_fade_delay_ms = 20;
3093 settings.scrollbar_fade_duration_ms = 20;
3094 CreateHostImpl(settings, CreateOutputSurface());
3095
3096 gfx::Size viewport_size(300, 200);
3097 gfx::Size content_size(1000, 1000);
3098
3099 const int vert_1_id = 10;
3100 const int horiz_1_id = 11;
3101 const int vert_2_id = 12;
3102 const int horiz_2_id = 13;
3103 const int child_clip_id = 14;
3104 const int child_scroll_id = 15;
3105
3106 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
3107 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3108 viewport_size);
3109 LayerImpl* root_scroll =
3110 host_impl_->active_tree()->OuterViewportScrollLayer();
danakj60bc3bc2016-04-09 00:24:483111 std::unique_ptr<SolidColorScrollbarLayerImpl> vert_1_scrollbar =
aeliasa57c40d122015-10-08 00:20:093112 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_1_id,
3113 VERTICAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483114 std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_1_scrollbar =
aeliasa57c40d122015-10-08 00:20:093115 SolidColorScrollbarLayerImpl::Create(
3116 host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483117 std::unique_ptr<SolidColorScrollbarLayerImpl> vert_2_scrollbar =
aeliasa57c40d122015-10-08 00:20:093118 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_2_id,
3119 VERTICAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483120 std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_2_scrollbar =
aeliasa57c40d122015-10-08 00:20:093121 SolidColorScrollbarLayerImpl::Create(
3122 host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483123 std::unique_ptr<LayerImpl> child =
aeliasa57c40d122015-10-08 00:20:093124 LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
3125 child->SetBounds(content_size);
danakj60bc3bc2016-04-09 00:24:483126 std::unique_ptr<LayerImpl> child_clip =
aeliasa57c40d122015-10-08 00:20:093127 LayerImpl::Create(host_impl_->active_tree(), child_clip_id);
3128 child->SetBounds(viewport_size);
3129 LayerImpl* child_ptr = child.get();
3130 LayerImpl* child_clip_ptr = child_clip.get();
3131
3132 // Check scrollbar registration on the viewport layers.
3133 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3134 EXPECT_EQ(nullptr,
3135 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3136 vert_1_scrollbar->SetScrollLayerId(root_scroll->id());
3137 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3138 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3139 horiz_1_scrollbar->SetScrollLayerId(root_scroll->id());
3140 EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3141 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3142
3143 // Changing one of the viewport layers should result in a scrollbar animation
3144 // update.
3145 animation_task_ = base::Closure();
3146 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBoundsDelta(
3147 gfx::Vector2dF(10, 10));
3148 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3149 animation_task_ = base::Closure();
3150 host_impl_->active_tree()->OuterViewportScrollLayer()->SetCurrentScrollOffset(
3151 gfx::ScrollOffset(10, 10));
3152 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3153 animation_task_ = base::Closure();
3154 host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset(
3155 gfx::ScrollOffset(10, 10));
3156 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3157 animation_task_ = base::Closure();
3158
3159 // Check scrollbar registration on a sublayer.
3160 child->SetScrollClipLayer(child_clip->id());
jaydasika89f7b5a2016-06-22 02:08:393161 child_clip->test_properties()->AddChild(std::move(child));
3162 root_scroll->test_properties()->AddChild(std::move(child_clip));
aeliasa57c40d122015-10-08 00:20:093163 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3164 EXPECT_EQ(nullptr,
3165 host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3166 vert_2_scrollbar->SetScrollLayerId(child_scroll_id);
3167 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3168 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3169 horiz_2_scrollbar->SetScrollLayerId(child_scroll_id);
3170 EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3171 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3172
3173 // Changing one of the child layers should result in a scrollbar animation
3174 // update.
3175 animation_task_ = base::Closure();
3176 child_clip_ptr->SetBounds(gfx::Size(200, 200));
3177 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3178 animation_task_ = base::Closure();
3179 child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(10, 10));
3180 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3181 animation_task_ = base::Closure();
3182
3183 // Check scrollbar unregistration.
3184 vert_1_scrollbar.reset();
3185 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3186 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3187 horiz_1_scrollbar.reset();
3188 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3189 EXPECT_EQ(nullptr,
3190 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3191
3192 EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3193 vert_2_scrollbar.reset();
3194 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3195 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3196 horiz_2_scrollbar.reset();
3197 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3198 EXPECT_EQ(nullptr,
3199 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3200
3201 // Changing scroll offset should no longer trigger any animation.
3202 host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset(
3203 gfx::ScrollOffset(20, 20));
3204 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
3205 child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(20, 20));
3206 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
3207}
3208
[email protected]bf1cfd9a2013-09-26 05:43:023209void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
3210 float device_scale_factor) {
weiliangc8f4ef0d2015-11-27 00:15:553211 LayerTreeSettings settings = DefaultSettings();
[email protected]930ff43b2014-05-02 05:24:003212 settings.scrollbar_fade_delay_ms = 500;
3213 settings.scrollbar_fade_duration_ms = 300;
ericrk7c030992015-02-20 01:39:383214 settings.scrollbar_animator = LayerTreeSettings::THINNING;
[email protected]bf1cfd9a2013-09-26 05:43:023215
3216 gfx::Size viewport_size(300, 200);
danakjddaec912015-09-25 19:38:403217 gfx::Size device_viewport_size =
3218 gfx::ScaleToFlooredSize(viewport_size, device_scale_factor);
[email protected]bf1cfd9a2013-09-26 05:43:023219 gfx::Size content_size(1000, 1000);
aeliasa57c40d122015-10-08 00:20:093220 gfx::Size scrollbar_size(gfx::Size(15, viewport_size.height()));
[email protected]bf1cfd9a2013-09-26 05:43:023221
[email protected]ce2e8112013-11-28 07:44:363222 CreateHostImpl(settings, CreateOutputSurface());
ajuma1d48e012015-09-25 22:24:163223 host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor);
[email protected]bf1cfd9a2013-09-26 05:43:023224 host_impl_->SetViewportSize(device_viewport_size);
3225
aeliasa57c40d122015-10-08 00:20:093226 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
3227 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3228 viewport_size);
[email protected]adeda572014-01-31 00:49:473229 LayerImpl* root_scroll =
aeliasa57c40d122015-10-08 00:20:093230 host_impl_->active_tree()->OuterViewportScrollLayer();
3231 // The scrollbar is on the left side.
danakj60bc3bc2016-04-09 00:24:483232 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
aeliasa57c40d122015-10-08 00:20:093233 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6,
3234 VERTICAL, 5, 5, true, true);
3235 scrollbar->SetScrollLayerId(root_scroll->id());
3236 scrollbar->SetDrawsContent(true);
3237 scrollbar->SetBounds(scrollbar_size);
3238 scrollbar->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size));
jaydasika89f7b5a2016-06-22 02:08:393239 host_impl_->active_tree()
3240 ->InnerViewportContainerLayer()
3241 ->test_properties()
3242 ->AddChild(std::move(scrollbar));
danakj74af409e2016-07-01 00:41:483243 host_impl_->active_tree()->BuildPropertyTreesForTesting();
aeliasa57c40d122015-10-08 00:20:093244 host_impl_->active_tree()->DidBecomeActive();
3245
3246 DrawFrame();
3247 host_impl_->active_tree()->UpdateDrawProperties(false);
3248
[email protected]bf1cfd9a2013-09-26 05:43:023249 ScrollbarAnimationControllerThinning* scrollbar_animation_controller =
3250 static_cast<ScrollbarAnimationControllerThinning*>(
aeliasa57c40d122015-10-08 00:20:093251 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
[email protected]bf1cfd9a2013-09-26 05:43:023252 scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
3253
aeliasa57c40d122015-10-08 00:20:093254 host_impl_->MouseMoveAt(gfx::Point(200, 1));
[email protected]534236b2013-10-25 21:19:203255 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023256
aeliasa57c40d122015-10-08 00:20:093257 host_impl_->MouseMoveAt(gfx::Point(100, 50));
[email protected]534236b2013-10-25 21:19:203258 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023259
aeliasa57c40d122015-10-08 00:20:093260 host_impl_->MouseMoveAt(gfx::Point(116, 100));
[email protected]534236b2013-10-25 21:19:203261 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023262
3263 scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
aeliasa57c40d122015-10-08 00:20:093264 host_impl_->MouseMoveAt(gfx::Point(116, 100));
[email protected]534236b2013-10-25 21:19:203265 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]f620b0e72013-10-01 21:38:243266
3267 did_request_redraw_ = false;
aeliasa57c40d122015-10-08 00:20:093268 EXPECT_EQ(Layer::INVALID_ID,
3269 host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
3270 host_impl_->MouseMoveAt(gfx::Point(10, 100));
3271 EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
3272 host_impl_->MouseMoveAt(gfx::Point(10, 120));
3273 EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
[email protected]f620b0e72013-10-01 21:38:243274 host_impl_->MouseMoveAt(gfx::Point(150, 120));
aeliasa57c40d122015-10-08 00:20:093275 EXPECT_EQ(Layer::INVALID_ID,
3276 host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023277}
3278
3279TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
3280 SetupMouseMoveAtWithDeviceScale(1.f);
3281}
3282
3283TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
3284 SetupMouseMoveAtWithDeviceScale(2.f);
3285}
3286
[email protected]aa043632013-03-25 03:39:423287TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
3288 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:403289 host_impl_->SetViewportSize(gfx::Size(50, 50));
aelias58eec0812014-12-04 01:04:403290 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:363291 DrawFrame();
[email protected]aa043632013-03-25 03:39:423292 {
3293 CompositorFrameMetadata metadata =
3294 host_impl_->MakeCompositorFrameMetadata();
3295 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
3296 EXPECT_EQ(1.f, metadata.page_scale_factor);
[email protected]f3f611f2014-07-09 04:05:323297 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size);
[email protected]aa043632013-03-25 03:39:423298 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
3299 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
3300 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
jdduke2afdbf722015-02-12 06:28:203301 EXPECT_FALSE(metadata.root_overflow_x_hidden);
3302 EXPECT_FALSE(metadata.root_overflow_y_hidden);
[email protected]aa043632013-03-25 03:39:423303 }
[email protected]94f206c12012-08-25 00:09:143304
[email protected]aa043632013-03-25 03:39:423305 // Scrolling should update metadata immediately.
tdresser81e84c672016-01-18 23:21:223306 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:183307 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:223308 InputHandler::WHEEL)
3309 .thread);
majidvp944a8cd2016-01-12 21:05:183310 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
[email protected]aa043632013-03-25 03:39:423311 {
3312 CompositorFrameMetadata metadata =
3313 host_impl_->MakeCompositorFrameMetadata();
3314 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3315 }
majidvp944a8cd2016-01-12 21:05:183316 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:423317 {
3318 CompositorFrameMetadata metadata =
3319 host_impl_->MakeCompositorFrameMetadata();
3320 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3321 }
[email protected]94f206c12012-08-25 00:09:143322
hush33370e12015-04-07 03:49:503323 // Root "overflow: hidden" properties should be reflected on the outer
3324 // viewport scroll layer.
jdduke2afdbf722015-02-12 06:28:203325 {
3326 host_impl_->active_tree()
hush33370e12015-04-07 03:49:503327 ->OuterViewportScrollLayer()
jdduke2afdbf722015-02-12 06:28:203328 ->set_user_scrollable_horizontal(false);
3329 CompositorFrameMetadata metadata =
3330 host_impl_->MakeCompositorFrameMetadata();
3331 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3332 EXPECT_FALSE(metadata.root_overflow_y_hidden);
3333
3334 host_impl_->active_tree()
hush33370e12015-04-07 03:49:503335 ->OuterViewportScrollLayer()
jdduke2afdbf722015-02-12 06:28:203336 ->set_user_scrollable_vertical(false);
3337 metadata = host_impl_->MakeCompositorFrameMetadata();
3338 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3339 EXPECT_TRUE(metadata.root_overflow_y_hidden);
3340 }
3341
hugo.holgerssone5e7aa92015-08-17 14:07:193342 // Re-enable scrollability and verify that overflows are no longer hidden.
3343 {
3344 host_impl_->active_tree()
3345 ->OuterViewportScrollLayer()
3346 ->set_user_scrollable_horizontal(true);
3347 host_impl_->active_tree()
3348 ->OuterViewportScrollLayer()
3349 ->set_user_scrollable_vertical(true);
3350 CompositorFrameMetadata metadata =
3351 host_impl_->MakeCompositorFrameMetadata();
3352 EXPECT_FALSE(metadata.root_overflow_x_hidden);
3353 EXPECT_FALSE(metadata.root_overflow_y_hidden);
3354 }
3355
3356 // Root "overflow: hidden" properties should also be reflected on the
3357 // inner viewport scroll layer.
3358 {
3359 host_impl_->active_tree()
3360 ->InnerViewportScrollLayer()
3361 ->set_user_scrollable_horizontal(false);
3362 CompositorFrameMetadata metadata =
3363 host_impl_->MakeCompositorFrameMetadata();
3364 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3365 EXPECT_FALSE(metadata.root_overflow_y_hidden);
3366
3367 host_impl_->active_tree()
3368 ->InnerViewportScrollLayer()
3369 ->set_user_scrollable_vertical(false);
3370 metadata = host_impl_->MakeCompositorFrameMetadata();
3371 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3372 EXPECT_TRUE(metadata.root_overflow_y_hidden);
3373 }
3374
[email protected]aa043632013-03-25 03:39:423375 // Page scale should update metadata correctly (shrinking only the viewport).
majidvp944a8cd2016-01-12 21:05:183376 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:033377 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:423378 host_impl_->PinchGestureBegin();
3379 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
3380 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:183381 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:423382 {
3383 CompositorFrameMetadata metadata =
3384 host_impl_->MakeCompositorFrameMetadata();
3385 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3386 EXPECT_EQ(2.f, metadata.page_scale_factor);
[email protected]f3f611f2014-07-09 04:05:323387 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size);
[email protected]aa043632013-03-25 03:39:423388 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
3389 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
3390 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
3391 }
[email protected]94f206c12012-08-25 00:09:143392
[email protected]aa043632013-03-25 03:39:423393 // Likewise if set from the main thread.
3394 host_impl_->ProcessScrollDeltas();
aelias58eec0812014-12-04 01:04:403395 host_impl_->active_tree()->PushPageScaleFromMainThread(4.f, 0.5f, 4.f);
danakj5ad246cd2015-09-12 01:04:503396 host_impl_->active_tree()->SetPageScaleOnActiveTree(4.f);
[email protected]aa043632013-03-25 03:39:423397 {
3398 CompositorFrameMetadata metadata =
3399 host_impl_->MakeCompositorFrameMetadata();
3400 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3401 EXPECT_EQ(4.f, metadata.page_scale_factor);
[email protected]f3f611f2014-07-09 04:05:323402 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size);
[email protected]aa043632013-03-25 03:39:423403 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
3404 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
3405 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
3406 }
[email protected]f2b5a5be2013-01-08 00:34:363407}
3408
[email protected]1001f5c2014-06-13 19:57:183409class DidDrawCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:423410 public:
danakj60bc3bc2016-04-09 00:24:483411 static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3412 return base::WrapUnique(new DidDrawCheckLayer(tree_impl, id));
[email protected]aa043632013-03-25 03:39:423413 }
[email protected]94f206c12012-08-25 00:09:143414
dcheng716bedf2014-10-21 09:51:083415 bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) override {
[email protected]ffbb2212013-06-02 23:47:593416 will_draw_called_ = true;
3417 if (will_draw_returns_false_)
3418 return false;
[email protected]1001f5c2014-06-13 19:57:183419 return LayerImpl::WillDraw(draw_mode, provider);
[email protected]ffbb2212013-06-02 23:47:593420 }
3421
dcheng716bedf2014-10-21 09:51:083422 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:083423 AppendQuadsData* append_quads_data) override {
[email protected]ffbb2212013-06-02 23:47:593424 append_quads_called_ = true;
danakja8c66a52015-02-14 01:53:223425 LayerImpl::AppendQuads(render_pass, append_quads_data);
[email protected]ffbb2212013-06-02 23:47:593426 }
3427
dcheng716bedf2014-10-21 09:51:083428 void DidDraw(ResourceProvider* provider) override {
[email protected]aa043632013-03-25 03:39:423429 did_draw_called_ = true;
[email protected]1001f5c2014-06-13 19:57:183430 LayerImpl::DidDraw(provider);
[email protected]aa043632013-03-25 03:39:423431 }
[email protected]94f206c12012-08-25 00:09:143432
[email protected]aa043632013-03-25 03:39:423433 bool will_draw_called() const { return will_draw_called_; }
[email protected]ffbb2212013-06-02 23:47:593434 bool append_quads_called() const { return append_quads_called_; }
3435 bool did_draw_called() const { return did_draw_called_; }
3436
3437 void set_will_draw_returns_false() { will_draw_returns_false_ = true; }
[email protected]94f206c12012-08-25 00:09:143438
[email protected]aa043632013-03-25 03:39:423439 void ClearDidDrawCheck() {
[email protected]aa043632013-03-25 03:39:423440 will_draw_called_ = false;
[email protected]ffbb2212013-06-02 23:47:593441 append_quads_called_ = false;
3442 did_draw_called_ = false;
[email protected]aa043632013-03-25 03:39:423443 }
[email protected]94f206c12012-08-25 00:09:143444
danakj60bc3bc2016-04-09 00:24:483445 static void IgnoreResult(std::unique_ptr<CopyOutputResult> result) {}
danakjec8b22b2015-03-11 02:20:343446
3447 void AddCopyRequest() {
ajumae6f541b2016-05-31 16:50:503448 test_properties()->copy_requests.push_back(
danakjec8b22b2015-03-11 02:20:343449 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreResult)));
danakjec8b22b2015-03-11 02:20:343450 }
3451
[email protected]aa043632013-03-25 03:39:423452 protected:
3453 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id)
[email protected]1001f5c2014-06-13 19:57:183454 : LayerImpl(tree_impl, id),
[email protected]ffbb2212013-06-02 23:47:593455 will_draw_returns_false_(false),
3456 will_draw_called_(false),
3457 append_quads_called_(false),
3458 did_draw_called_(false) {
[email protected]aa043632013-03-25 03:39:423459 SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423460 SetDrawsContent(true);
danakj64767d902015-06-19 00:10:433461 draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
[email protected]aa043632013-03-25 03:39:423462 }
[email protected]94f206c12012-08-25 00:09:143463
[email protected]aa043632013-03-25 03:39:423464 private:
[email protected]ffbb2212013-06-02 23:47:593465 bool will_draw_returns_false_;
[email protected]aa043632013-03-25 03:39:423466 bool will_draw_called_;
[email protected]ffbb2212013-06-02 23:47:593467 bool append_quads_called_;
3468 bool did_draw_called_;
[email protected]94f206c12012-08-25 00:09:143469};
3470
[email protected]ffbb2212013-06-02 23:47:593471TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
3472 // The root layer is always drawn, so run this test on a child layer that
3473 // will be masked out by the root layer's bounds.
jaydasikabf1875a2016-06-28 03:39:593474 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]ffbb2212013-06-02 23:47:593475 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483476 DidDrawCheckLayer* root =
3477 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]ffbb2212013-06-02 23:47:593478
jaydasika89f7b5a2016-06-22 02:08:393479 root->test_properties()->AddChild(
3480 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
jaydasika6b5a32bf2016-04-22 21:56:363481 root->test_properties()->force_render_surface = true;
[email protected]ffbb2212013-06-02 23:47:593482 DidDrawCheckLayer* layer =
jaydasikafc66cfb2016-06-10 04:34:223483 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
danakj74af409e2016-07-01 00:41:483484 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ffbb2212013-06-02 23:47:593485
3486 {
3487 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:483488 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453489 host_impl_->DrawLayers(&frame);
[email protected]ffbb2212013-06-02 23:47:593490 host_impl_->DidDrawAllLayers(frame);
3491
3492 EXPECT_TRUE(layer->will_draw_called());
3493 EXPECT_TRUE(layer->append_quads_called());
3494 EXPECT_TRUE(layer->did_draw_called());
3495 }
3496
[email protected]2aae96792014-05-15 23:10:503497 host_impl_->SetViewportDamage(gfx::Rect(10, 10));
3498
[email protected]ffbb2212013-06-02 23:47:593499 {
3500 LayerTreeHostImpl::FrameData frame;
3501
3502 layer->set_will_draw_returns_false();
3503 layer->ClearDidDrawCheck();
3504
danakj74af409e2016-07-01 00:41:483505 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453506 host_impl_->DrawLayers(&frame);
[email protected]ffbb2212013-06-02 23:47:593507 host_impl_->DidDrawAllLayers(frame);
3508
3509 EXPECT_TRUE(layer->will_draw_called());
3510 EXPECT_FALSE(layer->append_quads_called());
3511 EXPECT_FALSE(layer->did_draw_called());
3512 }
3513}
3514
[email protected]aa043632013-03-25 03:39:423515TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
3516 // The root layer is always drawn, so run this test on a child layer that
3517 // will be masked out by the root layer's bounds.
jaydasikabf1875a2016-06-28 03:39:593518 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423519 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483520 DidDrawCheckLayer* root =
3521 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]aa043632013-03-25 03:39:423522 root->SetMasksToBounds(true);
jaydasika6b5a32bf2016-04-22 21:56:363523 root->test_properties()->force_render_surface = true;
jaydasika89f7b5a2016-06-22 02:08:393524 root->test_properties()->AddChild(
3525 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
[email protected]aa043632013-03-25 03:39:423526 DidDrawCheckLayer* layer =
jaydasikafc66cfb2016-06-10 04:34:223527 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
danakj64767d902015-06-19 00:10:433528 // Ensure visible_layer_rect for layer is empty.
[email protected]aa043632013-03-25 03:39:423529 layer->SetPosition(gfx::PointF(100.f, 100.f));
3530 layer->SetBounds(gfx::Size(10, 10));
danakj74af409e2016-07-01 00:41:483531 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143532
[email protected]aa043632013-03-25 03:39:423533 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143534
[email protected]aa043632013-03-25 03:39:423535 EXPECT_FALSE(layer->will_draw_called());
3536 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143537
danakj74af409e2016-07-01 00:41:483538 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453539 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423540 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143541
[email protected]aa043632013-03-25 03:39:423542 EXPECT_FALSE(layer->will_draw_called());
3543 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143544
danakj64767d902015-06-19 00:10:433545 EXPECT_TRUE(layer->visible_layer_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:143546
danakj64767d902015-06-19 00:10:433547 // Ensure visible_layer_rect for layer is not empty
[email protected]aa043632013-03-25 03:39:423548 layer->SetPosition(gfx::PointF());
jaydasikaadfec8e2016-02-17 02:46:113549 layer->NoteLayerPropertyChanged();
danakj74af409e2016-07-01 00:41:483550 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143551
[email protected]aa043632013-03-25 03:39:423552 EXPECT_FALSE(layer->will_draw_called());
3553 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143554
danakj74af409e2016-07-01 00:41:483555 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453556 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423557 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143558
[email protected]aa043632013-03-25 03:39:423559 EXPECT_TRUE(layer->will_draw_called());
3560 EXPECT_TRUE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143561
danakj64767d902015-06-19 00:10:433562 EXPECT_FALSE(layer->visible_layer_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:143563}
3564
[email protected]aa043632013-03-25 03:39:423565TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
3566 gfx::Size big_size(1000, 1000);
[email protected]18ce59702013-04-09 04:58:403567 host_impl_->SetViewportSize(big_size);
[email protected]94f206c12012-08-25 00:09:143568
jaydasikabf1875a2016-06-28 03:39:593569 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423570 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483571 DidDrawCheckLayer* root =
3572 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]94f206c12012-08-25 00:09:143573
jaydasika89f7b5a2016-06-22 02:08:393574 root->test_properties()->AddChild(
3575 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
[email protected]aa043632013-03-25 03:39:423576 DidDrawCheckLayer* occluded_layer =
jaydasikafc66cfb2016-06-10 04:34:223577 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
[email protected]94f206c12012-08-25 00:09:143578
jaydasika89f7b5a2016-06-22 02:08:393579 root->test_properties()->AddChild(
3580 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
jaydasika6b5a32bf2016-04-22 21:56:363581 root->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:423582 DidDrawCheckLayer* top_layer =
jaydasikafc66cfb2016-06-10 04:34:223583 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[1]);
[email protected]aa043632013-03-25 03:39:423584 // This layer covers the occluded_layer above. Make this layer large so it can
3585 // occlude.
3586 top_layer->SetBounds(big_size);
[email protected]aa043632013-03-25 03:39:423587 top_layer->SetContentsOpaque(true);
danakj74af409e2016-07-01 00:41:483588 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143589
[email protected]aa043632013-03-25 03:39:423590 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143591
[email protected]aa043632013-03-25 03:39:423592 EXPECT_FALSE(occluded_layer->will_draw_called());
3593 EXPECT_FALSE(occluded_layer->did_draw_called());
3594 EXPECT_FALSE(top_layer->will_draw_called());
3595 EXPECT_FALSE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143596
danakj74af409e2016-07-01 00:41:483597 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453598 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423599 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143600
[email protected]aa043632013-03-25 03:39:423601 EXPECT_FALSE(occluded_layer->will_draw_called());
3602 EXPECT_FALSE(occluded_layer->did_draw_called());
3603 EXPECT_TRUE(top_layer->will_draw_called());
3604 EXPECT_TRUE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143605}
3606
[email protected]aa043632013-03-25 03:39:423607TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
jaydasikabf1875a2016-06-28 03:39:593608 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423609 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483610 DidDrawCheckLayer* root =
3611 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]94f206c12012-08-25 00:09:143612
jaydasika89f7b5a2016-06-22 02:08:393613 root->test_properties()->AddChild(
3614 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
jaydasika6b5a32bf2016-04-22 21:56:363615 root->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:423616 DidDrawCheckLayer* layer1 =
jaydasikafc66cfb2016-06-10 04:34:223617 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
[email protected]94f206c12012-08-25 00:09:143618
jaydasika89f7b5a2016-06-22 02:08:393619 layer1->test_properties()->AddChild(
3620 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
[email protected]aa043632013-03-25 03:39:423621 DidDrawCheckLayer* layer2 =
jaydasikafc66cfb2016-06-10 04:34:223622 static_cast<DidDrawCheckLayer*>(layer1->test_properties()->children[0]);
[email protected]94f206c12012-08-25 00:09:143623
jaydasika6b5a32bf2016-04-22 21:56:363624 layer1->test_properties()->force_render_surface = true;
jaydasikaca2605e2016-04-23 02:52:523625 layer1->test_properties()->should_flatten_transform = true;
danakj74af409e2016-07-01 00:41:483626 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143627
[email protected]aa043632013-03-25 03:39:423628 EXPECT_FALSE(root->did_draw_called());
3629 EXPECT_FALSE(layer1->did_draw_called());
3630 EXPECT_FALSE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143631
[email protected]aa043632013-03-25 03:39:423632 LayerTreeHostImpl::FrameData frame;
[email protected]ad63b2f2014-08-11 17:39:543633 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
danakj74af409e2016-07-01 00:41:483634 *host_impl_->active_tree()->begin());
3635 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453636 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423637 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143638
[email protected]aa043632013-03-25 03:39:423639 EXPECT_TRUE(root->did_draw_called());
3640 EXPECT_TRUE(layer1->did_draw_called());
3641 EXPECT_TRUE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143642
[email protected]aa043632013-03-25 03:39:423643 EXPECT_NE(root->render_surface(), layer1->render_surface());
thestigd5fcf982015-05-11 18:41:383644 EXPECT_TRUE(layer1->render_surface());
[email protected]94f206c12012-08-25 00:09:143645}
3646
3647class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
[email protected]aa043632013-03-25 03:39:423648 public:
danakj60bc3bc2016-04-09 00:24:483649 static std::unique_ptr<LayerImpl> Create(
loyso2b91c082016-01-06 00:38:383650 LayerTreeImpl* tree_impl,
3651 int id,
3652 bool tile_missing,
3653 bool had_incomplete_tile,
3654 bool animating,
3655 ResourceProvider* resource_provider,
3656 scoped_refptr<AnimationTimeline> timeline) {
danakj60bc3bc2016-04-09 00:24:483657 return base::WrapUnique(new MissingTextureAnimatingLayer(
loyso2b91c082016-01-06 00:38:383658 tree_impl, id, tile_missing, had_incomplete_tile, animating,
3659 resource_provider, timeline));
[email protected]aa043632013-03-25 03:39:423660 }
[email protected]94f206c12012-08-25 00:09:143661
dcheng716bedf2014-10-21 09:51:083662 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:083663 AppendQuadsData* append_quads_data) override {
danakja8c66a52015-02-14 01:53:223664 LayerImpl::AppendQuads(render_pass, append_quads_data);
[email protected]1001f5c2014-06-13 19:57:183665 if (had_incomplete_tile_)
[email protected]76ca89b2014-07-14 20:32:053666 append_quads_data->num_incomplete_tiles++;
[email protected]1001f5c2014-06-13 19:57:183667 if (tile_missing_)
3668 append_quads_data->num_missing_tiles++;
[email protected]3d609bb2014-02-01 01:10:233669 }
3670
[email protected]aa043632013-03-25 03:39:423671 private:
3672 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl,
3673 int id,
3674 bool tile_missing,
[email protected]1001f5c2014-06-13 19:57:183675 bool had_incomplete_tile,
[email protected]aa043632013-03-25 03:39:423676 bool animating,
loyso2b91c082016-01-06 00:38:383677 ResourceProvider* resource_provider,
3678 scoped_refptr<AnimationTimeline> timeline)
[email protected]1001f5c2014-06-13 19:57:183679 : DidDrawCheckLayer(tree_impl, id),
3680 tile_missing_(tile_missing),
3681 had_incomplete_tile_(had_incomplete_tile) {
vollickef2ae922016-06-29 17:54:273682 if (animating) {
3683 this->SetElementId(LayerIdToElementIdForTesting(id));
3684 AddAnimatedTransformToElementWithPlayer(this->element_id(), timeline,
3685 10.0, 3, 0);
3686 }
[email protected]aa043632013-03-25 03:39:423687 }
[email protected]3d609bb2014-02-01 01:10:233688
3689 bool tile_missing_;
[email protected]1001f5c2014-06-13 19:57:183690 bool had_incomplete_tile_;
[email protected]94f206c12012-08-25 00:09:143691};
3692
danakjec8b22b2015-03-11 02:20:343693struct PrepareToDrawSuccessTestCase {
3694 struct State {
3695 bool has_missing_tile = false;
3696 bool has_incomplete_tile = false;
3697 bool is_animating = false;
3698 bool has_copy_request = false;
3699 };
3700 bool high_res_required = false;
3701 State layer_before;
3702 State layer_between;
3703 State layer_after;
3704 DrawResult expected_result;
3705
3706 explicit PrepareToDrawSuccessTestCase(DrawResult result)
3707 : expected_result(result) {}
3708};
3709
sadrul0df063fc2016-07-27 17:36:513710static void CreateLayerFromState(
3711 DidDrawCheckLayer* root,
3712 const scoped_refptr<AnimationTimeline>& timeline,
3713 const PrepareToDrawSuccessTestCase::State& state) {
3714 static int layer_id = 2;
3715 root->test_properties()->AddChild(MissingTextureAnimatingLayer::Create(
3716 root->layer_tree_impl(), layer_id++, state.has_missing_tile,
3717 state.has_incomplete_tile, state.is_animating,
3718 root->layer_tree_impl()->resource_provider(), timeline));
3719 DidDrawCheckLayer* layer =
3720 static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
3721 if (state.has_copy_request)
3722 layer->AddCopyRequest();
3723}
3724
danakjec8b22b2015-03-11 02:20:343725TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) {
3726 std::vector<PrepareToDrawSuccessTestCase> cases;
3727
3728 // 0. Default case.
3729 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3730 // 1. Animated layer first.
3731 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3732 cases.back().layer_before.is_animating = true;
3733 // 2. Animated layer between.
3734 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3735 cases.back().layer_between.is_animating = true;
3736 // 3. Animated layer last.
3737 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3738 cases.back().layer_after.is_animating = true;
3739 // 4. Missing tile first.
3740 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3741 cases.back().layer_before.has_missing_tile = true;
3742 // 5. Missing tile between.
3743 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3744 cases.back().layer_between.has_missing_tile = true;
3745 // 6. Missing tile last.
3746 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3747 cases.back().layer_after.has_missing_tile = true;
3748 // 7. Incomplete tile first.
3749 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3750 cases.back().layer_before.has_incomplete_tile = true;
3751 // 8. Incomplete tile between.
3752 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3753 cases.back().layer_between.has_incomplete_tile = true;
3754 // 9. Incomplete tile last.
3755 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3756 cases.back().layer_after.has_incomplete_tile = true;
3757 // 10. Animation with missing tile.
3758 cases.push_back(
3759 PrepareToDrawSuccessTestCase(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS));
3760 cases.back().layer_between.has_missing_tile = true;
3761 cases.back().layer_between.is_animating = true;
weiliangc8dac5a62015-04-02 06:12:353762 // 11. Animation with incomplete tile.
danakjec8b22b2015-03-11 02:20:343763 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3764 cases.back().layer_between.has_incomplete_tile = true;
3765 cases.back().layer_between.is_animating = true;
3766
weiliangc8dac5a62015-04-02 06:12:353767 // 12. High res required.
danakjec8b22b2015-03-11 02:20:343768 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3769 cases.back().high_res_required = true;
weiliangc8dac5a62015-04-02 06:12:353770 // 13. High res required with incomplete tile.
danakjec8b22b2015-03-11 02:20:343771 cases.push_back(
3772 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3773 cases.back().high_res_required = true;
3774 cases.back().layer_between.has_incomplete_tile = true;
weiliangc8dac5a62015-04-02 06:12:353775 // 14. High res required with missing tile.
danakjec8b22b2015-03-11 02:20:343776 cases.push_back(
3777 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3778 cases.back().high_res_required = true;
3779 cases.back().layer_between.has_missing_tile = true;
3780
weiliangc8dac5a62015-04-02 06:12:353781 // 15. High res required is higher priority than animating missing tiles.
danakjec8b22b2015-03-11 02:20:343782 cases.push_back(
3783 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3784 cases.back().high_res_required = true;
3785 cases.back().layer_between.has_missing_tile = true;
3786 cases.back().layer_after.has_missing_tile = true;
3787 cases.back().layer_after.is_animating = true;
weiliangc8dac5a62015-04-02 06:12:353788 // 16. High res required is higher priority than animating missing tiles.
danakjec8b22b2015-03-11 02:20:343789 cases.push_back(
3790 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3791 cases.back().high_res_required = true;
3792 cases.back().layer_between.has_missing_tile = true;
3793 cases.back().layer_before.has_missing_tile = true;
3794 cases.back().layer_before.is_animating = true;
3795
jaydasikabf1875a2016-06-28 03:39:593796 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423797 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483798 DidDrawCheckLayer* root =
3799 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
jaydasika6b5a32bf2016-04-22 21:56:363800 root->test_properties()->force_render_surface = true;
danakj74af409e2016-07-01 00:41:483801 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143802
[email protected]aa043632013-03-25 03:39:423803 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:483804 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453805 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423806 host_impl_->DidDrawAllLayers(frame);
danakjec8b22b2015-03-11 02:20:343807
3808 for (size_t i = 0; i < cases.size(); ++i) {
loyso2b91c082016-01-06 00:38:383809 // Clean up host_impl_ state.
danakjec8b22b2015-03-11 02:20:343810 const auto& testcase = cases[i];
3811 std::vector<LayerImpl*> to_remove;
vmpstra2e89432016-07-20 02:05:343812 for (auto* child : root->test_properties()->children)
vollick83fbfc82016-03-22 18:33:273813 to_remove.push_back(child);
danakjec8b22b2015-03-11 02:20:343814 for (auto* child : to_remove)
jaydasika89f7b5a2016-06-22 02:08:393815 root->test_properties()->RemoveChild(child);
loyso9556c732016-03-11 07:54:583816 timeline()->ClearPlayers();
danakjec8b22b2015-03-11 02:20:343817
3818 std::ostringstream scope;
3819 scope << "Test case: " << i;
3820 SCOPED_TRACE(scope.str());
3821
sadrul0df063fc2016-07-27 17:36:513822 CreateLayerFromState(root, timeline(), testcase.layer_before);
3823 CreateLayerFromState(root, timeline(), testcase.layer_between);
3824 CreateLayerFromState(root, timeline(), testcase.layer_after);
danakj74af409e2016-07-01 00:41:483825 host_impl_->active_tree()->BuildPropertyTreesForTesting();
danakjec8b22b2015-03-11 02:20:343826
3827 if (testcase.high_res_required)
3828 host_impl_->SetRequiresHighResToDraw();
3829
3830 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:483831 EXPECT_EQ(testcase.expected_result, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453832 host_impl_->DrawLayers(&frame);
danakjec8b22b2015-03-11 02:20:343833 host_impl_->DidDrawAllLayers(frame);
danakjec8b22b2015-03-11 02:20:343834 }
[email protected]3d609bb2014-02-01 01:10:233835}
[email protected]94f206c12012-08-25 00:09:143836
danakjec8b22b2015-03-11 02:20:343837TEST_F(LayerTreeHostImplTest,
3838 PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame) {
3839 CreateHostImpl(DefaultSettings(),
danakj6021ec32016-07-22 22:16:083840 FakeOutputSurface::CreateDelegatingSoftware());
boliu8ca83902015-10-23 04:36:133841
3842 const gfx::Transform external_transform;
3843 const gfx::Rect external_viewport;
boliu8ca83902015-10-23 04:36:133844 const bool resourceless_software_draw = true;
boliu7097ee5b2015-12-17 03:16:093845 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
3846 external_transform);
danakjec8b22b2015-03-11 02:20:343847
3848 std::vector<PrepareToDrawSuccessTestCase> cases;
3849
3850 // 0. Default case.
3851 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3852 // 1. Animation with missing tile.
3853 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3854 cases.back().layer_between.has_missing_tile = true;
3855 cases.back().layer_between.is_animating = true;
3856 // 2. High res required with incomplete tile.
3857 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3858 cases.back().high_res_required = true;
3859 cases.back().layer_between.has_incomplete_tile = true;
3860 // 3. High res required with missing tile.
3861 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3862 cases.back().high_res_required = true;
3863 cases.back().layer_between.has_missing_tile = true;
3864
jaydasikabf1875a2016-06-28 03:39:593865 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]3d609bb2014-02-01 01:10:233866 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
jaydasikabf1875a2016-06-28 03:39:593867 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
3868 host_impl_->active_tree()->root_layer_for_testing());
jaydasika6b5a32bf2016-04-22 21:56:363869 root->test_properties()->force_render_surface = true;
danakj74af409e2016-07-01 00:41:483870 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]3d609bb2014-02-01 01:10:233871
boliu31c233ed2016-07-29 05:38:593872 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:093873 resourceless_software_draw);
sohan.jyoti9d1e4202014-09-23 21:02:333874
danakjec8b22b2015-03-11 02:20:343875 for (size_t i = 0; i < cases.size(); ++i) {
3876 const auto& testcase = cases[i];
3877 std::vector<LayerImpl*> to_remove;
vmpstra2e89432016-07-20 02:05:343878 for (auto* child : root->test_properties()->children)
vollick83fbfc82016-03-22 18:33:273879 to_remove.push_back(child);
danakjec8b22b2015-03-11 02:20:343880 for (auto* child : to_remove)
jaydasika89f7b5a2016-06-22 02:08:393881 root->test_properties()->RemoveChild(child);
[email protected]3d609bb2014-02-01 01:10:233882
danakjec8b22b2015-03-11 02:20:343883 std::ostringstream scope;
3884 scope << "Test case: " << i;
3885 SCOPED_TRACE(scope.str());
[email protected]1001f5c2014-06-13 19:57:183886
sadrul0df063fc2016-07-27 17:36:513887 CreateLayerFromState(root, timeline(), testcase.layer_before);
3888 CreateLayerFromState(root, timeline(), testcase.layer_between);
3889 CreateLayerFromState(root, timeline(), testcase.layer_after);
danakj74af409e2016-07-01 00:41:483890 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sohan.jyoti9d1e4202014-09-23 21:02:333891
danakjec8b22b2015-03-11 02:20:343892 if (testcase.high_res_required)
3893 host_impl_->SetRequiresHighResToDraw();
sohan.jyoti9d1e4202014-09-23 21:02:333894
boliu31c233ed2016-07-29 05:38:593895 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:093896 resourceless_software_draw);
danakjec8b22b2015-03-11 02:20:343897 }
[email protected]1001f5c2014-06-13 19:57:183898}
3899
[email protected]aa043632013-03-25 03:39:423900TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
danakj60bc3bc2016-04-09 00:24:483901 std::unique_ptr<LayerImpl> root =
3902 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]adeda572014-01-31 00:49:473903 root->SetScrollClipLayer(Layer::INVALID_ID);
jaydasika6b5a32bf2016-04-22 21:56:363904 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:593905 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:483906 host_impl_->active_tree()->BuildPropertyTreesForTesting();
3907
[email protected]ce2e8112013-11-28 07:44:363908 DrawFrame();
[email protected]94f206c12012-08-25 00:09:143909
[email protected]aa043632013-03-25 03:39:423910 // Scroll event is ignored because layer is not scrollable.
tdresser81e84c672016-01-18 23:21:223911 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
3912 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
3913 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:403914 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:223915 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:423916 EXPECT_FALSE(did_request_redraw_);
3917 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:143918}
3919
hush85432c82015-07-23 00:24:543920TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) {
3921 host_impl_->CreatePendingTree();
bokan0c33a092015-07-29 18:27:563922 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
hush85432c82015-07-23 00:24:543923 CreateScrollAndContentsLayers(host_impl_->pending_tree(),
3924 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:483925 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
hush85432c82015-07-23 00:24:543926 host_impl_->ActivateSyncTree();
3927
3928 host_impl_->CreatePendingTree();
3929 const gfx::ScrollOffset pending_scroll = gfx::ScrollOffset(-100, -100);
3930 LayerImpl* active_outer_layer =
3931 host_impl_->active_tree()->OuterViewportScrollLayer();
3932 LayerImpl* pending_outer_layer =
3933 host_impl_->pending_tree()->OuterViewportScrollLayer();
sunxdb7e79432016-03-09 21:13:423934 pending_outer_layer->layer_tree_impl()
3935 ->property_trees()
3936 ->scroll_tree.UpdateScrollOffsetBaseForTesting(pending_outer_layer->id(),
3937 pending_scroll);
hush85432c82015-07-23 00:24:543938
3939 host_impl_->ActivateSyncTree();
3940 // Scrolloffsets on the active tree will be clamped after activation.
3941 EXPECT_EQ(active_outer_layer->CurrentScrollOffset(), gfx::ScrollOffset(0, 0));
3942}
3943
[email protected]fef74fd2014-02-27 06:28:173944class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
3945 public:
3946 LayerTreeHostImplTopControlsTest()
3947 // Make the clip size the same as the layer (content) size so the layer is
3948 // non-scrollable.
3949 : layer_size_(10, 10),
dtrainorcb7779b82014-12-04 01:08:023950 clip_size_(layer_size_),
3951 top_controls_height_(50) {
dtrainorcb7779b82014-12-04 01:08:023952 viewport_size_ = gfx::Size(clip_size_.width(),
3953 clip_size_.height() + top_controls_height_);
3954 }
3955
3956 bool CreateHostImpl(const LayerTreeSettings& settings,
danakj60bc3bc2016-04-09 00:24:483957 std::unique_ptr<OutputSurface> output_surface) override {
danakja04855a2015-11-18 20:39:103958 bool init = LayerTreeHostImplTest::CreateHostImpl(
3959 settings, std::move(output_surface));
bokanaa5d1b032015-03-09 21:51:323960 if (init) {
dtrainorcb7779b82014-12-04 01:08:023961 host_impl_->active_tree()->set_top_controls_height(top_controls_height_);
aelias6004fe02015-02-07 21:43:013962 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f);
bokan0c33a092015-07-29 18:27:563963 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
dtrainorcb7779b82014-12-04 01:08:023964 }
3965 return init;
[email protected]fef74fd2014-02-27 06:28:173966 }
[email protected]c8415bf92013-02-17 18:57:273967
bokanef971462014-10-13 22:58:323968 void SetupTopControlsAndScrollLayerWithVirtualViewport(
3969 const gfx::Size& inner_viewport_size,
3970 const gfx::Size& outer_viewport_size,
3971 const gfx::Size& scroll_layer_size) {
weiliangc8f4ef0d2015-11-27 00:15:553972 settings_ = DefaultSettings();
bokanef971462014-10-13 22:58:323973 CreateHostImpl(settings_, CreateOutputSurface());
bokan7ad75ed2016-03-30 19:29:573974 SetupTopControlsAndScrollLayerWithVirtualViewport(
3975 host_impl_->active_tree(), inner_viewport_size, outer_viewport_size,
3976 scroll_layer_size);
3977 }
3978
3979 void SetupTopControlsAndScrollLayerWithVirtualViewport(
3980 LayerTreeImpl* tree_impl,
3981 const gfx::Size& inner_viewport_size,
3982 const gfx::Size& outer_viewport_size,
3983 const gfx::Size& scroll_layer_size) {
3984 tree_impl->set_top_controls_shrink_blink_size(true);
3985 tree_impl->set_top_controls_height(top_controls_height_);
3986 tree_impl->SetCurrentTopControlsShownRatio(1.f);
3987 tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
dtrainorcb7779b82014-12-04 01:08:023988 host_impl_->DidChangeTopControlsPosition();
bokanef971462014-10-13 22:58:323989
danakj60bc3bc2016-04-09 00:24:483990 std::unique_ptr<LayerImpl> root = LayerImpl::Create(tree_impl, 1);
3991 std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(tree_impl, 2);
3992 std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(tree_impl, 3);
bokanef971462014-10-13 22:58:323993
danakj60bc3bc2016-04-09 00:24:483994 std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(tree_impl, 4);
3995 std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5);
bokanef971462014-10-13 22:58:323996
3997 root_clip->SetBounds(inner_viewport_size);
3998 root->SetScrollClipLayer(root_clip->id());
3999 root->SetBounds(outer_viewport_size);
bokanef971462014-10-13 22:58:324000 root->SetPosition(gfx::PointF());
4001 root->SetDrawsContent(false);
jaydasika6b5a32bf2016-04-22 21:56:364002 root_clip->test_properties()->force_render_surface = true;
jaydasikaca2605e2016-04-23 02:52:524003 root->test_properties()->is_container_for_fixed_position_layers = true;
bokanef971462014-10-13 22:58:324004 outer_clip->SetBounds(outer_viewport_size);
4005 outer_scroll->SetScrollClipLayer(outer_clip->id());
4006 outer_scroll->SetBounds(scroll_layer_size);
bokanef971462014-10-13 22:58:324007 outer_scroll->SetPosition(gfx::PointF());
4008 outer_scroll->SetDrawsContent(false);
jaydasikaca2605e2016-04-23 02:52:524009 outer_scroll->test_properties()->is_container_for_fixed_position_layers =
4010 true;
bokanef971462014-10-13 22:58:324011
4012 int inner_viewport_scroll_layer_id = root->id();
4013 int outer_viewport_scroll_layer_id = outer_scroll->id();
4014 int page_scale_layer_id = page_scale->id();
4015
jaydasika89f7b5a2016-06-22 02:08:394016 outer_clip->test_properties()->AddChild(std::move(outer_scroll));
4017 root->test_properties()->AddChild(std::move(outer_clip));
4018 page_scale->test_properties()->AddChild(std::move(root));
4019 root_clip->test_properties()->AddChild(std::move(page_scale));
bokanef971462014-10-13 22:58:324020
jaydasikabf1875a2016-06-28 03:39:594021 tree_impl->SetRootLayerForTesting(std::move(root_clip));
bokan7ad75ed2016-03-30 19:29:574022 tree_impl->SetViewportLayersFromIds(Layer::INVALID_ID, page_scale_layer_id,
4023 inner_viewport_scroll_layer_id,
4024 outer_viewport_scroll_layer_id);
danakj74af409e2016-07-01 00:41:484025 tree_impl->BuildPropertyTreesForTesting();
bokanef971462014-10-13 22:58:324026
4027 host_impl_->SetViewportSize(inner_viewport_size);
jaydasikabf1875a2016-06-28 03:39:594028 LayerImpl* root_clip_ptr = tree_impl->root_layer_for_testing();
bokanef971462014-10-13 22:58:324029 EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds());
4030 }
4031
[email protected]fef74fd2014-02-27 06:28:174032 protected:
4033 gfx::Size layer_size_;
4034 gfx::Size clip_size_;
4035 gfx::Size viewport_size_;
dtrainorcb7779b82014-12-04 01:08:024036 float top_controls_height_;
[email protected]fef74fd2014-02-27 06:28:174037
4038 LayerTreeSettings settings_;
4039}; // class LayerTreeHostImplTopControlsTest
4040
bokan574c43632015-08-14 02:22:074041// Tests that, on a page with content the same size as the viewport, hiding
4042// the top controls also increases the ScrollableSize (i.e. the content size).
4043// Since the viewport got larger, the effective scrollable "content" also did.
4044// This ensures, for one thing, that the overscroll glow is shown in the right
4045// place.
4046TEST_F(LayerTreeHostImplTopControlsTest,
4047 HidingTopControlsExpandsScrollableSize) {
4048 SetupTopControlsAndScrollLayerWithVirtualViewport(
4049 gfx::Size(50, 50), gfx::Size(50, 50), gfx::Size(50, 50));
4050
4051 LayerTreeImpl* active_tree = host_impl_->active_tree();
4052
4053 // Create a content layer beneath the outer viewport scroll layer.
4054 int id = host_impl_->OuterViewportScrollLayer()->id();
jaydasika89f7b5a2016-06-22 02:08:394055 host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild(
bokan574c43632015-08-14 02:22:074056 LayerImpl::Create(host_impl_->active_tree(), id + 2));
jaydasikafc66cfb2016-06-10 04:34:224057 LayerImpl* content =
4058 active_tree->OuterViewportScrollLayer()->test_properties()->children[0];
bokan574c43632015-08-14 02:22:074059 content->SetBounds(gfx::Size(50, 50));
danakj74af409e2016-07-01 00:41:484060 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan574c43632015-08-14 02:22:074061
4062 DrawFrame();
4063
4064 LayerImpl* inner_container = active_tree->InnerViewportContainerLayer();
4065 LayerImpl* outer_container = active_tree->OuterViewportContainerLayer();
4066
4067 // The top controls should start off showing so the viewport should be shrunk.
4068 ASSERT_EQ(gfx::Size(50, 50), inner_container->bounds());
4069 ASSERT_EQ(gfx::Size(50, 50), outer_container->bounds());
4070
4071 EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize());
4072
tdresser81e84c672016-01-18 23:21:224073 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034074 host_impl_
4075 ->ScrollBegin(BeginState(gfx::Point()).get(),
4076 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224077 .thread);
bokan574c43632015-08-14 02:22:074078
4079 host_impl_->top_controls_manager()->ScrollBegin();
4080
4081 // Hide the top controls by a bit, the scrollable size should increase but the
4082 // actual content bounds shouldn't.
4083 {
4084 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
4085 ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds());
4086 ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds());
4087 EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize());
4088 EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling());
4089 }
4090
4091 // Fully hide the top controls.
4092 {
4093 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
4094 ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds());
4095 ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds());
4096 EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
4097 EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling());
4098 }
4099
4100 // Scrolling additionally shouldn't have any effect.
4101 {
4102 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
4103 ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds());
4104 ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds());
4105 EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
4106 EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling());
4107 }
4108
4109 host_impl_->top_controls_manager()->ScrollEnd();
majidvp944a8cd2016-01-12 21:05:184110 host_impl_->ScrollEnd(EndState().get());
bokan574c43632015-08-14 02:22:074111}
4112
[email protected]fef74fd2014-02-27 06:28:174113TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) {
bokan8273d962014-10-22 02:40:274114 SetupTopControlsAndScrollLayerWithVirtualViewport(
4115 gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
[email protected]fef74fd2014-02-27 06:28:174116 DrawFrame();
4117
tdresser81e84c672016-01-18 23:21:224118 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034119 host_impl_
4120 ->ScrollBegin(BeginState(gfx::Point()).get(),
4121 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224122 .thread);
[email protected]fef74fd2014-02-27 06:28:174123
4124 // Make the test scroll delta a fractional amount, to verify that the
4125 // fixed container size delta is (1) non-zero, and (2) fractional, and
4126 // (3) matches the movement of the top controls.
4127 gfx::Vector2dF top_controls_scroll_delta(0.f, 5.25f);
4128 host_impl_->top_controls_manager()->ScrollBegin();
4129 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4130 host_impl_->top_controls_manager()->ScrollEnd();
4131
4132 LayerImpl* inner_viewport_scroll_layer =
4133 host_impl_->active_tree()->InnerViewportScrollLayer();
4134 DCHECK(inner_viewport_scroll_layer);
majidvp944a8cd2016-01-12 21:05:184135 host_impl_->ScrollEnd(EndState().get());
aelias6004fe02015-02-07 21:43:014136 EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(),
4137 inner_viewport_scroll_layer->FixedContainerSizeDelta().y());
[email protected]fef74fd2014-02-27 06:28:174138}
4139
bokana203a4b12014-11-18 16:28:084140// In this test, the outer viewport is initially unscrollable. We test that a
4141// scroll initiated on the inner viewport, causing the top controls to show and
4142// thus making the outer viewport scrollable, still scrolls the outer viewport.
4143TEST_F(LayerTreeHostImplTopControlsTest,
4144 TopControlsOuterViewportBecomesScrollable) {
4145 SetupTopControlsAndScrollLayerWithVirtualViewport(
4146 gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
4147 DrawFrame();
4148
thestigd5fcf982015-05-11 18:41:384149 LayerImpl* inner_scroll =
bokana203a4b12014-11-18 16:28:084150 host_impl_->active_tree()->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:124151 inner_scroll->SetDrawsContent(true);
thestigd5fcf982015-05-11 18:41:384152 LayerImpl* inner_container =
bokana203a4b12014-11-18 16:28:084153 host_impl_->active_tree()->InnerViewportContainerLayer();
thestigd5fcf982015-05-11 18:41:384154 LayerImpl* outer_scroll =
bokana203a4b12014-11-18 16:28:084155 host_impl_->active_tree()->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:124156 outer_scroll->SetDrawsContent(true);
thestigd5fcf982015-05-11 18:41:384157 LayerImpl* outer_container =
bokana203a4b12014-11-18 16:28:084158 host_impl_->active_tree()->OuterViewportContainerLayer();
4159
4160 // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
4161 outer_scroll->SetDrawsContent(true);
aelias58eec0812014-12-04 01:04:404162 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
bokana203a4b12014-11-18 16:28:084163
tdresser81e84c672016-01-18 23:21:224164 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034165 host_impl_
4166 ->ScrollBegin(BeginState(gfx::Point()).get(),
4167 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224168 .thread);
majidvp944a8cd2016-01-12 21:05:184169 host_impl_->ScrollBy(
4170 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 50.f)).get());
bokana203a4b12014-11-18 16:28:084171
4172 // The entire scroll delta should have been used to hide the top controls.
4173 // The viewport layers should be resized back to their full sizes.
aelias6004fe02015-02-07 21:43:014174 EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
aeliasf998da82015-02-03 01:40:514175 EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084176 EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height());
4177 EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height());
4178
4179 // The inner viewport should be scrollable by 50px * page_scale.
majidvp944a8cd2016-01-12 21:05:184180 host_impl_->ScrollBy(
4181 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 100.f)).get());
aeliasf998da82015-02-03 01:40:514182 EXPECT_EQ(50.f, inner_scroll->CurrentScrollOffset().y());
4183 EXPECT_EQ(0.f, outer_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084184 EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset());
4185
majidvp944a8cd2016-01-12 21:05:184186 host_impl_->ScrollEnd(EndState().get());
bokana203a4b12014-11-18 16:28:084187
tdresser81e84c672016-01-18 23:21:224188 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034189 host_impl_
4190 ->ScrollBegin(BeginState(gfx::Point()).get(),
4191 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224192 .thread);
bokana203a4b12014-11-18 16:28:084193 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
4194
majidvp944a8cd2016-01-12 21:05:184195 host_impl_->ScrollBy(
4196 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get());
bokana203a4b12014-11-18 16:28:084197
4198 // The entire scroll delta should have been used to show the top controls.
4199 // The outer viewport should be resized to accomodate and scrolled to the
4200 // bottom of the document to keep the viewport in place.
aelias6004fe02015-02-07 21:43:014201 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
bokana203a4b12014-11-18 16:28:084202 EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height());
4203 EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height());
aeliasf998da82015-02-03 01:40:514204 EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
4205 EXPECT_EQ(25.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084206
4207 // Now when we continue scrolling, make sure the outer viewport gets scrolled
4208 // since it wasn't scrollable when the scroll began.
majidvp944a8cd2016-01-12 21:05:184209 host_impl_->ScrollBy(
4210 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -20.f)).get());
bokan1f01388f2015-09-15 20:55:544211 EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
4212 EXPECT_EQ(15.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084213
majidvp944a8cd2016-01-12 21:05:184214 host_impl_->ScrollBy(
4215 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -30.f)).get());
bokan1f01388f2015-09-15 20:55:544216 EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
4217 EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084218
majidvp944a8cd2016-01-12 21:05:184219 host_impl_->ScrollBy(
4220 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get());
4221 host_impl_->ScrollEnd(EndState().get());
bokana203a4b12014-11-18 16:28:084222
aeliasf998da82015-02-03 01:40:514223 EXPECT_EQ(0.f, outer_scroll->CurrentScrollOffset().y());
4224 EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084225}
4226
bokan8273d962014-10-22 02:40:274227// Test that the fixed position container delta is appropriately adjusted
4228// by the top controls showing/hiding and page scale doesn't affect it.
4229TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
4230 SetupTopControlsAndScrollLayerWithVirtualViewport(
4231 gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
[email protected]fef74fd2014-02-27 06:28:174232 DrawFrame();
bokan0c33a092015-07-29 18:27:564233 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
[email protected]fef74fd2014-02-27 06:28:174234
bokan8273d962014-10-22 02:40:274235 float page_scale = 1.5f;
bokan8273d962014-10-22 02:40:274236 LayerImpl* outer_viewport_scroll_layer =
4237 host_impl_->active_tree()->OuterViewportScrollLayer();
4238
4239 // Zoom in, since the fixed container is the outer viewport, the delta should
4240 // not be scaled.
aelias58eec0812014-12-04 01:04:404241 host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
bokan8273d962014-10-22 02:40:274242
tdresser81e84c672016-01-18 23:21:224243 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034244 host_impl_
4245 ->ScrollBegin(BeginState(gfx::Point()).get(),
4246 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224247 .thread);
[email protected]fef74fd2014-02-27 06:28:174248
bokan8273d962014-10-22 02:40:274249 // Scroll down, the top controls hiding should expand the viewport size so
4250 // the delta should be equal to the scroll distance.
4251 gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f);
[email protected]fef74fd2014-02-27 06:28:174252 host_impl_->top_controls_manager()->ScrollBegin();
4253 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
aelias6004fe02015-02-07 21:43:014254 EXPECT_FLOAT_EQ(top_controls_height_ - top_controls_scroll_delta.y(),
4255 host_impl_->top_controls_manager()->ContentTopOffset());
bokan0c33a092015-07-29 18:27:564256 EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(),
4257 outer_viewport_scroll_layer->FixedContainerSizeDelta().y());
majidvp944a8cd2016-01-12 21:05:184258 host_impl_->ScrollEnd(EndState().get());
[email protected]fef74fd2014-02-27 06:28:174259
bokan8273d962014-10-22 02:40:274260 // Scroll past the maximum extent. The delta shouldn't be greater than the
4261 // top controls height.
4262 host_impl_->top_controls_manager()->ScrollBegin();
4263 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4264 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4265 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4266 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
dtrainorcb7779b82014-12-04 01:08:024267 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_),
bokan8273d962014-10-22 02:40:274268 outer_viewport_scroll_layer->FixedContainerSizeDelta());
majidvp944a8cd2016-01-12 21:05:184269 host_impl_->ScrollEnd(EndState().get());
bokan8273d962014-10-22 02:40:274270
4271 // Scroll in the direction to make the top controls show.
4272 host_impl_->top_controls_manager()->ScrollBegin();
4273 host_impl_->top_controls_manager()->ScrollBy(-top_controls_scroll_delta);
4274 EXPECT_EQ(top_controls_scroll_delta.y(),
4275 host_impl_->top_controls_manager()->ContentTopOffset());
4276 EXPECT_VECTOR_EQ(
dtrainorcb7779b82014-12-04 01:08:024277 gfx::Vector2dF(0, top_controls_height_ - top_controls_scroll_delta.y()),
bokan8273d962014-10-22 02:40:274278 outer_viewport_scroll_layer->FixedContainerSizeDelta());
4279 host_impl_->top_controls_manager()->ScrollEnd();
[email protected]fef74fd2014-02-27 06:28:174280}
4281
bokan0223f2f722016-06-23 12:35:014282// Push a top controls ratio from the main thread that we didn't send as a delta
4283// and make sure that the ratio is clamped to the [0, 1] range.
4284TEST_F(LayerTreeHostImplTopControlsTest, TopControlsPushUnsentRatio) {
4285 SetupTopControlsAndScrollLayerWithVirtualViewport(
4286 gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
4287 DrawFrame();
4288
4289 // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
4290 LayerImpl* inner_scroll =
4291 host_impl_->active_tree()->InnerViewportScrollLayer();
4292 inner_scroll->SetDrawsContent(true);
4293 LayerImpl* outer_scroll =
4294 host_impl_->active_tree()->OuterViewportScrollLayer();
4295 outer_scroll->SetDrawsContent(true);
4296
4297 host_impl_->active_tree()->PushTopControlsFromMainThread(1);
4298 ASSERT_EQ(1.0f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4299
4300 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.5f);
4301 ASSERT_EQ(0.5f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4302
4303 host_impl_->active_tree()->PushTopControlsFromMainThread(0);
4304
4305 ASSERT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4306}
4307
tdressera4bec5df2015-07-14 13:23:344308// Test that if only the top controls are scrolled, we shouldn't request a
4309// commit.
4310TEST_F(LayerTreeHostImplTopControlsTest, TopControlsDontTriggerCommit) {
4311 SetupTopControlsAndScrollLayerWithVirtualViewport(
4312 gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100));
4313 DrawFrame();
4314
4315 // Show top controls
4316 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4317
4318 // Scroll 25px to hide top controls
4319 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224320 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034321 host_impl_
4322 ->ScrollBegin(BeginState(gfx::Point()).get(),
4323 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224324 .thread);
majidvp944a8cd2016-01-12 21:05:184325 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdressera4bec5df2015-07-14 13:23:344326 EXPECT_FALSE(did_request_commit_);
4327}
4328
elisabets01d84d32014-12-15 12:50:054329// Test that if a scrollable sublayer doesn't consume the scroll,
4330// top controls should hide when scrolling down.
4331TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) {
4332 gfx::Size sub_content_size(100, 400);
4333 gfx::Size sub_content_layer_size(100, 300);
4334 SetupTopControlsAndScrollLayerWithVirtualViewport(
4335 gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100));
4336 DrawFrame();
4337
4338 // Show top controls
aelias6004fe02015-02-07 21:43:014339 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
elisabets01d84d32014-12-15 12:50:054340
4341 LayerImpl* outer_viewport_scroll_layer =
4342 host_impl_->active_tree()->OuterViewportScrollLayer();
4343 int id = outer_viewport_scroll_layer->id();
4344
danakj60bc3bc2016-04-09 00:24:484345 std::unique_ptr<LayerImpl> child =
elisabets01d84d32014-12-15 12:50:054346 LayerImpl::Create(host_impl_->active_tree(), id + 2);
danakj60bc3bc2016-04-09 00:24:484347 std::unique_ptr<LayerImpl> child_clip =
elisabets01d84d32014-12-15 12:50:054348 LayerImpl::Create(host_impl_->active_tree(), id + 3);
4349
4350 child_clip->SetBounds(sub_content_layer_size);
4351 child->SetScrollClipLayer(child_clip->id());
4352 child->SetBounds(sub_content_size);
elisabets01d84d32014-12-15 12:50:054353 child->SetPosition(gfx::PointF());
4354 child->SetDrawsContent(true);
jaydasikaca2605e2016-04-23 02:52:524355 child->test_properties()->is_container_for_fixed_position_layers = true;
elisabets01d84d32014-12-15 12:50:054356
4357 // scroll child to limit
sunxdb7e79432016-03-09 21:13:424358 SetScrollOffsetDelta(child.get(), gfx::Vector2dF(0, 100.f));
jaydasika89f7b5a2016-06-22 02:08:394359 child_clip->test_properties()->AddChild(std::move(child));
4360 outer_viewport_scroll_layer->test_properties()->AddChild(
4361 std::move(child_clip));
danakj74af409e2016-07-01 00:41:484362 host_impl_->active_tree()->BuildPropertyTreesForTesting();
elisabets01d84d32014-12-15 12:50:054363
4364 // Scroll 25px to hide top controls
4365 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224366 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034367 host_impl_
4368 ->ScrollBegin(BeginState(gfx::Point()).get(),
4369 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224370 .thread);
majidvp944a8cd2016-01-12 21:05:184371 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
4372 host_impl_->ScrollEnd(EndState().get());
elisabets01d84d32014-12-15 12:50:054373
4374 // Top controls should be hidden
4375 EXPECT_EQ(scroll_delta.y(),
4376 top_controls_height_ -
aelias6004fe02015-02-07 21:43:014377 host_impl_->top_controls_manager()->ContentTopOffset());
elisabets01d84d32014-12-15 12:50:054378}
4379
bokan88eae012014-09-09 20:40:424380// Ensure setting the top controls position explicitly using the setters on the
4381// TreeImpl correctly affects the top controls manager and viewport bounds.
4382TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) {
weiliangc8f4ef0d2015-11-27 00:15:554383 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024384 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054385 SetupTopControlsAndScrollLayerWithVirtualViewport(
4386 layer_size_, layer_size_, layer_size_);
bokan88eae012014-09-09 20:40:424387 DrawFrame();
4388
aelias6004fe02015-02-07 21:43:014389 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
4390 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4391 30.f / top_controls_height_);
4392 host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
4393 EXPECT_FLOAT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset());
4394 EXPECT_FLOAT_EQ(-20.f,
4395 host_impl_->top_controls_manager()->ControlsTopOffset());
bokan88eae012014-09-09 20:40:424396
aelias6004fe02015-02-07 21:43:014397 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
4398 EXPECT_FLOAT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4399 EXPECT_FLOAT_EQ(-50.f,
4400 host_impl_->top_controls_manager()->ControlsTopOffset());
bokan88eae012014-09-09 20:40:424401
4402 host_impl_->DidChangeTopControlsPosition();
4403
4404 // Now that top controls have moved, expect the clip to resize.
jaydasikaf419bf72016-06-15 10:21:214405 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4406 ->test_properties()
4407 ->parent->test_properties()
4408 ->parent;
bokanf553cb3b2015-07-23 18:54:054409 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424410}
4411
4412// Test that the top_controls delta and sent delta are appropriately
4413// applied on sync tree activation. The total top controls offset shouldn't
4414// change after the activation.
4415TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) {
weiliangc8f4ef0d2015-11-27 00:15:554416 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024417 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054418 SetupTopControlsAndScrollLayerWithVirtualViewport(
4419 layer_size_, layer_size_, layer_size_);
bokan88eae012014-09-09 20:40:424420 DrawFrame();
4421
aelias6004fe02015-02-07 21:43:014422 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4423 20.f / top_controls_height_);
4424 host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
4425 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(
4426 15.f / top_controls_height_);
4427 host_impl_->active_tree()
4428 ->top_controls_shown_ratio()
4429 ->PullDeltaForMainThread();
4430 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
4431 host_impl_->sync_tree()->PushTopControlsFromMainThread(15.f /
4432 top_controls_height_);
bokan88eae012014-09-09 20:40:424433
4434 host_impl_->DidChangeTopControlsPosition();
jaydasikaf419bf72016-06-15 10:21:214435 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4436 ->test_properties()
4437 ->parent->test_properties()
4438 ->parent;
bokanf553cb3b2015-07-23 18:54:054439 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424440 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4441
4442 host_impl_->ActivateSyncTree();
4443
jaydasikaf419bf72016-06-15 10:21:214444 inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4445 ->test_properties()
4446 ->parent->test_properties()
4447 ->parent;
bokan88eae012014-09-09 20:40:424448 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
bokanf553cb3b2015-07-23 18:54:054449 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424450
aelias6004fe02015-02-07 21:43:014451 EXPECT_FLOAT_EQ(
4452 -15.f, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() *
4453 top_controls_height_);
4454 EXPECT_FLOAT_EQ(
4455 15.f,
4456 host_impl_->active_tree()->top_controls_shown_ratio()->ActiveBase() *
4457 top_controls_height_);
bokan88eae012014-09-09 20:40:424458}
4459
4460// Test that changing the top controls layout height is correctly applied to
4461// the inner viewport container bounds. That is, the top controls layout
4462// height is the amount that the inner viewport container was shrunk outside
4463// the compositor to accommodate the top controls.
4464TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) {
weiliangc8f4ef0d2015-11-27 00:15:554465 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024466 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054467 SetupTopControlsAndScrollLayerWithVirtualViewport(
4468 layer_size_, layer_size_, layer_size_);
bokan88eae012014-09-09 20:40:424469 DrawFrame();
4470
aelias6004fe02015-02-07 21:43:014471 host_impl_->sync_tree()->PushTopControlsFromMainThread(1.f);
dtrainorcb7779b82014-12-04 01:08:024472 host_impl_->sync_tree()->set_top_controls_shrink_blink_size(true);
bokan88eae012014-09-09 20:40:424473
aelias6004fe02015-02-07 21:43:014474 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4475 1.f);
4476 host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
4477 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
bokan88eae012014-09-09 20:40:424478
4479 host_impl_->DidChangeTopControlsPosition();
jaydasikaf419bf72016-06-15 10:21:214480 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4481 ->test_properties()
4482 ->parent->test_properties()
4483 ->parent;
bokanf553cb3b2015-07-23 18:54:054484 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424485 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4486
jaydasikabf1875a2016-06-28 03:39:594487 host_impl_->sync_tree()->root_layer_for_testing()->SetBounds(
bokanf553cb3b2015-07-23 18:54:054488 gfx::Size(inner_clip_ptr->bounds().width(),
4489 inner_clip_ptr->bounds().height() - 50.f));
bokan88eae012014-09-09 20:40:424490
4491 host_impl_->ActivateSyncTree();
4492
jaydasikaf419bf72016-06-15 10:21:214493 inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4494 ->test_properties()
4495 ->parent->test_properties()
4496 ->parent;
bokan88eae012014-09-09 20:40:424497 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4498
4499 // The total bounds should remain unchanged since the bounds delta should
4500 // account for the difference between the layout height and the current
4501 // top controls offset.
bokanf553cb3b2015-07-23 18:54:054502 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
4503 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), inner_clip_ptr->bounds_delta());
bokan88eae012014-09-09 20:40:424504
aelias6004fe02015-02-07 21:43:014505 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f);
bokan88eae012014-09-09 20:40:424506 host_impl_->DidChangeTopControlsPosition();
4507
aelias6004fe02015-02-07 21:43:014508 EXPECT_EQ(1.f, host_impl_->top_controls_manager()->TopControlsShownRatio());
4509 EXPECT_EQ(50.f, host_impl_->top_controls_manager()->TopControlsHeight());
dtrainorcb7779b82014-12-04 01:08:024510 EXPECT_EQ(50.f, host_impl_->top_controls_manager()->ContentTopOffset());
bokanf553cb3b2015-07-23 18:54:054511 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), inner_clip_ptr->bounds_delta());
dtrainorcb7779b82014-12-04 01:08:024512 EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f),
bokanf553cb3b2015-07-23 18:54:054513 inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424514}
4515
bokanef971462014-10-13 22:58:324516// Test that showing/hiding the top controls when the viewport is fully scrolled
4517// doesn't incorrectly change the viewport offset due to clamping from changing
4518// viewport bounds.
4519TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) {
4520 SetupTopControlsAndScrollLayerWithVirtualViewport(
4521 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
4522 DrawFrame();
4523
aelias6004fe02015-02-07 21:43:014524 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
bokanef971462014-10-13 22:58:324525
4526 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
4527 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
4528
4529 // Scroll the viewports to max scroll offset.
sunxdb7e79432016-03-09 21:13:424530 SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f));
4531 SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100.f));
bokanef971462014-10-13 22:58:324532
4533 gfx::ScrollOffset viewport_offset =
4534 host_impl_->active_tree()->TotalScrollOffset();
4535 EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset);
4536
4537 // Hide the top controls by 25px.
4538 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224539 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034540 host_impl_
4541 ->ScrollBegin(BeginState(gfx::Point()).get(),
4542 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224543 .thread);
majidvp944a8cd2016-01-12 21:05:184544 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
sujiths.s344435e2014-11-08 03:04:034545
4546 // scrolling down at the max extents no longer hides the top controls
aelias6004fe02015-02-07 21:43:014547 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
sujiths.s344435e2014-11-08 03:04:034548
4549 // forcefully hide the top controls by 25px
4550 host_impl_->top_controls_manager()->ScrollBy(scroll_delta);
majidvp944a8cd2016-01-12 21:05:184551 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324552
aelias6004fe02015-02-07 21:43:014553 EXPECT_FLOAT_EQ(scroll_delta.y(),
4554 top_controls_height_ -
4555 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324556
4557 inner_scroll->ClampScrollToMaxScrollOffset();
4558 outer_scroll->ClampScrollToMaxScrollOffset();
4559
4560 // We should still be fully scrolled.
4561 EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
4562 host_impl_->active_tree()->TotalScrollOffset());
4563
4564 viewport_offset = host_impl_->active_tree()->TotalScrollOffset();
4565
4566 // Bring the top controls down by 25px.
4567 scroll_delta = gfx::Vector2dF(0.f, -25.f);
tdresser81e84c672016-01-18 23:21:224568 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034569 host_impl_
4570 ->ScrollBegin(BeginState(gfx::Point()).get(),
4571 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224572 .thread);
majidvp944a8cd2016-01-12 21:05:184573 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
4574 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324575
4576 // The viewport offset shouldn't have changed.
4577 EXPECT_EQ(viewport_offset,
4578 host_impl_->active_tree()->TotalScrollOffset());
4579
4580 // Scroll the viewports to max scroll offset.
sunxdb7e79432016-03-09 21:13:424581 SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f));
4582 SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100.f));
bokanef971462014-10-13 22:58:324583 EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
4584 host_impl_->active_tree()->TotalScrollOffset());
4585}
4586
4587// Test that the top controls coming in and out maintains the same aspect ratio
4588// between the inner and outer viewports.
4589TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) {
4590 SetupTopControlsAndScrollLayerWithVirtualViewport(
4591 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
bokan0c33a092015-07-29 18:27:564592 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 2.f);
bokanef971462014-10-13 22:58:324593 DrawFrame();
4594
aelias6004fe02015-02-07 21:43:014595 EXPECT_FLOAT_EQ(top_controls_height_,
4596 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324597
4598 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224599 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034600 host_impl_
4601 ->ScrollBegin(BeginState(gfx::Point()).get(),
4602 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224603 .thread);
majidvp944a8cd2016-01-12 21:05:184604 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
4605 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324606
aelias6004fe02015-02-07 21:43:014607 EXPECT_FLOAT_EQ(scroll_delta.y(),
4608 top_controls_height_ -
4609 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324610
4611 // Top controls were hidden by 25px so the inner viewport should have expanded
4612 // by that much.
4613 LayerImpl* outer_container =
4614 host_impl_->active_tree()->OuterViewportContainerLayer();
4615 LayerImpl* inner_container =
4616 host_impl_->active_tree()->InnerViewportContainerLayer();
danakjddaec912015-09-25 19:38:404617 EXPECT_EQ(gfx::SizeF(100.f, 100.f + 25.f),
4618 inner_container->BoundsForScrolling());
bokanef971462014-10-13 22:58:324619
4620 // Outer viewport should match inner's aspect ratio. The bounds are ceiled.
4621 float aspect_ratio = inner_container->BoundsForScrolling().width() /
4622 inner_container->BoundsForScrolling().height();
danakjddaec912015-09-25 19:38:404623 gfx::SizeF expected =
4624 gfx::SizeF(gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio)));
bokanef971462014-10-13 22:58:324625 EXPECT_EQ(expected, outer_container->BoundsForScrolling());
4626 EXPECT_EQ(expected,
4627 host_impl_->InnerViewportScrollLayer()->BoundsForScrolling());
4628}
4629
4630// Test that scrolling the outer viewport affects the top controls.
4631TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) {
4632 SetupTopControlsAndScrollLayerWithVirtualViewport(
4633 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
4634 DrawFrame();
4635
dtrainorcb7779b82014-12-04 01:08:024636 EXPECT_EQ(top_controls_height_,
aelias6004fe02015-02-07 21:43:014637 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324638
4639 // Send a gesture scroll that will scroll the outer viewport, make sure the
4640 // top controls get scrolled.
4641 gfx::Vector2dF scroll_delta(0.f, 15.f);
tdresser81e84c672016-01-18 23:21:224642 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034643 host_impl_
4644 ->ScrollBegin(BeginState(gfx::Point()).get(),
4645 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224646 .thread);
majidvp944a8cd2016-01-12 21:05:184647 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdressera3b162b82015-09-29 17:51:434648
tdressera3f3a942015-09-28 21:15:394649 EXPECT_EQ(host_impl_->InnerViewportScrollLayer(),
bokanef971462014-10-13 22:58:324650 host_impl_->CurrentlyScrollingLayer());
majidvp944a8cd2016-01-12 21:05:184651 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324652
aelias6004fe02015-02-07 21:43:014653 EXPECT_FLOAT_EQ(scroll_delta.y(),
4654 top_controls_height_ -
4655 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324656
4657 scroll_delta = gfx::Vector2dF(0.f, 50.f);
tdresser81e84c672016-01-18 23:21:224658 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034659 host_impl_
4660 ->ScrollBegin(BeginState(gfx::Point()).get(),
4661 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224662 .thread);
majidvp944a8cd2016-01-12 21:05:184663 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokanef971462014-10-13 22:58:324664
aelias6004fe02015-02-07 21:43:014665 EXPECT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset());
tdressera3f3a942015-09-28 21:15:394666 EXPECT_EQ(host_impl_->InnerViewportScrollLayer(),
bokanef971462014-10-13 22:58:324667 host_impl_->CurrentlyScrollingLayer());
4668
majidvp944a8cd2016-01-12 21:05:184669 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324670
4671 // Position the viewports such that the inner viewport will be scrolled.
4672 gfx::Vector2dF inner_viewport_offset(0.f, 25.f);
sunxdb7e79432016-03-09 21:13:424673 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(),
4674 gfx::Vector2dF());
4675 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(),
4676 inner_viewport_offset);
bokanef971462014-10-13 22:58:324677
4678 scroll_delta = gfx::Vector2dF(0.f, -65.f);
tdresser81e84c672016-01-18 23:21:224679 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034680 host_impl_
4681 ->ScrollBegin(BeginState(gfx::Point()).get(),
4682 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224683 .thread);
majidvp944a8cd2016-01-12 21:05:184684 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokanef971462014-10-13 22:58:324685
dtrainorcb7779b82014-12-04 01:08:024686 EXPECT_EQ(top_controls_height_,
aelias6004fe02015-02-07 21:43:014687 host_impl_->top_controls_manager()->ContentTopOffset());
4688 EXPECT_FLOAT_EQ(
dtrainorcb7779b82014-12-04 01:08:024689 inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_),
sunxdb7e79432016-03-09 21:13:424690 ScrollDelta(host_impl_->InnerViewportScrollLayer()).y());
bokanef971462014-10-13 22:58:324691
majidvp944a8cd2016-01-12 21:05:184692 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324693}
4694
[email protected]fef74fd2014-02-27 06:28:174695TEST_F(LayerTreeHostImplTopControlsTest,
4696 ScrollNonScrollableRootWithTopControls) {
weiliangc8f4ef0d2015-11-27 00:15:554697 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024698 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054699 SetupTopControlsAndScrollLayerWithVirtualViewport(
4700 layer_size_, layer_size_, layer_size_);
[email protected]ce2e8112013-11-28 07:44:364701 DrawFrame();
[email protected]c8415bf92013-02-17 18:57:274702
tdresser81e84c672016-01-18 23:21:224703 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034704 host_impl_
4705 ->ScrollBegin(BeginState(gfx::Point()).get(),
4706 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224707 .thread);
[email protected]c8415bf92013-02-17 18:57:274708
[email protected]aa043632013-03-25 03:39:424709 host_impl_->top_controls_manager()->ScrollBegin();
4710 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
4711 host_impl_->top_controls_manager()->ScrollEnd();
bokan88eae012014-09-09 20:40:424712 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
[email protected]fef74fd2014-02-27 06:28:174713 // Now that top controls have moved, expect the clip to resize.
jaydasikaf419bf72016-06-15 10:21:214714 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4715 ->test_properties()
4716 ->parent->test_properties()
4717 ->parent;
bokanf553cb3b2015-07-23 18:54:054718 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
[email protected]c8415bf92013-02-17 18:57:274719
majidvp944a8cd2016-01-12 21:05:184720 host_impl_->ScrollEnd(EndState().get());
[email protected]d948c112014-01-10 02:13:534721
tdresser81e84c672016-01-18 23:21:224722 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034723 host_impl_
4724 ->ScrollBegin(BeginState(gfx::Point()).get(),
4725 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224726 .thread);
[email protected]fef74fd2014-02-27 06:28:174727
4728 float scroll_increment_y = -25.f;
4729 host_impl_->top_controls_manager()->ScrollBegin();
4730 host_impl_->top_controls_manager()->ScrollBy(
4731 gfx::Vector2dF(0.f, scroll_increment_y));
aelias6004fe02015-02-07 21:43:014732 EXPECT_FLOAT_EQ(-scroll_increment_y,
4733 host_impl_->top_controls_manager()->ContentTopOffset());
[email protected]fef74fd2014-02-27 06:28:174734 // Now that top controls have moved, expect the clip to resize.
4735 EXPECT_EQ(gfx::Size(viewport_size_.width(),
4736 viewport_size_.height() + scroll_increment_y),
bokanf553cb3b2015-07-23 18:54:054737 inner_clip_ptr->bounds());
[email protected]fef74fd2014-02-27 06:28:174738
4739 host_impl_->top_controls_manager()->ScrollBy(
4740 gfx::Vector2dF(0.f, scroll_increment_y));
4741 host_impl_->top_controls_manager()->ScrollEnd();
aelias6004fe02015-02-07 21:43:014742 EXPECT_FLOAT_EQ(-2 * scroll_increment_y,
4743 host_impl_->top_controls_manager()->ContentTopOffset());
[email protected]fef74fd2014-02-27 06:28:174744 // Now that top controls have moved, expect the clip to resize.
bokanf553cb3b2015-07-23 18:54:054745 EXPECT_EQ(clip_size_, inner_clip_ptr->bounds());
[email protected]fef74fd2014-02-27 06:28:174746
majidvp944a8cd2016-01-12 21:05:184747 host_impl_->ScrollEnd(EndState().get());
[email protected]fef74fd2014-02-27 06:28:174748
4749 // Verify the layer is once-again non-scrollable.
4750 EXPECT_EQ(
miletusf57925d2014-10-01 19:38:134751 gfx::ScrollOffset(),
[email protected]fef74fd2014-02-27 06:28:174752 host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
4753
tdresser81e84c672016-01-18 23:21:224754 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034755 host_impl_
4756 ->ScrollBegin(BeginState(gfx::Point()).get(),
4757 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224758 .thread);
[email protected]c8415bf92013-02-17 18:57:274759}
4760
bokan7ad75ed2016-03-30 19:29:574761// Tests that activating a pending tree while there's a bounds_delta on the
4762// viewport layers from top controls doesn't cause a scroll jump. This bug was
4763// occurring because the UpdateViewportContainerSizes was being called before
4764// the property trees were updated with the bounds_delta. crbug.com/597266.
4765TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) {
bokanfe9e63e2016-07-19 19:19:084766 const gfx::Size inner_viewport_size(1000, 1000);
bokan7ad75ed2016-03-30 19:29:574767 const gfx::Size outer_viewport_size(1000, 1000);
4768 const gfx::Size content_size(2000, 2000);
4769
bokanfe9e63e2016-07-19 19:19:084770 // Initialization
4771 {
4772 SetupTopControlsAndScrollLayerWithVirtualViewport(
4773 inner_viewport_size, outer_viewport_size, content_size);
4774 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
bokan7ad75ed2016-03-30 19:29:574775
bokanfe9e63e2016-07-19 19:19:084776 // Start off with the top controls hidden on both main and impl.
4777 host_impl_->active_tree()->set_top_controls_shrink_blink_size(false);
4778 host_impl_->active_tree()->PushTopControlsFromMainThread(0);
bokan7ad75ed2016-03-30 19:29:574779
bokanfe9e63e2016-07-19 19:19:084780 host_impl_->CreatePendingTree();
4781 SetupTopControlsAndScrollLayerWithVirtualViewport(
4782 host_impl_->pending_tree(), inner_viewport_size, outer_viewport_size,
4783 content_size);
4784 host_impl_->pending_tree()->set_top_controls_shrink_blink_size(false);
bokan7ad75ed2016-03-30 19:29:574785
bokanfe9e63e2016-07-19 19:19:084786 // Fully scroll the viewport.
4787 host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
4788 InputHandler::TOUCHSCREEN);
4789 host_impl_->ScrollBy(
4790 UpdateState(gfx::Point(), gfx::Vector2d(0, 2000)).get());
4791 host_impl_->ScrollEnd(EndState().get());
4792 }
bokan7ad75ed2016-03-30 19:29:574793
bokan7ad75ed2016-03-30 19:29:574794 LayerImpl* outer_scroll =
4795 host_impl_->active_tree()->OuterViewportScrollLayer();
4796
bokanfe9e63e2016-07-19 19:19:084797 ASSERT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset());
4798 ASSERT_EQ(1000, outer_scroll->MaxScrollOffset().y());
4799 ASSERT_EQ(1000, outer_scroll->CurrentScrollOffset().y());
bokan7ad75ed2016-03-30 19:29:574800
bokanfe9e63e2016-07-19 19:19:084801 // Kick off an animation to show the top controls.
4802 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN, true);
4803 base::TimeTicks start_time = base::TimeTicks::Now();
4804 BeginFrameArgs begin_frame_args =
4805 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
bokan7ad75ed2016-03-30 19:29:574806
bokanfe9e63e2016-07-19 19:19:084807 // Pump an animation frame to put some delta in the top controls.
4808 {
4809 begin_frame_args.frame_time =
4810 start_time + base::TimeDelta::FromMilliseconds(50);
4811 host_impl_->WillBeginImplFrame(begin_frame_args);
4812 host_impl_->Animate();
4813 host_impl_->UpdateAnimationState(true);
4814 host_impl_->DidFinishImplFrame();
4815 }
4816
4817 // Pull the top controls delta and get it back to the pending tree so that
4818 // when we go to activate the pending tree we cause a change to top controls.
4819 {
4820 float delta =
4821 host_impl_->active_tree()->top_controls_shown_ratio()->Delta();
4822 ASSERT_GT(delta, 0);
4823 ASSERT_LT(delta, 1);
4824 host_impl_->active_tree()
4825 ->top_controls_shown_ratio()
4826 ->PullDeltaForMainThread();
4827 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4828 delta);
4829 }
4830
4831 // 200 is the kShowHideMaxDurationMs value from top_controls_manager.cc so the
4832 // top controls should be fully animated in this frame.
4833 {
4834 begin_frame_args.frame_time =
4835 start_time + base::TimeDelta::FromMilliseconds(200);
4836 host_impl_->WillBeginImplFrame(begin_frame_args);
4837 host_impl_->Animate();
4838 host_impl_->UpdateAnimationState(true);
4839 host_impl_->DidFinishImplFrame();
4840
4841 ASSERT_EQ(50, host_impl_->top_controls_manager()->ContentTopOffset());
4842 ASSERT_EQ(1050, outer_scroll->MaxScrollOffset().y());
4843 // NEAR because clip layer bounds are truncated in MaxScrollOffset so we
4844 // lose some precision in the intermediate animation steps.
4845 ASSERT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1.f);
4846 }
4847
4848 // Activate the pending tree which should have the same scroll value as the
bokan7ad75ed2016-03-30 19:29:574849 // active tree.
bokanfe9e63e2016-07-19 19:19:084850 {
4851 host_impl_->pending_tree()
4852 ->property_trees()
4853 ->scroll_tree.SetScrollOffsetDeltaForTesting(outer_scroll->id(),
4854 gfx::Vector2dF(0, 1050));
4855 host_impl_->ActivateSyncTree();
bokan7ad75ed2016-03-30 19:29:574856
bokanfe9e63e2016-07-19 19:19:084857 // Make sure we don't accidentally clamp the outer offset based on a bounds
4858 // delta that hasn't yet been updated.
4859 EXPECT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1.f);
4860 }
bokan7ad75ed2016-03-30 19:29:574861}
4862
[email protected]aa043632013-03-25 03:39:424863TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
4864 // Test the configuration where a non-composited root layer is embedded in a
4865 // scrollable outer layer.
4866 gfx::Size surface_size(10, 10);
[email protected]adeda572014-01-31 00:49:474867 gfx::Size contents_size(20, 20);
[email protected]94f206c12012-08-25 00:09:144868
danakj60bc3bc2016-04-09 00:24:484869 std::unique_ptr<LayerImpl> content_layer =
[email protected]aa043632013-03-25 03:39:424870 LayerImpl::Create(host_impl_->active_tree(), 1);
4871 content_layer->SetDrawsContent(true);
4872 content_layer->SetPosition(gfx::PointF());
[email protected]adeda572014-01-31 00:49:474873 content_layer->SetBounds(contents_size);
[email protected]94f206c12012-08-25 00:09:144874
danakj60bc3bc2016-04-09 00:24:484875 std::unique_ptr<LayerImpl> scroll_clip_layer =
[email protected]adeda572014-01-31 00:49:474876 LayerImpl::Create(host_impl_->active_tree(), 3);
4877 scroll_clip_layer->SetBounds(surface_size);
4878
danakj60bc3bc2016-04-09 00:24:484879 std::unique_ptr<LayerImpl> scroll_layer =
[email protected]aa043632013-03-25 03:39:424880 LayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]adeda572014-01-31 00:49:474881 scroll_layer->SetScrollClipLayer(3);
4882 scroll_layer->SetBounds(contents_size);
[email protected]aa043632013-03-25 03:39:424883 scroll_layer->SetPosition(gfx::PointF());
jaydasika89f7b5a2016-06-22 02:08:394884 scroll_layer->test_properties()->AddChild(std::move(content_layer));
4885 scroll_clip_layer->test_properties()->AddChild(std::move(scroll_layer));
[email protected]94f206c12012-08-25 00:09:144886
jaydasika6b5a32bf2016-04-22 21:56:364887 scroll_clip_layer->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:594888 host_impl_->active_tree()->SetRootLayerForTesting(
4889 std::move(scroll_clip_layer));
danakj74af409e2016-07-01 00:41:484890 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4891
[email protected]18ce59702013-04-09 04:58:404892 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364893 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144894
tdresser81e84c672016-01-18 23:21:224895 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:184896 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:224897 InputHandler::WHEEL)
4898 .thread);
majidvp944a8cd2016-01-12 21:05:184899 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
4900 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:424901 EXPECT_TRUE(did_request_redraw_);
4902 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144903}
4904
[email protected]aa043632013-03-25 03:39:424905TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
4906 gfx::Size surface_size(10, 10);
[email protected]adeda572014-01-31 00:49:474907 gfx::Size contents_size(20, 20);
danakj60bc3bc2016-04-09 00:24:484908 std::unique_ptr<LayerImpl> root =
4909 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:424910 root->SetBounds(surface_size);
jaydasika89f7b5a2016-06-22 02:08:394911 root->test_properties()->AddChild(
4912 CreateScrollableLayer(2, contents_size, root.get()));
jaydasika6b5a32bf2016-04-22 21:56:364913 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:594914 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:484915 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4916
[email protected]18ce59702013-04-09 04:58:404917 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364918 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144919
tdresser81e84c672016-01-18 23:21:224920 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:184921 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:224922 InputHandler::WHEEL)
4923 .thread);
majidvp944a8cd2016-01-12 21:05:184924 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
4925 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:424926 EXPECT_TRUE(did_request_redraw_);
4927 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144928}
4929
[email protected]aa043632013-03-25 03:39:424930TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
4931 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:484932 std::unique_ptr<LayerImpl> root =
4933 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika89f7b5a2016-06-22 02:08:394934 root->test_properties()->AddChild(
4935 CreateScrollableLayer(2, surface_size, root.get()));
jaydasika6b5a32bf2016-04-22 21:56:364936 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:594937 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:484938 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4939
[email protected]18ce59702013-04-09 04:58:404940 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364941 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144942
[email protected]aa043632013-03-25 03:39:424943 // Scroll event is ignored because the input coordinate is outside the layer
4944 // boundaries.
tdresser81e84c672016-01-18 23:21:224945 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
4946 BeginState(gfx::Point(15, 5)).get(), InputHandler::WHEEL);
4947 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:404948 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:224949 status.main_thread_scrolling_reasons);
4950
[email protected]aa043632013-03-25 03:39:424951 EXPECT_FALSE(did_request_redraw_);
4952 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144953}
4954
[email protected]aa043632013-03-25 03:39:424955TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
4956 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:484957 std::unique_ptr<LayerImpl> root =
4958 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika6b5a32bf2016-04-22 21:56:364959 root->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:484960 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:474961 CreateScrollableLayer(2, surface_size, root.get());
[email protected]94f206c12012-08-25 00:09:144962
[email protected]aa043632013-03-25 03:39:424963 gfx::Transform matrix;
4964 matrix.RotateAboutXAxis(180.0);
jaydasika10d43fc2016-08-18 04:06:044965 child->test_properties()->transform = matrix;
jaydasika6b5a32bf2016-04-22 21:56:364966 child->test_properties()->double_sided = false;
[email protected]94f206c12012-08-25 00:09:144967
jaydasika89f7b5a2016-06-22 02:08:394968 root->test_properties()->AddChild(std::move(child));
jaydasikabf1875a2016-06-28 03:39:594969 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:484970 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4971
4972 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364973 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144974
[email protected]aa043632013-03-25 03:39:424975 // Scroll event is ignored because the scrollable layer is not facing the
4976 // viewer and there is nothing scrollable behind it.
tdresser81e84c672016-01-18 23:21:224977 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
4978 BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL);
4979 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:404980 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:224981 status.main_thread_scrolling_reasons);
4982
[email protected]aa043632013-03-25 03:39:424983 EXPECT_FALSE(did_request_redraw_);
4984 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144985}
4986
[email protected]aa043632013-03-25 03:39:424987TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
4988 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:484989 std::unique_ptr<LayerImpl> clip_layer =
[email protected]adeda572014-01-31 00:49:474990 LayerImpl::Create(host_impl_->active_tree(), 3);
danakj60bc3bc2016-04-09 00:24:484991 std::unique_ptr<LayerImpl> content_layer =
[email protected]adeda572014-01-31 00:49:474992 CreateScrollableLayer(1, surface_size, clip_layer.get());
tdresser81e84c672016-01-18 23:21:224993 content_layer->set_main_thread_scrolling_reasons(
danakj35904762016-01-21 20:49:404994 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
[email protected]adeda572014-01-31 00:49:474995 content_layer->SetScrollClipLayer(Layer::INVALID_ID);
[email protected]94f206c12012-08-25 00:09:144996
[email protected]adeda572014-01-31 00:49:474997 // Note: we can use the same clip layer for both since both calls to
4998 // CreateScrollableLayer() use the same surface size.
danakj60bc3bc2016-04-09 00:24:484999 std::unique_ptr<LayerImpl> scroll_layer =
[email protected]adeda572014-01-31 00:49:475000 CreateScrollableLayer(2, surface_size, clip_layer.get());
jaydasika89f7b5a2016-06-22 02:08:395001 scroll_layer->test_properties()->AddChild(std::move(content_layer));
5002 clip_layer->test_properties()->AddChild(std::move(scroll_layer));
jaydasika6b5a32bf2016-04-22 21:56:365003 clip_layer->test_properties()->force_render_surface = true;
[email protected]94f206c12012-08-25 00:09:145004
jaydasikabf1875a2016-06-28 03:39:595005 host_impl_->active_tree()->SetRootLayerForTesting(std::move(clip_layer));
danakj74af409e2016-07-01 00:41:485006 host_impl_->active_tree()->BuildPropertyTreesForTesting();
5007
[email protected]18ce59702013-04-09 04:58:405008 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365009 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145010
[email protected]aa043632013-03-25 03:39:425011 // Scrolling fails because the content layer is asking to be scrolled on the
5012 // main thread.
tdresser81e84c672016-01-18 23:21:225013 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
5014 BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL);
5015 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:405016 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:225017 status.main_thread_scrolling_reasons);
[email protected]94f206c12012-08-25 00:09:145018}
5019
[email protected]aa043632013-03-25 03:39:425020TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
bokan1f01388f2015-09-15 20:55:545021 gfx::Size viewport_size(20, 20);
[email protected]aa043632013-03-25 03:39:425022 float page_scale = 2.f;
bokan1f86d8f2015-07-30 16:08:545023
5024 SetupScrollAndContentsLayers(viewport_size);
5025
5026 // Setup the layers so that the outer viewport is scrollable.
jaydasikaf419bf72016-06-15 10:21:215027 host_impl_->active_tree()
5028 ->InnerViewportScrollLayer()
5029 ->test_properties()
5030 ->parent->SetBounds(viewport_size);
bokan1f86d8f2015-07-30 16:08:545031 host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds(
bokan1f01388f2015-09-15 20:55:545032 gfx::Size(40, 40));
bokan1f86d8f2015-07-30 16:08:545033 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
[email protected]ce2e8112013-11-28 07:44:365034 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145035
[email protected]adeda572014-01-31 00:49:475036 LayerImpl* root_scroll =
bokan1f86d8f2015-07-30 16:08:545037 host_impl_->active_tree()->OuterViewportScrollLayer();
bokan1f01388f2015-09-15 20:55:545038 LayerImpl* inner_scroll =
5039 host_impl_->active_tree()->InnerViewportScrollLayer();
[email protected]fef74fd2014-02-27 06:28:175040 EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds());
[email protected]9781afa2013-07-17 23:15:325041
[email protected]aa043632013-03-25 03:39:425042 gfx::Vector2d scroll_delta(0, 10);
5043 gfx::Vector2d expected_scroll_delta = scroll_delta;
miletusf57925d2014-10-01 19:38:135044 gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
tdresser81e84c672016-01-18 23:21:225045 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185046 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225047 InputHandler::WHEEL)
5048 .thread);
majidvp944a8cd2016-01-12 21:05:185049 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5050 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145051
[email protected]aa043632013-03-25 03:39:425052 // Set new page scale from main thread.
bokan1f86d8f2015-07-30 16:08:545053 host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
[email protected]94f206c12012-08-25 00:09:145054
danakj60bc3bc2016-04-09 00:24:485055 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5056 host_impl_->ProcessScrollDeltas();
bokan1f01388f2015-09-15 20:55:545057 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
tdresser99977952015-07-02 19:49:185058 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145059
[email protected]aa043632013-03-25 03:39:425060 // The scroll range should also have been updated.
[email protected]adeda572014-01-31 00:49:475061 EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
[email protected]94f206c12012-08-25 00:09:145062
[email protected]aa043632013-03-25 03:39:425063 // The page scale delta remains constant because the impl thread did not
5064 // scale.
[email protected]f2136262013-04-26 21:10:195065 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:145066}
5067
[email protected]aa043632013-03-25 03:39:425068TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
bokan1f01388f2015-09-15 20:55:545069 gfx::Size viewport_size(20, 20);
[email protected]aa043632013-03-25 03:39:425070 float page_scale = 2.f;
bokan1f86d8f2015-07-30 16:08:545071
5072 SetupScrollAndContentsLayers(viewport_size);
5073
5074 // Setup the layers so that the outer viewport is scrollable.
jaydasikaf419bf72016-06-15 10:21:215075 host_impl_->active_tree()
5076 ->InnerViewportScrollLayer()
5077 ->test_properties()
5078 ->parent->SetBounds(viewport_size);
bokan1f86d8f2015-07-30 16:08:545079 host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds(
bokan1f01388f2015-09-15 20:55:545080 gfx::Size(40, 40));
bokan1f86d8f2015-07-30 16:08:545081 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
danakj74af409e2016-07-01 00:41:485082 host_impl_->active_tree()->BuildPropertyTreesForTesting();
5083
[email protected]ce2e8112013-11-28 07:44:365084 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145085
[email protected]adeda572014-01-31 00:49:475086 LayerImpl* root_scroll =
bokan1f86d8f2015-07-30 16:08:545087 host_impl_->active_tree()->OuterViewportScrollLayer();
bokan1f01388f2015-09-15 20:55:545088 LayerImpl* inner_scroll =
5089 host_impl_->active_tree()->InnerViewportScrollLayer();
[email protected]fef74fd2014-02-27 06:28:175090 EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds());
[email protected]9781afa2013-07-17 23:15:325091
[email protected]aa043632013-03-25 03:39:425092 gfx::Vector2d scroll_delta(0, 10);
5093 gfx::Vector2d expected_scroll_delta = scroll_delta;
miletusf57925d2014-10-01 19:38:135094 gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
tdresser81e84c672016-01-18 23:21:225095 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185096 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225097 InputHandler::WHEEL)
5098 .thread);
majidvp944a8cd2016-01-12 21:05:185099 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5100 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145101
[email protected]aa043632013-03-25 03:39:425102 // Set new page scale on impl thread by pinching.
majidvp944a8cd2016-01-12 21:05:185103 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:035104 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:425105 host_impl_->PinchGestureBegin();
5106 host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
5107 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:185108 host_impl_->ScrollEnd(EndState().get());
danakj74af409e2016-07-01 00:41:485109
[email protected]aa043632013-03-25 03:39:425110 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:145111
[email protected]aa043632013-03-25 03:39:425112 // The scroll delta is not scaled because the main thread did not scale.
danakj60bc3bc2016-04-09 00:24:485113 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5114 host_impl_->ProcessScrollDeltas();
bokan1f01388f2015-09-15 20:55:545115 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
tdresser99977952015-07-02 19:49:185116 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145117
[email protected]aa043632013-03-25 03:39:425118 // The scroll range should also have been updated.
[email protected]adeda572014-01-31 00:49:475119 EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
[email protected]94f206c12012-08-25 00:09:145120
[email protected]aa043632013-03-25 03:39:425121 // The page scale delta should match the new scale on the impl side.
aelias58eec0812014-12-04 01:04:405122 EXPECT_EQ(page_scale, host_impl_->active_tree()->current_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:145123}
5124
[email protected]aa043632013-03-25 03:39:425125TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
bokan0c33a092015-07-29 18:27:565126 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
[email protected]aa043632013-03-25 03:39:425127 gfx::Size surface_size(10, 10);
5128 float default_page_scale = 1.f;
5129 gfx::Transform default_page_scale_matrix;
[email protected]3209161d2013-03-29 19:17:345130 default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
[email protected]1c0c9bc2012-10-08 22:41:485131
[email protected]aa043632013-03-25 03:39:425132 float new_page_scale = 2.f;
5133 gfx::Transform new_page_scale_matrix;
5134 new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
[email protected]94f206c12012-08-25 00:09:145135
[email protected]aa043632013-03-25 03:39:425136 // Create a normal scrollable root layer and another scrollable child layer.
[email protected]35a99a12013-05-09 23:52:295137 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
jaydasikad7dea632015-11-06 04:40:125138 scroll->SetDrawsContent(true);
jaydasikabf1875a2016-06-28 03:39:595139 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
jaydasikafc66cfb2016-06-10 04:34:225140 LayerImpl* child = scroll->test_properties()->children[0];
jaydasikad7dea632015-11-06 04:40:125141 child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:145142
danakj60bc3bc2016-04-09 00:24:485143 std::unique_ptr<LayerImpl> scrollable_child_clip =
[email protected]adeda572014-01-31 00:49:475144 LayerImpl::Create(host_impl_->active_tree(), 6);
danakj60bc3bc2016-04-09 00:24:485145 std::unique_ptr<LayerImpl> scrollable_child =
[email protected]adeda572014-01-31 00:49:475146 CreateScrollableLayer(7, surface_size, scrollable_child_clip.get());
jaydasika89f7b5a2016-06-22 02:08:395147 scrollable_child_clip->test_properties()->AddChild(
5148 std::move(scrollable_child));
5149 child->test_properties()->AddChild(std::move(scrollable_child_clip));
jaydasikafc66cfb2016-06-10 04:34:225150 LayerImpl* grand_child = child->test_properties()->children[0];
jaydasikad7dea632015-11-06 04:40:125151 grand_child->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:485152 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145153
[email protected]aa043632013-03-25 03:39:425154 // Set new page scale on impl thread by pinching.
majidvp944a8cd2016-01-12 21:05:185155 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:035156 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:425157 host_impl_->PinchGestureBegin();
5158 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
5159 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:185160 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:425161 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:145162
[email protected]aa043632013-03-25 03:39:425163 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
5164 // the page scale delta on the root layer is applied hierarchically.
5165 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:485166 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:455167 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:425168 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:145169
ajumad9432e32015-11-30 19:43:445170 EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(0, 0));
5171 EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(1, 1));
5172 EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(0, 0));
5173 EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(1, 1));
5174 EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(0, 0));
5175 EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(1, 1));
[email protected]aa043632013-03-25 03:39:425176 EXPECT_EQ(new_page_scale,
ajumad9432e32015-11-30 19:43:445177 grand_child->DrawTransform().matrix().getDouble(0, 0));
[email protected]aa043632013-03-25 03:39:425178 EXPECT_EQ(new_page_scale,
ajumad9432e32015-11-30 19:43:445179 grand_child->DrawTransform().matrix().getDouble(1, 1));
[email protected]94f206c12012-08-25 00:09:145180}
5181
[email protected]aa043632013-03-25 03:39:425182TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
bokan1f01388f2015-09-15 20:55:545183 SetupScrollAndContentsLayers(gfx::Size(30, 30));
bokanf553cb3b2015-07-23 18:54:055184
5185 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
bokan1f01388f2015-09-15 20:55:545186 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
bokanf553cb3b2015-07-23 18:54:055187
5188 // Make the outer scroll layer scrollable.
5189 outer_scroll->SetBounds(gfx::Size(50, 50));
danakj74af409e2016-07-01 00:41:485190 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokanf553cb3b2015-07-23 18:54:055191
[email protected]ce2e8112013-11-28 07:44:365192 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145193
[email protected]aa043632013-03-25 03:39:425194 gfx::Vector2d scroll_delta(0, 10);
5195 gfx::Vector2d expected_scroll_delta(scroll_delta);
bokanf553cb3b2015-07-23 18:54:055196 gfx::ScrollOffset expected_max_scroll(outer_scroll->MaxScrollOffset());
tdresser81e84c672016-01-18 23:21:225197 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185198 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225199 InputHandler::WHEEL)
5200 .thread);
majidvp944a8cd2016-01-12 21:05:185201 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5202 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145203
[email protected]aa043632013-03-25 03:39:425204 float page_scale = 2.f;
aelias58eec0812014-12-04 01:04:405205 host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f,
[email protected]aa043632013-03-25 03:39:425206 page_scale);
danakj74af409e2016-07-01 00:41:485207 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145208
[email protected]aa043632013-03-25 03:39:425209 DrawOneFrame();
[email protected]1c0c9bc2012-10-08 22:41:485210
danakj60bc3bc2016-04-09 00:24:485211 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5212 host_impl_->ProcessScrollDeltas();
bokan1f01388f2015-09-15 20:55:545213 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
tdresser99977952015-07-02 19:49:185214 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145215
[email protected]aa043632013-03-25 03:39:425216 // The scroll range should not have changed.
bokanf553cb3b2015-07-23 18:54:055217 EXPECT_EQ(outer_scroll->MaxScrollOffset(), expected_max_scroll);
[email protected]94f206c12012-08-25 00:09:145218
[email protected]aa043632013-03-25 03:39:425219 // The page scale delta remains constant because the impl thread did not
5220 // scale.
[email protected]f2136262013-04-26 21:10:195221 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:145222}
5223
[email protected]aa043632013-03-25 03:39:425224TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
5225 // Scroll a child layer beyond its maximum scroll range and make sure the
tdressera3b162b82015-09-29 17:51:435226 // parent layer isn't scrolled.
[email protected]aa043632013-03-25 03:39:425227 gfx::Size surface_size(10, 10);
[email protected]adeda572014-01-31 00:49:475228 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:485229 std::unique_ptr<LayerImpl> root =
5230 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]adeda572014-01-31 00:49:475231 root->SetBounds(surface_size);
jaydasika6b5a32bf2016-04-22 21:56:365232 root->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:485233 std::unique_ptr<LayerImpl> grand_child =
[email protected]adeda572014-01-31 00:49:475234 CreateScrollableLayer(3, content_size, root.get());
[email protected]94f206c12012-08-25 00:09:145235
danakj60bc3bc2016-04-09 00:24:485236 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:475237 CreateScrollableLayer(2, content_size, root.get());
5238 LayerImpl* grand_child_layer = grand_child.get();
jaydasika89f7b5a2016-06-22 02:08:395239 child->test_properties()->AddChild(std::move(grand_child));
[email protected]94f206c12012-08-25 00:09:145240
[email protected]adeda572014-01-31 00:49:475241 LayerImpl* child_layer = child.get();
jaydasika89f7b5a2016-06-22 02:08:395242 root->test_properties()->AddChild(std::move(child));
jaydasikabf1875a2016-06-28 03:39:595243 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:485244 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425245 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:485246
sunxdb7e79432016-03-09 21:13:425247 grand_child_layer->layer_tree_impl()
5248 ->property_trees()
5249 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
5250 gfx::ScrollOffset(0, 5));
5251 child_layer->layer_tree_impl()
5252 ->property_trees()
5253 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
5254 gfx::ScrollOffset(3, 0));
[email protected]adeda572014-01-31 00:49:475255
danakj74af409e2016-07-01 00:41:485256 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365257 DrawFrame();
[email protected]aa043632013-03-25 03:39:425258 {
5259 gfx::Vector2d scroll_delta(-8, -7);
tdresser81e84c672016-01-18 23:21:225260 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185261 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225262 InputHandler::WHEEL)
5263 .thread);
majidvp944a8cd2016-01-12 21:05:185264 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5265 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145266
danakj60bc3bc2016-04-09 00:24:485267 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425268 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:145269
[email protected]aa043632013-03-25 03:39:425270 // The grand child should have scrolled up to its limit.
jaydasikabf1875a2016-06-28 03:39:595271 LayerImpl* child = host_impl_->active_tree()
5272 ->root_layer_for_testing()
5273 ->test_properties()
5274 ->children[0];
jaydasikafc66cfb2016-06-10 04:34:225275 LayerImpl* grand_child = child->test_properties()->children[0];
tdresser99977952015-07-02 19:49:185276 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5277 gfx::Vector2d(0, -5)));
[email protected]94f206c12012-08-25 00:09:145278
tdressera3b162b82015-09-29 17:51:435279 // The child should not have scrolled.
5280 ExpectNone(*scroll_info.get(), child->id());
[email protected]aa043632013-03-25 03:39:425281 }
[email protected]94f206c12012-08-25 00:09:145282}
5283
[email protected]aa043632013-03-25 03:39:425284TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
5285 // Scroll a child layer beyond its maximum scroll range and make sure the
5286 // the scroll doesn't bubble up to the parent layer.
[email protected]adeda572014-01-31 00:49:475287 gfx::Size surface_size(20, 20);
[email protected]fef74fd2014-02-27 06:28:175288 gfx::Size viewport_size(10, 10);
danakj60bc3bc2016-04-09 00:24:485289 std::unique_ptr<LayerImpl> root_ptr =
sunxd676696572016-01-07 16:28:305290 LayerImpl::Create(host_impl_->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:485291 std::unique_ptr<LayerImpl> root_clip =
sunxd676696572016-01-07 16:28:305292 LayerImpl::Create(host_impl_->active_tree(), 2);
jaydasika6b5a32bf2016-04-22 21:56:365293 root_clip->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:485294 std::unique_ptr<LayerImpl> root_scrolling =
sunxd676696572016-01-07 16:28:305295 CreateScrollableLayer(3, surface_size, root_clip.get());
jaydasikaca2605e2016-04-23 02:52:525296 root_scrolling->test_properties()->is_container_for_fixed_position_layers =
5297 true;
[email protected]7dfa6862013-01-31 01:29:095298
danakj60bc3bc2016-04-09 00:24:485299 std::unique_ptr<LayerImpl> grand_child =
sunxd676696572016-01-07 16:28:305300 CreateScrollableLayer(5, surface_size, root_clip.get());
[email protected]7dfa6862013-01-31 01:29:095301
danakj60bc3bc2016-04-09 00:24:485302 std::unique_ptr<LayerImpl> child =
sunxd676696572016-01-07 16:28:305303 CreateScrollableLayer(4, surface_size, root_clip.get());
[email protected]adeda572014-01-31 00:49:475304 LayerImpl* grand_child_layer = grand_child.get();
jaydasika89f7b5a2016-06-22 02:08:395305 child->test_properties()->AddChild(std::move(grand_child));
[email protected]7dfa6862013-01-31 01:29:095306
[email protected]adeda572014-01-31 00:49:475307 LayerImpl* child_layer = child.get();
jaydasika89f7b5a2016-06-22 02:08:395308 root_scrolling->test_properties()->AddChild(std::move(child));
5309 root_clip->test_properties()->AddChild(std::move(root_scrolling));
sunxd676696572016-01-07 16:28:305310 EXPECT_EQ(viewport_size, root_clip->bounds());
jaydasika89f7b5a2016-06-22 02:08:395311 root_ptr->test_properties()->AddChild(std::move(root_clip));
jaydasikabf1875a2016-06-28 03:39:595312 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
danakj74af409e2016-07-01 00:41:485313 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd676696572016-01-07 16:28:305314 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3,
ccameron8230b68b2014-11-21 19:25:185315 Layer::INVALID_ID);
[email protected]aa043632013-03-25 03:39:425316 host_impl_->active_tree()->DidBecomeActive();
[email protected]fef74fd2014-02-27 06:28:175317 host_impl_->SetViewportSize(viewport_size);
[email protected]adeda572014-01-31 00:49:475318
sunxdb7e79432016-03-09 21:13:425319 grand_child_layer->layer_tree_impl()
5320 ->property_trees()
5321 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
5322 gfx::ScrollOffset(0, 2));
5323 child_layer->layer_tree_impl()
5324 ->property_trees()
5325 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
5326 gfx::ScrollOffset(0, 3));
[email protected]adeda572014-01-31 00:49:475327
[email protected]ce2e8112013-11-28 07:44:365328 DrawFrame();
[email protected]aa043632013-03-25 03:39:425329 {
5330 gfx::Vector2d scroll_delta(0, -10);
tdresser81e84c672016-01-18 23:21:225331 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185332 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225333 InputHandler::NON_BUBBLING_GESTURE)
5334 .thread);
majidvp944a8cd2016-01-12 21:05:185335 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5336 host_impl_->ScrollEnd(EndState().get());
[email protected]7dfa6862013-01-31 01:29:095337
danakj60bc3bc2016-04-09 00:24:485338 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425339 host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:095340
[email protected]aa043632013-03-25 03:39:425341 // The grand child should have scrolled up to its limit.
sunxd676696572016-01-07 16:28:305342 LayerImpl* child = host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:595343 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:225344 ->test_properties()
5345 ->children[0]
5346 ->test_properties()
5347 ->children[0]
5348 ->test_properties()
5349 ->children[0];
5350 LayerImpl* grand_child = child->test_properties()->children[0];
tdresser99977952015-07-02 19:49:185351 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5352 gfx::Vector2d(0, -2)));
[email protected]7dfa6862013-01-31 01:29:095353
[email protected]aa043632013-03-25 03:39:425354 // The child should not have scrolled.
5355 ExpectNone(*scroll_info.get(), child->id());
[email protected]7dfa6862013-01-31 01:29:095356
[email protected]aa043632013-03-25 03:39:425357 // The next time we scroll we should only scroll the parent.
5358 scroll_delta = gfx::Vector2d(0, -3);
tdresser81e84c672016-01-18 23:21:225359 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185360 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225361 InputHandler::NON_BUBBLING_GESTURE)
5362 .thread);
[email protected]aa043632013-03-25 03:39:425363 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:185364 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]aa043632013-03-25 03:39:425365 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
majidvp944a8cd2016-01-12 21:05:185366 host_impl_->ScrollEnd(EndState().get());
[email protected]7dfa6862013-01-31 01:29:095367
[email protected]aa043632013-03-25 03:39:425368 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:095369
[email protected]aa043632013-03-25 03:39:425370 // The child should have scrolled up to its limit.
tdresser99977952015-07-02 19:49:185371 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
5372 gfx::Vector2d(0, -3)));
[email protected]7dfa6862013-01-31 01:29:095373
[email protected]aa043632013-03-25 03:39:425374 // The grand child should not have scrolled.
tdresser99977952015-07-02 19:49:185375 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5376 gfx::Vector2d(0, -2)));
[email protected]7dfa6862013-01-31 01:29:095377
[email protected]aa043632013-03-25 03:39:425378 // After scrolling the parent, another scroll on the opposite direction
5379 // should still scroll the child.
5380 scroll_delta = gfx::Vector2d(0, 7);
tdresser81e84c672016-01-18 23:21:225381 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185382 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225383 InputHandler::NON_BUBBLING_GESTURE)
5384 .thread);
[email protected]aa043632013-03-25 03:39:425385 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:185386 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]aa043632013-03-25 03:39:425387 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:185388 host_impl_->ScrollEnd(EndState().get());
[email protected]7dfa6862013-01-31 01:29:095389
[email protected]aa043632013-03-25 03:39:425390 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:095391
[email protected]aa043632013-03-25 03:39:425392 // The grand child should have scrolled.
tdresser99977952015-07-02 19:49:185393 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5394 gfx::Vector2d(0, 5)));
[email protected]7dfa6862013-01-31 01:29:095395
[email protected]aa043632013-03-25 03:39:425396 // The child should not have scrolled.
tdresser99977952015-07-02 19:49:185397 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
5398 gfx::Vector2d(0, -3)));
[email protected]f4937272013-02-07 05:54:505399
[email protected]aa043632013-03-25 03:39:425400 // Scrolling should be adjusted from viewport space.
aelias58eec0812014-12-04 01:04:405401 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f);
danakj5ad246cd2015-09-12 01:04:505402 host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
[email protected]f4937272013-02-07 05:54:505403
[email protected]aa043632013-03-25 03:39:425404 scroll_delta = gfx::Vector2d(0, -2);
tdresser81e84c672016-01-18 23:21:225405 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185406 host_impl_->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
tdresser81e84c672016-01-18 23:21:225407 InputHandler::NON_BUBBLING_GESTURE)
5408 .thread);
[email protected]aa043632013-03-25 03:39:425409 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer());
majidvp944a8cd2016-01-12 21:05:185410 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5411 host_impl_->ScrollEnd(EndState().get());
[email protected]f4937272013-02-07 05:54:505412
[email protected]aa043632013-03-25 03:39:425413 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]f4937272013-02-07 05:54:505414
[email protected]aa043632013-03-25 03:39:425415 // Should have scrolled by half the amount in layer space (5 - 2/2)
tdresser99977952015-07-02 19:49:185416 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5417 gfx::Vector2d(0, 4)));
[email protected]aa043632013-03-25 03:39:425418 }
[email protected]7dfa6862013-01-31 01:29:095419}
[email protected]aa043632013-03-25 03:39:425420TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
5421 // When we try to scroll a non-scrollable child layer, the scroll delta
5422 // should be applied to one of its ancestors if possible.
5423 gfx::Size surface_size(10, 10);
5424 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:485425 std::unique_ptr<LayerImpl> root_ptr =
sunxd676696572016-01-07 16:28:305426 LayerImpl::Create(host_impl_->active_tree(), 4);
danakj60bc3bc2016-04-09 00:24:485427 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:475428 LayerImpl::Create(host_impl_->active_tree(), 3);
jaydasika6b5a32bf2016-04-22 21:56:365429 root_clip->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:485430 std::unique_ptr<LayerImpl> root_scroll =
[email protected]adeda572014-01-31 00:49:475431 CreateScrollableLayer(1, content_size, root_clip.get());
5432 // Make 'root' the clip layer for child: since they have the same sizes the
5433 // child will have zero max_scroll_offset and scrolls will bubble.
danakj60bc3bc2016-04-09 00:24:485434 std::unique_ptr<LayerImpl> child =
sunxd676696572016-01-07 16:28:305435 CreateScrollableLayer(2, content_size, root_scroll.get());
jaydasikaca2605e2016-04-23 02:52:525436 child->test_properties()->is_container_for_fixed_position_layers = true;
sunxd676696572016-01-07 16:28:305437 root_scroll->SetBounds(content_size);
[email protected]94f206c12012-08-25 00:09:145438
sunxd676696572016-01-07 16:28:305439 int root_scroll_id = root_scroll->id();
jaydasika89f7b5a2016-06-22 02:08:395440 root_scroll->test_properties()->AddChild(std::move(child));
5441 root_clip->test_properties()->AddChild(std::move(root_scroll));
5442 root_ptr->test_properties()->AddChild(std::move(root_clip));
[email protected]94f206c12012-08-25 00:09:145443
jaydasikabf1875a2016-06-28 03:39:595444 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
sunxd676696572016-01-07 16:28:305445 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 2,
ccameron8230b68b2014-11-21 19:25:185446 Layer::INVALID_ID);
danakj74af409e2016-07-01 00:41:485447 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425448 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:485449
5450 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365451 DrawFrame();
[email protected]aa043632013-03-25 03:39:425452 {
5453 gfx::Vector2d scroll_delta(0, 4);
tdresser81e84c672016-01-18 23:21:225454 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185455 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225456 InputHandler::WHEEL)
5457 .thread);
majidvp944a8cd2016-01-12 21:05:185458 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5459 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145460
danakj60bc3bc2016-04-09 00:24:485461 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425462 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:145463
[email protected]adeda572014-01-31 00:49:475464 // Only the root scroll should have scrolled.
[email protected]aa043632013-03-25 03:39:425465 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
tdresser99977952015-07-02 19:49:185466 EXPECT_TRUE(
5467 ScrollInfoContains(*scroll_info.get(), root_scroll_id, scroll_delta));
[email protected]aa043632013-03-25 03:39:425468 }
[email protected]94f206c12012-08-25 00:09:145469}
5470
[email protected]aa043632013-03-25 03:39:425471TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
5472 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:485473 std::unique_ptr<LayerImpl> root_ptr =
[email protected]adeda572014-01-31 00:49:475474 LayerImpl::Create(host_impl_->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:485475 std::unique_ptr<LayerImpl> root_clip =
sunxd676696572016-01-07 16:28:305476 LayerImpl::Create(host_impl_->active_tree(), 2);
danakj60bc3bc2016-04-09 00:24:485477 std::unique_ptr<LayerImpl> root_scroll =
sunxd676696572016-01-07 16:28:305478 CreateScrollableLayer(3, surface_size, root_clip.get());
jaydasika6b5a32bf2016-04-22 21:56:365479 root_clip->test_properties()->force_render_surface = true;
jaydasikaca2605e2016-04-23 02:52:525480 root_scroll->test_properties()->is_container_for_fixed_position_layers = true;
jaydasika89f7b5a2016-06-22 02:08:395481 root_clip->test_properties()->AddChild(std::move(root_scroll));
5482 root_ptr->test_properties()->AddChild(std::move(root_clip));
jaydasikabf1875a2016-06-28 03:39:595483 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
sunxd676696572016-01-07 16:28:305484 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3,
ccameron8230b68b2014-11-21 19:25:185485 Layer::INVALID_ID);
danakj74af409e2016-07-01 00:41:485486 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425487 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:485488
[email protected]18ce59702013-04-09 04:58:405489 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:145490
[email protected]aa043632013-03-25 03:39:425491 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
5492 // synchronization.
[email protected]ce2e8112013-11-28 07:44:365493 DrawFrame();
danakj74af409e2016-07-01 00:41:485494
rockot2176f922016-06-08 19:18:325495 host_impl_->active_tree()->DetachLayers();
danakj60bc3bc2016-04-09 00:24:485496 std::unique_ptr<LayerImpl> root_ptr2 =
sunxd676696572016-01-07 16:28:305497 LayerImpl::Create(host_impl_->active_tree(), 4);
danakj60bc3bc2016-04-09 00:24:485498 std::unique_ptr<LayerImpl> root_clip2 =
sunxd676696572016-01-07 16:28:305499 LayerImpl::Create(host_impl_->active_tree(), 5);
danakj60bc3bc2016-04-09 00:24:485500 std::unique_ptr<LayerImpl> root_scroll2 =
sunxd676696572016-01-07 16:28:305501 CreateScrollableLayer(6, surface_size, root_clip2.get());
jaydasikaca2605e2016-04-23 02:52:525502 root_scroll2->test_properties()->is_container_for_fixed_position_layers =
5503 true;
jaydasika89f7b5a2016-06-22 02:08:395504 root_clip2->test_properties()->AddChild(std::move(root_scroll2));
jaydasika6b5a32bf2016-04-22 21:56:365505 root_clip2->test_properties()->force_render_surface = true;
jaydasika89f7b5a2016-06-22 02:08:395506 root_ptr2->test_properties()->AddChild(std::move(root_clip2));
jaydasikabf1875a2016-06-28 03:39:595507 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr2));
danakj74af409e2016-07-01 00:41:485508 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd676696572016-01-07 16:28:305509 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 6,
ccameron8230b68b2014-11-21 19:25:185510 Layer::INVALID_ID);
[email protected]aa043632013-03-25 03:39:425511 host_impl_->active_tree()->DidBecomeActive();
[email protected]94f206c12012-08-25 00:09:145512
[email protected]aa043632013-03-25 03:39:425513 // Scrolling should still work even though we did not draw yet.
tdresser81e84c672016-01-18 23:21:225514 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185515 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225516 InputHandler::WHEEL)
5517 .thread);
[email protected]94f206c12012-08-25 00:09:145518}
5519
[email protected]aa043632013-03-25 03:39:425520TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:295521 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
jaydasikad7dea632015-11-06 04:40:125522 scroll_layer->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:145523
[email protected]aa043632013-03-25 03:39:425524 // Rotate the root layer 90 degrees counter-clockwise about its center.
5525 gfx::Transform rotate_transform;
5526 rotate_transform.Rotate(-90.0);
jaydasika10d43fc2016-08-18 04:06:045527 host_impl_->active_tree()
5528 ->root_layer_for_testing()
5529 ->test_properties()
5530 ->transform = rotate_transform;
danakj74af409e2016-07-01 00:41:485531 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145532
[email protected]aa043632013-03-25 03:39:425533 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:405534 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365535 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145536
[email protected]aa043632013-03-25 03:39:425537 // Scroll to the right in screen coordinates with a gesture.
5538 gfx::Vector2d gesture_scroll_delta(10, 0);
tdresser81e84c672016-01-18 23:21:225539 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035540 host_impl_
5541 ->ScrollBegin(BeginState(gfx::Point()).get(),
5542 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225543 .thread);
majidvp944a8cd2016-01-12 21:05:185544 host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
5545 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145546
[email protected]aa043632013-03-25 03:39:425547 // The layer should have scrolled down in its local coordinates.
danakj60bc3bc2016-04-09 00:24:485548 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5549 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185550 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5551 gfx::Vector2d(0, gesture_scroll_delta.x())));
[email protected]94f206c12012-08-25 00:09:145552
[email protected]aa043632013-03-25 03:39:425553 // Reset and scroll down with the wheel.
sunxdb7e79432016-03-09 21:13:425554 SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:425555 gfx::Vector2d wheel_scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225556 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185557 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225558 InputHandler::WHEEL)
5559 .thread);
majidvp944a8cd2016-01-12 21:05:185560 host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get());
5561 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145562
[email protected]aa043632013-03-25 03:39:425563 // The layer should have scrolled down in its local coordinates.
5564 scroll_info = host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185565 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5566 wheel_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145567}
5568
[email protected]aa043632013-03-25 03:39:425569TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:295570 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]adeda572014-01-31 00:49:475571 int child_clip_layer_id = 6;
5572 int child_layer_id = 7;
[email protected]aa043632013-03-25 03:39:425573 float child_layer_angle = -20.f;
[email protected]94f206c12012-08-25 00:09:145574
[email protected]aa043632013-03-25 03:39:425575 // Create a child layer that is rotated to a non-axis-aligned angle.
danakj60bc3bc2016-04-09 00:24:485576 std::unique_ptr<LayerImpl> clip_layer =
[email protected]adeda572014-01-31 00:49:475577 LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
danakj60bc3bc2016-04-09 00:24:485578 std::unique_ptr<LayerImpl> child = CreateScrollableLayer(
Dana Jansensc46d3742015-06-18 01:33:145579 child_layer_id, scroll_layer->bounds(), clip_layer.get());
[email protected]aa043632013-03-25 03:39:425580 gfx::Transform rotate_transform;
5581 rotate_transform.Translate(-50.0, -50.0);
5582 rotate_transform.Rotate(child_layer_angle);
5583 rotate_transform.Translate(50.0, 50.0);
jaydasika10d43fc2016-08-18 04:06:045584 clip_layer->test_properties()->transform = rotate_transform;
[email protected]94f206c12012-08-25 00:09:145585
[email protected]aa043632013-03-25 03:39:425586 // Only allow vertical scrolling.
[email protected]adeda572014-01-31 00:49:475587 clip_layer->SetBounds(
5588 gfx::Size(child->bounds().width(), child->bounds().height() / 2));
[email protected]a2566412014-06-05 03:14:205589 // The rotation depends on the layer's transform origin, and the child layer
5590 // is a different size than the clip, so make sure the clip layer's origin
5591 // lines up over the child.
jaydasika38be7a822016-04-21 16:07:065592 clip_layer->test_properties()->transform_origin = gfx::Point3F(
5593 clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f);
[email protected]adeda572014-01-31 00:49:475594 LayerImpl* child_ptr = child.get();
jaydasika89f7b5a2016-06-22 02:08:395595 clip_layer->test_properties()->AddChild(std::move(child));
5596 scroll_layer->test_properties()->AddChild(std::move(clip_layer));
danakj74af409e2016-07-01 00:41:485597 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145598
[email protected]aa043632013-03-25 03:39:425599 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:405600 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365601 DrawFrame();
[email protected]aa043632013-03-25 03:39:425602 {
[email protected]94f206c12012-08-25 00:09:145603 // Scroll down in screen coordinates with a gesture.
[email protected]aa043632013-03-25 03:39:425604 gfx::Vector2d gesture_scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225605 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035606 host_impl_
5607 ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
5608 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225609 .thread);
majidvp944a8cd2016-01-12 21:05:185610 host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
5611 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145612
[email protected]aa043632013-03-25 03:39:425613 // The child layer should have scrolled down in its local coordinates an
5614 // amount proportional to the angle between it and the input scroll delta.
miletusd799dd22015-03-19 04:23:175615 gfx::Vector2d expected_scroll_delta(
miletus7a221752015-02-04 20:44:495616 0, gesture_scroll_delta.y() *
5617 std::cos(MathUtil::Deg2Rad(child_layer_angle)));
danakj60bc3bc2016-04-09 00:24:485618 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425619 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185620 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
5621 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145622
[email protected]35a99a12013-05-09 23:52:295623 // The root scroll layer should not have scrolled, because the input delta
5624 // was close to the layer's axis of movement.
[email protected]aa043632013-03-25 03:39:425625 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
5626 }
5627 {
5628 // Now reset and scroll the same amount horizontally.
sunxdb7e79432016-03-09 21:13:425629 SetScrollOffsetDelta(child_ptr, gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:425630 gfx::Vector2d gesture_scroll_delta(10, 0);
tdresser81e84c672016-01-18 23:21:225631 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035632 host_impl_
5633 ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
5634 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225635 .thread);
majidvp944a8cd2016-01-12 21:05:185636 host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
5637 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145638
tdressera3b162b82015-09-29 17:51:435639 // The child layer shouldn't have scrolled.
miletusd799dd22015-03-19 04:23:175640 gfx::Vector2d expected_scroll_delta(
miletus7a221752015-02-04 20:44:495641 0, -gesture_scroll_delta.x() *
5642 std::sin(MathUtil::Deg2Rad(child_layer_angle)));
danakj60bc3bc2016-04-09 00:24:485643 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425644 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185645 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
5646 expected_scroll_delta));
[email protected]aa043632013-03-25 03:39:425647
tdressera3b162b82015-09-29 17:51:435648 // The root scroll layer shouldn't have scrolled.
5649 ExpectNone(*scroll_info.get(), scroll_layer->id());
[email protected]aa043632013-03-25 03:39:425650 }
5651}
5652
tdressere8575f592015-07-03 12:53:135653TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
5654 // When scrolling an element with perspective, the distance scrolled
5655 // depends on the point at which the scroll begins.
5656 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
5657 int child_clip_layer_id = 6;
5658 int child_layer_id = 7;
5659
5660 // Create a child layer that is rotated on its x axis, with perspective.
danakj60bc3bc2016-04-09 00:24:485661 std::unique_ptr<LayerImpl> clip_layer =
tdressere8575f592015-07-03 12:53:135662 LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
danakj60bc3bc2016-04-09 00:24:485663 std::unique_ptr<LayerImpl> child = CreateScrollableLayer(
tdressere8575f592015-07-03 12:53:135664 child_layer_id, scroll_layer->bounds(), clip_layer.get());
5665 LayerImpl* child_ptr = child.get();
5666 gfx::Transform perspective_transform;
5667 perspective_transform.Translate(-50.0, -50.0);
5668 perspective_transform.ApplyPerspectiveDepth(20);
5669 perspective_transform.RotateAboutXAxis(45);
5670 perspective_transform.Translate(50.0, 50.0);
jaydasika10d43fc2016-08-18 04:06:045671 clip_layer->test_properties()->transform = perspective_transform;
tdressere8575f592015-07-03 12:53:135672
5673 clip_layer->SetBounds(gfx::Size(child_ptr->bounds().width() / 2,
5674 child_ptr->bounds().height() / 2));
5675 // The transform depends on the layer's transform origin, and the child layer
5676 // is a different size than the clip, so make sure the clip layer's origin
5677 // lines up over the child.
jaydasika38be7a822016-04-21 16:07:065678 clip_layer->test_properties()->transform_origin = gfx::Point3F(
5679 clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f);
jaydasika89f7b5a2016-06-22 02:08:395680 clip_layer->test_properties()->AddChild(std::move(child));
5681 scroll_layer->test_properties()->AddChild(std::move(clip_layer));
danakj74af409e2016-07-01 00:41:485682 host_impl_->active_tree()->BuildPropertyTreesForTesting();
tdressere8575f592015-07-03 12:53:135683
5684 gfx::Size surface_size(50, 50);
5685 host_impl_->SetViewportSize(surface_size);
5686
danakj60bc3bc2016-04-09 00:24:485687 std::unique_ptr<ScrollAndScaleSet> scroll_info;
tdressere8575f592015-07-03 12:53:135688
5689 gfx::Vector2d gesture_scroll_deltas[4];
5690 gesture_scroll_deltas[0] = gfx::Vector2d(4, 10);
5691 gesture_scroll_deltas[1] = gfx::Vector2d(4, 10);
5692 gesture_scroll_deltas[2] = gfx::Vector2d(10, 0);
5693 gesture_scroll_deltas[3] = gfx::Vector2d(10, 0);
5694
5695 gfx::Vector2d expected_scroll_deltas[4];
5696 // Perspective affects the vertical delta by a different
5697 // amount depending on the vertical position of the |viewport_point|.
5698 expected_scroll_deltas[0] = gfx::Vector2d(2, 8);
5699 expected_scroll_deltas[1] = gfx::Vector2d(1, 4);
5700 // Deltas which start with the same vertical position of the
5701 // |viewport_point| are subject to identical perspective effects.
5702 expected_scroll_deltas[2] = gfx::Vector2d(4, 0);
5703 expected_scroll_deltas[3] = gfx::Vector2d(4, 0);
5704
5705 gfx::Point viewport_point(1, 1);
5706
5707 // Scroll in screen coordinates with a gesture. Each scroll starts
5708 // where the previous scroll ended, but the scroll position is reset
5709 // for each scroll.
5710 for (int i = 0; i < 4; ++i) {
sunxdb7e79432016-03-09 21:13:425711 SetScrollOffsetDelta(child_ptr, gfx::Vector2dF());
tdressere8575f592015-07-03 12:53:135712 DrawFrame();
tdresser81e84c672016-01-18 23:21:225713 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035714 host_impl_
5715 ->ScrollBegin(BeginState(viewport_point).get(),
5716 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225717 .thread);
majidvp944a8cd2016-01-12 21:05:185718 host_impl_->ScrollBy(
5719 UpdateState(viewport_point, gesture_scroll_deltas[i]).get());
tdressere8575f592015-07-03 12:53:135720 viewport_point += gesture_scroll_deltas[i];
majidvp944a8cd2016-01-12 21:05:185721 host_impl_->ScrollEnd(EndState().get());
tdressere8575f592015-07-03 12:53:135722
5723 scroll_info = host_impl_->ProcessScrollDeltas();
5724 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
5725 expected_scroll_deltas[i]));
5726
5727 // The root scroll layer should not have scrolled, because the input delta
5728 // was close to the layer's axis of movement.
5729 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
5730 }
5731}
5732
[email protected]aa043632013-03-25 03:39:425733TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
[email protected]35a99a12013-05-09 23:52:295734 LayerImpl* scroll_layer =
5735 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:425736
5737 // Scale the layer to twice its normal size.
5738 int scale = 2;
5739 gfx::Transform scale_transform;
5740 scale_transform.Scale(scale, scale);
jaydasika10d43fc2016-08-18 04:06:045741 scroll_layer->test_properties()->parent->test_properties()->transform =
5742 scale_transform;
danakj74af409e2016-07-01 00:41:485743 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425744
5745 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:405746 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365747 DrawFrame();
[email protected]aa043632013-03-25 03:39:425748
5749 // Scroll down in screen coordinates with a gesture.
5750 gfx::Vector2d scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225751 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035752 host_impl_
5753 ->ScrollBegin(BeginState(gfx::Point()).get(),
5754 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225755 .thread);
majidvp944a8cd2016-01-12 21:05:185756 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5757 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:425758
5759 // The layer should have scrolled down in its local coordinates, but half the
5760 // amount.
danakj60bc3bc2016-04-09 00:24:485761 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5762 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185763 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5764 gfx::Vector2d(0, scroll_delta.y() / scale)));
[email protected]aa043632013-03-25 03:39:425765
5766 // Reset and scroll down with the wheel.
sunxdb7e79432016-03-09 21:13:425767 SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:425768 gfx::Vector2d wheel_scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225769 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185770 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225771 InputHandler::WHEEL)
5772 .thread);
majidvp944a8cd2016-01-12 21:05:185773 host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get());
5774 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:425775
lanweid17d0742014-12-01 18:58:525776 // It should apply the scale factor to the scroll delta for the wheel event.
[email protected]aa043632013-03-25 03:39:425777 scroll_info = host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185778 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5779 wheel_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145780}
5781
[email protected]a6d2ffe822014-08-21 10:11:395782TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
5783 int width = 332;
5784 int height = 20;
5785 int scale = 3;
5786 SetupScrollAndContentsLayers(gfx::Size(width, height));
[email protected]587941d2014-08-22 01:40:015787 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
5788 gfx::Size(width * scale - 1, height * scale));
danakj74af409e2016-07-01 00:41:485789 host_impl_->active_tree()->BuildPropertyTreesForTesting();
5790
ajuma1d48e012015-09-25 22:24:165791 host_impl_->active_tree()->SetDeviceScaleFactor(scale);
aelias58eec0812014-12-04 01:04:405792 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]a6d2ffe822014-08-21 10:11:395793
5794 LayerImpl* inner_viewport_scroll_layer =
5795 host_impl_->active_tree()->InnerViewportScrollLayer();
miletusf57925d2014-10-01 19:38:135796 EXPECT_EQ(gfx::ScrollOffset(0, 0),
[email protected]a6d2ffe822014-08-21 10:11:395797 inner_viewport_scroll_layer->MaxScrollOffset());
5798}
5799
danakjdd74e512015-09-21 23:07:595800class TestInputHandlerClient : public InputHandlerClient {
[email protected]0a0d1422013-05-02 09:14:525801 public:
danakjdd74e512015-09-21 23:07:595802 TestInputHandlerClient()
[email protected]68fe60f2014-02-12 13:49:115803 : page_scale_factor_(0.f),
5804 min_page_scale_factor_(-1.f),
danakje9f830c2015-09-09 21:36:165805 max_page_scale_factor_(-1.f) {}
danakjdd74e512015-09-21 23:07:595806 ~TestInputHandlerClient() override {}
[email protected]20d2b742013-09-26 05:41:345807
danakjdd74e512015-09-21 23:07:595808 // InputHandlerClient implementation.
5809 void WillShutdown() override {}
5810 void Animate(base::TimeTicks time) override {}
5811 void MainThreadHasStoppedFlinging() override {}
5812 void ReconcileElasticOverscrollAndRootScroll() override {}
5813 void UpdateRootLayerStateForSynchronousInputHandler(
5814 const gfx::ScrollOffset& total_scroll_offset,
5815 const gfx::ScrollOffset& max_scroll_offset,
5816 const gfx::SizeF& scrollable_size,
5817 float page_scale_factor,
5818 float min_page_scale_factor,
5819 float max_page_scale_factor) override {
[email protected]ec2322e2014-05-15 16:32:005820 DCHECK(total_scroll_offset.x() <= max_scroll_offset.x());
5821 DCHECK(total_scroll_offset.y() <= max_scroll_offset.y());
5822 last_set_scroll_offset_ = total_scroll_offset;
5823 max_scroll_offset_ = max_scroll_offset;
5824 scrollable_size_ = scrollable_size;
[email protected]20d2b742013-09-26 05:41:345825 page_scale_factor_ = page_scale_factor;
[email protected]68fe60f2014-02-12 13:49:115826 min_page_scale_factor_ = min_page_scale_factor;
5827 max_page_scale_factor_ = max_page_scale_factor;
[email protected]20d2b742013-09-26 05:41:345828 }
5829
miletusf57925d2014-10-01 19:38:135830 gfx::ScrollOffset last_set_scroll_offset() {
[email protected]0a0d1422013-05-02 09:14:525831 return last_set_scroll_offset_;
5832 }
5833
miletusf57925d2014-10-01 19:38:135834 gfx::ScrollOffset max_scroll_offset() const {
[email protected]20d2b742013-09-26 05:41:345835 return max_scroll_offset_;
5836 }
5837
5838 gfx::SizeF scrollable_size() const {
5839 return scrollable_size_;
5840 }
5841
5842 float page_scale_factor() const {
5843 return page_scale_factor_;
5844 }
5845
[email protected]68fe60f2014-02-12 13:49:115846 float min_page_scale_factor() const {
5847 return min_page_scale_factor_;
5848 }
5849
5850 float max_page_scale_factor() const {
5851 return max_page_scale_factor_;
5852 }
5853
[email protected]0a0d1422013-05-02 09:14:525854 private:
miletusf57925d2014-10-01 19:38:135855 gfx::ScrollOffset last_set_scroll_offset_;
miletusf57925d2014-10-01 19:38:135856 gfx::ScrollOffset max_scroll_offset_;
[email protected]20d2b742013-09-26 05:41:345857 gfx::SizeF scrollable_size_;
5858 float page_scale_factor_;
[email protected]68fe60f2014-02-12 13:49:115859 float min_page_scale_factor_;
5860 float max_page_scale_factor_;
[email protected]0a0d1422013-05-02 09:14:525861};
5862
5863TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
danakjdd74e512015-09-21 23:07:595864 TestInputHandlerClient scroll_watcher;
[email protected]20d2b742013-09-26 05:41:345865 host_impl_->SetViewportSize(gfx::Size(10, 20));
[email protected]35a99a12013-05-09 23:52:295866 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
jaydasikaf419bf72016-06-15 10:21:215867 LayerImpl* clip_layer =
5868 scroll_layer->test_properties()->parent->test_properties()->parent;
[email protected]adeda572014-01-31 00:49:475869 clip_layer->SetBounds(gfx::Size(10, 20));
danakj74af409e2016-07-01 00:41:485870 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]0a0d1422013-05-02 09:14:525871
danakjdd74e512015-09-21 23:07:595872 host_impl_->BindToClient(&scroll_watcher);
5873
[email protected]35a99a12013-05-09 23:52:295874 gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
sunxdb7e79432016-03-09 21:13:425875 scroll_layer->layer_tree_impl()
5876 ->property_trees()
5877 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
5878 gfx::ScrollOffset());
5879 SetScrollOffsetDelta(scroll_layer, initial_scroll_delta);
danakjdd74e512015-09-21 23:07:595880
5881 EXPECT_EQ(gfx::ScrollOffset(), scroll_watcher.last_set_scroll_offset());
5882
5883 // Requesting an update results in the current scroll offset being set.
5884 host_impl_->RequestUpdateForSynchronousInputHandler();
5885 EXPECT_EQ(gfx::ScrollOffset(initial_scroll_delta),
5886 scroll_watcher.last_set_scroll_offset());
[email protected]0a0d1422013-05-02 09:14:525887
[email protected]68fe60f2014-02-12 13:49:115888 // Setting the delegate results in the scrollable_size, max_scroll_offset,
5889 // page_scale_factor and {min|max}_page_scale_factor being set.
danakjdd74e512015-09-21 23:07:595890 EXPECT_EQ(gfx::SizeF(100, 100), scroll_watcher.scrollable_size());
5891 EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_watcher.max_scroll_offset());
5892 EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
5893 EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
5894 EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
[email protected]20d2b742013-09-26 05:41:345895
danakja342d6f3b2015-09-17 22:25:485896 // Put a page scale on the tree.
aelias58eec0812014-12-04 01:04:405897 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 0.5f, 4.f);
danakjdd74e512015-09-21 23:07:595898 EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
5899 EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
5900 EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
danakja342d6f3b2015-09-17 22:25:485901 // Activation will update the delegate.
5902 host_impl_->ActivateSyncTree();
danakjdd74e512015-09-21 23:07:595903 EXPECT_EQ(2.f, scroll_watcher.page_scale_factor());
5904 EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
5905 EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
danakja342d6f3b2015-09-17 22:25:485906
danakja342d6f3b2015-09-17 22:25:485907 // Animating page scale can change the root offset, so it should update the
danakj4923440542015-10-29 19:34:535908 // delegate. Also resets the page scale to 1 for the rest of the test.
5909 host_impl_->LayerTreeHostImpl::StartPageScaleAnimation(
5910 gfx::Vector2d(0, 0), false, 1.f, base::TimeDelta());
danakja342d6f3b2015-09-17 22:25:485911 host_impl_->Animate();
danakjdd74e512015-09-21 23:07:595912 EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
5913 EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
5914 EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
[email protected]20d2b742013-09-26 05:41:345915
[email protected]ec2322e2014-05-15 16:32:005916 // The pinch gesture doesn't put the delegate into a state where the scroll
5917 // offset is outside of the scroll range. (this is verified by DCHECKs in the
5918 // delegate).
majidvp944a8cd2016-01-12 21:05:185919 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:035920 InputHandler::TOUCHSCREEN);
[email protected]ec2322e2014-05-15 16:32:005921 host_impl_->PinchGestureBegin();
5922 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
5923 host_impl_->PinchGestureUpdate(.5f, gfx::Point());
5924 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:185925 host_impl_->ScrollEnd(EndState().get());
[email protected]ec2322e2014-05-15 16:32:005926
danakj0481b572015-09-10 01:18:015927 // Scrolling should be relative to the offset as given by the delegate.
[email protected]35a99a12013-05-09 23:52:295928 gfx::Vector2dF scroll_delta(0.f, 10.f);
miletusf57925d2014-10-01 19:38:135929 gfx::ScrollOffset current_offset(7.f, 8.f);
[email protected]0a0d1422013-05-02 09:14:525930
tdresser81e84c672016-01-18 23:21:225931 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035932 host_impl_
5933 ->ScrollBegin(BeginState(gfx::Point()).get(),
5934 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225935 .thread);
danakjdd74e512015-09-21 23:07:595936 host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
[email protected]0a0d1422013-05-02 09:14:525937
majidvp944a8cd2016-01-12 21:05:185938 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
miletusf57925d2014-10-01 19:38:135939 EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta),
danakjdd74e512015-09-21 23:07:595940 scroll_watcher.last_set_scroll_offset());
[email protected]0a0d1422013-05-02 09:14:525941
miletusf57925d2014-10-01 19:38:135942 current_offset = gfx::ScrollOffset(42.f, 41.f);
danakjdd74e512015-09-21 23:07:595943 host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
majidvp944a8cd2016-01-12 21:05:185944 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
miletusf57925d2014-10-01 19:38:135945 EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta),
danakjdd74e512015-09-21 23:07:595946 scroll_watcher.last_set_scroll_offset());
majidvp944a8cd2016-01-12 21:05:185947 host_impl_->ScrollEnd(EndState().get());
danakjdd74e512015-09-21 23:07:595948 host_impl_->SetSynchronousInputHandlerRootScrollOffset(gfx::ScrollOffset());
[email protected]0a0d1422013-05-02 09:14:525949
[email protected]7d1b07e2013-10-01 17:31:305950 // Forces a full tree synchronization and ensures that the scroll delegate
5951 // sees the correct size of the new tree.
5952 gfx::Size new_size(42, 24);
5953 host_impl_->CreatePendingTree();
bokan0c33a092015-07-29 18:27:565954 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
[email protected]7d1b07e2013-10-01 17:31:305955 CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size);
danakj74af409e2016-07-01 00:41:485956 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
[email protected]fc20d142014-07-01 00:49:155957 host_impl_->ActivateSyncTree();
danakjddaec912015-09-25 19:38:405958 EXPECT_EQ(gfx::SizeF(new_size), scroll_watcher.scrollable_size());
[email protected]7d1b07e2013-10-01 17:31:305959
danakjdd74e512015-09-21 23:07:595960 // Tear down the LayerTreeHostImpl before the InputHandlerClient.
danakjee6547a22016-07-01 20:41:505961 host_impl_->ReleaseOutputSurface();
5962 host_impl_ = nullptr;
[email protected]0a0d1422013-05-02 09:14:525963}
5964
[email protected]b4a3d462014-06-17 09:17:085965void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) {
5966 const gfx::Transform target_space_transform =
5967 layer->draw_properties().target_space_transform;
5968 EXPECT_TRUE(target_space_transform.IsScaleOrTranslation());
5969 gfx::Point translated_point;
5970 target_space_transform.TransformPoint(&translated_point);
5971 gfx::Point expected_point = gfx::Point() - ToRoundedVector2d(scroll_delta);
5972 EXPECT_EQ(expected_point.ToString(), translated_point.ToString());
5973}
5974
5975TEST_F(LayerTreeHostImplTest,
5976 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) {
[email protected]b4a3d462014-06-17 09:17:085977 host_impl_->SetViewportSize(gfx::Size(10, 20));
5978 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
jaydasikaf419bf72016-06-15 10:21:215979 LayerImpl* clip_layer =
5980 scroll_layer->test_properties()->parent->test_properties()->parent;
[email protected]b4a3d462014-06-17 09:17:085981 clip_layer->SetBounds(gfx::Size(10, 20));
jaydasikad7dea632015-11-06 04:40:125982 scroll_layer->SetDrawsContent(true);
[email protected]b4a3d462014-06-17 09:17:085983
5984 // Draw first frame to clear any pending draws and check scroll.
5985 DrawFrame();
5986 CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f));
5987 EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
5988
5989 // Set external scroll delta on delegate and notify LayerTreeHost.
miletusf57925d2014-10-01 19:38:135990 gfx::ScrollOffset scroll_offset(10.f, 10.f);
danakjdd74e512015-09-21 23:07:595991 host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
danakj74af409e2016-07-01 00:41:485992 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]b4a3d462014-06-17 09:17:085993
5994 // Check scroll delta reflected in layer.
boliu7d5dbab2014-10-10 20:05:475995 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:485996 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:455997 host_impl_->DrawLayers(&frame);
boliu7d5dbab2014-10-10 20:05:475998 host_impl_->DidDrawAllLayers(frame);
5999 EXPECT_FALSE(frame.has_no_damage);
miletusf57925d2014-10-01 19:38:136000 CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset));
[email protected]b4a3d462014-06-17 09:17:086001}
6002
[email protected]a2b5ded2013-05-20 21:32:536003TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
ccameron36d091f2014-11-07 03:18:506004 InputHandlerScrollResult scroll_result;
[email protected]a2b5ded2013-05-20 21:32:536005 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:486006 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6007
[email protected]a2b5ded2013-05-20 21:32:536008 host_impl_->SetViewportSize(gfx::Size(50, 50));
aelias58eec0812014-12-04 01:04:406009 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:366010 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:536011 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536012
6013 // In-bounds scrolling does not affect overscroll.
tdresser81e84c672016-01-18 23:21:226014 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186015 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:226016 InputHandler::WHEEL)
6017 .thread);
majidvp944a8cd2016-01-12 21:05:186018 scroll_result = host_impl_->ScrollBy(
6019 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
ccameron36d091f2014-11-07 03:18:506020 EXPECT_TRUE(scroll_result.did_scroll);
6021 EXPECT_FALSE(scroll_result.did_overscroll_root);
6022 EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536023 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536024
6025 // Overscroll events are reflected immediately.
majidvp944a8cd2016-01-12 21:05:186026 scroll_result = host_impl_->ScrollBy(
6027 UpdateState(gfx::Point(), gfx::Vector2d(0, 50)).get());
ccameron36d091f2014-11-07 03:18:506028 EXPECT_TRUE(scroll_result.did_scroll);
6029 EXPECT_TRUE(scroll_result.did_overscroll_root);
6030 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536031 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506032 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6033 host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536034
[email protected]2bd503f2013-07-23 05:35:296035 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
majidvp944a8cd2016-01-12 21:05:186036 scroll_result = host_impl_->ScrollBy(
6037 UpdateState(gfx::Point(), gfx::Vector2d(0, -50)).get());
ccameron36d091f2014-11-07 03:18:506038 EXPECT_TRUE(scroll_result.did_scroll);
6039 EXPECT_FALSE(scroll_result.did_overscroll_root);
6040 EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536041 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506042 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6043 host_impl_->accumulated_root_overscroll());
6044
majidvp944a8cd2016-01-12 21:05:186045 scroll_result = host_impl_->ScrollBy(
6046 UpdateState(gfx::Point(), gfx::Vector2d(0, -10)).get());
ccameron36d091f2014-11-07 03:18:506047 EXPECT_FALSE(scroll_result.did_scroll);
6048 EXPECT_TRUE(scroll_result.did_overscroll_root);
6049 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536050 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506051 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6052 host_impl_->accumulated_root_overscroll());
6053
majidvp944a8cd2016-01-12 21:05:186054 scroll_result = host_impl_->ScrollBy(
6055 UpdateState(gfx::Point(), gfx::Vector2d(10, 0)).get());
ccameron36d091f2014-11-07 03:18:506056 EXPECT_TRUE(scroll_result.did_scroll);
6057 EXPECT_FALSE(scroll_result.did_overscroll_root);
6058 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296059 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506060 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6061 host_impl_->accumulated_root_overscroll());
6062
majidvp944a8cd2016-01-12 21:05:186063 scroll_result = host_impl_->ScrollBy(
6064 UpdateState(gfx::Point(), gfx::Vector2d(-15, 0)).get());
ccameron36d091f2014-11-07 03:18:506065 EXPECT_TRUE(scroll_result.did_scroll);
6066 EXPECT_TRUE(scroll_result.did_overscroll_root);
6067 EXPECT_EQ(gfx::Vector2dF(-5, 0), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296068 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506069 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6070 host_impl_->accumulated_root_overscroll());
6071
majidvp944a8cd2016-01-12 21:05:186072 scroll_result = host_impl_->ScrollBy(
6073 UpdateState(gfx::Point(), gfx::Vector2d(0, 60)).get());
ccameron36d091f2014-11-07 03:18:506074 EXPECT_TRUE(scroll_result.did_scroll);
6075 EXPECT_TRUE(scroll_result.did_overscroll_root);
6076 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296077 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506078 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6079 host_impl_->accumulated_root_overscroll());
6080
majidvp944a8cd2016-01-12 21:05:186081 scroll_result = host_impl_->ScrollBy(
6082 UpdateState(gfx::Point(), gfx::Vector2d(10, -60)).get());
ccameron36d091f2014-11-07 03:18:506083 EXPECT_TRUE(scroll_result.did_scroll);
6084 EXPECT_TRUE(scroll_result.did_overscroll_root);
6085 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296086 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506087 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6088 host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536089
6090 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
6091 // as no scroll occurs.
majidvp944a8cd2016-01-12 21:05:186092 scroll_result = host_impl_->ScrollBy(
6093 UpdateState(gfx::Point(), gfx::Vector2d(0, -20)).get());
ccameron36d091f2014-11-07 03:18:506094 EXPECT_FALSE(scroll_result.did_scroll);
6095 EXPECT_TRUE(scroll_result.did_overscroll_root);
6096 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536097 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506098 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6099 host_impl_->accumulated_root_overscroll());
6100
majidvp944a8cd2016-01-12 21:05:186101 scroll_result = host_impl_->ScrollBy(
6102 UpdateState(gfx::Point(), gfx::Vector2d(0, -20)).get());
ccameron36d091f2014-11-07 03:18:506103 EXPECT_FALSE(scroll_result.did_scroll);
6104 EXPECT_TRUE(scroll_result.did_overscroll_root);
6105 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536106 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506107 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6108 host_impl_->accumulated_root_overscroll());
6109
[email protected]a2b5ded2013-05-20 21:32:536110 // Overscroll resets on valid scroll.
majidvp944a8cd2016-01-12 21:05:186111 scroll_result = host_impl_->ScrollBy(
6112 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
ccameron36d091f2014-11-07 03:18:506113 EXPECT_TRUE(scroll_result.did_scroll);
6114 EXPECT_FALSE(scroll_result.did_overscroll_root);
6115 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536116 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506117 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6118 host_impl_->accumulated_root_overscroll());
6119
majidvp944a8cd2016-01-12 21:05:186120 scroll_result = host_impl_->ScrollBy(
6121 UpdateState(gfx::Point(), gfx::Vector2d(0, -20)).get());
ccameron36d091f2014-11-07 03:18:506122 EXPECT_TRUE(scroll_result.did_scroll);
6123 EXPECT_TRUE(scroll_result.did_overscroll_root);
6124 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536125 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506126 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6127 host_impl_->accumulated_root_overscroll());
6128
majidvp944a8cd2016-01-12 21:05:186129 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536130}
6131
6132
6133TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
6134 // Scroll child layers beyond their maximum scroll range and make sure root
6135 // overscroll does not accumulate.
tdresserdeeba3f2015-07-10 19:26:586136 InputHandlerScrollResult scroll_result;
[email protected]a2b5ded2013-05-20 21:32:536137 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:486138 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:476139 LayerImpl::Create(host_impl_->active_tree(), 4);
jaydasika6b5a32bf2016-04-22 21:56:366140 root_clip->test_properties()->force_render_surface = true;
awoloszyne83f28c2014-12-22 15:40:006141
danakj60bc3bc2016-04-09 00:24:486142 std::unique_ptr<LayerImpl> root =
[email protected]adeda572014-01-31 00:49:476143 CreateScrollableLayer(1, surface_size, root_clip.get());
[email protected]a2b5ded2013-05-20 21:32:536144
danakj60bc3bc2016-04-09 00:24:486145 std::unique_ptr<LayerImpl> grand_child =
[email protected]adeda572014-01-31 00:49:476146 CreateScrollableLayer(3, surface_size, root_clip.get());
[email protected]a2b5ded2013-05-20 21:32:536147
danakj60bc3bc2016-04-09 00:24:486148 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:476149 CreateScrollableLayer(2, surface_size, root_clip.get());
6150 LayerImpl* grand_child_layer = grand_child.get();
jaydasika89f7b5a2016-06-22 02:08:396151 child->test_properties()->AddChild(std::move(grand_child));
[email protected]a2b5ded2013-05-20 21:32:536152
[email protected]adeda572014-01-31 00:49:476153 LayerImpl* child_layer = child.get();
jaydasika89f7b5a2016-06-22 02:08:396154 root->test_properties()->AddChild(std::move(child));
6155 root_clip->test_properties()->AddChild(std::move(root));
danakj74af409e2016-07-01 00:41:486156 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip));
6157 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6158 host_impl_->active_tree()->DidBecomeActive();
6159
sunxdb7e79432016-03-09 21:13:426160 child_layer->layer_tree_impl()
6161 ->property_trees()
6162 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
6163 gfx::ScrollOffset(0, 3));
6164 grand_child_layer->layer_tree_impl()
6165 ->property_trees()
6166 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
6167 gfx::ScrollOffset(0, 2));
danakj74af409e2016-07-01 00:41:486168
[email protected]a2b5ded2013-05-20 21:32:536169 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:366170 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:536171 {
6172 gfx::Vector2d scroll_delta(0, -10);
tdresser81e84c672016-01-18 23:21:226173 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186174 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:226175 InputHandler::NON_BUBBLING_GESTURE)
6176 .thread);
majidvp944a8cd2016-01-12 21:05:186177 scroll_result =
6178 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586179 EXPECT_TRUE(scroll_result.did_scroll);
6180 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536181 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186182 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536183
[email protected]a2b5ded2013-05-20 21:32:536184 // The next time we scroll we should only scroll the parent, but overscroll
6185 // should still not reach the root layer.
6186 scroll_delta = gfx::Vector2d(0, -30);
tdresser81e84c672016-01-18 23:21:226187 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186188 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:226189 InputHandler::NON_BUBBLING_GESTURE)
6190 .thread);
[email protected]adeda572014-01-31 00:49:476191 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
[email protected]a2b5ded2013-05-20 21:32:536192 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186193 scroll_result =
6194 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586195 EXPECT_TRUE(scroll_result.did_scroll);
6196 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]adeda572014-01-31 00:49:476197 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_layer);
[email protected]a2b5ded2013-05-20 21:32:536198 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186199 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536200
6201 // After scrolling the parent, another scroll on the opposite direction
[email protected]635b0e92014-04-02 21:48:016202 // should scroll the child.
[email protected]a2b5ded2013-05-20 21:32:536203 scroll_delta = gfx::Vector2d(0, 70);
tdresser81e84c672016-01-18 23:21:226204 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186205 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:226206 InputHandler::NON_BUBBLING_GESTURE)
6207 .thread);
[email protected]adeda572014-01-31 00:49:476208 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
majidvp944a8cd2016-01-12 21:05:186209 scroll_result =
6210 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586211 EXPECT_TRUE(scroll_result.did_scroll);
6212 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]adeda572014-01-31 00:49:476213 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
[email protected]a2b5ded2013-05-20 21:32:536214 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186215 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536216 }
6217}
6218
6219TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
6220 // When we try to scroll a non-scrollable child layer, the scroll delta
6221 // should be applied to one of its ancestors if possible. Overscroll should
6222 // be reflected only when it has bubbled up to the root scrolling layer.
tdresserdeeba3f2015-07-10 19:26:586223 InputHandlerScrollResult scroll_result;
bokan1f86d8f2015-07-30 16:08:546224 SetupScrollAndContentsLayers(gfx::Size(20, 20));
danakj74af409e2016-07-01 00:41:486225 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6226
[email protected]ce2e8112013-11-28 07:44:366227 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:536228 {
6229 gfx::Vector2d scroll_delta(0, 8);
tdresser81e84c672016-01-18 23:21:226230 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186231 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:226232 InputHandler::WHEEL)
6233 .thread);
majidvp944a8cd2016-01-12 21:05:186234 scroll_result =
6235 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586236 EXPECT_TRUE(scroll_result.did_scroll);
6237 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536238 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186239 scroll_result =
6240 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586241 EXPECT_TRUE(scroll_result.did_scroll);
6242 EXPECT_TRUE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536243 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186244 scroll_result =
6245 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586246 EXPECT_FALSE(scroll_result.did_scroll);
6247 EXPECT_TRUE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536248 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186249 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536250 }
6251}
6252
[email protected]34d43432013-09-26 20:04:106253TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
tdresserdeeba3f2015-07-10 19:26:586254 InputHandlerScrollResult scroll_result;
weiliangc8f4ef0d2015-11-27 00:15:556255 LayerTreeSettings settings = DefaultSettings();
[email protected]ce2e8112013-11-28 07:44:366256 CreateHostImpl(settings, CreateOutputSurface());
[email protected]34d43432013-09-26 20:04:106257
[email protected]adeda572014-01-31 00:49:476258 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50));
jaydasikaf419bf72016-06-15 10:21:216259 LayerImpl* clip_layer =
6260 scroll_layer->test_properties()->parent->test_properties()->parent;
danakj74af409e2016-07-01 00:41:486261
[email protected]adeda572014-01-31 00:49:476262 clip_layer->SetBounds(gfx::Size(50, 50));
danakj74af409e2016-07-01 00:41:486263 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6264
[email protected]34d43432013-09-26 20:04:106265 host_impl_->SetViewportSize(gfx::Size(50, 50));
aelias58eec0812014-12-04 01:04:406266 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:366267 DrawFrame();
[email protected]34d43432013-09-26 20:04:106268 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
[email protected]34d43432013-09-26 20:04:106269
6270 // Even though the layer can't scroll the overscroll still happens.
tdresser81e84c672016-01-18 23:21:226271 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186272 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:226273 InputHandler::WHEEL)
6274 .thread);
majidvp944a8cd2016-01-12 21:05:186275 scroll_result = host_impl_->ScrollBy(
6276 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
tdresserdeeba3f2015-07-10 19:26:586277 EXPECT_FALSE(scroll_result.did_scroll);
6278 EXPECT_TRUE(scroll_result.did_overscroll_root);
[email protected]34d43432013-09-26 20:04:106279 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
[email protected]34d43432013-09-26 20:04:106280}
[email protected]a2b5ded2013-05-20 21:32:536281
[email protected]5b8a865c2014-04-03 00:35:516282TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
tdresserdeeba3f2015-07-10 19:26:586283 InputHandlerScrollResult scroll_result;
bokan1f86d8f2015-07-30 16:08:546284 SetupScrollAndContentsLayers(gfx::Size(200, 200));
danakj74af409e2016-07-01 00:41:486285 host_impl_->active_tree()->BuildPropertyTreesForTesting();
awoloszyne83f28c2014-12-22 15:40:006286
[email protected]485a42dc2014-03-26 22:44:346287 DrawFrame();
6288 {
[email protected]5b8a865c2014-04-03 00:35:516289 // Edge glow effect should be applicable only upon reaching Edges
6290 // of the content. unnecessary glow effect calls shouldn't be
6291 // called while scrolling up without reaching the edge of the content.
tdresser81e84c672016-01-18 23:21:226292 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186293 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
tdresser81e84c672016-01-18 23:21:226294 InputHandler::WHEEL)
6295 .thread);
majidvp944a8cd2016-01-12 21:05:186296 scroll_result = host_impl_->ScrollBy(
6297 UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
tdresserdeeba3f2015-07-10 19:26:586298 EXPECT_TRUE(scroll_result.did_scroll);
6299 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]485a42dc2014-03-26 22:44:346300 EXPECT_EQ(gfx::Vector2dF().ToString(),
6301 host_impl_->accumulated_root_overscroll().ToString());
majidvp944a8cd2016-01-12 21:05:186302 scroll_result = host_impl_->ScrollBy(
6303 UpdateState(gfx::Point(), gfx::Vector2dF(0, -2.30f)).get());
tdresserdeeba3f2015-07-10 19:26:586304 EXPECT_TRUE(scroll_result.did_scroll);
6305 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]485a42dc2014-03-26 22:44:346306 EXPECT_EQ(gfx::Vector2dF().ToString(),
6307 host_impl_->accumulated_root_overscroll().ToString());
majidvp944a8cd2016-01-12 21:05:186308 host_impl_->ScrollEnd(EndState().get());
[email protected]5b8a865c2014-04-03 00:35:516309 // unusedrootDelta should be subtracted from applied delta so that
6310 // unwanted glow effect calls are not called.
tdresser81e84c672016-01-18 23:21:226311 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
6312 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6313 InputHandler::NON_BUBBLING_GESTURE)
6314 .thread);
6315 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
6316 host_impl_->FlingScrollBegin().thread);
majidvp944a8cd2016-01-12 21:05:186317 scroll_result = host_impl_->ScrollBy(
6318 UpdateState(gfx::Point(), gfx::Vector2dF(0, 20)).get());
tdresserdeeba3f2015-07-10 19:26:586319 EXPECT_TRUE(scroll_result.did_scroll);
6320 EXPECT_TRUE(scroll_result.did_overscroll_root);
jaydasikad7dea632015-11-06 04:40:126321 EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
6322 host_impl_->accumulated_root_overscroll());
[email protected]5b8a865c2014-04-03 00:35:516323
majidvp944a8cd2016-01-12 21:05:186324 scroll_result = host_impl_->ScrollBy(
6325 UpdateState(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f)).get());
tdresserdeeba3f2015-07-10 19:26:586326 EXPECT_FALSE(scroll_result.did_scroll);
6327 EXPECT_FALSE(scroll_result.did_overscroll_root);
jaydasikad7dea632015-11-06 04:40:126328 EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
6329 host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186330 host_impl_->ScrollEnd(EndState().get());
[email protected]9328ede2014-04-04 07:45:526331 // TestCase to check kEpsilon, which prevents minute values to trigger
6332 // gloweffect without reaching edge.
tdresser81e84c672016-01-18 23:21:226333 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186334 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
tdresser81e84c672016-01-18 23:21:226335 InputHandler::WHEEL)
6336 .thread);
majidvp944a8cd2016-01-12 21:05:186337 scroll_result = host_impl_->ScrollBy(
6338 UpdateState(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f)).get());
tdresserdeeba3f2015-07-10 19:26:586339 EXPECT_FALSE(scroll_result.did_scroll);
6340 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]9328ede2014-04-04 07:45:526341 EXPECT_EQ(gfx::Vector2dF().ToString(),
6342 host_impl_->accumulated_root_overscroll().ToString());
majidvp944a8cd2016-01-12 21:05:186343 host_impl_->ScrollEnd(EndState().get());
[email protected]485a42dc2014-03-26 22:44:346344 }
6345}
6346
eseckler59eeb022016-07-05 10:45:176347TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) {
6348 InputHandlerScrollResult scroll_result;
6349 LayerTreeSettings settings = DefaultSettings();
6350 CreateHostImpl(settings, CreateOutputSurface());
6351
6352 const gfx::Size content_size(50, 50);
6353 const gfx::Size viewport_size(50, 50);
6354 CreateBasicVirtualViewportLayers(viewport_size, content_size);
6355
6356 LayerImpl* scroll_layer =
6357 host_impl_->active_tree()->InnerViewportScrollLayer();
6358 scroll_layer->set_main_thread_scrolling_reasons(
6359 MainThreadScrollingReason::kThreadedScrollingDisabled);
6360 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6361
6362 DrawFrame();
6363
6364 // Overscroll initiated outside layers will be handled by the main thread.
6365 EXPECT_EQ(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6366 gfx::PointF(0, 60)));
6367 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD,
6368 host_impl_
6369 ->ScrollBegin(BeginState(gfx::Point(0, 60)).get(),
6370 InputHandler::WHEEL)
6371 .thread);
6372
6373 // Overscroll initiated inside layers will be handled by the main thread.
6374 EXPECT_NE(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6375 gfx::PointF(0, 0)));
6376 EXPECT_EQ(
6377 InputHandler::SCROLL_ON_MAIN_THREAD,
6378 host_impl_
6379 ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::WHEEL)
6380 .thread);
6381}
6382
bokanbc115b42016-08-22 13:46:326383// Test that scrolls chain correctly when a child scroller on the page (e.g. a
6384// scrolling div) is set as the outer viewport. This happens in the
6385// rootScroller proposal.
6386TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
6387 const gfx::Size content_size(200, 200);
6388 const gfx::Size viewport_size(100, 100);
6389
6390 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
6391
6392 LayerImpl* content_layer =
6393 CreateBasicVirtualViewportLayers(viewport_size, content_size);
6394 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
6395 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
6396
6397 LayerImpl* scroll_layer = nullptr;
6398 LayerImpl* child_scroll_layer = nullptr;
6399
6400 // Initialization: Add two nested scrolling layers, simulating a scrolling div
6401 // with another scrolling div inside it. Set the outer "div" to be the outer
6402 // viewport.
6403 {
6404 std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
6405 clip->SetBounds(content_size);
6406 clip->SetPosition(gfx::PointF());
6407
6408 std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
6409 scroll->SetBounds(gfx::Size(400, 400));
6410 scroll->SetScrollClipLayer(clip->id());
6411 scroll->SetDrawsContent(true);
6412
6413 std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 12);
6414 clip2->SetBounds(gfx::Size(300, 300));
6415 clip2->SetPosition(gfx::PointF());
6416 clip2->SetDrawsContent(true);
6417
6418 std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13);
6419 scroll2->SetBounds(gfx::Size(500, 500));
6420 scroll2->SetScrollClipLayer(clip2->id());
6421 scroll2->SetDrawsContent(true);
6422
6423 scroll_layer = scroll.get();
6424 child_scroll_layer = scroll2.get();
6425
6426 clip2->test_properties()->AddChild(std::move(scroll2));
6427 scroll->test_properties()->AddChild(std::move(clip2));
6428
6429 clip->test_properties()->AddChild(std::move(scroll));
6430 content_layer->test_properties()->AddChild(std::move(clip));
6431 layer_tree_impl->SetViewportLayersFromIds(
6432 Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(),
6433 inner_scroll_layer->id(), scroll_layer->id());
6434 layer_tree_impl->BuildPropertyTreesForTesting();
6435 }
6436
6437 // Scroll should target the nested scrolling layer in the content and then
6438 // chain to the parent scrolling layer which is now set as the outer
6439 // viewport. The original outer viewport layer shouldn't get any scroll here.
6440 {
6441 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6442 InputHandler::TOUCHSCREEN);
6443 host_impl_->ScrollBy(
6444 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
6445 host_impl_->ScrollEnd(EndState().get());
6446
6447 EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
6448 child_scroll_layer->CurrentScrollOffset());
6449
6450 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6451 InputHandler::TOUCHSCREEN);
6452 host_impl_->ScrollBy(
6453 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
6454 host_impl_->ScrollEnd(EndState().get());
6455
6456 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
6457 outer_scroll_layer->CurrentScrollOffset());
6458
6459 EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
6460 scroll_layer->CurrentScrollOffset());
6461 }
6462
6463 // Now that the nested scrolling layers are fully scrolled, further scrolls
6464 // would normally chain up to the "outer viewport" but since we've set the
6465 // scrolling content as the outer viewport, it should stop chaining there.
6466 {
6467 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6468 InputHandler::TOUCHSCREEN);
6469 host_impl_->ScrollBy(
6470 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
6471 host_impl_->ScrollEnd(EndState().get());
6472
6473 EXPECT_VECTOR_EQ(gfx::Vector2dF(),
6474 outer_scroll_layer->CurrentScrollOffset());
6475 }
6476
6477 // Zoom into the page by a 2X factor so that the inner viewport becomes
6478 // scrollable.
6479 float min_page_scale = 1.f, max_page_scale = 4.f;
6480 float page_scale_factor = 2.f;
6481 host_impl_->active_tree()->PushPageScaleFromMainThread(
6482 page_scale_factor, min_page_scale, max_page_scale);
6483 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
6484
6485 // Reset the parent scrolling layer (i.e. the current outer viewport) so that
6486 // we can ensure viewport scrolling works correctly.
6487 scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0));
6488
6489 // Scrolling the content layer should now scroll the inner viewport first,
6490 // and then chain up to the current outer viewport (i.e. the parent scroll
6491 // layer).
6492 {
6493 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6494 InputHandler::TOUCHSCREEN);
6495 host_impl_->ScrollBy(
6496 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
6497 host_impl_->ScrollEnd(EndState().get());
6498
6499 EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
6500 inner_scroll_layer->CurrentScrollOffset());
6501
6502 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6503 InputHandler::TOUCHSCREEN);
6504 host_impl_->ScrollBy(
6505 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
6506 host_impl_->ScrollEnd(EndState().get());
6507
6508 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
6509 outer_scroll_layer->CurrentScrollOffset());
6510 EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
6511 scroll_layer->CurrentScrollOffset());
6512 }
6513}
6514
eseckler59eeb022016-07-05 10:45:176515TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) {
6516 InputHandlerScrollResult scroll_result;
6517 LayerTreeSettings settings = DefaultSettings();
6518 CreateHostImpl(settings, CreateOutputSurface());
6519
6520 const gfx::Size content_size(50, 50);
6521 const gfx::Size viewport_size(50, 50);
6522 CreateBasicVirtualViewportLayers(viewport_size, content_size);
6523
6524 // By default, no main thread scrolling reasons should exist.
6525 LayerImpl* scroll_layer =
6526 host_impl_->active_tree()->InnerViewportScrollLayer();
6527 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
6528 scroll_layer->main_thread_scrolling_reasons());
6529
6530 DrawFrame();
6531
6532 // Overscroll initiated outside layers will be handled by the impl thread.
6533 EXPECT_EQ(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6534 gfx::PointF(0, 60)));
6535 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
6536 host_impl_
6537 ->ScrollBegin(BeginState(gfx::Point(0, 60)).get(),
6538 InputHandler::WHEEL)
6539 .thread);
6540
6541 // Overscroll initiated inside layers will be handled by the impl thread.
6542 EXPECT_NE(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6543 gfx::PointF(0, 0)));
6544 EXPECT_EQ(
6545 InputHandler::SCROLL_ON_IMPL_THREAD,
6546 host_impl_
6547 ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::WHEEL)
6548 .thread);
6549}
6550
[email protected]96baf3e2012-10-22 23:09:556551class BlendStateCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:426552 public:
danakj60bc3bc2016-04-09 00:24:486553 static std::unique_ptr<LayerImpl> Create(
6554 LayerTreeImpl* tree_impl,
6555 int id,
6556 ResourceProvider* resource_provider) {
6557 return base::WrapUnique(
danakjf446a072014-09-27 21:55:486558 new BlendStateCheckLayer(tree_impl, id, resource_provider));
[email protected]aa043632013-03-25 03:39:426559 }
[email protected]94f206c12012-08-25 00:09:146560
dcheng716bedf2014-10-21 09:51:086561 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:086562 AppendQuadsData* append_quads_data) override {
[email protected]aa043632013-03-25 03:39:426563 quads_appended_ = true;
[email protected]94f206c12012-08-25 00:09:146564
[email protected]aa043632013-03-25 03:39:426565 gfx::Rect opaque_rect;
6566 if (contents_opaque())
6567 opaque_rect = quad_rect_;
6568 else
6569 opaque_rect = opaque_content_rect_;
[email protected]9bf06c72014-03-07 18:16:246570 gfx::Rect visible_quad_rect = quad_rect_;
[email protected]94f206c12012-08-25 00:09:146571
[email protected]c6707fd2014-06-23 05:50:366572 SharedQuadState* shared_quad_state =
6573 render_pass->CreateAndAppendSharedQuadState();
[email protected]9be1adc2014-05-07 15:39:416574 PopulateSharedQuadState(shared_quad_state);
6575
[email protected]f7030c32014-07-03 18:54:346576 TileDrawQuad* test_blending_draw_quad =
6577 render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
[email protected]aa043632013-03-25 03:39:426578 test_blending_draw_quad->SetNew(shared_quad_state,
6579 quad_rect_,
6580 opaque_rect,
[email protected]9bf06c72014-03-07 18:16:246581 visible_quad_rect,
[email protected]aa043632013-03-25 03:39:426582 resource_id_,
6583 gfx::RectF(0.f, 0.f, 1.f, 1.f),
6584 gfx::Size(1, 1),
jackhou24229612014-12-13 23:41:006585 false,
[email protected]aa043632013-03-25 03:39:426586 false);
6587 test_blending_draw_quad->visible_rect = quad_visible_rect_;
6588 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
6589 EXPECT_EQ(has_render_surface_, !!render_surface());
[email protected]aa043632013-03-25 03:39:426590 }
[email protected]94f206c12012-08-25 00:09:146591
[email protected]aa043632013-03-25 03:39:426592 void SetExpectation(bool blend, bool has_render_surface) {
6593 blend_ = blend;
6594 has_render_surface_ = has_render_surface;
6595 quads_appended_ = false;
6596 }
[email protected]94f206c12012-08-25 00:09:146597
[email protected]aa043632013-03-25 03:39:426598 bool quads_appended() const { return quads_appended_; }
[email protected]94f206c12012-08-25 00:09:146599
[email protected]0023fc72014-01-10 20:05:066600 void SetQuadRect(const gfx::Rect& rect) { quad_rect_ = rect; }
6601 void SetQuadVisibleRect(const gfx::Rect& rect) { quad_visible_rect_ = rect; }
6602 void SetOpaqueContentRect(const gfx::Rect& rect) {
6603 opaque_content_rect_ = rect;
6604 }
[email protected]94f206c12012-08-25 00:09:146605
[email protected]aa043632013-03-25 03:39:426606 private:
6607 BlendStateCheckLayer(LayerTreeImpl* tree_impl,
6608 int id,
6609 ResourceProvider* resource_provider)
6610 : LayerImpl(tree_impl, id),
6611 blend_(false),
6612 has_render_surface_(false),
6613 quads_appended_(false),
6614 quad_rect_(5, 5, 5, 5),
6615 quad_visible_rect_(5, 5, 5, 5),
6616 resource_id_(resource_provider->CreateResource(
6617 gfx::Size(1, 1),
ericrk7c030992015-02-20 01:39:386618 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
ccameronb4d92362016-08-12 07:33:266619 RGBA_8888,
6620 gfx::ColorSpace())) {
[email protected]aa043632013-03-25 03:39:426621 resource_provider->AllocateForTesting(resource_id_);
[email protected]aa043632013-03-25 03:39:426622 SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:426623 SetDrawsContent(true);
6624 }
[email protected]94f206c12012-08-25 00:09:146625
[email protected]aa043632013-03-25 03:39:426626 bool blend_;
6627 bool has_render_surface_;
6628 bool quads_appended_;
6629 gfx::Rect quad_rect_;
6630 gfx::Rect opaque_content_rect_;
6631 gfx::Rect quad_visible_rect_;
jbaumanbbd425e2015-05-19 00:33:356632 ResourceId resource_id_;
[email protected]94f206c12012-08-25 00:09:146633};
6634
[email protected]aa043632013-03-25 03:39:426635TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
6636 {
danakj60bc3bc2016-04-09 00:24:486637 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:426638 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:426639 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:426640 root->SetDrawsContent(false);
jaydasika6b5a32bf2016-04-22 21:56:366641 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:596642 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
[email protected]aa043632013-03-25 03:39:426643 }
jaydasikabf1875a2016-06-28 03:39:596644 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]94f206c12012-08-25 00:09:146645
jaydasika89f7b5a2016-06-22 02:08:396646 root->test_properties()->AddChild(BlendStateCheckLayer::Create(
6647 host_impl_->active_tree(), 2, host_impl_->resource_provider()));
[email protected]aa043632013-03-25 03:39:426648 BlendStateCheckLayer* layer1 =
jaydasikafc66cfb2016-06-10 04:34:226649 static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]);
[email protected]aa043632013-03-25 03:39:426650 layer1->SetPosition(gfx::PointF(2.f, 2.f));
[email protected]94f206c12012-08-25 00:09:146651
[email protected]aa043632013-03-25 03:39:426652 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:146653
[email protected]aa043632013-03-25 03:39:426654 // Opaque layer, drawn without blending.
6655 layer1->SetContentsOpaque(true);
6656 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146657 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486658 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6659 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456660 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426661 EXPECT_TRUE(layer1->quads_appended());
6662 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146663
[email protected]aa043632013-03-25 03:39:426664 // Layer with translucent content and painting, so drawn with blending.
6665 layer1->SetContentsOpaque(false);
6666 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146667 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486668 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6669 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456670 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426671 EXPECT_TRUE(layer1->quads_appended());
6672 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146673
[email protected]aa043632013-03-25 03:39:426674 // Layer with translucent opacity, drawn with blending.
6675 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186676 layer1->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356677 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426678 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146679 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486680 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6681 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456682 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426683 EXPECT_TRUE(layer1->quads_appended());
6684 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146685
[email protected]aa043632013-03-25 03:39:426686 // Layer with translucent opacity and painting, drawn with blending.
6687 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186688 layer1->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356689 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426690 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146691 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486692 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6693 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456694 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426695 EXPECT_TRUE(layer1->quads_appended());
6696 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146697
jaydasika89f7b5a2016-06-22 02:08:396698 layer1->test_properties()->AddChild(BlendStateCheckLayer::Create(
6699 host_impl_->active_tree(), 3, host_impl_->resource_provider()));
jaydasikafc66cfb2016-06-10 04:34:226700 BlendStateCheckLayer* layer2 = static_cast<BlendStateCheckLayer*>(
6701 layer1->test_properties()->children[0]);
[email protected]aa043632013-03-25 03:39:426702 layer2->SetPosition(gfx::PointF(4.f, 4.f));
[email protected]94f206c12012-08-25 00:09:146703
[email protected]aa043632013-03-25 03:39:426704 // 2 opaque layers, drawn without blending.
6705 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186706 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356707 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426708 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146709 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426710 layer2->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186711 layer2->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356712 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426713 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146714 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486715 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6716 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456717 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426718 EXPECT_TRUE(layer1->quads_appended());
6719 EXPECT_TRUE(layer2->quads_appended());
6720 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146721
[email protected]aa043632013-03-25 03:39:426722 // Parent layer with translucent content, drawn with blending.
6723 // Child layer with opaque content, drawn without blending.
6724 layer1->SetContentsOpaque(false);
6725 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146726 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426727 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146728 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486729 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6730 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456731 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426732 EXPECT_TRUE(layer1->quads_appended());
6733 EXPECT_TRUE(layer2->quads_appended());
6734 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146735
[email protected]aa043632013-03-25 03:39:426736 // Parent layer with translucent content but opaque painting, drawn without
6737 // blending.
6738 // Child layer with opaque content, drawn without blending.
6739 layer1->SetContentsOpaque(true);
6740 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146741 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426742 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146743 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486744 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6745 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456746 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426747 EXPECT_TRUE(layer1->quads_appended());
6748 EXPECT_TRUE(layer2->quads_appended());
6749 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146750
[email protected]aa043632013-03-25 03:39:426751 // Parent layer with translucent opacity and opaque content. Since it has a
6752 // drawing child, it's drawn to a render surface which carries the opacity,
6753 // so it's itself drawn without blending.
6754 // Child layer with opaque content, drawn without blending (parent surface
6755 // carries the inherited opacity).
6756 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186757 layer1->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356758 layer1->NoteLayerPropertyChanged();
jaydasika6b5a32bf2016-04-22 21:56:366759 layer1->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:426760 layer1->SetExpectation(false, true);
Dana Jansensc46d3742015-06-18 01:33:146761 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426762 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146763 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]ad63b2f2014-08-11 17:39:546764 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
jaydasikabf1875a2016-06-28 03:39:596765 host_impl_->active_tree()->root_layer_for_testing());
danakj74af409e2016-07-01 00:41:486766 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6767 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456768 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426769 EXPECT_TRUE(layer1->quads_appended());
6770 EXPECT_TRUE(layer2->quads_appended());
6771 host_impl_->DidDrawAllLayers(frame);
jaydasika6b5a32bf2016-04-22 21:56:366772 layer1->test_properties()->force_render_surface = false;
[email protected]94f206c12012-08-25 00:09:146773
[email protected]aa043632013-03-25 03:39:426774 // Draw again, but with child non-opaque, to make sure
6775 // layer1 not culled.
6776 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186777 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356778 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426779 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146780 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426781 layer2->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186782 layer2->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356783 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426784 layer2->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146785 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486786 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6787 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456788 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426789 EXPECT_TRUE(layer1->quads_appended());
6790 EXPECT_TRUE(layer2->quads_appended());
6791 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146792
[email protected]aa043632013-03-25 03:39:426793 // A second way of making the child non-opaque.
6794 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186795 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356796 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426797 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146798 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426799 layer2->SetContentsOpaque(false);
jaydasikaab317e02016-06-01 00:53:186800 layer2->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356801 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426802 layer2->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146803 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486804 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6805 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456806 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426807 EXPECT_TRUE(layer1->quads_appended());
6808 EXPECT_TRUE(layer2->quads_appended());
6809 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146810
[email protected]aa043632013-03-25 03:39:426811 // And when the layer says its not opaque but is painted opaque, it is not
6812 // blended.
6813 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186814 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356815 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426816 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146817 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426818 layer2->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186819 layer2->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356820 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426821 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146822 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486823 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6824 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456825 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426826 EXPECT_TRUE(layer1->quads_appended());
6827 EXPECT_TRUE(layer2->quads_appended());
6828 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146829
[email protected]aa043632013-03-25 03:39:426830 // Layer with partially opaque contents, drawn with blending.
6831 layer1->SetContentsOpaque(false);
6832 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6833 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
6834 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6835 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146836 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486837 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6838 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456839 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426840 EXPECT_TRUE(layer1->quads_appended());
6841 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146842
[email protected]aa043632013-03-25 03:39:426843 // Layer with partially opaque contents partially culled, drawn with blending.
6844 layer1->SetContentsOpaque(false);
6845 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6846 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
6847 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6848 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146849 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486850 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6851 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456852 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426853 EXPECT_TRUE(layer1->quads_appended());
6854 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146855
[email protected]aa043632013-03-25 03:39:426856 // Layer with partially opaque contents culled, drawn with blending.
6857 layer1->SetContentsOpaque(false);
6858 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6859 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
6860 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6861 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146862 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486863 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6864 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456865 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426866 EXPECT_TRUE(layer1->quads_appended());
6867 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146868
[email protected]aa043632013-03-25 03:39:426869 // Layer with partially opaque contents and translucent contents culled, drawn
6870 // without blending.
6871 layer1->SetContentsOpaque(false);
6872 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6873 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
6874 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6875 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146876 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486877 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6878 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456879 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426880 EXPECT_TRUE(layer1->quads_appended());
6881 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146882}
6883
sadrul32d10972016-07-30 05:26:216884static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) {
6885 host_impl->active_tree()->BuildPropertyTreesForTesting();
6886 LayerTreeHostImpl::FrameData frame;
6887 EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame));
6888 host_impl->DrawLayers(&frame);
sadrul32d10972016-07-30 05:26:216889 host_impl->DidDrawAllLayers(frame);
6890 return frame.may_contain_video;
6891}
6892
6893TEST_F(LayerTreeHostImplTest, MayContainVideo) {
6894 gfx::Size big_size(1000, 1000);
6895 host_impl_->SetViewportSize(big_size);
6896
6897 int layer_id = 1;
6898 host_impl_->active_tree()->SetRootLayerForTesting(
6899 DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++));
6900 DidDrawCheckLayer* root =
6901 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
6902
6903 root->test_properties()->AddChild(
6904 DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++));
6905 DidDrawCheckLayer* video_layer =
6906 static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
6907 video_layer->set_may_contain_video(true);
6908 EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6909
6910 // Test with the video layer occluded.
6911 root->test_properties()->AddChild(
6912 DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++));
6913 DidDrawCheckLayer* large_layer =
6914 static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
6915 large_layer->SetBounds(big_size);
6916 large_layer->SetContentsOpaque(true);
6917 EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6918
6919 // Remove the large layer.
6920 root->test_properties()->RemoveChild(large_layer);
6921 EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6922
6923 // Move the video layer so it goes beyond the root.
6924 video_layer->SetPosition(gfx::PointF(100.f, 100.f));
6925 EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6926
6927 video_layer->SetPosition(gfx::PointF(0.f, 0.f));
6928 video_layer->NoteLayerPropertyChanged();
6929 EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6930}
6931
[email protected]6133cc232013-07-30 18:47:076932class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
[email protected]ce2e8112013-11-28 07:44:366933 protected:
[email protected]9f4f6a32013-09-04 21:35:126934 LayerTreeHostImplViewportCoveredTest() :
6935 gutter_quad_material_(DrawQuad::SOLID_COLOR),
6936 child_(NULL),
6937 did_activate_pending_tree_(false) {}
6938
danakj60bc3bc2016-04-09 00:24:486939 std::unique_ptr<OutputSurface> CreateFakeOutputSurface(bool software) {
danakj6021ec32016-07-22 22:16:086940 if (software)
6941 return FakeOutputSurface::CreateDelegatingSoftware();
danakjf33ceec2016-07-20 20:04:456942 return FakeOutputSurface::CreateDelegating3d();
[email protected]6133cc232013-07-30 18:47:076943 }
[email protected]94f206c12012-08-25 00:09:146944
[email protected]6133cc232013-07-30 18:47:076945 void SetupActiveTreeLayers() {
6946 host_impl_->active_tree()->set_background_color(SK_ColorGRAY);
jaydasikabf1875a2016-06-28 03:39:596947 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]6133cc232013-07-30 18:47:076948 LayerImpl::Create(host_impl_->active_tree(), 1));
jaydasika6b5a32bf2016-04-22 21:56:366949 host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:596950 ->root_layer_for_testing()
jaydasika6b5a32bf2016-04-22 21:56:366951 ->test_properties()
6952 ->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:596953 host_impl_->active_tree()
6954 ->root_layer_for_testing()
6955 ->test_properties()
6956 ->AddChild(BlendStateCheckLayer::Create(
6957 host_impl_->active_tree(), 2, host_impl_->resource_provider()));
jaydasikafc66cfb2016-06-10 04:34:226958 child_ = static_cast<BlendStateCheckLayer*>(host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:596959 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:226960 ->test_properties()
6961 ->children[0]);
[email protected]6133cc232013-07-30 18:47:076962 child_->SetExpectation(false, false);
6963 child_->SetContentsOpaque(true);
6964 }
[email protected]94f206c12012-08-25 00:09:146965
[email protected]6133cc232013-07-30 18:47:076966 // Expect no gutter rects.
6967 void TestLayerCoversFullViewport() {
6968 gfx::Rect layer_rect(viewport_size_);
danakja2fdbc702015-10-20 23:05:246969 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:076970 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:076971 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
6972 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:486973 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:146974
[email protected]aa043632013-03-25 03:39:426975 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:486976 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]aa043632013-03-25 03:39:426977 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:146978
[email protected]9f4f6a32013-09-04 21:35:126979 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:426980 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:126981 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:146982
[email protected]9f4f6a32013-09-04 21:35:126983 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:426984 host_impl_->DidDrawAllLayers(frame);
6985 }
[email protected]94f206c12012-08-25 00:09:146986
[email protected]6133cc232013-07-30 18:47:076987 // Expect fullscreen gutter rect.
boliu7097ee5b2015-12-17 03:16:096988 void SetUpEmptylayer() {
[email protected]aa043632013-03-25 03:39:426989 gfx::Rect layer_rect(0, 0, 0, 0);
danakja2fdbc702015-10-20 23:05:246990 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:076991 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:076992 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
6993 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:486994 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:096995 }
[email protected]94f206c12012-08-25 00:09:146996
boliu7097ee5b2015-12-17 03:16:096997 void VerifyEmptyLayerRenderPasses(const RenderPassList& render_passes) {
6998 ASSERT_EQ(1u, render_passes.size());
6999
7000 EXPECT_EQ(1u, CountGutterQuads(render_passes[0]->quad_list));
7001 EXPECT_EQ(1u, render_passes[0]->quad_list.size());
7002 ValidateTextureDrawQuads(render_passes[0]->quad_list);
7003
7004 VerifyQuadsExactlyCoverViewport(render_passes[0]->quad_list);
7005 }
7006
7007 void TestEmptyLayer() {
7008 SetUpEmptylayer();
[email protected]aa043632013-03-25 03:39:427009 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487010 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
boliu7097ee5b2015-12-17 03:16:097011 VerifyEmptyLayerRenderPasses(frame.render_passes);
[email protected]aa043632013-03-25 03:39:427012 host_impl_->DidDrawAllLayers(frame);
7013 }
[email protected]94f206c12012-08-25 00:09:147014
boliu7097ee5b2015-12-17 03:16:097015 void TestEmptyLayerWithOnDraw() {
7016 SetUpEmptylayer();
7017 gfx::Transform identity;
7018 gfx::Rect viewport(viewport_size_);
7019 bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:597020 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:097021 VerifyEmptyLayerRenderPasses(last_on_draw_render_passes_);
7022 }
7023
[email protected]6133cc232013-07-30 18:47:077024 // Expect four surrounding gutter rects.
boliu7097ee5b2015-12-17 03:16:097025 void SetUpLayerInMiddleOfViewport() {
[email protected]aa043632013-03-25 03:39:427026 gfx::Rect layer_rect(500, 500, 200, 200);
danakja2fdbc702015-10-20 23:05:247027 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:077028 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:077029 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
7030 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:487031 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:097032 }
[email protected]94f206c12012-08-25 00:09:147033
boliu7097ee5b2015-12-17 03:16:097034 void VerifyLayerInMiddleOfViewport(const RenderPassList& render_passes) {
7035 ASSERT_EQ(1u, render_passes.size());
7036
7037 EXPECT_EQ(4u, CountGutterQuads(render_passes[0]->quad_list));
7038 EXPECT_EQ(5u, render_passes[0]->quad_list.size());
7039 ValidateTextureDrawQuads(render_passes[0]->quad_list);
7040
7041 VerifyQuadsExactlyCoverViewport(render_passes[0]->quad_list);
7042 }
7043
7044 void TestLayerInMiddleOfViewport() {
7045 SetUpLayerInMiddleOfViewport();
[email protected]aa043632013-03-25 03:39:427046 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487047 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
boliu7097ee5b2015-12-17 03:16:097048 VerifyLayerInMiddleOfViewport(frame.render_passes);
[email protected]aa043632013-03-25 03:39:427049 host_impl_->DidDrawAllLayers(frame);
7050 }
[email protected]6133cc232013-07-30 18:47:077051
boliu7097ee5b2015-12-17 03:16:097052 void TestLayerInMiddleOfViewportWithOnDraw() {
7053 SetUpLayerInMiddleOfViewport();
7054 gfx::Transform identity;
7055 gfx::Rect viewport(viewport_size_);
7056 bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:597057 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:097058 VerifyLayerInMiddleOfViewport(last_on_draw_render_passes_);
7059 }
7060
[email protected]6133cc232013-07-30 18:47:077061 // Expect no gutter rects.
boliu7097ee5b2015-12-17 03:16:097062 void SetUpLayerIsLargerThanViewport() {
[email protected]6133cc232013-07-30 18:47:077063 gfx::Rect layer_rect(viewport_size_.width() + 10,
7064 viewport_size_.height() + 10);
danakja2fdbc702015-10-20 23:05:247065 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:077066 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:077067 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
7068 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:487069 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:097070 }
[email protected]6133cc232013-07-30 18:47:077071
boliu7097ee5b2015-12-17 03:16:097072 void VerifyLayerIsLargerThanViewport(const RenderPassList& render_passes) {
7073 ASSERT_EQ(1u, render_passes.size());
7074
7075 EXPECT_EQ(0u, CountGutterQuads(render_passes[0]->quad_list));
7076 EXPECT_EQ(1u, render_passes[0]->quad_list.size());
7077 ValidateTextureDrawQuads(render_passes[0]->quad_list);
7078 }
7079
7080 void TestLayerIsLargerThanViewport() {
7081 SetUpLayerIsLargerThanViewport();
[email protected]6133cc232013-07-30 18:47:077082 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487083 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
boliu7097ee5b2015-12-17 03:16:097084 VerifyLayerIsLargerThanViewport(frame.render_passes);
[email protected]6133cc232013-07-30 18:47:077085 host_impl_->DidDrawAllLayers(frame);
7086 }
7087
boliu7097ee5b2015-12-17 03:16:097088 void TestLayerIsLargerThanViewportWithOnDraw() {
7089 SetUpLayerIsLargerThanViewport();
7090 gfx::Transform identity;
7091 gfx::Rect viewport(viewport_size_);
7092 bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:597093 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:097094 VerifyLayerIsLargerThanViewport(last_on_draw_render_passes_);
7095 }
7096
dcheng716bedf2014-10-21 09:51:087097 void DidActivateSyncTree() override { did_activate_pending_tree_ = true; }
[email protected]6133cc232013-07-30 18:47:077098
[email protected]9f4f6a32013-09-04 21:35:127099 void set_gutter_quad_material(DrawQuad::Material material) {
7100 gutter_quad_material_ = material;
7101 }
[email protected]64348ea2014-01-29 22:58:267102 void set_gutter_texture_size(const gfx::Size& gutter_texture_size) {
[email protected]9f4f6a32013-09-04 21:35:127103 gutter_texture_size_ = gutter_texture_size;
7104 }
7105
[email protected]6133cc232013-07-30 18:47:077106 protected:
[email protected]9f4f6a32013-09-04 21:35:127107 size_t CountGutterQuads(const QuadList& quad_list) {
7108 size_t num_gutter_quads = 0;
vmpstra2e89432016-07-20 02:05:347109 for (auto* quad : quad_list) {
weiliangc48805fce2014-10-29 20:30:127110 num_gutter_quads += (quad->material == gutter_quad_material_) ? 1 : 0;
[email protected]9f4f6a32013-09-04 21:35:127111 }
7112 return num_gutter_quads;
7113 }
7114
7115 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) {
7116 LayerTestCommon::VerifyQuadsExactlyCoverRect(
7117 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_)));
7118 }
7119
7120 // Make sure that the texture coordinates match their expectations.
7121 void ValidateTextureDrawQuads(const QuadList& quad_list) {
vmpstra2e89432016-07-20 02:05:347122 for (auto* quad : quad_list) {
weiliangc48805fce2014-10-29 20:30:127123 if (quad->material != DrawQuad::TEXTURE_CONTENT)
[email protected]9f4f6a32013-09-04 21:35:127124 continue;
weiliangc48805fce2014-10-29 20:30:127125 const TextureDrawQuad* texture_quad = TextureDrawQuad::MaterialCast(quad);
ajuma1d48e012015-09-25 22:24:167126 gfx::SizeF gutter_texture_size_pixels =
7127 gfx::ScaleSize(gfx::SizeF(gutter_texture_size_),
7128 host_impl_->active_tree()->device_scale_factor());
weiliangc7eb7ee62014-10-07 00:04:407129 EXPECT_EQ(texture_quad->uv_top_left.x(),
7130 texture_quad->rect.x() / gutter_texture_size_pixels.width());
7131 EXPECT_EQ(texture_quad->uv_top_left.y(),
7132 texture_quad->rect.y() / gutter_texture_size_pixels.height());
7133 EXPECT_EQ(
7134 texture_quad->uv_bottom_right.x(),
7135 texture_quad->rect.right() / gutter_texture_size_pixels.width());
7136 EXPECT_EQ(
7137 texture_quad->uv_bottom_right.y(),
7138 texture_quad->rect.bottom() / gutter_texture_size_pixels.height());
[email protected]9f4f6a32013-09-04 21:35:127139 }
7140 }
7141
[email protected]64348ea2014-01-29 22:58:267142 gfx::Size DipSizeToPixelSize(const gfx::Size& size) {
ajuma1d48e012015-09-25 22:24:167143 return gfx::ScaleToRoundedSize(
7144 size, host_impl_->active_tree()->device_scale_factor());
[email protected]9f4f6a32013-09-04 21:35:127145 }
7146
7147 DrawQuad::Material gutter_quad_material_;
7148 gfx::Size gutter_texture_size_;
[email protected]6133cc232013-07-30 18:47:077149 gfx::Size viewport_size_;
7150 BlendStateCheckLayer* child_;
7151 bool did_activate_pending_tree_;
7152};
7153
7154TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) {
[email protected]ce2e8112013-11-28 07:44:367155 viewport_size_ = gfx::Size(1000, 1000);
7156
boliu8ca83902015-10-23 04:36:137157 bool software = false;
7158 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]6133cc232013-07-30 18:47:077159
[email protected]9f4f6a32013-09-04 21:35:127160 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:077161 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097162 EXPECT_SCOPED(TestLayerCoversFullViewport());
7163 EXPECT_SCOPED(TestEmptyLayer());
7164 EXPECT_SCOPED(TestLayerInMiddleOfViewport());
7165 EXPECT_SCOPED(TestLayerIsLargerThanViewport());
[email protected]94f206c12012-08-25 00:09:147166}
7167
[email protected]9f4f6a32013-09-04 21:35:127168TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
[email protected]ce2e8112013-11-28 07:44:367169 viewport_size_ = gfx::Size(1000, 1000);
7170
boliu8ca83902015-10-23 04:36:137171 bool software = false;
7172 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]9f4f6a32013-09-04 21:35:127173
ajuma1d48e012015-09-25 22:24:167174 host_impl_->active_tree()->SetDeviceScaleFactor(2.f);
[email protected]9f4f6a32013-09-04 21:35:127175 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
7176 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097177 EXPECT_SCOPED(TestLayerCoversFullViewport());
7178 EXPECT_SCOPED(TestEmptyLayer());
7179 EXPECT_SCOPED(TestLayerInMiddleOfViewport());
7180 EXPECT_SCOPED(TestLayerIsLargerThanViewport());
[email protected]9f4f6a32013-09-04 21:35:127181}
7182
[email protected]6133cc232013-07-30 18:47:077183TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
[email protected]ce2e8112013-11-28 07:44:367184 viewport_size_ = gfx::Size(1000, 1000);
[email protected]ce2e8112013-11-28 07:44:367185
boliu8ca83902015-10-23 04:36:137186 bool software = true;
7187 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]6133cc232013-07-30 18:47:077188
7189 // Pending tree to force active_tree size invalid. Not used otherwise.
7190 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:127191 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:077192 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
7193
7194 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097195 EXPECT_SCOPED(TestEmptyLayerWithOnDraw());
7196 EXPECT_SCOPED(TestLayerInMiddleOfViewportWithOnDraw());
7197 EXPECT_SCOPED(TestLayerIsLargerThanViewportWithOnDraw());
[email protected]6133cc232013-07-30 18:47:077198}
7199
7200TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) {
[email protected]ce2e8112013-11-28 07:44:367201 viewport_size_ = gfx::Size(1000, 1000);
[email protected]ce2e8112013-11-28 07:44:367202
boliu8ca83902015-10-23 04:36:137203 bool software = true;
7204 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]6133cc232013-07-30 18:47:077205
7206 // Set larger viewport and activate it to active tree.
7207 host_impl_->CreatePendingTree();
7208 gfx::Size larger_viewport(viewport_size_.width() + 100,
7209 viewport_size_.height() + 100);
[email protected]9f4f6a32013-09-04 21:35:127210 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport));
[email protected]6133cc232013-07-30 18:47:077211 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
[email protected]fc20d142014-07-01 00:49:157212 host_impl_->ActivateSyncTree();
[email protected]6133cc232013-07-30 18:47:077213 EXPECT_TRUE(did_activate_pending_tree_);
7214 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid());
7215
7216 // Shrink pending tree viewport without activating.
7217 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:127218 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:077219 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
7220
7221 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097222 EXPECT_SCOPED(TestEmptyLayerWithOnDraw());
7223 EXPECT_SCOPED(TestLayerInMiddleOfViewportWithOnDraw());
7224 EXPECT_SCOPED(TestLayerIsLargerThanViewportWithOnDraw());
[email protected]6133cc232013-07-30 18:47:077225}
[email protected]94f206c12012-08-25 00:09:147226
[email protected]96baf3e2012-10-22 23:09:557227class FakeDrawableLayerImpl: public LayerImpl {
[email protected]aa043632013-03-25 03:39:427228 public:
danakj60bc3bc2016-04-09 00:24:487229 static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
7230 return base::WrapUnique(new FakeDrawableLayerImpl(tree_impl, id));
[email protected]aa043632013-03-25 03:39:427231 }
7232 protected:
7233 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id)
7234 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:147235};
7236
[email protected]94f206c12012-08-25 00:09:147237// Make sure damage tracking propagates all the way to the graphics context,
[email protected]aa043632013-03-25 03:39:427238// where it should request to swap only the sub-buffer that is damaged.
7239TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
[email protected]d9a54602013-12-10 07:01:597240 scoped_refptr<TestContextProvider> context_provider(
[email protected]4bf41752013-11-05 01:34:327241 TestContextProvider::Create());
[email protected]d9a54602013-12-10 07:01:597242 context_provider->BindToCurrentThread();
7243 context_provider->TestContext3d()->set_have_post_sub_buffer(true);
[email protected]0634cdd42013-08-16 00:46:097244
danakj60bc3bc2016-04-09 00:24:487245 std::unique_ptr<FakeOutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457246 FakeOutputSurface::CreateDelegating3d(context_provider));
sievers06680482014-10-10 20:21:507247 FakeOutputSurface* fake_output_surface = output_surface.get();
[email protected]94f206c12012-08-25 00:09:147248
[email protected]aa043632013-03-25 03:39:427249 // This test creates its own LayerTreeHostImpl, so
7250 // that we can force partial swap enabled.
weiliangc8f4ef0d2015-11-27 00:15:557251 LayerTreeSettings settings = DefaultSettings();
jbaumanc5be44c2014-11-20 22:17:127252 settings.renderer_settings.partial_swap_enabled = true;
danakj60bc3bc2016-04-09 00:24:487253 std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl =
reveman34b7a1522015-03-23 20:27:477254 LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:167255 settings, this, &task_runner_provider_, &stats_instrumentation_,
loysoab32ee72016-06-08 03:33:187256 &shared_bitmap_manager_, NULL, &task_graph_runner_,
7257 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
sievers71c62dd52015-10-07 01:44:397258 layer_tree_host_impl->SetVisible(true);
revemand180dfc32015-09-24 00:19:437259 layer_tree_host_impl->InitializeRenderer(output_surface.get());
mithro0bdb49d2015-05-27 13:08:017260 layer_tree_host_impl->WillBeginImplFrame(
7261 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
[email protected]18ce59702013-04-09 04:58:407262 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
[email protected]94f206c12012-08-25 00:09:147263
danakj60bc3bc2016-04-09 00:24:487264 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:427265 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
jaydasika6b5a32bf2016-04-22 21:56:367266 root->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:487267 std::unique_ptr<LayerImpl> child =
[email protected]aa043632013-03-25 03:39:427268 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
7269 child->SetPosition(gfx::PointF(12.f, 13.f));
[email protected]aa043632013-03-25 03:39:427270 child->SetBounds(gfx::Size(14, 15));
[email protected]aa043632013-03-25 03:39:427271 child->SetDrawsContent(true);
[email protected]aa043632013-03-25 03:39:427272 root->SetBounds(gfx::Size(500, 500));
[email protected]aa043632013-03-25 03:39:427273 root->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397274 root->test_properties()->AddChild(std::move(child));
jaydasikabf1875a2016-06-28 03:39:597275 layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487276 layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:147277
[email protected]aa043632013-03-25 03:39:427278 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:147279
[email protected]aa043632013-03-25 03:39:427280 // First frame, the entire screen should get swapped.
[email protected]2aae96792014-05-15 23:10:507281 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457282 layer_tree_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427283 layer_tree_host_impl->DidDrawAllLayers(frame);
danakjf33ceec2016-07-20 20:04:457284 gfx::Rect expected_swap_rect(500, 500);
sievers06680482014-10-10 20:21:507285 EXPECT_EQ(expected_swap_rect.ToString(),
7286 fake_output_surface->last_swap_rect().ToString());
[email protected]d9a54602013-12-10 07:01:597287
[email protected]aa043632013-03-25 03:39:427288 // Second frame, only the damaged area should get swapped. Damage should be
danakjf33ceec2016-07-20 20:04:457289 // the union of old and new child rects: gfx::Rect(26, 28).
jaydasikaadfec8e2016-02-17 02:46:117290 layer_tree_host_impl->active_tree()
jaydasikabf1875a2016-06-28 03:39:597291 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:227292 ->test_properties()
7293 ->children[0]
7294 ->SetPosition(gfx::PointF());
7295 layer_tree_host_impl->active_tree()
jaydasikabf1875a2016-06-28 03:39:597296 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:227297 ->test_properties()
7298 ->children[0]
jaydasikaadfec8e2016-02-17 02:46:117299 ->NoteLayerPropertyChanged();
danakj74af409e2016-07-01 00:41:487300 layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
[email protected]2aae96792014-05-15 23:10:507301 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457302 layer_tree_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427303 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147304
danakjf33ceec2016-07-20 20:04:457305 expected_swap_rect = gfx::Rect(26, 28);
[email protected]d9a54602013-12-10 07:01:597306 EXPECT_EQ(expected_swap_rect.ToString(),
sievers06680482014-10-10 20:21:507307 fake_output_surface->last_swap_rect().ToString());
[email protected]d9a54602013-12-10 07:01:597308
[email protected]18ce59702013-04-09 04:58:407309 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427310 // This will damage everything.
jaydasikabf1875a2016-06-28 03:39:597311 layer_tree_host_impl->active_tree()
7312 ->root_layer_for_testing()
7313 ->SetBackgroundColor(SK_ColorBLACK);
[email protected]2aae96792014-05-15 23:10:507314 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457315 layer_tree_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427316 host_impl_->DidDrawAllLayers(frame);
[email protected]d9a54602013-12-10 07:01:597317
danakjf33ceec2016-07-20 20:04:457318 expected_swap_rect = gfx::Rect(10, 10);
sievers06680482014-10-10 20:21:507319 EXPECT_EQ(expected_swap_rect.ToString(),
7320 fake_output_surface->last_swap_rect().ToString());
danakjee6547a22016-07-01 20:41:507321
7322 layer_tree_host_impl->ReleaseOutputSurface();
[email protected]94f206c12012-08-25 00:09:147323}
7324
[email protected]aa043632013-03-25 03:39:427325TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
danakj60bc3bc2016-04-09 00:24:487326 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:427327 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:487328 std::unique_ptr<LayerImpl> child =
[email protected]aa043632013-03-25 03:39:427329 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]aa043632013-03-25 03:39:427330 child->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427331 child->SetDrawsContent(true);
[email protected]aa043632013-03-25 03:39:427332 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427333 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:367334 root->test_properties()->force_render_surface = true;
jaydasika89f7b5a2016-06-22 02:08:397335 root->test_properties()->AddChild(std::move(child));
[email protected]94f206c12012-08-25 00:09:147336
jaydasikabf1875a2016-06-28 03:39:597337 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487338 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:147339
[email protected]aa043632013-03-25 03:39:427340 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:147341
danakj74af409e2016-07-01 00:41:487342 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]aa043632013-03-25 03:39:427343 EXPECT_EQ(1u, frame.render_surface_layer_list->size());
7344 EXPECT_EQ(1u, frame.render_passes.size());
7345 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147346}
7347
[email protected]96baf3e2012-10-22 23:09:557348class FakeLayerWithQuads : public LayerImpl {
[email protected]aa043632013-03-25 03:39:427349 public:
danakj60bc3bc2016-04-09 00:24:487350 static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
7351 return base::WrapUnique(new FakeLayerWithQuads(tree_impl, id));
[email protected]aa043632013-03-25 03:39:427352 }
[email protected]94f206c12012-08-25 00:09:147353
dcheng716bedf2014-10-21 09:51:087354 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:087355 AppendQuadsData* append_quads_data) override {
[email protected]c6707fd2014-06-23 05:50:367356 SharedQuadState* shared_quad_state =
7357 render_pass->CreateAndAppendSharedQuadState();
[email protected]9be1adc2014-05-07 15:39:417358 PopulateSharedQuadState(shared_quad_state);
[email protected]94f206c12012-08-25 00:09:147359
[email protected]aa043632013-03-25 03:39:427360 SkColor gray = SkColorSetRGB(100, 100, 100);
Dana Jansensc46d3742015-06-18 01:33:147361 gfx::Rect quad_rect(bounds());
[email protected]9bf06c72014-03-07 18:16:247362 gfx::Rect visible_quad_rect(quad_rect);
[email protected]f7030c32014-07-03 18:54:347363 SolidColorDrawQuad* my_quad =
7364 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
[email protected]9bf06c72014-03-07 18:16:247365 my_quad->SetNew(
7366 shared_quad_state, quad_rect, visible_quad_rect, gray, false);
[email protected]aa043632013-03-25 03:39:427367 }
[email protected]94f206c12012-08-25 00:09:147368
[email protected]aa043632013-03-25 03:39:427369 private:
7370 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id)
7371 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:147372};
7373
danakj60bc3bc2016-04-09 00:24:487374static std::unique_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
weiliangc8f4ef0d2015-11-27 00:15:557375 LayerTreeSettings settings,
[email protected]aa043632013-03-25 03:39:427376 bool partial_swap,
7377 LayerTreeHostImplClient* client,
khushalsagarb64b360d2015-10-21 19:25:167378 TaskRunnerProvider* task_runner_provider,
[email protected]4e2eb352014-03-20 17:25:457379 SharedBitmapManager* manager,
danakjcf610582015-06-16 22:48:567380 TaskGraphRunner* task_graph_runner,
revemand180dfc32015-09-24 00:19:437381 RenderingStatsInstrumentation* stats_instrumentation,
7382 OutputSurface* output_surface) {
jbaumanc5be44c2014-11-20 22:17:127383 settings.renderer_settings.partial_swap_enabled = partial_swap;
danakj60bc3bc2016-04-09 00:24:487384 std::unique_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:167385 settings, client, task_runner_provider, stats_instrumentation, manager,
loysoab32ee72016-06-08 03:33:187386 nullptr, task_graph_runner,
7387 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
sievers71c62dd52015-10-07 01:44:397388 my_host_impl->SetVisible(true);
revemand180dfc32015-09-24 00:19:437389 my_host_impl->InitializeRenderer(output_surface);
mithro0bdb49d2015-05-27 13:08:017390 my_host_impl->WillBeginImplFrame(
7391 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
[email protected]18ce59702013-04-09 04:58:407392 my_host_impl->SetViewportSize(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:147393
[email protected]aa043632013-03-25 03:39:427394 /*
7395 Layers are created as follows:
[email protected]94f206c12012-08-25 00:09:147396
[email protected]aa043632013-03-25 03:39:427397 +--------------------+
7398 | 1 |
7399 | +-----------+ |
7400 | | 2 | |
7401 | | +-------------------+
7402 | | | 3 |
7403 | | +-------------------+
7404 | | | |
7405 | +-----------+ |
7406 | |
7407 | |
7408 +--------------------+
[email protected]94f206c12012-08-25 00:09:147409
[email protected]aa043632013-03-25 03:39:427410 Layers 1, 2 have render surfaces
7411 */
danakj60bc3bc2016-04-09 00:24:487412 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:427413 LayerImpl::Create(my_host_impl->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:487414 std::unique_ptr<LayerImpl> child =
[email protected]aa043632013-03-25 03:39:427415 LayerImpl::Create(my_host_impl->active_tree(), 2);
danakj60bc3bc2016-04-09 00:24:487416 std::unique_ptr<LayerImpl> grand_child =
[email protected]aa043632013-03-25 03:39:427417 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3);
[email protected]94f206c12012-08-25 00:09:147418
[email protected]aa043632013-03-25 03:39:427419 gfx::Rect root_rect(0, 0, 100, 100);
7420 gfx::Rect child_rect(10, 10, 50, 50);
7421 gfx::Rect grand_child_rect(5, 5, 150, 150);
[email protected]94f206c12012-08-25 00:09:147422
jaydasika6b5a32bf2016-04-22 21:56:367423 root->test_properties()->force_render_surface = true;
danakja2fdbc702015-10-20 23:05:247424 root->SetPosition(gfx::PointF(root_rect.origin()));
[email protected]aa043632013-03-25 03:39:427425 root->SetBounds(root_rect.size());
danakj64767d902015-06-19 00:10:437426 root->draw_properties().visible_layer_rect = root_rect;
[email protected]aa043632013-03-25 03:39:427427 root->SetDrawsContent(false);
[email protected]94f206c12012-08-25 00:09:147428
[email protected]aa043632013-03-25 03:39:427429 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
jaydasikaab317e02016-06-01 00:53:187430 child->test_properties()->opacity = 0.5f;
[email protected]aa043632013-03-25 03:39:427431 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
danakj64767d902015-06-19 00:10:437432 child->draw_properties().visible_layer_rect = child_rect;
[email protected]aa043632013-03-25 03:39:427433 child->SetDrawsContent(false);
jaydasika6b5a32bf2016-04-22 21:56:367434 child->test_properties()->force_render_surface = true;
[email protected]94f206c12012-08-25 00:09:147435
danakja2fdbc702015-10-20 23:05:247436 grand_child->SetPosition(gfx::PointF(grand_child_rect.origin()));
[email protected]aa043632013-03-25 03:39:427437 grand_child->SetBounds(grand_child_rect.size());
danakj64767d902015-06-19 00:10:437438 grand_child->draw_properties().visible_layer_rect = grand_child_rect;
[email protected]aa043632013-03-25 03:39:427439 grand_child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:147440
jaydasika89f7b5a2016-06-22 02:08:397441 child->test_properties()->AddChild(std::move(grand_child));
7442 root->test_properties()->AddChild(std::move(child));
[email protected]94f206c12012-08-25 00:09:147443
jaydasikabf1875a2016-06-28 03:39:597444 my_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487445 my_host_impl->active_tree()->BuildPropertyTreesForTesting();
danakja04855a2015-11-18 20:39:107446 return my_host_impl;
[email protected]94f206c12012-08-25 00:09:147447}
7448
[email protected]aa043632013-03-25 03:39:427449TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
danakjcf610582015-06-16 22:48:567450 TestSharedBitmapManager shared_bitmap_manager;
7451 TestTaskGraphRunner task_graph_runner;
revemand180dfc32015-09-24 00:19:437452 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
7453 provider->BindToCurrentThread();
7454 provider->TestContext3d()->set_have_post_sub_buffer(true);
danakj60bc3bc2016-04-09 00:24:487455 std::unique_ptr<OutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457456 FakeOutputSurface::CreateDelegating3d(provider));
danakj60bc3bc2016-04-09 00:24:487457 std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity(
weiliangc8f4ef0d2015-11-27 00:15:557458 DefaultSettings(), true, this, &task_runner_provider_,
7459 &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_,
7460 output_surface.get());
[email protected]aa043632013-03-25 03:39:427461 {
7462 LayerTreeHostImpl::FrameData frame;
[email protected]2aae96792014-05-15 23:10:507463 EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
[email protected]94f206c12012-08-25 00:09:147464
[email protected]aa043632013-03-25 03:39:427465 // Verify all quads have been computed
7466 ASSERT_EQ(2U, frame.render_passes.size());
7467 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
7468 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
7469 EXPECT_EQ(DrawQuad::SOLID_COLOR,
weiliangc032e929d2014-09-26 01:55:017470 frame.render_passes[0]->quad_list.front()->material);
[email protected]aa043632013-03-25 03:39:427471 EXPECT_EQ(DrawQuad::RENDER_PASS,
weiliangc032e929d2014-09-26 01:55:017472 frame.render_passes[1]->quad_list.front()->material);
[email protected]94f206c12012-08-25 00:09:147473
mithro248d1722015-05-05 05:23:457474 my_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427475 my_host_impl->DidDrawAllLayers(frame);
7476 }
danakjee6547a22016-07-01 20:41:507477 my_host_impl->ReleaseOutputSurface();
[email protected]94f206c12012-08-25 00:09:147478}
7479
[email protected]aa043632013-03-25 03:39:427480TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
danakjcf610582015-06-16 22:48:567481 TestSharedBitmapManager shared_bitmap_manager;
7482 TestTaskGraphRunner task_graph_runner;
revemand180dfc32015-09-24 00:19:437483 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
7484 provider->BindToCurrentThread();
7485 provider->TestContext3d()->set_have_post_sub_buffer(true);
danakj60bc3bc2016-04-09 00:24:487486 std::unique_ptr<OutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457487 FakeOutputSurface::CreateDelegating3d(provider));
danakj60bc3bc2016-04-09 00:24:487488 std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity(
weiliangc8f4ef0d2015-11-27 00:15:557489 DefaultSettings(), false, this, &task_runner_provider_,
7490 &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_,
7491 output_surface.get());
[email protected]aa043632013-03-25 03:39:427492 {
7493 LayerTreeHostImpl::FrameData frame;
[email protected]2aae96792014-05-15 23:10:507494 EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
[email protected]94f206c12012-08-25 00:09:147495
[email protected]aa043632013-03-25 03:39:427496 // Verify all quads have been computed
7497 ASSERT_EQ(2U, frame.render_passes.size());
7498 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
7499 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
7500 EXPECT_EQ(DrawQuad::SOLID_COLOR,
weiliangc032e929d2014-09-26 01:55:017501 frame.render_passes[0]->quad_list.front()->material);
[email protected]aa043632013-03-25 03:39:427502 EXPECT_EQ(DrawQuad::RENDER_PASS,
weiliangc032e929d2014-09-26 01:55:017503 frame.render_passes[1]->quad_list.front()->material);
[email protected]94f206c12012-08-25 00:09:147504
mithro248d1722015-05-05 05:23:457505 my_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427506 my_host_impl->DidDrawAllLayers(frame);
7507 }
danakjee6547a22016-07-01 20:41:507508 my_host_impl->ReleaseOutputSurface();
[email protected]94f206c12012-08-25 00:09:147509}
7510
[email protected]aa043632013-03-25 03:39:427511TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
danakj60bc3bc2016-04-09 00:24:487512 std::unique_ptr<TestWebGraphicsContext3D> context =
[email protected]aa043632013-03-25 03:39:427513 TestWebGraphicsContext3D::Create();
7514 TestWebGraphicsContext3D* context3d = context.get();
danakj60bc3bc2016-04-09 00:24:487515 std::unique_ptr<OutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457516 FakeOutputSurface::CreateDelegating3d(std::move(context)));
danakja04855a2015-11-18 20:39:107517 CreateHostImpl(DefaultSettings(), std::move(output_surface));
[email protected]d993b602013-01-04 02:08:127518
danakj60bc3bc2016-04-09 00:24:487519 std::unique_ptr<LayerImpl> root_layer =
[email protected]aa043632013-03-25 03:39:427520 LayerImpl::Create(host_impl_->active_tree(), 1);
7521 root_layer->SetBounds(gfx::Size(10, 10));
jaydasika6b5a32bf2016-04-22 21:56:367522 root_layer->test_properties()->force_render_surface = true;
[email protected]94f206c12012-08-25 00:09:147523
[email protected]aa043632013-03-25 03:39:427524 scoped_refptr<VideoFrame> softwareFrame =
7525 media::VideoFrame::CreateColorFrame(
7526 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
7527 FakeVideoFrameProvider provider;
7528 provider.set_frame(softwareFrame);
danakj60bc3bc2016-04-09 00:24:487529 std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
[email protected]f78c3e82014-08-08 01:24:477530 host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0);
[email protected]aa043632013-03-25 03:39:427531 video_layer->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427532 video_layer->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397533 root_layer->test_properties()->AddChild(std::move(video_layer));
[email protected]94f206c12012-08-25 00:09:147534
jaydasikabf1875a2016-06-28 03:39:597535 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer));
danakj74af409e2016-07-01 00:41:487536 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:147537
[email protected]aa043632013-03-25 03:39:427538 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]d993b602013-01-04 02:08:127539
[email protected]aa043632013-03-25 03:39:427540 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487541 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457542 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427543 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147544
[email protected]aa043632013-03-25 03:39:427545 EXPECT_GT(context3d->NumTextures(), 0u);
[email protected]94f206c12012-08-25 00:09:147546
[email protected]aa043632013-03-25 03:39:427547 // Kill the layer tree.
rockot2176f922016-06-08 19:18:327548 host_impl_->active_tree()->DetachLayers();
[email protected]aa043632013-03-25 03:39:427549 // There should be no textures left in use after.
7550 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]94f206c12012-08-25 00:09:147551}
7552
[email protected]c8756fbe2013-02-12 01:53:497553class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:427554 public:
[email protected]0f9969982014-01-11 02:26:377555 MOCK_METHOD1(useProgram, void(GLuint program));
7556 MOCK_METHOD4(drawElements, void(GLenum mode,
7557 GLsizei count,
7558 GLenum type,
7559 GLintptr offset));
[email protected]94f206c12012-08-25 00:09:147560};
7561
[email protected]aa043632013-03-25 03:39:427562TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
[email protected]aa043632013-03-25 03:39:427563 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:487564 host_impl_->active_tree()->BuildPropertyTreesForTesting();
7565
[email protected]aa043632013-03-25 03:39:427566 host_impl_->active_tree()->set_background_color(SK_ColorWHITE);
[email protected]94f206c12012-08-25 00:09:147567
[email protected]aa043632013-03-25 03:39:427568 // Verify one quad is drawn when transparent background set is not set.
7569 host_impl_->active_tree()->set_has_transparent_background(false);
[email protected]aa043632013-03-25 03:39:427570 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487571 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjf33ceec2016-07-20 20:04:457572 {
7573 const auto& root_pass = frame.render_passes.back();
7574 ASSERT_EQ(1u, root_pass->quad_list.size());
7575 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.front()->material);
7576 }
mithro248d1722015-05-05 05:23:457577 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427578 host_impl_->DidDrawAllLayers(frame);
danakjf33ceec2016-07-20 20:04:457579
7580 // Cause damage so we would draw something if possible.
danakjb902c672016-08-17 02:33:547581 host_impl_->SetFullViewportDamage();
[email protected]94f206c12012-08-25 00:09:147582
[email protected]aa043632013-03-25 03:39:427583 // Verify no quads are drawn when transparent background is set.
7584 host_impl_->active_tree()->set_has_transparent_background(true);
danakjb902c672016-08-17 02:33:547585 host_impl_->SetFullViewportDamage();
danakj74af409e2016-07-01 00:41:487586 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjf33ceec2016-07-20 20:04:457587 {
7588 const auto& root_pass = frame.render_passes.back();
7589 ASSERT_EQ(0u, root_pass->quad_list.size());
7590 }
mithro248d1722015-05-05 05:23:457591 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427592 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147593}
7594
[email protected]aa043632013-03-25 03:39:427595class LayerTreeHostImplTestWithDelegatingRenderer
7596 : public LayerTreeHostImplTest {
7597 protected:
danakj60bc3bc2016-04-09 00:24:487598 std::unique_ptr<OutputSurface> CreateOutputSurface() override {
danakjf446a072014-09-27 21:55:487599 return FakeOutputSurface::CreateDelegating3d();
[email protected]aa043632013-03-25 03:39:427600 }
7601
danakj5e6ff6d2015-09-05 04:43:447602 void DrawFrameAndTestDamage(const gfx::Rect& expected_damage) {
[email protected]e0341352013-04-06 05:01:207603 bool expect_to_draw = !expected_damage.IsEmpty();
7604
[email protected]aa043632013-03-25 03:39:427605 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487606 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]aa043632013-03-25 03:39:427607
[email protected]e0341352013-04-06 05:01:207608 if (!expect_to_draw) {
7609 // With no damage, we don't draw, and no quads are created.
7610 ASSERT_EQ(0u, frame.render_passes.size());
7611 } else {
7612 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]aa043632013-03-25 03:39:427613
[email protected]e0341352013-04-06 05:01:207614 // Verify the damage rect for the root render pass.
vmpstra370ef52015-11-18 10:41:287615 const RenderPass* root_render_pass = frame.render_passes.back().get();
hush6b614212014-12-04 22:37:327616 EXPECT_EQ(expected_damage, root_render_pass->damage_rect);
[email protected]e0341352013-04-06 05:01:207617
7618 // Verify the root and child layers' quads are generated and not being
7619 // culled.
7620 ASSERT_EQ(2u, root_render_pass->quad_list.size());
7621
jaydasikafc66cfb2016-06-10 04:34:227622 LayerImpl* child = host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:597623 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:227624 ->test_properties()
7625 ->children[0];
danakj5e6ff6d2015-09-05 04:43:447626 gfx::Rect expected_child_visible_rect(child->bounds());
hush6b614212014-12-04 22:37:327627 EXPECT_EQ(expected_child_visible_rect,
7628 root_render_pass->quad_list.front()->visible_rect);
[email protected]e0341352013-04-06 05:01:207629
jaydasikabf1875a2016-06-28 03:39:597630 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
danakj5e6ff6d2015-09-05 04:43:447631 gfx::Rect expected_root_visible_rect(root->bounds());
hush6b614212014-12-04 22:37:327632 EXPECT_EQ(expected_root_visible_rect,
7633 root_render_pass->quad_list.ElementAt(1)->visible_rect);
[email protected]e0341352013-04-06 05:01:207634 }
[email protected]aa043632013-03-25 03:39:427635
danakjaecfcfba2016-09-07 22:33:187636 EXPECT_EQ(expect_to_draw, host_impl_->DrawLayers(&frame));
[email protected]aa043632013-03-25 03:39:427637 host_impl_->DidDrawAllLayers(frame);
[email protected]aa043632013-03-25 03:39:427638 }
7639};
7640
7641TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
danakj60bc3bc2016-04-09 00:24:487642 std::unique_ptr<SolidColorLayerImpl> root =
[email protected]aa043632013-03-25 03:39:427643 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:427644 root->SetPosition(gfx::PointF());
7645 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427646 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:367647 root->test_properties()->force_render_surface = true;
[email protected]e0341352013-04-06 05:01:207648
7649 // Child layer is in the bottom right corner.
danakj60bc3bc2016-04-09 00:24:487650 std::unique_ptr<SolidColorLayerImpl> child =
[email protected]e0341352013-04-06 05:01:207651 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]e0341352013-04-06 05:01:207652 child->SetPosition(gfx::PointF(9.f, 9.f));
7653 child->SetBounds(gfx::Size(1, 1));
[email protected]e0341352013-04-06 05:01:207654 child->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397655 root->test_properties()->AddChild(std::move(child));
[email protected]e0341352013-04-06 05:01:207656
jaydasikabf1875a2016-06-28 03:39:597657 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487658 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:427659
7660 // Draw a frame. In the first frame, the entire viewport should be damaged.
[email protected]54af03522013-09-05 00:43:287661 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
[email protected]aa043632013-03-25 03:39:427662 DrawFrameAndTestDamage(full_frame_damage);
7663
[email protected]e0341352013-04-06 05:01:207664 // The second frame has damage that doesn't touch the child layer. Its quads
7665 // should still be generated.
7666 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
jaydasikabf1875a2016-06-28 03:39:597667 host_impl_->active_tree()->root_layer_for_testing()->SetUpdateRect(
7668 small_damage);
[email protected]e0341352013-04-06 05:01:207669 DrawFrameAndTestDamage(small_damage);
7670
7671 // The third frame should have no damage, so no quads should be generated.
[email protected]aa043632013-03-25 03:39:427672 gfx::Rect no_damage;
7673 DrawFrameAndTestDamage(no_damage);
[email protected]ea9d8f22012-12-08 03:39:297674}
7675
[email protected]46b79d52013-09-07 04:29:297676class GLRendererWithSetupQuadForAntialiasing : public GLRenderer {
7677 public:
timav8a72a922014-11-07 00:47:217678 using GLRenderer::ShouldAntialiasQuad;
[email protected]46b79d52013-09-07 04:29:297679};
7680
7681TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
7682 // Due to precision issues (especially on Android), sometimes far
7683 // away quads can end up thinking they need AA.
7684 float device_scale_factor = 4.f / 3.f;
[email protected]46b79d52013-09-07 04:29:297685 gfx::Size root_size(2000, 1000);
7686 gfx::Size device_viewport_size =
danakjddaec912015-09-25 19:38:407687 gfx::ScaleToCeiledSize(root_size, device_scale_factor);
[email protected]46b79d52013-09-07 04:29:297688 host_impl_->SetViewportSize(device_viewport_size);
7689
7690 host_impl_->CreatePendingTree();
ajuma1d48e012015-09-25 22:24:167691 host_impl_->pending_tree()->SetDeviceScaleFactor(device_scale_factor);
aelias58eec0812014-12-04 01:04:407692 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f,
7693 16.f);
[email protected]46b79d52013-09-07 04:29:297694
danakj60bc3bc2016-04-09 00:24:487695 std::unique_ptr<LayerImpl> scoped_root =
[email protected]46b79d52013-09-07 04:29:297696 LayerImpl::Create(host_impl_->pending_tree(), 1);
7697 LayerImpl* root = scoped_root.get();
jaydasika6b5a32bf2016-04-22 21:56:367698 root->test_properties()->force_render_surface = true;
[email protected]46b79d52013-09-07 04:29:297699
jaydasikabf1875a2016-06-28 03:39:597700 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root));
[email protected]46b79d52013-09-07 04:29:297701
danakj60bc3bc2016-04-09 00:24:487702 std::unique_ptr<LayerImpl> scoped_scrolling_layer =
[email protected]46b79d52013-09-07 04:29:297703 LayerImpl::Create(host_impl_->pending_tree(), 2);
7704 LayerImpl* scrolling_layer = scoped_scrolling_layer.get();
jaydasika89f7b5a2016-06-22 02:08:397705 root->test_properties()->AddChild(std::move(scoped_scrolling_layer));
[email protected]46b79d52013-09-07 04:29:297706
7707 gfx::Size content_layer_bounds(100000, 100);
vmpstr41d68f882016-03-30 01:20:237708 scoped_refptr<FakeRasterSource> raster_source(
7709 FakeRasterSource::CreateFilled(content_layer_bounds));
[email protected]46b79d52013-09-07 04:29:297710
danakj60bc3bc2016-04-09 00:24:487711 std::unique_ptr<FakePictureLayerImpl> scoped_content_layer =
hendrikw9d909aa72014-11-11 20:19:527712 FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(),
vmpstr856740262015-09-24 00:25:257713 3, raster_source);
[email protected]46b79d52013-09-07 04:29:297714 LayerImpl* content_layer = scoped_content_layer.get();
jaydasika89f7b5a2016-06-22 02:08:397715 scrolling_layer->test_properties()->AddChild(std::move(scoped_content_layer));
[email protected]46b79d52013-09-07 04:29:297716 content_layer->SetBounds(content_layer_bounds);
7717 content_layer->SetDrawsContent(true);
7718
7719 root->SetBounds(root_size);
7720
miletusf57925d2014-10-01 19:38:137721 gfx::ScrollOffset scroll_offset(100000, 0);
[email protected]adeda572014-01-31 00:49:477722 scrolling_layer->SetScrollClipLayer(root->id());
danakj74af409e2016-07-01 00:41:487723 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
7724
sunxdb7e79432016-03-09 21:13:427725 scrolling_layer->layer_tree_impl()
7726 ->property_trees()
7727 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scrolling_layer->id(),
7728 scroll_offset);
[email protected]fc20d142014-07-01 00:49:157729 host_impl_->ActivateSyncTree();
[email protected]46b79d52013-09-07 04:29:297730
enneaf5bda32015-02-19 01:27:367731 bool update_lcd_text = false;
7732 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
[email protected]46b79d52013-09-07 04:29:297733 ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
7734
7735 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487736 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]46b79d52013-09-07 04:29:297737
7738 ASSERT_EQ(1u, frame.render_passes.size());
7739 ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
weiliangc032e929d2014-09-26 01:55:017740 const DrawQuad* quad = frame.render_passes[0]->quad_list.front();
[email protected]46b79d52013-09-07 04:29:297741
roscaf519af22015-06-17 20:57:107742 bool clipped = false, force_aa = false;
7743 gfx::QuadF device_layer_quad = MathUtil::MapQuad(
danakj64767d902015-06-19 00:10:437744 quad->shared_quad_state->quad_to_target_transform,
danakj5e6ff6d2015-09-05 04:43:447745 gfx::QuadF(gfx::RectF(quad->shared_quad_state->visible_quad_layer_rect)),
7746 &clipped);
roscaf519af22015-06-17 20:57:107747 EXPECT_FALSE(clipped);
[email protected]46b79d52013-09-07 04:29:297748 bool antialiased =
timav8a72a922014-11-07 00:47:217749 GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
roscaf519af22015-06-17 20:57:107750 device_layer_quad, clipped, force_aa);
[email protected]46b79d52013-09-07 04:29:297751 EXPECT_FALSE(antialiased);
7752
mithro248d1722015-05-05 05:23:457753 host_impl_->DrawLayers(&frame);
[email protected]46b79d52013-09-07 04:29:297754 host_impl_->DidDrawAllLayers(frame);
7755}
7756
[email protected]bb1e2822013-04-17 22:06:017757class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
7758 public:
7759 CompositorFrameMetadataTest()
7760 : swap_buffers_complete_(0) {}
7761
dcheng716bedf2014-10-21 09:51:087762 void DidSwapBuffersCompleteOnImplThread() override {
[email protected]bb1e2822013-04-17 22:06:017763 swap_buffers_complete_++;
7764 }
7765
7766 int swap_buffers_complete_;
7767};
7768
7769TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
7770 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:487771 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]bb1e2822013-04-17 22:06:017772 {
7773 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487774 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457775 host_impl_->DrawLayers(&frame);
[email protected]bb1e2822013-04-17 22:06:017776 host_impl_->DidDrawAllLayers(frame);
7777 }
fsamuelb62b78222016-07-15 01:14:147778 host_impl_->ReclaimResources(ReturnedResourceArray());
[email protected]c14902662014-04-18 05:06:117779 host_impl_->DidSwapBuffersComplete();
[email protected]bb1e2822013-04-17 22:06:017780 EXPECT_EQ(swap_buffers_complete_, 1);
7781}
7782
[email protected]fbe89f72013-05-21 07:24:247783class CountingSoftwareDevice : public SoftwareOutputDevice {
7784 public:
7785 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
7786
dcheng716bedf2014-10-21 09:51:087787 SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
[email protected]fbe89f72013-05-21 07:24:247788 ++frames_began_;
7789 return SoftwareOutputDevice::BeginPaint(damage_rect);
7790 }
jbauman95f741352015-08-07 02:10:347791 void EndPaint() override {
7792 SoftwareOutputDevice::EndPaint();
[email protected]fbe89f72013-05-21 07:24:247793 ++frames_ended_;
[email protected]fbe89f72013-05-21 07:24:247794 }
7795
7796 int frames_began_, frames_ended_;
7797};
7798
[email protected]ffbb2212013-06-02 23:47:597799TEST_F(LayerTreeHostImplTest,
7800 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) {
[email protected]50644642013-06-20 13:58:557801 set_reduce_memory_result(false);
danakj6021ec32016-07-22 22:16:087802 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
7803 FakeOutputSurface::CreateDelegatingSoftware()));
[email protected]ffbb2212013-06-02 23:47:597804
[email protected]c05dfbb2014-07-10 22:49:047805 const gfx::Transform external_transform;
7806 const gfx::Rect external_viewport;
[email protected]c05dfbb2014-07-10 22:49:047807 const bool resourceless_software_draw = true;
boliu7097ee5b2015-12-17 03:16:097808 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
7809 external_transform);
[email protected]ffbb2212013-06-02 23:47:597810
7811 // SolidColorLayerImpl will be drawn.
danakj60bc3bc2016-04-09 00:24:487812 std::unique_ptr<SolidColorLayerImpl> root_layer =
[email protected]ffbb2212013-06-02 23:47:597813 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
7814
7815 // VideoLayerImpl will not be drawn.
7816 FakeVideoFrameProvider provider;
danakj60bc3bc2016-04-09 00:24:487817 std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
[email protected]f78c3e82014-08-08 01:24:477818 host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0);
[email protected]ffbb2212013-06-02 23:47:597819 video_layer->SetBounds(gfx::Size(10, 10));
[email protected]ffbb2212013-06-02 23:47:597820 video_layer->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397821 root_layer->test_properties()->AddChild(std::move(video_layer));
danakja04855a2015-11-18 20:39:107822 SetupRootLayerImpl(std::move(root_layer));
danakj74af409e2016-07-01 00:41:487823 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ffbb2212013-06-02 23:47:597824
boliu31c233ed2016-07-29 05:38:597825 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:097826 resourceless_software_draw);
[email protected]ffbb2212013-06-02 23:47:597827
boliu7097ee5b2015-12-17 03:16:097828 EXPECT_EQ(1u, last_on_draw_frame_->will_draw_layers.size());
jaydasikabf1875a2016-06-28 03:39:597829 EXPECT_EQ(host_impl_->active_tree()->root_layer_for_testing(),
boliu7097ee5b2015-12-17 03:16:097830 last_on_draw_frame_->will_draw_layers[0]);
[email protected]ffbb2212013-06-02 23:47:597831}
7832
danakjaa5c4912016-09-10 00:28:237833// Checks that we use the memory limits provided.
7834TEST_F(LayerTreeHostImplTest, MemoryLimits) {
danakjee6547a22016-07-01 20:41:507835 host_impl_->ReleaseOutputSurface();
7836 host_impl_ = nullptr;
7837
danakjaa5c4912016-09-10 00:28:237838 const size_t kGpuByteLimit = 1234321;
7839 const size_t kSoftwareByteLimit = 4321234;
7840 const size_t kGpuResourceLimit = 2345432;
7841 const size_t kSoftwareResourceLimit = 5432345;
7842 const gpu::MemoryAllocation::PriorityCutoff kGpuCutoff =
7843 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
7844 const gpu::MemoryAllocation::PriorityCutoff kSoftwareCutoff =
7845 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
7846
7847 const TileMemoryLimitPolicy kGpuTileCutoff =
7848 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(kGpuCutoff);
7849 const TileMemoryLimitPolicy kSoftwareTileCutoff =
7850 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
7851 kSoftwareCutoff);
7852 const TileMemoryLimitPolicy kNothingTileCutoff =
7853 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
7854 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
7855 EXPECT_NE(kGpuTileCutoff, kNothingTileCutoff);
7856 EXPECT_NE(kSoftwareTileCutoff, kNothingTileCutoff);
7857
weiliangc8f4ef0d2015-11-27 00:15:557858 LayerTreeSettings settings = DefaultSettings();
danakjaa5c4912016-09-10 00:28:237859 settings.gpu_memory_policy =
7860 ManagedMemoryPolicy(kGpuByteLimit, kGpuCutoff, kGpuResourceLimit);
7861 settings.software_memory_policy = ManagedMemoryPolicy(
7862 kSoftwareByteLimit, kSoftwareCutoff, kSoftwareResourceLimit);
reveman34b7a1522015-03-23 20:27:477863 host_impl_ = LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:167864 settings, this, &task_runner_provider_, &stats_instrumentation_,
7865 &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_,
loysoab32ee72016-06-08 03:33:187866 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
[email protected]fd32d122013-06-29 13:11:047867
danakjaa5c4912016-09-10 00:28:237868 // Gpu compositing.
revemand180dfc32015-09-24 00:19:437869 output_surface_ =
danakjf33ceec2016-07-20 20:04:457870 FakeOutputSurface::CreateDelegating3d(TestWebGraphicsContext3D::Create());
sievers71c62dd52015-10-07 01:44:397871 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:437872 host_impl_->InitializeRenderer(output_surface_.get());
danakjaa5c4912016-09-10 00:28:237873 {
7874 const auto& state = host_impl_->global_tile_state();
7875 EXPECT_EQ(kGpuByteLimit, state.hard_memory_limit_in_bytes);
7876 EXPECT_EQ(kGpuResourceLimit, state.num_resources_limit);
7877 EXPECT_EQ(kGpuTileCutoff, state.memory_limit_policy);
7878 }
7879
7880 // Not visible, drops to 0.
7881 host_impl_->SetVisible(false);
7882 {
7883 const auto& state = host_impl_->global_tile_state();
7884 EXPECT_EQ(0u, state.hard_memory_limit_in_bytes);
7885 EXPECT_EQ(kGpuResourceLimit, state.num_resources_limit);
7886 EXPECT_EQ(kNothingTileCutoff, state.memory_limit_policy);
7887 }
7888
7889 // Visible, is the gpu limit again.
7890 host_impl_->SetVisible(true);
7891 {
7892 const auto& state = host_impl_->global_tile_state();
7893 EXPECT_EQ(kGpuByteLimit, state.hard_memory_limit_in_bytes);
7894 EXPECT_EQ(kGpuResourceLimit, state.num_resources_limit);
7895 }
7896
7897 // Software compositing.
7898 host_impl_->ReleaseOutputSurface();
7899 output_surface_ = FakeOutputSurface::CreateDelegatingSoftware();
7900 host_impl_->InitializeRenderer(output_surface_.get());
7901 {
7902 const auto& state = host_impl_->global_tile_state();
7903 EXPECT_EQ(kSoftwareByteLimit, state.hard_memory_limit_in_bytes);
7904 EXPECT_EQ(kSoftwareResourceLimit, state.num_resources_limit);
7905 EXPECT_EQ(kSoftwareTileCutoff, state.memory_limit_policy);
7906 }
7907
7908 // Not visible, drops to 0.
7909 host_impl_->SetVisible(false);
7910 {
7911 const auto& state = host_impl_->global_tile_state();
7912 EXPECT_EQ(0u, state.hard_memory_limit_in_bytes);
7913 EXPECT_EQ(kSoftwareResourceLimit, state.num_resources_limit);
7914 EXPECT_EQ(kNothingTileCutoff, state.memory_limit_policy);
7915 }
7916
7917 // Visible, is the software limit again.
7918 host_impl_->SetVisible(true);
7919 {
7920 const auto& state = host_impl_->global_tile_state();
7921 EXPECT_EQ(kSoftwareByteLimit, state.hard_memory_limit_in_bytes);
7922 EXPECT_EQ(kSoftwareResourceLimit, state.num_resources_limit);
7923 EXPECT_EQ(kSoftwareTileCutoff, state.memory_limit_policy);
7924 }
[email protected]fd32d122013-06-29 13:11:047925}
7926
[email protected]10608052014-05-13 21:30:037927TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) {
7928 ASSERT_TRUE(host_impl_->active_tree());
7929
sohan.jyoti9d1e4202014-09-23 21:02:337930 // RequiresHighResToDraw is set when new output surface is used.
vmpstr61ed94a12014-10-09 04:49:307931 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
sohan.jyoti9d1e4202014-09-23 21:02:337932
vmpstr61ed94a12014-10-09 04:49:307933 host_impl_->ResetRequiresHighResToDraw();
sohan.jyoti9d1e4202014-09-23 21:02:337934
[email protected]10608052014-05-13 21:30:037935 host_impl_->SetVisible(false);
vmpstr61ed94a12014-10-09 04:49:307936 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037937 host_impl_->SetVisible(true);
vmpstr61ed94a12014-10-09 04:49:307938 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037939 host_impl_->SetVisible(false);
vmpstr61ed94a12014-10-09 04:49:307940 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037941
vmpstr61ed94a12014-10-09 04:49:307942 host_impl_->ResetRequiresHighResToDraw();
[email protected]10608052014-05-13 21:30:037943
vmpstr61ed94a12014-10-09 04:49:307944 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037945 host_impl_->SetVisible(true);
vmpstr61ed94a12014-10-09 04:49:307946 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037947}
7948
[email protected]13525d62014-05-20 21:22:047949TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
7950 ASSERT_TRUE(host_impl_->active_tree());
7951 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
7952
sohan.jyoti9d1e4202014-09-23 21:02:337953 // RequiresHighResToDraw is set when new output surface is used.
vmpstr61ed94a12014-10-09 04:49:307954 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
sohan.jyoti9d1e4202014-09-23 21:02:337955
vmpstr61ed94a12014-10-09 04:49:307956 host_impl_->ResetRequiresHighResToDraw();
sohan.jyoti9d1e4202014-09-23 21:02:337957
senorblanco9c04acb2015-05-15 19:41:327958 host_impl_->SetContentIsSuitableForGpuRasterization(true);
7959 host_impl_->SetHasGpuRasterizationTrigger(false);
danakj1a86f6d62016-08-17 20:10:407960 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307961 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
senorblanco9c04acb2015-05-15 19:41:327962 host_impl_->SetHasGpuRasterizationTrigger(true);
danakj1a86f6d62016-08-17 20:10:407963 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307964 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
senorblanco9c04acb2015-05-15 19:41:327965 host_impl_->SetHasGpuRasterizationTrigger(false);
danakj1a86f6d62016-08-17 20:10:407966 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307967 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]13525d62014-05-20 21:22:047968
vmpstr61ed94a12014-10-09 04:49:307969 host_impl_->ResetRequiresHighResToDraw();
[email protected]13525d62014-05-20 21:22:047970
vmpstr61ed94a12014-10-09 04:49:307971 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
senorblanco9c04acb2015-05-15 19:41:327972 host_impl_->SetHasGpuRasterizationTrigger(true);
danakj1a86f6d62016-08-17 20:10:407973 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307974 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]13525d62014-05-20 21:22:047975}
7976
vmiura59ea9b4042014-12-09 20:50:397977class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest {
[email protected]222c6782013-09-05 22:24:497978 public:
danakjaeb95062014-11-14 01:35:367979 void SetUp() override {
danakj431a1202015-06-17 19:09:337980 fake_host_impl_ =
khushalsagarb64b360d2015-10-21 19:25:167981 new FakeLayerTreeHostImpl(LayerTreeSettings(), &task_runner_provider_,
danakj431a1202015-06-17 19:09:337982 &shared_bitmap_manager_, &task_graph_runner_);
[email protected]222c6782013-09-05 22:24:497983 host_impl_.reset(fake_host_impl_);
revemand180dfc32015-09-24 00:19:437984 output_surface_ = CreateOutputSurface();
sievers71c62dd52015-10-07 01:44:397985 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:437986 host_impl_->InitializeRenderer(output_surface_.get());
[email protected]222c6782013-09-05 22:24:497987 host_impl_->SetViewportSize(gfx::Size(10, 10));
7988 }
7989
7990 FakeLayerTreeHostImpl* fake_host_impl_;
7991};
7992
vmiura59ea9b4042014-12-09 20:50:397993TEST_F(LayerTreeHostImplTestPrepareTiles, PrepareTilesWhenInvisible) {
vmiura59ea9b4042014-12-09 20:50:397994 EXPECT_TRUE(fake_host_impl_->prepare_tiles_needed());
sievers71c62dd52015-10-07 01:44:397995 host_impl_->SetVisible(false);
vmiura59ea9b4042014-12-09 20:50:397996 EXPECT_FALSE(fake_host_impl_->prepare_tiles_needed());
sievers71c62dd52015-10-07 01:44:397997 host_impl_->SetVisible(true);
7998 EXPECT_TRUE(fake_host_impl_->prepare_tiles_needed());
[email protected]222c6782013-09-05 22:24:497999}
8000
[email protected]c9280762013-08-01 06:28:578001TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
danakj60bc3bc2016-04-09 00:24:488002 std::unique_ptr<TestWebGraphicsContext3D> context =
[email protected]c9280762013-08-01 06:28:578003 TestWebGraphicsContext3D::Create();
8004 TestWebGraphicsContext3D* context3d = context.get();
danakj60bc3bc2016-04-09 00:24:488005 std::unique_ptr<FakeOutputSurface> output_surface =
danakjf33ceec2016-07-20 20:04:458006 FakeOutputSurface::CreateDelegating3d();
danakja04855a2015-11-18 20:39:108007 CreateHostImpl(DefaultSettings(), std::move(output_surface));
[email protected]c9280762013-08-01 06:28:578008
8009 EXPECT_EQ(0u, context3d->NumTextures());
8010
8011 UIResourceId ui_resource_id = 1;
[email protected]0046982c2014-03-25 22:00:518012 bool is_opaque = false;
8013 UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
[email protected]c9280762013-08-01 06:28:578014 host_impl_->CreateUIResource(ui_resource_id, bitmap);
8015 EXPECT_EQ(1u, context3d->NumTextures());
jbaumanbbd425e2015-05-19 00:33:358016 ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
[email protected]c9280762013-08-01 06:28:578017 EXPECT_NE(0u, id1);
8018
8019 // Multiple requests with the same id is allowed. The previous texture is
8020 // deleted.
8021 host_impl_->CreateUIResource(ui_resource_id, bitmap);
8022 EXPECT_EQ(1u, context3d->NumTextures());
jbaumanbbd425e2015-05-19 00:33:358023 ResourceId id2 = host_impl_->ResourceIdForUIResource(ui_resource_id);
[email protected]c9280762013-08-01 06:28:578024 EXPECT_NE(0u, id2);
8025 EXPECT_NE(id1, id2);
8026
8027 // Deleting invalid UIResourceId is allowed and does not change state.
8028 host_impl_->DeleteUIResource(-1);
8029 EXPECT_EQ(1u, context3d->NumTextures());
8030
8031 // Should return zero for invalid UIResourceId. Number of textures should
8032 // not change.
8033 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
8034 EXPECT_EQ(1u, context3d->NumTextures());
8035
8036 host_impl_->DeleteUIResource(ui_resource_id);
8037 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
8038 EXPECT_EQ(0u, context3d->NumTextures());
8039
8040 // Should not change state for multiple deletion on one UIResourceId
8041 host_impl_->DeleteUIResource(ui_resource_id);
8042 EXPECT_EQ(0u, context3d->NumTextures());
8043}
8044
[email protected]6be50ba82013-11-08 12:04:128045TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
danakj60bc3bc2016-04-09 00:24:488046 std::unique_ptr<TestWebGraphicsContext3D> context =
[email protected]6be50ba82013-11-08 12:04:128047 TestWebGraphicsContext3D::Create();
8048 TestWebGraphicsContext3D* context3d = context.get();
danakjf33ceec2016-07-20 20:04:458049 CreateHostImpl(DefaultSettings(), FakeOutputSurface::CreateDelegating3d());
[email protected]6be50ba82013-11-08 12:04:128050
8051 EXPECT_EQ(0u, context3d->NumTextures());
8052
[email protected]80ee2332014-02-06 18:31:078053 gfx::Size size(4, 4);
8054 // SkImageInfo has no support for ETC1. The |info| below contains the right
8055 // total pixel size for the bitmap but not the right height and width. The
8056 // correct width/height are passed directly to UIResourceBitmap.
[email protected]7bc1c512014-01-23 01:15:278057 SkImageInfo info =
[email protected]80ee2332014-02-06 18:31:078058 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType);
tomhudson992ec28b2016-04-27 16:45:398059 sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::NewAllocate(info, 0, 0));
[email protected]7bc1c512014-01-23 01:15:278060 pixel_ref->setImmutable();
tomhudson992ec28b2016-04-27 16:45:398061 UIResourceBitmap bitmap(std::move(pixel_ref), size);
[email protected]6be50ba82013-11-08 12:04:128062 UIResourceId ui_resource_id = 1;
8063 host_impl_->CreateUIResource(ui_resource_id, bitmap);
8064 EXPECT_EQ(1u, context3d->NumTextures());
jbaumanbbd425e2015-05-19 00:33:358065 ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
[email protected]6be50ba82013-11-08 12:04:128066 EXPECT_NE(0u, id1);
8067}
8068
danakj60bc3bc2016-04-09 00:24:488069void ShutdownReleasesContext_Callback(
8070 std::unique_ptr<CopyOutputResult> result) {}
[email protected]ea468c6c2013-09-10 08:25:118071
8072TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
8073 scoped_refptr<TestContextProvider> context_provider =
8074 TestContextProvider::Create();
8075
danakjf33ceec2016-07-20 20:04:458076 CreateHostImpl(
8077 DefaultSettings(),
8078 base::MakeUnique<TestDelegatingOutputSurface>(
8079 context_provider, TestContextProvider::CreateWorker(),
8080 FakeOutputSurface::Create3d(context_provider), nullptr, nullptr,
8081 RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(),
danakj014316e2016-08-04 18:40:268082 true /* synchronous_composite */,
8083 false /* force_disable_reclaim_resources */));
[email protected]ea468c6c2013-09-10 08:25:118084
8085 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
8086
jaydasikabf1875a2016-06-28 03:39:598087 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
ajumae6f541b2016-05-31 16:50:508088 root->test_properties()->copy_requests.push_back(
8089 CopyOutputRequest::CreateRequest(
8090 base::Bind(&ShutdownReleasesContext_Callback)));
danakj74af409e2016-07-01 00:41:488091 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ea468c6c2013-09-10 08:25:118092
8093 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:488094 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:458095 host_impl_->DrawLayers(&frame);
[email protected]ea468c6c2013-09-10 08:25:118096 host_impl_->DidDrawAllLayers(frame);
[email protected]ea468c6c2013-09-10 08:25:118097
8098 // The CopyOutputResult's callback has a ref on the ContextProvider and a
8099 // texture in a texture mailbox.
8100 EXPECT_FALSE(context_provider->HasOneRef());
8101 EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
8102
danakjee6547a22016-07-01 20:41:508103 host_impl_->ReleaseOutputSurface();
danakjf446a072014-09-27 21:55:488104 host_impl_ = nullptr;
[email protected]ea468c6c2013-09-10 08:25:118105
8106 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
8107 // released, and the texture deleted.
8108 EXPECT_TRUE(context_provider->HasOneRef());
8109 EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
8110}
8111
[email protected]df0c42342013-10-08 20:52:128112TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) {
8113 // When flinging via touch, only the child should scroll (we should not
8114 // bubble).
8115 gfx::Size surface_size(10, 10);
8116 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:488117 std::unique_ptr<LayerImpl> root_ptr =
sunxd676696572016-01-07 16:28:308118 LayerImpl::Create(host_impl_->active_tree(), 4);
danakj60bc3bc2016-04-09 00:24:488119 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:478120 LayerImpl::Create(host_impl_->active_tree(), 3);
jaydasika6b5a32bf2016-04-22 21:56:368121 root_clip->test_properties()->force_render_surface = true;
awoloszyne83f28c2014-12-22 15:40:008122
danakj60bc3bc2016-04-09 00:24:488123 std::unique_ptr<LayerImpl> root_scroll =
[email protected]adeda572014-01-31 00:49:478124 CreateScrollableLayer(1, content_size, root_clip.get());
jaydasikaca2605e2016-04-23 02:52:528125 root_scroll->test_properties()->is_container_for_fixed_position_layers = true;
danakj60bc3bc2016-04-09 00:24:488126 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:478127 CreateScrollableLayer(2, content_size, root_clip.get());
[email protected]df0c42342013-10-08 20:52:128128
jaydasika89f7b5a2016-06-22 02:08:398129 root_scroll->test_properties()->AddChild(std::move(child));
sunxd676696572016-01-07 16:28:308130 int root_id = root_scroll->id();
jaydasika89f7b5a2016-06-22 02:08:398131 root_clip->test_properties()->AddChild(std::move(root_scroll));
8132 root_ptr->test_properties()->AddChild(std::move(root_clip));
[email protected]df0c42342013-10-08 20:52:128133
8134 host_impl_->SetViewportSize(surface_size);
jaydasikabf1875a2016-06-28 03:39:598135 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
sunxd676696572016-01-07 16:28:308136 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 1,
ccameron8230b68b2014-11-21 19:25:188137 Layer::INVALID_ID);
danakj74af409e2016-07-01 00:41:488138 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]df0c42342013-10-08 20:52:128139 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:368140 DrawFrame();
[email protected]df0c42342013-10-08 20:52:128141 {
tdresser81e84c672016-01-18 23:21:228142 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038143 host_impl_
8144 ->ScrollBegin(BeginState(gfx::Point()).get(),
8145 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228146 .thread);
[email protected]df0c42342013-10-08 20:52:128147
tdresser81e84c672016-01-18 23:21:228148 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
8149 host_impl_->FlingScrollBegin().thread);
[email protected]df0c42342013-10-08 20:52:128150
8151 gfx::Vector2d scroll_delta(0, 100);
majidvp944a8cd2016-01-12 21:05:188152 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
8153 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]df0c42342013-10-08 20:52:128154
majidvp944a8cd2016-01-12 21:05:188155 host_impl_->ScrollEnd(EndState().get());
[email protected]df0c42342013-10-08 20:52:128156
danakj60bc3bc2016-04-09 00:24:488157 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]df0c42342013-10-08 20:52:128158 host_impl_->ProcessScrollDeltas();
8159
8160 // Only the child should have scrolled.
8161 ASSERT_EQ(1u, scroll_info->scrolls.size());
[email protected]adeda572014-01-31 00:49:478162 ExpectNone(*scroll_info.get(), root_id);
[email protected]df0c42342013-10-08 20:52:128163 }
8164}
8165
tdressera3b162b82015-09-29 17:51:438166TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) {
[email protected]db102612013-12-20 22:04:128167 // Scroll a child layer beyond its maximum scroll range and make sure the
8168 // the scroll doesn't bubble up to the parent layer.
[email protected]d41d7cb92013-10-15 16:08:098169 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:488170 std::unique_ptr<LayerImpl> root =
8171 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika6b5a32bf2016-04-22 21:56:368172 root->test_properties()->force_render_surface = true;
[email protected]d41d7cb92013-10-15 16:08:098173
danakj74af409e2016-07-01 00:41:488174 std::unique_ptr<LayerImpl> root_scrolling_owned =
8175 CreateScrollableLayer(2, surface_size, root.get());
8176 auto* root_scrolling = root_scrolling_owned.get();
8177 root->test_properties()->AddChild(std::move(root_scrolling_owned));
8178
8179 std::unique_ptr<LayerImpl> child_owned =
8180 CreateScrollableLayer(3, surface_size, root.get());
8181 auto* child = child_owned.get();
8182 root_scrolling->test_properties()->AddChild(std::move(child_owned));
8183
8184 std::unique_ptr<LayerImpl> grand_child_owned =
[email protected]adeda572014-01-31 00:49:478185 CreateScrollableLayer(4, surface_size, root.get());
danakj74af409e2016-07-01 00:41:488186 auto* grand_child = grand_child_owned.get();
8187 child->test_properties()->AddChild(std::move(grand_child_owned));
8188
8189 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
8190 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8191 host_impl_->active_tree()->DidBecomeActive();
8192
8193 child->layer_tree_impl()
8194 ->property_trees()
8195 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child->id(),
8196 gfx::ScrollOffset(0, 4));
sunxdb7e79432016-03-09 21:13:428197 grand_child->layer_tree_impl()
8198 ->property_trees()
8199 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->id(),
8200 gfx::ScrollOffset(0, 2));
[email protected]d41d7cb92013-10-15 16:08:098201
[email protected]db102612013-12-20 22:04:128202 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:368203 DrawFrame();
[email protected]d41d7cb92013-10-15 16:08:098204 {
danakj60bc3bc2016-04-09 00:24:488205 std::unique_ptr<ScrollAndScaleSet> scroll_info;
jaydasikafc66cfb2016-06-10 04:34:228206 LayerImpl* child = host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:598207 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:228208 ->test_properties()
8209 ->children[0]
8210 ->test_properties()
8211 ->children[0];
8212 LayerImpl* grand_child = child->test_properties()->children[0];
[email protected]db102612013-12-20 22:04:128213
8214 gfx::Vector2d scroll_delta(0, -2);
tdresser81e84c672016-01-18 23:21:228215 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038216 host_impl_
8217 ->ScrollBegin(BeginState(gfx::Point()).get(),
8218 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228219 .thread);
majidvp944a8cd2016-01-12 21:05:188220 EXPECT_TRUE(
8221 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8222 .did_scroll);
[email protected]d41d7cb92013-10-15 16:08:098223
[email protected]db102612013-12-20 22:04:128224 // The grand child should have scrolled up to its limit.
[email protected]d41d7cb92013-10-15 16:08:098225 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]db102612013-12-20 22:04:128226 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:188227 EXPECT_TRUE(
8228 ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
[email protected]db102612013-12-20 22:04:128229 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
8230
tdressera3b162b82015-09-29 17:51:438231 // The locked scrolling layer should remain set as the grand child.
majidvp944a8cd2016-01-12 21:05:188232 EXPECT_FALSE(
8233 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8234 .did_scroll);
[email protected]db102612013-12-20 22:04:128235 scroll_info = host_impl_->ProcessScrollDeltas();
tdressera3b162b82015-09-29 17:51:438236 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:188237 EXPECT_TRUE(
8238 ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
tdressera3b162b82015-09-29 17:51:438239 ExpectNone(*scroll_info, child->id());
[email protected]db102612013-12-20 22:04:128240 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
8241
tdresser81e84c672016-01-18 23:21:228242 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
8243 host_impl_->FlingScrollBegin().thread);
majidvp944a8cd2016-01-12 21:05:188244 EXPECT_FALSE(
8245 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8246 .did_scroll);
tdressera3b162b82015-09-29 17:51:438247 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
[email protected]db102612013-12-20 22:04:128248
tdressera3b162b82015-09-29 17:51:438249 // The child should not have scrolled.
[email protected]db102612013-12-20 22:04:128250 scroll_info = host_impl_->ProcessScrollDeltas();
tdressera3b162b82015-09-29 17:51:438251 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:188252 EXPECT_TRUE(
8253 ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
tdressera3b162b82015-09-29 17:51:438254 ExpectNone(*scroll_info, child->id());
[email protected]db102612013-12-20 22:04:128255
8256 // As the locked layer is at it's limit, no further scrolling can occur.
majidvp944a8cd2016-01-12 21:05:188257 EXPECT_FALSE(
8258 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8259 .did_scroll);
tdressera3b162b82015-09-29 17:51:438260 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:188261 host_impl_->ScrollEnd(EndState().get());
[email protected]d41d7cb92013-10-15 16:08:098262 }
8263}
8264
tdressera3b162b82015-09-29 17:51:438265TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) {
8266 // When flinging via wheel, we shouldn't bubble.
[email protected]df0c42342013-10-08 20:52:128267 gfx::Size surface_size(10, 10);
8268 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:488269 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:478270 LayerImpl::Create(host_impl_->active_tree(), 3);
jaydasika6b5a32bf2016-04-22 21:56:368271 root_clip->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:488272 std::unique_ptr<LayerImpl> root_scroll =
[email protected]adeda572014-01-31 00:49:478273 CreateScrollableLayer(1, content_size, root_clip.get());
8274 int root_scroll_id = root_scroll->id();
danakj60bc3bc2016-04-09 00:24:488275 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:478276 CreateScrollableLayer(2, content_size, root_clip.get());
[email protected]df0c42342013-10-08 20:52:128277
jaydasika89f7b5a2016-06-22 02:08:398278 root_scroll->test_properties()->AddChild(std::move(child));
8279 root_clip->test_properties()->AddChild(std::move(root_scroll));
[email protected]df0c42342013-10-08 20:52:128280
jaydasikabf1875a2016-06-28 03:39:598281 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip));
danakj74af409e2016-07-01 00:41:488282 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]df0c42342013-10-08 20:52:128283 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:488284
8285 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:368286 DrawFrame();
[email protected]df0c42342013-10-08 20:52:128287 {
tdresser81e84c672016-01-18 23:21:228288 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188289 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228290 InputHandler::WHEEL)
8291 .thread);
[email protected]df0c42342013-10-08 20:52:128292
tdresser81e84c672016-01-18 23:21:228293 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
8294 host_impl_->FlingScrollBegin().thread);
[email protected]df0c42342013-10-08 20:52:128295
8296 gfx::Vector2d scroll_delta(0, 100);
majidvp944a8cd2016-01-12 21:05:188297 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
8298 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]df0c42342013-10-08 20:52:128299
majidvp944a8cd2016-01-12 21:05:188300 host_impl_->ScrollEnd(EndState().get());
[email protected]df0c42342013-10-08 20:52:128301
danakj60bc3bc2016-04-09 00:24:488302 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]df0c42342013-10-08 20:52:128303 host_impl_->ProcessScrollDeltas();
8304
tdressera3b162b82015-09-29 17:51:438305 // The root shouldn't have scrolled.
8306 ASSERT_EQ(1u, scroll_info->scrolls.size());
8307 ExpectNone(*scroll_info.get(), root_scroll_id);
[email protected]df0c42342013-10-08 20:52:128308 }
8309}
8310
[email protected]05ba53c2014-04-16 21:22:518311TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) {
8312 // If we ray cast a scroller that is not on the first layer's ancestor chain,
ericrk7c030992015-02-20 01:39:388313 // we should return SCROLL_UNKNOWN.
[email protected]05ba53c2014-04-16 21:22:518314 gfx::Size content_size(100, 100);
8315 SetupScrollAndContentsLayers(content_size);
8316
8317 int scroll_layer_id = 2;
8318 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108319 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]05ba53c2014-04-16 21:22:518320 scroll_layer->SetDrawsContent(true);
8321
8322 int page_scale_layer_id = 5;
8323 LayerImpl* page_scale_layer =
vollickcb3f6b12016-03-01 23:44:108324 host_impl_->active_tree()->LayerById(page_scale_layer_id);
[email protected]05ba53c2014-04-16 21:22:518325
8326 int occluder_layer_id = 6;
danakj60bc3bc2016-04-09 00:24:488327 std::unique_ptr<LayerImpl> occluder_layer =
[email protected]05ba53c2014-04-16 21:22:518328 LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
8329 occluder_layer->SetDrawsContent(true);
8330 occluder_layer->SetBounds(content_size);
[email protected]05ba53c2014-04-16 21:22:518331 occluder_layer->SetPosition(gfx::PointF());
[email protected]05ba53c2014-04-16 21:22:518332
8333 // The parent of the occluder is *above* the scroller.
jaydasika89f7b5a2016-06-22 02:08:398334 page_scale_layer->test_properties()->AddChild(std::move(occluder_layer));
danakj74af409e2016-07-01 00:41:488335 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]05ba53c2014-04-16 21:22:518336
8337 DrawFrame();
8338
tdresser81e84c672016-01-18 23:21:228339 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
8340 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
8341 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
danakj35904762016-01-21 20:49:408342 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
tdresser81e84c672016-01-18 23:21:228343 status.main_thread_scrolling_reasons);
[email protected]05ba53c2014-04-16 21:22:518344}
8345
8346TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
8347 // If we ray cast a scroller this is on the first layer's ancestor chain, but
8348 // is not the first scroller we encounter when walking up from the layer, we
ericrk7c030992015-02-20 01:39:388349 // should also return SCROLL_UNKNOWN.
[email protected]05ba53c2014-04-16 21:22:518350 gfx::Size content_size(100, 100);
8351 SetupScrollAndContentsLayers(content_size);
8352
8353 int scroll_layer_id = 2;
8354 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108355 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]05ba53c2014-04-16 21:22:518356 scroll_layer->SetDrawsContent(true);
8357
8358 int occluder_layer_id = 6;
danakj60bc3bc2016-04-09 00:24:488359 std::unique_ptr<LayerImpl> occluder_layer =
[email protected]05ba53c2014-04-16 21:22:518360 LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
8361 occluder_layer->SetDrawsContent(true);
8362 occluder_layer->SetBounds(content_size);
[email protected]28336d52014-05-12 19:07:288363 occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f));
[email protected]05ba53c2014-04-16 21:22:518364
8365 int child_scroll_clip_layer_id = 7;
danakj60bc3bc2016-04-09 00:24:488366 std::unique_ptr<LayerImpl> child_scroll_clip =
[email protected]05ba53c2014-04-16 21:22:518367 LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id);
8368
8369 int child_scroll_layer_id = 8;
danakj60bc3bc2016-04-09 00:24:488370 std::unique_ptr<LayerImpl> child_scroll = CreateScrollableLayer(
[email protected]05ba53c2014-04-16 21:22:518371 child_scroll_layer_id, content_size, child_scroll_clip.get());
8372
[email protected]28336d52014-05-12 19:07:288373 child_scroll->SetPosition(gfx::PointF(10.f, 10.f));
[email protected]05ba53c2014-04-16 21:22:518374
jaydasika89f7b5a2016-06-22 02:08:398375 child_scroll->test_properties()->AddChild(std::move(occluder_layer));
8376 child_scroll_clip->test_properties()->AddChild(std::move(child_scroll));
8377 scroll_layer->test_properties()->AddChild(std::move(child_scroll_clip));
danakj74af409e2016-07-01 00:41:488378 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]05ba53c2014-04-16 21:22:518379
8380 DrawFrame();
8381
tdresser81e84c672016-01-18 23:21:228382 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
8383 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
8384 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
danakj35904762016-01-21 20:49:408385 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
tdresser81e84c672016-01-18 23:21:228386 status.main_thread_scrolling_reasons);
[email protected]05ba53c2014-04-16 21:22:518387}
8388
majidvp6cfcc362015-03-06 20:46:398389TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) {
[email protected]28336d52014-05-12 19:07:288390 gfx::Size content_size(100, 100);
8391 SetupScrollAndContentsLayers(content_size);
8392
vollickcb3f6b12016-03-01 23:44:108393 LayerImpl* root = host_impl_->active_tree()->LayerById(1);
[email protected]28336d52014-05-12 19:07:288394
8395 int scroll_layer_id = 2;
8396 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108397 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]28336d52014-05-12 19:07:288398
8399 int child_scroll_layer_id = 7;
danakj60bc3bc2016-04-09 00:24:488400 std::unique_ptr<LayerImpl> child_scroll =
[email protected]28336d52014-05-12 19:07:288401 CreateScrollableLayer(child_scroll_layer_id, content_size, root);
8402 child_scroll->SetDrawsContent(false);
8403
jaydasika89f7b5a2016-06-22 02:08:398404 scroll_layer->test_properties()->AddChild(std::move(child_scroll));
danakj74af409e2016-07-01 00:41:488405 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]28336d52014-05-12 19:07:288406
8407 DrawFrame();
8408
8409 // We should not have scrolled |child_scroll| even though we technically "hit"
8410 // it. The reason for this is that if the scrolling the scroll would not move
8411 // any layer that is a drawn RSLL member, then we can ignore the hit.
8412 //
ericrk7c030992015-02-20 01:39:388413 // Why SCROLL_STARTED? In this case, it's because we've bubbled out and
majidvp6cfcc362015-03-06 20:46:398414 // started scrolling the inner viewport.
tdresser81e84c672016-01-18 23:21:228415 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188416 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228417 InputHandler::WHEEL)
8418 .thread);
[email protected]28336d52014-05-12 19:07:288419
8420 EXPECT_EQ(2, host_impl_->CurrentlyScrollingLayer()->id());
8421}
8422
majidvp6cfcc362015-03-06 20:46:398423TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleDescendent) {
8424 gfx::Size content_size(100, 100);
8425 SetupScrollAndContentsLayers(content_size);
8426
vollickcb3f6b12016-03-01 23:44:108427 LayerImpl* root = host_impl_->active_tree()->LayerById(1);
8428 LayerImpl* root_scroll_layer = host_impl_->active_tree()->LayerById(2);
majidvp6cfcc362015-03-06 20:46:398429
danakj60bc3bc2016-04-09 00:24:488430 std::unique_ptr<LayerImpl> invisible_scroll_layer =
majidvp6cfcc362015-03-06 20:46:398431 CreateScrollableLayer(7, content_size, root);
8432 invisible_scroll_layer->SetDrawsContent(false);
8433
danakj60bc3bc2016-04-09 00:24:488434 std::unique_ptr<LayerImpl> child_layer =
majidvp6cfcc362015-03-06 20:46:398435 LayerImpl::Create(host_impl_->active_tree(), 8);
8436 child_layer->SetDrawsContent(false);
8437
danakj60bc3bc2016-04-09 00:24:488438 std::unique_ptr<LayerImpl> grand_child_layer =
majidvp6cfcc362015-03-06 20:46:398439 LayerImpl::Create(host_impl_->active_tree(), 9);
8440 grand_child_layer->SetDrawsContent(true);
8441 grand_child_layer->SetBounds(content_size);
majidvp6cfcc362015-03-06 20:46:398442 // Move the grand child so it's not hit by our test point.
8443 grand_child_layer->SetPosition(gfx::PointF(10.f, 10.f));
8444
jaydasika89f7b5a2016-06-22 02:08:398445 child_layer->test_properties()->AddChild(std::move(grand_child_layer));
8446 invisible_scroll_layer->test_properties()->AddChild(std::move(child_layer));
8447 root_scroll_layer->test_properties()->AddChild(
8448 std::move(invisible_scroll_layer));
danakj74af409e2016-07-01 00:41:488449 host_impl_->active_tree()->BuildPropertyTreesForTesting();
majidvp6cfcc362015-03-06 20:46:398450
8451 DrawFrame();
8452
8453 // We should have scrolled |invisible_scroll_layer| as it was hit and it has
8454 // a descendant which is a drawn RSLL member.
tdresser81e84c672016-01-18 23:21:228455 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188456 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228457 InputHandler::WHEEL)
8458 .thread);
majidvp6cfcc362015-03-06 20:46:398459
8460 EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id());
8461}
8462
[email protected]28336d52014-05-12 19:07:288463TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) {
8464 // This test case is very similar to the one above with one key difference:
8465 // the invisible scroller has a scroll child that is indeed draw contents.
8466 // If we attempt to initiate a gesture scroll off of the visible scroll child
8467 // we should still start the scroll child.
8468 gfx::Size content_size(100, 100);
8469 SetupScrollAndContentsLayers(content_size);
8470
vollickcb3f6b12016-03-01 23:44:108471 LayerImpl* root = host_impl_->active_tree()->LayerById(1);
[email protected]28336d52014-05-12 19:07:288472
8473 int scroll_layer_id = 2;
8474 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108475 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]28336d52014-05-12 19:07:288476
8477 int scroll_child_id = 6;
danakj60bc3bc2016-04-09 00:24:488478 std::unique_ptr<LayerImpl> scroll_child =
[email protected]28336d52014-05-12 19:07:288479 LayerImpl::Create(host_impl_->active_tree(), scroll_child_id);
8480 scroll_child->SetDrawsContent(true);
8481 scroll_child->SetBounds(content_size);
[email protected]28336d52014-05-12 19:07:288482 // Move the scroll child so it's not hit by our test point.
8483 scroll_child->SetPosition(gfx::PointF(10.f, 10.f));
[email protected]28336d52014-05-12 19:07:288484
8485 int invisible_scroll_layer_id = 7;
danakj60bc3bc2016-04-09 00:24:488486 std::unique_ptr<LayerImpl> invisible_scroll =
[email protected]28336d52014-05-12 19:07:288487 CreateScrollableLayer(invisible_scroll_layer_id, content_size, root);
8488 invisible_scroll->SetDrawsContent(false);
8489
8490 int container_id = 8;
danakj60bc3bc2016-04-09 00:24:488491 std::unique_ptr<LayerImpl> container =
[email protected]28336d52014-05-12 19:07:288492 LayerImpl::Create(host_impl_->active_tree(), container_id);
8493
danakj60bc3bc2016-04-09 00:24:488494 std::unique_ptr<std::set<LayerImpl*>> scroll_children(
8495 new std::set<LayerImpl*>);
[email protected]28336d52014-05-12 19:07:288496 scroll_children->insert(scroll_child.get());
jaydasika1c0a27d42016-04-28 01:54:568497 invisible_scroll->test_properties()->scroll_children.reset(
8498 scroll_children.release());
[email protected]28336d52014-05-12 19:07:288499
jaydasika1c0a27d42016-04-28 01:54:568500 scroll_child->test_properties()->scroll_parent = invisible_scroll.get();
[email protected]28336d52014-05-12 19:07:288501
jaydasika89f7b5a2016-06-22 02:08:398502 container->test_properties()->AddChild(std::move(invisible_scroll));
8503 container->test_properties()->AddChild(std::move(scroll_child));
[email protected]28336d52014-05-12 19:07:288504
jaydasika89f7b5a2016-06-22 02:08:398505 scroll_layer->test_properties()->AddChild(std::move(container));
danakj74af409e2016-07-01 00:41:488506 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]28336d52014-05-12 19:07:288507
8508 DrawFrame();
8509
majidvp6cfcc362015-03-06 20:46:398510 // We should have scrolled |child_scroll| even though it is invisible.
8511 // The reason for this is that if the scrolling the scroll would move a layer
8512 // that is a drawn RSLL member, then we should accept this hit.
tdresser81e84c672016-01-18 23:21:228513 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188514 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228515 InputHandler::WHEEL)
8516 .thread);
[email protected]28336d52014-05-12 19:07:288517
8518 EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id());
8519}
8520
[email protected]d359203a2013-11-29 06:16:558521// Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
danakjaecfcfba2016-09-07 22:33:188522// in CompositorFrameMetadata.
[email protected]d359203a2013-11-29 06:16:558523TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
danakj60bc3bc2016-04-09 00:24:488524 std::unique_ptr<SolidColorLayerImpl> root =
[email protected]d359203a2013-11-29 06:16:558525 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]d359203a2013-11-29 06:16:558526 root->SetPosition(gfx::PointF());
8527 root->SetBounds(gfx::Size(10, 10));
[email protected]d359203a2013-11-29 06:16:558528 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:368529 root->test_properties()->force_render_surface = true;
[email protected]d359203a2013-11-29 06:16:558530
jaydasikabf1875a2016-06-28 03:39:598531 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:488532 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]d359203a2013-11-29 06:16:558533
8534 FakeOutputSurface* fake_output_surface =
8535 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
8536
[email protected]d359203a2013-11-29 06:16:558537 ui::LatencyInfo latency_info;
8538 latency_info.AddLatencyNumber(
8539 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0);
danakj60bc3bc2016-04-09 00:24:488540 std::unique_ptr<SwapPromise> swap_promise(
[email protected]6be422b2013-12-08 06:47:318541 new LatencyInfoSwapPromise(latency_info));
danakja04855a2015-11-18 20:39:108542 host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
[email protected]d359203a2013-11-29 06:16:558543
8544 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
8545 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:488546 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjaecfcfba2016-09-07 22:33:188547 EXPECT_TRUE(host_impl_->DrawLayers(&frame));
[email protected]d359203a2013-11-29 06:16:558548 host_impl_->DidDrawAllLayers(frame);
[email protected]d359203a2013-11-29 06:16:558549
[email protected]b76029b2014-01-02 22:56:508550 const std::vector<ui::LatencyInfo>& metadata_latency_after =
fsamueld63137a2016-06-24 23:39:518551 fake_output_surface->last_sent_frame()->metadata.latency_info;
[email protected]b76029b2014-01-02 22:56:508552 EXPECT_EQ(1u, metadata_latency_after.size());
8553 EXPECT_TRUE(metadata_latency_after[0].FindLatency(
[email protected]d359203a2013-11-29 06:16:558554 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL));
8555}
8556
[email protected]19aec372014-07-01 19:08:498557TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
8558 int root_layer_id = 1;
danakj60bc3bc2016-04-09 00:24:488559 std::unique_ptr<SolidColorLayerImpl> root =
[email protected]19aec372014-07-01 19:08:498560 SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
8561 root->SetPosition(gfx::PointF());
8562 root->SetBounds(gfx::Size(10, 10));
[email protected]19aec372014-07-01 19:08:498563 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:368564 root->test_properties()->force_render_surface = true;
[email protected]19aec372014-07-01 19:08:498565
jaydasikabf1875a2016-06-28 03:39:598566 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:488567 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]19aec372014-07-01 19:08:498568
8569 // Ensure the default frame selection bounds are empty.
8570 FakeOutputSurface* fake_output_surface =
8571 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
[email protected]19aec372014-07-01 19:08:498572
8573 // Plumb the layer-local selection bounds.
danakja2fdbc702015-10-20 23:05:248574 gfx::Point selection_top(5, 0);
8575 gfx::Point selection_bottom(5, 5);
jdduke449b5292015-04-23 19:36:448576 LayerSelection selection;
fsamuel5ca57df2016-06-04 00:34:558577 selection.start.type = gfx::SelectionBound::CENTER;
jdduke449b5292015-04-23 19:36:448578 selection.start.layer_id = root_layer_id;
8579 selection.start.edge_bottom = selection_bottom;
8580 selection.start.edge_top = selection_top;
8581 selection.end = selection.start;
8582 host_impl_->active_tree()->RegisterSelection(selection);
[email protected]19aec372014-07-01 19:08:498583
8584 // Trigger a draw-swap sequence.
8585 host_impl_->SetNeedsRedraw();
8586
8587 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
8588 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:488589 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjaecfcfba2016-09-07 22:33:188590 EXPECT_TRUE(host_impl_->DrawLayers(&frame));
[email protected]19aec372014-07-01 19:08:498591 host_impl_->DidDrawAllLayers(frame);
[email protected]19aec372014-07-01 19:08:498592
8593 // Ensure the selection bounds have propagated to the frame metadata.
fsamuel5ca57df2016-06-04 00:34:558594 const Selection<gfx::SelectionBound>& selection_after =
fsamueld63137a2016-06-24 23:39:518595 fake_output_surface->last_sent_frame()->metadata.selection;
fsamuel5ca57df2016-06-04 00:34:558596 EXPECT_EQ(selection.start.type, selection_after.start.type());
8597 EXPECT_EQ(selection.end.type, selection_after.end.type());
8598 EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom());
8599 EXPECT_EQ(gfx::PointF(selection_top), selection_after.start.edge_top());
8600 EXPECT_TRUE(selection_after.start.visible());
8601 EXPECT_TRUE(selection_after.start.visible());
[email protected]19aec372014-07-01 19:08:498602}
8603
[email protected]6be422b2013-12-08 06:47:318604class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
8605 public:
8606 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
8607 LayerTreeHostImpl* layer_tree_host_impl,
8608 int* set_needs_commit_count,
[email protected]dab0a422014-08-13 16:09:468609 int* set_needs_redraw_count,
8610 int* forward_to_main_count)
[email protected]6be422b2013-12-08 06:47:318611 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
8612 set_needs_commit_count_(set_needs_commit_count),
[email protected]dab0a422014-08-13 16:09:468613 set_needs_redraw_count_(set_needs_redraw_count),
8614 forward_to_main_count_(forward_to_main_count) {}
[email protected]6be422b2013-12-08 06:47:318615
dcheng716bedf2014-10-21 09:51:088616 ~SimpleSwapPromiseMonitor() override {}
[email protected]6be422b2013-12-08 06:47:318617
dcheng716bedf2014-10-21 09:51:088618 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
[email protected]6be422b2013-12-08 06:47:318619
dcheng716bedf2014-10-21 09:51:088620 void OnSetNeedsRedrawOnImpl() override { (*set_needs_redraw_count_)++; }
[email protected]6be422b2013-12-08 06:47:318621
dcheng716bedf2014-10-21 09:51:088622 void OnForwardScrollUpdateToMainThreadOnImpl() override {
[email protected]dab0a422014-08-13 16:09:468623 (*forward_to_main_count_)++;
8624 }
8625
[email protected]6be422b2013-12-08 06:47:318626 private:
8627 int* set_needs_commit_count_;
8628 int* set_needs_redraw_count_;
[email protected]dab0a422014-08-13 16:09:468629 int* forward_to_main_count_;
[email protected]6be422b2013-12-08 06:47:318630};
8631
8632TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) {
8633 int set_needs_commit_count = 0;
8634 int set_needs_redraw_count = 0;
[email protected]dab0a422014-08-13 16:09:468635 int forward_to_main_count = 0;
[email protected]6be422b2013-12-08 06:47:318636
8637 {
danakj60bc3bc2016-04-09 00:24:488638 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8639 new SimpleSwapPromiseMonitor(
8640 NULL, host_impl_.get(), &set_needs_commit_count,
8641 &set_needs_redraw_count, &forward_to_main_count));
[email protected]6be422b2013-12-08 06:47:318642 host_impl_->SetNeedsRedraw();
8643 EXPECT_EQ(0, set_needs_commit_count);
8644 EXPECT_EQ(1, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468645 EXPECT_EQ(0, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318646 }
8647
8648 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
8649 // monitored.
8650 host_impl_->SetNeedsRedraw();
8651 EXPECT_EQ(0, set_needs_commit_count);
8652 EXPECT_EQ(1, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468653 EXPECT_EQ(0, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318654
8655 {
danakj60bc3bc2016-04-09 00:24:488656 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8657 new SimpleSwapPromiseMonitor(
8658 NULL, host_impl_.get(), &set_needs_commit_count,
8659 &set_needs_redraw_count, &forward_to_main_count));
[email protected]6be422b2013-12-08 06:47:318660 host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10));
8661 EXPECT_EQ(0, set_needs_commit_count);
8662 EXPECT_EQ(2, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468663 EXPECT_EQ(0, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318664 }
8665
8666 {
danakj60bc3bc2016-04-09 00:24:488667 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8668 new SimpleSwapPromiseMonitor(
8669 NULL, host_impl_.get(), &set_needs_commit_count,
8670 &set_needs_redraw_count, &forward_to_main_count));
[email protected]6be422b2013-12-08 06:47:318671 // Empty damage rect won't signal the monitor.
8672 host_impl_->SetNeedsRedrawRect(gfx::Rect());
8673 EXPECT_EQ(0, set_needs_commit_count);
8674 EXPECT_EQ(2, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468675 EXPECT_EQ(0, forward_to_main_count);
8676 }
8677
8678 {
8679 set_needs_commit_count = 0;
8680 set_needs_redraw_count = 0;
8681 forward_to_main_count = 0;
danakj60bc3bc2016-04-09 00:24:488682 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8683 new SimpleSwapPromiseMonitor(
8684 NULL, host_impl_.get(), &set_needs_commit_count,
8685 &set_needs_redraw_count, &forward_to_main_count));
dtapuskaf024e552016-02-03 01:19:468686 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]dab0a422014-08-13 16:09:468687
8688 // Scrolling normally should not trigger any forwarding.
tdresser81e84c672016-01-18 23:21:228689 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038690 host_impl_
8691 ->ScrollBegin(BeginState(gfx::Point()).get(),
8692 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228693 .thread);
ccameron36d091f2014-11-07 03:18:508694 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188695 host_impl_->ScrollBy(
8696 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
8697 .did_scroll);
8698 host_impl_->ScrollEnd(EndState().get());
[email protected]dab0a422014-08-13 16:09:468699
8700 EXPECT_EQ(0, set_needs_commit_count);
8701 EXPECT_EQ(1, set_needs_redraw_count);
8702 EXPECT_EQ(0, forward_to_main_count);
8703
8704 // Scrolling with a scroll handler should defer the swap to the main
8705 // thread.
dtapuskaf024e552016-02-03 01:19:468706 host_impl_->active_tree()->set_have_scroll_event_handlers(true);
tdresser81e84c672016-01-18 23:21:228707 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038708 host_impl_
8709 ->ScrollBegin(BeginState(gfx::Point()).get(),
8710 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228711 .thread);
ccameron36d091f2014-11-07 03:18:508712 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188713 host_impl_->ScrollBy(
8714 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
8715 .did_scroll);
8716 host_impl_->ScrollEnd(EndState().get());
[email protected]dab0a422014-08-13 16:09:468717
8718 EXPECT_EQ(0, set_needs_commit_count);
8719 EXPECT_EQ(2, set_needs_redraw_count);
8720 EXPECT_EQ(1, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318721 }
8722}
8723
[email protected]68d3fc12014-02-18 16:31:088724class LayerTreeHostImplWithTopControlsTest : public LayerTreeHostImplTest {
8725 public:
danakjaeb95062014-11-14 01:35:368726 void SetUp() override {
[email protected]68d3fc12014-02-18 16:31:088727 LayerTreeSettings settings = DefaultSettings();
[email protected]68d3fc12014-02-18 16:31:088728 CreateHostImpl(settings, CreateOutputSurface());
dtrainorcb7779b82014-12-04 01:08:028729 host_impl_->active_tree()->set_top_controls_height(top_controls_height_);
aelias6004fe02015-02-07 21:43:018730 host_impl_->sync_tree()->set_top_controls_height(top_controls_height_);
8731 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f);
[email protected]68d3fc12014-02-18 16:31:088732 }
[email protected]f42cffb2014-03-08 18:03:258733
8734 protected:
8735 static const int top_controls_height_;
[email protected]68d3fc12014-02-18 16:31:088736};
8737
[email protected]f42cffb2014-03-08 18:03:258738const int LayerTreeHostImplWithTopControlsTest::top_controls_height_ = 50;
8739
[email protected]68d3fc12014-02-18 16:31:088740TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) {
sunxdb7e79432016-03-09 21:13:428741 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
8742 scroll_layer->layer_tree_impl()
8743 ->property_trees()
8744 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
8745 gfx::ScrollOffset(0, 10));
danakj12e2f6e2015-08-19 22:25:448746 BeginFrameArgs begin_frame_args =
8747 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
8748 host_impl_->WillBeginImplFrame(begin_frame_args);
8749 host_impl_->Animate();
[email protected]68d3fc12014-02-18 16:31:088750 EXPECT_FALSE(did_request_redraw_);
danakj12e2f6e2015-08-19 22:25:448751 host_impl_->DidFinishImplFrame();
[email protected]68d3fc12014-02-18 16:31:088752}
8753
dtrainorcb7779b82014-12-04 01:08:028754TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsHeightIsCommitted) {
8755 SetupScrollAndContentsLayers(gfx::Size(100, 100));
8756 EXPECT_FALSE(did_request_redraw_);
8757 host_impl_->CreatePendingTree();
8758 host_impl_->sync_tree()->set_top_controls_height(100);
8759 host_impl_->ActivateSyncTree();
aelias6004fe02015-02-07 21:43:018760 EXPECT_EQ(100, host_impl_->top_controls_manager()->TopControlsHeight());
dtrainorcb7779b82014-12-04 01:08:028761}
8762
8763TEST_F(LayerTreeHostImplWithTopControlsTest,
8764 TopControlsStayFullyVisibleOnHeightChange) {
8765 SetupScrollAndContentsLayers(gfx::Size(100, 100));
aelias6004fe02015-02-07 21:43:018766 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset());
dtrainorcb7779b82014-12-04 01:08:028767
8768 host_impl_->CreatePendingTree();
8769 host_impl_->sync_tree()->set_top_controls_height(0);
8770 host_impl_->ActivateSyncTree();
aelias6004fe02015-02-07 21:43:018771 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset());
dtrainorcb7779b82014-12-04 01:08:028772
8773 host_impl_->CreatePendingTree();
8774 host_impl_->sync_tree()->set_top_controls_height(50);
8775 host_impl_->ActivateSyncTree();
aelias6004fe02015-02-07 21:43:018776 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset());
dtrainorcb7779b82014-12-04 01:08:028777}
8778
[email protected]43b8f982014-04-30 21:24:338779TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) {
sunxdb7e79432016-03-09 21:13:428780 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
8781 scroll_layer->layer_tree_impl()
8782 ->property_trees()
8783 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
8784 gfx::ScrollOffset(0, 10));
[email protected]43b8f982014-04-30 21:24:338785 host_impl_->DidChangeTopControlsPosition();
danakja18e826a2015-12-03 00:27:038786 EXPECT_TRUE(did_request_next_frame_);
[email protected]43b8f982014-04-30 21:24:338787 EXPECT_TRUE(did_request_redraw_);
8788}
8789
[email protected]f42cffb2014-03-08 18:03:258790TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) {
tdresser7befa9c2015-07-16 17:47:288791 InputHandlerScrollResult result;
[email protected]f42cffb2014-03-08 18:03:258792 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:488793 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8794
[email protected]f42cffb2014-03-08 18:03:258795 host_impl_->SetViewportSize(gfx::Size(100, 100));
bokan55b2f152014-09-15 14:47:598796 host_impl_->top_controls_manager()->UpdateTopControlsState(
8797 BOTH, SHOWN, false);
[email protected]f42cffb2014-03-08 18:03:258798 DrawFrame();
8799
tdresser81e84c672016-01-18 23:21:228800 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038801 host_impl_
8802 ->ScrollBegin(BeginState(gfx::Point()).get(),
8803 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228804 .thread);
bokan88eae012014-09-09 20:40:428805 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258806 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518807 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258808
8809 // Scroll just the top controls and verify that the scroll succeeds.
8810 const float residue = 10;
8811 float offset = top_controls_height_ - residue;
majidvp944a8cd2016-01-12 21:05:188812 result = host_impl_->ScrollBy(
8813 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288814 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
8815 EXPECT_TRUE(result.did_scroll);
lof84c1f962df2015-03-10 19:03:438816 EXPECT_FLOAT_EQ(-offset,
8817 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258818 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518819 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258820
8821 // Scroll across the boundary
8822 const float content_scroll = 20;
8823 offset = residue + content_scroll;
majidvp944a8cd2016-01-12 21:05:188824 result = host_impl_->ScrollBy(
8825 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288826 EXPECT_TRUE(result.did_scroll);
8827 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
[email protected]f42cffb2014-03-08 18:03:258828 EXPECT_EQ(-top_controls_height_,
bokan88eae012014-09-09 20:40:428829 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258830 EXPECT_EQ(gfx::Vector2dF(0, content_scroll).ToString(),
aeliasf998da82015-02-03 01:40:518831 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258832
8833 // Now scroll back to the top of the content
8834 offset = -content_scroll;
majidvp944a8cd2016-01-12 21:05:188835 result = host_impl_->ScrollBy(
8836 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288837 EXPECT_TRUE(result.did_scroll);
8838 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
[email protected]f42cffb2014-03-08 18:03:258839 EXPECT_EQ(-top_controls_height_,
bokan88eae012014-09-09 20:40:428840 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258841 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518842 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258843
8844 // And scroll the top controls completely into view
8845 offset = -top_controls_height_;
majidvp944a8cd2016-01-12 21:05:188846 result = host_impl_->ScrollBy(
8847 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288848 EXPECT_TRUE(result.did_scroll);
8849 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
bokan88eae012014-09-09 20:40:428850 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258851 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518852 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258853
8854 // And attempt to scroll past the end
majidvp944a8cd2016-01-12 21:05:188855 result = host_impl_->ScrollBy(
8856 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288857 EXPECT_FALSE(result.did_scroll);
8858 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, -50));
bokan88eae012014-09-09 20:40:428859 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258860 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518861 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258862
majidvp944a8cd2016-01-12 21:05:188863 host_impl_->ScrollEnd(EndState().get());
[email protected]f42cffb2014-03-08 18:03:258864}
8865
jdduke7f366ae2015-07-17 00:36:028866TEST_F(LayerTreeHostImplWithTopControlsTest, WheelUnhandledByTopControls) {
8867 SetupScrollAndContentsLayers(gfx::Size(100, 200));
bokan0c33a092015-07-29 18:27:568868 host_impl_->SetViewportSize(gfx::Size(50, 100));
8869 host_impl_->active_tree()->set_top_controls_shrink_blink_size(true);
jdduke7f366ae2015-07-17 00:36:028870 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
8871 false);
8872 DrawFrame();
8873
bokan0c33a092015-07-29 18:27:568874 LayerImpl* viewport_layer = host_impl_->InnerViewportScrollLayer();
jdduke7f366ae2015-07-17 00:36:028875
tdresser81e84c672016-01-18 23:21:228876 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188877 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228878 InputHandler::WHEEL)
8879 .thread);
jdduke7f366ae2015-07-17 00:36:028880 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
8881 EXPECT_VECTOR_EQ(gfx::Vector2dF(), viewport_layer->CurrentScrollOffset());
8882
8883 // Wheel scrolls should not affect the top controls, and should pass
8884 // directly through to the viewport.
8885 const float delta = top_controls_height_;
8886 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188887 host_impl_->ScrollBy(
8888 UpdateState(gfx::Point(), gfx::Vector2d(0, delta)).get())
8889 .did_scroll);
jdduke7f366ae2015-07-17 00:36:028890 EXPECT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
8891 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, delta),
8892 viewport_layer->CurrentScrollOffset());
8893
8894 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188895 host_impl_->ScrollBy(
8896 UpdateState(gfx::Point(), gfx::Vector2d(0, delta)).get())
8897 .did_scroll);
jdduke7f366ae2015-07-17 00:36:028898 EXPECT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
8899 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, delta * 2),
8900 viewport_layer->CurrentScrollOffset());
8901}
8902
[email protected]ac3446d2014-08-13 08:51:208903TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) {
8904 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:488905 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8906
[email protected]ac3446d2014-08-13 08:51:208907 host_impl_->SetViewportSize(gfx::Size(100, 200));
bokan55b2f152014-09-15 14:47:598908 host_impl_->top_controls_manager()->UpdateTopControlsState(
8909 BOTH, SHOWN, false);
[email protected]ac3446d2014-08-13 08:51:208910 DrawFrame();
8911
tdresser81e84c672016-01-18 23:21:228912 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038913 host_impl_
8914 ->ScrollBegin(BeginState(gfx::Point()).get(),
8915 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228916 .thread);
bokan88eae012014-09-09 20:40:428917 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:208918 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518919 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:208920
8921 // Scroll the top controls partially.
8922 const float residue = 35;
8923 float offset = top_controls_height_ - residue;
ccameron36d091f2014-11-07 03:18:508924 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188925 host_impl_->ScrollBy(
8926 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
8927 .did_scroll);
lof84c1f962df2015-03-10 19:03:438928 EXPECT_FLOAT_EQ(-offset,
8929 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:208930 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518931 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:208932
8933 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:038934 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:208935 did_request_commit_ = false;
8936
8937 // End the scroll while the controls are still offset from their limit.
majidvp944a8cd2016-01-12 21:05:188938 host_impl_->ScrollEnd(EndState().get());
loyso8b876b72016-01-08 04:27:388939 ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:038940 EXPECT_TRUE(did_request_next_frame_);
[email protected]ac3446d2014-08-13 08:51:208941 EXPECT_TRUE(did_request_redraw_);
8942 EXPECT_FALSE(did_request_commit_);
8943
8944 // The top controls should properly animate until finished, despite the scroll
8945 // offset being at the origin.
danakj12e2f6e2015-08-19 22:25:448946 BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(
8947 BEGINFRAME_FROM_HERE, base::TimeTicks::Now());
danakja18e826a2015-12-03 00:27:038948 while (did_request_next_frame_) {
[email protected]ac3446d2014-08-13 08:51:208949 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:038950 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:208951 did_request_commit_ = false;
8952
8953 float old_offset =
bokan88eae012014-09-09 20:40:428954 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:208955
danakj12e2f6e2015-08-19 22:25:448956 begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5);
8957 host_impl_->WillBeginImplFrame(begin_frame_args);
8958 host_impl_->Animate();
[email protected]ac3446d2014-08-13 08:51:208959 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518960 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:208961
8962 float new_offset =
bokan88eae012014-09-09 20:40:428963 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:208964
8965 // No commit is needed as the controls are animating the content offset,
8966 // not the scroll offset.
8967 EXPECT_FALSE(did_request_commit_);
8968
8969 if (new_offset != old_offset)
8970 EXPECT_TRUE(did_request_redraw_);
8971
8972 if (new_offset != 0) {
loyso8b876b72016-01-08 04:27:388973 EXPECT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:038974 EXPECT_TRUE(did_request_next_frame_);
[email protected]ac3446d2014-08-13 08:51:208975 }
danakj12e2f6e2015-08-19 22:25:448976 host_impl_->DidFinishImplFrame();
[email protected]ac3446d2014-08-13 08:51:208977 }
loyso8b876b72016-01-08 04:27:388978 EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation());
[email protected]ac3446d2014-08-13 08:51:208979}
8980
8981TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) {
8982 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:488983 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8984
[email protected]ac3446d2014-08-13 08:51:208985 host_impl_->SetViewportSize(gfx::Size(100, 100));
bokan55b2f152014-09-15 14:47:598986 host_impl_->top_controls_manager()->UpdateTopControlsState(
8987 BOTH, SHOWN, false);
[email protected]ac3446d2014-08-13 08:51:208988 float initial_scroll_offset = 50;
sunxdb7e79432016-03-09 21:13:428989 scroll_layer->layer_tree_impl()
8990 ->property_trees()
8991 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
8992 scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset));
[email protected]ac3446d2014-08-13 08:51:208993 DrawFrame();
8994
tdresser81e84c672016-01-18 23:21:228995 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038996 host_impl_
8997 ->ScrollBegin(BeginState(gfx::Point()).get(),
8998 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228999 .thread);
bokan88eae012014-09-09 20:40:429000 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:209001 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
aeliasf998da82015-02-03 01:40:519002 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:209003
9004 // Scroll the top controls partially.
9005 const float residue = 15;
9006 float offset = top_controls_height_ - residue;
ccameron36d091f2014-11-07 03:18:509007 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189008 host_impl_->ScrollBy(
9009 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9010 .did_scroll);
lof84c1f962df2015-03-10 19:03:439011 EXPECT_FLOAT_EQ(-offset,
9012 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:209013 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
aeliasf998da82015-02-03 01:40:519014 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:209015
9016 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039017 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:209018 did_request_commit_ = false;
9019
9020 // End the scroll while the controls are still offset from the limit.
majidvp944a8cd2016-01-12 21:05:189021 host_impl_->ScrollEnd(EndState().get());
loyso8b876b72016-01-08 04:27:389022 ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:039023 EXPECT_TRUE(did_request_next_frame_);
[email protected]ac3446d2014-08-13 08:51:209024 EXPECT_TRUE(did_request_redraw_);
9025 EXPECT_FALSE(did_request_commit_);
9026
9027 // Animate the top controls to the limit.
danakj12e2f6e2015-08-19 22:25:449028 BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(
9029 BEGINFRAME_FROM_HERE, base::TimeTicks::Now());
danakja18e826a2015-12-03 00:27:039030 while (did_request_next_frame_) {
[email protected]ac3446d2014-08-13 08:51:209031 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039032 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:209033 did_request_commit_ = false;
9034
9035 float old_offset =
bokan88eae012014-09-09 20:40:429036 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:209037
danakj12e2f6e2015-08-19 22:25:449038 begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5);
9039 host_impl_->WillBeginImplFrame(begin_frame_args);
9040 host_impl_->Animate();
[email protected]ac3446d2014-08-13 08:51:209041
9042 float new_offset =
bokan88eae012014-09-09 20:40:429043 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:209044
9045 if (new_offset != old_offset) {
9046 EXPECT_TRUE(did_request_redraw_);
9047 EXPECT_TRUE(did_request_commit_);
9048 }
danakj12e2f6e2015-08-19 22:25:449049 host_impl_->DidFinishImplFrame();
[email protected]ac3446d2014-08-13 08:51:209050 }
loyso8b876b72016-01-08 04:27:389051 EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation());
majidvpfb80e432015-02-23 14:15:509052 EXPECT_EQ(-top_controls_height_,
9053 host_impl_->top_controls_manager()->ControlsTopOffset());
9054}
9055
9056TEST_F(LayerTreeHostImplWithTopControlsTest,
9057 TopControlsAnimationAfterMainThreadFlingStopped) {
9058 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:489059 host_impl_->active_tree()->BuildPropertyTreesForTesting();
9060
majidvpfb80e432015-02-23 14:15:509061 host_impl_->SetViewportSize(gfx::Size(100, 100));
9062 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
9063 false);
9064 float initial_scroll_offset = 50;
sunxdb7e79432016-03-09 21:13:429065 scroll_layer->layer_tree_impl()
9066 ->property_trees()
9067 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
9068 scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset));
majidvpfb80e432015-02-23 14:15:509069 DrawFrame();
9070
tdresser81e84c672016-01-18 23:21:229071 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039072 host_impl_
9073 ->ScrollBegin(BeginState(gfx::Point()).get(),
9074 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229075 .thread);
majidvpfb80e432015-02-23 14:15:509076 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
9077 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
9078 scroll_layer->CurrentScrollOffset().ToString());
9079
9080 // Scroll the top controls partially.
9081 const float residue = 15;
9082 float offset = top_controls_height_ - residue;
9083 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189084 host_impl_->ScrollBy(
9085 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9086 .did_scroll);
lof84c1f962df2015-03-10 19:03:439087 EXPECT_FLOAT_EQ(-offset,
9088 host_impl_->top_controls_manager()->ControlsTopOffset());
majidvpfb80e432015-02-23 14:15:509089 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
9090 scroll_layer->CurrentScrollOffset().ToString());
9091
9092 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039093 did_request_next_frame_ = false;
majidvpfb80e432015-02-23 14:15:509094 did_request_commit_ = false;
9095
9096 // End the fling while the controls are still offset from the limit.
9097 host_impl_->MainThreadHasStoppedFlinging();
loyso8b876b72016-01-08 04:27:389098 ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:039099 EXPECT_TRUE(did_request_next_frame_);
majidvpfb80e432015-02-23 14:15:509100 EXPECT_TRUE(did_request_redraw_);
9101 EXPECT_FALSE(did_request_commit_);
9102
9103 // Animate the top controls to the limit.
danakj12e2f6e2015-08-19 22:25:449104 BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(
9105 BEGINFRAME_FROM_HERE, base::TimeTicks::Now());
danakja18e826a2015-12-03 00:27:039106 while (did_request_next_frame_) {
majidvpfb80e432015-02-23 14:15:509107 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039108 did_request_next_frame_ = false;
majidvpfb80e432015-02-23 14:15:509109 did_request_commit_ = false;
9110
9111 float old_offset = host_impl_->top_controls_manager()->ControlsTopOffset();
9112
danakj12e2f6e2015-08-19 22:25:449113 begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5);
9114 host_impl_->WillBeginImplFrame(begin_frame_args);
9115 host_impl_->Animate();
majidvpfb80e432015-02-23 14:15:509116
9117 float new_offset = host_impl_->top_controls_manager()->ControlsTopOffset();
9118
9119 if (new_offset != old_offset) {
9120 EXPECT_TRUE(did_request_redraw_);
9121 EXPECT_TRUE(did_request_commit_);
9122 }
danakj12e2f6e2015-08-19 22:25:449123 host_impl_->DidFinishImplFrame();
majidvpfb80e432015-02-23 14:15:509124 }
loyso8b876b72016-01-08 04:27:389125 EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation());
majidvpfb80e432015-02-23 14:15:509126 EXPECT_EQ(-top_controls_height_,
9127 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:209128}
9129
sujiths.s344435e2014-11-08 03:04:039130TEST_F(LayerTreeHostImplWithTopControlsTest,
9131 TopControlsScrollDeltaInOverScroll) {
tdresser96f4a2b2015-07-15 14:11:549132 // Verifies that the overscroll delta should not have accumulated in
sujiths.s344435e2014-11-08 03:04:039133 // the top controls if we do a hide and show without releasing finger.
sujiths.s344435e2014-11-08 03:04:039134 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:489135 host_impl_->active_tree()->BuildPropertyTreesForTesting();
9136
sujiths.s344435e2014-11-08 03:04:039137 host_impl_->SetViewportSize(gfx::Size(100, 100));
9138 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
9139 false);
sunxd22ecae62016-02-11 21:38:129140 DrawFrame();
sujiths.s344435e2014-11-08 03:04:039141
tdresser81e84c672016-01-18 23:21:229142 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039143 host_impl_
9144 ->ScrollBegin(BeginState(gfx::Point()).get(),
9145 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229146 .thread);
sujiths.s344435e2014-11-08 03:04:039147 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
9148
9149 float offset = 50;
9150 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189151 host_impl_->ScrollBy(
9152 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9153 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039154 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
9155 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:519156 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039157
9158 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189159 host_impl_->ScrollBy(
9160 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9161 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039162 EXPECT_EQ(gfx::Vector2dF(0, offset).ToString(),
aeliasf998da82015-02-03 01:40:519163 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039164
9165 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189166 host_impl_->ScrollBy(
9167 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9168 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039169
9170 // Should have fully scrolled
9171 EXPECT_EQ(gfx::Vector2dF(0, scroll_layer->MaxScrollOffset().y()).ToString(),
aeliasf998da82015-02-03 01:40:519172 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039173
9174 float overscrollamount = 10;
9175
9176 // Overscroll the content
9177 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:189178 host_impl_->ScrollBy(UpdateState(gfx::Point(),
9179 gfx::Vector2d(0, overscrollamount))
9180 .get())
sujiths.s344435e2014-11-08 03:04:039181 .did_scroll);
9182 EXPECT_EQ(gfx::Vector2dF(0, 2 * offset).ToString(),
aeliasf998da82015-02-03 01:40:519183 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039184 EXPECT_EQ(gfx::Vector2dF(0, overscrollamount).ToString(),
9185 host_impl_->accumulated_root_overscroll().ToString());
9186
majidvp944a8cd2016-01-12 21:05:189187 EXPECT_TRUE(host_impl_->ScrollBy(UpdateState(gfx::Point(),
9188 gfx::Vector2d(0, -2 * offset))
9189 .get())
sujiths.s344435e2014-11-08 03:04:039190 .did_scroll);
9191 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
aeliasf998da82015-02-03 01:40:519192 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039193 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
9194
9195 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189196 host_impl_->ScrollBy(
9197 UpdateState(gfx::Point(), gfx::Vector2d(0, -offset)).get())
9198 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039199 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
aeliasf998da82015-02-03 01:40:519200 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039201
9202 // Top controls should be fully visible
9203 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
9204
majidvp944a8cd2016-01-12 21:05:189205 host_impl_->ScrollEnd(EndState().get());
sujiths.s344435e2014-11-08 03:04:039206}
9207
bokanbc115b42016-08-22 13:46:329208// Tests that when we set a child scroller (e.g. a scrolling div) as the outer
9209// viewport, scrolling it controls the top controls.
9210TEST_F(LayerTreeHostImplTopControlsTest,
9211 ReplacedOuterViewportScrollsTopControls) {
9212 const gfx::Size scroll_content_size(400, 400);
9213 const gfx::Size root_layer_size(200, 200);
9214 const gfx::Size viewport_size(100, 100);
9215
9216 SetupTopControlsAndScrollLayerWithVirtualViewport(
9217 viewport_size, viewport_size, root_layer_size);
9218
9219 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9220 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9221 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
9222 LayerImpl* scroll_layer = nullptr;
9223
9224 // Initialization: Add a child scrolling layer to the outer scroll layer and
9225 // set its scroll layer as the outer viewport. This simulates setting a
9226 // scrolling element as the root scroller on the page.
9227 {
9228 std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
9229 clip->SetBounds(root_layer_size);
9230 clip->SetPosition(gfx::PointF());
9231
9232 std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
9233 scroll->SetBounds(scroll_content_size);
9234 scroll->SetScrollClipLayer(clip->id());
9235 scroll->SetDrawsContent(true);
9236
9237 scroll_layer = scroll.get();
9238
9239 clip->test_properties()->AddChild(std::move(scroll));
9240 outer_scroll->test_properties()->AddChild(std::move(clip));
9241 layer_tree_impl->SetViewportLayersFromIds(
9242 Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(),
9243 inner_scroll->id(), scroll_layer->id());
9244 layer_tree_impl->BuildPropertyTreesForTesting();
9245 DrawFrame();
9246 }
9247
9248 ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
9249
9250 // Scrolling should scroll the child content and the top controls. The
9251 // original outer viewport should get no scroll.
9252 {
9253 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
9254 InputHandler::TOUCHSCREEN);
9255 host_impl_->ScrollBy(
9256 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
9257 host_impl_->ScrollEnd(EndState().get());
9258
9259 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll->CurrentScrollOffset());
9260 EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 50.f),
9261 scroll_layer->CurrentScrollOffset());
9262 EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
9263 }
9264}
9265
[email protected]09a6f2c2014-02-20 20:19:149266class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
9267 public:
9268 void SetupVirtualViewportLayers(const gfx::Size& content_size,
9269 const gfx::Size& outer_viewport,
9270 const gfx::Size& inner_viewport) {
9271 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
9272 const int kOuterViewportClipLayerId = 6;
9273 const int kOuterViewportScrollLayerId = 7;
9274 const int kInnerViewportScrollLayerId = 2;
9275 const int kInnerViewportClipLayerId = 4;
9276 const int kPageScaleLayerId = 5;
9277
danakj60bc3bc2016-04-09 00:24:489278 std::unique_ptr<LayerImpl> inner_scroll =
[email protected]09a6f2c2014-02-20 20:19:149279 LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId);
jaydasikaca2605e2016-04-23 02:52:529280 inner_scroll->test_properties()->is_container_for_fixed_position_layers =
9281 true;
sunxdb7e79432016-03-09 21:13:429282 inner_scroll->layer_tree_impl()
9283 ->property_trees()
9284 ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(),
9285 gfx::ScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149286
danakj60bc3bc2016-04-09 00:24:489287 std::unique_ptr<LayerImpl> inner_clip =
[email protected]09a6f2c2014-02-20 20:19:149288 LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
9289 inner_clip->SetBounds(inner_viewport);
9290
danakj60bc3bc2016-04-09 00:24:489291 std::unique_ptr<LayerImpl> page_scale =
[email protected]09a6f2c2014-02-20 20:19:149292 LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
9293
9294 inner_scroll->SetScrollClipLayer(inner_clip->id());
9295 inner_scroll->SetBounds(outer_viewport);
[email protected]09a6f2c2014-02-20 20:19:149296 inner_scroll->SetPosition(gfx::PointF());
[email protected]09a6f2c2014-02-20 20:19:149297
danakj60bc3bc2016-04-09 00:24:489298 std::unique_ptr<LayerImpl> outer_clip =
[email protected]09a6f2c2014-02-20 20:19:149299 LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
9300 outer_clip->SetBounds(outer_viewport);
jaydasikaca2605e2016-04-23 02:52:529301 outer_clip->test_properties()->is_container_for_fixed_position_layers =
9302 true;
[email protected]09a6f2c2014-02-20 20:19:149303
danakj60bc3bc2016-04-09 00:24:489304 std::unique_ptr<LayerImpl> outer_scroll =
[email protected]09a6f2c2014-02-20 20:19:149305 LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
9306 outer_scroll->SetScrollClipLayer(outer_clip->id());
sunxdb7e79432016-03-09 21:13:429307 outer_scroll->layer_tree_impl()
9308 ->property_trees()
9309 ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
9310 gfx::ScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149311 outer_scroll->SetBounds(content_size);
[email protected]09a6f2c2014-02-20 20:19:149312 outer_scroll->SetPosition(gfx::PointF());
[email protected]09a6f2c2014-02-20 20:19:149313
danakj60bc3bc2016-04-09 00:24:489314 std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, 8);
[email protected]09a6f2c2014-02-20 20:19:149315 contents->SetDrawsContent(true);
9316 contents->SetBounds(content_size);
[email protected]09a6f2c2014-02-20 20:19:149317 contents->SetPosition(gfx::PointF());
[email protected]09a6f2c2014-02-20 20:19:149318
jaydasika89f7b5a2016-06-22 02:08:399319 outer_scroll->test_properties()->AddChild(std::move(contents));
9320 outer_clip->test_properties()->AddChild(std::move(outer_scroll));
9321 inner_scroll->test_properties()->AddChild(std::move(outer_clip));
9322 page_scale->test_properties()->AddChild(std::move(inner_scroll));
9323 inner_clip->test_properties()->AddChild(std::move(page_scale));
[email protected]09a6f2c2014-02-20 20:19:149324
jaydasika6b5a32bf2016-04-22 21:56:369325 inner_clip->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:599326 layer_tree_impl->SetRootLayerForTesting(std::move(inner_clip));
ccameron8230b68b2014-11-21 19:25:189327 layer_tree_impl->SetViewportLayersFromIds(
9328 Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId,
9329 kOuterViewportScrollLayerId);
[email protected]09a6f2c2014-02-20 20:19:149330
danakj74af409e2016-07-01 00:41:489331 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]09a6f2c2014-02-20 20:19:149332 host_impl_->active_tree()->DidBecomeActive();
9333 }
9334};
9335
hush33370e12015-04-07 03:49:509336TEST_F(LayerTreeHostImplVirtualViewportTest, ScrollBothInnerAndOuterLayer) {
9337 gfx::Size content_size = gfx::Size(100, 160);
9338 gfx::Size outer_viewport = gfx::Size(50, 80);
9339 gfx::Size inner_viewport = gfx::Size(25, 40);
9340
9341 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9342
hush33370e12015-04-07 03:49:509343 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9344 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
danakj74af409e2016-07-01 00:41:489345
hush33370e12015-04-07 03:49:509346 DrawFrame();
9347 {
9348 gfx::ScrollOffset inner_expected;
9349 gfx::ScrollOffset outer_expected;
9350 EXPECT_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9351 EXPECT_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
9352
9353 gfx::ScrollOffset current_offset(70.f, 100.f);
9354
danakjdd74e512015-09-21 23:07:599355 host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
hush33370e12015-04-07 03:49:509356 EXPECT_EQ(gfx::ScrollOffset(25.f, 40.f), inner_scroll->MaxScrollOffset());
9357 EXPECT_EQ(gfx::ScrollOffset(50.f, 80.f), outer_scroll->MaxScrollOffset());
9358
9359 // Outer viewport scrolls first. Then the rest is applied to the inner
9360 // viewport.
9361 EXPECT_EQ(gfx::ScrollOffset(20.f, 20.f),
9362 inner_scroll->CurrentScrollOffset());
9363 EXPECT_EQ(gfx::ScrollOffset(50.f, 80.f),
9364 outer_scroll->CurrentScrollOffset());
9365 }
9366}
9367
[email protected]09a6f2c2014-02-20 20:19:149368TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) {
bokan1f01388f2015-09-15 20:55:549369 gfx::Size content_size = gfx::Size(200, 320);
9370 gfx::Size outer_viewport = gfx::Size(100, 160);
9371 gfx::Size inner_viewport = gfx::Size(50, 80);
[email protected]09a6f2c2014-02-20 20:19:149372
9373 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9374
9375 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9376 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
danakj74af409e2016-07-01 00:41:489377
[email protected]09a6f2c2014-02-20 20:19:149378 DrawFrame();
9379 {
9380 gfx::Vector2dF inner_expected;
9381 gfx::Vector2dF outer_expected;
aeliasf998da82015-02-03 01:40:519382 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9383 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149384
bokan1f01388f2015-09-15 20:55:549385 // Scrolling the viewport always sets the outer scroll layer as the
9386 // currently scrolling layer.
tdresser81e84c672016-01-18 23:21:229387 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039388 host_impl_
9389 ->ScrollBegin(BeginState(gfx::Point()).get(),
9390 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229391 .thread);
tdressera3f3a942015-09-28 21:15:399392 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
tdresser81e84c672016-01-18 23:21:229393 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9394 host_impl_->FlingScrollBegin().thread);
tdressera3f3a942015-09-28 21:15:399395 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149396
bokan1f01388f2015-09-15 20:55:549397 gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f,
9398 inner_viewport.height() / 2.f);
majidvp944a8cd2016-01-12 21:05:189399 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549400 inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
tdressera3f3a942015-09-28 21:15:399401 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149402
majidvp944a8cd2016-01-12 21:05:189403 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499404 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke2491ebe2015-08-10 15:41:159405 EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149406
aeliasf998da82015-02-03 01:40:519407 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9408 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149409
bokan1f01388f2015-09-15 20:55:549410 // Fling past the inner viewport boundry, make sure outer viewport scrolls.
tdresser81e84c672016-01-18 23:21:229411 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039412 host_impl_
9413 ->ScrollBegin(BeginState(gfx::Point()).get(),
9414 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229415 .thread);
tdressera3f3a942015-09-28 21:15:399416 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
tdresser81e84c672016-01-18 23:21:229417 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9418 host_impl_->FlingScrollBegin().thread);
tdressera3f3a942015-09-28 21:15:399419 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149420
majidvp944a8cd2016-01-12 21:05:189421 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549422 inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
tdressera3f3a942015-09-28 21:15:399423 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149424
majidvp944a8cd2016-01-12 21:05:189425 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549426 outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
tdressera3f3a942015-09-28 21:15:399427 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149428
majidvp944a8cd2016-01-12 21:05:189429 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499430 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke2491ebe2015-08-10 15:41:159431 EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149432
aeliasf998da82015-02-03 01:40:519433 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9434 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149435 }
9436}
9437
jddukea7173dd2014-11-19 22:05:289438TEST_F(LayerTreeHostImplVirtualViewportTest,
9439 DiagonalScrollBubblesPerfectlyToInner) {
bokan1f01388f2015-09-15 20:55:549440 gfx::Size content_size = gfx::Size(200, 320);
9441 gfx::Size outer_viewport = gfx::Size(100, 160);
9442 gfx::Size inner_viewport = gfx::Size(50, 80);
jddukea7173dd2014-11-19 22:05:289443
9444 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9445
9446 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9447 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
danakj74af409e2016-07-01 00:41:489448
jddukea7173dd2014-11-19 22:05:289449 DrawFrame();
9450 {
9451 gfx::Vector2dF inner_expected;
9452 gfx::Vector2dF outer_expected;
aeliasf998da82015-02-03 01:40:519453 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9454 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
jddukea7173dd2014-11-19 22:05:289455
bokan1f01388f2015-09-15 20:55:549456 // Make sure the scroll goes to the inner viewport first.
tdresser81e84c672016-01-18 23:21:229457 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039458 host_impl_
9459 ->ScrollBegin(BeginState(gfx::Point()).get(),
9460 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229461 .thread);
9462 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9463 host_impl_->FlingScrollBegin().thread);
dtapuska40e8aff2016-03-11 21:45:039464 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9465 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289466
9467 // Scroll near the edge of the outer viewport.
bokan1f01388f2015-09-15 20:55:549468 gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f,
9469 inner_viewport.height() / 2.f);
majidvp944a8cd2016-01-12 21:05:189470 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549471 inner_expected += scroll_delta;
dtapuska40e8aff2016-03-11 21:45:039472 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9473 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289474
aeliasf998da82015-02-03 01:40:519475 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9476 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
jddukea7173dd2014-11-19 22:05:289477
9478 // Now diagonal scroll across the outer viewport boundary in a single event.
9479 // The entirety of the scroll should be consumed, as bubbling between inner
9480 // and outer viewport layers is perfect.
majidvp944a8cd2016-01-12 21:05:189481 host_impl_->ScrollBy(
9482 UpdateState(gfx::Point(), gfx::ScaleVector2d(scroll_delta, 2)).get());
dtapuska40e8aff2016-03-11 21:45:039483 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9484 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289485 outer_expected += scroll_delta;
9486 inner_expected += scroll_delta;
majidvp944a8cd2016-01-12 21:05:189487 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499488 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke366df482015-05-05 01:07:569489 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
dtapuska40e8aff2016-03-11 21:45:039490 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289491
aeliasf998da82015-02-03 01:40:519492 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9493 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
jddukea7173dd2014-11-19 22:05:289494 }
9495}
9496
jdduke14ffa6b2014-12-06 07:12:409497TEST_F(LayerTreeHostImplVirtualViewportTest,
tdressera3b162b82015-09-29 17:51:439498 TouchFlingDoesntSwitchScrollingLayer) {
jdduke14ffa6b2014-12-06 07:12:409499 gfx::Size content_size = gfx::Size(100, 160);
9500 gfx::Size outer_viewport = gfx::Size(50, 80);
9501 gfx::Size inner_viewport = gfx::Size(25, 40);
9502
9503 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9504
9505 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9506 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9507
danakj60bc3bc2016-04-09 00:24:489508 std::unique_ptr<LayerImpl> child =
jdduke14ffa6b2014-12-06 07:12:409509 CreateScrollableLayer(10, outer_viewport, outer_scroll);
9510 LayerImpl* child_scroll = child.get();
jaydasika89f7b5a2016-06-22 02:08:399511 outer_scroll->test_properties()->children[0]->test_properties()->AddChild(
9512 std::move(child));
danakj74af409e2016-07-01 00:41:489513 host_impl_->active_tree()->BuildPropertyTreesForTesting();
jdduke14ffa6b2014-12-06 07:12:409514
9515 DrawFrame();
9516 {
danakj60bc3bc2016-04-09 00:24:489517 std::unique_ptr<ScrollAndScaleSet> scroll_info;
jdduke14ffa6b2014-12-06 07:12:409518
9519 gfx::Vector2d scroll_delta(0, inner_viewport.height());
tdresser81e84c672016-01-18 23:21:229520 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039521 host_impl_
9522 ->ScrollBegin(BeginState(gfx::Point()).get(),
9523 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229524 .thread);
majidvp944a8cd2016-01-12 21:05:189525 EXPECT_TRUE(
9526 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
9527 .did_scroll);
dtapuska40e8aff2016-03-11 21:45:039528 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9529 gfx::Point(), InputHandler::TOUCHSCREEN));
jdduke14ffa6b2014-12-06 07:12:409530
9531 // The child should have scrolled up to its limit.
9532 scroll_info = host_impl_->ProcessScrollDeltas();
9533 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:189534 EXPECT_TRUE(
9535 ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
jdduke14ffa6b2014-12-06 07:12:409536 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
9537
tdressera3b162b82015-09-29 17:51:439538 // The fling have no effect on the currently scrolling layer.
tdresser81e84c672016-01-18 23:21:229539 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9540 host_impl_->FlingScrollBegin().thread);
majidvp944a8cd2016-01-12 21:05:189541 EXPECT_FALSE(
9542 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
9543 .did_scroll);
tdressera3b162b82015-09-29 17:51:439544 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
dtapuska40e8aff2016-03-11 21:45:039545 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9546 gfx::Point(), InputHandler::TOUCHSCREEN));
jdduke14ffa6b2014-12-06 07:12:409547
tdressera3b162b82015-09-29 17:51:439548 // The inner viewport shouldn't have scrolled.
jdduke14ffa6b2014-12-06 07:12:409549 scroll_info = host_impl_->ProcessScrollDeltas();
tdressera3b162b82015-09-29 17:51:439550 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:189551 EXPECT_TRUE(
9552 ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
tdressera3b162b82015-09-29 17:51:439553 ExpectNone(*scroll_info, inner_scroll->id());
jdduke14ffa6b2014-12-06 07:12:409554
9555 // As the locked layer is at its limit, no further scrolling can occur.
majidvp944a8cd2016-01-12 21:05:189556 EXPECT_FALSE(
9557 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
9558 .did_scroll);
tdressera3b162b82015-09-29 17:51:439559 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
majidvp944a8cd2016-01-12 21:05:189560 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499561 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke366df482015-05-05 01:07:569562 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
dtapuska40e8aff2016-03-11 21:45:039563 gfx::Point(), InputHandler::TOUCHSCREEN));
jdduke14ffa6b2014-12-06 07:12:409564 }
9565}
9566
hush1c873232015-06-23 21:22:119567TEST_F(LayerTreeHostImplVirtualViewportTest,
9568 ScrollBeginEventThatTargetsViewportLayerSkipsHitTest) {
9569 gfx::Size content_size = gfx::Size(100, 160);
9570 gfx::Size outer_viewport = gfx::Size(50, 80);
9571 gfx::Size inner_viewport = gfx::Size(25, 40);
9572
9573 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9574
9575 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9576 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9577
danakj60bc3bc2016-04-09 00:24:489578 std::unique_ptr<LayerImpl> child =
hush1c873232015-06-23 21:22:119579 CreateScrollableLayer(10, outer_viewport, outer_scroll);
9580 LayerImpl* child_scroll = child.get();
jaydasika89f7b5a2016-06-22 02:08:399581 outer_scroll->test_properties()->children[0]->test_properties()->AddChild(
9582 std::move(child));
danakj74af409e2016-07-01 00:41:489583 host_impl_->active_tree()->BuildPropertyTreesForTesting();
hush1c873232015-06-23 21:22:119584
9585 DrawFrame();
9586
tdresser81e84c672016-01-18 23:21:229587 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039588 host_impl_
9589 ->RootScrollBegin(BeginState(gfx::Point()).get(),
9590 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229591 .thread);
hush1c873232015-06-23 21:22:119592 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
majidvp944a8cd2016-01-12 21:05:189593 host_impl_->ScrollEnd(EndState().get());
tdresser81e84c672016-01-18 23:21:229594 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039595 host_impl_
9596 ->ScrollBegin(BeginState(gfx::Point()).get(),
9597 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229598 .thread);
hush1c873232015-06-23 21:22:119599 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
majidvp944a8cd2016-01-12 21:05:189600 host_impl_->ScrollEnd(EndState().get());
hush1c873232015-06-23 21:22:119601}
9602
hugo.holgerssone5e7aa92015-08-17 14:07:199603TEST_F(LayerTreeHostImplVirtualViewportTest,
9604 NoOverscrollWhenInnerViewportCantScroll) {
9605 InputHandlerScrollResult scroll_result;
9606 gfx::Size content_size = gfx::Size(100, 160);
9607 gfx::Size outer_viewport = gfx::Size(50, 80);
9608 gfx::Size inner_viewport = gfx::Size(25, 40);
9609 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
hugo.holgerssone5e7aa92015-08-17 14:07:199610 // Make inner viewport unscrollable.
9611 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9612 inner_scroll->set_user_scrollable_horizontal(false);
9613 inner_scroll->set_user_scrollable_vertical(false);
danakj74af409e2016-07-01 00:41:489614 host_impl_->active_tree()->BuildPropertyTreesForTesting();
9615
sunxd2668bea62016-03-17 00:49:479616 DrawFrame();
hugo.holgerssone5e7aa92015-08-17 14:07:199617
9618 // Ensure inner viewport doesn't react to scrolls (test it's unscrollable).
9619 EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset());
tdresser81e84c672016-01-18 23:21:229620 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039621 host_impl_
9622 ->ScrollBegin(BeginState(gfx::Point()).get(),
9623 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229624 .thread);
majidvp944a8cd2016-01-12 21:05:189625 scroll_result = host_impl_->ScrollBy(
9626 UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
hugo.holgerssone5e7aa92015-08-17 14:07:199627 EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset());
9628
9629 // When inner viewport is unscrollable, a fling gives zero overscroll.
9630 EXPECT_FALSE(scroll_result.did_overscroll_root);
9631 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
9632}
9633
[email protected]4bb0f312014-02-25 02:02:329634class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest {
9635 public:
danakjaeb95062014-11-14 01:35:369636 void SetUp() override {
[email protected]4bb0f312014-02-25 02:02:329637 LayerTreeSettings settings = DefaultSettings();
[email protected]4bb0f312014-02-25 02:02:329638 settings.max_memory_for_prepaint_percentage = 50;
9639 CreateHostImpl(settings, CreateOutputSurface());
9640 }
9641};
9642
9643TEST_F(LayerTreeHostImplWithImplicitLimitsTest, ImplicitMemoryLimits) {
9644 // Set up a memory policy and percentages which could cause
9645 // 32-bit integer overflows.
9646 ManagedMemoryPolicy mem_policy(300 * 1024 * 1024); // 300MB
9647
9648 // Verify implicit limits are calculated correctly with no overflows
9649 host_impl_->SetMemoryPolicy(mem_policy);
9650 EXPECT_EQ(host_impl_->global_tile_state().hard_memory_limit_in_bytes,
9651 300u * 1024u * 1024u);
9652 EXPECT_EQ(host_impl_->global_tile_state().soft_memory_limit_in_bytes,
9653 150u * 1024u * 1024u);
[email protected]4bb0f312014-02-25 02:02:329654}
9655
[email protected]ea12b5502014-06-24 21:37:369656TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) {
9657 const gfx::Size layer_size(100, 100);
9658 gfx::Transform external_transform;
9659 const gfx::Rect external_viewport(layer_size);
[email protected]c05dfbb2014-07-10 22:49:049660 const bool resourceless_software_draw = false;
[email protected]ea12b5502014-06-24 21:37:369661 LayerImpl* layer = SetupScrollAndContentsLayers(layer_size);
jaydasikad7dea632015-11-06 04:40:129662 layer->SetDrawsContent(true);
[email protected]ea12b5502014-06-24 21:37:369663
boliu7097ee5b2015-12-17 03:16:099664 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9665 external_transform);
boliu31c233ed2016-07-29 05:38:599666 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099667 resourceless_software_draw);
[email protected]ea12b5502014-06-24 21:37:369668 EXPECT_TRANSFORMATION_MATRIX_EQ(
9669 external_transform, layer->draw_properties().target_space_transform);
9670
9671 external_transform.Translate(20, 20);
boliu7097ee5b2015-12-17 03:16:099672 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9673 external_transform);
boliu31c233ed2016-07-29 05:38:599674 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099675 resourceless_software_draw);
[email protected]ea12b5502014-06-24 21:37:369676 EXPECT_TRANSFORMATION_MATRIX_EQ(
9677 external_transform, layer->draw_properties().target_space_transform);
9678}
9679
boliudaa9bdb2015-10-17 15:11:499680TEST_F(LayerTreeHostImplTest, ExternalTransformSetNeedsRedraw) {
9681 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:489682 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliudaa9bdb2015-10-17 15:11:499683
boliu7097ee5b2015-12-17 03:16:099684 const gfx::Size viewport_size(100, 100);
9685 host_impl_->SetViewportSize(viewport_size);
9686
9687 const gfx::Transform transform_for_tile_priority;
9688 const gfx::Transform draw_transform;
9689 const gfx::Rect viewport_for_tile_priority1(viewport_size);
9690 const gfx::Rect viewport_for_tile_priority2(50, 50);
9691 const gfx::Rect draw_viewport(viewport_size);
boliudaa9bdb2015-10-17 15:11:499692 bool resourceless_software_draw = false;
9693
boliu7097ee5b2015-12-17 03:16:099694 // Clear any damage.
9695 host_impl_->SetExternalTilePriorityConstraints(viewport_for_tile_priority1,
9696 transform_for_tile_priority);
boliu31c233ed2016-07-29 05:38:599697 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099698 last_on_draw_frame_.reset();
boliudaa9bdb2015-10-17 15:11:499699
9700 // Setting new constraints needs redraw.
9701 did_request_redraw_ = false;
boliu7097ee5b2015-12-17 03:16:099702 host_impl_->SetExternalTilePriorityConstraints(viewport_for_tile_priority2,
9703 transform_for_tile_priority);
boliudaa9bdb2015-10-17 15:11:499704 EXPECT_TRUE(did_request_redraw_);
boliu31c233ed2016-07-29 05:38:599705 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099706 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
9707}
boliudaa9bdb2015-10-17 15:11:499708
boliu7097ee5b2015-12-17 03:16:099709TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) {
9710 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:489711 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliudaa9bdb2015-10-17 15:11:499712
boliu7097ee5b2015-12-17 03:16:099713 const gfx::Size viewport_size(100, 100);
9714 host_impl_->SetViewportSize(viewport_size);
9715
9716 const gfx::Transform draw_transform;
9717 const gfx::Rect draw_viewport1(viewport_size);
9718 const gfx::Rect draw_viewport2(50, 50);
boliu7097ee5b2015-12-17 03:16:099719 bool resourceless_software_draw = false;
9720
9721 // Clear any damage.
boliu31c233ed2016-07-29 05:38:599722 host_impl_->OnDraw(draw_transform, draw_viewport1,
boliu7097ee5b2015-12-17 03:16:099723 resourceless_software_draw);
9724 last_on_draw_frame_.reset();
9725
9726 // Same draw params does not swap.
boliudaa9bdb2015-10-17 15:11:499727 did_request_redraw_ = false;
boliu31c233ed2016-07-29 05:38:599728 host_impl_->OnDraw(draw_transform, draw_viewport1,
boliu7097ee5b2015-12-17 03:16:099729 resourceless_software_draw);
9730 EXPECT_FALSE(did_request_redraw_);
9731 EXPECT_TRUE(last_on_draw_frame_->has_no_damage);
9732 last_on_draw_frame_.reset();
9733
9734 // Different draw params does swap.
9735 did_request_redraw_ = false;
boliu31c233ed2016-07-29 05:38:599736 host_impl_->OnDraw(draw_transform, draw_viewport2,
boliu7097ee5b2015-12-17 03:16:099737 resourceless_software_draw);
9738 EXPECT_TRUE(did_request_redraw_);
9739 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
9740}
9741
9742class ResourcelessSoftwareLayerTreeHostImplTest : public LayerTreeHostImplTest {
9743 protected:
danakj60bc3bc2016-04-09 00:24:489744 std::unique_ptr<OutputSurface> CreateOutputSurface() override {
danakj554c98a2016-07-08 00:25:079745 return FakeOutputSurface::CreateDelegating3d();
boliu7097ee5b2015-12-17 03:16:099746 }
9747};
9748
9749TEST_F(ResourcelessSoftwareLayerTreeHostImplTest,
9750 ResourcelessSoftwareSetNeedsRedraw) {
9751 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:489752 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:099753
9754 const gfx::Size viewport_size(100, 100);
9755 host_impl_->SetViewportSize(viewport_size);
9756
9757 const gfx::Transform draw_transform;
9758 const gfx::Rect draw_viewport(viewport_size);
boliu7097ee5b2015-12-17 03:16:099759 bool resourceless_software_draw = false;
9760
9761 // Clear any damage.
boliu31c233ed2016-07-29 05:38:599762 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099763 last_on_draw_frame_.reset();
9764
9765 // Always swap even if same draw params.
boliudaa9bdb2015-10-17 15:11:499766 resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:599767 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099768 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
9769 last_on_draw_frame_.reset();
boliudaa9bdb2015-10-17 15:11:499770
boliu7097ee5b2015-12-17 03:16:099771 // Next hardware draw has damage.
boliudaa9bdb2015-10-17 15:11:499772 resourceless_software_draw = false;
boliu31c233ed2016-07-29 05:38:599773 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099774 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
boliudaa9bdb2015-10-17 15:11:499775}
9776
boliu99b904a2016-01-26 22:18:019777TEST_F(ResourcelessSoftwareLayerTreeHostImplTest,
9778 ResourcelessSoftwareDrawSkipsUpdateTiles) {
9779 const gfx::Size viewport_size(100, 100);
9780 host_impl_->SetViewportSize(viewport_size);
9781
9782 host_impl_->CreatePendingTree();
vmpstr41d68f882016-03-30 01:20:239783 scoped_refptr<FakeRasterSource> raster_source(
9784 FakeRasterSource::CreateFilled(viewport_size));
danakj60bc3bc2016-04-09 00:24:489785 std::unique_ptr<FakePictureLayerImpl> layer(
boliu99b904a2016-01-26 22:18:019786 FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(),
9787 11, raster_source));
9788 layer->SetBounds(viewport_size);
9789 layer->SetDrawsContent(true);
jaydasikabf1875a2016-06-28 03:39:599790 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer));
boliu99b904a2016-01-26 22:18:019791
danakj74af409e2016-07-01 00:41:489792 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
boliu99b904a2016-01-26 22:18:019793 host_impl_->ActivateSyncTree();
9794
9795 const gfx::Transform draw_transform;
9796 const gfx::Rect draw_viewport(viewport_size);
boliu99b904a2016-01-26 22:18:019797 bool resourceless_software_draw = false;
9798
9799 // Regular draw causes UpdateTiles.
9800 did_request_prepare_tiles_ = false;
boliu31c233ed2016-07-29 05:38:599801 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu99b904a2016-01-26 22:18:019802 EXPECT_TRUE(did_request_prepare_tiles_);
9803 host_impl_->PrepareTiles();
9804
9805 // Resourceless draw skips UpdateTiles.
9806 const gfx::Rect new_draw_viewport(50, 50);
9807 resourceless_software_draw = true;
9808 did_request_prepare_tiles_ = false;
boliu31c233ed2016-07-29 05:38:599809 host_impl_->OnDraw(draw_transform, new_draw_viewport,
boliu99b904a2016-01-26 22:18:019810 resourceless_software_draw);
9811 EXPECT_FALSE(did_request_prepare_tiles_);
9812}
9813
boliu5a1970d2016-02-08 21:58:019814TEST_F(LayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) {
9815 EXPECT_FALSE(host_impl_->CommitToActiveTree());
9816 const gfx::Size layer_size(100, 100);
9817 host_impl_->SetViewportSize(layer_size);
9818 bool update_lcd_text = false;
9819
9820 // Set up active and pending tree.
9821 host_impl_->CreatePendingTree();
jaydasikabf1875a2016-06-28 03:39:599822 host_impl_->pending_tree()->SetRootLayerForTesting(
boliu5a1970d2016-02-08 21:58:019823 LayerImpl::Create(host_impl_->pending_tree(), 1));
danakj74af409e2016-07-01 00:41:489824 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
boliu5a1970d2016-02-08 21:58:019825 host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text);
9826
9827 host_impl_->ActivateSyncTree();
danakj74af409e2016-07-01 00:41:489828 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu5a1970d2016-02-08 21:58:019829 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9830
9831 host_impl_->CreatePendingTree();
9832 host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text);
9833 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9834
9835 EXPECT_FALSE(host_impl_->pending_tree()->needs_update_draw_properties());
9836 EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
9837
9838 // Update external constraints should set_needs_update_draw_properties on
9839 // both trees.
9840 gfx::Transform external_transform;
9841 gfx::Rect external_viewport(10, 20);
9842 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9843 external_transform);
9844 EXPECT_TRUE(host_impl_->pending_tree()->needs_update_draw_properties());
9845 EXPECT_TRUE(host_impl_->active_tree()->needs_update_draw_properties());
9846}
9847
ajumaed5bee12015-10-21 13:06:329848TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) {
9849 const gfx::Size layer_size(100, 100);
9850 SetupScrollAndContentsLayers(layer_size);
jaydasikafc66cfb2016-06-10 04:34:229851 LayerImpl* content_layer = host_impl_->active_tree()
9852 ->OuterViewportScrollLayer()
9853 ->test_properties()
9854 ->children[0];
ajumaed5bee12015-10-21 13:06:329855
9856 bool update_lcd_text = false;
9857
9858 host_impl_->SetViewportSize(gfx::Size(90, 90));
9859 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9860 EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect());
9861
9862 gfx::Transform external_transform;
9863 gfx::Rect external_viewport(10, 20);
ajumaed5bee12015-10-21 13:06:329864 bool resourceless_software_draw = false;
boliu7097ee5b2015-12-17 03:16:099865 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9866 external_transform);
boliu31c233ed2016-07-29 05:38:599867 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099868 resourceless_software_draw);
ajumaed5bee12015-10-21 13:06:329869 EXPECT_EQ(gfx::Rect(10, 20), content_layer->visible_layer_rect());
9870
9871 // Clear the external viewport.
9872 external_viewport = gfx::Rect();
boliu7097ee5b2015-12-17 03:16:099873 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9874 external_transform);
ajumaed5bee12015-10-21 13:06:329875
boliu31c233ed2016-07-29 05:38:599876 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099877 resourceless_software_draw);
ajumaed5bee12015-10-21 13:06:329878 EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect());
9879}
9880
jaydasikaf18cd962015-10-23 17:29:069881TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) {
9882 const gfx::Size layer_size(100, 100);
9883 SetupScrollAndContentsLayers(layer_size);
jaydasikafc66cfb2016-06-10 04:34:229884 LayerImpl* content_layer = host_impl_->active_tree()
9885 ->OuterViewportScrollLayer()
9886 ->test_properties()
9887 ->children[0];
jaydasikaf18cd962015-10-23 17:29:069888
9889 bool update_lcd_text = false;
9890
9891 host_impl_->SetViewportSize(gfx::Size(50, 50));
9892 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9893 EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect());
9894
9895 gfx::Transform external_transform;
9896 external_transform.Translate(10, 10);
9897 external_transform.Scale(2, 2);
9898 gfx::Rect external_viewport;
jaydasikaf18cd962015-10-23 17:29:069899 bool resourceless_software_draw = false;
boliu7097ee5b2015-12-17 03:16:099900 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9901 external_transform);
jaydasikaf18cd962015-10-23 17:29:069902
9903 // Visible rects should now be shifted and scaled because of the external
9904 // transform.
boliu31c233ed2016-07-29 05:38:599905 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099906 resourceless_software_draw);
jaydasikaf18cd962015-10-23 17:29:069907 EXPECT_EQ(gfx::Rect(20, 20), content_layer->visible_layer_rect());
9908
9909 // Clear the external transform.
9910 external_transform = gfx::Transform();
boliu7097ee5b2015-12-17 03:16:099911 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9912 external_transform);
jaydasikaf18cd962015-10-23 17:29:069913
boliu31c233ed2016-07-29 05:38:599914 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099915 resourceless_software_draw);
jaydasikaf18cd962015-10-23 17:29:069916 EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect());
9917}
9918
jaydasika049b3fb2015-10-23 21:21:579919TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) {
9920 const gfx::Size layer_size(100, 100);
9921 SetupScrollAndContentsLayers(layer_size);
jaydasikafc66cfb2016-06-10 04:34:229922 LayerImpl* content_layer = host_impl_->active_tree()
9923 ->OuterViewportScrollLayer()
9924 ->test_properties()
9925 ->children[0];
jaydasika89f7b5a2016-06-22 02:08:399926 content_layer->test_properties()->AddChild(
9927 LayerImpl::Create(host_impl_->active_tree(), 100));
vollickcb3f6b12016-03-01 23:44:109928 LayerImpl* test_layer = host_impl_->active_tree()->LayerById(100);
jaydasika6b5a32bf2016-04-22 21:56:369929 test_layer->test_properties()->force_render_surface = true;
jaydasika049b3fb2015-10-23 21:21:579930 test_layer->SetDrawsContent(true);
9931 test_layer->SetBounds(layer_size);
9932 gfx::Transform perspective_transform;
9933 perspective_transform.ApplyPerspectiveDepth(2);
jaydasika10d43fc2016-08-18 04:06:049934 test_layer->test_properties()->transform = perspective_transform;
danakj74af409e2016-07-01 00:41:489935 host_impl_->active_tree()->BuildPropertyTreesForTesting();
jaydasika049b3fb2015-10-23 21:21:579936
jaydasika049b3fb2015-10-23 21:21:579937 bool update_lcd_text = false;
9938
9939 host_impl_->SetViewportSize(gfx::Size(50, 50));
9940 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9941 TransformNode* node =
9942 host_impl_->active_tree()->property_trees()->transform_tree.Node(
9943 test_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:439944 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
jaydasika049b3fb2015-10-23 21:21:579945
9946 gfx::Transform external_transform;
9947 external_transform.Translate(10, 10);
9948 external_transform.Scale(2, 2);
9949 gfx::Rect external_viewport;
jaydasika049b3fb2015-10-23 21:21:579950 bool resourceless_software_draw = false;
boliu7097ee5b2015-12-17 03:16:099951 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9952 external_transform);
jaydasika049b3fb2015-10-23 21:21:579953
9954 // Transform node's sublayer scale should include the device transform scale.
boliu31c233ed2016-07-29 05:38:599955 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099956 resourceless_software_draw);
jaydasika049b3fb2015-10-23 21:21:579957 node = host_impl_->active_tree()->property_trees()->transform_tree.Node(
9958 test_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:439959 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f));
jaydasika049b3fb2015-10-23 21:21:579960
9961 // Clear the external transform.
9962 external_transform = gfx::Transform();
boliu7097ee5b2015-12-17 03:16:099963 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9964 external_transform);
jaydasika049b3fb2015-10-23 21:21:579965
boliu31c233ed2016-07-29 05:38:599966 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099967 resourceless_software_draw);
jaydasika049b3fb2015-10-23 21:21:579968 node = host_impl_->active_tree()->property_trees()->transform_tree.Node(
9969 test_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:439970 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
jaydasika049b3fb2015-10-23 21:21:579971}
9972
[email protected]749cbc62014-07-10 01:06:359973TEST_F(LayerTreeHostImplTest, ScrollAnimated) {
ymalik99740e852016-04-07 04:18:139974 const gfx::Size content_size(1000, 1000);
9975 const gfx::Size viewport_size(50, 100);
9976 CreateBasicVirtualViewportLayers(viewport_size, content_size);
skobesde5abdb82015-10-20 19:16:349977
[email protected]749cbc62014-07-10 01:06:359978 DrawFrame();
9979
9980 base::TimeTicks start_time =
9981 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
9982
danakj12e2f6e2015-08-19 22:25:449983 BeginFrameArgs begin_frame_args =
9984 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
9985
tdresser81e84c672016-01-18 23:21:229986 EXPECT_EQ(
9987 InputHandler::SCROLL_ON_IMPL_THREAD,
9988 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
[email protected]749cbc62014-07-10 01:06:359989
9990 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
skobesde5abdb82015-10-20 19:16:349991 EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer);
[email protected]749cbc62014-07-10 01:06:359992
danakj12e2f6e2015-08-19 22:25:449993 begin_frame_args.frame_time = start_time;
9994 host_impl_->WillBeginImplFrame(begin_frame_args);
9995 host_impl_->Animate();
[email protected]749cbc62014-07-10 01:06:359996 host_impl_->UpdateAnimationState(true);
9997
aeliasf998da82015-02-03 01:40:519998 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
danakj12e2f6e2015-08-19 22:25:449999 host_impl_->DidFinishImplFrame();
[email protected]749cbc62014-07-10 01:06:3510000
danakj12e2f6e2015-08-19 22:25:4410001 begin_frame_args.frame_time =
10002 start_time + base::TimeDelta::FromMilliseconds(50);
10003 host_impl_->WillBeginImplFrame(begin_frame_args);
10004 host_impl_->Animate();
[email protected]749cbc62014-07-10 01:06:3510005 host_impl_->UpdateAnimationState(true);
10006
aeliasf998da82015-02-03 01:40:5110007 float y = scrolling_layer->CurrentScrollOffset().y();
[email protected]749cbc62014-07-10 01:06:3510008 EXPECT_TRUE(y > 1 && y < 49);
10009
[email protected]7a7d5be2014-07-18 22:37:2610010 // Update target.
tdresser81e84c672016-01-18 23:21:2210011 EXPECT_EQ(
10012 InputHandler::SCROLL_ON_IMPL_THREAD,
10013 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
danakj12e2f6e2015-08-19 22:25:4410014 host_impl_->DidFinishImplFrame();
[email protected]7a7d5be2014-07-18 22:37:2610015
danakj12e2f6e2015-08-19 22:25:4410016 begin_frame_args.frame_time =
10017 start_time + base::TimeDelta::FromMilliseconds(200);
10018 host_impl_->WillBeginImplFrame(begin_frame_args);
10019 host_impl_->Animate();
[email protected]749cbc62014-07-10 01:06:3510020 host_impl_->UpdateAnimationState(true);
10021
aeliasf998da82015-02-03 01:40:5110022 y = scrolling_layer->CurrentScrollOffset().y();
[email protected]7a7d5be2014-07-18 22:37:2610023 EXPECT_TRUE(y > 50 && y < 100);
10024 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410025 host_impl_->DidFinishImplFrame();
[email protected]7a7d5be2014-07-18 22:37:2610026
danakj12e2f6e2015-08-19 22:25:4410027 begin_frame_args.frame_time =
10028 start_time + base::TimeDelta::FromMilliseconds(250);
10029 host_impl_->WillBeginImplFrame(begin_frame_args);
10030 host_impl_->Animate();
[email protected]7a7d5be2014-07-18 22:37:2610031 host_impl_->UpdateAnimationState(true);
10032
miletusf57925d2014-10-01 19:38:1310033 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
aeliasf998da82015-02-03 01:40:5110034 scrolling_layer->CurrentScrollOffset());
[email protected]749cbc62014-07-10 01:06:3510035 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410036 host_impl_->DidFinishImplFrame();
[email protected]749cbc62014-07-10 01:06:3510037}
10038
sahelebcfc332016-09-01 00:13:3710039TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) {
10040 const gfx::Size content_size(1000, 1000);
10041 const gfx::Size viewport_size(50, 100);
10042 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10043
10044 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10045 host_impl_->ScrollAnimatedBegin(gfx::Point()).thread);
10046
10047 // The second ScrollAnimatedBegin should not get ignored.
10048 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10049 host_impl_->ScrollAnimatedBegin(gfx::Point()).thread);
10050}
10051
ymalik04da03c2016-08-18 18:38:1610052// Verfify that a smooth scroll animation doesn't jump when UpdateTarget gets
10053// called before the animation is started.
10054TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) {
10055 const gfx::Size content_size(1000, 1000);
10056 const gfx::Size viewport_size(50, 100);
10057 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10058
10059 DrawFrame();
10060
10061 base::TimeTicks start_time =
10062 base::TimeTicks() + base::TimeDelta::FromMilliseconds(200);
10063
10064 BeginFrameArgs begin_frame_args =
10065 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10066 begin_frame_args.frame_time = start_time;
10067 host_impl_->WillBeginImplFrame(begin_frame_args);
10068 host_impl_->UpdateAnimationState(true);
10069 host_impl_->DidFinishImplFrame();
10070
10071 EXPECT_EQ(
10072 InputHandler::SCROLL_ON_IMPL_THREAD,
10073 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
10074 // This will call ScrollOffsetAnimationCurve::UpdateTarget while the animation
10075 // created above is in state ANIMATION::WAITING_FOR_TARGET_AVAILABILITY and
10076 // doesn't have a start time.
10077 EXPECT_EQ(
10078 InputHandler::SCROLL_ON_IMPL_THREAD,
10079 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100)).thread);
10080
10081 begin_frame_args.frame_time =
10082 start_time + base::TimeDelta::FromMilliseconds(250);
10083 // This is when the animation above gets promoted to STARTING.
10084 host_impl_->WillBeginImplFrame(begin_frame_args);
10085 host_impl_->UpdateAnimationState(true);
10086 host_impl_->DidFinishImplFrame();
10087
10088 begin_frame_args.frame_time =
10089 start_time + base::TimeDelta::FromMilliseconds(300);
10090 // This is when the animation above gets ticked.
10091 host_impl_->WillBeginImplFrame(begin_frame_args);
10092 host_impl_->UpdateAnimationState(true);
10093 host_impl_->DidFinishImplFrame();
10094
10095 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10096 EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer);
10097
10098 // Verify no jump.
10099 float y = scrolling_layer->CurrentScrollOffset().y();
10100 EXPECT_TRUE(y > 1 && y < 49);
10101}
10102
ymalikddfc3522016-09-05 18:40:3710103TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) {
10104 const gfx::Size content_size(1000, 1000);
10105 const gfx::Size viewport_size(50, 100);
10106 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10107
10108 DrawFrame();
10109
10110 base::TimeTicks start_time =
10111 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10112 BeginFrameArgs begin_frame_args =
10113 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10114
10115 // Create animation with a 100ms delay.
10116 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10117 host_impl_
10118 ->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100),
10119 base::TimeDelta::FromMilliseconds(100))
10120 .thread);
10121 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10122 EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer);
10123
10124 // First tick, animation is started.
10125 begin_frame_args.frame_time = start_time;
10126 host_impl_->WillBeginImplFrame(begin_frame_args);
10127 host_impl_->UpdateAnimationState(true);
10128 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10129 host_impl_->DidFinishImplFrame();
10130
10131 // Second tick after 50ms, animation should be half way done since
10132 // the duration due to delay is 100ms.
10133 begin_frame_args.frame_time =
10134 start_time + base::TimeDelta::FromMilliseconds(50);
10135 host_impl_->WillBeginImplFrame(begin_frame_args);
10136 host_impl_->UpdateAnimationState(true);
10137 EXPECT_EQ(50, scrolling_layer->CurrentScrollOffset().y());
10138 host_impl_->DidFinishImplFrame();
10139
10140 // Update target.
10141 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10142 host_impl_
10143 ->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100),
10144 base::TimeDelta::FromMilliseconds(150))
10145 .thread);
10146
10147 // Third tick after 100ms, should be at the target position since update
10148 // target was called with a large value of jank.
10149 begin_frame_args.frame_time =
10150 start_time + base::TimeDelta::FromMilliseconds(100);
10151 host_impl_->WillBeginImplFrame(begin_frame_args);
10152 host_impl_->UpdateAnimationState(true);
10153 EXPECT_LT(100, scrolling_layer->CurrentScrollOffset().y());
10154}
10155
ymalik0f4192062016-01-14 17:18:3510156// Test that a smooth scroll offset animation is aborted when followed by a
10157// non-smooth scroll offset animation.
10158TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) {
ymalik399b4762016-01-25 16:10:1710159 const gfx::Size content_size(1000, 1000);
10160 const gfx::Size viewport_size(500, 500);
10161 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10162
ymalik0f4192062016-01-14 17:18:3510163 DrawFrame();
10164
10165 base::TimeTicks start_time =
10166 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10167
10168 BeginFrameArgs begin_frame_args =
10169 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10170
10171 // Perform animated scroll.
tdresser81e84c672016-01-18 23:21:2210172 EXPECT_EQ(
10173 InputHandler::SCROLL_ON_IMPL_THREAD,
10174 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
ymalik0f4192062016-01-14 17:18:3510175
10176 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10177
10178 begin_frame_args.frame_time = start_time;
10179 host_impl_->WillBeginImplFrame(begin_frame_args);
10180 host_impl_->Animate();
10181 host_impl_->UpdateAnimationState(true);
10182
10183 EXPECT_TRUE(host_impl_->animation_host()->HasAnyAnimationTargetingProperty(
vollickef2ae922016-06-29 17:54:2710184 scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET));
ymalik0f4192062016-01-14 17:18:3510185
10186 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10187 host_impl_->DidFinishImplFrame();
10188
10189 begin_frame_args.frame_time =
10190 start_time + base::TimeDelta::FromMilliseconds(50);
10191 host_impl_->WillBeginImplFrame(begin_frame_args);
10192 host_impl_->Animate();
10193 host_impl_->UpdateAnimationState(true);
10194
10195 float y = scrolling_layer->CurrentScrollOffset().y();
10196 EXPECT_TRUE(y > 1 && y < 49);
10197
10198 // Perform instant scroll.
tdresser81e84c672016-01-18 23:21:2210199 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
ymalik0f4192062016-01-14 17:18:3510200 host_impl_->ScrollBegin(BeginState(gfx::Point(0, y)).get(),
tdresser81e84c672016-01-18 23:21:2210201 InputHandler::WHEEL)
10202 .thread);
ymalik0f4192062016-01-14 17:18:3510203 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y),
10204 InputHandler::WHEEL));
10205 host_impl_->ScrollBy(
10206 UpdateState(gfx::Point(0, y), gfx::Vector2d(0, 50)).get());
10207 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y + 50),
10208 InputHandler::WHEEL));
danakj60bc3bc2016-04-09 00:24:4810209 std::unique_ptr<ScrollState> scroll_state_end = EndState();
tdresserebe6e34c2016-02-10 18:46:0610210 host_impl_->ScrollEnd(scroll_state_end.get());
sahel7adc4a72016-08-25 19:53:4910211 host_impl_->ClearCurrentlyScrollingLayerForTesting();
ymalik0f4192062016-01-14 17:18:3510212 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
10213 InputHandler::WHEEL));
10214
10215 // The instant scroll should have marked the smooth scroll animation as
10216 // aborted.
loysodb73537f2016-03-14 05:07:4510217 EXPECT_FALSE(host_impl_->animation_host()->HasActiveAnimationForTesting(
vollickef2ae922016-06-29 17:54:2710218 scrolling_layer->element_id()));
ymalik0f4192062016-01-14 17:18:3510219
10220 EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(0, y + 50),
10221 scrolling_layer->CurrentScrollOffset());
10222 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
10223 host_impl_->DidFinishImplFrame();
10224}
10225
ymalik4c34ac552016-05-26 00:58:2910226// Test that a smooth scroll offset animation is marked finished when aborted
10227// with the needs_completion flag. The animation is then finished on the
ymalik6581bb3e2016-03-01 07:32:0710228// main thread.
10229TEST_F(LayerTreeHostImplTimelinesTest,
10230 ScrollAnimatedFinishedByMainThreadScrollingReason) {
10231 const gfx::Size content_size(1000, 1000);
10232 const gfx::Size viewport_size(500, 500);
10233 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10234
10235 DrawFrame();
10236
10237 base::TimeTicks start_time =
10238 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10239
10240 BeginFrameArgs begin_frame_args =
10241 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10242
10243 // Perform animated scroll.
10244 EXPECT_EQ(
10245 InputHandler::SCROLL_ON_IMPL_THREAD,
10246 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100)).thread);
10247
10248 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10249
10250 begin_frame_args.frame_time = start_time;
10251 host_impl_->WillBeginImplFrame(begin_frame_args);
10252 host_impl_->Animate();
10253 host_impl_->UpdateAnimationState(true);
10254
10255 EXPECT_TRUE(host_impl_->animation_host()->HasAnyAnimationTargetingProperty(
vollickef2ae922016-06-29 17:54:2710256 scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET));
ymalik6581bb3e2016-03-01 07:32:0710257
10258 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10259 host_impl_->DidFinishImplFrame();
10260
10261 begin_frame_args.frame_time =
10262 start_time + base::TimeDelta::FromMilliseconds(50);
10263 host_impl_->WillBeginImplFrame(begin_frame_args);
10264 host_impl_->Animate();
10265 host_impl_->UpdateAnimationState(true);
10266
10267 float y = scrolling_layer->CurrentScrollOffset().y();
10268 EXPECT_TRUE(y > 1 && y < 49);
10269
ymalik4c34ac552016-05-26 00:58:2910270 // Abort animation.
10271 host_impl_->animation_host()->ScrollAnimationAbort(true /*needs_completion*/);
ymalik6581bb3e2016-03-01 07:32:0710272 host_impl_->UpdateAnimationState(true);
10273
ymalik4c34ac552016-05-26 00:58:2910274 // Aborting with the needs completion param should have marked the smooth
10275 // scroll animation as finished.
loysodb73537f2016-03-14 05:07:4510276 EXPECT_FALSE(host_impl_->animation_host()->HasActiveAnimationForTesting(
vollickef2ae922016-06-29 17:54:2710277 scrolling_layer->element_id()));
ymalik6581bb3e2016-03-01 07:32:0710278 EXPECT_TRUE(y > 1 && y < 49);
10279 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
10280 host_impl_->DidFinishImplFrame();
10281}
10282
loysoce3bb822015-07-08 02:40:4710283// Evolved from LayerTreeHostImplTest.ScrollAnimated.
10284TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) {
ymalik399b4762016-01-25 16:10:1710285 const gfx::Size content_size(1000, 1000);
10286 const gfx::Size viewport_size(500, 500);
10287 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10288
loysoce3bb822015-07-08 02:40:4710289 DrawFrame();
10290
10291 base::TimeTicks start_time =
10292 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10293
danakj12e2f6e2015-08-19 22:25:4410294 BeginFrameArgs begin_frame_args =
10295 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10296
tdresser81e84c672016-01-18 23:21:2210297 EXPECT_EQ(
10298 InputHandler::SCROLL_ON_IMPL_THREAD,
10299 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
loysoce3bb822015-07-08 02:40:4710300
10301 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
danakj12e2f6e2015-08-19 22:25:4410302 begin_frame_args.frame_time = start_time;
10303 host_impl_->WillBeginImplFrame(begin_frame_args);
10304 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710305 host_impl_->UpdateAnimationState(true);
10306
10307 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
danakj12e2f6e2015-08-19 22:25:4410308 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710309
danakj12e2f6e2015-08-19 22:25:4410310 begin_frame_args.frame_time =
10311 start_time + base::TimeDelta::FromMilliseconds(50);
10312 host_impl_->WillBeginImplFrame(begin_frame_args);
10313 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710314 host_impl_->UpdateAnimationState(true);
10315
10316 float y = scrolling_layer->CurrentScrollOffset().y();
10317 EXPECT_TRUE(y > 1 && y < 49);
10318
10319 // Update target.
tdresser81e84c672016-01-18 23:21:2210320 EXPECT_EQ(
10321 InputHandler::SCROLL_ON_IMPL_THREAD,
10322 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
danakj12e2f6e2015-08-19 22:25:4410323 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710324
danakj12e2f6e2015-08-19 22:25:4410325 begin_frame_args.frame_time =
10326 start_time + base::TimeDelta::FromMilliseconds(200);
10327 host_impl_->WillBeginImplFrame(begin_frame_args);
10328 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710329 host_impl_->UpdateAnimationState(true);
10330
10331 y = scrolling_layer->CurrentScrollOffset().y();
10332 EXPECT_TRUE(y > 50 && y < 100);
10333 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410334 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710335
danakj12e2f6e2015-08-19 22:25:4410336 begin_frame_args.frame_time =
10337 start_time + base::TimeDelta::FromMilliseconds(250);
10338 host_impl_->WillBeginImplFrame(begin_frame_args);
10339 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710340 host_impl_->UpdateAnimationState(true);
10341
10342 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
10343 scrolling_layer->CurrentScrollOffset());
10344 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410345 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710346}
10347
ymalik99740e852016-04-07 04:18:1310348// Test that the scroll delta for an animated scroll is distributed correctly
10349// between the inner and outer viewport.
10350TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
10351 const gfx::Size content_size(200, 200);
10352 const gfx::Size viewport_size(100, 100);
10353 CreateBasicVirtualViewportLayers(viewport_size, content_size);
danakj74af409e2016-07-01 00:41:4810354 host_impl_->active_tree()->BuildPropertyTreesForTesting();
ymalik99740e852016-04-07 04:18:1310355
10356 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
10357 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
10358
10359 // Zoom into the page by a 2X factor
10360 float min_page_scale = 1.f, max_page_scale = 4.f;
10361 float page_scale_factor = 2.f;
ymalik99740e852016-04-07 04:18:1310362 host_impl_->active_tree()->PushPageScaleFromMainThread(
10363 page_scale_factor, min_page_scale, max_page_scale);
10364 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
10365
10366 // Scroll by a small amount, there should be no bubbling to the outer
10367 // viewport.
10368 base::TimeTicks start_time =
10369 base::TimeTicks() + base::TimeDelta::FromMilliseconds(250);
10370 BeginFrameArgs begin_frame_args =
10371 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10372 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10373 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(10.f, 20.f))
10374 .thread);
10375 host_impl_->Animate();
10376 host_impl_->UpdateAnimationState(true);
10377 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10378
10379 BeginImplFrameAndAnimate(begin_frame_args, start_time);
10380 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10),
10381 inner_scroll_layer->CurrentScrollOffset());
10382 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10383 outer_scroll_layer->CurrentScrollOffset());
10384 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset());
10385
10386 // Scroll by the inner viewport's max scroll extent, the remainder
10387 // should bubble up to the outer viewport.
10388 EXPECT_EQ(
10389 InputHandler::SCROLL_ON_IMPL_THREAD,
10390 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(100.f, 100.f))
10391 .thread);
10392 host_impl_->Animate();
10393 host_impl_->UpdateAnimationState(true);
10394 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10395
10396 BeginImplFrameAndAnimate(begin_frame_args,
10397 start_time + base::TimeDelta::FromMilliseconds(350));
10398 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
10399 inner_scroll_layer->CurrentScrollOffset());
10400 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10),
10401 outer_scroll_layer->CurrentScrollOffset());
10402
10403 // Scroll by the outer viewport's max scroll extent, it should all go to the
10404 // outer viewport.
10405 EXPECT_EQ(
10406 InputHandler::SCROLL_ON_IMPL_THREAD,
10407 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(190.f, 180.f))
10408 .thread);
10409 host_impl_->Animate();
10410 host_impl_->UpdateAnimationState(true);
10411 EXPECT_EQ(outer_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10412
10413 BeginImplFrameAndAnimate(begin_frame_args,
10414 start_time + base::TimeDelta::FromMilliseconds(850));
10415 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
10416 inner_scroll_layer->CurrentScrollOffset());
10417 EXPECT_VECTOR_EQ(gfx::Vector2dF(100, 100),
10418 outer_scroll_layer->CurrentScrollOffset());
10419
10420 // Scroll upwards by the max scroll extent. The inner viewport should animate
10421 // and the remainder should bubble to the outer viewport.
10422 EXPECT_EQ(
10423 InputHandler::SCROLL_ON_IMPL_THREAD,
10424 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(-110.f, -120.f))
10425 .thread);
10426 host_impl_->Animate();
10427 host_impl_->UpdateAnimationState(true);
10428 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10429
10430 BeginImplFrameAndAnimate(
10431 begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1200));
10432 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10433 inner_scroll_layer->CurrentScrollOffset());
10434 EXPECT_VECTOR_EQ(gfx::Vector2dF(95, 90),
10435 outer_scroll_layer->CurrentScrollOffset());
10436}
10437
10438// Test that the correct viewport scroll layer is updated when the target offset
10439// is updated.
10440TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) {
10441 const gfx::Size content_size(200, 200);
10442 const gfx::Size viewport_size(100, 100);
10443 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10444
10445 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
10446 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
10447
10448 // Zoom into the page by a 2X factor
10449 float min_page_scale = 1.f, max_page_scale = 4.f;
10450 float page_scale_factor = 2.f;
ymalik99740e852016-04-07 04:18:1310451 host_impl_->active_tree()->PushPageScaleFromMainThread(
10452 page_scale_factor, min_page_scale, max_page_scale);
10453 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
10454
10455 // Scroll the inner viewport.
10456 base::TimeTicks start_time =
10457 base::TimeTicks() + base::TimeDelta::FromMilliseconds(50);
10458 BeginFrameArgs begin_frame_args =
10459 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10460 EXPECT_EQ(
10461 InputHandler::SCROLL_ON_IMPL_THREAD,
10462 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(90, 90)).thread);
10463 host_impl_->Animate();
10464 host_impl_->UpdateAnimationState(true);
10465 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10466
10467 BeginImplFrameAndAnimate(begin_frame_args, start_time);
10468 float inner_x = inner_scroll_layer->CurrentScrollOffset().x();
10469 float inner_y = inner_scroll_layer->CurrentScrollOffset().y();
10470 EXPECT_TRUE(inner_x > 0 && inner_x < 45);
10471 EXPECT_TRUE(inner_y > 0 && inner_y < 45);
10472 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10473 outer_scroll_layer->CurrentScrollOffset());
10474
10475 // Update target.
10476 EXPECT_EQ(
10477 InputHandler::SCROLL_ON_IMPL_THREAD,
10478 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread);
10479 host_impl_->Animate();
10480 host_impl_->UpdateAnimationState(true);
10481 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10482
10483 // Verify that all the delta is applied to the inner viewport and nothing is
10484 // carried forward.
10485 BeginImplFrameAndAnimate(begin_frame_args,
10486 start_time + base::TimeDelta::FromMilliseconds(350));
10487 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
10488 inner_scroll_layer->CurrentScrollOffset());
10489 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10490 outer_scroll_layer->CurrentScrollOffset());
10491 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset());
10492}
10493
ymalik399b4762016-01-25 16:10:1710494// Test that smooth scroll offset animation doesn't happen for non user
10495// scrollable layers.
10496TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) {
10497 const gfx::Size content_size(1000, 1000);
10498 const gfx::Size viewport_size(500, 500);
10499 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10500
10501 host_impl_->OuterViewportScrollLayer()->set_user_scrollable_vertical(true);
10502 host_impl_->OuterViewportScrollLayer()->set_user_scrollable_horizontal(false);
danakj74af409e2016-07-01 00:41:4810503 host_impl_->active_tree()->BuildPropertyTreesForTesting();
ymalik399b4762016-01-25 16:10:1710504
10505 DrawFrame();
10506
10507 base::TimeTicks start_time =
10508 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10509
10510 BeginFrameArgs begin_frame_args =
10511 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10512
10513 EXPECT_EQ(
10514 InputHandler::SCROLL_ON_IMPL_THREAD,
10515 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread);
10516
10517 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10518 begin_frame_args.frame_time = start_time;
10519 host_impl_->WillBeginImplFrame(begin_frame_args);
10520 host_impl_->Animate();
10521 host_impl_->UpdateAnimationState(true);
10522
10523 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10524 host_impl_->DidFinishImplFrame();
10525
10526 begin_frame_args.frame_time =
10527 start_time + base::TimeDelta::FromMilliseconds(50);
10528 host_impl_->WillBeginImplFrame(begin_frame_args);
10529 host_impl_->Animate();
10530 host_impl_->UpdateAnimationState(true);
10531
10532 // Should not have scrolled horizontally.
10533 EXPECT_EQ(0, scrolling_layer->CurrentScrollOffset().x());
10534 float y = scrolling_layer->CurrentScrollOffset().y();
10535 EXPECT_TRUE(y > 1 && y < 49);
10536
10537 // Update target.
10538 EXPECT_EQ(
10539 InputHandler::SCROLL_ON_IMPL_THREAD,
10540 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread);
10541 host_impl_->DidFinishImplFrame();
10542
10543 begin_frame_args.frame_time =
10544 start_time + base::TimeDelta::FromMilliseconds(200);
10545 host_impl_->WillBeginImplFrame(begin_frame_args);
10546 host_impl_->Animate();
10547 host_impl_->UpdateAnimationState(true);
10548
10549 y = scrolling_layer->CurrentScrollOffset().y();
10550 EXPECT_TRUE(y > 50 && y < 100);
10551 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
10552 host_impl_->DidFinishImplFrame();
10553
10554 begin_frame_args.frame_time =
10555 start_time + base::TimeDelta::FromMilliseconds(250);
10556 host_impl_->WillBeginImplFrame(begin_frame_args);
10557 host_impl_->Animate();
10558 host_impl_->UpdateAnimationState(true);
10559
10560 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
10561 scrolling_layer->CurrentScrollOffset());
10562 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
10563 host_impl_->DidFinishImplFrame();
10564}
10565
skobes4d7f47cc82016-05-04 22:05:4110566// Test that smooth scrolls clamp correctly when bounds change mid-animation.
10567TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) {
10568 const gfx::Size old_content_size(1000, 1000);
10569 const gfx::Size new_content_size(750, 750);
10570 const gfx::Size viewport_size(500, 500);
10571
10572 LayerImpl* content_layer =
10573 CreateBasicVirtualViewportLayers(viewport_size, old_content_size);
danakj74af409e2016-07-01 00:41:4810574
skobes4d7f47cc82016-05-04 22:05:4110575 DrawFrame();
10576
10577 base::TimeTicks start_time =
10578 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10579 BeginFrameArgs begin_frame_args =
10580 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10581
10582 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(500, 500));
10583 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10584
10585 begin_frame_args.frame_time = start_time;
10586 host_impl_->WillBeginImplFrame(begin_frame_args);
10587 host_impl_->Animate();
10588 host_impl_->UpdateAnimationState(true);
10589 host_impl_->DidFinishImplFrame();
10590
10591 content_layer->SetBounds(new_content_size);
10592 scrolling_layer->SetBounds(new_content_size);
danakj74af409e2016-07-01 00:41:4810593 host_impl_->active_tree()->BuildPropertyTreesForTesting();
10594
skobes4d7f47cc82016-05-04 22:05:4110595 DrawFrame();
10596
10597 begin_frame_args.frame_time =
10598 start_time + base::TimeDelta::FromMilliseconds(200);
10599 host_impl_->WillBeginImplFrame(begin_frame_args);
10600 host_impl_->Animate();
10601 host_impl_->UpdateAnimationState(true);
10602 host_impl_->DidFinishImplFrame();
10603
10604 EXPECT_EQ(gfx::ScrollOffset(250, 250),
10605 scrolling_layer->CurrentScrollOffset());
10606}
10607
hendrikw72abb582015-05-08 18:19:5310608TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
10609 host_impl_->CreatePendingTree();
10610
10611 Region empty_invalidation;
vmpstr41d68f882016-03-30 01:20:2310612 scoped_refptr<RasterSource> raster_source_with_tiles(
10613 FakeRasterSource::CreateFilled(gfx::Size(10, 10)));
hendrikw72abb582015-05-08 18:19:5310614
danakj60bc3bc2016-04-09 00:24:4810615 std::unique_ptr<FakePictureLayerImpl> layer =
hendrikw72abb582015-05-08 18:19:5310616 FakePictureLayerImpl::Create(host_impl_->pending_tree(), 11);
10617 layer->SetBounds(gfx::Size(10, 10));
10618 layer->set_gpu_raster_max_texture_size(host_impl_->device_viewport_size());
10619 layer->SetDrawsContent(true);
vmpstr856740262015-09-24 00:25:2510620 layer->tilings()->AddTiling(1.0f, raster_source_with_tiles);
10621 layer->UpdateRasterSource(raster_source_with_tiles, &empty_invalidation,
10622 nullptr);
hendrikw72abb582015-05-08 18:19:5310623 layer->tilings()->tiling_at(0)->set_resolution(
10624 TileResolution::HIGH_RESOLUTION);
10625 layer->tilings()->tiling_at(0)->CreateAllTilesForTesting();
vmpstrcf111332016-05-04 21:20:4310626 layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0,
10627 Occlusion(), true);
jaydasikabf1875a2016-06-28 03:39:5910628 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer));
hendrikw72abb582015-05-08 18:19:5310629
10630 FakePictureLayerImpl* root_layer = static_cast<FakePictureLayerImpl*>(
jaydasikabf1875a2016-06-28 03:39:5910631 host_impl_->pending_tree()->root_layer_for_testing());
hendrikw72abb582015-05-08 18:19:5310632
10633 root_layer->set_has_valid_tile_priorities(true);
danakj60bc3bc2016-04-09 00:24:4810634 std::unique_ptr<RasterTilePriorityQueue> non_empty_raster_priority_queue_all =
hendrikw72abb582015-05-08 18:19:5310635 host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES,
10636 RasterTilePriorityQueue::Type::ALL);
10637 EXPECT_FALSE(non_empty_raster_priority_queue_all->IsEmpty());
10638
10639 root_layer->set_has_valid_tile_priorities(false);
danakj60bc3bc2016-04-09 00:24:4810640 std::unique_ptr<RasterTilePriorityQueue> empty_raster_priority_queue_all =
hendrikw72abb582015-05-08 18:19:5310641 host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES,
10642 RasterTilePriorityQueue::Type::ALL);
10643 EXPECT_TRUE(empty_raster_priority_queue_all->IsEmpty());
10644}
10645
[email protected]db2e29c2014-08-06 05:58:2510646TEST_F(LayerTreeHostImplTest, DidBecomeActive) {
10647 host_impl_->CreatePendingTree();
10648 host_impl_->ActivateSyncTree();
10649 host_impl_->CreatePendingTree();
10650
10651 LayerTreeImpl* pending_tree = host_impl_->pending_tree();
10652
danakj60bc3bc2016-04-09 00:24:4810653 std::unique_ptr<FakePictureLayerImpl> pending_layer =
[email protected]db2e29c2014-08-06 05:58:2510654 FakePictureLayerImpl::Create(pending_tree, 10);
[email protected]db2e29c2014-08-06 05:58:2510655 FakePictureLayerImpl* raw_pending_layer = pending_layer.get();
jaydasikabf1875a2016-06-28 03:39:5910656 pending_tree->SetRootLayerForTesting(std::move(pending_layer));
jaydasikabf1875a2016-06-28 03:39:5910657 ASSERT_EQ(raw_pending_layer, pending_tree->root_layer_for_testing());
[email protected]db2e29c2014-08-06 05:58:2510658
10659 EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count());
10660 pending_tree->DidBecomeActive();
10661 EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count());
10662
danakj60bc3bc2016-04-09 00:24:4810663 std::unique_ptr<FakePictureLayerImpl> mask_layer =
[email protected]db2e29c2014-08-06 05:58:2510664 FakePictureLayerImpl::Create(pending_tree, 11);
[email protected]db2e29c2014-08-06 05:58:2510665 FakePictureLayerImpl* raw_mask_layer = mask_layer.get();
ajuma1d4026a32016-06-14 13:18:5010666 raw_pending_layer->test_properties()->SetMaskLayer(std::move(mask_layer));
10667 ASSERT_EQ(raw_mask_layer, raw_pending_layer->test_properties()->mask_layer);
danakj74af409e2016-07-01 00:41:4810668 pending_tree->BuildPropertyTreesForTesting();
[email protected]db2e29c2014-08-06 05:58:2510669
10670 EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count());
10671 EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count());
10672 pending_tree->DidBecomeActive();
10673 EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count());
10674 EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count());
10675
danakj60bc3bc2016-04-09 00:24:4810676 std::unique_ptr<FakePictureLayerImpl> replica_layer =
[email protected]db2e29c2014-08-06 05:58:2510677 FakePictureLayerImpl::Create(pending_tree, 12);
danakj60bc3bc2016-04-09 00:24:4810678 std::unique_ptr<FakePictureLayerImpl> replica_mask_layer =
[email protected]db2e29c2014-08-06 05:58:2510679 FakePictureLayerImpl::Create(pending_tree, 13);
[email protected]db2e29c2014-08-06 05:58:2510680 FakePictureLayerImpl* raw_replica_mask_layer = replica_mask_layer.get();
ajuma1d4026a32016-06-14 13:18:5010681 replica_layer->test_properties()->SetMaskLayer(std::move(replica_mask_layer));
10682 raw_pending_layer->test_properties()->SetReplicaLayer(
10683 std::move(replica_layer));
10684 ASSERT_EQ(raw_replica_mask_layer, raw_pending_layer->test_properties()
10685 ->replica_layer->test_properties()
10686 ->mask_layer);
danakj74af409e2016-07-01 00:41:4810687 pending_tree->BuildPropertyTreesForTesting();
[email protected]db2e29c2014-08-06 05:58:2510688
10689 EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count());
10690 EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count());
10691 EXPECT_EQ(0u, raw_replica_mask_layer->did_become_active_call_count());
10692 pending_tree->DidBecomeActive();
10693 EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count());
10694 EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count());
10695 EXPECT_EQ(1u, raw_replica_mask_layer->did_become_active_call_count());
10696}
10697
lanweid17d0742014-12-01 18:58:5210698TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) {
10699 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
10700 host_impl_->SetViewportSize(gfx::Size(50, 50));
10701 DrawFrame();
10702
10703 EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer());
10704
10705 float min_page_scale = 1.f, max_page_scale = 4.f;
10706 float page_scale_factor = 1.f;
10707
10708 // The scroll deltas should have the page scale factor applied.
10709 {
aelias58eec0812014-12-04 01:04:4010710 host_impl_->active_tree()->PushPageScaleFromMainThread(
lanweid17d0742014-12-01 18:58:5210711 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:5010712 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
sunxdb7e79432016-03-09 21:13:4210713 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
lanweid17d0742014-12-01 18:58:5210714
10715 float page_scale_delta = 2.f;
majidvp944a8cd2016-01-12 21:05:1810716 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:0310717 InputHandler::TOUCHSCREEN);
lanweid17d0742014-12-01 18:58:5210718 host_impl_->PinchGestureBegin();
10719 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
10720 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:1810721 host_impl_->ScrollEnd(EndState().get());
lanweid17d0742014-12-01 18:58:5210722
10723 gfx::Vector2dF scroll_delta(0, 5);
tdresser81e84c672016-01-18 23:21:2210724 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:1810725 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:2210726 InputHandler::WHEEL)
10727 .thread);
aeliasf998da82015-02-03 01:40:5110728 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
lanweid17d0742014-12-01 18:58:5210729
majidvp944a8cd2016-01-12 21:05:1810730 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
10731 host_impl_->ScrollEnd(EndState().get());
aeliasf998da82015-02-03 01:40:5110732 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 2.5),
10733 scroll_layer->CurrentScrollOffset());
lanweid17d0742014-12-01 18:58:5210734 }
10735}
10736
[email protected]0e0b7fd92014-08-08 22:53:1110737class LayerTreeHostImplCountingLostSurfaces : public LayerTreeHostImplTest {
10738 public:
10739 LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {}
dcheng716bedf2014-10-21 09:51:0810740 void DidLoseOutputSurfaceOnImplThread() override { num_lost_surfaces_++; }
[email protected]0e0b7fd92014-08-08 22:53:1110741
10742 protected:
10743 int num_lost_surfaces_;
10744};
10745
10746TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) {
[email protected]0e0b7fd92014-08-08 22:53:1110747 // Really we just need at least one client notification each time
10748 // we go from having a valid output surface to not having a valid output
10749 // surface.
10750 EXPECT_EQ(0, num_lost_surfaces_);
[email protected]0e0b7fd92014-08-08 22:53:1110751 host_impl_->DidLoseOutputSurface();
[email protected]0e0b7fd92014-08-08 22:53:1110752 EXPECT_EQ(1, num_lost_surfaces_);
10753 host_impl_->DidLoseOutputSurface();
dnetob71e30c2014-08-25 23:27:2010754 EXPECT_LE(1, num_lost_surfaces_);
[email protected]0e0b7fd92014-08-08 22:53:1110755}
10756
danakj61902b82015-10-30 00:30:2610757size_t CountRenderPassesWithId(const RenderPassList& list, RenderPassId id) {
vmpstra370ef52015-11-18 10:41:2810758 return std::count_if(
10759 list.begin(), list.end(),
danakj60bc3bc2016-04-09 00:24:4810760 [id](const std::unique_ptr<RenderPass>& p) { return p->id == id; });
danakj61902b82015-10-30 00:30:2610761}
10762
danakj112d3a102015-04-14 18:24:4910763TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) {
10764 LayerTreeHostImpl::FrameData frame;
10765 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810766 RenderPass* pass3 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910767 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810768 RenderPass* pass2 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910769 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810770 RenderPass* pass1 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910771
10772 pass1->SetNew(RenderPassId(1, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10773 pass2->SetNew(RenderPassId(2, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10774 pass3->SetNew(RenderPassId(3, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10775
danakj112d3a102015-04-14 18:24:4910776 // Add a quad to each pass so they aren't empty.
10777 SolidColorDrawQuad* color_quad;
10778 color_quad = pass1->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10779 color_quad->material = DrawQuad::SOLID_COLOR;
10780 color_quad = pass2->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10781 color_quad->material = DrawQuad::SOLID_COLOR;
10782 color_quad = pass3->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10783 color_quad->material = DrawQuad::SOLID_COLOR;
10784
10785 // pass3 is referenced by pass2.
10786 RenderPassDrawQuad* rpdq =
10787 pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10788 rpdq->material = DrawQuad::RENDER_PASS;
10789 rpdq->render_pass_id = pass3->id;
10790
10791 // But pass2 is not referenced by pass1. So pass2 and pass3 should be culled.
10792 FakeLayerTreeHostImpl::RemoveRenderPasses(&frame);
danakj112d3a102015-04-14 18:24:4910793 EXPECT_EQ(1u, frame.render_passes.size());
danakj61902b82015-10-30 00:30:2610794 EXPECT_EQ(1u,
10795 CountRenderPassesWithId(frame.render_passes, RenderPassId(1, 0)));
10796 EXPECT_EQ(0u,
10797 CountRenderPassesWithId(frame.render_passes, RenderPassId(2, 0)));
10798 EXPECT_EQ(0u,
10799 CountRenderPassesWithId(frame.render_passes, RenderPassId(3, 0)));
danakj112d3a102015-04-14 18:24:4910800 EXPECT_EQ(RenderPassId(1, 0), frame.render_passes[0]->id);
10801}
10802
10803TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) {
10804 LayerTreeHostImpl::FrameData frame;
10805 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810806 RenderPass* pass3 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910807 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810808 RenderPass* pass2 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910809 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810810 RenderPass* pass1 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910811
10812 pass1->SetNew(RenderPassId(1, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10813 pass2->SetNew(RenderPassId(2, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10814 pass3->SetNew(RenderPassId(3, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10815
danakj112d3a102015-04-14 18:24:4910816 // pass1 is not empty, but pass2 and pass3 are.
10817 SolidColorDrawQuad* color_quad;
10818 color_quad = pass1->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10819 color_quad->material = DrawQuad::SOLID_COLOR;
10820
10821 // pass3 is referenced by pass2.
10822 RenderPassDrawQuad* rpdq =
10823 pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10824 rpdq->material = DrawQuad::RENDER_PASS;
10825 rpdq->render_pass_id = pass3->id;
10826
10827 // pass2 is referenced by pass1.
10828 rpdq = pass1->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10829 rpdq->material = DrawQuad::RENDER_PASS;
10830 rpdq->render_pass_id = pass2->id;
10831
10832 // Since pass3 is empty it should be removed. Then pass2 is empty too, and
10833 // should be removed.
10834 FakeLayerTreeHostImpl::RemoveRenderPasses(&frame);
danakj112d3a102015-04-14 18:24:4910835 EXPECT_EQ(1u, frame.render_passes.size());
danakj61902b82015-10-30 00:30:2610836 EXPECT_EQ(1u,
10837 CountRenderPassesWithId(frame.render_passes, RenderPassId(1, 0)));
10838 EXPECT_EQ(0u,
10839 CountRenderPassesWithId(frame.render_passes, RenderPassId(2, 0)));
10840 EXPECT_EQ(0u,
10841 CountRenderPassesWithId(frame.render_passes, RenderPassId(3, 0)));
danakj112d3a102015-04-14 18:24:4910842 EXPECT_EQ(RenderPassId(1, 0), frame.render_passes[0]->id);
10843 // The RenderPassDrawQuad should be removed from pass1.
10844 EXPECT_EQ(1u, pass1->quad_list.size());
10845 EXPECT_EQ(DrawQuad::SOLID_COLOR, pass1->quad_list.ElementAt(0)->material);
10846}
10847
10848TEST_F(LayerTreeHostImplTest, DoNotRemoveEmptyRootRenderPass) {
10849 LayerTreeHostImpl::FrameData frame;
10850 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810851 RenderPass* pass3 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910852 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810853 RenderPass* pass2 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910854 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810855 RenderPass* pass1 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910856
10857 pass1->SetNew(RenderPassId(1, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10858 pass2->SetNew(RenderPassId(2, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10859 pass3->SetNew(RenderPassId(3, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10860
danakj112d3a102015-04-14 18:24:4910861 // pass3 is referenced by pass2.
10862 RenderPassDrawQuad* rpdq =
10863 pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10864 rpdq->material = DrawQuad::RENDER_PASS;
10865 rpdq->render_pass_id = pass3->id;
10866
10867 // pass2 is referenced by pass1.
10868 rpdq = pass1->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10869 rpdq->material = DrawQuad::RENDER_PASS;
10870 rpdq->render_pass_id = pass2->id;
10871
10872 // Since pass3 is empty it should be removed. Then pass2 is empty too, and
10873 // should be removed. Then pass1 is empty too, but it's the root so it should
10874 // not be removed.
10875 FakeLayerTreeHostImpl::RemoveRenderPasses(&frame);
danakj112d3a102015-04-14 18:24:4910876 EXPECT_EQ(1u, frame.render_passes.size());
danakj61902b82015-10-30 00:30:2610877 EXPECT_EQ(1u,
10878 CountRenderPassesWithId(frame.render_passes, RenderPassId(1, 0)));
10879 EXPECT_EQ(0u,
10880 CountRenderPassesWithId(frame.render_passes, RenderPassId(2, 0)));
10881 EXPECT_EQ(0u,
10882 CountRenderPassesWithId(frame.render_passes, RenderPassId(3, 0)));
danakj112d3a102015-04-14 18:24:4910883 EXPECT_EQ(RenderPassId(1, 0), frame.render_passes[0]->id);
10884 // The RenderPassDrawQuad should be removed from pass1.
10885 EXPECT_EQ(0u, pass1->quad_list.size());
10886}
10887
sunnypsc052ba992015-05-05 00:42:2910888class FakeVideoFrameController : public VideoFrameController {
10889 public:
10890 void OnBeginFrame(const BeginFrameArgs& args) override {
10891 begin_frame_args_ = args;
dalecurtise8024c42015-05-29 21:22:3510892 did_draw_frame_ = false;
sunnypsc052ba992015-05-05 00:42:2910893 }
10894
dalecurtise8024c42015-05-29 21:22:3510895 void DidDrawFrame() override { did_draw_frame_ = true; }
10896
10897 const BeginFrameArgs& begin_frame_args() const { return begin_frame_args_; }
10898
10899 bool did_draw_frame() const { return did_draw_frame_; }
sunnypsc052ba992015-05-05 00:42:2910900
10901 private:
10902 BeginFrameArgs begin_frame_args_;
dalecurtise8024c42015-05-29 21:22:3510903 bool did_draw_frame_ = false;
sunnypsc052ba992015-05-05 00:42:2910904};
10905
10906TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
10907 BeginFrameArgs begin_frame_args =
10908 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10909 FakeVideoFrameController controller;
10910
10911 host_impl_->WillBeginImplFrame(begin_frame_args);
10912 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10913 host_impl_->AddVideoFrameController(&controller);
10914 EXPECT_TRUE(controller.begin_frame_args().IsValid());
mithro51693e382015-05-07 23:52:4110915 host_impl_->DidFinishImplFrame();
dalecurtise8024c42015-05-29 21:22:3510916
10917 EXPECT_FALSE(controller.did_draw_frame());
10918 LayerTreeHostImpl::FrameData frame;
10919 host_impl_->DidDrawAllLayers(frame);
10920 EXPECT_TRUE(controller.did_draw_frame());
10921
10922 controller.OnBeginFrame(begin_frame_args);
10923 EXPECT_FALSE(controller.did_draw_frame());
10924 host_impl_->RemoveVideoFrameController(&controller);
10925 host_impl_->DidDrawAllLayers(frame);
10926 EXPECT_FALSE(controller.did_draw_frame());
sunnypsc052ba992015-05-05 00:42:2910927}
10928
10929TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
10930 BeginFrameArgs begin_frame_args =
10931 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10932 FakeVideoFrameController controller;
10933
10934 host_impl_->WillBeginImplFrame(begin_frame_args);
mithro51693e382015-05-07 23:52:4110935 host_impl_->DidFinishImplFrame();
sunnypsc052ba992015-05-05 00:42:2910936
10937 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10938 host_impl_->AddVideoFrameController(&controller);
10939 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10940
10941 begin_frame_args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10942 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10943 host_impl_->WillBeginImplFrame(begin_frame_args);
10944 EXPECT_TRUE(controller.begin_frame_args().IsValid());
dalecurtise8024c42015-05-29 21:22:3510945
10946 EXPECT_FALSE(controller.did_draw_frame());
10947 LayerTreeHostImpl::FrameData frame;
10948 host_impl_->DidDrawAllLayers(frame);
10949 EXPECT_TRUE(controller.did_draw_frame());
10950
10951 controller.OnBeginFrame(begin_frame_args);
10952 EXPECT_FALSE(controller.did_draw_frame());
10953 host_impl_->RemoveVideoFrameController(&controller);
10954 host_impl_->DidDrawAllLayers(frame);
10955 EXPECT_FALSE(controller.did_draw_frame());
sunnypsc052ba992015-05-05 00:42:2910956}
10957
senorblancofb88a4e2015-05-08 17:28:4110958TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) {
10959 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
10960
senorblanco9c04acb2015-05-15 19:41:3210961 host_impl_->SetHasGpuRasterizationTrigger(true);
10962 host_impl_->SetContentIsSuitableForGpuRasterization(true);
danakj1a86f6d62016-08-17 20:10:4010963 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110964 EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
10965 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
10966
senorblanco9c04acb2015-05-15 19:41:3210967 host_impl_->SetHasGpuRasterizationTrigger(false);
10968 host_impl_->SetContentIsSuitableForGpuRasterization(true);
danakj1a86f6d62016-08-17 20:10:4010969 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110970 EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT,
10971 host_impl_->gpu_rasterization_status());
10972 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
10973
senorblanco9c04acb2015-05-15 19:41:3210974 host_impl_->SetHasGpuRasterizationTrigger(true);
10975 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4010976 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110977 EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT,
10978 host_impl_->gpu_rasterization_status());
10979 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
10980 EXPECT_FALSE(host_impl_->use_msaa());
10981
danakj60bc3bc2016-04-09 00:24:4810982 std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa =
senorblancofb88a4e2015-05-08 17:28:4110983 TestWebGraphicsContext3D::Create();
10984 context_with_msaa->SetMaxSamples(8);
10985
10986 LayerTreeSettings msaaSettings = GpuRasterizationEnabledSettings();
10987 msaaSettings.gpu_rasterization_msaa_sample_count = 4;
10988 EXPECT_TRUE(CreateHostImpl(
danakjf33ceec2016-07-20 20:04:4510989 msaaSettings,
10990 FakeOutputSurface::CreateDelegating3d(std::move(context_with_msaa))));
senorblanco9c04acb2015-05-15 19:41:3210991 host_impl_->SetHasGpuRasterizationTrigger(true);
10992 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4010993 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110994 EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
10995 host_impl_->gpu_rasterization_status());
10996 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
10997 EXPECT_TRUE(host_impl_->use_msaa());
10998
10999 LayerTreeSettings settings = DefaultSettings();
11000 settings.gpu_rasterization_enabled = false;
danakjf33ceec2016-07-20 20:04:4511001 EXPECT_TRUE(
11002 CreateHostImpl(settings, FakeOutputSurface::CreateDelegating3d()));
senorblanco9c04acb2015-05-15 19:41:3211003 host_impl_->SetHasGpuRasterizationTrigger(true);
11004 host_impl_->SetContentIsSuitableForGpuRasterization(true);
danakj1a86f6d62016-08-17 20:10:4011005 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4111006 EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE,
11007 host_impl_->gpu_rasterization_status());
11008 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
11009
11010 settings.gpu_rasterization_forced = true;
danakjf33ceec2016-07-20 20:04:4511011 EXPECT_TRUE(
11012 CreateHostImpl(settings, FakeOutputSurface::CreateDelegating3d()));
senorblancofb88a4e2015-05-08 17:28:4111013
senorblanco9c04acb2015-05-15 19:41:3211014 host_impl_->SetHasGpuRasterizationTrigger(false);
11015 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4011016 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4111017 EXPECT_EQ(GpuRasterizationStatus::ON_FORCED,
11018 host_impl_->gpu_rasterization_status());
11019 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
11020}
11021
ericrkd72af43d2016-03-18 21:44:3111022class MsaaIsSlowLayerTreeHostImplTest : public LayerTreeHostImplTest {
11023 public:
11024 void CreateHostImplWithMsaaIsSlow(bool msaa_is_slow) {
11025 LayerTreeSettings settings = DefaultSettings();
11026 settings.gpu_rasterization_enabled = true;
11027 settings.gpu_rasterization_msaa_sample_count = 4;
11028 auto context_provider = TestContextProvider::Create();
11029 context_provider->UnboundTestContext3d()->SetMaxSamples(4);
11030 context_provider->UnboundTestContext3d()->set_msaa_is_slow(msaa_is_slow);
11031 auto msaa_is_normal_output_surface =
danakjf33ceec2016-07-20 20:04:4511032 FakeOutputSurface::CreateDelegating3d(context_provider);
ericrkd72af43d2016-03-18 21:44:3111033 EXPECT_TRUE(
11034 CreateHostImpl(settings, std::move(msaa_is_normal_output_surface)));
11035 }
11036};
11037
11038TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) {
11039 // Ensure that without the msaa_is_slow cap we raster unsuitable content with
11040 // msaa.
11041 CreateHostImplWithMsaaIsSlow(false);
11042 host_impl_->SetHasGpuRasterizationTrigger(true);
11043 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4011044 host_impl_->CommitComplete();
ericrkd72af43d2016-03-18 21:44:3111045 EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
11046 host_impl_->gpu_rasterization_status());
11047 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
11048
11049 // Ensure that with the msaa_is_slow cap we don't raster unsuitable content
11050 // with msaa.
11051 CreateHostImplWithMsaaIsSlow(true);
11052 host_impl_->SetHasGpuRasterizationTrigger(true);
11053 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4011054 host_impl_->CommitComplete();
ericrkd72af43d2016-03-18 21:44:3111055 EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT,
11056 host_impl_->gpu_rasterization_status());
11057 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
11058}
11059
ericrk17ec17f2015-05-19 19:50:5111060// A mock output surface which lets us detect calls to ForceReclaimResources.
11061class MockReclaimResourcesOutputSurface : public FakeOutputSurface {
11062 public:
danakjc070bf552016-08-10 22:41:5511063 MockReclaimResourcesOutputSurface()
11064 : FakeOutputSurface(TestContextProvider::Create(),
11065 TestContextProvider::CreateWorker(),
11066 true) {}
ericrk17ec17f2015-05-19 19:50:5111067
11068 MOCK_METHOD0(ForceReclaimResources, void());
ericrk17ec17f2015-05-19 19:50:5111069};
11070
11071// Display::Draw (and the planned Display Scheduler) currently rely on resources
11072// being reclaimed to block drawing between BeginCommit / Swap. This test
11073// ensures that BeginCommit triggers ForceReclaimResources. See
11074// crbug.com/489515.
11075TEST_F(LayerTreeHostImplTest, BeginCommitReclaimsResources) {
danakjc070bf552016-08-10 22:41:5511076 auto output_surface = base::MakeUnique<MockReclaimResourcesOutputSurface>();
ericrk17ec17f2015-05-19 19:50:5111077 // Hold an unowned pointer to the output surface to use for mock expectations.
11078 MockReclaimResourcesOutputSurface* mock_output_surface = output_surface.get();
11079
danakja04855a2015-11-18 20:39:1011080 CreateHostImpl(DefaultSettings(), std::move(output_surface));
ericrk17ec17f2015-05-19 19:50:5111081 EXPECT_CALL(*mock_output_surface, ForceReclaimResources()).Times(1);
11082 host_impl_->BeginCommit();
11083}
11084
jaydasika0c1fd602015-10-07 17:59:5211085TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
11086 // Check page scale factor update in property trees when an update is made
11087 // on the active tree.
11088 host_impl_->CreatePendingTree();
11089 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f);
11090 CreateScrollAndContentsLayers(host_impl_->pending_tree(),
11091 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:4811092 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasika0c1fd602015-10-07 17:59:5211093 host_impl_->ActivateSyncTree();
11094 DrawFrame();
11095
11096 host_impl_->CreatePendingTree();
11097 host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
11098 LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer();
11099
11100 TransformNode* active_tree_node =
11101 host_impl_->active_tree()->property_trees()->transform_tree.Node(
11102 page_scale_layer->transform_tree_index());
sunxdcfccd1b32016-02-11 00:54:2011103 // SetPageScaleOnActiveTree also updates the factors in property trees.
trchendba8b1502016-07-08 09:47:0111104 EXPECT_EQ(active_tree_node->post_local_scale_factor, 2.f);
jaydasika0c1fd602015-10-07 17:59:5211105 EXPECT_EQ(host_impl_->active_tree()->current_page_scale_factor(), 2.f);
11106
11107 TransformNode* pending_tree_node =
11108 host_impl_->pending_tree()->property_trees()->transform_tree.Node(
11109 page_scale_layer->transform_tree_index());
trchendba8b1502016-07-08 09:47:0111110 EXPECT_EQ(pending_tree_node->post_local_scale_factor, 1.f);
jaydasika0c1fd602015-10-07 17:59:5211111 EXPECT_EQ(host_impl_->pending_tree()->current_page_scale_factor(), 2.f);
11112
11113 host_impl_->pending_tree()->UpdateDrawProperties(false);
11114 pending_tree_node =
11115 host_impl_->pending_tree()->property_trees()->transform_tree.Node(
11116 page_scale_layer->transform_tree_index());
trchendba8b1502016-07-08 09:47:0111117 EXPECT_EQ(pending_tree_node->post_local_scale_factor, 2.f);
jaydasika0c1fd602015-10-07 17:59:5211118
11119 host_impl_->ActivateSyncTree();
11120 host_impl_->active_tree()->UpdateDrawProperties(false);
11121 active_tree_node =
11122 host_impl_->active_tree()->property_trees()->transform_tree.Node(
11123 page_scale_layer->transform_tree_index());
trchendba8b1502016-07-08 09:47:0111124 EXPECT_EQ(active_tree_node->post_local_scale_factor, 2.f);
jaydasika0c1fd602015-10-07 17:59:5211125}
11126
jaydasikafbb9f43a2015-10-22 20:44:0811127TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) {
11128 // Checks that the sublayer scale of a transform node in the subtree of the
11129 // page scale layer is updated without a property tree rebuild.
11130 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f);
11131 CreateScrollAndContentsLayers(host_impl_->active_tree(), gfx::Size(100, 100));
11132 LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer();
jaydasika89f7b5a2016-06-22 02:08:3911133 page_scale_layer->test_properties()->AddChild(
11134 LayerImpl::Create(host_impl_->active_tree(), 100));
jaydasikafbb9f43a2015-10-22 20:44:0811135
11136 LayerImpl* in_subtree_of_page_scale_layer =
vollickcb3f6b12016-03-01 23:44:1011137 host_impl_->active_tree()->LayerById(100);
jaydasika6b5a32bf2016-04-22 21:56:3611138 in_subtree_of_page_scale_layer->test_properties()->force_render_surface =
11139 true;
danakj74af409e2016-07-01 00:41:4811140 host_impl_->active_tree()->BuildPropertyTreesForTesting();
11141
jaydasikafbb9f43a2015-10-22 20:44:0811142 DrawFrame();
danakj74af409e2016-07-01 00:41:4811143
jaydasikafbb9f43a2015-10-22 20:44:0811144 TransformNode* node =
11145 host_impl_->active_tree()->property_trees()->transform_tree.Node(
11146 in_subtree_of_page_scale_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:4311147 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
jaydasikafbb9f43a2015-10-22 20:44:0811148
11149 host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
danakj74af409e2016-07-01 00:41:4811150
jaydasikafbb9f43a2015-10-22 20:44:0811151 DrawFrame();
danakj74af409e2016-07-01 00:41:4811152
vollickcb3f6b12016-03-01 23:44:1011153 in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100);
jaydasikafbb9f43a2015-10-22 20:44:0811154 node = host_impl_->active_tree()->property_trees()->transform_tree.Node(
11155 in_subtree_of_page_scale_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:4311156 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f));
jaydasikafbb9f43a2015-10-22 20:44:0811157}
11158
jaydasikacb93d1c2015-12-09 23:52:4611159TEST_F(LayerTreeHostImplTest, JitterTest) {
11160 host_impl_->SetViewportSize(gfx::Size(100, 100));
11161
11162 host_impl_->CreatePendingTree();
11163 CreateScrollAndContentsLayers(host_impl_->pending_tree(),
11164 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:4811165 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasikacb93d1c2015-12-09 23:52:4611166
11167 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
jaydasikacb93d1c2015-12-09 23:52:4611168 const int scroll = 5;
11169 int accumulated_scroll = 0;
11170 for (int i = 0; i < host_impl_->pending_tree()->kFixedPointHitsThreshold + 1;
11171 ++i) {
11172 host_impl_->ActivateSyncTree();
majidvp944a8cd2016-01-12 21:05:1811173 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
dtapuska40e8aff2016-03-11 21:45:0311174 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:1811175 host_impl_->ScrollBy(
11176 UpdateState(gfx::Point(), gfx::Vector2dF(0, scroll)).get());
jaydasikacb93d1c2015-12-09 23:52:4611177 accumulated_scroll += scroll;
majidvp944a8cd2016-01-12 21:05:1811178 host_impl_->ScrollEnd(EndState().get());
jaydasikacb93d1c2015-12-09 23:52:4611179 host_impl_->active_tree()->UpdateDrawProperties(false);
11180
11181 host_impl_->CreatePendingTree();
11182 host_impl_->pending_tree()->set_source_frame_number(i + 1);
jaydasikafc66cfb2016-06-10 04:34:2211183 LayerImpl* content_layer = host_impl_->pending_tree()
11184 ->OuterViewportScrollLayer()
11185 ->test_properties()
11186 ->children[0];
jaydasikacb93d1c2015-12-09 23:52:4611187 // The scroll done on the active tree is undone on the pending tree.
11188 gfx::Transform translate;
11189 translate.Translate(0, accumulated_scroll);
jaydasika10d43fc2016-08-18 04:06:0411190 content_layer->test_properties()->transform = translate;
jaydasikacb93d1c2015-12-09 23:52:4611191
11192 LayerTreeImpl* pending_tree = host_impl_->pending_tree();
11193 pending_tree->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
vollickcb3f6b12016-03-01 23:44:1011194 LayerImpl* last_scrolled_layer = pending_tree->LayerById(
jaydasikacb93d1c2015-12-09 23:52:4611195 host_impl_->active_tree()->LastScrolledLayerId());
sunxdc36713a2016-03-03 22:31:1011196
11197 // When building property trees from impl side, the builder uses the scroll
11198 // offset of layer_impl to initialize the scroll offset in scroll tree:
11199 // scroll_tree.synced_scroll_offset.PushFromMainThread(
11200 // layer->CurrentScrollOffset()).
11201 // However, layer_impl does not store scroll_offset, so it is using scroll
11202 // tree's scroll offset to initialize itself. Usually this approach works
11203 // because this is a simple assignment. However if scroll_offset's pending
11204 // delta is not zero, the delta would be counted twice.
11205 // This hacking here is to restore the damaged scroll offset.
11206 gfx::ScrollOffset pending_base =
sunxdc044b11a2016-03-16 16:23:2011207 pending_tree->property_trees()
11208 ->scroll_tree.GetScrollOffsetBaseForTesting(
11209 last_scrolled_layer->id());
danakj74af409e2016-07-01 00:41:4811210 pending_tree->BuildPropertyTreesForTesting();
sunxdc044b11a2016-03-16 16:23:2011211 pending_tree->property_trees()
11212 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
11213 last_scrolled_layer->id(), pending_base);
jaydasika69dc9412016-06-25 00:34:5711214 pending_tree->LayerById(content_layer->id())->SetNeedsPushProperties();
sunxdc36713a2016-03-03 22:31:1011215
11216 pending_tree->set_needs_update_draw_properties();
11217 pending_tree->UpdateDrawProperties(false);
jaydasikaeaa8d0852016-03-29 23:55:3911218 float jitter = LayerTreeHostCommon::CalculateLayerJitter(content_layer);
jaydasikacb93d1c2015-12-09 23:52:4611219 // There should not be any jitter measured till we hit the fixed point hits
11220 // threshold.
11221 float expected_jitter =
11222 (i == pending_tree->kFixedPointHitsThreshold) ? 500 : 0;
11223 EXPECT_EQ(jitter, expected_jitter);
11224 }
11225}
11226
ericrk563e1a0152016-05-02 18:54:0611227// Checks that if we lose a GPU raster enabled OutputSurface and replace it
11228// with a software OutputSurface, LayerTreeHostImpl correctly re-computes GPU
11229// rasterization status.
11230TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnOutputSurfaceChange) {
danakjee6547a22016-07-01 20:41:5011231 host_impl_->ReleaseOutputSurface();
11232 host_impl_ = nullptr;
11233
ericrk563e1a0152016-05-02 18:54:0611234 LayerTreeSettings settings = DefaultSettings();
11235 settings.gpu_rasterization_forced = true;
11236
11237 host_impl_ = LayerTreeHostImpl::Create(
11238 settings, this, &task_runner_provider_, &stats_instrumentation_,
11239 &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_,
loysoab32ee72016-06-08 03:33:1811240 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
ericrk563e1a0152016-05-02 18:54:0611241 host_impl_->SetVisible(true);
11242
11243 // InitializeRenderer with a gpu-raster enabled output surface.
11244 auto gpu_raster_output_surface =
danakjf33ceec2016-07-20 20:04:4511245 FakeOutputSurface::CreateDelegating3d(TestWebGraphicsContext3D::Create());
ericrk563e1a0152016-05-02 18:54:0611246 host_impl_->InitializeRenderer(gpu_raster_output_surface.get());
11247 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
11248
11249 // Re-initialize with a software output surface.
danakj6021ec32016-07-22 22:16:0811250 output_surface_ = FakeOutputSurface::CreateDelegatingSoftware();
ericrk563e1a0152016-05-02 18:54:0611251 host_impl_->InitializeRenderer(output_surface_.get());
11252 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
11253}
11254
[email protected]ba565742012-11-10 09:29:4811255} // namespace
11256} // namespace cc