blob: bcb68a1823e6c8912c8f7ee5aac5d8aacd3cec92 [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"
khushalsagar8ec07402016-09-10 03:13:1947#include "cc/resources/ui_resource_bitmap.h"
48#include "cc/resources/ui_resource_manager.h"
[email protected]101441ce2012-10-16 01:45:0349#include "cc/test/animation_test_common.h"
[email protected]04c5900d2014-08-18 13:38:3650#include "cc/test/begin_frame_args_test.h"
[email protected]222c6782013-09-05 22:24:4951#include "cc/test/fake_layer_tree_host_impl.h"
ajumad9432e32015-11-30 19:43:4452#include "cc/test/fake_mask_layer_impl.h"
[email protected]a46f32932012-12-07 21:43:1653#include "cc/test/fake_output_surface.h"
[email protected]0634cdd42013-08-16 00:46:0954#include "cc/test/fake_output_surface_client.h"
[email protected]46b79d52013-09-07 04:29:2955#include "cc/test/fake_picture_layer_impl.h"
vmpstr41d68f882016-03-30 01:20:2356#include "cc/test/fake_raster_source.h"
[email protected]d993b602013-01-04 02:08:1257#include "cc/test/fake_video_frame_provider.h"
[email protected]101441ce2012-10-16 01:45:0358#include "cc/test/geometry_test_utils.h"
senorblancofb88a4e2015-05-08 17:28:4159#include "cc/test/gpu_rasterization_enabled_settings.h"
[email protected]101441ce2012-10-16 01:45:0360#include "cc/test/layer_test_common.h"
awoloszyne83f28c2014-12-22 15:40:0061#include "cc/test/layer_tree_test.h"
danakjf33ceec2016-07-20 20:04:4562#include "cc/test/test_delegating_output_surface.h"
reveman22dd9292014-10-13 20:52:0563#include "cc/test/test_gpu_memory_buffer_manager.h"
[email protected]4e2eb352014-03-20 17:25:4564#include "cc/test/test_shared_bitmap_manager.h"
reveman34b7a1522015-03-23 20:27:4765#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5966#include "cc/test/test_web_graphics_context_3d.h"
trchendba8b1502016-07-08 09:47:0167#include "cc/trees/effect_node.h"
danakj94b7e4f2016-07-20 01:49:3868#include "cc/trees/layer_tree_host_common.h"
[email protected]556fd292013-03-18 08:03:0469#include "cc/trees/layer_tree_impl.h"
70#include "cc/trees/single_thread_proxy.h"
trchendba8b1502016-07-08 09:47:0171#include "cc/trees/transform_node.h"
[email protected]59cb7b352012-10-30 06:45:4872#include "media/base/media.h"
[email protected]7f0c53db2012-10-02 00:23:1873#include "testing/gmock/include/gmock/gmock.h"
74#include "testing/gtest/include/gtest/gtest.h"
[email protected]7bc1c512014-01-23 01:15:2775#include "third_party/skia/include/core/SkMallocPixelRef.h"
heejin.r.chungd28506ba2014-10-23 16:36:2076#include "ui/gfx/geometry/rect_conversions.h"
77#include "ui/gfx/geometry/size_conversions.h"
78#include "ui/gfx/geometry/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1479
boliu7097ee5b2015-12-17 03:16:0980#define EXPECT_SCOPED(statements) \
81 { \
82 SCOPED_TRACE(""); \
83 statements; \
84 }
85
[email protected]94f206c12012-08-25 00:09:1486using ::testing::Mock;
87using ::testing::Return;
88using ::testing::AnyNumber;
89using ::testing::AtLeast;
90using ::testing::_;
[email protected]568285b2013-01-07 23:19:1991using media::VideoFrame;
[email protected]94f206c12012-08-25 00:09:1492
[email protected]ba565742012-11-10 09:29:4893namespace cc {
[email protected]94f206c12012-08-25 00:09:1494namespace {
95
[email protected]c2d0c5a2013-02-26 04:43:3696class LayerTreeHostImplTest : public testing::Test,
[email protected]9bdcfd642012-11-14 21:24:2697 public LayerTreeHostImplClient {
[email protected]aa043632013-03-25 03:39:4298 public:
99 LayerTreeHostImplTest()
khushalsagarb7db1fe2015-11-12 00:51:27100 : task_runner_provider_(base::ThreadTaskRunnerHandle::Get()),
khushalsagarb64b360d2015-10-21 19:25:16101 always_main_thread_blocked_(&task_runner_provider_),
[email protected]aa043632013-03-25 03:39:42102 on_can_draw_state_changed_called_(false),
[email protected]4f48f6e2013-08-27 06:33:38103 did_notify_ready_to_activate_(false),
[email protected]aa043632013-03-25 03:39:42104 did_request_commit_(false),
105 did_request_redraw_(false),
danakja18e826a2015-12-03 00:27:03106 did_request_next_frame_(false),
vmiura59ea9b4042014-12-09 20:50:39107 did_request_prepare_tiles_(false),
rouslanf7ebd8832015-01-22 01:54:14108 did_complete_page_scale_animation_(false),
danakjaecfcfba2016-09-07 22:33:18109 reduce_memory_result_(true) {
chcunninghamfd11b3c2015-06-09 02:09:42110 media::InitializeMediaLibrary();
[email protected]aa043632013-03-25 03:39:42111 }
[email protected]1c0c9bc2012-10-08 22:41:48112
[email protected]ce2e8112013-11-28 07:44:36113 LayerTreeSettings DefaultSettings() {
[email protected]96baf3e2012-10-22 23:09:55114 LayerTreeSettings settings;
[email protected]aa043632013-03-25 03:39:42115 settings.minimum_occlusion_tracking_size = gfx::Size();
jbaumanc5be44c2014-11-20 22:17:12116 settings.renderer_settings.texture_id_allocation_chunk_size = 1;
senorblanco8d1b3ac2015-05-05 00:14:26117 settings.gpu_rasterization_enabled = true;
weiliangc365a6fe2016-05-12 19:32:31118 settings.verify_clip_tree_calculations = true;
jaydasika7de66e952016-07-01 01:36:48119 settings.verify_transform_tree_calculations = true;
ericrk9151705c2016-07-26 19:53:16120 settings.renderer_settings.buffer_to_texture_target_map =
121 DefaultBufferToTextureTargetMapForTesting();
[email protected]ce2e8112013-11-28 07:44:36122 return settings;
123 }
[email protected]94f206c12012-08-25 00:09:14124
danakjaeb95062014-11-14 01:35:36125 void SetUp() override {
[email protected]ce2e8112013-11-28 07:44:36126 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
[email protected]aa043632013-03-25 03:39:42127 }
[email protected]94f206c12012-08-25 00:09:14128
danakjee6547a22016-07-01 20:41:50129 void TearDown() override {
130 if (host_impl_)
131 host_impl_->ReleaseOutputSurface();
132 }
[email protected]94f206c12012-08-25 00:09:14133
dcheng716bedf2014-10-21 09:51:08134 void DidLoseOutputSurfaceOnImplThread() override {}
enne19c108582016-04-14 03:35:32135 void SetBeginFrameSource(BeginFrameSource* source) override {}
dcheng716bedf2014-10-21 09:51:08136 void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override {}
dcheng716bedf2014-10-21 09:51:08137 void DidSwapBuffersCompleteOnImplThread() override {}
138 void OnCanDrawStateChanged(bool can_draw) override {
[email protected]aa043632013-03-25 03:39:42139 on_can_draw_state_changed_called_ = true;
140 }
dcheng716bedf2014-10-21 09:51:08141 void NotifyReadyToActivate() override {
[email protected]4f48f6e2013-08-27 06:33:38142 did_notify_ready_to_activate_ = true;
[email protected]fc20d142014-07-01 00:49:15143 host_impl_->ActivateSyncTree();
[email protected]aa043632013-03-25 03:39:42144 }
ernstmdfac03e2014-11-11 20:18:05145 void NotifyReadyToDraw() override {}
dcheng716bedf2014-10-21 09:51:08146 void SetNeedsRedrawOnImplThread() override { did_request_redraw_ = true; }
147 void SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) override {
[email protected]aa043632013-03-25 03:39:42148 did_request_redraw_ = true;
149 }
danakja18e826a2015-12-03 00:27:03150 void SetNeedsOneBeginImplFrameOnImplThread() override {
151 did_request_next_frame_ = true;
152 }
vmiura59ea9b4042014-12-09 20:50:39153 void SetNeedsPrepareTilesOnImplThread() override {
154 did_request_prepare_tiles_ = true;
[email protected]c48536a52013-09-14 00:02:08155 }
dcheng716bedf2014-10-21 09:51:08156 void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; }
sunnyps7d073dc2015-04-16 23:29:12157 void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {}
dcheng716bedf2014-10-21 09:51:08158 void PostAnimationEventsToMainThreadOnImplThread(
danakj60bc3bc2016-04-09 00:24:48159 std::unique_ptr<AnimationEvents> events) override {}
dcheng716bedf2014-10-21 09:51:08160 bool IsInsideDraw() override { return false; }
161 void RenewTreePriority() override {}
sunnypsae4316a2015-02-25 00:54:58162 void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
dcheng716bedf2014-10-21 09:51:08163 base::TimeDelta delay) override {
sunnypsae4316a2015-02-25 00:54:58164 animation_task_ = task;
165 requested_animation_delay_ = delay;
[email protected]930ff43b2014-05-02 05:24:00166 }
dcheng716bedf2014-10-21 09:51:08167 void DidActivateSyncTree() override {}
brianderson68749812015-07-07 22:39:39168 void WillPrepareTiles() override {}
vmiura59ea9b4042014-12-09 20:50:39169 void DidPrepareTiles() override {}
rouslanf7ebd8832015-01-22 01:54:14170 void DidCompletePageScaleAnimationOnImplThread() override {
171 did_complete_page_scale_animation_ = true;
172 }
boliu7097ee5b2015-12-17 03:16:09173 void OnDrawForOutputSurface(bool resourceless_software_draw) override {
danakj60bc3bc2016-04-09 00:24:48174 std::unique_ptr<LayerTreeHostImpl::FrameData> frame(
boliu7097ee5b2015-12-17 03:16:09175 new LayerTreeHostImpl::FrameData);
danakj74af409e2016-07-01 00:41:48176 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(frame.get()));
boliu7097ee5b2015-12-17 03:16:09177 last_on_draw_render_passes_.clear();
178 RenderPass::CopyAll(frame->render_passes, &last_on_draw_render_passes_);
danakjaecfcfba2016-09-07 22:33:18179 host_impl_->DrawLayers(frame.get());
boliu7097ee5b2015-12-17 03:16:09180 host_impl_->DidDrawAllLayers(*frame);
boliu7097ee5b2015-12-17 03:16:09181 last_on_draw_frame_ = std::move(frame);
182 }
[email protected]aa043632013-03-25 03:39:42183
184 void set_reduce_memory_result(bool reduce_memory_result) {
185 reduce_memory_result_ = reduce_memory_result;
186 }
187
dtrainorcb7779b82014-12-04 01:08:02188 virtual bool CreateHostImpl(const LayerTreeSettings& settings,
danakj60bc3bc2016-04-09 00:24:48189 std::unique_ptr<OutputSurface> output_surface) {
danakja18e826a2015-12-03 00:27:03190 return CreateHostImplWithTaskRunnerProvider(
191 settings, std::move(output_surface), &task_runner_provider_);
192 }
193
194 virtual bool CreateHostImplWithTaskRunnerProvider(
195 const LayerTreeSettings& settings,
danakj60bc3bc2016-04-09 00:24:48196 std::unique_ptr<OutputSurface> output_surface,
danakja18e826a2015-12-03 00:27:03197 TaskRunnerProvider* task_runner_provider) {
danakjee6547a22016-07-01 20:41:50198 if (host_impl_)
199 host_impl_->ReleaseOutputSurface();
reveman34b7a1522015-03-23 20:27:47200 host_impl_ = LayerTreeHostImpl::Create(
danakja18e826a2015-12-03 00:27:03201 settings, this, task_runner_provider, &stats_instrumentation_,
danakjcf610582015-06-16 22:48:56202 &shared_bitmap_manager_, &gpu_memory_buffer_manager_,
loysoab32ee72016-06-08 03:33:18203 &task_graph_runner_,
204 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
danakja04855a2015-11-18 20:39:10205 output_surface_ = std::move(output_surface);
sievers71c62dd52015-10-07 01:44:39206 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:43207 bool init = host_impl_->InitializeRenderer(output_surface_.get());
[email protected]18ce59702013-04-09 04:58:40208 host_impl_->SetViewportSize(gfx::Size(10, 10));
bokan0c33a092015-07-29 18:27:56209 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
mithro0bdb49d2015-05-27 13:08:01210 // Set the BeginFrameArgs so that methods which use it are able to.
danakj12e2f6e2015-08-19 22:25:44211 host_impl_->WillBeginImplFrame(CreateBeginFrameArgsForTesting(
212 BEGINFRAME_FROM_HERE,
213 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
214 host_impl_->DidFinishImplFrame();
loyso2b91c082016-01-06 00:38:38215
loyso9556c732016-03-11 07:54:58216 timeline_ =
217 AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
218 host_impl_->animation_host()->AddAnimationTimeline(timeline_);
loyso2b91c082016-01-06 00:38:38219
[email protected]ce2e8112013-11-28 07:44:36220 return init;
[email protected]aa043632013-03-25 03:39:42221 }
222
danakj60bc3bc2016-04-09 00:24:48223 void SetupRootLayerImpl(std::unique_ptr<LayerImpl> root) {
[email protected]aa043632013-03-25 03:39:42224 root->SetPosition(gfx::PointF());
225 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:42226 root->SetDrawsContent(true);
danakj64767d902015-06-19 00:10:43227 root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
jaydasika6b5a32bf2016-04-22 21:56:36228 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:59229 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
[email protected]aa043632013-03-25 03:39:42230 }
231
sunxdb7e79432016-03-09 21:13:42232 static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) {
sunxdc044b11a2016-03-16 16:23:20233 gfx::ScrollOffset delta =
234 layer_impl->layer_tree_impl()
235 ->property_trees()
236 ->scroll_tree.GetScrollOffsetDeltaForTesting(layer_impl->id());
237 return gfx::Vector2dF(delta.x(), delta.y());
sunxdb7e79432016-03-09 21:13:42238 }
239
sunxdb2e13c92016-04-23 01:00:05240 static void ExpectClearedScrollDeltasRecursive(LayerImpl* root) {
241 for (auto* layer : *root->layer_tree_impl())
242 ASSERT_EQ(ScrollDelta(layer), gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:42243 }
244
tdresser99977952015-07-02 19:49:18245 static ::testing::AssertionResult ScrollInfoContains(
246 const ScrollAndScaleSet& scroll_info,
247 int id,
248 const gfx::Vector2d& scroll_delta) {
[email protected]aa043632013-03-25 03:39:42249 int times_encountered = 0;
250
251 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
252 if (scroll_info.scrolls[i].layer_id != id)
253 continue;
tdresser99977952015-07-02 19:49:18254
255 if (scroll_delta != scroll_info.scrolls[i].scroll_delta) {
256 return ::testing::AssertionFailure()
257 << "Expected " << scroll_delta.ToString() << ", not "
258 << scroll_info.scrolls[i].scroll_delta.ToString();
259 }
[email protected]aa043632013-03-25 03:39:42260 times_encountered++;
261 }
262
bokan4222c272016-07-18 17:24:54263 if (id == scroll_info.inner_viewport_scroll.layer_id) {
264 if (scroll_delta != scroll_info.inner_viewport_scroll.scroll_delta) {
265 return ::testing::AssertionFailure()
266 << "Expected " << scroll_delta.ToString() << ", not "
267 << scroll_info.inner_viewport_scroll.scroll_delta.ToString();
268 }
269 times_encountered++;
270 }
271
tdresser99977952015-07-02 19:49:18272 if (times_encountered != 1)
273 return ::testing::AssertionFailure() << "No layer found with id " << id;
274 return ::testing::AssertionSuccess();
[email protected]aa043632013-03-25 03:39:42275 }
276
277 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
278 int times_encountered = 0;
279
280 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
281 if (scroll_info.scrolls[i].layer_id != id)
282 continue;
283 times_encountered++;
284 }
285
286 ASSERT_EQ(0, times_encountered);
287 }
288
[email protected]7d1b07e2013-10-01 17:31:30289 LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl,
[email protected]64348ea2014-01-29 22:58:26290 const gfx::Size& content_size) {
hush33370e12015-04-07 03:49:50291 // Create both an inner viewport scroll layer and an outer viewport scroll
292 // layer. The MaxScrollOffset of the outer viewport scroll layer will be
293 // 0x0, so the scrolls will be applied directly to the inner viewport.
294 const int kOuterViewportClipLayerId = 116;
295 const int kOuterViewportScrollLayerId = 117;
296 const int kContentLayerId = 118;
[email protected]adeda572014-01-31 00:49:47297 const int kInnerViewportScrollLayerId = 2;
298 const int kInnerViewportClipLayerId = 4;
299 const int kPageScaleLayerId = 5;
hush33370e12015-04-07 03:49:50300
danakj60bc3bc2016-04-09 00:24:48301 std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
[email protected]aa043632013-03-25 03:39:42302 root->SetBounds(content_size);
[email protected]aa043632013-03-25 03:39:42303 root->SetPosition(gfx::PointF());
jaydasika6b5a32bf2016-04-22 21:56:36304 root->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:42305
danakj60bc3bc2016-04-09 00:24:48306 std::unique_ptr<LayerImpl> inner_scroll =
[email protected]adeda572014-01-31 00:49:47307 LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId);
jaydasikaca2605e2016-04-23 02:52:52308 inner_scroll->test_properties()->is_container_for_fixed_position_layers =
309 true;
sunxdb7e79432016-03-09 21:13:42310 inner_scroll->layer_tree_impl()
311 ->property_trees()
312 ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(),
313 gfx::ScrollOffset());
[email protected]adeda572014-01-31 00:49:47314
danakj60bc3bc2016-04-09 00:24:48315 std::unique_ptr<LayerImpl> inner_clip =
[email protected]adeda572014-01-31 00:49:47316 LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
hush33370e12015-04-07 03:49:50317 inner_clip->SetBounds(
[email protected]adeda572014-01-31 00:49:47318 gfx::Size(content_size.width() / 2, content_size.height() / 2));
319
danakj60bc3bc2016-04-09 00:24:48320 std::unique_ptr<LayerImpl> page_scale =
[email protected]adeda572014-01-31 00:49:47321 LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
322
hush33370e12015-04-07 03:49:50323 inner_scroll->SetScrollClipLayer(inner_clip->id());
324 inner_scroll->SetBounds(content_size);
hush33370e12015-04-07 03:49:50325 inner_scroll->SetPosition(gfx::PointF());
326
danakj60bc3bc2016-04-09 00:24:48327 std::unique_ptr<LayerImpl> outer_clip =
hush33370e12015-04-07 03:49:50328 LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
329 outer_clip->SetBounds(content_size);
jaydasikaca2605e2016-04-23 02:52:52330 outer_clip->test_properties()->is_container_for_fixed_position_layers =
331 true;
hush33370e12015-04-07 03:49:50332
danakj60bc3bc2016-04-09 00:24:48333 std::unique_ptr<LayerImpl> outer_scroll =
hush33370e12015-04-07 03:49:50334 LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
335 outer_scroll->SetScrollClipLayer(outer_clip->id());
sunxdb7e79432016-03-09 21:13:42336 outer_scroll->layer_tree_impl()
337 ->property_trees()
338 ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
339 gfx::ScrollOffset());
hush33370e12015-04-07 03:49:50340 outer_scroll->SetBounds(content_size);
hush33370e12015-04-07 03:49:50341 outer_scroll->SetPosition(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29342
danakj60bc3bc2016-04-09 00:24:48343 std::unique_ptr<LayerImpl> contents =
hush33370e12015-04-07 03:49:50344 LayerImpl::Create(layer_tree_impl, kContentLayerId);
[email protected]aa043632013-03-25 03:39:42345 contents->SetDrawsContent(true);
346 contents->SetBounds(content_size);
[email protected]aa043632013-03-25 03:39:42347 contents->SetPosition(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29348
jaydasika89f7b5a2016-06-22 02:08:39349 outer_scroll->test_properties()->AddChild(std::move(contents));
350 outer_clip->test_properties()->AddChild(std::move(outer_scroll));
351 inner_scroll->test_properties()->AddChild(std::move(outer_clip));
352 page_scale->test_properties()->AddChild(std::move(inner_scroll));
353 inner_clip->test_properties()->AddChild(std::move(page_scale));
354 root->test_properties()->AddChild(std::move(inner_clip));
[email protected]35a99a12013-05-09 23:52:29355
jaydasikabf1875a2016-06-28 03:39:59356 layer_tree_impl->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:48357 layer_tree_impl->BuildPropertyTreesForTesting();
[email protected]adeda572014-01-31 00:49:47358 layer_tree_impl->SetViewportLayersFromIds(
ccameron8230b68b2014-11-21 19:25:18359 Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId,
hush33370e12015-04-07 03:49:50360 kOuterViewportScrollLayerId);
[email protected]adeda572014-01-31 00:49:47361
hush33370e12015-04-07 03:49:50362 layer_tree_impl->DidBecomeActive();
363 return layer_tree_impl->InnerViewportScrollLayer();
[email protected]7d1b07e2013-10-01 17:31:30364 }
365
[email protected]64348ea2014-01-29 22:58:26366 LayerImpl* SetupScrollAndContentsLayers(const gfx::Size& content_size) {
[email protected]7d1b07e2013-10-01 17:31:30367 LayerImpl* scroll_layer = CreateScrollAndContentsLayers(
368 host_impl_->active_tree(), content_size);
[email protected]aa043632013-03-25 03:39:42369 host_impl_->active_tree()->DidBecomeActive();
[email protected]35a99a12013-05-09 23:52:29370 return scroll_layer;
[email protected]aa043632013-03-25 03:39:42371 }
372
bokan499dd082015-06-24 15:35:19373 // Sets up a typical virtual viewport setup with one child content layer.
374 // Returns a pointer to the content layer.
375 LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size,
376 const gfx::Size& content_size) {
377 // CreateScrollAndContentsLayers makes the outer viewport unscrollable and
378 // the inner a different size from the outer. We'll reuse its layer
379 // hierarchy but adjust the sizing to our needs.
380 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
381
jaydasikafc66cfb2016-06-10 04:34:22382 LayerImpl* content_layer = host_impl_->OuterViewportScrollLayer()
383 ->test_properties()
384 ->children.back();
bokan499dd082015-06-24 15:35:19385 content_layer->SetBounds(content_size);
386 host_impl_->OuterViewportScrollLayer()->SetBounds(content_size);
387
jaydasikaf419bf72016-06-15 10:21:21388 LayerImpl* outer_clip =
389 host_impl_->OuterViewportScrollLayer()->test_properties()->parent;
bokan499dd082015-06-24 15:35:19390 outer_clip->SetBounds(viewport_size);
391
jaydasikaf419bf72016-06-15 10:21:21392 LayerImpl* inner_clip_layer = host_impl_->InnerViewportScrollLayer()
393 ->test_properties()
394 ->parent->test_properties()
395 ->parent;
bokan499dd082015-06-24 15:35:19396 inner_clip_layer->SetBounds(viewport_size);
397 host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size);
vollickef2ae922016-06-29 17:54:27398
399 // Needs to happen before building property trees as the latter propagates
400 // these element ids to property tree nodes.
401 host_impl_->active_tree()->SetElementIdsForTesting();
danakj74af409e2016-07-01 00:41:48402 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan499dd082015-06-24 15:35:19403
404 host_impl_->SetViewportSize(viewport_size);
405 host_impl_->active_tree()->DidBecomeActive();
406
407 return content_layer;
408 }
409
danakj60bc3bc2016-04-09 00:24:48410 std::unique_ptr<LayerImpl> CreateScrollableLayer(int id,
411 const gfx::Size& size,
412 LayerImpl* clip_layer) {
[email protected]adeda572014-01-31 00:49:47413 DCHECK(clip_layer);
414 DCHECK(id != clip_layer->id());
danakj60bc3bc2016-04-09 00:24:48415 std::unique_ptr<LayerImpl> layer =
[email protected]aa043632013-03-25 03:39:42416 LayerImpl::Create(host_impl_->active_tree(), id);
[email protected]adeda572014-01-31 00:49:47417 layer->SetScrollClipLayer(clip_layer->id());
[email protected]aa043632013-03-25 03:39:42418 layer->SetDrawsContent(true);
419 layer->SetBounds(size);
[email protected]adeda572014-01-31 00:49:47420 clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2));
danakja04855a2015-11-18 20:39:10421 return layer;
[email protected]aa043632013-03-25 03:39:42422 }
423
danakj60bc3bc2016-04-09 00:24:48424 std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) {
tdresserebe6e34c2016-02-10 18:46:06425 ScrollStateData scroll_state_data;
426 scroll_state_data.is_beginning = true;
bokan578ff4a2016-04-12 21:54:05427 scroll_state_data.position_x = point.x();
428 scroll_state_data.position_y = point.y();
danakj60bc3bc2016-04-09 00:24:48429 std::unique_ptr<ScrollState> scroll_state(
430 new ScrollState(scroll_state_data));
tdresserebe6e34c2016-02-10 18:46:06431 return scroll_state;
majidvp944a8cd2016-01-12 21:05:18432 }
433
danakj60bc3bc2016-04-09 00:24:48434 std::unique_ptr<ScrollState> UpdateState(const gfx::Point& point,
435 const gfx::Vector2dF& delta) {
tdresserebe6e34c2016-02-10 18:46:06436 ScrollStateData scroll_state_data;
437 scroll_state_data.delta_x = delta.x();
438 scroll_state_data.delta_y = delta.y();
bokan578ff4a2016-04-12 21:54:05439 scroll_state_data.position_x = point.x();
440 scroll_state_data.position_y = point.y();
danakj60bc3bc2016-04-09 00:24:48441 std::unique_ptr<ScrollState> scroll_state(
442 new ScrollState(scroll_state_data));
tdresserebe6e34c2016-02-10 18:46:06443 return scroll_state;
majidvp944a8cd2016-01-12 21:05:18444 }
445
danakj60bc3bc2016-04-09 00:24:48446 std::unique_ptr<ScrollState> EndState() {
tdresserebe6e34c2016-02-10 18:46:06447 ScrollStateData scroll_state_data;
448 scroll_state_data.is_ending = true;
danakj60bc3bc2016-04-09 00:24:48449 std::unique_ptr<ScrollState> scroll_state(
450 new ScrollState(scroll_state_data));
tdresserebe6e34c2016-02-10 18:46:06451 return scroll_state;
majidvp944a8cd2016-01-12 21:05:18452 }
453
[email protected]fbe89f72013-05-21 07:24:24454 void DrawFrame() {
[email protected]aa043632013-03-25 03:39:42455 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:48456 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:45457 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:42458 host_impl_->DidDrawAllLayers(frame);
[email protected]aa043632013-03-25 03:39:42459 }
460
461 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor);
462 void pinch_zoom_pan_viewport_test(float device_scale_factor);
463 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor);
464 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
465 float device_scale_factor);
466
[email protected]bf1cfd9a2013-09-26 05:43:02467 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
468
loyso2b91c082016-01-06 00:38:38469 scoped_refptr<AnimationTimeline> timeline() { return timeline_; }
470
[email protected]aa043632013-03-25 03:39:42471 protected:
danakj60bc3bc2016-04-09 00:24:48472 virtual std::unique_ptr<OutputSurface> CreateOutputSurface() {
danakjf33ceec2016-07-20 20:04:45473 return FakeOutputSurface::CreateDelegating3d();
[email protected]aa043632013-03-25 03:39:42474 }
475
476 void DrawOneFrame() {
477 LayerTreeHostImpl::FrameData frame_data;
danakj74af409e2016-07-01 00:41:48478 host_impl_->PrepareToDraw(&frame_data);
[email protected]aa043632013-03-25 03:39:42479 host_impl_->DidDrawAllLayers(frame_data);
480 }
481
sunxdb7e79432016-03-09 21:13:42482 static void SetScrollOffsetDelta(LayerImpl* layer_impl,
483 const gfx::Vector2dF& delta) {
sunxdc044b11a2016-03-16 16:23:20484 if (layer_impl->layer_tree_impl()
485 ->property_trees()
486 ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
487 delta))
488 layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
489 layer_impl->id(), layer_impl->transform_tree_index());
sunxdb7e79432016-03-09 21:13:42490 }
491
ymalik99740e852016-04-07 04:18:13492 void BeginImplFrameAndAnimate(BeginFrameArgs begin_frame_args,
493 base::TimeTicks frame_time) {
494 begin_frame_args.frame_time = frame_time;
495 host_impl_->WillBeginImplFrame(begin_frame_args);
496 host_impl_->Animate();
497 host_impl_->UpdateAnimationState(true);
498 host_impl_->DidFinishImplFrame();
499 }
500
khushalsagarb7db1fe2015-11-12 00:51:27501 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]aa043632013-03-25 03:39:42502 DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
503
danakjcf610582015-06-16 22:48:56504 TestSharedBitmapManager shared_bitmap_manager_;
505 TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
506 TestTaskGraphRunner task_graph_runner_;
danakj60bc3bc2016-04-09 00:24:48507 std::unique_ptr<OutputSurface> output_surface_;
508 std::unique_ptr<LayerTreeHostImpl> host_impl_;
[email protected]aa043632013-03-25 03:39:42509 FakeRenderingStatsInstrumentation stats_instrumentation_;
510 bool on_can_draw_state_changed_called_;
[email protected]4f48f6e2013-08-27 06:33:38511 bool did_notify_ready_to_activate_;
[email protected]aa043632013-03-25 03:39:42512 bool did_request_commit_;
513 bool did_request_redraw_;
danakja18e826a2015-12-03 00:27:03514 bool did_request_next_frame_;
vmiura59ea9b4042014-12-09 20:50:39515 bool did_request_prepare_tiles_;
rouslanf7ebd8832015-01-22 01:54:14516 bool did_complete_page_scale_animation_;
[email protected]aa043632013-03-25 03:39:42517 bool reduce_memory_result_;
sunnypsae4316a2015-02-25 00:54:58518 base::Closure animation_task_;
519 base::TimeDelta requested_animation_delay_;
danakj60bc3bc2016-04-09 00:24:48520 std::unique_ptr<LayerTreeHostImpl::FrameData> last_on_draw_frame_;
boliu7097ee5b2015-12-17 03:16:09521 RenderPassList last_on_draw_render_passes_;
loyso2b91c082016-01-06 00:38:38522 scoped_refptr<AnimationTimeline> timeline_;
[email protected]aa043632013-03-25 03:39:42523};
524
loysoce3bb822015-07-08 02:40:47525// A test fixture for new animation timelines tests.
526class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest {
527 public:
528 void SetUp() override {
loyso0940d412016-03-14 01:30:31529 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
loysoce3bb822015-07-08 02:40:47530 }
531};
532
[email protected]6133cc232013-07-30 18:47:07533TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
boliu7097ee5b2015-12-17 03:16:09534 // Note: It is not possible to disable the renderer once it has been set,
535 // so we do not need to test that disabling the renderer notifies us
536 // that can_draw changed.
537 EXPECT_FALSE(host_impl_->CanDraw());
538 on_can_draw_state_changed_called_ = false;
539
540 // Set up the root layer, which allows us to draw.
541 SetupScrollAndContentsLayers(gfx::Size(100, 100));
542 EXPECT_TRUE(host_impl_->CanDraw());
543 EXPECT_TRUE(on_can_draw_state_changed_called_);
544 on_can_draw_state_changed_called_ = false;
545
546 // Toggle the root layer to make sure it toggles can_draw
jaydasikabf1875a2016-06-28 03:39:59547 host_impl_->active_tree()->SetRootLayerForTesting(nullptr);
rockot2176f922016-06-08 19:18:32548 host_impl_->active_tree()->DetachLayers();
boliu7097ee5b2015-12-17 03:16:09549 EXPECT_FALSE(host_impl_->CanDraw());
550 EXPECT_TRUE(on_can_draw_state_changed_called_);
551 on_can_draw_state_changed_called_ = false;
552
553 SetupScrollAndContentsLayers(gfx::Size(100, 100));
554 EXPECT_TRUE(host_impl_->CanDraw());
555 EXPECT_TRUE(on_can_draw_state_changed_called_);
556 on_can_draw_state_changed_called_ = false;
557
558 // Toggle the device viewport size to make sure it toggles can_draw.
559 host_impl_->SetViewportSize(gfx::Size());
560 EXPECT_FALSE(host_impl_->CanDraw());
561 EXPECT_TRUE(on_can_draw_state_changed_called_);
562 on_can_draw_state_changed_called_ = false;
563
564 host_impl_->SetViewportSize(gfx::Size(100, 100));
565 EXPECT_TRUE(host_impl_->CanDraw());
566 EXPECT_TRUE(on_can_draw_state_changed_called_);
567 on_can_draw_state_changed_called_ = false;
[email protected]6133cc232013-07-30 18:47:07568}
569
boliu7097ee5b2015-12-17 03:16:09570TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) {
danakjf446a072014-09-27 21:55:48571 CreateHostImpl(DefaultSettings(),
danakj6021ec32016-07-22 22:16:08572 FakeOutputSurface::CreateDelegatingSoftware());
boliu7097ee5b2015-12-17 03:16:09573 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:48574 host_impl_->active_tree()->BuildPropertyTreesForTesting();
575
boliu7097ee5b2015-12-17 03:16:09576 EXPECT_TRUE(host_impl_->CanDraw());
577 host_impl_->SetViewportSize(gfx::Size());
578 EXPECT_FALSE(host_impl_->CanDraw());
[email protected]6133cc232013-07-30 18:47:07579
boliu7097ee5b2015-12-17 03:16:09580 FakeOutputSurface* fake_output_surface =
581 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
582 EXPECT_EQ(fake_output_surface->num_sent_frames(), 0u);
583 gfx::Transform identity;
584 gfx::Rect viewport(100, 100);
585 const bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:59586 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:09587 ASSERT_EQ(fake_output_surface->num_sent_frames(), 1u);
588 EXPECT_EQ(gfx::SizeF(100.f, 100.f),
fsamueld63137a2016-06-24 23:39:51589 fake_output_surface->last_sent_frame()->metadata.root_layer_size);
[email protected]6133cc232013-07-30 18:47:07590}
591
[email protected]aa043632013-03-25 03:39:42592TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) {
jaydasikabf1875a2016-06-28 03:39:59593 ASSERT_FALSE(host_impl_->active_tree()->root_layer_for_testing());
[email protected]94f206c12012-08-25 00:09:14594
danakj60bc3bc2016-04-09 00:24:48595 std::unique_ptr<ScrollAndScaleSet> scroll_info =
596 host_impl_->ProcessScrollDeltas();
[email protected]aa043632013-03-25 03:39:42597 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
[email protected]94f206c12012-08-25 00:09:14598}
599
[email protected]aa043632013-03-25 03:39:42600TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
601 {
danakj60bc3bc2016-04-09 00:24:48602 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:42603 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika89f7b5a2016-06-22 02:08:39604 root->test_properties()->AddChild(
605 LayerImpl::Create(host_impl_->active_tree(), 2));
606 root->test_properties()->AddChild(
607 LayerImpl::Create(host_impl_->active_tree(), 3));
608 root->test_properties()->children[1]->test_properties()->AddChild(
[email protected]aa043632013-03-25 03:39:42609 LayerImpl::Create(host_impl_->active_tree(), 4));
jaydasika89f7b5a2016-06-22 02:08:39610 root->test_properties()->children[1]->test_properties()->AddChild(
[email protected]aa043632013-03-25 03:39:42611 LayerImpl::Create(host_impl_->active_tree(), 5));
jaydasikafc66cfb2016-06-10 04:34:22612 root->test_properties()
613 ->children[1]
614 ->test_properties()
615 ->children[0]
jaydasika89f7b5a2016-06-22 02:08:39616 ->test_properties()
jaydasikafc66cfb2016-06-10 04:34:22617 ->AddChild(LayerImpl::Create(host_impl_->active_tree(), 6));
jaydasikabf1875a2016-06-28 03:39:59618 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
[email protected]aa043632013-03-25 03:39:42619 }
danakj74af409e2016-07-01 00:41:48620 LayerImpl* root = *host_impl_->active_tree()->begin();
[email protected]94f206c12012-08-25 00:09:14621
[email protected]aa043632013-03-25 03:39:42622 ExpectClearedScrollDeltasRecursive(root);
[email protected]0ede3bb2012-12-09 09:14:39623
danakj60bc3bc2016-04-09 00:24:48624 std::unique_ptr<ScrollAndScaleSet> scroll_info;
[email protected]aa043632013-03-25 03:39:42625
626 scroll_info = host_impl_->ProcessScrollDeltas();
627 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
628 ExpectClearedScrollDeltasRecursive(root);
629
630 scroll_info = host_impl_->ProcessScrollDeltas();
631 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
632 ExpectClearedScrollDeltasRecursive(root);
[email protected]94f206c12012-08-25 00:09:14633}
634
[email protected]aa043632013-03-25 03:39:42635TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
miletusf57925d2014-10-01 19:38:13636 gfx::ScrollOffset scroll_offset(20, 30);
[email protected]aa043632013-03-25 03:39:42637 gfx::Vector2d scroll_delta(11, -15);
sunxd676696572016-01-07 16:28:30638
danakj74af409e2016-07-01 00:41:48639 auto root_clip_owned = LayerImpl::Create(host_impl_->active_tree(), 2);
640 auto* root_clip = root_clip_owned.get();
641 auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1);
642 auto* root = root_owned.get();
643
644 root_clip->SetBounds(gfx::Size(10, 10));
645 root_clip->test_properties()->AddChild(std::move(root_owned));
646 root->SetBounds(gfx::Size(110, 110));
647 root->SetScrollClipLayer(root_clip->id());
648 root->layer_tree_impl()
649 ->property_trees()
650 ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->id(), scroll_offset);
651 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip_owned));
652 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:14653
danakj60bc3bc2016-04-09 00:24:48654 std::unique_ptr<ScrollAndScaleSet> scroll_info;
[email protected]94f206c12012-08-25 00:09:14655
danakj74af409e2016-07-01 00:41:48656 root->ScrollBy(scroll_delta);
[email protected]aa043632013-03-25 03:39:42657 scroll_info = host_impl_->ProcessScrollDeltas();
658 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
tdresser99977952015-07-02 19:49:18659 EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), scroll_delta));
[email protected]94f206c12012-08-25 00:09:14660
[email protected]aa043632013-03-25 03:39:42661 gfx::Vector2d scroll_delta2(-5, 27);
662 root->ScrollBy(scroll_delta2);
663 scroll_info = host_impl_->ProcessScrollDeltas();
664 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
tdresser99977952015-07-02 19:49:18665 EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
666 scroll_delta + scroll_delta2));
[email protected]aa043632013-03-25 03:39:42667
668 root->ScrollBy(gfx::Vector2d());
669 scroll_info = host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:18670 EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
671 scroll_delta + scroll_delta2));
[email protected]94f206c12012-08-25 00:09:14672}
673
[email protected]aa043632013-03-25 03:39:42674TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
675 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:48676 host_impl_->active_tree()->BuildPropertyTreesForTesting();
677
[email protected]18ce59702013-04-09 04:58:40678 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36679 DrawFrame();
[email protected]94f206c12012-08-25 00:09:14680
tdresser81e84c672016-01-18 23:21:22681 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
682 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
683 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40684 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22685 status.main_thread_scrolling_reasons);
686
[email protected]edcc1a12014-05-06 01:26:39687 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
ericrk7c030992015-02-20 01:39:38688 InputHandler::WHEEL));
majidvp944a8cd2016-01-12 21:05:18689 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
[email protected]edcc1a12014-05-06 01:26:39690 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
ericrk7c030992015-02-20 01:39:38691 InputHandler::WHEEL));
majidvp944a8cd2016-01-12 21:05:18692 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:49693 host_impl_->ClearCurrentlyScrollingLayerForTesting();
[email protected]edcc1a12014-05-06 01:26:39694 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
ericrk7c030992015-02-20 01:39:38695 InputHandler::WHEEL));
[email protected]aa043632013-03-25 03:39:42696 EXPECT_TRUE(did_request_redraw_);
697 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:14698}
699
jdduke16dde6e2014-10-24 00:22:56700TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) {
701 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:48702 host_impl_->active_tree()->BuildPropertyTreesForTesting();
703
jdduke16dde6e2014-10-24 00:22:56704 host_impl_->SetViewportSize(gfx::Size(50, 50));
705 DrawFrame();
706
tdresser81e84c672016-01-18 23:21:22707 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
708 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
709 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40710 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22711 status.main_thread_scrolling_reasons);
712
jdduke16dde6e2014-10-24 00:22:56713 EXPECT_FALSE(host_impl_->IsActivelyScrolling());
majidvp944a8cd2016-01-12 21:05:18714 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
jdduke16dde6e2014-10-24 00:22:56715 EXPECT_TRUE(host_impl_->IsActivelyScrolling());
majidvp944a8cd2016-01-12 21:05:18716 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:49717 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke16dde6e2014-10-24 00:22:56718 EXPECT_FALSE(host_impl_->IsActivelyScrolling());
719}
720
[email protected]aa043632013-03-25 03:39:42721TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
722 // We should not crash when trying to scroll an empty layer tree.
tdresser81e84c672016-01-18 23:21:22723 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
724 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
725 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40726 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22727 status.main_thread_scrolling_reasons);
[email protected]94f206c12012-08-25 00:09:14728}
729
[email protected]aa043632013-03-25 03:39:42730TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
danakj60bc3bc2016-04-09 00:24:48731 std::unique_ptr<TestWebGraphicsContext3D> context_owned =
[email protected]0634cdd42013-08-16 00:46:09732 TestWebGraphicsContext3D::Create();
[email protected]c9addd12013-12-08 22:43:26733 context_owned->set_context_lost(true);
[email protected]0634cdd42013-08-16 00:46:09734
[email protected]ce2e8112013-11-28 07:44:36735 // Initialization will fail.
danakjf33ceec2016-07-20 20:04:45736 EXPECT_FALSE(CreateHostImpl(
737 DefaultSettings(),
738 FakeOutputSurface::CreateDelegating3d(std::move(context_owned))));
[email protected]a90aa702012-11-07 04:48:24739
[email protected]aa043632013-03-25 03:39:42740 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:14741
[email protected]aa043632013-03-25 03:39:42742 // We should not crash when trying to scroll after the renderer initialization
743 // fails.
tdresser81e84c672016-01-18 23:21:22744 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
745 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
746 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40747 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22748 status.main_thread_scrolling_reasons);
[email protected]94f206c12012-08-25 00:09:14749}
750
[email protected]aa043632013-03-25 03:39:42751TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
[email protected]35a99a12013-05-09 23:52:29752 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40753 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36754 DrawFrame();
[email protected]a9710962012-11-14 20:11:02755
[email protected]aa043632013-03-25 03:39:42756 // We should not crash if the tree is replaced while we are scrolling.
tdresser81e84c672016-01-18 23:21:22757 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:18758 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:22759 InputHandler::WHEEL)
760 .thread);
rockot2176f922016-06-08 19:18:32761 host_impl_->active_tree()->DetachLayers();
[email protected]aa043632013-03-25 03:39:42762
[email protected]35a99a12013-05-09 23:52:29763 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42764
765 // We should still be scrolling, because the scrolled layer also exists in the
766 // new tree.
767 gfx::Vector2d scroll_delta(0, 10);
majidvp944a8cd2016-01-12 21:05:18768 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
769 host_impl_->ScrollEnd(EndState().get());
danakj60bc3bc2016-04-09 00:24:48770 std::unique_ptr<ScrollAndScaleSet> scroll_info =
771 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:18772 EXPECT_TRUE(
773 ScrollInfoContains(*scroll_info, scroll_layer->id(), scroll_delta));
[email protected]aa043632013-03-25 03:39:42774}
775
rbyers18779d822015-02-05 06:22:06776TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) {
[email protected]aa043632013-03-25 03:39:42777 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40778 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36779 DrawFrame();
[email protected]aa043632013-03-25 03:39:42780
dtapuskae7dd21de2016-06-09 13:41:56781 // Wheel handlers determine whether mouse events block scroll.
dtapuskaf206a40d2016-02-05 21:36:02782 host_impl_->active_tree()->set_event_listener_properties(
783 EventListenerClass::kMouseWheel, EventListenerProperties::kBlocking);
dtapuskae7dd21de2016-06-09 13:41:56784 EXPECT_EQ(
785 EventListenerProperties::kBlocking,
786 host_impl_->GetEventListenerProperties(EventListenerClass::kMouseWheel));
787
788 // But they don't influence the actual handling of the scroll gestures.
dtapuskacd4231232016-01-28 19:18:11789 InputHandler::ScrollStatus status =
790 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:22791 InputHandler::WHEEL);
tdresser81e84c672016-01-18 23:21:22792 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40793 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22794 status.main_thread_scrolling_reasons);
majidvp944a8cd2016-01-12 21:05:18795 host_impl_->ScrollEnd(EndState().get());
rbyers18779d822015-02-05 06:22:06796}
797
798TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) {
799 LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100));
800 host_impl_->SetViewportSize(gfx::Size(50, 50));
801 DrawFrame();
jaydasikabf1875a2016-06-28 03:39:59802 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
rbyers18779d822015-02-05 06:22:06803
804 LayerImpl* child = 0;
805 {
danakj60bc3bc2016-04-09 00:24:48806 std::unique_ptr<LayerImpl> child_layer =
rbyers18779d822015-02-05 06:22:06807 LayerImpl::Create(host_impl_->active_tree(), 6);
808 child = child_layer.get();
809 child_layer->SetDrawsContent(true);
810 child_layer->SetPosition(gfx::PointF(0, 20));
811 child_layer->SetBounds(gfx::Size(50, 50));
jaydasika89f7b5a2016-06-22 02:08:39812 scroll->test_properties()->AddChild(std::move(child_layer));
danakj74af409e2016-07-01 00:41:48813 host_impl_->active_tree()->BuildPropertyTreesForTesting();
rbyers18779d822015-02-05 06:22:06814 }
815
816 // Touch handler regions determine whether touch events block scroll.
817 root->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
rbyers18779d822015-02-05 06:22:06818 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 10)));
819
820 // But they don't influence the actual handling of the scroll gestures.
tdresser81e84c672016-01-18 23:21:22821 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
dtapuska40e8aff2016-03-11 21:45:03822 BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22823 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40824 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22825 status.main_thread_scrolling_reasons);
majidvp944a8cd2016-01-12 21:05:18826 host_impl_->ScrollEnd(EndState().get());
rbyers18779d822015-02-05 06:22:06827
rbyers18779d822015-02-05 06:22:06828 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
dtapuskacd4231232016-01-28 19:18:11829 root->SetTouchEventHandlerRegion(gfx::Rect());
rbyers18779d822015-02-05 06:22:06830 EXPECT_FALSE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
dtapuskacd4231232016-01-28 19:18:11831 child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
rbyers18779d822015-02-05 06:22:06832 EXPECT_TRUE(host_impl_->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
833}
834
[email protected]7c45d8152013-04-23 18:27:21835TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) {
836 SetupScrollAndContentsLayers(gfx::Size(100, 100));
837 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36838 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21839
840 // Ignore the fling since no layer is being scrolled
tdresser81e84c672016-01-18 23:21:22841 InputHandler::ScrollStatus status = host_impl_->FlingScrollBegin();
842 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40843 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22844 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21845
846 // Start scrolling a layer
tdresser81e84c672016-01-18 23:21:22847 status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:03848 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22849 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40850 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22851 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21852
853 // Now the fling should go ahead since we've started scrolling a layer
tdresser81e84c672016-01-18 23:21:22854 status = host_impl_->FlingScrollBegin();
855 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40856 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22857 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21858}
859
860TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) {
861 SetupScrollAndContentsLayers(gfx::Size(100, 100));
862 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36863 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21864
865 // Ignore the fling since no layer is being scrolled
tdresser81e84c672016-01-18 23:21:22866 InputHandler::ScrollStatus status = host_impl_->FlingScrollBegin();
867 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40868 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22869 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21870
871 // Start scrolling a layer
tdresser81e84c672016-01-18 23:21:22872 status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
873 InputHandler::WHEEL);
874 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40875 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22876 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21877
878 // Now the fling should go ahead since we've started scrolling a layer
tdresser81e84c672016-01-18 23:21:22879 status = host_impl_->FlingScrollBegin();
880 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:40881 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:22882 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21883}
884
885TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) {
886 SetupScrollAndContentsLayers(gfx::Size(100, 100));
887 host_impl_->SetViewportSize(gfx::Size(50, 50));
jaydasikabf1875a2016-06-28 03:39:59888 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]7c45d8152013-04-23 18:27:21889
tdresser81e84c672016-01-18 23:21:22890 root->set_main_thread_scrolling_reasons(
danakj35904762016-01-21 20:49:40891 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
danakj74af409e2016-07-01 00:41:48892 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]7c45d8152013-04-23 18:27:21893
sunxdd1abacf2016-02-16 22:08:30894 DrawFrame();
895
[email protected]7c45d8152013-04-23 18:27:21896 // Start scrolling a layer
tdresser81e84c672016-01-18 23:21:22897 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
dtapuska40e8aff2016-03-11 21:45:03898 BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22899 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:40900 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:22901 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21902
903 // The fling should be ignored since there's no layer being scrolled impl-side
tdresser81e84c672016-01-18 23:21:22904 status = host_impl_->FlingScrollBegin();
905 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:40906 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:22907 status.main_thread_scrolling_reasons);
[email protected]7c45d8152013-04-23 18:27:21908}
909
[email protected]aa043632013-03-25 03:39:42910TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
911 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40912 host_impl_->SetViewportSize(gfx::Size(50, 50));
jaydasikabf1875a2016-06-28 03:39:59913 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]aa043632013-03-25 03:39:42914
tdresser81e84c672016-01-18 23:21:22915 root->set_main_thread_scrolling_reasons(
danakj35904762016-01-21 20:49:40916 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
danakj74af409e2016-07-01 00:41:48917 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxdd1abacf2016-02-16 22:08:30918 DrawFrame();
[email protected]aa043632013-03-25 03:39:42919
tdresser81e84c672016-01-18 23:21:22920 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
921 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
922 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:40923 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:22924 status.main_thread_scrolling_reasons);
925
926 status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:03927 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:22928 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:40929 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:22930 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:42931}
932
sunxd0b34eb52016-04-13 01:13:39933TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) {
934 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
935 gfx::Size content_size = gfx::Size(360, 600);
936 gfx::Size scroll_content_size = gfx::Size(345, 3800);
937 gfx::Size scrollbar_size = gfx::Size(15, 600);
938
939 host_impl_->SetViewportSize(content_size);
940 std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1);
941 root->SetBounds(content_size);
942 root->SetPosition(gfx::PointF());
943
944 std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2);
945 clip->SetBounds(content_size);
946 clip->SetPosition(gfx::PointF());
947
948 std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3);
949 scroll->SetBounds(scroll_content_size);
950 scroll->SetScrollClipLayer(clip->id());
951 scroll->SetDrawsContent(true);
952
953 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
954 SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0,
955 false, true);
956 scrollbar->SetBounds(scrollbar_size);
957 scrollbar->SetPosition(gfx::PointF(345, 0));
958 scrollbar->SetScrollLayerId(scroll->id());
sunxd0b34eb52016-04-13 01:13:39959 scrollbar->SetDrawsContent(true);
jaydasikaab317e02016-06-01 00:53:18960 scrollbar->test_properties()->opacity = 1.f;
sunxd0b34eb52016-04-13 01:13:39961
962 std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5);
963 squash1->SetBounds(gfx::Size(140, 300));
964 squash1->SetPosition(gfx::PointF(220, 0));
965 squash1->SetDrawsContent(true);
966
967 std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6);
968 squash2->SetBounds(gfx::Size(140, 300));
969 squash2->SetPosition(gfx::PointF(220, 300));
970 squash2->SetDrawsContent(true);
971
jaydasika89f7b5a2016-06-22 02:08:39972 scroll->test_properties()->AddChild(std::move(squash2));
973 clip->test_properties()->AddChild(std::move(scroll));
974 clip->test_properties()->AddChild(std::move(scrollbar));
975 clip->test_properties()->AddChild(std::move(squash1));
976 root->test_properties()->AddChild(std::move(clip));
sunxd0b34eb52016-04-13 01:13:39977
jaydasikabf1875a2016-06-28 03:39:59978 layer_tree_impl->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:48979 layer_tree_impl->BuildPropertyTreesForTesting();
sunxd0b34eb52016-04-13 01:13:39980 layer_tree_impl->DidBecomeActive();
981
982 // The point hits squash1 layer and also scroll layer, because scroll layer is
983 // not an ancestor of squash1 layer, we cannot scroll on impl thread.
984 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
985 BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL);
986 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
987 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
988 status.main_thread_scrolling_reasons);
989
990 // The point hits squash1 layer and also scrollbar layer.
991 status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(),
992 InputHandler::WHEEL);
993 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
994 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
995 status.main_thread_scrolling_reasons);
996
997 // The point hits squash2 layer and also scroll layer, because scroll layer is
998 // an ancestor of squash2 layer, we should scroll on impl.
999 status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(),
1000 InputHandler::WHEEL);
1001 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
1002}
1003
[email protected]aa043632013-03-25 03:39:421004TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
1005 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:401006 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:421007
jaydasikabf1875a2016-06-28 03:39:591008 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]aa043632013-03-25 03:39:421009 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
1010
danakj74af409e2016-07-01 00:41:481011 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ce2e8112013-11-28 07:44:361012 DrawFrame();
[email protected]aa043632013-03-25 03:39:421013
1014 // All scroll types inside the non-fast scrollable region should fail.
tdresser81e84c672016-01-18 23:21:221015 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
1016 BeginState(gfx::Point(25, 25)).get(), InputHandler::WHEEL);
1017 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:401018 EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
tdresser81e84c672016-01-18 23:21:221019 status.main_thread_scrolling_reasons);
[email protected]edcc1a12014-05-06 01:26:391020 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
ericrk7c030992015-02-20 01:39:381021 InputHandler::WHEEL));
tdresser81e84c672016-01-18 23:21:221022
1023 status = host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(),
dtapuska40e8aff2016-03-11 21:45:031024 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:221025 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:401026 EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
tdresser81e84c672016-01-18 23:21:221027 status.main_thread_scrolling_reasons);
dtapuska40e8aff2016-03-11 21:45:031028 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1029 gfx::Point(25, 25), InputHandler::TOUCHSCREEN));
[email protected]aa043632013-03-25 03:39:421030
1031 // All scroll types outside this region should succeed.
tdresser81e84c672016-01-18 23:21:221032 status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
1033 InputHandler::WHEEL);
1034 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401035 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221036 status.main_thread_scrolling_reasons);
1037
dtapuska40e8aff2016-03-11 21:45:031038 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
1039 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
majidvp944a8cd2016-01-12 21:05:181040 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
dtapuska40e8aff2016-03-11 21:45:031041 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1042 gfx::Point(25, 25), InputHandler::TOUCHSCREEN));
majidvp944a8cd2016-01-12 21:05:181043 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:491044 host_impl_->ClearCurrentlyScrollingLayerForTesting();
dtapuska40e8aff2016-03-11 21:45:031045 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1046 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
tdresser81e84c672016-01-18 23:21:221047
1048 status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
dtapuska40e8aff2016-03-11 21:45:031049 InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:221050 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401051 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221052 status.main_thread_scrolling_reasons);
dtapuska40e8aff2016-03-11 21:45:031053 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
1054 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
majidvp944a8cd2016-01-12 21:05:181055 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
1056 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:491057 host_impl_->ClearCurrentlyScrollingLayerForTesting();
dtapuska40e8aff2016-03-11 21:45:031058 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
1059 gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
[email protected]aa043632013-03-25 03:39:421060}
1061
1062TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
1063 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:401064 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:421065
danakj74af409e2016-07-01 00:41:481066 LayerImpl* root = *host_impl_->active_tree()->begin();
[email protected]aa043632013-03-25 03:39:421067 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
1068 root->SetPosition(gfx::PointF(-25.f, 0.f));
jaydasikad7dea632015-11-06 04:40:121069 root->SetDrawsContent(true);
[email protected]aa043632013-03-25 03:39:421070
danakj74af409e2016-07-01 00:41:481071 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ce2e8112013-11-28 07:44:361072 DrawFrame();
[email protected]aa043632013-03-25 03:39:421073
1074 // This point would fall into the non-fast scrollable region except that we've
1075 // moved the layer down by 25 pixels.
tdresser81e84c672016-01-18 23:21:221076 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
1077 BeginState(gfx::Point(40, 10)).get(), InputHandler::WHEEL);
1078 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401079 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221080 status.main_thread_scrolling_reasons);
1081
[email protected]edcc1a12014-05-06 01:26:391082 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
ericrk7c030992015-02-20 01:39:381083 InputHandler::WHEEL));
majidvp944a8cd2016-01-12 21:05:181084 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 1)).get());
1085 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:421086
1087 // This point is still inside the non-fast region.
tdresser81e84c672016-01-18 23:21:221088 status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
1089 InputHandler::WHEEL);
1090 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:401091 EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
tdresser81e84c672016-01-18 23:21:221092 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:421093}
1094
[email protected]f161ca9e2014-04-01 13:57:011095TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) {
dtapuskaf024e552016-02-03 01:19:461096 SetupScrollAndContentsLayers(gfx::Size(200, 200));
1097 EXPECT_FALSE(host_impl_->active_tree()->have_scroll_event_handlers());
[email protected]f161ca9e2014-04-01 13:57:011098 host_impl_->SetViewportSize(gfx::Size(50, 50));
1099 DrawFrame();
1100
1101 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181102 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:031103 InputHandler::TOUCHSCREEN);
[email protected]f161ca9e2014-04-01 13:57:011104 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181105 host_impl_->ScrollEnd(EndState().get());
[email protected]f161ca9e2014-04-01 13:57:011106 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
1107}
1108
1109TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) {
dtapuskaf024e552016-02-03 01:19:461110 SetupScrollAndContentsLayers(gfx::Size(200, 200));
1111 host_impl_->active_tree()->set_have_scroll_event_handlers(true);
[email protected]f161ca9e2014-04-01 13:57:011112 host_impl_->SetViewportSize(gfx::Size(50, 50));
1113 DrawFrame();
1114
1115 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181116 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:031117 InputHandler::TOUCHSCREEN);
[email protected]f161ca9e2014-04-01 13:57:011118 EXPECT_TRUE(host_impl_->scroll_affects_scroll_handler());
majidvp944a8cd2016-01-12 21:05:181119 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:491120 host_impl_->ClearCurrentlyScrollingLayerForTesting();
[email protected]f161ca9e2014-04-01 13:57:011121 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
1122}
1123
[email protected]aa043632013-03-25 03:39:421124TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
1125 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:401126 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:421127
[email protected]ce2e8112013-11-28 07:44:361128 DrawFrame();
[email protected]aa043632013-03-25 03:39:421129
tdresser81e84c672016-01-18 23:21:221130 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
dtapuska40e8aff2016-03-11 21:45:031131 BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
tdresser81e84c672016-01-18 23:21:221132 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
danakj35904762016-01-21 20:49:401133 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
tdresser81e84c672016-01-18 23:21:221134 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:421135
1136 // Trying to scroll to the left/top will not succeed.
ccameron36d091f2014-11-07 03:18:501137 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:181138 host_impl_->ScrollBy(
1139 UpdateState(gfx::Point(), gfx::Vector2d(-10, 0)).get())
1140 .did_scroll);
ccameron36d091f2014-11-07 03:18:501141 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:181142 host_impl_->ScrollBy(
1143 UpdateState(gfx::Point(), gfx::Vector2d(0, -10)).get())
1144 .did_scroll);
ccameron36d091f2014-11-07 03:18:501145 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:181146 host_impl_->ScrollBy(
1147 UpdateState(gfx::Point(), gfx::Vector2d(-10, -10)).get())
1148 .did_scroll);
[email protected]aa043632013-03-25 03:39:421149
1150 // Scrolling to the right/bottom will succeed.
ccameron36d091f2014-11-07 03:18:501151 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181152 host_impl_->ScrollBy(
1153 UpdateState(gfx::Point(), gfx::Vector2d(10, 0)).get())
1154 .did_scroll);
ccameron36d091f2014-11-07 03:18:501155 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181156 host_impl_->ScrollBy(
1157 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
1158 .did_scroll);
ccameron36d091f2014-11-07 03:18:501159 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181160 host_impl_->ScrollBy(
1161 UpdateState(gfx::Point(), gfx::Vector2d(10, 10)).get())
1162 .did_scroll);
[email protected]aa043632013-03-25 03:39:421163
1164 // Scrolling to left/top will now succeed.
ccameron36d091f2014-11-07 03:18:501165 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181166 host_impl_->ScrollBy(
1167 UpdateState(gfx::Point(), gfx::Vector2d(-10, 0)).get())
1168 .did_scroll);
ccameron36d091f2014-11-07 03:18:501169 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181170 host_impl_->ScrollBy(
1171 UpdateState(gfx::Point(), gfx::Vector2d(0, -10)).get())
1172 .did_scroll);
ccameron36d091f2014-11-07 03:18:501173 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181174 host_impl_->ScrollBy(
1175 UpdateState(gfx::Point(), gfx::Vector2d(-10, -10)).get())
1176 .did_scroll);
[email protected]aa043632013-03-25 03:39:421177
1178 // Scrolling diagonally against an edge will succeed.
ccameron36d091f2014-11-07 03:18:501179 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181180 host_impl_->ScrollBy(
1181 UpdateState(gfx::Point(), gfx::Vector2d(10, -10)).get())
1182 .did_scroll);
ccameron36d091f2014-11-07 03:18:501183 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181184 host_impl_->ScrollBy(
1185 UpdateState(gfx::Point(), gfx::Vector2d(-10, 0)).get())
1186 .did_scroll);
ccameron36d091f2014-11-07 03:18:501187 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181188 host_impl_->ScrollBy(
1189 UpdateState(gfx::Point(), gfx::Vector2d(-10, 10)).get())
1190 .did_scroll);
[email protected]aa043632013-03-25 03:39:421191
1192 // Trying to scroll more than the available space will also succeed.
ccameron36d091f2014-11-07 03:18:501193 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:181194 host_impl_->ScrollBy(
1195 UpdateState(gfx::Point(), gfx::Vector2d(5000, 5000)).get())
1196 .did_scroll);
[email protected]aa043632013-03-25 03:39:421197}
1198
1199TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) {
1200 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
[email protected]18ce59702013-04-09 04:58:401201 host_impl_->SetViewportSize(gfx::Size(100, 1000));
[email protected]aa043632013-03-25 03:39:421202
[email protected]ce2e8112013-11-28 07:44:361203 DrawFrame();
[email protected]aa043632013-03-25 03:39:421204
tdresser81e84c672016-01-18 23:21:221205 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181206 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:221207 InputHandler::WHEEL)
1208 .thread);
[email protected]aa043632013-03-25 03:39:421209
aeliasa57c40d122015-10-08 00:20:091210 // Trying to scroll if not user_scrollable_vertical will fail.
1211 host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(false);
danakj74af409e2016-07-01 00:41:481212 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd2668bea62016-03-17 00:49:471213 DrawFrame();
[email protected]aa043632013-03-25 03:39:421214 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491215 gfx::Point(), SCROLL_FORWARD));
[email protected]aa043632013-03-25 03:39:421216 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491217 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:421218
aeliasa57c40d122015-10-08 00:20:091219 host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(true);
danakj74af409e2016-07-01 00:41:481220 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd2668bea62016-03-17 00:49:471221 DrawFrame();
[email protected]aa043632013-03-25 03:39:421222 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491223 gfx::Point(), SCROLL_FORWARD));
[email protected]adeda572014-01-31 00:49:471224 EXPECT_FLOAT_EQ(875.f,
sunxdb7e79432016-03-09 21:13:421225 ScrollDelta(host_impl_->InnerViewportScrollLayer()).y());
[email protected]aa043632013-03-25 03:39:421226 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:491227 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:421228}
1229
aeliasaf915a882014-10-14 04:12:041230TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
[email protected]59a7d552013-10-22 03:36:431231 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
1232 host_impl_->SetViewportSize(gfx::Size(100, 100));
1233
1234 gfx::Size overflow_size(400, 400);
jaydasikafc66cfb2016-06-10 04:34:221235 ASSERT_EQ(1u, scroll_layer->test_properties()->children.size());
1236 LayerImpl* overflow = scroll_layer->test_properties()->children[0];
[email protected]59a7d552013-10-22 03:36:431237 overflow->SetBounds(overflow_size);
jaydasikaf419bf72016-06-15 10:21:211238 overflow->SetScrollClipLayer(
1239 scroll_layer->test_properties()->parent->test_properties()->parent->id());
sunxdb7e79432016-03-09 21:13:421240 overflow->layer_tree_impl()
1241 ->property_trees()
1242 ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->id(),
1243 gfx::ScrollOffset());
[email protected]59a7d552013-10-22 03:36:431244 overflow->SetPosition(gfx::PointF());
danakj74af409e2016-07-01 00:41:481245 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]59a7d552013-10-22 03:36:431246
[email protected]ce2e8112013-11-28 07:44:361247 DrawFrame();
[email protected]59a7d552013-10-22 03:36:431248 gfx::Point scroll_position(10, 10);
1249
tdresser81e84c672016-01-18 23:21:221250 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181251 host_impl_->ScrollBegin(BeginState(scroll_position).get(),
tdresser81e84c672016-01-18 23:21:221252 InputHandler::WHEEL)
1253 .thread);
aeliasf998da82015-02-03 01:40:511254 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
1255 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431256
1257 gfx::Vector2dF scroll_delta(10, 10);
majidvp944a8cd2016-01-12 21:05:181258 host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
1259 host_impl_->ScrollEnd(EndState().get());
aeliasf998da82015-02-03 01:40:511260 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
1261 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431262
1263 overflow->set_user_scrollable_horizontal(false);
danakj74af409e2016-07-01 00:41:481264 host_impl_->active_tree()->BuildPropertyTreesForTesting();
1265
sunxd2668bea62016-03-17 00:49:471266 DrawFrame();
[email protected]59a7d552013-10-22 03:36:431267
tdresser81e84c672016-01-18 23:21:221268 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181269 host_impl_->ScrollBegin(BeginState(scroll_position).get(),
tdresser81e84c672016-01-18 23:21:221270 InputHandler::WHEEL)
1271 .thread);
aeliasf998da82015-02-03 01:40:511272 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
1273 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431274
majidvp944a8cd2016-01-12 21:05:181275 host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
1276 host_impl_->ScrollEnd(EndState().get());
tdressera3b162b82015-09-29 17:51:431277 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset());
aeliasf998da82015-02-03 01:40:511278 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431279
1280 overflow->set_user_scrollable_vertical(false);
danakj74af409e2016-07-01 00:41:481281 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd2668bea62016-03-17 00:49:471282 DrawFrame();
[email protected]59a7d552013-10-22 03:36:431283
tdresser81e84c672016-01-18 23:21:221284 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181285 host_impl_->ScrollBegin(BeginState(scroll_position).get(),
tdresser81e84c672016-01-18 23:21:221286 InputHandler::WHEEL)
1287 .thread);
tdressera3b162b82015-09-29 17:51:431288 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset());
aeliasf998da82015-02-03 01:40:511289 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431290
majidvp944a8cd2016-01-12 21:05:181291 host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
1292 host_impl_->ScrollEnd(EndState().get());
tdressera3b162b82015-09-29 17:51:431293 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), scroll_layer->CurrentScrollOffset());
aeliasf998da82015-02-03 01:40:511294 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
[email protected]59a7d552013-10-22 03:36:431295}
1296
danakjb56d7d82015-08-28 19:28:591297TEST_F(LayerTreeHostImplTest, AnimationSchedulingPendingTree) {
danakja18e826a2015-12-03 00:27:031298 EXPECT_FALSE(host_impl_->CommitToActiveTree());
1299
danakjb56d7d82015-08-28 19:28:591300 host_impl_->SetViewportSize(gfx::Size(50, 50));
1301
1302 host_impl_->CreatePendingTree();
danakj74af409e2016-07-01 00:41:481303 auto root_owned = LayerImpl::Create(host_impl_->pending_tree(), 1);
1304 auto* root = root_owned.get();
1305 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned));
danakjb56d7d82015-08-28 19:28:591306 root->SetBounds(gfx::Size(50, 50));
jaydasika6b5a32bf2016-04-22 21:56:361307 root->test_properties()->force_render_surface = true;
danakjb56d7d82015-08-28 19:28:591308
jaydasika89f7b5a2016-06-22 02:08:391309 root->test_properties()->AddChild(
1310 LayerImpl::Create(host_impl_->pending_tree(), 2));
jaydasikafc66cfb2016-06-10 04:34:221311 LayerImpl* child = root->test_properties()->children[0];
danakjb56d7d82015-08-28 19:28:591312 child->SetBounds(gfx::Size(10, 10));
1313 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1314 child->SetDrawsContent(true);
vollickef2ae922016-06-29 17:54:271315
1316 host_impl_->pending_tree()->SetElementIdsForTesting();
1317
1318 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 10.0,
1319 3, 0);
danakjb56d7d82015-08-28 19:28:591320
danakja18e826a2015-12-03 00:27:031321 EXPECT_FALSE(did_request_next_frame_);
danakjb56d7d82015-08-28 19:28:591322 EXPECT_FALSE(did_request_redraw_);
1323 EXPECT_FALSE(did_request_commit_);
1324
danakj4923440542015-10-29 19:34:531325 host_impl_->AnimatePendingTreeAfterCommit();
danakjb56d7d82015-08-28 19:28:591326
danakj4923440542015-10-29 19:34:531327 // An animation exists on the pending layer. Doing
1328 // AnimatePendingTreeAfterCommit() requests another frame.
danakjb56d7d82015-08-28 19:28:591329 // In reality, animations without has_set_start_time() == true do not need to
1330 // be continuously ticked on the pending tree, so it should not request
1331 // another animation frame here. But we currently do so blindly if any
1332 // animation exists.
danakja18e826a2015-12-03 00:27:031333 EXPECT_TRUE(did_request_next_frame_);
danakjb56d7d82015-08-28 19:28:591334 // The pending tree with an animation does not need to draw after animating.
1335 EXPECT_FALSE(did_request_redraw_);
1336 EXPECT_FALSE(did_request_commit_);
1337
danakja18e826a2015-12-03 00:27:031338 did_request_next_frame_ = false;
danakjb56d7d82015-08-28 19:28:591339 did_request_redraw_ = false;
1340 did_request_commit_ = false;
1341
1342 host_impl_->ActivateSyncTree();
1343
1344 // When the animation activates, we should request another animation frame
1345 // to keep the animation moving.
danakja18e826a2015-12-03 00:27:031346 EXPECT_TRUE(did_request_next_frame_);
danakjb56d7d82015-08-28 19:28:591347 // On activation we don't need to request a redraw for the animation,
1348 // activating will draw on its own when it's ready.
1349 EXPECT_FALSE(did_request_redraw_);
1350 EXPECT_FALSE(did_request_commit_);
1351}
1352
1353TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) {
danakja18e826a2015-12-03 00:27:031354 EXPECT_FALSE(host_impl_->CommitToActiveTree());
1355
danakjb56d7d82015-08-28 19:28:591356 host_impl_->SetViewportSize(gfx::Size(50, 50));
1357
jaydasikabf1875a2016-06-28 03:39:591358 host_impl_->active_tree()->SetRootLayerForTesting(
danakjb56d7d82015-08-28 19:28:591359 LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:481360 LayerImpl* root = *host_impl_->active_tree()->begin();
danakjb56d7d82015-08-28 19:28:591361 root->SetBounds(gfx::Size(50, 50));
jaydasika6b5a32bf2016-04-22 21:56:361362 root->test_properties()->force_render_surface = true;
danakjb56d7d82015-08-28 19:28:591363
jaydasika89f7b5a2016-06-22 02:08:391364 root->test_properties()->AddChild(
1365 LayerImpl::Create(host_impl_->active_tree(), 2));
jaydasikafc66cfb2016-06-10 04:34:221366 LayerImpl* child = root->test_properties()->children[0];
danakjb56d7d82015-08-28 19:28:591367 child->SetBounds(gfx::Size(10, 10));
1368 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1369 child->SetDrawsContent(true);
danakjee6547a22016-07-01 20:41:501370 host_impl_->active_tree()->BuildPropertyTreesForTesting();
vollickef2ae922016-06-29 17:54:271371 host_impl_->active_tree()->SetElementIdsForTesting();
1372
danakjb56d7d82015-08-28 19:28:591373 // Add a translate from 6,7 to 8,9.
1374 TransformOperations start;
1375 start.AppendTranslate(6.f, 7.f, 0.f);
1376 TransformOperations end;
1377 end.AppendTranslate(8.f, 9.f, 0.f);
vollickef2ae922016-06-29 17:54:271378 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 4.0,
1379 start, end);
danakjb56d7d82015-08-28 19:28:591380
1381 base::TimeTicks now = base::TimeTicks::Now();
1382 host_impl_->WillBeginImplFrame(
1383 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
1384
danakja18e826a2015-12-03 00:27:031385 // TODO(crbug.com/551134): We always request a new frame and a draw for
1386 // animations that are on the pending tree, but we don't need to do that
1387 // unless they are waiting for some future time to start.
1388 EXPECT_TRUE(did_request_next_frame_);
1389 EXPECT_TRUE(did_request_redraw_);
danakjb56d7d82015-08-28 19:28:591390 EXPECT_FALSE(did_request_commit_);
danakja18e826a2015-12-03 00:27:031391 did_request_next_frame_ = false;
danakjb56d7d82015-08-28 19:28:591392 did_request_redraw_ = false;
1393 did_request_commit_ = false;
1394
danakja18e826a2015-12-03 00:27:031395 host_impl_->ActivateAnimations();
1396
1397 // On activating an animation, we should request another frame so that we'll
1398 // continue ticking the animation.
1399 EXPECT_TRUE(did_request_next_frame_);
1400 EXPECT_FALSE(did_request_redraw_);
1401 EXPECT_FALSE(did_request_commit_);
1402 did_request_next_frame_ = false;
1403 did_request_redraw_ = false;
1404 did_request_commit_ = false;
1405
1406 // The next frame after activating, we'll tick the animation again.
danakjb56d7d82015-08-28 19:28:591407 host_impl_->Animate();
1408
1409 // An animation exists on the active layer. Doing Animate() requests another
1410 // frame after the current one.
danakja18e826a2015-12-03 00:27:031411 EXPECT_TRUE(did_request_next_frame_);
danakj4923440542015-10-29 19:34:531412 // The animation should cause us to draw at the frame's deadline.
1413 EXPECT_TRUE(did_request_redraw_);
danakjb56d7d82015-08-28 19:28:591414 EXPECT_FALSE(did_request_commit_);
1415}
1416
danakja18e826a2015-12-03 00:27:031417TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) {
1418 FakeImplTaskRunnerProvider provider(nullptr);
1419 CreateHostImplWithTaskRunnerProvider(DefaultSettings(), CreateOutputSurface(),
1420 &provider);
1421 EXPECT_TRUE(host_impl_->CommitToActiveTree());
1422
1423 host_impl_->SetViewportSize(gfx::Size(50, 50));
1424
danakj74af409e2016-07-01 00:41:481425 auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1);
1426 auto* root = root_owned.get();
1427 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned));
danakja18e826a2015-12-03 00:27:031428 root->SetBounds(gfx::Size(50, 50));
1429 root->SetHasRenderSurface(true);
1430
danakj74af409e2016-07-01 00:41:481431 auto child_owned = LayerImpl::Create(host_impl_->active_tree(), 2);
1432 auto* child = child_owned.get();
1433 root->test_properties()->AddChild(std::move(child_owned));
danakja18e826a2015-12-03 00:27:031434 child->SetBounds(gfx::Size(10, 10));
1435 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1436 child->SetDrawsContent(true);
vollickef2ae922016-06-29 17:54:271437
1438 host_impl_->active_tree()->SetElementIdsForTesting();
1439
1440 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 10.0,
1441 3, 0);
danakja18e826a2015-12-03 00:27:031442
1443 // Set up the property trees so that UpdateDrawProperties will work in
1444 // CommitComplete below.
1445 LayerImplList list;
1446 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
ajuma0adb5902016-04-28 16:32:381447 root, gfx::Size(50, 50), &list);
sunxdb365de02016-04-28 20:32:571448 LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
danakja18e826a2015-12-03 00:27:031449
1450 EXPECT_FALSE(did_request_next_frame_);
1451 EXPECT_FALSE(did_request_redraw_);
1452 EXPECT_FALSE(did_request_commit_);
1453
1454 host_impl_->CommitComplete();
1455
1456 // Animations on the active tree should be started and ticked, and a new frame
1457 // should be requested to continue ticking them.
1458 EXPECT_TRUE(did_request_next_frame_);
1459 EXPECT_TRUE(did_request_redraw_);
1460 EXPECT_FALSE(did_request_commit_);
1461
1462 // Delete the LayerTreeHostImpl before the TaskRunnerProvider goes away.
danakjee6547a22016-07-01 20:41:501463 host_impl_->ReleaseOutputSurface();
danakja18e826a2015-12-03 00:27:031464 host_impl_ = nullptr;
1465}
1466
loyso638ef702016-06-07 02:51:571467TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) {
1468 host_impl_->SetViewportSize(gfx::Size(50, 50));
1469
jaydasikabf1875a2016-06-28 03:39:591470 host_impl_->active_tree()->SetRootLayerForTesting(
loyso638ef702016-06-07 02:51:571471 LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:481472 LayerImpl* root = *host_impl_->active_tree()->begin();
loyso638ef702016-06-07 02:51:571473 root->SetBounds(gfx::Size(50, 50));
1474
jaydasika89f7b5a2016-06-22 02:08:391475 root->test_properties()->AddChild(
1476 LayerImpl::Create(host_impl_->active_tree(), 2));
jaydasikafc66cfb2016-06-10 04:34:221477 LayerImpl* child = root->test_properties()->children[0];
loyso638ef702016-06-07 02:51:571478 child->SetBounds(gfx::Size(10, 10));
1479 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1480 child->SetDrawsContent(true);
1481
danakjee6547a22016-07-01 20:41:501482 host_impl_->active_tree()->BuildPropertyTreesForTesting();
vollickef2ae922016-06-29 17:54:271483 host_impl_->active_tree()->SetElementIdsForTesting();
1484
loyso638ef702016-06-07 02:51:571485 // Add a translate animation.
1486 TransformOperations start;
1487 start.AppendTranslate(6.f, 7.f, 0.f);
1488 TransformOperations end;
1489 end.AppendTranslate(8.f, 9.f, 0.f);
vollickef2ae922016-06-29 17:54:271490 AddAnimatedTransformToElementWithPlayer(child->element_id(), timeline(), 4.0,
1491 start, end);
loyso638ef702016-06-07 02:51:571492
1493 base::TimeTicks now = base::TimeTicks::Now();
1494 host_impl_->WillBeginImplFrame(
1495 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
1496 EXPECT_TRUE(did_request_next_frame_);
1497 did_request_next_frame_ = false;
1498
1499 host_impl_->ActivateAnimations();
1500 // On activating an animation, we should request another frame so that we'll
1501 // continue ticking the animation.
1502 EXPECT_TRUE(did_request_next_frame_);
1503 did_request_next_frame_ = false;
1504
1505 // The next frame after activating, we'll tick the animation again.
1506 host_impl_->Animate();
1507 // An animation exists on the active layer. Doing Animate() requests another
1508 // frame after the current one.
1509 EXPECT_TRUE(did_request_next_frame_);
1510 did_request_next_frame_ = false;
1511
1512 // Destroy layer, unregister animation target (element).
jaydasikaf419bf72016-06-15 10:21:211513 child->test_properties()->parent = nullptr;
jaydasika89f7b5a2016-06-22 02:08:391514 root->test_properties()->RemoveChild(child);
loyso638ef702016-06-07 02:51:571515 child = nullptr;
1516
1517 // Doing Animate() doesn't request another frame after the current one.
1518 host_impl_->Animate();
1519 EXPECT_FALSE(did_request_next_frame_);
1520
1521 host_impl_->Animate();
1522 EXPECT_FALSE(did_request_next_frame_);
1523}
1524
vmpstre1564a52015-11-24 19:43:151525class MissingTilesLayer : public LayerImpl {
1526 public:
1527 MissingTilesLayer(LayerTreeImpl* layer_tree_impl, int id)
1528 : LayerImpl(layer_tree_impl, id), has_missing_tiles_(true) {}
1529
1530 void set_has_missing_tiles(bool has_missing_tiles) {
1531 has_missing_tiles_ = has_missing_tiles;
1532 }
1533
1534 void AppendQuads(RenderPass* render_pass,
1535 AppendQuadsData* append_quads_data) override {
1536 append_quads_data->num_missing_tiles += has_missing_tiles_;
1537 }
1538
1539 private:
1540 bool has_missing_tiles_;
1541};
1542
danakja18e826a2015-12-03 00:27:031543TEST_F(LayerTreeHostImplTest, AnimationMarksLayerNotReady) {
vmpstre1564a52015-11-24 19:43:151544 host_impl_->SetViewportSize(gfx::Size(50, 50));
1545
jaydasikabf1875a2016-06-28 03:39:591546 host_impl_->active_tree()->SetRootLayerForTesting(
vmpstre1564a52015-11-24 19:43:151547 LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:481548 LayerImpl* root = *host_impl_->active_tree()->begin();
vmpstre1564a52015-11-24 19:43:151549 root->SetBounds(gfx::Size(50, 50));
1550 root->SetHasRenderSurface(true);
1551
jaydasika89f7b5a2016-06-22 02:08:391552 root->test_properties()->AddChild(std::unique_ptr<MissingTilesLayer>(
vmpstre1564a52015-11-24 19:43:151553 new MissingTilesLayer(host_impl_->active_tree(), 2)));
1554 MissingTilesLayer* child =
jaydasikafc66cfb2016-06-10 04:34:221555 static_cast<MissingTilesLayer*>(root->test_properties()->children[0]);
vmpstre1564a52015-11-24 19:43:151556 child->SetBounds(gfx::Size(10, 10));
1557 child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
1558 child->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481559 host_impl_->active_tree()->BuildPropertyTreesForTesting();
vmpstre1564a52015-11-24 19:43:151560
vollickef2ae922016-06-29 17:54:271561 host_impl_->active_tree()->SetElementIdsForTesting();
1562
vmpstre1564a52015-11-24 19:43:151563 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1564
1565 // Add a translate from 6,7 to 8,9.
1566 TransformOperations start;
1567 start.AppendTranslate(6.f, 7.f, 0.f);
1568 TransformOperations end;
1569 end.AppendTranslate(8.f, 9.f, 0.f);
vollickef2ae922016-06-29 17:54:271570 int animation_id = AddAnimatedTransformToElementWithPlayer(
1571 child->element_id(), timeline(), 4.0, start, end);
vmpstre1564a52015-11-24 19:43:151572
1573 base::TimeTicks now = base::TimeTicks::Now();
1574 host_impl_->WillBeginImplFrame(
1575 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now));
1576
1577 host_impl_->ActivateAnimations();
1578 host_impl_->Animate();
1579
1580 EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation());
1581
vmpstre1564a52015-11-24 19:43:151582 host_impl_->ResetRequiresHighResToDraw();
1583
1584 // Child layer has an animating transform but missing tiles.
1585 FakeLayerTreeHostImpl::FrameData frame;
1586 DrawResult result = host_impl_->PrepareToDraw(&frame);
1587 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result);
1588 host_impl_->DidDrawAllLayers(frame);
1589
1590 child->set_has_missing_tiles(false);
1591
1592 // Child layer has an animating and no missing tiles.
1593 result = host_impl_->PrepareToDraw(&frame);
1594 EXPECT_EQ(DRAW_SUCCESS, result);
1595 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1596 host_impl_->DidDrawAllLayers(frame);
1597
1598 // Remove the animation.
1599 child->set_has_missing_tiles(true);
vollickef2ae922016-06-29 17:54:271600 RemoveAnimationFromElementWithExistingPlayer(child->element_id(), timeline(),
1601 animation_id);
vmpstre1564a52015-11-24 19:43:151602 child->draw_properties().screen_space_transform_is_animating = false;
1603
1604 // Child layer doesn't have an animation, but was never ready since the last
1605 // time it animated (and has missing tiles).
1606 result = host_impl_->PrepareToDraw(&frame);
1607 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result);
1608 EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation());
1609 host_impl_->DidDrawAllLayers(frame);
1610
1611 child->set_has_missing_tiles(false);
1612
1613 // Child layer doesn't have an animation and all tiles are ready.
1614 result = host_impl_->PrepareToDraw(&frame);
1615 EXPECT_EQ(DRAW_SUCCESS, result);
1616 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1617 host_impl_->DidDrawAllLayers(frame);
1618
1619 child->set_has_missing_tiles(true);
1620
1621 // Child layer doesn't have an animation, and was ready at least once since
1622 // the last time it animated.
1623 result = host_impl_->PrepareToDraw(&frame);
1624 EXPECT_EQ(DRAW_SUCCESS, result);
1625 EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation());
1626 host_impl_->DidDrawAllLayers(frame);
1627}
1628
[email protected]aa043632013-03-25 03:39:421629TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
[email protected]35a99a12013-05-09 23:52:291630 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:481631 host_impl_->active_tree()->BuildPropertyTreesForTesting();
1632
[email protected]18ce59702013-04-09 04:58:401633 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:361634 DrawFrame();
[email protected]aa043632013-03-25 03:39:421635
[email protected]adeda572014-01-31 00:49:471636 EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer());
[email protected]fef74fd2014-02-27 06:28:171637 LayerImpl* container_layer = scroll_layer->scroll_clip_layer();
bokancccfde72014-10-08 15:15:221638 EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
[email protected]aa043632013-03-25 03:39:421639
1640 float min_page_scale = 1.f, max_page_scale = 4.f;
[email protected]fef74fd2014-02-27 06:28:171641 float page_scale_factor = 1.f;
[email protected]aa043632013-03-25 03:39:421642
1643 // The impl-based pinch zoom should adjust the max scroll position.
1644 {
aelias58eec0812014-12-04 01:04:401645 host_impl_->active_tree()->PushPageScaleFromMainThread(
[email protected]fef74fd2014-02-27 06:28:171646 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:501647 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
sunxdb7e79432016-03-09 21:13:421648 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:421649
1650 float page_scale_delta = 2.f;
[email protected]fef74fd2014-02-27 06:28:171651
majidvp944a8cd2016-01-12 21:05:181652 host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
dtapuska40e8aff2016-03-11 21:45:031653 InputHandler::TOUCHSCREEN);
[email protected]adeda572014-01-31 00:49:471654 host_impl_->PinchGestureBegin();
[email protected]aa043632013-03-25 03:39:421655 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
1656 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181657 host_impl_->ScrollEnd(EndState().get());
danakja18e826a2015-12-03 00:27:031658 EXPECT_FALSE(did_request_next_frame_);
[email protected]aa043632013-03-25 03:39:421659 EXPECT_TRUE(did_request_redraw_);
1660 EXPECT_TRUE(did_request_commit_);
bokancccfde72014-10-08 15:15:221661 EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
[email protected]aa043632013-03-25 03:39:421662
danakj60bc3bc2016-04-09 00:24:481663 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:421664 host_impl_->ProcessScrollDeltas();
1665 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
1666
miletusf57925d2014-10-01 19:38:131667 EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(),
[email protected]adeda572014-01-31 00:49:471668 scroll_layer->MaxScrollOffset().ToString());
[email protected]aa043632013-03-25 03:39:421669 }
1670
1671 // Scrolling after a pinch gesture should always be in local space. The
lanweid17d0742014-12-01 18:58:521672 // scroll deltas have the page scale factor applied.
[email protected]aa043632013-03-25 03:39:421673 {
aelias58eec0812014-12-04 01:04:401674 host_impl_->active_tree()->PushPageScaleFromMainThread(
[email protected]fef74fd2014-02-27 06:28:171675 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:501676 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
sunxdb7e79432016-03-09 21:13:421677 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:421678
1679 float page_scale_delta = 2.f;
majidvp944a8cd2016-01-12 21:05:181680 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:031681 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:421682 host_impl_->PinchGestureBegin();
1683 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
1684 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181685 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:421686
1687 gfx::Vector2d scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:221688 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:181689 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:221690 InputHandler::WHEEL)
1691 .thread);
majidvp944a8cd2016-01-12 21:05:181692 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
1693 host_impl_->ScrollEnd(EndState().get());
[email protected]a9710962012-11-14 20:11:021694
danakj60bc3bc2016-04-09 00:24:481695 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:421696 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:181697 EXPECT_TRUE(ScrollInfoContains(
1698 *scroll_info.get(), scroll_layer->id(),
1699 gfx::Vector2d(0, scroll_delta.y() / page_scale_delta)));
[email protected]aa043632013-03-25 03:39:421700 }
[email protected]a9710962012-11-14 20:11:021701}
1702
bokaneaee880f2015-08-04 18:01:071703TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
1704 LayerTreeSettings settings = DefaultSettings();
bokaneaee880f2015-08-04 18:01:071705 CreateHostImpl(settings,
1706 CreateOutputSurface());
1707 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 4.f);
1708
1709 const gfx::Size content_size(1000, 1000);
1710 const gfx::Size viewport_size(500, 500);
1711 CreateBasicVirtualViewportLayers(viewport_size, content_size);
1712
1713 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121714 outer_scroll_layer->SetDrawsContent(true);
bokaneaee880f2015-08-04 18:01:071715 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121716 inner_scroll_layer->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481717 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokaneaee880f2015-08-04 18:01:071718
1719 EXPECT_VECTOR_EQ(
1720 gfx::Vector2dF(500, 500),
1721 outer_scroll_layer->MaxScrollOffset());
1722
majidvp944a8cd2016-01-12 21:05:181723 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031724 InputHandler::TOUCHSCREEN);
bokaneaee880f2015-08-04 18:01:071725 host_impl_->PinchGestureBegin();
1726 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
1727 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181728 host_impl_->ScrollEnd(EndState().get());
bokaneaee880f2015-08-04 18:01:071729
1730 // Sanity check - we're zoomed in, starting from the origin.
1731 EXPECT_VECTOR_EQ(
1732 gfx::Vector2dF(0, 0),
1733 outer_scroll_layer->CurrentScrollOffset());
1734 EXPECT_VECTOR_EQ(
1735 gfx::Vector2dF(0, 0),
1736 inner_scroll_layer->CurrentScrollOffset());
1737
1738 // Scroll down - only the inner viewport should scroll.
majidvp944a8cd2016-01-12 21:05:181739 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
dtapuska40e8aff2016-03-11 21:45:031740 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181741 host_impl_->ScrollBy(
1742 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
1743 host_impl_->ScrollEnd(EndState().get());
bokaneaee880f2015-08-04 18:01:071744
1745 EXPECT_VECTOR_EQ(
1746 gfx::Vector2dF(50, 50),
1747 inner_scroll_layer->CurrentScrollOffset());
1748 EXPECT_VECTOR_EQ(
1749 gfx::Vector2dF(0, 0),
1750 outer_scroll_layer->CurrentScrollOffset());
1751
1752 // Scroll down - outer viewport should start scrolling after the inner is at
1753 // its maximum.
majidvp944a8cd2016-01-12 21:05:181754 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
dtapuska40e8aff2016-03-11 21:45:031755 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181756 host_impl_->ScrollBy(
1757 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get());
1758 host_impl_->ScrollEnd(EndState().get());
bokaneaee880f2015-08-04 18:01:071759
1760 EXPECT_VECTOR_EQ(
1761 gfx::Vector2dF(250, 250),
1762 inner_scroll_layer->CurrentScrollOffset());
1763 EXPECT_VECTOR_EQ(
1764 gfx::Vector2dF(300, 300),
1765 outer_scroll_layer->CurrentScrollOffset());
1766}
1767
bokan49c85a922015-10-07 21:08:031768// Make sure scrolls smaller than a unit applied to the viewport don't get
1769// dropped. crbug.com/539334.
1770TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) {
1771 LayerTreeSettings settings = DefaultSettings();
1772 CreateHostImpl(settings, CreateOutputSurface());
1773 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
1774
1775 const gfx::Size content_size(1000, 1000);
1776 const gfx::Size viewport_size(500, 500);
1777 CreateBasicVirtualViewportLayers(viewport_size, content_size);
1778
1779 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121780 outer_scroll_layer->SetDrawsContent(true);
bokan49c85a922015-10-07 21:08:031781 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121782 inner_scroll_layer->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481783 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan49c85a922015-10-07 21:08:031784
1785 // Sanity checks.
1786 EXPECT_VECTOR_EQ(
1787 gfx::Vector2dF(500, 500),
1788 outer_scroll_layer->MaxScrollOffset());
1789 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset());
1790 EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll_layer->CurrentScrollOffset());
1791
bokan49c85a922015-10-07 21:08:031792 // Scroll only the layout viewport.
majidvp944a8cd2016-01-12 21:05:181793 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031794 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181795 host_impl_->ScrollBy(
1796 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(0.125f, 0.125f)).get());
bokan49c85a922015-10-07 21:08:031797 EXPECT_VECTOR2DF_EQ(
1798 gfx::Vector2dF(0.125f, 0.125f),
1799 outer_scroll_layer->CurrentScrollOffset());
1800 EXPECT_VECTOR2DF_EQ(
1801 gfx::Vector2dF(0, 0),
1802 inner_scroll_layer->CurrentScrollOffset());
majidvp944a8cd2016-01-12 21:05:181803 host_impl_->ScrollEnd(EndState().get());
bokan49c85a922015-10-07 21:08:031804
1805 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
1806
1807 // Now that we zoomed in, the scroll should be applied to the inner viewport.
majidvp944a8cd2016-01-12 21:05:181808 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031809 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:181810 host_impl_->ScrollBy(
1811 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(0.5f, 0.5f)).get());
bokan49c85a922015-10-07 21:08:031812 EXPECT_VECTOR2DF_EQ(
1813 gfx::Vector2dF(0.125f, 0.125f),
1814 outer_scroll_layer->CurrentScrollOffset());
1815 EXPECT_VECTOR2DF_EQ(
1816 gfx::Vector2dF(0.25f, 0.25f),
1817 inner_scroll_layer->CurrentScrollOffset());
majidvp944a8cd2016-01-12 21:05:181818 host_impl_->ScrollEnd(EndState().get());
bokan49c85a922015-10-07 21:08:031819}
1820
bokan32f1b902015-08-12 22:25:321821// Tests that scrolls during a pinch gesture (i.e. "two-finger" scrolls) work
1822// as expected. That is, scrolling during a pinch should bubble from the inner
1823// to the outer viewport.
1824TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
bokan9e5569612015-06-09 18:41:201825 LayerTreeSettings settings = DefaultSettings();
bokan9e5569612015-06-09 18:41:201826 CreateHostImpl(settings,
1827 CreateOutputSurface());
bokan0c33a092015-07-29 18:27:561828 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
bokan9e5569612015-06-09 18:41:201829
bokan499dd082015-06-24 15:35:191830 const gfx::Size content_size(1000, 1000);
1831 const gfx::Size viewport_size(500, 500);
1832 CreateBasicVirtualViewportLayers(viewport_size, content_size);
bokan9e5569612015-06-09 18:41:201833
bokan9e5569612015-06-09 18:41:201834 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121835 outer_scroll_layer->SetDrawsContent(true);
bokan499dd082015-06-24 15:35:191836 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:121837 inner_scroll_layer->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:481838 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan9e5569612015-06-09 18:41:201839
1840 EXPECT_VECTOR_EQ(
bokan499dd082015-06-24 15:35:191841 gfx::Vector2dF(500, 500),
bokan9e5569612015-06-09 18:41:201842 outer_scroll_layer->MaxScrollOffset());
1843
majidvp944a8cd2016-01-12 21:05:181844 host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
dtapuska40e8aff2016-03-11 21:45:031845 InputHandler::TOUCHSCREEN);
bokan9e5569612015-06-09 18:41:201846 host_impl_->PinchGestureBegin();
bokan9e5569612015-06-09 18:41:201847
bokan32f1b902015-08-12 22:25:321848 host_impl_->PinchGestureUpdate(2, gfx::Point(250, 250));
1849 EXPECT_VECTOR_EQ(
1850 gfx::Vector2dF(0, 0),
1851 outer_scroll_layer->CurrentScrollOffset());
1852 EXPECT_VECTOR_EQ(
1853 gfx::Vector2dF(125, 125),
1854 inner_scroll_layer->CurrentScrollOffset());
1855
1856 // Needed so that the pinch is accounted for in draw properties.
1857 DrawFrame();
1858
majidvp944a8cd2016-01-12 21:05:181859 host_impl_->ScrollBy(
1860 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(10.f, 10.f)).get());
bokan9e5569612015-06-09 18:41:201861 EXPECT_VECTOR_EQ(
1862 gfx::Vector2dF(0, 0),
1863 outer_scroll_layer->CurrentScrollOffset());
1864 EXPECT_VECTOR_EQ(
bokan499dd082015-06-24 15:35:191865 gfx::Vector2dF(130, 130),
bokan9e5569612015-06-09 18:41:201866 inner_scroll_layer->CurrentScrollOffset());
bokan32f1b902015-08-12 22:25:321867
1868 DrawFrame();
1869
majidvp944a8cd2016-01-12 21:05:181870 host_impl_->ScrollBy(
1871 UpdateState(gfx::Point(250, 250), gfx::Vector2dF(400.f, 400.f)).get());
bokan32f1b902015-08-12 22:25:321872 EXPECT_VECTOR_EQ(
1873 gfx::Vector2dF(80, 80),
1874 outer_scroll_layer->CurrentScrollOffset());
1875 EXPECT_VECTOR_EQ(
1876 gfx::Vector2dF(250, 250),
1877 inner_scroll_layer->CurrentScrollOffset());
1878
1879 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181880 host_impl_->ScrollEnd(EndState().get());
bokan9e5569612015-06-09 18:41:201881}
1882
bokan499dd082015-06-24 15:35:191883// Tests the "snapping" of pinch-zoom gestures to the screen edge. That is, when
1884// a pinch zoom is anchored within a certain margin of the screen edge, we
1885// should assume the user means to scroll into the edge of the screen.
1886TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) {
1887 LayerTreeSettings settings = DefaultSettings();
bokan499dd082015-06-24 15:35:191888 CreateHostImpl(settings,
1889 CreateOutputSurface());
bokan0c33a092015-07-29 18:27:561890 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
bokan499dd082015-06-24 15:35:191891
1892 const gfx::Size content_size(1000, 1000);
1893 const gfx::Size viewport_size(500, 500);
1894 CreateBasicVirtualViewportLayers(viewport_size, content_size);
1895
1896 int offsetFromEdge = Viewport::kPinchZoomSnapMarginDips - 5;
1897 gfx::Point anchor(viewport_size.width() - offsetFromEdge,
1898 viewport_size.height() - offsetFromEdge);
1899
1900 // Pinch in within the margins. The scroll should stay exactly locked to the
1901 // bottom and right.
dtapuska40e8aff2016-03-11 21:45:031902 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191903 host_impl_->PinchGestureBegin();
1904 host_impl_->PinchGestureUpdate(2, anchor);
1905 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181906 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191907
1908 EXPECT_VECTOR_EQ(
1909 gfx::Vector2dF(250, 250),
1910 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1911
1912 // Reset.
1913 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
sunxdb7e79432016-03-09 21:13:421914 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d());
1915 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d());
bokan499dd082015-06-24 15:35:191916
1917 // Pinch in within the margins. The scroll should stay exactly locked to the
1918 // top and left.
1919 anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
dtapuska40e8aff2016-03-11 21:45:031920 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191921 host_impl_->PinchGestureBegin();
1922 host_impl_->PinchGestureUpdate(2, anchor);
1923 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181924 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191925
1926 EXPECT_VECTOR_EQ(
1927 gfx::Vector2dF(0, 0),
1928 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1929
1930 // Reset.
1931 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
sunxdb7e79432016-03-09 21:13:421932 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d());
1933 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d());
bokan499dd082015-06-24 15:35:191934
1935 // Pinch in just outside the margin. There should be no snapping.
1936 offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
1937 anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
dtapuska40e8aff2016-03-11 21:45:031938 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191939 host_impl_->PinchGestureBegin();
1940 host_impl_->PinchGestureUpdate(2, anchor);
1941 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181942 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191943
1944 EXPECT_VECTOR_EQ(
1945 gfx::Vector2dF(50, 50),
1946 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1947
1948 // Reset.
1949 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
sunxdb7e79432016-03-09 21:13:421950 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d());
1951 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d());
bokan499dd082015-06-24 15:35:191952
1953 // Pinch in just outside the margin. There should be no snapping.
1954 offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
1955 anchor = gfx::Point(viewport_size.width() - offsetFromEdge,
1956 viewport_size.height() - offsetFromEdge);
dtapuska40e8aff2016-03-11 21:45:031957 host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
bokan499dd082015-06-24 15:35:191958 host_impl_->PinchGestureBegin();
1959 host_impl_->PinchGestureUpdate(2, anchor);
1960 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:181961 host_impl_->ScrollEnd(EndState().get());
bokan499dd082015-06-24 15:35:191962
1963 EXPECT_VECTOR_EQ(
1964 gfx::Vector2dF(200, 200),
1965 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
1966}
1967
bokan74efa332015-05-20 19:50:071968TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
bokan499dd082015-06-24 15:35:191969 const gfx::Size content_size(200, 200);
1970 const gfx::Size viewport_size(100, 100);
1971 CreateBasicVirtualViewportLayers(viewport_size, content_size);
bokan74efa332015-05-20 19:50:071972
bokan74efa332015-05-20 19:50:071973 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
bokan499dd082015-06-24 15:35:191974 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
bokan74efa332015-05-20 19:50:071975
1976 // Zoom into the page by a 2X factor
1977 float min_page_scale = 1.f, max_page_scale = 4.f;
1978 float page_scale_factor = 2.f;
1979 host_impl_->active_tree()->PushPageScaleFromMainThread(
1980 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:501981 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
bokan74efa332015-05-20 19:50:071982
bokan1f01388f2015-09-15 20:55:541983 // Scroll by a small amount, there should be no bubbling to the outer
bokan74efa332015-05-20 19:50:071984 // viewport.
majidvp944a8cd2016-01-12 21:05:181985 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
1986 InputHandler::WHEEL);
1987 host_impl_->ScrollBy(
1988 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(10.f, 20.f)).get());
1989 host_impl_->ScrollEnd(EndState().get());
bokan74efa332015-05-20 19:50:071990
1991 EXPECT_VECTOR_EQ(
1992 gfx::Vector2dF(5, 10),
bokan1f01388f2015-09-15 20:55:541993 inner_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:071994 EXPECT_VECTOR_EQ(
1995 gfx::Vector2dF(),
bokan1f01388f2015-09-15 20:55:541996 outer_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:071997
bokan1f01388f2015-09-15 20:55:541998 // Scroll by the inner viewport's max scroll extent, the remainder
1999 // should bubble up to the outer viewport.
majidvp944a8cd2016-01-12 21:05:182000 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
2001 InputHandler::WHEEL);
2002 host_impl_->ScrollBy(
2003 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
2004 host_impl_->ScrollEnd(EndState().get());
bokan74efa332015-05-20 19:50:072005
2006 EXPECT_VECTOR_EQ(
bokan1f01388f2015-09-15 20:55:542007 gfx::Vector2dF(50, 50),
2008 inner_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:072009 EXPECT_VECTOR_EQ(
2010 gfx::Vector2dF(5, 10),
bokan1f01388f2015-09-15 20:55:542011 outer_scroll_layer->CurrentScrollOffset());
bokan74efa332015-05-20 19:50:072012
bokan1f01388f2015-09-15 20:55:542013 // Scroll by the outer viewport's max scroll extent, it should all go to the
2014 // outer viewport.
majidvp944a8cd2016-01-12 21:05:182015 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
2016 InputHandler::WHEEL);
2017 host_impl_->ScrollBy(
2018 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(190.f, 180.f)).get());
2019 host_impl_->ScrollEnd(EndState().get());
bokan74efa332015-05-20 19:50:072020
2021 EXPECT_VECTOR_EQ(
2022 gfx::Vector2dF(100, 100),
2023 outer_scroll_layer->CurrentScrollOffset());
2024 EXPECT_VECTOR_EQ(
2025 gfx::Vector2dF(50, 50),
2026 inner_scroll_layer->CurrentScrollOffset());
2027}
2028
[email protected]dab0a422014-08-13 16:09:462029TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
2030 ui::LatencyInfo latency_info;
miletus45effdc42015-08-05 00:29:182031 latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
2032 1234);
danakj60bc3bc2016-04-09 00:24:482033 std::unique_ptr<SwapPromise> swap_promise(
[email protected]dab0a422014-08-13 16:09:462034 new LatencyInfoSwapPromise(latency_info));
2035
2036 SetupScrollAndContentsLayers(gfx::Size(100, 100));
tdresser81e84c672016-01-18 23:21:222037 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:032038 host_impl_
2039 ->ScrollBegin(BeginState(gfx::Point()).get(),
2040 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:222041 .thread);
majidvp944a8cd2016-01-12 21:05:182042 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
danakja04855a2015-11-18 20:39:102043 host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(
2044 std::move(swap_promise));
majidvp944a8cd2016-01-12 21:05:182045 host_impl_->ScrollEnd(EndState().get());
[email protected]dab0a422014-08-13 16:09:462046
danakj60bc3bc2016-04-09 00:24:482047 std::unique_ptr<ScrollAndScaleSet> scroll_info =
2048 host_impl_->ProcessScrollDeltas();
[email protected]dab0a422014-08-13 16:09:462049 EXPECT_EQ(1u, scroll_info->swap_promises.size());
miletus45effdc42015-08-05 00:29:182050 EXPECT_EQ(latency_info.trace_id(), scroll_info->swap_promises[0]->TraceId());
[email protected]dab0a422014-08-13 16:09:462051}
2052
tdressera3b162b82015-09-29 17:51:432053// Test that scrolls targeting a layer with a non-null scroll_parent() don't
2054// bubble up.
2055TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
bokan79ab8af2015-06-11 14:01:152056 LayerImpl* viewport_scroll =
2057 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2058 host_impl_->SetViewportSize(gfx::Size(50, 50));
2059
2060 // Set up two scrolling children of the root, one of which is a scroll parent
tdressera3b162b82015-09-29 17:51:432061 // to the other. Scrolls shouldn't bubbling from the child.
bokan79ab8af2015-06-11 14:01:152062 LayerImpl *parent;
2063 LayerImpl *child;
2064 LayerImpl *child_clip;
2065
danakj60bc3bc2016-04-09 00:24:482066 std::unique_ptr<LayerImpl> scroll_parent_clip =
bokan79ab8af2015-06-11 14:01:152067 LayerImpl::Create(host_impl_->active_tree(), 6);
danakj60bc3bc2016-04-09 00:24:482068 std::unique_ptr<LayerImpl> scroll_parent =
2069 CreateScrollableLayer(7, gfx::Size(10, 10), scroll_parent_clip.get());
bokan79ab8af2015-06-11 14:01:152070 parent = scroll_parent.get();
jaydasika89f7b5a2016-06-22 02:08:392071 scroll_parent_clip->test_properties()->AddChild(std::move(scroll_parent));
bokan79ab8af2015-06-11 14:01:152072
jaydasika89f7b5a2016-06-22 02:08:392073 viewport_scroll->test_properties()->AddChild(std::move(scroll_parent_clip));
bokan79ab8af2015-06-11 14:01:152074
danakj60bc3bc2016-04-09 00:24:482075 std::unique_ptr<LayerImpl> scroll_child_clip =
bokan79ab8af2015-06-11 14:01:152076 LayerImpl::Create(host_impl_->active_tree(), 8);
danakj60bc3bc2016-04-09 00:24:482077 std::unique_ptr<LayerImpl> scroll_child =
2078 CreateScrollableLayer(9, gfx::Size(10, 10), scroll_child_clip.get());
bokan79ab8af2015-06-11 14:01:152079 child = scroll_child.get();
danakja2fdbc702015-10-20 23:05:242080 scroll_child->SetPosition(gfx::PointF(20.f, 20.f));
jaydasika89f7b5a2016-06-22 02:08:392081 scroll_child_clip->test_properties()->AddChild(std::move(scroll_child));
bokan79ab8af2015-06-11 14:01:152082
2083 child_clip = scroll_child_clip.get();
jaydasika89f7b5a2016-06-22 02:08:392084 viewport_scroll->test_properties()->AddChild(std::move(scroll_child_clip));
bokan79ab8af2015-06-11 14:01:152085
jaydasika1c0a27d42016-04-28 01:54:562086 child_clip->test_properties()->scroll_parent = parent;
danakj60bc3bc2016-04-09 00:24:482087 std::unique_ptr<std::set<LayerImpl*>> scroll_children(
2088 new std::set<LayerImpl*>);
jaydasikab5a1a8c2015-09-29 18:38:492089 scroll_children->insert(child_clip);
jaydasika1c0a27d42016-04-28 01:54:562090 parent->test_properties()->scroll_children.reset(scroll_children.release());
danakj74af409e2016-07-01 00:41:482091 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan79ab8af2015-06-11 14:01:152092
2093 DrawFrame();
2094
2095 {
majidvp944a8cd2016-01-12 21:05:182096 host_impl_->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
dtapuska40e8aff2016-03-11 21:45:032097 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:182098 host_impl_->ScrollBy(
2099 UpdateState(gfx::Point(21, 21), gfx::Vector2d(5, 5)).get());
2100 host_impl_->ScrollBy(
2101 UpdateState(gfx::Point(21, 21), gfx::Vector2d(100, 100)).get());
2102 host_impl_->ScrollEnd(EndState().get());
bokan79ab8af2015-06-11 14:01:152103
2104 // The child should be fully scrolled by the first ScrollBy.
2105 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), child->CurrentScrollOffset());
2106
tdressera3b162b82015-09-29 17:51:432107 // The scroll_parent shouldn't receive the second ScrollBy.
2108 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), parent->CurrentScrollOffset());
bokan79ab8af2015-06-11 14:01:152109
2110 // The viewport shouldn't have been scrolled at all.
2111 EXPECT_VECTOR_EQ(
2112 gfx::Vector2dF(0, 0),
2113 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
2114 EXPECT_VECTOR_EQ(
2115 gfx::Vector2dF(0, 0),
2116 host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset());
2117 }
2118
2119 {
majidvp944a8cd2016-01-12 21:05:182120 host_impl_->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
dtapuska40e8aff2016-03-11 21:45:032121 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:182122 host_impl_->ScrollBy(
2123 UpdateState(gfx::Point(21, 21), gfx::Vector2d(3, 4)).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_->ScrollBy(
2129 UpdateState(gfx::Point(21, 21), gfx::Vector2d(2, 1)).get());
2130 host_impl_->ScrollEnd(EndState().get());
bokan79ab8af2015-06-11 14:01:152131
tdressera3b162b82015-09-29 17:51:432132 // The ScrollBy's should scroll the parent to its extent.
bokan79ab8af2015-06-11 14:01:152133 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), parent->CurrentScrollOffset());
2134
tdressera3b162b82015-09-29 17:51:432135 // The viewport shouldn't receive any scroll delta.
bokan79ab8af2015-06-11 14:01:152136 EXPECT_VECTOR_EQ(
tdressera3b162b82015-09-29 17:51:432137 gfx::Vector2dF(0, 0),
bokan79ab8af2015-06-11 14:01:152138 host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
2139 EXPECT_VECTOR_EQ(
2140 gfx::Vector2dF(0, 0),
2141 host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset());
2142 }
2143}
2144
2145
[email protected]aa043632013-03-25 03:39:422146TEST_F(LayerTreeHostImplTest, PinchGesture) {
2147 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:402148 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:362149 DrawFrame();
[email protected]be782f52013-03-23 21:36:142150
[email protected]adeda572014-01-31 00:49:472151 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
[email protected]aa043632013-03-25 03:39:422152 DCHECK(scroll_layer);
[email protected]be782f52013-03-23 21:36:142153
[email protected]aa043632013-03-25 03:39:422154 float min_page_scale = 1.f;
2155 float max_page_scale = 4.f;
[email protected]be782f52013-03-23 21:36:142156
[email protected]aa043632013-03-25 03:39:422157 // Basic pinch zoom in gesture
2158 {
aelias58eec0812014-12-04 01:04:402159 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422160 max_page_scale);
sunxdb7e79432016-03-09 21:13:422161 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]be782f52013-03-23 21:36:142162
[email protected]aa043632013-03-25 03:39:422163 float page_scale_delta = 2.f;
majidvp944a8cd2016-01-12 21:05:182164 host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
dtapuska40e8aff2016-03-11 21:45:032165 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422166 host_impl_->PinchGestureBegin();
2167 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
2168 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182169 host_impl_->ScrollEnd(EndState().get());
danakja18e826a2015-12-03 00:27:032170 EXPECT_FALSE(did_request_next_frame_);
[email protected]aa043632013-03-25 03:39:422171 EXPECT_TRUE(did_request_redraw_);
2172 EXPECT_TRUE(did_request_commit_);
[email protected]be782f52013-03-23 21:36:142173
danakj60bc3bc2016-04-09 00:24:482174 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422175 host_impl_->ProcessScrollDeltas();
2176 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
2177 }
2178
2179 // Zoom-in clamping
2180 {
aelias58eec0812014-12-04 01:04:402181 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422182 max_page_scale);
sunxdb7e79432016-03-09 21:13:422183 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:422184 float page_scale_delta = 10.f;
2185
majidvp944a8cd2016-01-12 21:05:182186 host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
dtapuska40e8aff2016-03-11 21:45:032187 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422188 host_impl_->PinchGestureBegin();
2189 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
2190 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182191 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422192
danakj60bc3bc2016-04-09 00:24:482193 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422194 host_impl_->ProcessScrollDeltas();
2195 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale);
2196 }
2197
2198 // Zoom-out clamping
2199 {
aelias58eec0812014-12-04 01:04:402200 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422201 max_page_scale);
sunxdb7e79432016-03-09 21:13:422202 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202203 scroll_layer->layer_tree_impl()
2204 ->property_trees()
2205 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422206 scroll_layer->layer_tree_impl()
2207 ->property_trees()
2208 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2209 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]aa043632013-03-25 03:39:422210
2211 float page_scale_delta = 0.1f;
majidvp944a8cd2016-01-12 21:05:182212 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:032213 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422214 host_impl_->PinchGestureBegin();
2215 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
2216 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182217 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422218
danakj60bc3bc2016-04-09 00:24:482219 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422220 host_impl_->ProcessScrollDeltas();
2221 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
2222
2223 EXPECT_TRUE(scroll_info->scrolls.empty());
2224 }
2225
2226 // Two-finger panning should not happen based on pinch events only
2227 {
aelias58eec0812014-12-04 01:04:402228 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422229 max_page_scale);
sunxdb7e79432016-03-09 21:13:422230 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202231 scroll_layer->layer_tree_impl()
2232 ->property_trees()
2233 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422234 scroll_layer->layer_tree_impl()
2235 ->property_trees()
2236 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2237 scroll_layer->id(), gfx::ScrollOffset(20, 20));
[email protected]aa043632013-03-25 03:39:422238
2239 float page_scale_delta = 1.f;
majidvp944a8cd2016-01-12 21:05:182240 host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
dtapuska40e8aff2016-03-11 21:45:032241 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422242 host_impl_->PinchGestureBegin();
2243 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
2244 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
2245 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182246 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422247
danakj60bc3bc2016-04-09 00:24:482248 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422249 host_impl_->ProcessScrollDeltas();
2250 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
2251 EXPECT_TRUE(scroll_info->scrolls.empty());
2252 }
2253
2254 // Two-finger panning should work with interleaved scroll events
2255 {
aelias58eec0812014-12-04 01:04:402256 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422257 max_page_scale);
sunxdb7e79432016-03-09 21:13:422258 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202259 scroll_layer->layer_tree_impl()
2260 ->property_trees()
2261 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422262 scroll_layer->layer_tree_impl()
2263 ->property_trees()
2264 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2265 scroll_layer->id(), gfx::ScrollOffset(20, 20));
[email protected]aa043632013-03-25 03:39:422266
2267 float page_scale_delta = 1.f;
majidvp944a8cd2016-01-12 21:05:182268 host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
dtapuska40e8aff2016-03-11 21:45:032269 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:422270 host_impl_->PinchGestureBegin();
2271 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
majidvp944a8cd2016-01-12 21:05:182272 host_impl_->ScrollBy(
2273 UpdateState(gfx::Point(10, 10), gfx::Vector2d(-10, -10)).get());
[email protected]aa043632013-03-25 03:39:422274 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
2275 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182276 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:422277
danakj60bc3bc2016-04-09 00:24:482278 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422279 host_impl_->ProcessScrollDeltas();
2280 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
tdresser99977952015-07-02 19:49:182281 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2282 gfx::Vector2d(-10, -10)));
[email protected]aa043632013-03-25 03:39:422283 }
[email protected]9ec24df2013-08-09 23:32:572284
2285 // Two-finger panning should work when starting fully zoomed out.
2286 {
aelias58eec0812014-12-04 01:04:402287 host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f);
sunxdb7e79432016-03-09 21:13:422288 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
sunxdc044b11a2016-03-16 16:23:202289 scroll_layer->layer_tree_impl()
2290 ->property_trees()
2291 ->scroll_tree.CollectScrollDeltasForTesting();
sunxdb7e79432016-03-09 21:13:422292 scroll_layer->layer_tree_impl()
2293 ->property_trees()
2294 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
2295 gfx::ScrollOffset(0, 0));
[email protected]9ec24df2013-08-09 23:32:572296
majidvp944a8cd2016-01-12 21:05:182297 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
dtapuska40e8aff2016-03-11 21:45:032298 InputHandler::TOUCHSCREEN);
[email protected]9ec24df2013-08-09 23:32:572299 host_impl_->PinchGestureBegin();
2300 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
2301 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
bokan1f01388f2015-09-15 20:55:542302
2303 // Needed so layer transform includes page scale.
2304 DrawFrame();
2305
majidvp944a8cd2016-01-12 21:05:182306 host_impl_->ScrollBy(
2307 UpdateState(gfx::Point(0, 0), gfx::Vector2d(10, 10)).get());
[email protected]9ec24df2013-08-09 23:32:572308 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
2309 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:182310 host_impl_->ScrollEnd(EndState().get());
[email protected]9ec24df2013-08-09 23:32:572311
danakj60bc3bc2016-04-09 00:24:482312 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]9ec24df2013-08-09 23:32:572313 host_impl_->ProcessScrollDeltas();
2314 EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
tdresser99977952015-07-02 19:49:182315 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
bokan1f01388f2015-09-15 20:55:542316 gfx::Vector2d(10, 10)));
[email protected]9ec24df2013-08-09 23:32:572317 }
[email protected]be782f52013-03-23 21:36:142318}
2319
[email protected]aa043632013-03-25 03:39:422320TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
2321 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:402322 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:362323 DrawFrame();
[email protected]df8f44f2013-01-08 08:00:312324
[email protected]adeda572014-01-31 00:49:472325 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
[email protected]aa043632013-03-25 03:39:422326 DCHECK(scroll_layer);
[email protected]df8f44f2013-01-08 08:00:312327
[email protected]aa043632013-03-25 03:39:422328 float min_page_scale = 0.5f;
2329 float max_page_scale = 4.f;
2330 base::TimeTicks start_time = base::TimeTicks() +
2331 base::TimeDelta::FromSeconds(1);
2332 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
2333 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2334 base::TimeTicks end_time = start_time + duration;
[email protected]aa043632013-03-25 03:39:422335
danakj12e2f6e2015-08-19 22:25:442336 BeginFrameArgs begin_frame_args =
2337 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2338
[email protected]aa043632013-03-25 03:39:422339 // Non-anchor zoom-in
2340 {
aelias58eec0812014-12-04 01:04:402341 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422342 max_page_scale);
sunxdb7e79432016-03-09 21:13:422343 scroll_layer->layer_tree_impl()
2344 ->property_trees()
2345 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2346 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]aa043632013-03-25 03:39:422347
[email protected]c2321962014-04-28 19:16:422348 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032349 did_request_next_frame_ = false;
bokanfcdbc182014-11-21 21:53:332350 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482351 std::unique_ptr<PendingPageScaleAnimation>(
2352 new PendingPageScaleAnimation(gfx::Vector2d(), false, 2.f,
2353 duration)));
bokan915bf352014-10-02 21:57:142354 host_impl_->ActivateSyncTree();
[email protected]43b8f982014-04-30 21:24:332355 EXPECT_FALSE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032356 EXPECT_TRUE(did_request_next_frame_);
[email protected]43b8f982014-04-30 21:24:332357
2358 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032359 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442360 begin_frame_args.frame_time = start_time;
2361 host_impl_->WillBeginImplFrame(begin_frame_args);
2362 host_impl_->Animate();
[email protected]34e1b512013-09-26 17:32:332363 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032364 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442365 host_impl_->DidFinishImplFrame();
[email protected]34e1b512013-09-26 17:32:332366
2367 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032368 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442369 begin_frame_args.frame_time = halfway_through_animation;
2370 host_impl_->WillBeginImplFrame(begin_frame_args);
2371 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422372 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032373 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442374 host_impl_->DidFinishImplFrame();
[email protected]34e1b512013-09-26 17:32:332375
2376 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032377 did_request_next_frame_ = false;
[email protected]34e1b512013-09-26 17:32:332378 did_request_commit_ = false;
danakj12e2f6e2015-08-19 22:25:442379 begin_frame_args.frame_time = end_time;
2380 host_impl_->WillBeginImplFrame(begin_frame_args);
2381 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422382 EXPECT_TRUE(did_request_commit_);
danakja18e826a2015-12-03 00:27:032383 EXPECT_FALSE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442384 host_impl_->DidFinishImplFrame();
[email protected]aa043632013-03-25 03:39:422385
danakj60bc3bc2016-04-09 00:24:482386 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422387 host_impl_->ProcessScrollDeltas();
2388 EXPECT_EQ(scroll_info->page_scale_delta, 2);
tdresser99977952015-07-02 19:49:182389 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2390 gfx::Vector2d(-50, -50)));
[email protected]aa043632013-03-25 03:39:422391 }
2392
danakj12e2f6e2015-08-19 22:25:442393 start_time += base::TimeDelta::FromSeconds(10);
2394 halfway_through_animation += base::TimeDelta::FromSeconds(10);
2395 end_time += base::TimeDelta::FromSeconds(10);
2396
[email protected]aa043632013-03-25 03:39:422397 // Anchor zoom-out
2398 {
aelias58eec0812014-12-04 01:04:402399 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422400 max_page_scale);
sunxdb7e79432016-03-09 21:13:422401 scroll_layer->layer_tree_impl()
2402 ->property_trees()
2403 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2404 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]aa043632013-03-25 03:39:422405
[email protected]43b8f982014-04-30 21:24:332406 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032407 did_request_next_frame_ = false;
bokanfcdbc182014-11-21 21:53:332408 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482409 std::unique_ptr<PendingPageScaleAnimation>(
2410 new PendingPageScaleAnimation(gfx::Vector2d(25, 25), true,
2411 min_page_scale, duration)));
bokan915bf352014-10-02 21:57:142412 host_impl_->ActivateSyncTree();
[email protected]43b8f982014-04-30 21:24:332413 EXPECT_FALSE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032414 EXPECT_TRUE(did_request_next_frame_);
[email protected]43b8f982014-04-30 21:24:332415
[email protected]34e1b512013-09-26 17:32:332416 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032417 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442418 begin_frame_args.frame_time = start_time;
2419 host_impl_->WillBeginImplFrame(begin_frame_args);
2420 host_impl_->Animate();
[email protected]34e1b512013-09-26 17:32:332421 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032422 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442423 host_impl_->DidFinishImplFrame();
[email protected]34e1b512013-09-26 17:32:332424
2425 did_request_redraw_ = false;
2426 did_request_commit_ = false;
danakja18e826a2015-12-03 00:27:032427 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442428 begin_frame_args.frame_time = end_time;
2429 host_impl_->WillBeginImplFrame(begin_frame_args);
2430 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422431 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032432 EXPECT_FALSE(did_request_next_frame_);
[email protected]aa043632013-03-25 03:39:422433 EXPECT_TRUE(did_request_commit_);
danakj12e2f6e2015-08-19 22:25:442434 host_impl_->DidFinishImplFrame();
[email protected]aa043632013-03-25 03:39:422435
danakj60bc3bc2016-04-09 00:24:482436 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422437 host_impl_->ProcessScrollDeltas();
2438 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
2439 // Pushed to (0,0) via clamping against contents layer size.
tdresser99977952015-07-02 19:49:182440 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2441 gfx::Vector2d(-50, -50)));
[email protected]aa043632013-03-25 03:39:422442 }
[email protected]df8f44f2013-01-08 08:00:312443}
2444
[email protected]aa043632013-03-25 03:39:422445TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
2446 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:402447 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:362448 DrawFrame();
[email protected]1c0c9bc2012-10-08 22:41:482449
[email protected]adeda572014-01-31 00:49:472450 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
[email protected]aa043632013-03-25 03:39:422451 DCHECK(scroll_layer);
[email protected]1c0c9bc2012-10-08 22:41:482452
[email protected]aa043632013-03-25 03:39:422453 float min_page_scale = 0.5f;
2454 float max_page_scale = 4.f;
2455 base::TimeTicks start_time = base::TimeTicks() +
2456 base::TimeDelta::FromSeconds(1);
2457 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
2458 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2459 base::TimeTicks end_time = start_time + duration;
[email protected]1c0c9bc2012-10-08 22:41:482460
danakj12e2f6e2015-08-19 22:25:442461 BeginFrameArgs begin_frame_args =
2462 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2463
[email protected]aa043632013-03-25 03:39:422464 // Anchor zoom with unchanged page scale should not change scroll or scale.
2465 {
aelias58eec0812014-12-04 01:04:402466 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
[email protected]aa043632013-03-25 03:39:422467 max_page_scale);
sunxdb7e79432016-03-09 21:13:422468 scroll_layer->layer_tree_impl()
2469 ->property_trees()
2470 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2471 scroll_layer->id(), gfx::ScrollOffset(50, 50));
[email protected]c60279472013-01-30 12:10:512472
bokanfcdbc182014-11-21 21:53:332473 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482474 std::unique_ptr<PendingPageScaleAnimation>(
2475 new PendingPageScaleAnimation(gfx::Vector2d(), true, 1.f,
2476 duration)));
bokan915bf352014-10-02 21:57:142477 host_impl_->ActivateSyncTree();
danakj12e2f6e2015-08-19 22:25:442478 begin_frame_args.frame_time = start_time;
2479 host_impl_->WillBeginImplFrame(begin_frame_args);
2480 host_impl_->Animate();
2481 host_impl_->DidFinishImplFrame();
2482
2483 begin_frame_args.frame_time = halfway_through_animation;
2484 host_impl_->WillBeginImplFrame(begin_frame_args);
2485 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422486 EXPECT_TRUE(did_request_redraw_);
danakj12e2f6e2015-08-19 22:25:442487 host_impl_->DidFinishImplFrame();
2488
2489 begin_frame_args.frame_time = end_time;
2490 host_impl_->WillBeginImplFrame(begin_frame_args);
2491 host_impl_->Animate();
[email protected]aa043632013-03-25 03:39:422492 EXPECT_TRUE(did_request_commit_);
danakj12e2f6e2015-08-19 22:25:442493 host_impl_->DidFinishImplFrame();
[email protected]c60279472013-01-30 12:10:512494
danakj60bc3bc2016-04-09 00:24:482495 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:422496 host_impl_->ProcessScrollDeltas();
2497 EXPECT_EQ(scroll_info->page_scale_delta, 1);
2498 ExpectNone(*scroll_info, scroll_layer->id());
2499 }
[email protected]1c0c9bc2012-10-08 22:41:482500}
2501
bokan915bf352014-10-02 21:57:142502TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
2503 host_impl_->CreatePendingTree();
bokan0c33a092015-07-29 18:27:562504 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
bokan915bf352014-10-02 21:57:142505 CreateScrollAndContentsLayers(
2506 host_impl_->pending_tree(),
2507 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:482508 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
bokan915bf352014-10-02 21:57:142509 host_impl_->ActivateSyncTree();
2510 DrawFrame();
2511
2512 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
2513 DCHECK(scroll_layer);
2514
2515 float min_page_scale = 0.5f;
2516 float max_page_scale = 4.f;
aelias58eec0812014-12-04 01:04:402517 host_impl_->sync_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
bokan915bf352014-10-02 21:57:142518 max_page_scale);
2519 host_impl_->ActivateSyncTree();
2520
2521 base::TimeTicks start_time = base::TimeTicks() +
2522 base::TimeDelta::FromSeconds(1);
2523 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
aelias74c39352014-10-14 03:48:142524 base::TimeTicks third_through_animation = start_time + duration / 3;
bokan915bf352014-10-02 21:57:142525 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2526 base::TimeTicks end_time = start_time + duration;
2527 float target_scale = 2.f;
2528
danakj12e2f6e2015-08-19 22:25:442529 BeginFrameArgs begin_frame_args =
2530 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2531
sunxdb7e79432016-03-09 21:13:422532 scroll_layer->layer_tree_impl()
2533 ->property_trees()
2534 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
2535 gfx::ScrollOffset(50, 50));
bokan915bf352014-10-02 21:57:142536
2537 // Make sure TakePageScaleAnimation works properly.
bokanfcdbc182014-11-21 21:53:332538
2539 host_impl_->sync_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482540 std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
2541 gfx::Vector2d(), false, target_scale, duration)));
2542 std::unique_ptr<PendingPageScaleAnimation> psa =
bokanfcdbc182014-11-21 21:53:332543 host_impl_->sync_tree()->TakePendingPageScaleAnimation();
2544 EXPECT_EQ(target_scale, psa->scale);
2545 EXPECT_EQ(duration, psa->duration);
2546 EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePendingPageScaleAnimation());
bokan915bf352014-10-02 21:57:142547
2548 // Recreate the PSA. Nothing should happen here since the tree containing the
2549 // PSA hasn't been activated yet.
2550 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032551 did_request_next_frame_ = false;
bokanfcdbc182014-11-21 21:53:332552 host_impl_->sync_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482553 std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
2554 gfx::Vector2d(), false, target_scale, duration)));
danakj12e2f6e2015-08-19 22:25:442555 begin_frame_args.frame_time = halfway_through_animation;
2556 host_impl_->WillBeginImplFrame(begin_frame_args);
2557 host_impl_->Animate();
danakja18e826a2015-12-03 00:27:032558 EXPECT_FALSE(did_request_next_frame_);
bokan915bf352014-10-02 21:57:142559 EXPECT_FALSE(did_request_redraw_);
danakj12e2f6e2015-08-19 22:25:442560 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142561
2562 // Activate the sync tree. This should cause the animation to become enabled.
2563 // It should also clear the pointer on the sync tree.
2564 host_impl_->ActivateSyncTree();
bokanfcdbc182014-11-21 21:53:332565 EXPECT_EQ(nullptr,
2566 host_impl_->sync_tree()->TakePendingPageScaleAnimation().get());
bokan915bf352014-10-02 21:57:142567 EXPECT_FALSE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032568 EXPECT_TRUE(did_request_next_frame_);
bokan915bf352014-10-02 21:57:142569
danakj12e2f6e2015-08-19 22:25:442570 start_time += base::TimeDelta::FromSeconds(10);
2571 third_through_animation += base::TimeDelta::FromSeconds(10);
2572 halfway_through_animation += base::TimeDelta::FromSeconds(10);
2573 end_time += base::TimeDelta::FromSeconds(10);
2574
bokan915bf352014-10-02 21:57:142575 // From here on, make sure the animation runs as normal.
2576 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032577 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442578 begin_frame_args.frame_time = start_time;
2579 host_impl_->WillBeginImplFrame(begin_frame_args);
2580 host_impl_->Animate();
bokan915bf352014-10-02 21:57:142581 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032582 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442583 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142584
2585 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032586 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442587 begin_frame_args.frame_time = third_through_animation;
2588 host_impl_->WillBeginImplFrame(begin_frame_args);
2589 host_impl_->Animate();
aelias74c39352014-10-14 03:48:142590 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032591 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442592 host_impl_->DidFinishImplFrame();
aelias74c39352014-10-14 03:48:142593
2594 // Another activation shouldn't have any effect on the animation.
2595 host_impl_->ActivateSyncTree();
2596
2597 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032598 did_request_next_frame_ = false;
danakj12e2f6e2015-08-19 22:25:442599 begin_frame_args.frame_time = halfway_through_animation;
2600 host_impl_->WillBeginImplFrame(begin_frame_args);
2601 host_impl_->Animate();
bokan915bf352014-10-02 21:57:142602 EXPECT_TRUE(did_request_redraw_);
danakja18e826a2015-12-03 00:27:032603 EXPECT_TRUE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442604 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142605
2606 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:032607 did_request_next_frame_ = false;
bokan915bf352014-10-02 21:57:142608 did_request_commit_ = false;
danakj12e2f6e2015-08-19 22:25:442609 begin_frame_args.frame_time = end_time;
2610 host_impl_->WillBeginImplFrame(begin_frame_args);
2611 host_impl_->Animate();
bokan915bf352014-10-02 21:57:142612 EXPECT_TRUE(did_request_commit_);
danakja18e826a2015-12-03 00:27:032613 EXPECT_FALSE(did_request_next_frame_);
danakj12e2f6e2015-08-19 22:25:442614 host_impl_->DidFinishImplFrame();
bokan915bf352014-10-02 21:57:142615
danakj60bc3bc2016-04-09 00:24:482616 std::unique_ptr<ScrollAndScaleSet> scroll_info =
bokan915bf352014-10-02 21:57:142617 host_impl_->ProcessScrollDeltas();
2618 EXPECT_EQ(scroll_info->page_scale_delta, target_scale);
tdresser99977952015-07-02 19:49:182619 EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
2620 gfx::Vector2d(-50, -50)));
bokan915bf352014-10-02 21:57:142621}
2622
rouslanf7ebd8832015-01-22 01:54:142623TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
2624 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2625 host_impl_->SetViewportSize(gfx::Size(50, 50));
2626 DrawFrame();
2627
2628 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
2629 DCHECK(scroll_layer);
2630
2631 base::TimeTicks start_time =
2632 base::TimeTicks() + base::TimeDelta::FromSeconds(1);
2633 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
2634 base::TimeTicks halfway_through_animation = start_time + duration / 2;
2635 base::TimeTicks end_time = start_time + duration;
2636
danakj12e2f6e2015-08-19 22:25:442637 BeginFrameArgs begin_frame_args =
2638 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
2639
rouslanf7ebd8832015-01-22 01:54:142640 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
sunxdb7e79432016-03-09 21:13:422641 scroll_layer->layer_tree_impl()
2642 ->property_trees()
2643 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
2644 gfx::ScrollOffset(50, 50));
rouslanf7ebd8832015-01-22 01:54:142645
2646 did_complete_page_scale_animation_ = false;
2647 host_impl_->active_tree()->SetPendingPageScaleAnimation(
danakj60bc3bc2016-04-09 00:24:482648 std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
rouslanf7ebd8832015-01-22 01:54:142649 gfx::Vector2d(), false, 2.f, duration)));
2650 host_impl_->ActivateSyncTree();
danakj12e2f6e2015-08-19 22:25:442651 begin_frame_args.frame_time = start_time;
2652 host_impl_->WillBeginImplFrame(begin_frame_args);
2653 host_impl_->Animate();
rouslanf7ebd8832015-01-22 01:54:142654 EXPECT_FALSE(did_complete_page_scale_animation_);
danakj12e2f6e2015-08-19 22:25:442655 host_impl_->DidFinishImplFrame();
rouslanf7ebd8832015-01-22 01:54:142656
danakj12e2f6e2015-08-19 22:25:442657 begin_frame_args.frame_time = halfway_through_animation;
2658 host_impl_->WillBeginImplFrame(begin_frame_args);
2659 host_impl_->Animate();
rouslanf7ebd8832015-01-22 01:54:142660 EXPECT_FALSE(did_complete_page_scale_animation_);
danakj12e2f6e2015-08-19 22:25:442661 host_impl_->DidFinishImplFrame();
rouslanf7ebd8832015-01-22 01:54:142662
danakj12e2f6e2015-08-19 22:25:442663 begin_frame_args.frame_time = end_time;
2664 host_impl_->WillBeginImplFrame(begin_frame_args);
2665 host_impl_->Animate();
rouslanf7ebd8832015-01-22 01:54:142666 EXPECT_TRUE(did_complete_page_scale_animation_);
danakj12e2f6e2015-08-19 22:25:442667 host_impl_->DidFinishImplFrame();
rouslanf7ebd8832015-01-22 01:54:142668}
2669
sunxdcfccd1b32016-02-11 00:54:202670TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByBoundsDelta) {
2671 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2672 host_impl_->SetViewportSize(gfx::Size(50, 50));
2673 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
danakj74af409e2016-07-01 00:41:482674 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxdcfccd1b32016-02-11 00:54:202675 DrawFrame();
2676
2677 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
2678 LayerImpl* inner_container = inner_scroll->scroll_clip_layer();
2679 DCHECK(inner_scroll);
2680 DCHECK(inner_container);
2681 EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset());
2682
2683 inner_container->SetBoundsDelta(gfx::Vector2dF(15.f, 15.f));
2684 inner_scroll->SetBoundsDelta(gfx::Vector2dF(7.f, 7.f));
2685 EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset());
2686
2687 inner_container->SetBoundsDelta(gfx::Vector2dF());
2688 inner_scroll->SetBoundsDelta(gfx::Vector2dF());
2689 inner_scroll->SetBounds(gfx::Size());
danakj74af409e2016-07-01 00:41:482690 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxdcfccd1b32016-02-11 00:54:202691 DrawFrame();
2692
2693 inner_scroll->SetBoundsDelta(gfx::Vector2dF(60.f, 60.f));
2694 EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset());
2695}
2696
[email protected]21c9dee72013-06-15 01:20:052697class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
2698 public:
2699 LayerTreeHostImplOverridePhysicalTime(
2700 const LayerTreeSettings& settings,
2701 LayerTreeHostImplClient* client,
khushalsagarb64b360d2015-10-21 19:25:162702 TaskRunnerProvider* task_runner_provider,
[email protected]4e2eb352014-03-20 17:25:452703 SharedBitmapManager* manager,
danakjcf610582015-06-16 22:48:562704 TaskGraphRunner* task_graph_runner,
[email protected]21c9dee72013-06-15 01:20:052705 RenderingStatsInstrumentation* rendering_stats_instrumentation)
2706 : LayerTreeHostImpl(settings,
2707 client,
khushalsagarb64b360d2015-10-21 19:25:162708 task_runner_provider,
[email protected]a7f35682013-10-22 23:05:572709 rendering_stats_instrumentation,
[email protected]4e2eb352014-03-20 17:25:452710 manager,
danakjcf610582015-06-16 22:48:562711 nullptr,
2712 task_graph_runner,
loysoab32ee72016-06-08 03:33:182713 AnimationHost::CreateForTesting(ThreadInstance::IMPL),
[email protected]dbe759a2013-12-02 19:23:022714 0) {}
[email protected]21c9dee72013-06-15 01:20:052715
dcheng716bedf2014-10-21 09:51:082716 BeginFrameArgs CurrentBeginFrameArgs() const override {
mithro06d1f3bf2014-12-02 02:19:152717 return CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE,
2718 fake_current_physical_time_);
[email protected]21c9dee72013-06-15 01:20:052719 }
2720
2721 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) {
2722 fake_current_physical_time_ = fake_now;
2723 }
2724
2725 private:
2726 base::TimeTicks fake_current_physical_time_;
2727};
2728
sunnyps102dbf692015-03-07 02:17:462729class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
2730 protected:
2731 void SetupLayers(LayerTreeSettings settings) {
danakjee6547a22016-07-01 20:41:502732 host_impl_->ReleaseOutputSurface();
2733 host_impl_ = nullptr;
2734
sunnyps102dbf692015-03-07 02:17:462735 gfx::Size content_size(100, 100);
[email protected]e6e7f292014-04-24 22:23:032736
sunnyps102dbf692015-03-07 02:17:462737 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =
danakjcf610582015-06-16 22:48:562738 new LayerTreeHostImplOverridePhysicalTime(
khushalsagarb64b360d2015-10-21 19:25:162739 settings, this, &task_runner_provider_, &shared_bitmap_manager_,
danakjcf610582015-06-16 22:48:562740 &task_graph_runner_, &stats_instrumentation_);
danakj60bc3bc2016-04-09 00:24:482741 host_impl_ = base::WrapUnique(host_impl_override_time);
revemand180dfc32015-09-24 00:19:432742 output_surface_ = CreateOutputSurface();
sievers71c62dd52015-10-07 01:44:392743 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:432744 host_impl_->InitializeRenderer(output_surface_.get());
[email protected]21c9dee72013-06-15 01:20:052745
bokan1f86d8f2015-07-30 16:08:542746 SetupScrollAndContentsLayers(content_size);
2747 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
2748 host_impl_->SetViewportSize(
2749 gfx::Size(content_size.width() / 2, content_size.height() / 2));
[email protected]21c9dee72013-06-15 01:20:052750
danakj60bc3bc2016-04-09 00:24:482751 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
bokan1f86d8f2015-07-30 16:08:542752 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 400,
sunnyps102dbf692015-03-07 02:17:462753 VERTICAL, 10, 0, false, true);
jaydasikaab317e02016-06-01 00:53:182754 scrollbar->test_properties()->opacity = 0.f;
2755 EXPECT_FLOAT_EQ(0.f, scrollbar->test_properties()->opacity);
[email protected]cdc07002013-09-06 22:33:462756
aeliasa57c40d122015-10-08 00:20:092757 LayerImpl* scroll = host_impl_->active_tree()->OuterViewportScrollLayer();
2758 LayerImpl* root = host_impl_->active_tree()->InnerViewportContainerLayer();
2759 scrollbar->SetScrollLayerId(scroll->id());
jaydasika89f7b5a2016-06-22 02:08:392760 root->test_properties()->AddChild(std::move(scrollbar));
danakj74af409e2016-07-01 00:41:482761 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunnyps102dbf692015-03-07 02:17:462762 host_impl_->active_tree()->DidBecomeActive();
2763 DrawFrame();
2764 }
sunnypsae4316a2015-02-25 00:54:582765
sunnyps102dbf692015-03-07 02:17:462766 void RunTest(LayerTreeSettings::ScrollbarAnimator animator) {
weiliangc8f4ef0d2015-11-27 00:15:552767 LayerTreeSettings settings = DefaultSettings();
sunnyps102dbf692015-03-07 02:17:462768 settings.scrollbar_animator = animator;
2769 settings.scrollbar_fade_delay_ms = 20;
2770 settings.scrollbar_fade_duration_ms = 20;
[email protected]21c9dee72013-06-15 01:20:052771
eseckler025a0202016-08-05 09:16:122772 // If no animator is set, scrollbar won't show and no animation is expected.
2773 bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR;
2774
sunnyps102dbf692015-03-07 02:17:462775 SetupLayers(settings);
[email protected]21c9dee72013-06-15 01:20:052776
abhishek.ka7215854d2015-05-26 06:13:172777 base::TimeTicks fake_now = base::TimeTicks::Now();
sataya.m68d7d9b42014-09-22 16:01:592778
eseckler025a0202016-08-05 09:16:122779 if (expecting_animations) {
2780 // A task will be posted to fade the initial scrollbar.
2781 EXPECT_FALSE(did_request_next_frame_);
2782 EXPECT_FALSE(did_request_redraw_);
2783 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2784 requested_animation_delay_ = base::TimeDelta();
2785 animation_task_ = base::Closure();
2786 } else {
2787 EXPECT_FALSE(did_request_next_frame_);
2788 EXPECT_FALSE(did_request_redraw_);
2789 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2790 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2791 }
sunnypsae4316a2015-02-25 00:54:582792
sunnyps102dbf692015-03-07 02:17:462793 // If no scroll happened during a scroll gesture, it should have no effect.
majidvp944a8cd2016-01-12 21:05:182794 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
2795 InputHandler::WHEEL);
2796 host_impl_->ScrollEnd(EndState().get());
danakja18e826a2015-12-03 00:27:032797 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462798 EXPECT_FALSE(did_request_redraw_);
2799 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2800 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2801
danakja18e826a2015-12-03 00:27:032802 // Before the scrollbar animation exists, we should not get redraws.
2803 BeginFrameArgs begin_frame_args =
2804 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2805 host_impl_->WillBeginImplFrame(begin_frame_args);
2806 host_impl_->Animate();
2807 EXPECT_FALSE(did_request_next_frame_);
2808 did_request_next_frame_ = false;
2809 EXPECT_FALSE(did_request_redraw_);
2810 did_request_redraw_ = false;
2811 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2812 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2813 host_impl_->DidFinishImplFrame();
2814
sunnyps102dbf692015-03-07 02:17:462815 // After a scroll, a scrollbar animation should be scheduled about 20ms from
2816 // now.
majidvp944a8cd2016-01-12 21:05:182817 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
2818 InputHandler::WHEEL);
2819 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get());
danakja18e826a2015-12-03 00:27:032820 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462821 EXPECT_TRUE(did_request_redraw_);
2822 did_request_redraw_ = false;
2823 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2824 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2825
majidvp944a8cd2016-01-12 21:05:182826 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:492827 host_impl_->ClearCurrentlyScrollingLayerForTesting();
danakja18e826a2015-12-03 00:27:032828 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462829 EXPECT_FALSE(did_request_redraw_);
eseckler025a0202016-08-05 09:16:122830 if (expecting_animations) {
2831 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
2832 requested_animation_delay_);
2833 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2834 } else {
2835 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2836 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2837 }
sunnyps102dbf692015-03-07 02:17:462838
eseckler025a0202016-08-05 09:16:122839 if (expecting_animations) {
2840 // Before the scrollbar animation begins, we should not get redraws.
2841 begin_frame_args =
2842 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2843 host_impl_->WillBeginImplFrame(begin_frame_args);
2844 host_impl_->Animate();
2845 EXPECT_FALSE(did_request_next_frame_);
2846 did_request_next_frame_ = false;
2847 EXPECT_FALSE(did_request_redraw_);
2848 did_request_redraw_ = false;
2849 host_impl_->DidFinishImplFrame();
danakja18e826a2015-12-03 00:27:032850
eseckler025a0202016-08-05 09:16:122851 // Start the scrollbar animation.
2852 fake_now += requested_animation_delay_;
2853 requested_animation_delay_ = base::TimeDelta();
2854 animation_task_.Run();
2855 animation_task_ = base::Closure();
2856 EXPECT_TRUE(did_request_next_frame_);
2857 did_request_next_frame_ = false;
2858 EXPECT_FALSE(did_request_redraw_);
sunnyps102dbf692015-03-07 02:17:462859
eseckler025a0202016-08-05 09:16:122860 // After the scrollbar animation begins, we should start getting redraws.
2861 begin_frame_args =
2862 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2863 host_impl_->WillBeginImplFrame(begin_frame_args);
2864 host_impl_->Animate();
2865 EXPECT_TRUE(did_request_next_frame_);
2866 did_request_next_frame_ = false;
2867 EXPECT_TRUE(did_request_redraw_);
2868 did_request_redraw_ = false;
2869 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2870 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2871 host_impl_->DidFinishImplFrame();
2872 }
sunnyps102dbf692015-03-07 02:17:462873
2874 // Setting the scroll offset outside a scroll should also cause the
2875 // scrollbar to appear and to schedule a scrollbar animation.
sunxdb7e79432016-03-09 21:13:422876 if (host_impl_->active_tree()
2877 ->property_trees()
2878 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
2879 host_impl_->InnerViewportScrollLayer()->id(),
2880 gfx::ScrollOffset(5, 5)))
sunxdc044b11a2016-03-16 16:23:202881 host_impl_->active_tree()->DidUpdateScrollOffset(
2882 host_impl_->InnerViewportScrollLayer()->id(),
2883 host_impl_->InnerViewportScrollLayer()->transform_tree_index());
danakja18e826a2015-12-03 00:27:032884 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462885 EXPECT_FALSE(did_request_redraw_);
eseckler025a0202016-08-05 09:16:122886 if (expecting_animations) {
2887 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
2888 requested_animation_delay_);
2889 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2890 requested_animation_delay_ = base::TimeDelta();
2891 animation_task_ = base::Closure();
2892 } else {
2893 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2894 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2895 }
sunnyps102dbf692015-03-07 02:17:462896
eseckler025a0202016-08-05 09:16:122897 if (expecting_animations) {
2898 // Scrolling should have stopped the animation, so we should not be
2899 // getting redraws.
2900 begin_frame_args =
2901 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, fake_now);
2902 host_impl_->WillBeginImplFrame(begin_frame_args);
2903 host_impl_->Animate();
2904 EXPECT_FALSE(did_request_next_frame_);
2905 did_request_next_frame_ = false;
2906 EXPECT_FALSE(did_request_redraw_);
2907 did_request_redraw_ = false;
2908 host_impl_->DidFinishImplFrame();
2909 }
danakja18e826a2015-12-03 00:27:032910
sunnyps102dbf692015-03-07 02:17:462911 // Scrollbar animation is not triggered unnecessarily.
majidvp944a8cd2016-01-12 21:05:182912 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
2913 InputHandler::WHEEL);
2914 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(5, 0)).get());
danakja18e826a2015-12-03 00:27:032915 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462916 EXPECT_TRUE(did_request_redraw_);
2917 did_request_redraw_ = false;
2918 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2919 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2920
majidvp944a8cd2016-01-12 21:05:182921 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:492922 host_impl_->ClearCurrentlyScrollingLayerForTesting();
danakja18e826a2015-12-03 00:27:032923 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462924 EXPECT_FALSE(did_request_redraw_);
2925 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2926 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2927
2928 // Changing page scale triggers scrollbar animation.
2929 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
danakj5ad246cd2015-09-12 01:04:502930 host_impl_->active_tree()->SetPageScaleOnActiveTree(1.1f);
danakja18e826a2015-12-03 00:27:032931 EXPECT_FALSE(did_request_next_frame_);
sunnyps102dbf692015-03-07 02:17:462932 EXPECT_FALSE(did_request_redraw_);
eseckler025a0202016-08-05 09:16:122933 if (expecting_animations) {
2934 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
2935 requested_animation_delay_);
2936 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
2937 requested_animation_delay_ = base::TimeDelta();
2938 animation_task_ = base::Closure();
2939 } else {
2940 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
2941 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
2942 }
sunnyps102dbf692015-03-07 02:17:462943 }
2944};
2945
2946TEST_F(LayerTreeHostImplTestScrollbarAnimation, LinearFade) {
2947 RunTest(LayerTreeSettings::LINEAR_FADE);
[email protected]21c9dee72013-06-15 01:20:052948}
2949
sunnyps102dbf692015-03-07 02:17:462950TEST_F(LayerTreeHostImplTestScrollbarAnimation, Thinning) {
2951 RunTest(LayerTreeSettings::THINNING);
[email protected]e6e7f292014-04-24 22:23:032952}
2953
eseckler025a0202016-08-05 09:16:122954TEST_F(LayerTreeHostImplTestScrollbarAnimation, NoAnimator) {
2955 RunTest(LayerTreeSettings::NO_ANIMATOR);
2956}
2957
jaydasika4f290d82015-09-18 20:25:212958class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
2959 protected:
2960 void RunTest(LayerTreeSettings::ScrollbarAnimator animator) {
weiliangc8f4ef0d2015-11-27 00:15:552961 LayerTreeSettings settings = DefaultSettings();
jaydasika4f290d82015-09-18 20:25:212962 settings.scrollbar_animator = animator;
2963 settings.scrollbar_fade_delay_ms = 20;
2964 settings.scrollbar_fade_duration_ms = 20;
jaydasika4f290d82015-09-18 20:25:212965 gfx::Size content_size(100, 100);
2966
eseckler025a0202016-08-05 09:16:122967 // If no animator is set, scrollbar won't show and no animation is expected.
2968 bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR;
2969
jaydasika4f290d82015-09-18 20:25:212970 CreateHostImpl(settings, CreateOutputSurface());
2971 host_impl_->CreatePendingTree();
2972 CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size);
danakj60bc3bc2016-04-09 00:24:482973 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
jaydasika4f290d82015-09-18 20:25:212974 SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400,
2975 VERTICAL, 10, 0, false, true);
jaydasikaab317e02016-06-01 00:53:182976 scrollbar->test_properties()->opacity = 0.f;
aeliasa57c40d122015-10-08 00:20:092977 LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer();
jaydasika52c00182016-06-02 08:57:172978 LayerImpl* container =
2979 host_impl_->pending_tree()->InnerViewportContainerLayer();
aeliasa57c40d122015-10-08 00:20:092980 scrollbar->SetScrollLayerId(scroll->id());
jaydasika89f7b5a2016-06-22 02:08:392981 container->test_properties()->AddChild(std::move(scrollbar));
jaydasika4f290d82015-09-18 20:25:212982 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
danakj74af409e2016-07-01 00:41:482983 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasika4f290d82015-09-18 20:25:212984 host_impl_->ActivateSyncTree();
2985
jaydasika52c00182016-06-02 08:57:172986 LayerImpl* active_scrollbar_layer =
2987 host_impl_->active_tree()->LayerById(400);
jaydasika4f290d82015-09-18 20:25:212988
2989 EffectNode* active_tree_node =
2990 host_impl_->active_tree()->property_trees()->effect_tree.Node(
jaydasika52c00182016-06-02 08:57:172991 active_scrollbar_layer->effect_tree_index());
2992 EXPECT_FLOAT_EQ(active_scrollbar_layer->Opacity(),
trchendba8b1502016-07-08 09:47:012993 active_tree_node->opacity);
jaydasika4f290d82015-09-18 20:25:212994
eseckler025a0202016-08-05 09:16:122995 if (expecting_animations) {
2996 host_impl_->ScrollbarAnimationControllerForId(scroll->id())
2997 ->DidMouseMoveNear(0);
2998 } else {
2999 EXPECT_EQ(nullptr,
3000 host_impl_->ScrollbarAnimationControllerForId(scroll->id()));
3001 }
majidvp944a8cd2016-01-12 21:05:183002 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
3003 InputHandler::WHEEL);
3004 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get());
3005 host_impl_->ScrollEnd(EndState().get());
jaydasika4f290d82015-09-18 20:25:213006 host_impl_->CreatePendingTree();
jaydasika52c00182016-06-02 08:57:173007 // To test the case where the effect tree index of scrollbar layer changes,
3008 // we force the container layer to create a render surface.
3009 container = host_impl_->pending_tree()->InnerViewportContainerLayer();
3010 container->test_properties()->force_render_surface = true;
3011 container->SetBounds(gfx::Size(10, 10));
danakj74af409e2016-07-01 00:41:483012 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasika52c00182016-06-02 08:57:173013
3014 LayerImpl* pending_scrollbar_layer =
3015 host_impl_->pending_tree()->LayerById(400);
eseckler025a0202016-08-05 09:16:123016 pending_scrollbar_layer->SetNeedsPushProperties();
jaydasika4f290d82015-09-18 20:25:213017 EffectNode* pending_tree_node =
3018 host_impl_->pending_tree()->property_trees()->effect_tree.Node(
jaydasika52c00182016-06-02 08:57:173019 pending_scrollbar_layer->effect_tree_index());
jaydasikaae9b7a02016-05-19 16:12:523020 host_impl_->pending_tree()
3021 ->property_trees()
3022 ->always_use_active_tree_opacity_effect_ids.push_back(400);
eseckler025a0202016-08-05 09:16:123023 if (expecting_animations) {
3024 EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity);
3025 EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity());
3026 } else {
3027 EXPECT_FLOAT_EQ(0.f, active_tree_node->opacity);
3028 EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity());
3029 }
trchendba8b1502016-07-08 09:47:013030 EXPECT_FLOAT_EQ(0.f, pending_tree_node->opacity);
jaydasika4f290d82015-09-18 20:25:213031 host_impl_->ActivateSyncTree();
3032 active_tree_node =
3033 host_impl_->active_tree()->property_trees()->effect_tree.Node(
jaydasika52c00182016-06-02 08:57:173034 active_scrollbar_layer->effect_tree_index());
eseckler025a0202016-08-05 09:16:123035 if (expecting_animations) {
3036 EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity);
3037 EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity());
3038 } else {
3039 EXPECT_FLOAT_EQ(0.f, active_tree_node->opacity);
3040 EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity());
3041 }
jaydasika4f290d82015-09-18 20:25:213042 }
3043};
3044
3045TEST_F(LayerTreeHostImplTestScrollbarOpacity, LinearFade) {
3046 RunTest(LayerTreeSettings::LINEAR_FADE);
3047}
3048
3049TEST_F(LayerTreeHostImplTestScrollbarOpacity, Thinning) {
3050 RunTest(LayerTreeSettings::THINNING);
3051}
3052
eseckler025a0202016-08-05 09:16:123053TEST_F(LayerTreeHostImplTestScrollbarOpacity, NoAnimator) {
3054 RunTest(LayerTreeSettings::NO_ANIMATOR);
3055}
3056
aelias14d87e0c2015-11-04 00:12:503057TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) {
weiliangc8f4ef0d2015-11-27 00:15:553058 LayerTreeSettings settings = DefaultSettings();
aelias14d87e0c2015-11-04 00:12:503059 CreateHostImpl(settings, CreateOutputSurface());
3060
3061 gfx::Size inner_viewport_size(315, 200);
3062 gfx::Size outer_viewport_size(300, 200);
3063 gfx::Size content_size(1000, 1000);
3064
3065 const int horiz_id = 11;
3066 const int child_clip_id = 14;
3067 const int child_scroll_id = 15;
3068
3069 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
3070 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3071 inner_viewport_size);
3072 host_impl_->active_tree()->OuterViewportContainerLayer()->SetBounds(
3073 outer_viewport_size);
3074 LayerImpl* root_scroll =
3075 host_impl_->active_tree()->OuterViewportScrollLayer();
danakj60bc3bc2016-04-09 00:24:483076 std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar =
aelias14d87e0c2015-11-04 00:12:503077 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id,
3078 HORIZONTAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483079 std::unique_ptr<LayerImpl> child =
aelias14d87e0c2015-11-04 00:12:503080 LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
3081 child->SetBounds(content_size);
danakj60bc3bc2016-04-09 00:24:483082 std::unique_ptr<LayerImpl> child_clip =
aelias14d87e0c2015-11-04 00:12:503083 LayerImpl::Create(host_impl_->active_tree(), child_clip_id);
3084 child->SetBounds(inner_viewport_size);
3085
3086 horiz_scrollbar->SetScrollLayerId(root_scroll->id());
3087
3088 EXPECT_EQ(300, horiz_scrollbar->clip_layer_length());
3089}
3090
aeliasa57c40d122015-10-08 00:20:093091TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
weiliangc8f4ef0d2015-11-27 00:15:553092 LayerTreeSettings settings = DefaultSettings();
aeliasa57c40d122015-10-08 00:20:093093 settings.scrollbar_animator = LayerTreeSettings::LINEAR_FADE;
3094 settings.scrollbar_fade_delay_ms = 20;
3095 settings.scrollbar_fade_duration_ms = 20;
3096 CreateHostImpl(settings, CreateOutputSurface());
3097
3098 gfx::Size viewport_size(300, 200);
3099 gfx::Size content_size(1000, 1000);
3100
3101 const int vert_1_id = 10;
3102 const int horiz_1_id = 11;
3103 const int vert_2_id = 12;
3104 const int horiz_2_id = 13;
3105 const int child_clip_id = 14;
3106 const int child_scroll_id = 15;
3107
3108 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
3109 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3110 viewport_size);
3111 LayerImpl* root_scroll =
3112 host_impl_->active_tree()->OuterViewportScrollLayer();
danakj60bc3bc2016-04-09 00:24:483113 std::unique_ptr<SolidColorScrollbarLayerImpl> vert_1_scrollbar =
aeliasa57c40d122015-10-08 00:20:093114 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_1_id,
3115 VERTICAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483116 std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_1_scrollbar =
aeliasa57c40d122015-10-08 00:20:093117 SolidColorScrollbarLayerImpl::Create(
3118 host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483119 std::unique_ptr<SolidColorScrollbarLayerImpl> vert_2_scrollbar =
aeliasa57c40d122015-10-08 00:20:093120 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_2_id,
3121 VERTICAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483122 std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_2_scrollbar =
aeliasa57c40d122015-10-08 00:20:093123 SolidColorScrollbarLayerImpl::Create(
3124 host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true);
danakj60bc3bc2016-04-09 00:24:483125 std::unique_ptr<LayerImpl> child =
aeliasa57c40d122015-10-08 00:20:093126 LayerImpl::Create(host_impl_->active_tree(), child_scroll_id);
3127 child->SetBounds(content_size);
danakj60bc3bc2016-04-09 00:24:483128 std::unique_ptr<LayerImpl> child_clip =
aeliasa57c40d122015-10-08 00:20:093129 LayerImpl::Create(host_impl_->active_tree(), child_clip_id);
3130 child->SetBounds(viewport_size);
3131 LayerImpl* child_ptr = child.get();
3132 LayerImpl* child_clip_ptr = child_clip.get();
3133
3134 // Check scrollbar registration on the viewport layers.
3135 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3136 EXPECT_EQ(nullptr,
3137 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3138 vert_1_scrollbar->SetScrollLayerId(root_scroll->id());
3139 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3140 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3141 horiz_1_scrollbar->SetScrollLayerId(root_scroll->id());
3142 EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3143 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3144
3145 // Changing one of the viewport layers should result in a scrollbar animation
3146 // update.
3147 animation_task_ = base::Closure();
3148 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBoundsDelta(
3149 gfx::Vector2dF(10, 10));
3150 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3151 animation_task_ = base::Closure();
3152 host_impl_->active_tree()->OuterViewportScrollLayer()->SetCurrentScrollOffset(
3153 gfx::ScrollOffset(10, 10));
3154 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3155 animation_task_ = base::Closure();
3156 host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset(
3157 gfx::ScrollOffset(10, 10));
3158 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3159 animation_task_ = base::Closure();
3160
3161 // Check scrollbar registration on a sublayer.
3162 child->SetScrollClipLayer(child_clip->id());
jaydasika89f7b5a2016-06-22 02:08:393163 child_clip->test_properties()->AddChild(std::move(child));
3164 root_scroll->test_properties()->AddChild(std::move(child_clip));
aeliasa57c40d122015-10-08 00:20:093165 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3166 EXPECT_EQ(nullptr,
3167 host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3168 vert_2_scrollbar->SetScrollLayerId(child_scroll_id);
3169 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3170 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3171 horiz_2_scrollbar->SetScrollLayerId(child_scroll_id);
3172 EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3173 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3174
3175 // Changing one of the child layers should result in a scrollbar animation
3176 // update.
3177 animation_task_ = base::Closure();
3178 child_clip_ptr->SetBounds(gfx::Size(200, 200));
3179 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3180 animation_task_ = base::Closure();
3181 child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(10, 10));
3182 EXPECT_FALSE(animation_task_.Equals(base::Closure()));
3183 animation_task_ = base::Closure();
3184
3185 // Check scrollbar unregistration.
3186 vert_1_scrollbar.reset();
3187 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3188 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3189 horiz_1_scrollbar.reset();
3190 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size());
3191 EXPECT_EQ(nullptr,
3192 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3193
3194 EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3195 vert_2_scrollbar.reset();
3196 EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3197 EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id));
3198 horiz_2_scrollbar.reset();
3199 EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size());
3200 EXPECT_EQ(nullptr,
3201 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
3202
3203 // Changing scroll offset should no longer trigger any animation.
3204 host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset(
3205 gfx::ScrollOffset(20, 20));
3206 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
3207 child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(20, 20));
3208 EXPECT_TRUE(animation_task_.Equals(base::Closure()));
3209}
3210
[email protected]bf1cfd9a2013-09-26 05:43:023211void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
3212 float device_scale_factor) {
weiliangc8f4ef0d2015-11-27 00:15:553213 LayerTreeSettings settings = DefaultSettings();
[email protected]930ff43b2014-05-02 05:24:003214 settings.scrollbar_fade_delay_ms = 500;
3215 settings.scrollbar_fade_duration_ms = 300;
ericrk7c030992015-02-20 01:39:383216 settings.scrollbar_animator = LayerTreeSettings::THINNING;
[email protected]bf1cfd9a2013-09-26 05:43:023217
3218 gfx::Size viewport_size(300, 200);
danakjddaec912015-09-25 19:38:403219 gfx::Size device_viewport_size =
3220 gfx::ScaleToFlooredSize(viewport_size, device_scale_factor);
[email protected]bf1cfd9a2013-09-26 05:43:023221 gfx::Size content_size(1000, 1000);
aeliasa57c40d122015-10-08 00:20:093222 gfx::Size scrollbar_size(gfx::Size(15, viewport_size.height()));
[email protected]bf1cfd9a2013-09-26 05:43:023223
[email protected]ce2e8112013-11-28 07:44:363224 CreateHostImpl(settings, CreateOutputSurface());
ajuma1d48e012015-09-25 22:24:163225 host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor);
[email protected]bf1cfd9a2013-09-26 05:43:023226 host_impl_->SetViewportSize(device_viewport_size);
3227
aeliasa57c40d122015-10-08 00:20:093228 CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
3229 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3230 viewport_size);
[email protected]adeda572014-01-31 00:49:473231 LayerImpl* root_scroll =
aeliasa57c40d122015-10-08 00:20:093232 host_impl_->active_tree()->OuterViewportScrollLayer();
3233 // The scrollbar is on the left side.
danakj60bc3bc2016-04-09 00:24:483234 std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar =
aeliasa57c40d122015-10-08 00:20:093235 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6,
3236 VERTICAL, 5, 5, true, true);
3237 scrollbar->SetScrollLayerId(root_scroll->id());
3238 scrollbar->SetDrawsContent(true);
3239 scrollbar->SetBounds(scrollbar_size);
3240 scrollbar->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size));
jaydasika89f7b5a2016-06-22 02:08:393241 host_impl_->active_tree()
3242 ->InnerViewportContainerLayer()
3243 ->test_properties()
3244 ->AddChild(std::move(scrollbar));
danakj74af409e2016-07-01 00:41:483245 host_impl_->active_tree()->BuildPropertyTreesForTesting();
aeliasa57c40d122015-10-08 00:20:093246 host_impl_->active_tree()->DidBecomeActive();
3247
3248 DrawFrame();
3249 host_impl_->active_tree()->UpdateDrawProperties(false);
3250
[email protected]bf1cfd9a2013-09-26 05:43:023251 ScrollbarAnimationControllerThinning* scrollbar_animation_controller =
3252 static_cast<ScrollbarAnimationControllerThinning*>(
aeliasa57c40d122015-10-08 00:20:093253 host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()));
[email protected]bf1cfd9a2013-09-26 05:43:023254 scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
3255
aeliasa57c40d122015-10-08 00:20:093256 host_impl_->MouseMoveAt(gfx::Point(200, 1));
[email protected]534236b2013-10-25 21:19:203257 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023258
aeliasa57c40d122015-10-08 00:20:093259 host_impl_->MouseMoveAt(gfx::Point(100, 50));
[email protected]534236b2013-10-25 21:19:203260 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023261
aeliasa57c40d122015-10-08 00:20:093262 host_impl_->MouseMoveAt(gfx::Point(116, 100));
[email protected]534236b2013-10-25 21:19:203263 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023264
3265 scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
aeliasa57c40d122015-10-08 00:20:093266 host_impl_->MouseMoveAt(gfx::Point(116, 100));
[email protected]534236b2013-10-25 21:19:203267 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]f620b0e72013-10-01 21:38:243268
3269 did_request_redraw_ = false;
aeliasa57c40d122015-10-08 00:20:093270 EXPECT_EQ(Layer::INVALID_ID,
3271 host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
3272 host_impl_->MouseMoveAt(gfx::Point(10, 100));
3273 EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
3274 host_impl_->MouseMoveAt(gfx::Point(10, 120));
3275 EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
[email protected]f620b0e72013-10-01 21:38:243276 host_impl_->MouseMoveAt(gfx::Point(150, 120));
aeliasa57c40d122015-10-08 00:20:093277 EXPECT_EQ(Layer::INVALID_ID,
3278 host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:023279}
3280
3281TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
3282 SetupMouseMoveAtWithDeviceScale(1.f);
3283}
3284
3285TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
3286 SetupMouseMoveAtWithDeviceScale(2.f);
3287}
3288
[email protected]aa043632013-03-25 03:39:423289TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
3290 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:403291 host_impl_->SetViewportSize(gfx::Size(50, 50));
aelias58eec0812014-12-04 01:04:403292 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:363293 DrawFrame();
[email protected]aa043632013-03-25 03:39:423294 {
3295 CompositorFrameMetadata metadata =
3296 host_impl_->MakeCompositorFrameMetadata();
3297 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
3298 EXPECT_EQ(1.f, metadata.page_scale_factor);
[email protected]f3f611f2014-07-09 04:05:323299 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size);
[email protected]aa043632013-03-25 03:39:423300 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
3301 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
3302 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
jdduke2afdbf722015-02-12 06:28:203303 EXPECT_FALSE(metadata.root_overflow_x_hidden);
3304 EXPECT_FALSE(metadata.root_overflow_y_hidden);
[email protected]aa043632013-03-25 03:39:423305 }
[email protected]94f206c12012-08-25 00:09:143306
[email protected]aa043632013-03-25 03:39:423307 // Scrolling should update metadata immediately.
tdresser81e84c672016-01-18 23:21:223308 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:183309 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:223310 InputHandler::WHEEL)
3311 .thread);
majidvp944a8cd2016-01-12 21:05:183312 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
[email protected]aa043632013-03-25 03:39:423313 {
3314 CompositorFrameMetadata metadata =
3315 host_impl_->MakeCompositorFrameMetadata();
3316 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3317 }
majidvp944a8cd2016-01-12 21:05:183318 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:423319 {
3320 CompositorFrameMetadata metadata =
3321 host_impl_->MakeCompositorFrameMetadata();
3322 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3323 }
[email protected]94f206c12012-08-25 00:09:143324
hush33370e12015-04-07 03:49:503325 // Root "overflow: hidden" properties should be reflected on the outer
3326 // viewport scroll layer.
jdduke2afdbf722015-02-12 06:28:203327 {
3328 host_impl_->active_tree()
hush33370e12015-04-07 03:49:503329 ->OuterViewportScrollLayer()
jdduke2afdbf722015-02-12 06:28:203330 ->set_user_scrollable_horizontal(false);
3331 CompositorFrameMetadata metadata =
3332 host_impl_->MakeCompositorFrameMetadata();
3333 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3334 EXPECT_FALSE(metadata.root_overflow_y_hidden);
3335
3336 host_impl_->active_tree()
hush33370e12015-04-07 03:49:503337 ->OuterViewportScrollLayer()
jdduke2afdbf722015-02-12 06:28:203338 ->set_user_scrollable_vertical(false);
3339 metadata = host_impl_->MakeCompositorFrameMetadata();
3340 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3341 EXPECT_TRUE(metadata.root_overflow_y_hidden);
3342 }
3343
hugo.holgerssone5e7aa92015-08-17 14:07:193344 // Re-enable scrollability and verify that overflows are no longer hidden.
3345 {
3346 host_impl_->active_tree()
3347 ->OuterViewportScrollLayer()
3348 ->set_user_scrollable_horizontal(true);
3349 host_impl_->active_tree()
3350 ->OuterViewportScrollLayer()
3351 ->set_user_scrollable_vertical(true);
3352 CompositorFrameMetadata metadata =
3353 host_impl_->MakeCompositorFrameMetadata();
3354 EXPECT_FALSE(metadata.root_overflow_x_hidden);
3355 EXPECT_FALSE(metadata.root_overflow_y_hidden);
3356 }
3357
3358 // Root "overflow: hidden" properties should also be reflected on the
3359 // inner viewport scroll layer.
3360 {
3361 host_impl_->active_tree()
3362 ->InnerViewportScrollLayer()
3363 ->set_user_scrollable_horizontal(false);
3364 CompositorFrameMetadata metadata =
3365 host_impl_->MakeCompositorFrameMetadata();
3366 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3367 EXPECT_FALSE(metadata.root_overflow_y_hidden);
3368
3369 host_impl_->active_tree()
3370 ->InnerViewportScrollLayer()
3371 ->set_user_scrollable_vertical(false);
3372 metadata = host_impl_->MakeCompositorFrameMetadata();
3373 EXPECT_TRUE(metadata.root_overflow_x_hidden);
3374 EXPECT_TRUE(metadata.root_overflow_y_hidden);
3375 }
3376
[email protected]aa043632013-03-25 03:39:423377 // Page scale should update metadata correctly (shrinking only the viewport).
majidvp944a8cd2016-01-12 21:05:183378 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:033379 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:423380 host_impl_->PinchGestureBegin();
3381 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
3382 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:183383 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:423384 {
3385 CompositorFrameMetadata metadata =
3386 host_impl_->MakeCompositorFrameMetadata();
3387 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3388 EXPECT_EQ(2.f, metadata.page_scale_factor);
[email protected]f3f611f2014-07-09 04:05:323389 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size);
[email protected]aa043632013-03-25 03:39:423390 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
3391 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
3392 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
3393 }
[email protected]94f206c12012-08-25 00:09:143394
[email protected]aa043632013-03-25 03:39:423395 // Likewise if set from the main thread.
3396 host_impl_->ProcessScrollDeltas();
aelias58eec0812014-12-04 01:04:403397 host_impl_->active_tree()->PushPageScaleFromMainThread(4.f, 0.5f, 4.f);
danakj5ad246cd2015-09-12 01:04:503398 host_impl_->active_tree()->SetPageScaleOnActiveTree(4.f);
[email protected]aa043632013-03-25 03:39:423399 {
3400 CompositorFrameMetadata metadata =
3401 host_impl_->MakeCompositorFrameMetadata();
3402 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
3403 EXPECT_EQ(4.f, metadata.page_scale_factor);
[email protected]f3f611f2014-07-09 04:05:323404 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size);
[email protected]aa043632013-03-25 03:39:423405 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
3406 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
3407 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
3408 }
[email protected]f2b5a5be2013-01-08 00:34:363409}
3410
[email protected]1001f5c2014-06-13 19:57:183411class DidDrawCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:423412 public:
danakj60bc3bc2016-04-09 00:24:483413 static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3414 return base::WrapUnique(new DidDrawCheckLayer(tree_impl, id));
[email protected]aa043632013-03-25 03:39:423415 }
[email protected]94f206c12012-08-25 00:09:143416
dcheng716bedf2014-10-21 09:51:083417 bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) override {
[email protected]ffbb2212013-06-02 23:47:593418 will_draw_called_ = true;
3419 if (will_draw_returns_false_)
3420 return false;
[email protected]1001f5c2014-06-13 19:57:183421 return LayerImpl::WillDraw(draw_mode, provider);
[email protected]ffbb2212013-06-02 23:47:593422 }
3423
dcheng716bedf2014-10-21 09:51:083424 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:083425 AppendQuadsData* append_quads_data) override {
[email protected]ffbb2212013-06-02 23:47:593426 append_quads_called_ = true;
danakja8c66a52015-02-14 01:53:223427 LayerImpl::AppendQuads(render_pass, append_quads_data);
[email protected]ffbb2212013-06-02 23:47:593428 }
3429
dcheng716bedf2014-10-21 09:51:083430 void DidDraw(ResourceProvider* provider) override {
[email protected]aa043632013-03-25 03:39:423431 did_draw_called_ = true;
[email protected]1001f5c2014-06-13 19:57:183432 LayerImpl::DidDraw(provider);
[email protected]aa043632013-03-25 03:39:423433 }
[email protected]94f206c12012-08-25 00:09:143434
[email protected]aa043632013-03-25 03:39:423435 bool will_draw_called() const { return will_draw_called_; }
[email protected]ffbb2212013-06-02 23:47:593436 bool append_quads_called() const { return append_quads_called_; }
3437 bool did_draw_called() const { return did_draw_called_; }
3438
3439 void set_will_draw_returns_false() { will_draw_returns_false_ = true; }
[email protected]94f206c12012-08-25 00:09:143440
[email protected]aa043632013-03-25 03:39:423441 void ClearDidDrawCheck() {
[email protected]aa043632013-03-25 03:39:423442 will_draw_called_ = false;
[email protected]ffbb2212013-06-02 23:47:593443 append_quads_called_ = false;
3444 did_draw_called_ = false;
[email protected]aa043632013-03-25 03:39:423445 }
[email protected]94f206c12012-08-25 00:09:143446
danakj60bc3bc2016-04-09 00:24:483447 static void IgnoreResult(std::unique_ptr<CopyOutputResult> result) {}
danakjec8b22b2015-03-11 02:20:343448
3449 void AddCopyRequest() {
ajumae6f541b2016-05-31 16:50:503450 test_properties()->copy_requests.push_back(
danakjec8b22b2015-03-11 02:20:343451 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreResult)));
danakjec8b22b2015-03-11 02:20:343452 }
3453
[email protected]aa043632013-03-25 03:39:423454 protected:
3455 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id)
[email protected]1001f5c2014-06-13 19:57:183456 : LayerImpl(tree_impl, id),
[email protected]ffbb2212013-06-02 23:47:593457 will_draw_returns_false_(false),
3458 will_draw_called_(false),
3459 append_quads_called_(false),
3460 did_draw_called_(false) {
[email protected]aa043632013-03-25 03:39:423461 SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423462 SetDrawsContent(true);
danakj64767d902015-06-19 00:10:433463 draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
[email protected]aa043632013-03-25 03:39:423464 }
[email protected]94f206c12012-08-25 00:09:143465
[email protected]aa043632013-03-25 03:39:423466 private:
[email protected]ffbb2212013-06-02 23:47:593467 bool will_draw_returns_false_;
[email protected]aa043632013-03-25 03:39:423468 bool will_draw_called_;
[email protected]ffbb2212013-06-02 23:47:593469 bool append_quads_called_;
3470 bool did_draw_called_;
[email protected]94f206c12012-08-25 00:09:143471};
3472
[email protected]ffbb2212013-06-02 23:47:593473TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
3474 // The root layer is always drawn, so run this test on a child layer that
3475 // will be masked out by the root layer's bounds.
jaydasikabf1875a2016-06-28 03:39:593476 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]ffbb2212013-06-02 23:47:593477 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483478 DidDrawCheckLayer* root =
3479 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]ffbb2212013-06-02 23:47:593480
jaydasika89f7b5a2016-06-22 02:08:393481 root->test_properties()->AddChild(
3482 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
jaydasika6b5a32bf2016-04-22 21:56:363483 root->test_properties()->force_render_surface = true;
[email protected]ffbb2212013-06-02 23:47:593484 DidDrawCheckLayer* layer =
jaydasikafc66cfb2016-06-10 04:34:223485 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
danakj74af409e2016-07-01 00:41:483486 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ffbb2212013-06-02 23:47:593487
3488 {
3489 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:483490 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453491 host_impl_->DrawLayers(&frame);
[email protected]ffbb2212013-06-02 23:47:593492 host_impl_->DidDrawAllLayers(frame);
3493
3494 EXPECT_TRUE(layer->will_draw_called());
3495 EXPECT_TRUE(layer->append_quads_called());
3496 EXPECT_TRUE(layer->did_draw_called());
3497 }
3498
[email protected]2aae96792014-05-15 23:10:503499 host_impl_->SetViewportDamage(gfx::Rect(10, 10));
3500
[email protected]ffbb2212013-06-02 23:47:593501 {
3502 LayerTreeHostImpl::FrameData frame;
3503
3504 layer->set_will_draw_returns_false();
3505 layer->ClearDidDrawCheck();
3506
danakj74af409e2016-07-01 00:41:483507 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453508 host_impl_->DrawLayers(&frame);
[email protected]ffbb2212013-06-02 23:47:593509 host_impl_->DidDrawAllLayers(frame);
3510
3511 EXPECT_TRUE(layer->will_draw_called());
3512 EXPECT_FALSE(layer->append_quads_called());
3513 EXPECT_FALSE(layer->did_draw_called());
3514 }
3515}
3516
[email protected]aa043632013-03-25 03:39:423517TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
3518 // The root layer is always drawn, so run this test on a child layer that
3519 // will be masked out by the root layer's bounds.
jaydasikabf1875a2016-06-28 03:39:593520 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423521 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483522 DidDrawCheckLayer* root =
3523 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]aa043632013-03-25 03:39:423524 root->SetMasksToBounds(true);
jaydasika6b5a32bf2016-04-22 21:56:363525 root->test_properties()->force_render_surface = true;
jaydasika89f7b5a2016-06-22 02:08:393526 root->test_properties()->AddChild(
3527 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
[email protected]aa043632013-03-25 03:39:423528 DidDrawCheckLayer* layer =
jaydasikafc66cfb2016-06-10 04:34:223529 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
danakj64767d902015-06-19 00:10:433530 // Ensure visible_layer_rect for layer is empty.
[email protected]aa043632013-03-25 03:39:423531 layer->SetPosition(gfx::PointF(100.f, 100.f));
3532 layer->SetBounds(gfx::Size(10, 10));
danakj74af409e2016-07-01 00:41:483533 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143534
[email protected]aa043632013-03-25 03:39:423535 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143536
[email protected]aa043632013-03-25 03:39:423537 EXPECT_FALSE(layer->will_draw_called());
3538 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143539
danakj74af409e2016-07-01 00:41:483540 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453541 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423542 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143543
[email protected]aa043632013-03-25 03:39:423544 EXPECT_FALSE(layer->will_draw_called());
3545 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143546
danakj64767d902015-06-19 00:10:433547 EXPECT_TRUE(layer->visible_layer_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:143548
danakj64767d902015-06-19 00:10:433549 // Ensure visible_layer_rect for layer is not empty
[email protected]aa043632013-03-25 03:39:423550 layer->SetPosition(gfx::PointF());
jaydasikaadfec8e2016-02-17 02:46:113551 layer->NoteLayerPropertyChanged();
danakj74af409e2016-07-01 00:41:483552 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143553
[email protected]aa043632013-03-25 03:39:423554 EXPECT_FALSE(layer->will_draw_called());
3555 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143556
danakj74af409e2016-07-01 00:41:483557 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453558 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423559 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143560
[email protected]aa043632013-03-25 03:39:423561 EXPECT_TRUE(layer->will_draw_called());
3562 EXPECT_TRUE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143563
danakj64767d902015-06-19 00:10:433564 EXPECT_FALSE(layer->visible_layer_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:143565}
3566
[email protected]aa043632013-03-25 03:39:423567TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
3568 gfx::Size big_size(1000, 1000);
[email protected]18ce59702013-04-09 04:58:403569 host_impl_->SetViewportSize(big_size);
[email protected]94f206c12012-08-25 00:09:143570
jaydasikabf1875a2016-06-28 03:39:593571 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423572 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483573 DidDrawCheckLayer* root =
3574 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]94f206c12012-08-25 00:09:143575
jaydasika89f7b5a2016-06-22 02:08:393576 root->test_properties()->AddChild(
3577 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
[email protected]aa043632013-03-25 03:39:423578 DidDrawCheckLayer* occluded_layer =
jaydasikafc66cfb2016-06-10 04:34:223579 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
[email protected]94f206c12012-08-25 00:09:143580
jaydasika89f7b5a2016-06-22 02:08:393581 root->test_properties()->AddChild(
3582 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
jaydasika6b5a32bf2016-04-22 21:56:363583 root->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:423584 DidDrawCheckLayer* top_layer =
jaydasikafc66cfb2016-06-10 04:34:223585 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[1]);
[email protected]aa043632013-03-25 03:39:423586 // This layer covers the occluded_layer above. Make this layer large so it can
3587 // occlude.
3588 top_layer->SetBounds(big_size);
[email protected]aa043632013-03-25 03:39:423589 top_layer->SetContentsOpaque(true);
danakj74af409e2016-07-01 00:41:483590 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143591
[email protected]aa043632013-03-25 03:39:423592 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143593
[email protected]aa043632013-03-25 03:39:423594 EXPECT_FALSE(occluded_layer->will_draw_called());
3595 EXPECT_FALSE(occluded_layer->did_draw_called());
3596 EXPECT_FALSE(top_layer->will_draw_called());
3597 EXPECT_FALSE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143598
danakj74af409e2016-07-01 00:41:483599 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453600 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423601 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143602
[email protected]aa043632013-03-25 03:39:423603 EXPECT_FALSE(occluded_layer->will_draw_called());
3604 EXPECT_FALSE(occluded_layer->did_draw_called());
3605 EXPECT_TRUE(top_layer->will_draw_called());
3606 EXPECT_TRUE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143607}
3608
[email protected]aa043632013-03-25 03:39:423609TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
jaydasikabf1875a2016-06-28 03:39:593610 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423611 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483612 DidDrawCheckLayer* root =
3613 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
[email protected]94f206c12012-08-25 00:09:143614
jaydasika89f7b5a2016-06-22 02:08:393615 root->test_properties()->AddChild(
3616 DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
jaydasika6b5a32bf2016-04-22 21:56:363617 root->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:423618 DidDrawCheckLayer* layer1 =
jaydasikafc66cfb2016-06-10 04:34:223619 static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]);
[email protected]94f206c12012-08-25 00:09:143620
jaydasika89f7b5a2016-06-22 02:08:393621 layer1->test_properties()->AddChild(
3622 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
[email protected]aa043632013-03-25 03:39:423623 DidDrawCheckLayer* layer2 =
jaydasikafc66cfb2016-06-10 04:34:223624 static_cast<DidDrawCheckLayer*>(layer1->test_properties()->children[0]);
[email protected]94f206c12012-08-25 00:09:143625
jaydasika6b5a32bf2016-04-22 21:56:363626 layer1->test_properties()->force_render_surface = true;
jaydasikaca2605e2016-04-23 02:52:523627 layer1->test_properties()->should_flatten_transform = true;
danakj74af409e2016-07-01 00:41:483628 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143629
[email protected]aa043632013-03-25 03:39:423630 EXPECT_FALSE(root->did_draw_called());
3631 EXPECT_FALSE(layer1->did_draw_called());
3632 EXPECT_FALSE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143633
[email protected]aa043632013-03-25 03:39:423634 LayerTreeHostImpl::FrameData frame;
[email protected]ad63b2f2014-08-11 17:39:543635 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
danakj74af409e2016-07-01 00:41:483636 *host_impl_->active_tree()->begin());
3637 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453638 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423639 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143640
[email protected]aa043632013-03-25 03:39:423641 EXPECT_TRUE(root->did_draw_called());
3642 EXPECT_TRUE(layer1->did_draw_called());
3643 EXPECT_TRUE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:143644
[email protected]aa043632013-03-25 03:39:423645 EXPECT_NE(root->render_surface(), layer1->render_surface());
thestigd5fcf982015-05-11 18:41:383646 EXPECT_TRUE(layer1->render_surface());
[email protected]94f206c12012-08-25 00:09:143647}
3648
3649class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
[email protected]aa043632013-03-25 03:39:423650 public:
danakj60bc3bc2016-04-09 00:24:483651 static std::unique_ptr<LayerImpl> Create(
loyso2b91c082016-01-06 00:38:383652 LayerTreeImpl* tree_impl,
3653 int id,
3654 bool tile_missing,
3655 bool had_incomplete_tile,
3656 bool animating,
3657 ResourceProvider* resource_provider,
3658 scoped_refptr<AnimationTimeline> timeline) {
danakj60bc3bc2016-04-09 00:24:483659 return base::WrapUnique(new MissingTextureAnimatingLayer(
loyso2b91c082016-01-06 00:38:383660 tree_impl, id, tile_missing, had_incomplete_tile, animating,
3661 resource_provider, timeline));
[email protected]aa043632013-03-25 03:39:423662 }
[email protected]94f206c12012-08-25 00:09:143663
dcheng716bedf2014-10-21 09:51:083664 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:083665 AppendQuadsData* append_quads_data) override {
danakja8c66a52015-02-14 01:53:223666 LayerImpl::AppendQuads(render_pass, append_quads_data);
[email protected]1001f5c2014-06-13 19:57:183667 if (had_incomplete_tile_)
[email protected]76ca89b2014-07-14 20:32:053668 append_quads_data->num_incomplete_tiles++;
[email protected]1001f5c2014-06-13 19:57:183669 if (tile_missing_)
3670 append_quads_data->num_missing_tiles++;
[email protected]3d609bb2014-02-01 01:10:233671 }
3672
[email protected]aa043632013-03-25 03:39:423673 private:
3674 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl,
3675 int id,
3676 bool tile_missing,
[email protected]1001f5c2014-06-13 19:57:183677 bool had_incomplete_tile,
[email protected]aa043632013-03-25 03:39:423678 bool animating,
loyso2b91c082016-01-06 00:38:383679 ResourceProvider* resource_provider,
3680 scoped_refptr<AnimationTimeline> timeline)
[email protected]1001f5c2014-06-13 19:57:183681 : DidDrawCheckLayer(tree_impl, id),
3682 tile_missing_(tile_missing),
3683 had_incomplete_tile_(had_incomplete_tile) {
vollickef2ae922016-06-29 17:54:273684 if (animating) {
3685 this->SetElementId(LayerIdToElementIdForTesting(id));
3686 AddAnimatedTransformToElementWithPlayer(this->element_id(), timeline,
3687 10.0, 3, 0);
3688 }
[email protected]aa043632013-03-25 03:39:423689 }
[email protected]3d609bb2014-02-01 01:10:233690
3691 bool tile_missing_;
[email protected]1001f5c2014-06-13 19:57:183692 bool had_incomplete_tile_;
[email protected]94f206c12012-08-25 00:09:143693};
3694
danakjec8b22b2015-03-11 02:20:343695struct PrepareToDrawSuccessTestCase {
3696 struct State {
3697 bool has_missing_tile = false;
3698 bool has_incomplete_tile = false;
3699 bool is_animating = false;
3700 bool has_copy_request = false;
3701 };
3702 bool high_res_required = false;
3703 State layer_before;
3704 State layer_between;
3705 State layer_after;
3706 DrawResult expected_result;
3707
3708 explicit PrepareToDrawSuccessTestCase(DrawResult result)
3709 : expected_result(result) {}
3710};
3711
sadrul0df063fc2016-07-27 17:36:513712static void CreateLayerFromState(
3713 DidDrawCheckLayer* root,
3714 const scoped_refptr<AnimationTimeline>& timeline,
3715 const PrepareToDrawSuccessTestCase::State& state) {
3716 static int layer_id = 2;
3717 root->test_properties()->AddChild(MissingTextureAnimatingLayer::Create(
3718 root->layer_tree_impl(), layer_id++, state.has_missing_tile,
3719 state.has_incomplete_tile, state.is_animating,
3720 root->layer_tree_impl()->resource_provider(), timeline));
3721 DidDrawCheckLayer* layer =
3722 static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
3723 if (state.has_copy_request)
3724 layer->AddCopyRequest();
3725}
3726
danakjec8b22b2015-03-11 02:20:343727TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) {
3728 std::vector<PrepareToDrawSuccessTestCase> cases;
3729
3730 // 0. Default case.
3731 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3732 // 1. Animated layer first.
3733 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3734 cases.back().layer_before.is_animating = true;
3735 // 2. Animated layer between.
3736 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3737 cases.back().layer_between.is_animating = true;
3738 // 3. Animated layer last.
3739 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3740 cases.back().layer_after.is_animating = true;
3741 // 4. Missing tile first.
3742 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3743 cases.back().layer_before.has_missing_tile = true;
3744 // 5. Missing tile between.
3745 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3746 cases.back().layer_between.has_missing_tile = true;
3747 // 6. Missing tile last.
3748 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3749 cases.back().layer_after.has_missing_tile = true;
3750 // 7. Incomplete tile first.
3751 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3752 cases.back().layer_before.has_incomplete_tile = true;
3753 // 8. Incomplete tile between.
3754 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3755 cases.back().layer_between.has_incomplete_tile = true;
3756 // 9. Incomplete tile last.
3757 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3758 cases.back().layer_after.has_incomplete_tile = true;
3759 // 10. Animation with missing tile.
3760 cases.push_back(
3761 PrepareToDrawSuccessTestCase(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS));
3762 cases.back().layer_between.has_missing_tile = true;
3763 cases.back().layer_between.is_animating = true;
weiliangc8dac5a62015-04-02 06:12:353764 // 11. Animation with incomplete tile.
danakjec8b22b2015-03-11 02:20:343765 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3766 cases.back().layer_between.has_incomplete_tile = true;
3767 cases.back().layer_between.is_animating = true;
3768
weiliangc8dac5a62015-04-02 06:12:353769 // 12. High res required.
danakjec8b22b2015-03-11 02:20:343770 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3771 cases.back().high_res_required = true;
weiliangc8dac5a62015-04-02 06:12:353772 // 13. High res required with incomplete tile.
danakjec8b22b2015-03-11 02:20:343773 cases.push_back(
3774 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3775 cases.back().high_res_required = true;
3776 cases.back().layer_between.has_incomplete_tile = true;
weiliangc8dac5a62015-04-02 06:12:353777 // 14. High res required with missing tile.
danakjec8b22b2015-03-11 02:20:343778 cases.push_back(
3779 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3780 cases.back().high_res_required = true;
3781 cases.back().layer_between.has_missing_tile = true;
3782
weiliangc8dac5a62015-04-02 06:12:353783 // 15. High res required is higher priority than animating missing tiles.
danakjec8b22b2015-03-11 02:20:343784 cases.push_back(
3785 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3786 cases.back().high_res_required = true;
3787 cases.back().layer_between.has_missing_tile = true;
3788 cases.back().layer_after.has_missing_tile = true;
3789 cases.back().layer_after.is_animating = true;
weiliangc8dac5a62015-04-02 06:12:353790 // 16. High res required is higher priority than animating missing tiles.
danakjec8b22b2015-03-11 02:20:343791 cases.push_back(
3792 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT));
3793 cases.back().high_res_required = true;
3794 cases.back().layer_between.has_missing_tile = true;
3795 cases.back().layer_before.has_missing_tile = true;
3796 cases.back().layer_before.is_animating = true;
3797
jaydasikabf1875a2016-06-28 03:39:593798 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]aa043632013-03-25 03:39:423799 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:483800 DidDrawCheckLayer* root =
3801 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
jaydasika6b5a32bf2016-04-22 21:56:363802 root->test_properties()->force_render_surface = true;
danakj74af409e2016-07-01 00:41:483803 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:143804
[email protected]aa043632013-03-25 03:39:423805 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:483806 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453807 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:423808 host_impl_->DidDrawAllLayers(frame);
danakjec8b22b2015-03-11 02:20:343809
3810 for (size_t i = 0; i < cases.size(); ++i) {
loyso2b91c082016-01-06 00:38:383811 // Clean up host_impl_ state.
danakjec8b22b2015-03-11 02:20:343812 const auto& testcase = cases[i];
3813 std::vector<LayerImpl*> to_remove;
vmpstra2e89432016-07-20 02:05:343814 for (auto* child : root->test_properties()->children)
vollick83fbfc82016-03-22 18:33:273815 to_remove.push_back(child);
danakjec8b22b2015-03-11 02:20:343816 for (auto* child : to_remove)
jaydasika89f7b5a2016-06-22 02:08:393817 root->test_properties()->RemoveChild(child);
loyso9556c732016-03-11 07:54:583818 timeline()->ClearPlayers();
danakjec8b22b2015-03-11 02:20:343819
3820 std::ostringstream scope;
3821 scope << "Test case: " << i;
3822 SCOPED_TRACE(scope.str());
3823
sadrul0df063fc2016-07-27 17:36:513824 CreateLayerFromState(root, timeline(), testcase.layer_before);
3825 CreateLayerFromState(root, timeline(), testcase.layer_between);
3826 CreateLayerFromState(root, timeline(), testcase.layer_after);
danakj74af409e2016-07-01 00:41:483827 host_impl_->active_tree()->BuildPropertyTreesForTesting();
danakjec8b22b2015-03-11 02:20:343828
3829 if (testcase.high_res_required)
3830 host_impl_->SetRequiresHighResToDraw();
3831
3832 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:483833 EXPECT_EQ(testcase.expected_result, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:453834 host_impl_->DrawLayers(&frame);
danakjec8b22b2015-03-11 02:20:343835 host_impl_->DidDrawAllLayers(frame);
danakjec8b22b2015-03-11 02:20:343836 }
[email protected]3d609bb2014-02-01 01:10:233837}
[email protected]94f206c12012-08-25 00:09:143838
danakjec8b22b2015-03-11 02:20:343839TEST_F(LayerTreeHostImplTest,
3840 PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame) {
3841 CreateHostImpl(DefaultSettings(),
danakj6021ec32016-07-22 22:16:083842 FakeOutputSurface::CreateDelegatingSoftware());
boliu8ca83902015-10-23 04:36:133843
3844 const gfx::Transform external_transform;
3845 const gfx::Rect external_viewport;
boliu8ca83902015-10-23 04:36:133846 const bool resourceless_software_draw = true;
boliu7097ee5b2015-12-17 03:16:093847 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
3848 external_transform);
danakjec8b22b2015-03-11 02:20:343849
3850 std::vector<PrepareToDrawSuccessTestCase> cases;
3851
3852 // 0. Default case.
3853 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3854 // 1. Animation with missing tile.
3855 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3856 cases.back().layer_between.has_missing_tile = true;
3857 cases.back().layer_between.is_animating = true;
3858 // 2. High res required with incomplete tile.
3859 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3860 cases.back().high_res_required = true;
3861 cases.back().layer_between.has_incomplete_tile = true;
3862 // 3. High res required with missing tile.
3863 cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS));
3864 cases.back().high_res_required = true;
3865 cases.back().layer_between.has_missing_tile = true;
3866
jaydasikabf1875a2016-06-28 03:39:593867 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]3d609bb2014-02-01 01:10:233868 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
jaydasikabf1875a2016-06-28 03:39:593869 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
3870 host_impl_->active_tree()->root_layer_for_testing());
jaydasika6b5a32bf2016-04-22 21:56:363871 root->test_properties()->force_render_surface = true;
danakj74af409e2016-07-01 00:41:483872 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]3d609bb2014-02-01 01:10:233873
boliu31c233ed2016-07-29 05:38:593874 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:093875 resourceless_software_draw);
sohan.jyoti9d1e4202014-09-23 21:02:333876
danakjec8b22b2015-03-11 02:20:343877 for (size_t i = 0; i < cases.size(); ++i) {
3878 const auto& testcase = cases[i];
3879 std::vector<LayerImpl*> to_remove;
vmpstra2e89432016-07-20 02:05:343880 for (auto* child : root->test_properties()->children)
vollick83fbfc82016-03-22 18:33:273881 to_remove.push_back(child);
danakjec8b22b2015-03-11 02:20:343882 for (auto* child : to_remove)
jaydasika89f7b5a2016-06-22 02:08:393883 root->test_properties()->RemoveChild(child);
[email protected]3d609bb2014-02-01 01:10:233884
danakjec8b22b2015-03-11 02:20:343885 std::ostringstream scope;
3886 scope << "Test case: " << i;
3887 SCOPED_TRACE(scope.str());
[email protected]1001f5c2014-06-13 19:57:183888
sadrul0df063fc2016-07-27 17:36:513889 CreateLayerFromState(root, timeline(), testcase.layer_before);
3890 CreateLayerFromState(root, timeline(), testcase.layer_between);
3891 CreateLayerFromState(root, timeline(), testcase.layer_after);
danakj74af409e2016-07-01 00:41:483892 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sohan.jyoti9d1e4202014-09-23 21:02:333893
danakjec8b22b2015-03-11 02:20:343894 if (testcase.high_res_required)
3895 host_impl_->SetRequiresHighResToDraw();
sohan.jyoti9d1e4202014-09-23 21:02:333896
boliu31c233ed2016-07-29 05:38:593897 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:093898 resourceless_software_draw);
danakjec8b22b2015-03-11 02:20:343899 }
[email protected]1001f5c2014-06-13 19:57:183900}
3901
[email protected]aa043632013-03-25 03:39:423902TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
danakj60bc3bc2016-04-09 00:24:483903 std::unique_ptr<LayerImpl> root =
3904 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]adeda572014-01-31 00:49:473905 root->SetScrollClipLayer(Layer::INVALID_ID);
jaydasika6b5a32bf2016-04-22 21:56:363906 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:593907 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:483908 host_impl_->active_tree()->BuildPropertyTreesForTesting();
3909
[email protected]ce2e8112013-11-28 07:44:363910 DrawFrame();
[email protected]94f206c12012-08-25 00:09:143911
[email protected]aa043632013-03-25 03:39:423912 // Scroll event is ignored because layer is not scrollable.
tdresser81e84c672016-01-18 23:21:223913 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
3914 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
3915 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:403916 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:223917 status.main_thread_scrolling_reasons);
[email protected]aa043632013-03-25 03:39:423918 EXPECT_FALSE(did_request_redraw_);
3919 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:143920}
3921
hush85432c82015-07-23 00:24:543922TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) {
3923 host_impl_->CreatePendingTree();
bokan0c33a092015-07-29 18:27:563924 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
hush85432c82015-07-23 00:24:543925 CreateScrollAndContentsLayers(host_impl_->pending_tree(),
3926 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:483927 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
hush85432c82015-07-23 00:24:543928 host_impl_->ActivateSyncTree();
3929
3930 host_impl_->CreatePendingTree();
3931 const gfx::ScrollOffset pending_scroll = gfx::ScrollOffset(-100, -100);
3932 LayerImpl* active_outer_layer =
3933 host_impl_->active_tree()->OuterViewportScrollLayer();
3934 LayerImpl* pending_outer_layer =
3935 host_impl_->pending_tree()->OuterViewportScrollLayer();
sunxdb7e79432016-03-09 21:13:423936 pending_outer_layer->layer_tree_impl()
3937 ->property_trees()
3938 ->scroll_tree.UpdateScrollOffsetBaseForTesting(pending_outer_layer->id(),
3939 pending_scroll);
hush85432c82015-07-23 00:24:543940
3941 host_impl_->ActivateSyncTree();
3942 // Scrolloffsets on the active tree will be clamped after activation.
3943 EXPECT_EQ(active_outer_layer->CurrentScrollOffset(), gfx::ScrollOffset(0, 0));
3944}
3945
[email protected]fef74fd2014-02-27 06:28:173946class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
3947 public:
3948 LayerTreeHostImplTopControlsTest()
3949 // Make the clip size the same as the layer (content) size so the layer is
3950 // non-scrollable.
3951 : layer_size_(10, 10),
dtrainorcb7779b82014-12-04 01:08:023952 clip_size_(layer_size_),
3953 top_controls_height_(50) {
dtrainorcb7779b82014-12-04 01:08:023954 viewport_size_ = gfx::Size(clip_size_.width(),
3955 clip_size_.height() + top_controls_height_);
3956 }
3957
3958 bool CreateHostImpl(const LayerTreeSettings& settings,
danakj60bc3bc2016-04-09 00:24:483959 std::unique_ptr<OutputSurface> output_surface) override {
danakja04855a2015-11-18 20:39:103960 bool init = LayerTreeHostImplTest::CreateHostImpl(
3961 settings, std::move(output_surface));
bokanaa5d1b032015-03-09 21:51:323962 if (init) {
dtrainorcb7779b82014-12-04 01:08:023963 host_impl_->active_tree()->set_top_controls_height(top_controls_height_);
aelias6004fe02015-02-07 21:43:013964 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f);
bokan0c33a092015-07-29 18:27:563965 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
dtrainorcb7779b82014-12-04 01:08:023966 }
3967 return init;
[email protected]fef74fd2014-02-27 06:28:173968 }
[email protected]c8415bf92013-02-17 18:57:273969
bokanef971462014-10-13 22:58:323970 void SetupTopControlsAndScrollLayerWithVirtualViewport(
3971 const gfx::Size& inner_viewport_size,
3972 const gfx::Size& outer_viewport_size,
3973 const gfx::Size& scroll_layer_size) {
weiliangc8f4ef0d2015-11-27 00:15:553974 settings_ = DefaultSettings();
bokanef971462014-10-13 22:58:323975 CreateHostImpl(settings_, CreateOutputSurface());
bokan7ad75ed2016-03-30 19:29:573976 SetupTopControlsAndScrollLayerWithVirtualViewport(
3977 host_impl_->active_tree(), inner_viewport_size, outer_viewport_size,
3978 scroll_layer_size);
3979 }
3980
3981 void SetupTopControlsAndScrollLayerWithVirtualViewport(
3982 LayerTreeImpl* tree_impl,
3983 const gfx::Size& inner_viewport_size,
3984 const gfx::Size& outer_viewport_size,
3985 const gfx::Size& scroll_layer_size) {
3986 tree_impl->set_top_controls_shrink_blink_size(true);
3987 tree_impl->set_top_controls_height(top_controls_height_);
3988 tree_impl->SetCurrentTopControlsShownRatio(1.f);
3989 tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
dtrainorcb7779b82014-12-04 01:08:023990 host_impl_->DidChangeTopControlsPosition();
bokanef971462014-10-13 22:58:323991
danakj60bc3bc2016-04-09 00:24:483992 std::unique_ptr<LayerImpl> root = LayerImpl::Create(tree_impl, 1);
3993 std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(tree_impl, 2);
3994 std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(tree_impl, 3);
bokanef971462014-10-13 22:58:323995
danakj60bc3bc2016-04-09 00:24:483996 std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(tree_impl, 4);
3997 std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5);
bokanef971462014-10-13 22:58:323998
3999 root_clip->SetBounds(inner_viewport_size);
4000 root->SetScrollClipLayer(root_clip->id());
4001 root->SetBounds(outer_viewport_size);
bokanef971462014-10-13 22:58:324002 root->SetPosition(gfx::PointF());
4003 root->SetDrawsContent(false);
jaydasika6b5a32bf2016-04-22 21:56:364004 root_clip->test_properties()->force_render_surface = true;
jaydasikaca2605e2016-04-23 02:52:524005 root->test_properties()->is_container_for_fixed_position_layers = true;
bokanef971462014-10-13 22:58:324006 outer_clip->SetBounds(outer_viewport_size);
4007 outer_scroll->SetScrollClipLayer(outer_clip->id());
4008 outer_scroll->SetBounds(scroll_layer_size);
bokanef971462014-10-13 22:58:324009 outer_scroll->SetPosition(gfx::PointF());
4010 outer_scroll->SetDrawsContent(false);
jaydasikaca2605e2016-04-23 02:52:524011 outer_scroll->test_properties()->is_container_for_fixed_position_layers =
4012 true;
bokanef971462014-10-13 22:58:324013
4014 int inner_viewport_scroll_layer_id = root->id();
4015 int outer_viewport_scroll_layer_id = outer_scroll->id();
4016 int page_scale_layer_id = page_scale->id();
4017
jaydasika89f7b5a2016-06-22 02:08:394018 outer_clip->test_properties()->AddChild(std::move(outer_scroll));
4019 root->test_properties()->AddChild(std::move(outer_clip));
4020 page_scale->test_properties()->AddChild(std::move(root));
4021 root_clip->test_properties()->AddChild(std::move(page_scale));
bokanef971462014-10-13 22:58:324022
jaydasikabf1875a2016-06-28 03:39:594023 tree_impl->SetRootLayerForTesting(std::move(root_clip));
bokan7ad75ed2016-03-30 19:29:574024 tree_impl->SetViewportLayersFromIds(Layer::INVALID_ID, page_scale_layer_id,
4025 inner_viewport_scroll_layer_id,
4026 outer_viewport_scroll_layer_id);
danakj74af409e2016-07-01 00:41:484027 tree_impl->BuildPropertyTreesForTesting();
bokanef971462014-10-13 22:58:324028
4029 host_impl_->SetViewportSize(inner_viewport_size);
jaydasikabf1875a2016-06-28 03:39:594030 LayerImpl* root_clip_ptr = tree_impl->root_layer_for_testing();
bokanef971462014-10-13 22:58:324031 EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds());
4032 }
4033
[email protected]fef74fd2014-02-27 06:28:174034 protected:
4035 gfx::Size layer_size_;
4036 gfx::Size clip_size_;
4037 gfx::Size viewport_size_;
dtrainorcb7779b82014-12-04 01:08:024038 float top_controls_height_;
[email protected]fef74fd2014-02-27 06:28:174039
4040 LayerTreeSettings settings_;
4041}; // class LayerTreeHostImplTopControlsTest
4042
bokan574c43632015-08-14 02:22:074043// Tests that, on a page with content the same size as the viewport, hiding
4044// the top controls also increases the ScrollableSize (i.e. the content size).
4045// Since the viewport got larger, the effective scrollable "content" also did.
4046// This ensures, for one thing, that the overscroll glow is shown in the right
4047// place.
4048TEST_F(LayerTreeHostImplTopControlsTest,
4049 HidingTopControlsExpandsScrollableSize) {
4050 SetupTopControlsAndScrollLayerWithVirtualViewport(
4051 gfx::Size(50, 50), gfx::Size(50, 50), gfx::Size(50, 50));
4052
4053 LayerTreeImpl* active_tree = host_impl_->active_tree();
4054
4055 // Create a content layer beneath the outer viewport scroll layer.
4056 int id = host_impl_->OuterViewportScrollLayer()->id();
jaydasika89f7b5a2016-06-22 02:08:394057 host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild(
bokan574c43632015-08-14 02:22:074058 LayerImpl::Create(host_impl_->active_tree(), id + 2));
jaydasikafc66cfb2016-06-10 04:34:224059 LayerImpl* content =
4060 active_tree->OuterViewportScrollLayer()->test_properties()->children[0];
bokan574c43632015-08-14 02:22:074061 content->SetBounds(gfx::Size(50, 50));
danakj74af409e2016-07-01 00:41:484062 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokan574c43632015-08-14 02:22:074063
4064 DrawFrame();
4065
4066 LayerImpl* inner_container = active_tree->InnerViewportContainerLayer();
4067 LayerImpl* outer_container = active_tree->OuterViewportContainerLayer();
4068
4069 // The top controls should start off showing so the viewport should be shrunk.
4070 ASSERT_EQ(gfx::Size(50, 50), inner_container->bounds());
4071 ASSERT_EQ(gfx::Size(50, 50), outer_container->bounds());
4072
4073 EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize());
4074
tdresser81e84c672016-01-18 23:21:224075 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034076 host_impl_
4077 ->ScrollBegin(BeginState(gfx::Point()).get(),
4078 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224079 .thread);
bokan574c43632015-08-14 02:22:074080
4081 host_impl_->top_controls_manager()->ScrollBegin();
4082
4083 // Hide the top controls by a bit, the scrollable size should increase but the
4084 // actual content bounds shouldn't.
4085 {
4086 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
4087 ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds());
4088 ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds());
4089 EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize());
4090 EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling());
4091 }
4092
4093 // Fully hide the top controls.
4094 {
4095 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
4096 ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds());
4097 ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds());
4098 EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
4099 EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling());
4100 }
4101
4102 // Scrolling additionally shouldn't have any effect.
4103 {
4104 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
4105 ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds());
4106 ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds());
4107 EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
4108 EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling());
4109 }
4110
4111 host_impl_->top_controls_manager()->ScrollEnd();
majidvp944a8cd2016-01-12 21:05:184112 host_impl_->ScrollEnd(EndState().get());
bokan574c43632015-08-14 02:22:074113}
4114
[email protected]fef74fd2014-02-27 06:28:174115TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) {
bokan8273d962014-10-22 02:40:274116 SetupTopControlsAndScrollLayerWithVirtualViewport(
4117 gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
[email protected]fef74fd2014-02-27 06:28:174118 DrawFrame();
4119
tdresser81e84c672016-01-18 23:21:224120 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034121 host_impl_
4122 ->ScrollBegin(BeginState(gfx::Point()).get(),
4123 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224124 .thread);
[email protected]fef74fd2014-02-27 06:28:174125
4126 // Make the test scroll delta a fractional amount, to verify that the
4127 // fixed container size delta is (1) non-zero, and (2) fractional, and
4128 // (3) matches the movement of the top controls.
4129 gfx::Vector2dF top_controls_scroll_delta(0.f, 5.25f);
4130 host_impl_->top_controls_manager()->ScrollBegin();
4131 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4132 host_impl_->top_controls_manager()->ScrollEnd();
4133
4134 LayerImpl* inner_viewport_scroll_layer =
4135 host_impl_->active_tree()->InnerViewportScrollLayer();
4136 DCHECK(inner_viewport_scroll_layer);
majidvp944a8cd2016-01-12 21:05:184137 host_impl_->ScrollEnd(EndState().get());
aelias6004fe02015-02-07 21:43:014138 EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(),
4139 inner_viewport_scroll_layer->FixedContainerSizeDelta().y());
[email protected]fef74fd2014-02-27 06:28:174140}
4141
bokana203a4b12014-11-18 16:28:084142// In this test, the outer viewport is initially unscrollable. We test that a
4143// scroll initiated on the inner viewport, causing the top controls to show and
4144// thus making the outer viewport scrollable, still scrolls the outer viewport.
4145TEST_F(LayerTreeHostImplTopControlsTest,
4146 TopControlsOuterViewportBecomesScrollable) {
4147 SetupTopControlsAndScrollLayerWithVirtualViewport(
4148 gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
4149 DrawFrame();
4150
thestigd5fcf982015-05-11 18:41:384151 LayerImpl* inner_scroll =
bokana203a4b12014-11-18 16:28:084152 host_impl_->active_tree()->InnerViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:124153 inner_scroll->SetDrawsContent(true);
thestigd5fcf982015-05-11 18:41:384154 LayerImpl* inner_container =
bokana203a4b12014-11-18 16:28:084155 host_impl_->active_tree()->InnerViewportContainerLayer();
thestigd5fcf982015-05-11 18:41:384156 LayerImpl* outer_scroll =
bokana203a4b12014-11-18 16:28:084157 host_impl_->active_tree()->OuterViewportScrollLayer();
jaydasikad7dea632015-11-06 04:40:124158 outer_scroll->SetDrawsContent(true);
thestigd5fcf982015-05-11 18:41:384159 LayerImpl* outer_container =
bokana203a4b12014-11-18 16:28:084160 host_impl_->active_tree()->OuterViewportContainerLayer();
4161
4162 // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
4163 outer_scroll->SetDrawsContent(true);
aelias58eec0812014-12-04 01:04:404164 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
bokana203a4b12014-11-18 16:28:084165
tdresser81e84c672016-01-18 23:21:224166 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034167 host_impl_
4168 ->ScrollBegin(BeginState(gfx::Point()).get(),
4169 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224170 .thread);
majidvp944a8cd2016-01-12 21:05:184171 host_impl_->ScrollBy(
4172 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 50.f)).get());
bokana203a4b12014-11-18 16:28:084173
4174 // The entire scroll delta should have been used to hide the top controls.
4175 // The viewport layers should be resized back to their full sizes.
aelias6004fe02015-02-07 21:43:014176 EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
aeliasf998da82015-02-03 01:40:514177 EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084178 EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height());
4179 EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height());
4180
4181 // The inner viewport should be scrollable by 50px * page_scale.
majidvp944a8cd2016-01-12 21:05:184182 host_impl_->ScrollBy(
4183 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 100.f)).get());
aeliasf998da82015-02-03 01:40:514184 EXPECT_EQ(50.f, inner_scroll->CurrentScrollOffset().y());
4185 EXPECT_EQ(0.f, outer_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084186 EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset());
4187
majidvp944a8cd2016-01-12 21:05:184188 host_impl_->ScrollEnd(EndState().get());
bokana203a4b12014-11-18 16:28:084189
tdresser81e84c672016-01-18 23:21:224190 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034191 host_impl_
4192 ->ScrollBegin(BeginState(gfx::Point()).get(),
4193 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224194 .thread);
bokana203a4b12014-11-18 16:28:084195 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
4196
majidvp944a8cd2016-01-12 21:05:184197 host_impl_->ScrollBy(
4198 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get());
bokana203a4b12014-11-18 16:28:084199
4200 // The entire scroll delta should have been used to show the top controls.
4201 // The outer viewport should be resized to accomodate and scrolled to the
4202 // bottom of the document to keep the viewport in place.
aelias6004fe02015-02-07 21:43:014203 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
bokana203a4b12014-11-18 16:28:084204 EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height());
4205 EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height());
aeliasf998da82015-02-03 01:40:514206 EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
4207 EXPECT_EQ(25.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084208
4209 // Now when we continue scrolling, make sure the outer viewport gets scrolled
4210 // since it wasn't scrollable when the scroll began.
majidvp944a8cd2016-01-12 21:05:184211 host_impl_->ScrollBy(
4212 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -20.f)).get());
bokan1f01388f2015-09-15 20:55:544213 EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
4214 EXPECT_EQ(15.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084215
majidvp944a8cd2016-01-12 21:05:184216 host_impl_->ScrollBy(
4217 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -30.f)).get());
bokan1f01388f2015-09-15 20:55:544218 EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
4219 EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084220
majidvp944a8cd2016-01-12 21:05:184221 host_impl_->ScrollBy(
4222 UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get());
4223 host_impl_->ScrollEnd(EndState().get());
bokana203a4b12014-11-18 16:28:084224
aeliasf998da82015-02-03 01:40:514225 EXPECT_EQ(0.f, outer_scroll->CurrentScrollOffset().y());
4226 EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
bokana203a4b12014-11-18 16:28:084227}
4228
bokan8273d962014-10-22 02:40:274229// Test that the fixed position container delta is appropriately adjusted
4230// by the top controls showing/hiding and page scale doesn't affect it.
4231TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
4232 SetupTopControlsAndScrollLayerWithVirtualViewport(
4233 gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
[email protected]fef74fd2014-02-27 06:28:174234 DrawFrame();
bokan0c33a092015-07-29 18:27:564235 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
[email protected]fef74fd2014-02-27 06:28:174236
bokan8273d962014-10-22 02:40:274237 float page_scale = 1.5f;
bokan8273d962014-10-22 02:40:274238 LayerImpl* outer_viewport_scroll_layer =
4239 host_impl_->active_tree()->OuterViewportScrollLayer();
4240
4241 // Zoom in, since the fixed container is the outer viewport, the delta should
4242 // not be scaled.
aelias58eec0812014-12-04 01:04:404243 host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
bokan8273d962014-10-22 02:40:274244
tdresser81e84c672016-01-18 23:21:224245 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034246 host_impl_
4247 ->ScrollBegin(BeginState(gfx::Point()).get(),
4248 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224249 .thread);
[email protected]fef74fd2014-02-27 06:28:174250
bokan8273d962014-10-22 02:40:274251 // Scroll down, the top controls hiding should expand the viewport size so
4252 // the delta should be equal to the scroll distance.
4253 gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f);
[email protected]fef74fd2014-02-27 06:28:174254 host_impl_->top_controls_manager()->ScrollBegin();
4255 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
aelias6004fe02015-02-07 21:43:014256 EXPECT_FLOAT_EQ(top_controls_height_ - top_controls_scroll_delta.y(),
4257 host_impl_->top_controls_manager()->ContentTopOffset());
bokan0c33a092015-07-29 18:27:564258 EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(),
4259 outer_viewport_scroll_layer->FixedContainerSizeDelta().y());
majidvp944a8cd2016-01-12 21:05:184260 host_impl_->ScrollEnd(EndState().get());
[email protected]fef74fd2014-02-27 06:28:174261
bokan8273d962014-10-22 02:40:274262 // Scroll past the maximum extent. The delta shouldn't be greater than the
4263 // top controls height.
4264 host_impl_->top_controls_manager()->ScrollBegin();
4265 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4266 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4267 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
4268 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
dtrainorcb7779b82014-12-04 01:08:024269 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_),
bokan8273d962014-10-22 02:40:274270 outer_viewport_scroll_layer->FixedContainerSizeDelta());
majidvp944a8cd2016-01-12 21:05:184271 host_impl_->ScrollEnd(EndState().get());
bokan8273d962014-10-22 02:40:274272
4273 // Scroll in the direction to make the top controls show.
4274 host_impl_->top_controls_manager()->ScrollBegin();
4275 host_impl_->top_controls_manager()->ScrollBy(-top_controls_scroll_delta);
4276 EXPECT_EQ(top_controls_scroll_delta.y(),
4277 host_impl_->top_controls_manager()->ContentTopOffset());
4278 EXPECT_VECTOR_EQ(
dtrainorcb7779b82014-12-04 01:08:024279 gfx::Vector2dF(0, top_controls_height_ - top_controls_scroll_delta.y()),
bokan8273d962014-10-22 02:40:274280 outer_viewport_scroll_layer->FixedContainerSizeDelta());
4281 host_impl_->top_controls_manager()->ScrollEnd();
[email protected]fef74fd2014-02-27 06:28:174282}
4283
bokan0223f2f722016-06-23 12:35:014284// Push a top controls ratio from the main thread that we didn't send as a delta
4285// and make sure that the ratio is clamped to the [0, 1] range.
4286TEST_F(LayerTreeHostImplTopControlsTest, TopControlsPushUnsentRatio) {
4287 SetupTopControlsAndScrollLayerWithVirtualViewport(
4288 gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
4289 DrawFrame();
4290
4291 // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
4292 LayerImpl* inner_scroll =
4293 host_impl_->active_tree()->InnerViewportScrollLayer();
4294 inner_scroll->SetDrawsContent(true);
4295 LayerImpl* outer_scroll =
4296 host_impl_->active_tree()->OuterViewportScrollLayer();
4297 outer_scroll->SetDrawsContent(true);
4298
4299 host_impl_->active_tree()->PushTopControlsFromMainThread(1);
4300 ASSERT_EQ(1.0f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4301
4302 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.5f);
4303 ASSERT_EQ(0.5f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4304
4305 host_impl_->active_tree()->PushTopControlsFromMainThread(0);
4306
4307 ASSERT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4308}
4309
tdressera4bec5df2015-07-14 13:23:344310// Test that if only the top controls are scrolled, we shouldn't request a
4311// commit.
4312TEST_F(LayerTreeHostImplTopControlsTest, TopControlsDontTriggerCommit) {
4313 SetupTopControlsAndScrollLayerWithVirtualViewport(
4314 gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100));
4315 DrawFrame();
4316
4317 // Show top controls
4318 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
4319
4320 // Scroll 25px to hide top controls
4321 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224322 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034323 host_impl_
4324 ->ScrollBegin(BeginState(gfx::Point()).get(),
4325 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224326 .thread);
majidvp944a8cd2016-01-12 21:05:184327 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdressera4bec5df2015-07-14 13:23:344328 EXPECT_FALSE(did_request_commit_);
4329}
4330
elisabets01d84d32014-12-15 12:50:054331// Test that if a scrollable sublayer doesn't consume the scroll,
4332// top controls should hide when scrolling down.
4333TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) {
4334 gfx::Size sub_content_size(100, 400);
4335 gfx::Size sub_content_layer_size(100, 300);
4336 SetupTopControlsAndScrollLayerWithVirtualViewport(
4337 gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100));
4338 DrawFrame();
4339
4340 // Show top controls
aelias6004fe02015-02-07 21:43:014341 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
elisabets01d84d32014-12-15 12:50:054342
4343 LayerImpl* outer_viewport_scroll_layer =
4344 host_impl_->active_tree()->OuterViewportScrollLayer();
4345 int id = outer_viewport_scroll_layer->id();
4346
danakj60bc3bc2016-04-09 00:24:484347 std::unique_ptr<LayerImpl> child =
elisabets01d84d32014-12-15 12:50:054348 LayerImpl::Create(host_impl_->active_tree(), id + 2);
danakj60bc3bc2016-04-09 00:24:484349 std::unique_ptr<LayerImpl> child_clip =
elisabets01d84d32014-12-15 12:50:054350 LayerImpl::Create(host_impl_->active_tree(), id + 3);
4351
4352 child_clip->SetBounds(sub_content_layer_size);
4353 child->SetScrollClipLayer(child_clip->id());
4354 child->SetBounds(sub_content_size);
elisabets01d84d32014-12-15 12:50:054355 child->SetPosition(gfx::PointF());
4356 child->SetDrawsContent(true);
jaydasikaca2605e2016-04-23 02:52:524357 child->test_properties()->is_container_for_fixed_position_layers = true;
elisabets01d84d32014-12-15 12:50:054358
4359 // scroll child to limit
sunxdb7e79432016-03-09 21:13:424360 SetScrollOffsetDelta(child.get(), gfx::Vector2dF(0, 100.f));
jaydasika89f7b5a2016-06-22 02:08:394361 child_clip->test_properties()->AddChild(std::move(child));
4362 outer_viewport_scroll_layer->test_properties()->AddChild(
4363 std::move(child_clip));
danakj74af409e2016-07-01 00:41:484364 host_impl_->active_tree()->BuildPropertyTreesForTesting();
elisabets01d84d32014-12-15 12:50:054365
4366 // Scroll 25px to hide top controls
4367 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224368 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034369 host_impl_
4370 ->ScrollBegin(BeginState(gfx::Point()).get(),
4371 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224372 .thread);
majidvp944a8cd2016-01-12 21:05:184373 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
4374 host_impl_->ScrollEnd(EndState().get());
elisabets01d84d32014-12-15 12:50:054375
4376 // Top controls should be hidden
4377 EXPECT_EQ(scroll_delta.y(),
4378 top_controls_height_ -
aelias6004fe02015-02-07 21:43:014379 host_impl_->top_controls_manager()->ContentTopOffset());
elisabets01d84d32014-12-15 12:50:054380}
4381
bokan88eae012014-09-09 20:40:424382// Ensure setting the top controls position explicitly using the setters on the
4383// TreeImpl correctly affects the top controls manager and viewport bounds.
4384TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) {
weiliangc8f4ef0d2015-11-27 00:15:554385 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024386 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054387 SetupTopControlsAndScrollLayerWithVirtualViewport(
4388 layer_size_, layer_size_, layer_size_);
bokan88eae012014-09-09 20:40:424389 DrawFrame();
4390
aelias6004fe02015-02-07 21:43:014391 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
4392 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4393 30.f / top_controls_height_);
4394 host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
4395 EXPECT_FLOAT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset());
4396 EXPECT_FLOAT_EQ(-20.f,
4397 host_impl_->top_controls_manager()->ControlsTopOffset());
bokan88eae012014-09-09 20:40:424398
aelias6004fe02015-02-07 21:43:014399 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
4400 EXPECT_FLOAT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4401 EXPECT_FLOAT_EQ(-50.f,
4402 host_impl_->top_controls_manager()->ControlsTopOffset());
bokan88eae012014-09-09 20:40:424403
4404 host_impl_->DidChangeTopControlsPosition();
4405
4406 // Now that top controls have moved, expect the clip to resize.
jaydasikaf419bf72016-06-15 10:21:214407 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4408 ->test_properties()
4409 ->parent->test_properties()
4410 ->parent;
bokanf553cb3b2015-07-23 18:54:054411 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424412}
4413
4414// Test that the top_controls delta and sent delta are appropriately
4415// applied on sync tree activation. The total top controls offset shouldn't
4416// change after the activation.
4417TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) {
weiliangc8f4ef0d2015-11-27 00:15:554418 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024419 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054420 SetupTopControlsAndScrollLayerWithVirtualViewport(
4421 layer_size_, layer_size_, layer_size_);
bokan88eae012014-09-09 20:40:424422 DrawFrame();
4423
aelias6004fe02015-02-07 21:43:014424 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4425 20.f / top_controls_height_);
4426 host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
4427 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(
4428 15.f / top_controls_height_);
4429 host_impl_->active_tree()
4430 ->top_controls_shown_ratio()
4431 ->PullDeltaForMainThread();
4432 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
4433 host_impl_->sync_tree()->PushTopControlsFromMainThread(15.f /
4434 top_controls_height_);
bokan88eae012014-09-09 20:40:424435
4436 host_impl_->DidChangeTopControlsPosition();
jaydasikaf419bf72016-06-15 10:21:214437 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4438 ->test_properties()
4439 ->parent->test_properties()
4440 ->parent;
bokanf553cb3b2015-07-23 18:54:054441 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424442 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4443
4444 host_impl_->ActivateSyncTree();
4445
jaydasikaf419bf72016-06-15 10:21:214446 inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4447 ->test_properties()
4448 ->parent->test_properties()
4449 ->parent;
bokan88eae012014-09-09 20:40:424450 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
bokanf553cb3b2015-07-23 18:54:054451 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424452
aelias6004fe02015-02-07 21:43:014453 EXPECT_FLOAT_EQ(
4454 -15.f, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() *
4455 top_controls_height_);
4456 EXPECT_FLOAT_EQ(
4457 15.f,
4458 host_impl_->active_tree()->top_controls_shown_ratio()->ActiveBase() *
4459 top_controls_height_);
bokan88eae012014-09-09 20:40:424460}
4461
4462// Test that changing the top controls layout height is correctly applied to
4463// the inner viewport container bounds. That is, the top controls layout
4464// height is the amount that the inner viewport container was shrunk outside
4465// the compositor to accommodate the top controls.
4466TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) {
weiliangc8f4ef0d2015-11-27 00:15:554467 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024468 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054469 SetupTopControlsAndScrollLayerWithVirtualViewport(
4470 layer_size_, layer_size_, layer_size_);
bokan88eae012014-09-09 20:40:424471 DrawFrame();
4472
aelias6004fe02015-02-07 21:43:014473 host_impl_->sync_tree()->PushTopControlsFromMainThread(1.f);
dtrainorcb7779b82014-12-04 01:08:024474 host_impl_->sync_tree()->set_top_controls_shrink_blink_size(true);
bokan88eae012014-09-09 20:40:424475
aelias6004fe02015-02-07 21:43:014476 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4477 1.f);
4478 host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
4479 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f);
bokan88eae012014-09-09 20:40:424480
4481 host_impl_->DidChangeTopControlsPosition();
jaydasikaf419bf72016-06-15 10:21:214482 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4483 ->test_properties()
4484 ->parent->test_properties()
4485 ->parent;
bokanf553cb3b2015-07-23 18:54:054486 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424487 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4488
jaydasikabf1875a2016-06-28 03:39:594489 host_impl_->sync_tree()->root_layer_for_testing()->SetBounds(
bokanf553cb3b2015-07-23 18:54:054490 gfx::Size(inner_clip_ptr->bounds().width(),
4491 inner_clip_ptr->bounds().height() - 50.f));
bokan88eae012014-09-09 20:40:424492
4493 host_impl_->ActivateSyncTree();
4494
jaydasikaf419bf72016-06-15 10:21:214495 inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4496 ->test_properties()
4497 ->parent->test_properties()
4498 ->parent;
bokan88eae012014-09-09 20:40:424499 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
4500
4501 // The total bounds should remain unchanged since the bounds delta should
4502 // account for the difference between the layout height and the current
4503 // top controls offset.
bokanf553cb3b2015-07-23 18:54:054504 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
4505 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), inner_clip_ptr->bounds_delta());
bokan88eae012014-09-09 20:40:424506
aelias6004fe02015-02-07 21:43:014507 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f);
bokan88eae012014-09-09 20:40:424508 host_impl_->DidChangeTopControlsPosition();
4509
aelias6004fe02015-02-07 21:43:014510 EXPECT_EQ(1.f, host_impl_->top_controls_manager()->TopControlsShownRatio());
4511 EXPECT_EQ(50.f, host_impl_->top_controls_manager()->TopControlsHeight());
dtrainorcb7779b82014-12-04 01:08:024512 EXPECT_EQ(50.f, host_impl_->top_controls_manager()->ContentTopOffset());
bokanf553cb3b2015-07-23 18:54:054513 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), inner_clip_ptr->bounds_delta());
dtrainorcb7779b82014-12-04 01:08:024514 EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f),
bokanf553cb3b2015-07-23 18:54:054515 inner_clip_ptr->bounds());
bokan88eae012014-09-09 20:40:424516}
4517
bokanef971462014-10-13 22:58:324518// Test that showing/hiding the top controls when the viewport is fully scrolled
4519// doesn't incorrectly change the viewport offset due to clamping from changing
4520// viewport bounds.
4521TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) {
4522 SetupTopControlsAndScrollLayerWithVirtualViewport(
4523 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
4524 DrawFrame();
4525
aelias6004fe02015-02-07 21:43:014526 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
bokanef971462014-10-13 22:58:324527
4528 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
4529 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
4530
4531 // Scroll the viewports to max scroll offset.
sunxdb7e79432016-03-09 21:13:424532 SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f));
4533 SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100.f));
bokanef971462014-10-13 22:58:324534
4535 gfx::ScrollOffset viewport_offset =
4536 host_impl_->active_tree()->TotalScrollOffset();
4537 EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset);
4538
4539 // Hide the top controls by 25px.
4540 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224541 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034542 host_impl_
4543 ->ScrollBegin(BeginState(gfx::Point()).get(),
4544 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224545 .thread);
majidvp944a8cd2016-01-12 21:05:184546 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
sujiths.s344435e2014-11-08 03:04:034547
4548 // scrolling down at the max extents no longer hides the top controls
aelias6004fe02015-02-07 21:43:014549 EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
sujiths.s344435e2014-11-08 03:04:034550
4551 // forcefully hide the top controls by 25px
4552 host_impl_->top_controls_manager()->ScrollBy(scroll_delta);
majidvp944a8cd2016-01-12 21:05:184553 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324554
aelias6004fe02015-02-07 21:43:014555 EXPECT_FLOAT_EQ(scroll_delta.y(),
4556 top_controls_height_ -
4557 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324558
4559 inner_scroll->ClampScrollToMaxScrollOffset();
4560 outer_scroll->ClampScrollToMaxScrollOffset();
4561
4562 // We should still be fully scrolled.
4563 EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
4564 host_impl_->active_tree()->TotalScrollOffset());
4565
4566 viewport_offset = host_impl_->active_tree()->TotalScrollOffset();
4567
4568 // Bring the top controls down by 25px.
4569 scroll_delta = gfx::Vector2dF(0.f, -25.f);
tdresser81e84c672016-01-18 23:21:224570 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034571 host_impl_
4572 ->ScrollBegin(BeginState(gfx::Point()).get(),
4573 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224574 .thread);
majidvp944a8cd2016-01-12 21:05:184575 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
4576 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324577
4578 // The viewport offset shouldn't have changed.
4579 EXPECT_EQ(viewport_offset,
4580 host_impl_->active_tree()->TotalScrollOffset());
4581
4582 // Scroll the viewports to max scroll offset.
sunxdb7e79432016-03-09 21:13:424583 SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f));
4584 SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100.f));
bokanef971462014-10-13 22:58:324585 EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
4586 host_impl_->active_tree()->TotalScrollOffset());
4587}
4588
4589// Test that the top controls coming in and out maintains the same aspect ratio
4590// between the inner and outer viewports.
4591TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) {
4592 SetupTopControlsAndScrollLayerWithVirtualViewport(
4593 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
bokan0c33a092015-07-29 18:27:564594 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 2.f);
bokanef971462014-10-13 22:58:324595 DrawFrame();
4596
aelias6004fe02015-02-07 21:43:014597 EXPECT_FLOAT_EQ(top_controls_height_,
4598 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324599
4600 gfx::Vector2dF scroll_delta(0.f, 25.f);
tdresser81e84c672016-01-18 23:21:224601 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034602 host_impl_
4603 ->ScrollBegin(BeginState(gfx::Point()).get(),
4604 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224605 .thread);
majidvp944a8cd2016-01-12 21:05:184606 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
4607 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324608
aelias6004fe02015-02-07 21:43:014609 EXPECT_FLOAT_EQ(scroll_delta.y(),
4610 top_controls_height_ -
4611 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324612
4613 // Top controls were hidden by 25px so the inner viewport should have expanded
4614 // by that much.
4615 LayerImpl* outer_container =
4616 host_impl_->active_tree()->OuterViewportContainerLayer();
4617 LayerImpl* inner_container =
4618 host_impl_->active_tree()->InnerViewportContainerLayer();
danakjddaec912015-09-25 19:38:404619 EXPECT_EQ(gfx::SizeF(100.f, 100.f + 25.f),
4620 inner_container->BoundsForScrolling());
bokanef971462014-10-13 22:58:324621
4622 // Outer viewport should match inner's aspect ratio. The bounds are ceiled.
4623 float aspect_ratio = inner_container->BoundsForScrolling().width() /
4624 inner_container->BoundsForScrolling().height();
danakjddaec912015-09-25 19:38:404625 gfx::SizeF expected =
4626 gfx::SizeF(gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio)));
bokanef971462014-10-13 22:58:324627 EXPECT_EQ(expected, outer_container->BoundsForScrolling());
4628 EXPECT_EQ(expected,
4629 host_impl_->InnerViewportScrollLayer()->BoundsForScrolling());
4630}
4631
4632// Test that scrolling the outer viewport affects the top controls.
4633TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) {
4634 SetupTopControlsAndScrollLayerWithVirtualViewport(
4635 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
4636 DrawFrame();
4637
dtrainorcb7779b82014-12-04 01:08:024638 EXPECT_EQ(top_controls_height_,
aelias6004fe02015-02-07 21:43:014639 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324640
4641 // Send a gesture scroll that will scroll the outer viewport, make sure the
4642 // top controls get scrolled.
4643 gfx::Vector2dF scroll_delta(0.f, 15.f);
tdresser81e84c672016-01-18 23:21:224644 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034645 host_impl_
4646 ->ScrollBegin(BeginState(gfx::Point()).get(),
4647 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224648 .thread);
majidvp944a8cd2016-01-12 21:05:184649 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdressera3b162b82015-09-29 17:51:434650
tdressera3f3a942015-09-28 21:15:394651 EXPECT_EQ(host_impl_->InnerViewportScrollLayer(),
bokanef971462014-10-13 22:58:324652 host_impl_->CurrentlyScrollingLayer());
majidvp944a8cd2016-01-12 21:05:184653 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324654
aelias6004fe02015-02-07 21:43:014655 EXPECT_FLOAT_EQ(scroll_delta.y(),
4656 top_controls_height_ -
4657 host_impl_->top_controls_manager()->ContentTopOffset());
bokanef971462014-10-13 22:58:324658
4659 scroll_delta = gfx::Vector2dF(0.f, 50.f);
tdresser81e84c672016-01-18 23:21:224660 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034661 host_impl_
4662 ->ScrollBegin(BeginState(gfx::Point()).get(),
4663 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224664 .thread);
majidvp944a8cd2016-01-12 21:05:184665 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokanef971462014-10-13 22:58:324666
aelias6004fe02015-02-07 21:43:014667 EXPECT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset());
tdressera3f3a942015-09-28 21:15:394668 EXPECT_EQ(host_impl_->InnerViewportScrollLayer(),
bokanef971462014-10-13 22:58:324669 host_impl_->CurrentlyScrollingLayer());
4670
majidvp944a8cd2016-01-12 21:05:184671 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324672
4673 // Position the viewports such that the inner viewport will be scrolled.
4674 gfx::Vector2dF inner_viewport_offset(0.f, 25.f);
sunxdb7e79432016-03-09 21:13:424675 SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(),
4676 gfx::Vector2dF());
4677 SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(),
4678 inner_viewport_offset);
bokanef971462014-10-13 22:58:324679
4680 scroll_delta = gfx::Vector2dF(0.f, -65.f);
tdresser81e84c672016-01-18 23:21:224681 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034682 host_impl_
4683 ->ScrollBegin(BeginState(gfx::Point()).get(),
4684 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224685 .thread);
majidvp944a8cd2016-01-12 21:05:184686 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokanef971462014-10-13 22:58:324687
dtrainorcb7779b82014-12-04 01:08:024688 EXPECT_EQ(top_controls_height_,
aelias6004fe02015-02-07 21:43:014689 host_impl_->top_controls_manager()->ContentTopOffset());
4690 EXPECT_FLOAT_EQ(
dtrainorcb7779b82014-12-04 01:08:024691 inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_),
sunxdb7e79432016-03-09 21:13:424692 ScrollDelta(host_impl_->InnerViewportScrollLayer()).y());
bokanef971462014-10-13 22:58:324693
majidvp944a8cd2016-01-12 21:05:184694 host_impl_->ScrollEnd(EndState().get());
bokanef971462014-10-13 22:58:324695}
4696
[email protected]fef74fd2014-02-27 06:28:174697TEST_F(LayerTreeHostImplTopControlsTest,
4698 ScrollNonScrollableRootWithTopControls) {
weiliangc8f4ef0d2015-11-27 00:15:554699 settings_ = DefaultSettings();
aelias5d3e3b42014-10-14 03:51:024700 CreateHostImpl(settings_, CreateOutputSurface());
bokanf553cb3b2015-07-23 18:54:054701 SetupTopControlsAndScrollLayerWithVirtualViewport(
4702 layer_size_, layer_size_, layer_size_);
[email protected]ce2e8112013-11-28 07:44:364703 DrawFrame();
[email protected]c8415bf92013-02-17 18:57:274704
tdresser81e84c672016-01-18 23:21:224705 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034706 host_impl_
4707 ->ScrollBegin(BeginState(gfx::Point()).get(),
4708 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224709 .thread);
[email protected]c8415bf92013-02-17 18:57:274710
[email protected]aa043632013-03-25 03:39:424711 host_impl_->top_controls_manager()->ScrollBegin();
4712 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
4713 host_impl_->top_controls_manager()->ScrollEnd();
bokan88eae012014-09-09 20:40:424714 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
[email protected]fef74fd2014-02-27 06:28:174715 // Now that top controls have moved, expect the clip to resize.
jaydasikaf419bf72016-06-15 10:21:214716 LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer()
4717 ->test_properties()
4718 ->parent->test_properties()
4719 ->parent;
bokanf553cb3b2015-07-23 18:54:054720 EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds());
[email protected]c8415bf92013-02-17 18:57:274721
majidvp944a8cd2016-01-12 21:05:184722 host_impl_->ScrollEnd(EndState().get());
[email protected]d948c112014-01-10 02:13:534723
tdresser81e84c672016-01-18 23:21:224724 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034725 host_impl_
4726 ->ScrollBegin(BeginState(gfx::Point()).get(),
4727 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224728 .thread);
[email protected]fef74fd2014-02-27 06:28:174729
4730 float scroll_increment_y = -25.f;
4731 host_impl_->top_controls_manager()->ScrollBegin();
4732 host_impl_->top_controls_manager()->ScrollBy(
4733 gfx::Vector2dF(0.f, scroll_increment_y));
aelias6004fe02015-02-07 21:43:014734 EXPECT_FLOAT_EQ(-scroll_increment_y,
4735 host_impl_->top_controls_manager()->ContentTopOffset());
[email protected]fef74fd2014-02-27 06:28:174736 // Now that top controls have moved, expect the clip to resize.
4737 EXPECT_EQ(gfx::Size(viewport_size_.width(),
4738 viewport_size_.height() + scroll_increment_y),
bokanf553cb3b2015-07-23 18:54:054739 inner_clip_ptr->bounds());
[email protected]fef74fd2014-02-27 06:28:174740
4741 host_impl_->top_controls_manager()->ScrollBy(
4742 gfx::Vector2dF(0.f, scroll_increment_y));
4743 host_impl_->top_controls_manager()->ScrollEnd();
aelias6004fe02015-02-07 21:43:014744 EXPECT_FLOAT_EQ(-2 * scroll_increment_y,
4745 host_impl_->top_controls_manager()->ContentTopOffset());
[email protected]fef74fd2014-02-27 06:28:174746 // Now that top controls have moved, expect the clip to resize.
bokanf553cb3b2015-07-23 18:54:054747 EXPECT_EQ(clip_size_, inner_clip_ptr->bounds());
[email protected]fef74fd2014-02-27 06:28:174748
majidvp944a8cd2016-01-12 21:05:184749 host_impl_->ScrollEnd(EndState().get());
[email protected]fef74fd2014-02-27 06:28:174750
4751 // Verify the layer is once-again non-scrollable.
4752 EXPECT_EQ(
miletusf57925d2014-10-01 19:38:134753 gfx::ScrollOffset(),
[email protected]fef74fd2014-02-27 06:28:174754 host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
4755
tdresser81e84c672016-01-18 23:21:224756 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:034757 host_impl_
4758 ->ScrollBegin(BeginState(gfx::Point()).get(),
4759 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:224760 .thread);
[email protected]c8415bf92013-02-17 18:57:274761}
4762
bokan7ad75ed2016-03-30 19:29:574763// Tests that activating a pending tree while there's a bounds_delta on the
4764// viewport layers from top controls doesn't cause a scroll jump. This bug was
4765// occurring because the UpdateViewportContainerSizes was being called before
4766// the property trees were updated with the bounds_delta. crbug.com/597266.
4767TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) {
bokanfe9e63e2016-07-19 19:19:084768 const gfx::Size inner_viewport_size(1000, 1000);
bokan7ad75ed2016-03-30 19:29:574769 const gfx::Size outer_viewport_size(1000, 1000);
4770 const gfx::Size content_size(2000, 2000);
4771
bokanfe9e63e2016-07-19 19:19:084772 // Initialization
4773 {
4774 SetupTopControlsAndScrollLayerWithVirtualViewport(
4775 inner_viewport_size, outer_viewport_size, content_size);
4776 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
bokan7ad75ed2016-03-30 19:29:574777
bokanfe9e63e2016-07-19 19:19:084778 // Start off with the top controls hidden on both main and impl.
4779 host_impl_->active_tree()->set_top_controls_shrink_blink_size(false);
4780 host_impl_->active_tree()->PushTopControlsFromMainThread(0);
bokan7ad75ed2016-03-30 19:29:574781
bokanfe9e63e2016-07-19 19:19:084782 host_impl_->CreatePendingTree();
4783 SetupTopControlsAndScrollLayerWithVirtualViewport(
4784 host_impl_->pending_tree(), inner_viewport_size, outer_viewport_size,
4785 content_size);
4786 host_impl_->pending_tree()->set_top_controls_shrink_blink_size(false);
bokan7ad75ed2016-03-30 19:29:574787
bokanfe9e63e2016-07-19 19:19:084788 // Fully scroll the viewport.
4789 host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
4790 InputHandler::TOUCHSCREEN);
4791 host_impl_->ScrollBy(
4792 UpdateState(gfx::Point(), gfx::Vector2d(0, 2000)).get());
4793 host_impl_->ScrollEnd(EndState().get());
4794 }
bokan7ad75ed2016-03-30 19:29:574795
bokan7ad75ed2016-03-30 19:29:574796 LayerImpl* outer_scroll =
4797 host_impl_->active_tree()->OuterViewportScrollLayer();
4798
bokanfe9e63e2016-07-19 19:19:084799 ASSERT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset());
4800 ASSERT_EQ(1000, outer_scroll->MaxScrollOffset().y());
4801 ASSERT_EQ(1000, outer_scroll->CurrentScrollOffset().y());
bokan7ad75ed2016-03-30 19:29:574802
bokanfe9e63e2016-07-19 19:19:084803 // Kick off an animation to show the top controls.
4804 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN, true);
4805 base::TimeTicks start_time = base::TimeTicks::Now();
4806 BeginFrameArgs begin_frame_args =
4807 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
bokan7ad75ed2016-03-30 19:29:574808
bokanfe9e63e2016-07-19 19:19:084809 // Pump an animation frame to put some delta in the top controls.
4810 {
4811 begin_frame_args.frame_time =
4812 start_time + base::TimeDelta::FromMilliseconds(50);
4813 host_impl_->WillBeginImplFrame(begin_frame_args);
4814 host_impl_->Animate();
4815 host_impl_->UpdateAnimationState(true);
4816 host_impl_->DidFinishImplFrame();
4817 }
4818
4819 // Pull the top controls delta and get it back to the pending tree so that
4820 // when we go to activate the pending tree we cause a change to top controls.
4821 {
4822 float delta =
4823 host_impl_->active_tree()->top_controls_shown_ratio()->Delta();
4824 ASSERT_GT(delta, 0);
4825 ASSERT_LT(delta, 1);
4826 host_impl_->active_tree()
4827 ->top_controls_shown_ratio()
4828 ->PullDeltaForMainThread();
4829 host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
4830 delta);
4831 }
4832
4833 // 200 is the kShowHideMaxDurationMs value from top_controls_manager.cc so the
4834 // top controls should be fully animated in this frame.
4835 {
4836 begin_frame_args.frame_time =
4837 start_time + base::TimeDelta::FromMilliseconds(200);
4838 host_impl_->WillBeginImplFrame(begin_frame_args);
4839 host_impl_->Animate();
4840 host_impl_->UpdateAnimationState(true);
4841 host_impl_->DidFinishImplFrame();
4842
4843 ASSERT_EQ(50, host_impl_->top_controls_manager()->ContentTopOffset());
4844 ASSERT_EQ(1050, outer_scroll->MaxScrollOffset().y());
4845 // NEAR because clip layer bounds are truncated in MaxScrollOffset so we
4846 // lose some precision in the intermediate animation steps.
4847 ASSERT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1.f);
4848 }
4849
4850 // Activate the pending tree which should have the same scroll value as the
bokan7ad75ed2016-03-30 19:29:574851 // active tree.
bokanfe9e63e2016-07-19 19:19:084852 {
4853 host_impl_->pending_tree()
4854 ->property_trees()
4855 ->scroll_tree.SetScrollOffsetDeltaForTesting(outer_scroll->id(),
4856 gfx::Vector2dF(0, 1050));
4857 host_impl_->ActivateSyncTree();
bokan7ad75ed2016-03-30 19:29:574858
bokanfe9e63e2016-07-19 19:19:084859 // Make sure we don't accidentally clamp the outer offset based on a bounds
4860 // delta that hasn't yet been updated.
4861 EXPECT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1.f);
4862 }
bokan7ad75ed2016-03-30 19:29:574863}
4864
[email protected]aa043632013-03-25 03:39:424865TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
4866 // Test the configuration where a non-composited root layer is embedded in a
4867 // scrollable outer layer.
4868 gfx::Size surface_size(10, 10);
[email protected]adeda572014-01-31 00:49:474869 gfx::Size contents_size(20, 20);
[email protected]94f206c12012-08-25 00:09:144870
danakj60bc3bc2016-04-09 00:24:484871 std::unique_ptr<LayerImpl> content_layer =
[email protected]aa043632013-03-25 03:39:424872 LayerImpl::Create(host_impl_->active_tree(), 1);
4873 content_layer->SetDrawsContent(true);
4874 content_layer->SetPosition(gfx::PointF());
[email protected]adeda572014-01-31 00:49:474875 content_layer->SetBounds(contents_size);
[email protected]94f206c12012-08-25 00:09:144876
danakj60bc3bc2016-04-09 00:24:484877 std::unique_ptr<LayerImpl> scroll_clip_layer =
[email protected]adeda572014-01-31 00:49:474878 LayerImpl::Create(host_impl_->active_tree(), 3);
4879 scroll_clip_layer->SetBounds(surface_size);
4880
danakj60bc3bc2016-04-09 00:24:484881 std::unique_ptr<LayerImpl> scroll_layer =
[email protected]aa043632013-03-25 03:39:424882 LayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]adeda572014-01-31 00:49:474883 scroll_layer->SetScrollClipLayer(3);
4884 scroll_layer->SetBounds(contents_size);
[email protected]aa043632013-03-25 03:39:424885 scroll_layer->SetPosition(gfx::PointF());
jaydasika89f7b5a2016-06-22 02:08:394886 scroll_layer->test_properties()->AddChild(std::move(content_layer));
4887 scroll_clip_layer->test_properties()->AddChild(std::move(scroll_layer));
[email protected]94f206c12012-08-25 00:09:144888
jaydasika6b5a32bf2016-04-22 21:56:364889 scroll_clip_layer->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:594890 host_impl_->active_tree()->SetRootLayerForTesting(
4891 std::move(scroll_clip_layer));
danakj74af409e2016-07-01 00:41:484892 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4893
[email protected]18ce59702013-04-09 04:58:404894 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364895 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144896
tdresser81e84c672016-01-18 23:21:224897 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:184898 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:224899 InputHandler::WHEEL)
4900 .thread);
majidvp944a8cd2016-01-12 21:05:184901 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
4902 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:424903 EXPECT_TRUE(did_request_redraw_);
4904 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144905}
4906
[email protected]aa043632013-03-25 03:39:424907TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
4908 gfx::Size surface_size(10, 10);
[email protected]adeda572014-01-31 00:49:474909 gfx::Size contents_size(20, 20);
danakj60bc3bc2016-04-09 00:24:484910 std::unique_ptr<LayerImpl> root =
4911 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:424912 root->SetBounds(surface_size);
jaydasika89f7b5a2016-06-22 02:08:394913 root->test_properties()->AddChild(
4914 CreateScrollableLayer(2, contents_size, root.get()));
jaydasika6b5a32bf2016-04-22 21:56:364915 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:594916 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:484917 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4918
[email protected]18ce59702013-04-09 04:58:404919 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364920 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144921
tdresser81e84c672016-01-18 23:21:224922 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:184923 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:224924 InputHandler::WHEEL)
4925 .thread);
majidvp944a8cd2016-01-12 21:05:184926 host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
4927 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:424928 EXPECT_TRUE(did_request_redraw_);
4929 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144930}
4931
[email protected]aa043632013-03-25 03:39:424932TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
4933 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:484934 std::unique_ptr<LayerImpl> root =
4935 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika89f7b5a2016-06-22 02:08:394936 root->test_properties()->AddChild(
4937 CreateScrollableLayer(2, surface_size, root.get()));
jaydasika6b5a32bf2016-04-22 21:56:364938 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:594939 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:484940 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4941
[email protected]18ce59702013-04-09 04:58:404942 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364943 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144944
[email protected]aa043632013-03-25 03:39:424945 // Scroll event is ignored because the input coordinate is outside the layer
4946 // boundaries.
tdresser81e84c672016-01-18 23:21:224947 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
4948 BeginState(gfx::Point(15, 5)).get(), InputHandler::WHEEL);
4949 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:404950 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:224951 status.main_thread_scrolling_reasons);
4952
[email protected]aa043632013-03-25 03:39:424953 EXPECT_FALSE(did_request_redraw_);
4954 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144955}
4956
[email protected]aa043632013-03-25 03:39:424957TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
4958 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:484959 std::unique_ptr<LayerImpl> root =
4960 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika6b5a32bf2016-04-22 21:56:364961 root->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:484962 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:474963 CreateScrollableLayer(2, surface_size, root.get());
[email protected]94f206c12012-08-25 00:09:144964
[email protected]aa043632013-03-25 03:39:424965 gfx::Transform matrix;
4966 matrix.RotateAboutXAxis(180.0);
jaydasika10d43fc2016-08-18 04:06:044967 child->test_properties()->transform = matrix;
jaydasika6b5a32bf2016-04-22 21:56:364968 child->test_properties()->double_sided = false;
[email protected]94f206c12012-08-25 00:09:144969
jaydasika89f7b5a2016-06-22 02:08:394970 root->test_properties()->AddChild(std::move(child));
jaydasikabf1875a2016-06-28 03:39:594971 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:484972 host_impl_->active_tree()->BuildPropertyTreesForTesting();
4973
4974 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:364975 DrawFrame();
[email protected]94f206c12012-08-25 00:09:144976
[email protected]aa043632013-03-25 03:39:424977 // Scroll event is ignored because the scrollable layer is not facing the
4978 // viewer and there is nothing scrollable behind it.
tdresser81e84c672016-01-18 23:21:224979 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
4980 BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL);
4981 EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
danakj35904762016-01-21 20:49:404982 EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
tdresser81e84c672016-01-18 23:21:224983 status.main_thread_scrolling_reasons);
4984
[email protected]aa043632013-03-25 03:39:424985 EXPECT_FALSE(did_request_redraw_);
4986 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144987}
4988
[email protected]aa043632013-03-25 03:39:424989TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
4990 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:484991 std::unique_ptr<LayerImpl> clip_layer =
[email protected]adeda572014-01-31 00:49:474992 LayerImpl::Create(host_impl_->active_tree(), 3);
danakj60bc3bc2016-04-09 00:24:484993 std::unique_ptr<LayerImpl> content_layer =
[email protected]adeda572014-01-31 00:49:474994 CreateScrollableLayer(1, surface_size, clip_layer.get());
tdresser81e84c672016-01-18 23:21:224995 content_layer->set_main_thread_scrolling_reasons(
danakj35904762016-01-21 20:49:404996 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
[email protected]adeda572014-01-31 00:49:474997 content_layer->SetScrollClipLayer(Layer::INVALID_ID);
[email protected]94f206c12012-08-25 00:09:144998
[email protected]adeda572014-01-31 00:49:474999 // Note: we can use the same clip layer for both since both calls to
5000 // CreateScrollableLayer() use the same surface size.
danakj60bc3bc2016-04-09 00:24:485001 std::unique_ptr<LayerImpl> scroll_layer =
[email protected]adeda572014-01-31 00:49:475002 CreateScrollableLayer(2, surface_size, clip_layer.get());
jaydasika89f7b5a2016-06-22 02:08:395003 scroll_layer->test_properties()->AddChild(std::move(content_layer));
5004 clip_layer->test_properties()->AddChild(std::move(scroll_layer));
jaydasika6b5a32bf2016-04-22 21:56:365005 clip_layer->test_properties()->force_render_surface = true;
[email protected]94f206c12012-08-25 00:09:145006
jaydasikabf1875a2016-06-28 03:39:595007 host_impl_->active_tree()->SetRootLayerForTesting(std::move(clip_layer));
danakj74af409e2016-07-01 00:41:485008 host_impl_->active_tree()->BuildPropertyTreesForTesting();
5009
[email protected]18ce59702013-04-09 04:58:405010 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365011 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145012
[email protected]aa043632013-03-25 03:39:425013 // Scrolling fails because the content layer is asking to be scrolled on the
5014 // main thread.
tdresser81e84c672016-01-18 23:21:225015 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
5016 BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL);
5017 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
danakj35904762016-01-21 20:49:405018 EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
tdresser81e84c672016-01-18 23:21:225019 status.main_thread_scrolling_reasons);
[email protected]94f206c12012-08-25 00:09:145020}
5021
[email protected]aa043632013-03-25 03:39:425022TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
bokan1f01388f2015-09-15 20:55:545023 gfx::Size viewport_size(20, 20);
[email protected]aa043632013-03-25 03:39:425024 float page_scale = 2.f;
bokan1f86d8f2015-07-30 16:08:545025
5026 SetupScrollAndContentsLayers(viewport_size);
5027
5028 // Setup the layers so that the outer viewport is scrollable.
jaydasikaf419bf72016-06-15 10:21:215029 host_impl_->active_tree()
5030 ->InnerViewportScrollLayer()
5031 ->test_properties()
5032 ->parent->SetBounds(viewport_size);
bokan1f86d8f2015-07-30 16:08:545033 host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds(
bokan1f01388f2015-09-15 20:55:545034 gfx::Size(40, 40));
bokan1f86d8f2015-07-30 16:08:545035 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
[email protected]ce2e8112013-11-28 07:44:365036 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145037
[email protected]adeda572014-01-31 00:49:475038 LayerImpl* root_scroll =
bokan1f86d8f2015-07-30 16:08:545039 host_impl_->active_tree()->OuterViewportScrollLayer();
bokan1f01388f2015-09-15 20:55:545040 LayerImpl* inner_scroll =
5041 host_impl_->active_tree()->InnerViewportScrollLayer();
[email protected]fef74fd2014-02-27 06:28:175042 EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds());
[email protected]9781afa2013-07-17 23:15:325043
[email protected]aa043632013-03-25 03:39:425044 gfx::Vector2d scroll_delta(0, 10);
5045 gfx::Vector2d expected_scroll_delta = scroll_delta;
miletusf57925d2014-10-01 19:38:135046 gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
tdresser81e84c672016-01-18 23:21:225047 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185048 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225049 InputHandler::WHEEL)
5050 .thread);
majidvp944a8cd2016-01-12 21:05:185051 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5052 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145053
[email protected]aa043632013-03-25 03:39:425054 // Set new page scale from main thread.
bokan1f86d8f2015-07-30 16:08:545055 host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
[email protected]94f206c12012-08-25 00:09:145056
danakj60bc3bc2016-04-09 00:24:485057 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5058 host_impl_->ProcessScrollDeltas();
bokan1f01388f2015-09-15 20:55:545059 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
tdresser99977952015-07-02 19:49:185060 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145061
[email protected]aa043632013-03-25 03:39:425062 // The scroll range should also have been updated.
[email protected]adeda572014-01-31 00:49:475063 EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
[email protected]94f206c12012-08-25 00:09:145064
[email protected]aa043632013-03-25 03:39:425065 // The page scale delta remains constant because the impl thread did not
5066 // scale.
[email protected]f2136262013-04-26 21:10:195067 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:145068}
5069
[email protected]aa043632013-03-25 03:39:425070TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
bokan1f01388f2015-09-15 20:55:545071 gfx::Size viewport_size(20, 20);
[email protected]aa043632013-03-25 03:39:425072 float page_scale = 2.f;
bokan1f86d8f2015-07-30 16:08:545073
5074 SetupScrollAndContentsLayers(viewport_size);
5075
5076 // Setup the layers so that the outer viewport is scrollable.
jaydasikaf419bf72016-06-15 10:21:215077 host_impl_->active_tree()
5078 ->InnerViewportScrollLayer()
5079 ->test_properties()
5080 ->parent->SetBounds(viewport_size);
bokan1f86d8f2015-07-30 16:08:545081 host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds(
bokan1f01388f2015-09-15 20:55:545082 gfx::Size(40, 40));
bokan1f86d8f2015-07-30 16:08:545083 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
danakj74af409e2016-07-01 00:41:485084 host_impl_->active_tree()->BuildPropertyTreesForTesting();
5085
[email protected]ce2e8112013-11-28 07:44:365086 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145087
[email protected]adeda572014-01-31 00:49:475088 LayerImpl* root_scroll =
bokan1f86d8f2015-07-30 16:08:545089 host_impl_->active_tree()->OuterViewportScrollLayer();
bokan1f01388f2015-09-15 20:55:545090 LayerImpl* inner_scroll =
5091 host_impl_->active_tree()->InnerViewportScrollLayer();
[email protected]fef74fd2014-02-27 06:28:175092 EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds());
[email protected]9781afa2013-07-17 23:15:325093
[email protected]aa043632013-03-25 03:39:425094 gfx::Vector2d scroll_delta(0, 10);
5095 gfx::Vector2d expected_scroll_delta = scroll_delta;
miletusf57925d2014-10-01 19:38:135096 gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
tdresser81e84c672016-01-18 23:21:225097 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185098 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225099 InputHandler::WHEEL)
5100 .thread);
majidvp944a8cd2016-01-12 21:05:185101 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5102 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145103
[email protected]aa043632013-03-25 03:39:425104 // Set new page scale on impl thread by pinching.
majidvp944a8cd2016-01-12 21:05:185105 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:035106 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:425107 host_impl_->PinchGestureBegin();
5108 host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
5109 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:185110 host_impl_->ScrollEnd(EndState().get());
danakj74af409e2016-07-01 00:41:485111
[email protected]aa043632013-03-25 03:39:425112 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:145113
[email protected]aa043632013-03-25 03:39:425114 // The scroll delta is not scaled because the main thread did not scale.
danakj60bc3bc2016-04-09 00:24:485115 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5116 host_impl_->ProcessScrollDeltas();
bokan1f01388f2015-09-15 20:55:545117 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
tdresser99977952015-07-02 19:49:185118 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145119
[email protected]aa043632013-03-25 03:39:425120 // The scroll range should also have been updated.
[email protected]adeda572014-01-31 00:49:475121 EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
[email protected]94f206c12012-08-25 00:09:145122
[email protected]aa043632013-03-25 03:39:425123 // The page scale delta should match the new scale on the impl side.
aelias58eec0812014-12-04 01:04:405124 EXPECT_EQ(page_scale, host_impl_->active_tree()->current_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:145125}
5126
[email protected]aa043632013-03-25 03:39:425127TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
bokan0c33a092015-07-29 18:27:565128 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
[email protected]aa043632013-03-25 03:39:425129 gfx::Size surface_size(10, 10);
5130 float default_page_scale = 1.f;
5131 gfx::Transform default_page_scale_matrix;
[email protected]3209161d2013-03-29 19:17:345132 default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
[email protected]1c0c9bc2012-10-08 22:41:485133
[email protected]aa043632013-03-25 03:39:425134 float new_page_scale = 2.f;
5135 gfx::Transform new_page_scale_matrix;
5136 new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
[email protected]94f206c12012-08-25 00:09:145137
[email protected]aa043632013-03-25 03:39:425138 // Create a normal scrollable root layer and another scrollable child layer.
[email protected]35a99a12013-05-09 23:52:295139 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
jaydasikad7dea632015-11-06 04:40:125140 scroll->SetDrawsContent(true);
jaydasikabf1875a2016-06-28 03:39:595141 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
jaydasikafc66cfb2016-06-10 04:34:225142 LayerImpl* child = scroll->test_properties()->children[0];
jaydasikad7dea632015-11-06 04:40:125143 child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:145144
danakj60bc3bc2016-04-09 00:24:485145 std::unique_ptr<LayerImpl> scrollable_child_clip =
[email protected]adeda572014-01-31 00:49:475146 LayerImpl::Create(host_impl_->active_tree(), 6);
danakj60bc3bc2016-04-09 00:24:485147 std::unique_ptr<LayerImpl> scrollable_child =
[email protected]adeda572014-01-31 00:49:475148 CreateScrollableLayer(7, surface_size, scrollable_child_clip.get());
jaydasika89f7b5a2016-06-22 02:08:395149 scrollable_child_clip->test_properties()->AddChild(
5150 std::move(scrollable_child));
5151 child->test_properties()->AddChild(std::move(scrollable_child_clip));
jaydasikafc66cfb2016-06-10 04:34:225152 LayerImpl* grand_child = child->test_properties()->children[0];
jaydasikad7dea632015-11-06 04:40:125153 grand_child->SetDrawsContent(true);
danakj74af409e2016-07-01 00:41:485154 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145155
[email protected]aa043632013-03-25 03:39:425156 // Set new page scale on impl thread by pinching.
majidvp944a8cd2016-01-12 21:05:185157 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:035158 InputHandler::TOUCHSCREEN);
[email protected]aa043632013-03-25 03:39:425159 host_impl_->PinchGestureBegin();
5160 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
5161 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:185162 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:425163 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:145164
[email protected]aa043632013-03-25 03:39:425165 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
5166 // the page scale delta on the root layer is applied hierarchically.
5167 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:485168 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:455169 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:425170 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:145171
ajumad9432e32015-11-30 19:43:445172 EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(0, 0));
5173 EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(1, 1));
5174 EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(0, 0));
5175 EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(1, 1));
5176 EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(0, 0));
5177 EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(1, 1));
[email protected]aa043632013-03-25 03:39:425178 EXPECT_EQ(new_page_scale,
ajumad9432e32015-11-30 19:43:445179 grand_child->DrawTransform().matrix().getDouble(0, 0));
[email protected]aa043632013-03-25 03:39:425180 EXPECT_EQ(new_page_scale,
ajumad9432e32015-11-30 19:43:445181 grand_child->DrawTransform().matrix().getDouble(1, 1));
[email protected]94f206c12012-08-25 00:09:145182}
5183
[email protected]aa043632013-03-25 03:39:425184TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
bokan1f01388f2015-09-15 20:55:545185 SetupScrollAndContentsLayers(gfx::Size(30, 30));
bokanf553cb3b2015-07-23 18:54:055186
5187 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
bokan1f01388f2015-09-15 20:55:545188 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
bokanf553cb3b2015-07-23 18:54:055189
5190 // Make the outer scroll layer scrollable.
5191 outer_scroll->SetBounds(gfx::Size(50, 50));
danakj74af409e2016-07-01 00:41:485192 host_impl_->active_tree()->BuildPropertyTreesForTesting();
bokanf553cb3b2015-07-23 18:54:055193
[email protected]ce2e8112013-11-28 07:44:365194 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145195
[email protected]aa043632013-03-25 03:39:425196 gfx::Vector2d scroll_delta(0, 10);
5197 gfx::Vector2d expected_scroll_delta(scroll_delta);
bokanf553cb3b2015-07-23 18:54:055198 gfx::ScrollOffset expected_max_scroll(outer_scroll->MaxScrollOffset());
tdresser81e84c672016-01-18 23:21:225199 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185200 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225201 InputHandler::WHEEL)
5202 .thread);
majidvp944a8cd2016-01-12 21:05:185203 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5204 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145205
[email protected]aa043632013-03-25 03:39:425206 float page_scale = 2.f;
aelias58eec0812014-12-04 01:04:405207 host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f,
[email protected]aa043632013-03-25 03:39:425208 page_scale);
danakj74af409e2016-07-01 00:41:485209 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145210
[email protected]aa043632013-03-25 03:39:425211 DrawOneFrame();
[email protected]1c0c9bc2012-10-08 22:41:485212
danakj60bc3bc2016-04-09 00:24:485213 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5214 host_impl_->ProcessScrollDeltas();
bokan1f01388f2015-09-15 20:55:545215 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
tdresser99977952015-07-02 19:49:185216 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145217
[email protected]aa043632013-03-25 03:39:425218 // The scroll range should not have changed.
bokanf553cb3b2015-07-23 18:54:055219 EXPECT_EQ(outer_scroll->MaxScrollOffset(), expected_max_scroll);
[email protected]94f206c12012-08-25 00:09:145220
[email protected]aa043632013-03-25 03:39:425221 // The page scale delta remains constant because the impl thread did not
5222 // scale.
[email protected]f2136262013-04-26 21:10:195223 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:145224}
5225
[email protected]aa043632013-03-25 03:39:425226TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
5227 // Scroll a child layer beyond its maximum scroll range and make sure the
tdressera3b162b82015-09-29 17:51:435228 // parent layer isn't scrolled.
[email protected]aa043632013-03-25 03:39:425229 gfx::Size surface_size(10, 10);
[email protected]adeda572014-01-31 00:49:475230 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:485231 std::unique_ptr<LayerImpl> root =
5232 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]adeda572014-01-31 00:49:475233 root->SetBounds(surface_size);
jaydasika6b5a32bf2016-04-22 21:56:365234 root->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:485235 std::unique_ptr<LayerImpl> grand_child =
[email protected]adeda572014-01-31 00:49:475236 CreateScrollableLayer(3, content_size, root.get());
[email protected]94f206c12012-08-25 00:09:145237
danakj60bc3bc2016-04-09 00:24:485238 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:475239 CreateScrollableLayer(2, content_size, root.get());
5240 LayerImpl* grand_child_layer = grand_child.get();
jaydasika89f7b5a2016-06-22 02:08:395241 child->test_properties()->AddChild(std::move(grand_child));
[email protected]94f206c12012-08-25 00:09:145242
[email protected]adeda572014-01-31 00:49:475243 LayerImpl* child_layer = child.get();
jaydasika89f7b5a2016-06-22 02:08:395244 root->test_properties()->AddChild(std::move(child));
jaydasikabf1875a2016-06-28 03:39:595245 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:485246 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425247 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:485248
sunxdb7e79432016-03-09 21:13:425249 grand_child_layer->layer_tree_impl()
5250 ->property_trees()
5251 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
5252 gfx::ScrollOffset(0, 5));
5253 child_layer->layer_tree_impl()
5254 ->property_trees()
5255 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
5256 gfx::ScrollOffset(3, 0));
[email protected]adeda572014-01-31 00:49:475257
danakj74af409e2016-07-01 00:41:485258 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365259 DrawFrame();
[email protected]aa043632013-03-25 03:39:425260 {
5261 gfx::Vector2d scroll_delta(-8, -7);
tdresser81e84c672016-01-18 23:21:225262 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185263 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225264 InputHandler::WHEEL)
5265 .thread);
majidvp944a8cd2016-01-12 21:05:185266 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5267 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145268
danakj60bc3bc2016-04-09 00:24:485269 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425270 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:145271
[email protected]aa043632013-03-25 03:39:425272 // The grand child should have scrolled up to its limit.
jaydasikabf1875a2016-06-28 03:39:595273 LayerImpl* child = host_impl_->active_tree()
5274 ->root_layer_for_testing()
5275 ->test_properties()
5276 ->children[0];
jaydasikafc66cfb2016-06-10 04:34:225277 LayerImpl* grand_child = child->test_properties()->children[0];
tdresser99977952015-07-02 19:49:185278 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5279 gfx::Vector2d(0, -5)));
[email protected]94f206c12012-08-25 00:09:145280
tdressera3b162b82015-09-29 17:51:435281 // The child should not have scrolled.
5282 ExpectNone(*scroll_info.get(), child->id());
[email protected]aa043632013-03-25 03:39:425283 }
[email protected]94f206c12012-08-25 00:09:145284}
5285
[email protected]aa043632013-03-25 03:39:425286TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
5287 // Scroll a child layer beyond its maximum scroll range and make sure the
5288 // the scroll doesn't bubble up to the parent layer.
[email protected]adeda572014-01-31 00:49:475289 gfx::Size surface_size(20, 20);
[email protected]fef74fd2014-02-27 06:28:175290 gfx::Size viewport_size(10, 10);
danakj60bc3bc2016-04-09 00:24:485291 std::unique_ptr<LayerImpl> root_ptr =
sunxd676696572016-01-07 16:28:305292 LayerImpl::Create(host_impl_->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:485293 std::unique_ptr<LayerImpl> root_clip =
sunxd676696572016-01-07 16:28:305294 LayerImpl::Create(host_impl_->active_tree(), 2);
jaydasika6b5a32bf2016-04-22 21:56:365295 root_clip->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:485296 std::unique_ptr<LayerImpl> root_scrolling =
sunxd676696572016-01-07 16:28:305297 CreateScrollableLayer(3, surface_size, root_clip.get());
jaydasikaca2605e2016-04-23 02:52:525298 root_scrolling->test_properties()->is_container_for_fixed_position_layers =
5299 true;
[email protected]7dfa6862013-01-31 01:29:095300
danakj60bc3bc2016-04-09 00:24:485301 std::unique_ptr<LayerImpl> grand_child =
sunxd676696572016-01-07 16:28:305302 CreateScrollableLayer(5, surface_size, root_clip.get());
[email protected]7dfa6862013-01-31 01:29:095303
danakj60bc3bc2016-04-09 00:24:485304 std::unique_ptr<LayerImpl> child =
sunxd676696572016-01-07 16:28:305305 CreateScrollableLayer(4, surface_size, root_clip.get());
[email protected]adeda572014-01-31 00:49:475306 LayerImpl* grand_child_layer = grand_child.get();
jaydasika89f7b5a2016-06-22 02:08:395307 child->test_properties()->AddChild(std::move(grand_child));
[email protected]7dfa6862013-01-31 01:29:095308
[email protected]adeda572014-01-31 00:49:475309 LayerImpl* child_layer = child.get();
jaydasika89f7b5a2016-06-22 02:08:395310 root_scrolling->test_properties()->AddChild(std::move(child));
5311 root_clip->test_properties()->AddChild(std::move(root_scrolling));
sunxd676696572016-01-07 16:28:305312 EXPECT_EQ(viewport_size, root_clip->bounds());
jaydasika89f7b5a2016-06-22 02:08:395313 root_ptr->test_properties()->AddChild(std::move(root_clip));
jaydasikabf1875a2016-06-28 03:39:595314 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
danakj74af409e2016-07-01 00:41:485315 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd676696572016-01-07 16:28:305316 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3,
ccameron8230b68b2014-11-21 19:25:185317 Layer::INVALID_ID);
[email protected]aa043632013-03-25 03:39:425318 host_impl_->active_tree()->DidBecomeActive();
[email protected]fef74fd2014-02-27 06:28:175319 host_impl_->SetViewportSize(viewport_size);
[email protected]adeda572014-01-31 00:49:475320
sunxdb7e79432016-03-09 21:13:425321 grand_child_layer->layer_tree_impl()
5322 ->property_trees()
5323 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
5324 gfx::ScrollOffset(0, 2));
5325 child_layer->layer_tree_impl()
5326 ->property_trees()
5327 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
5328 gfx::ScrollOffset(0, 3));
[email protected]adeda572014-01-31 00:49:475329
[email protected]ce2e8112013-11-28 07:44:365330 DrawFrame();
[email protected]aa043632013-03-25 03:39:425331 {
5332 gfx::Vector2d scroll_delta(0, -10);
tdresser81e84c672016-01-18 23:21:225333 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185334 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225335 InputHandler::NON_BUBBLING_GESTURE)
5336 .thread);
majidvp944a8cd2016-01-12 21:05:185337 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5338 host_impl_->ScrollEnd(EndState().get());
[email protected]7dfa6862013-01-31 01:29:095339
danakj60bc3bc2016-04-09 00:24:485340 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425341 host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:095342
[email protected]aa043632013-03-25 03:39:425343 // The grand child should have scrolled up to its limit.
sunxd676696572016-01-07 16:28:305344 LayerImpl* child = host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:595345 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:225346 ->test_properties()
5347 ->children[0]
5348 ->test_properties()
5349 ->children[0]
5350 ->test_properties()
5351 ->children[0];
5352 LayerImpl* grand_child = child->test_properties()->children[0];
tdresser99977952015-07-02 19:49:185353 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5354 gfx::Vector2d(0, -2)));
[email protected]7dfa6862013-01-31 01:29:095355
[email protected]aa043632013-03-25 03:39:425356 // The child should not have scrolled.
5357 ExpectNone(*scroll_info.get(), child->id());
[email protected]7dfa6862013-01-31 01:29:095358
[email protected]aa043632013-03-25 03:39:425359 // The next time we scroll we should only scroll the parent.
5360 scroll_delta = gfx::Vector2d(0, -3);
tdresser81e84c672016-01-18 23:21:225361 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185362 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225363 InputHandler::NON_BUBBLING_GESTURE)
5364 .thread);
[email protected]aa043632013-03-25 03:39:425365 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:185366 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]aa043632013-03-25 03:39:425367 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
majidvp944a8cd2016-01-12 21:05:185368 host_impl_->ScrollEnd(EndState().get());
[email protected]7dfa6862013-01-31 01:29:095369
[email protected]aa043632013-03-25 03:39:425370 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:095371
[email protected]aa043632013-03-25 03:39:425372 // The child should have scrolled up to its limit.
tdresser99977952015-07-02 19:49:185373 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
5374 gfx::Vector2d(0, -3)));
[email protected]7dfa6862013-01-31 01:29:095375
[email protected]aa043632013-03-25 03:39:425376 // The grand child should not have scrolled.
tdresser99977952015-07-02 19:49:185377 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5378 gfx::Vector2d(0, -2)));
[email protected]7dfa6862013-01-31 01:29:095379
[email protected]aa043632013-03-25 03:39:425380 // After scrolling the parent, another scroll on the opposite direction
5381 // should still scroll the child.
5382 scroll_delta = gfx::Vector2d(0, 7);
tdresser81e84c672016-01-18 23:21:225383 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185384 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225385 InputHandler::NON_BUBBLING_GESTURE)
5386 .thread);
[email protected]aa043632013-03-25 03:39:425387 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:185388 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]aa043632013-03-25 03:39:425389 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:185390 host_impl_->ScrollEnd(EndState().get());
[email protected]7dfa6862013-01-31 01:29:095391
[email protected]aa043632013-03-25 03:39:425392 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:095393
[email protected]aa043632013-03-25 03:39:425394 // The grand child should have scrolled.
tdresser99977952015-07-02 19:49:185395 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5396 gfx::Vector2d(0, 5)));
[email protected]7dfa6862013-01-31 01:29:095397
[email protected]aa043632013-03-25 03:39:425398 // The child should not have scrolled.
tdresser99977952015-07-02 19:49:185399 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
5400 gfx::Vector2d(0, -3)));
[email protected]f4937272013-02-07 05:54:505401
[email protected]aa043632013-03-25 03:39:425402 // Scrolling should be adjusted from viewport space.
aelias58eec0812014-12-04 01:04:405403 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f);
danakj5ad246cd2015-09-12 01:04:505404 host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
[email protected]f4937272013-02-07 05:54:505405
[email protected]aa043632013-03-25 03:39:425406 scroll_delta = gfx::Vector2d(0, -2);
tdresser81e84c672016-01-18 23:21:225407 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185408 host_impl_->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
tdresser81e84c672016-01-18 23:21:225409 InputHandler::NON_BUBBLING_GESTURE)
5410 .thread);
[email protected]aa043632013-03-25 03:39:425411 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer());
majidvp944a8cd2016-01-12 21:05:185412 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5413 host_impl_->ScrollEnd(EndState().get());
[email protected]f4937272013-02-07 05:54:505414
[email protected]aa043632013-03-25 03:39:425415 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]f4937272013-02-07 05:54:505416
[email protected]aa043632013-03-25 03:39:425417 // Should have scrolled by half the amount in layer space (5 - 2/2)
tdresser99977952015-07-02 19:49:185418 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
5419 gfx::Vector2d(0, 4)));
[email protected]aa043632013-03-25 03:39:425420 }
[email protected]7dfa6862013-01-31 01:29:095421}
[email protected]aa043632013-03-25 03:39:425422TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
5423 // When we try to scroll a non-scrollable child layer, the scroll delta
5424 // should be applied to one of its ancestors if possible.
5425 gfx::Size surface_size(10, 10);
5426 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:485427 std::unique_ptr<LayerImpl> root_ptr =
sunxd676696572016-01-07 16:28:305428 LayerImpl::Create(host_impl_->active_tree(), 4);
danakj60bc3bc2016-04-09 00:24:485429 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:475430 LayerImpl::Create(host_impl_->active_tree(), 3);
jaydasika6b5a32bf2016-04-22 21:56:365431 root_clip->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:485432 std::unique_ptr<LayerImpl> root_scroll =
[email protected]adeda572014-01-31 00:49:475433 CreateScrollableLayer(1, content_size, root_clip.get());
5434 // Make 'root' the clip layer for child: since they have the same sizes the
5435 // child will have zero max_scroll_offset and scrolls will bubble.
danakj60bc3bc2016-04-09 00:24:485436 std::unique_ptr<LayerImpl> child =
sunxd676696572016-01-07 16:28:305437 CreateScrollableLayer(2, content_size, root_scroll.get());
jaydasikaca2605e2016-04-23 02:52:525438 child->test_properties()->is_container_for_fixed_position_layers = true;
sunxd676696572016-01-07 16:28:305439 root_scroll->SetBounds(content_size);
[email protected]94f206c12012-08-25 00:09:145440
sunxd676696572016-01-07 16:28:305441 int root_scroll_id = root_scroll->id();
jaydasika89f7b5a2016-06-22 02:08:395442 root_scroll->test_properties()->AddChild(std::move(child));
5443 root_clip->test_properties()->AddChild(std::move(root_scroll));
5444 root_ptr->test_properties()->AddChild(std::move(root_clip));
[email protected]94f206c12012-08-25 00:09:145445
jaydasikabf1875a2016-06-28 03:39:595446 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
sunxd676696572016-01-07 16:28:305447 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 2,
ccameron8230b68b2014-11-21 19:25:185448 Layer::INVALID_ID);
danakj74af409e2016-07-01 00:41:485449 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425450 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:485451
5452 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365453 DrawFrame();
[email protected]aa043632013-03-25 03:39:425454 {
5455 gfx::Vector2d scroll_delta(0, 4);
tdresser81e84c672016-01-18 23:21:225456 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185457 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225458 InputHandler::WHEEL)
5459 .thread);
majidvp944a8cd2016-01-12 21:05:185460 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5461 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145462
danakj60bc3bc2016-04-09 00:24:485463 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425464 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:145465
[email protected]adeda572014-01-31 00:49:475466 // Only the root scroll should have scrolled.
[email protected]aa043632013-03-25 03:39:425467 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
tdresser99977952015-07-02 19:49:185468 EXPECT_TRUE(
5469 ScrollInfoContains(*scroll_info.get(), root_scroll_id, scroll_delta));
[email protected]aa043632013-03-25 03:39:425470 }
[email protected]94f206c12012-08-25 00:09:145471}
5472
[email protected]aa043632013-03-25 03:39:425473TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
5474 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:485475 std::unique_ptr<LayerImpl> root_ptr =
[email protected]adeda572014-01-31 00:49:475476 LayerImpl::Create(host_impl_->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:485477 std::unique_ptr<LayerImpl> root_clip =
sunxd676696572016-01-07 16:28:305478 LayerImpl::Create(host_impl_->active_tree(), 2);
danakj60bc3bc2016-04-09 00:24:485479 std::unique_ptr<LayerImpl> root_scroll =
sunxd676696572016-01-07 16:28:305480 CreateScrollableLayer(3, surface_size, root_clip.get());
jaydasika6b5a32bf2016-04-22 21:56:365481 root_clip->test_properties()->force_render_surface = true;
jaydasikaca2605e2016-04-23 02:52:525482 root_scroll->test_properties()->is_container_for_fixed_position_layers = true;
jaydasika89f7b5a2016-06-22 02:08:395483 root_clip->test_properties()->AddChild(std::move(root_scroll));
5484 root_ptr->test_properties()->AddChild(std::move(root_clip));
jaydasikabf1875a2016-06-28 03:39:595485 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
sunxd676696572016-01-07 16:28:305486 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3,
ccameron8230b68b2014-11-21 19:25:185487 Layer::INVALID_ID);
danakj74af409e2016-07-01 00:41:485488 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425489 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:485490
[email protected]18ce59702013-04-09 04:58:405491 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:145492
[email protected]aa043632013-03-25 03:39:425493 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
5494 // synchronization.
[email protected]ce2e8112013-11-28 07:44:365495 DrawFrame();
danakj74af409e2016-07-01 00:41:485496
rockot2176f922016-06-08 19:18:325497 host_impl_->active_tree()->DetachLayers();
danakj60bc3bc2016-04-09 00:24:485498 std::unique_ptr<LayerImpl> root_ptr2 =
sunxd676696572016-01-07 16:28:305499 LayerImpl::Create(host_impl_->active_tree(), 4);
danakj60bc3bc2016-04-09 00:24:485500 std::unique_ptr<LayerImpl> root_clip2 =
sunxd676696572016-01-07 16:28:305501 LayerImpl::Create(host_impl_->active_tree(), 5);
danakj60bc3bc2016-04-09 00:24:485502 std::unique_ptr<LayerImpl> root_scroll2 =
sunxd676696572016-01-07 16:28:305503 CreateScrollableLayer(6, surface_size, root_clip2.get());
jaydasikaca2605e2016-04-23 02:52:525504 root_scroll2->test_properties()->is_container_for_fixed_position_layers =
5505 true;
jaydasika89f7b5a2016-06-22 02:08:395506 root_clip2->test_properties()->AddChild(std::move(root_scroll2));
jaydasika6b5a32bf2016-04-22 21:56:365507 root_clip2->test_properties()->force_render_surface = true;
jaydasika89f7b5a2016-06-22 02:08:395508 root_ptr2->test_properties()->AddChild(std::move(root_clip2));
jaydasikabf1875a2016-06-28 03:39:595509 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr2));
danakj74af409e2016-07-01 00:41:485510 host_impl_->active_tree()->BuildPropertyTreesForTesting();
sunxd676696572016-01-07 16:28:305511 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 6,
ccameron8230b68b2014-11-21 19:25:185512 Layer::INVALID_ID);
[email protected]aa043632013-03-25 03:39:425513 host_impl_->active_tree()->DidBecomeActive();
[email protected]94f206c12012-08-25 00:09:145514
[email protected]aa043632013-03-25 03:39:425515 // Scrolling should still work even though we did not draw yet.
tdresser81e84c672016-01-18 23:21:225516 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185517 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:225518 InputHandler::WHEEL)
5519 .thread);
[email protected]94f206c12012-08-25 00:09:145520}
5521
[email protected]aa043632013-03-25 03:39:425522TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:295523 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
jaydasikad7dea632015-11-06 04:40:125524 scroll_layer->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:145525
[email protected]aa043632013-03-25 03:39:425526 // Rotate the root layer 90 degrees counter-clockwise about its center.
5527 gfx::Transform rotate_transform;
5528 rotate_transform.Rotate(-90.0);
jaydasika10d43fc2016-08-18 04:06:045529 host_impl_->active_tree()
5530 ->root_layer_for_testing()
5531 ->test_properties()
5532 ->transform = rotate_transform;
danakj74af409e2016-07-01 00:41:485533 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145534
[email protected]aa043632013-03-25 03:39:425535 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:405536 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365537 DrawFrame();
[email protected]94f206c12012-08-25 00:09:145538
[email protected]aa043632013-03-25 03:39:425539 // Scroll to the right in screen coordinates with a gesture.
5540 gfx::Vector2d gesture_scroll_delta(10, 0);
tdresser81e84c672016-01-18 23:21:225541 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035542 host_impl_
5543 ->ScrollBegin(BeginState(gfx::Point()).get(),
5544 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225545 .thread);
majidvp944a8cd2016-01-12 21:05:185546 host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
5547 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145548
[email protected]aa043632013-03-25 03:39:425549 // The layer should have scrolled down in its local coordinates.
danakj60bc3bc2016-04-09 00:24:485550 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5551 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185552 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5553 gfx::Vector2d(0, gesture_scroll_delta.x())));
[email protected]94f206c12012-08-25 00:09:145554
[email protected]aa043632013-03-25 03:39:425555 // Reset and scroll down with the wheel.
sunxdb7e79432016-03-09 21:13:425556 SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:425557 gfx::Vector2d wheel_scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225558 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185559 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225560 InputHandler::WHEEL)
5561 .thread);
majidvp944a8cd2016-01-12 21:05:185562 host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get());
5563 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145564
[email protected]aa043632013-03-25 03:39:425565 // The layer should have scrolled down in its local coordinates.
5566 scroll_info = host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185567 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5568 wheel_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145569}
5570
[email protected]aa043632013-03-25 03:39:425571TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:295572 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]adeda572014-01-31 00:49:475573 int child_clip_layer_id = 6;
5574 int child_layer_id = 7;
[email protected]aa043632013-03-25 03:39:425575 float child_layer_angle = -20.f;
[email protected]94f206c12012-08-25 00:09:145576
[email protected]aa043632013-03-25 03:39:425577 // Create a child layer that is rotated to a non-axis-aligned angle.
danakj60bc3bc2016-04-09 00:24:485578 std::unique_ptr<LayerImpl> clip_layer =
[email protected]adeda572014-01-31 00:49:475579 LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
danakj60bc3bc2016-04-09 00:24:485580 std::unique_ptr<LayerImpl> child = CreateScrollableLayer(
Dana Jansensc46d3742015-06-18 01:33:145581 child_layer_id, scroll_layer->bounds(), clip_layer.get());
[email protected]aa043632013-03-25 03:39:425582 gfx::Transform rotate_transform;
5583 rotate_transform.Translate(-50.0, -50.0);
5584 rotate_transform.Rotate(child_layer_angle);
5585 rotate_transform.Translate(50.0, 50.0);
jaydasika10d43fc2016-08-18 04:06:045586 clip_layer->test_properties()->transform = rotate_transform;
[email protected]94f206c12012-08-25 00:09:145587
[email protected]aa043632013-03-25 03:39:425588 // Only allow vertical scrolling.
[email protected]adeda572014-01-31 00:49:475589 clip_layer->SetBounds(
5590 gfx::Size(child->bounds().width(), child->bounds().height() / 2));
[email protected]a2566412014-06-05 03:14:205591 // The rotation depends on the layer's transform origin, and the child layer
5592 // is a different size than the clip, so make sure the clip layer's origin
5593 // lines up over the child.
jaydasika38be7a822016-04-21 16:07:065594 clip_layer->test_properties()->transform_origin = gfx::Point3F(
5595 clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f);
[email protected]adeda572014-01-31 00:49:475596 LayerImpl* child_ptr = child.get();
jaydasika89f7b5a2016-06-22 02:08:395597 clip_layer->test_properties()->AddChild(std::move(child));
5598 scroll_layer->test_properties()->AddChild(std::move(clip_layer));
danakj74af409e2016-07-01 00:41:485599 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:145600
[email protected]aa043632013-03-25 03:39:425601 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:405602 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365603 DrawFrame();
[email protected]aa043632013-03-25 03:39:425604 {
[email protected]94f206c12012-08-25 00:09:145605 // Scroll down in screen coordinates with a gesture.
[email protected]aa043632013-03-25 03:39:425606 gfx::Vector2d gesture_scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225607 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035608 host_impl_
5609 ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
5610 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225611 .thread);
majidvp944a8cd2016-01-12 21:05:185612 host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
5613 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145614
[email protected]aa043632013-03-25 03:39:425615 // The child layer should have scrolled down in its local coordinates an
5616 // amount proportional to the angle between it and the input scroll delta.
miletusd799dd22015-03-19 04:23:175617 gfx::Vector2d expected_scroll_delta(
miletus7a221752015-02-04 20:44:495618 0, gesture_scroll_delta.y() *
5619 std::cos(MathUtil::Deg2Rad(child_layer_angle)));
danakj60bc3bc2016-04-09 00:24:485620 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425621 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185622 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
5623 expected_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145624
[email protected]35a99a12013-05-09 23:52:295625 // The root scroll layer should not have scrolled, because the input delta
5626 // was close to the layer's axis of movement.
[email protected]aa043632013-03-25 03:39:425627 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
5628 }
5629 {
5630 // Now reset and scroll the same amount horizontally.
sunxdb7e79432016-03-09 21:13:425631 SetScrollOffsetDelta(child_ptr, gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:425632 gfx::Vector2d gesture_scroll_delta(10, 0);
tdresser81e84c672016-01-18 23:21:225633 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035634 host_impl_
5635 ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
5636 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225637 .thread);
majidvp944a8cd2016-01-12 21:05:185638 host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
5639 host_impl_->ScrollEnd(EndState().get());
[email protected]94f206c12012-08-25 00:09:145640
tdressera3b162b82015-09-29 17:51:435641 // The child layer shouldn't have scrolled.
miletusd799dd22015-03-19 04:23:175642 gfx::Vector2d expected_scroll_delta(
miletus7a221752015-02-04 20:44:495643 0, -gesture_scroll_delta.x() *
5644 std::sin(MathUtil::Deg2Rad(child_layer_angle)));
danakj60bc3bc2016-04-09 00:24:485645 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]aa043632013-03-25 03:39:425646 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185647 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
5648 expected_scroll_delta));
[email protected]aa043632013-03-25 03:39:425649
tdressera3b162b82015-09-29 17:51:435650 // The root scroll layer shouldn't have scrolled.
5651 ExpectNone(*scroll_info.get(), scroll_layer->id());
[email protected]aa043632013-03-25 03:39:425652 }
5653}
5654
tdressere8575f592015-07-03 12:53:135655TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
5656 // When scrolling an element with perspective, the distance scrolled
5657 // depends on the point at which the scroll begins.
5658 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
5659 int child_clip_layer_id = 6;
5660 int child_layer_id = 7;
5661
5662 // Create a child layer that is rotated on its x axis, with perspective.
danakj60bc3bc2016-04-09 00:24:485663 std::unique_ptr<LayerImpl> clip_layer =
tdressere8575f592015-07-03 12:53:135664 LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
danakj60bc3bc2016-04-09 00:24:485665 std::unique_ptr<LayerImpl> child = CreateScrollableLayer(
tdressere8575f592015-07-03 12:53:135666 child_layer_id, scroll_layer->bounds(), clip_layer.get());
5667 LayerImpl* child_ptr = child.get();
5668 gfx::Transform perspective_transform;
5669 perspective_transform.Translate(-50.0, -50.0);
5670 perspective_transform.ApplyPerspectiveDepth(20);
5671 perspective_transform.RotateAboutXAxis(45);
5672 perspective_transform.Translate(50.0, 50.0);
jaydasika10d43fc2016-08-18 04:06:045673 clip_layer->test_properties()->transform = perspective_transform;
tdressere8575f592015-07-03 12:53:135674
5675 clip_layer->SetBounds(gfx::Size(child_ptr->bounds().width() / 2,
5676 child_ptr->bounds().height() / 2));
5677 // The transform depends on the layer's transform origin, and the child layer
5678 // is a different size than the clip, so make sure the clip layer's origin
5679 // lines up over the child.
jaydasika38be7a822016-04-21 16:07:065680 clip_layer->test_properties()->transform_origin = gfx::Point3F(
5681 clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f);
jaydasika89f7b5a2016-06-22 02:08:395682 clip_layer->test_properties()->AddChild(std::move(child));
5683 scroll_layer->test_properties()->AddChild(std::move(clip_layer));
danakj74af409e2016-07-01 00:41:485684 host_impl_->active_tree()->BuildPropertyTreesForTesting();
tdressere8575f592015-07-03 12:53:135685
5686 gfx::Size surface_size(50, 50);
5687 host_impl_->SetViewportSize(surface_size);
5688
danakj60bc3bc2016-04-09 00:24:485689 std::unique_ptr<ScrollAndScaleSet> scroll_info;
tdressere8575f592015-07-03 12:53:135690
5691 gfx::Vector2d gesture_scroll_deltas[4];
5692 gesture_scroll_deltas[0] = gfx::Vector2d(4, 10);
5693 gesture_scroll_deltas[1] = gfx::Vector2d(4, 10);
5694 gesture_scroll_deltas[2] = gfx::Vector2d(10, 0);
5695 gesture_scroll_deltas[3] = gfx::Vector2d(10, 0);
5696
5697 gfx::Vector2d expected_scroll_deltas[4];
5698 // Perspective affects the vertical delta by a different
5699 // amount depending on the vertical position of the |viewport_point|.
5700 expected_scroll_deltas[0] = gfx::Vector2d(2, 8);
5701 expected_scroll_deltas[1] = gfx::Vector2d(1, 4);
5702 // Deltas which start with the same vertical position of the
5703 // |viewport_point| are subject to identical perspective effects.
5704 expected_scroll_deltas[2] = gfx::Vector2d(4, 0);
5705 expected_scroll_deltas[3] = gfx::Vector2d(4, 0);
5706
5707 gfx::Point viewport_point(1, 1);
5708
5709 // Scroll in screen coordinates with a gesture. Each scroll starts
5710 // where the previous scroll ended, but the scroll position is reset
5711 // for each scroll.
5712 for (int i = 0; i < 4; ++i) {
sunxdb7e79432016-03-09 21:13:425713 SetScrollOffsetDelta(child_ptr, gfx::Vector2dF());
tdressere8575f592015-07-03 12:53:135714 DrawFrame();
tdresser81e84c672016-01-18 23:21:225715 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035716 host_impl_
5717 ->ScrollBegin(BeginState(viewport_point).get(),
5718 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225719 .thread);
majidvp944a8cd2016-01-12 21:05:185720 host_impl_->ScrollBy(
5721 UpdateState(viewport_point, gesture_scroll_deltas[i]).get());
tdressere8575f592015-07-03 12:53:135722 viewport_point += gesture_scroll_deltas[i];
majidvp944a8cd2016-01-12 21:05:185723 host_impl_->ScrollEnd(EndState().get());
tdressere8575f592015-07-03 12:53:135724
5725 scroll_info = host_impl_->ProcessScrollDeltas();
5726 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
5727 expected_scroll_deltas[i]));
5728
5729 // The root scroll layer should not have scrolled, because the input delta
5730 // was close to the layer's axis of movement.
5731 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
5732 }
5733}
5734
[email protected]aa043632013-03-25 03:39:425735TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
[email protected]35a99a12013-05-09 23:52:295736 LayerImpl* scroll_layer =
5737 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:425738
5739 // Scale the layer to twice its normal size.
5740 int scale = 2;
5741 gfx::Transform scale_transform;
5742 scale_transform.Scale(scale, scale);
jaydasika10d43fc2016-08-18 04:06:045743 scroll_layer->test_properties()->parent->test_properties()->transform =
5744 scale_transform;
danakj74af409e2016-07-01 00:41:485745 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:425746
5747 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:405748 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:365749 DrawFrame();
[email protected]aa043632013-03-25 03:39:425750
5751 // Scroll down in screen coordinates with a gesture.
5752 gfx::Vector2d scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225753 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035754 host_impl_
5755 ->ScrollBegin(BeginState(gfx::Point()).get(),
5756 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225757 .thread);
majidvp944a8cd2016-01-12 21:05:185758 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
5759 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:425760
5761 // The layer should have scrolled down in its local coordinates, but half the
5762 // amount.
danakj60bc3bc2016-04-09 00:24:485763 std::unique_ptr<ScrollAndScaleSet> scroll_info =
5764 host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185765 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5766 gfx::Vector2d(0, scroll_delta.y() / scale)));
[email protected]aa043632013-03-25 03:39:425767
5768 // Reset and scroll down with the wheel.
sunxdb7e79432016-03-09 21:13:425769 SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:425770 gfx::Vector2d wheel_scroll_delta(0, 10);
tdresser81e84c672016-01-18 23:21:225771 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:185772 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:225773 InputHandler::WHEEL)
5774 .thread);
majidvp944a8cd2016-01-12 21:05:185775 host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get());
5776 host_impl_->ScrollEnd(EndState().get());
[email protected]aa043632013-03-25 03:39:425777
lanweid17d0742014-12-01 18:58:525778 // It should apply the scale factor to the scroll delta for the wheel event.
[email protected]aa043632013-03-25 03:39:425779 scroll_info = host_impl_->ProcessScrollDeltas();
tdresser99977952015-07-02 19:49:185780 EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
5781 wheel_scroll_delta));
[email protected]94f206c12012-08-25 00:09:145782}
5783
[email protected]a6d2ffe822014-08-21 10:11:395784TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
5785 int width = 332;
5786 int height = 20;
5787 int scale = 3;
5788 SetupScrollAndContentsLayers(gfx::Size(width, height));
[email protected]587941d2014-08-22 01:40:015789 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
5790 gfx::Size(width * scale - 1, height * scale));
danakj74af409e2016-07-01 00:41:485791 host_impl_->active_tree()->BuildPropertyTreesForTesting();
5792
ajuma1d48e012015-09-25 22:24:165793 host_impl_->active_tree()->SetDeviceScaleFactor(scale);
aelias58eec0812014-12-04 01:04:405794 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]a6d2ffe822014-08-21 10:11:395795
5796 LayerImpl* inner_viewport_scroll_layer =
5797 host_impl_->active_tree()->InnerViewportScrollLayer();
miletusf57925d2014-10-01 19:38:135798 EXPECT_EQ(gfx::ScrollOffset(0, 0),
[email protected]a6d2ffe822014-08-21 10:11:395799 inner_viewport_scroll_layer->MaxScrollOffset());
5800}
5801
danakjdd74e512015-09-21 23:07:595802class TestInputHandlerClient : public InputHandlerClient {
[email protected]0a0d1422013-05-02 09:14:525803 public:
danakjdd74e512015-09-21 23:07:595804 TestInputHandlerClient()
[email protected]68fe60f2014-02-12 13:49:115805 : page_scale_factor_(0.f),
5806 min_page_scale_factor_(-1.f),
danakje9f830c2015-09-09 21:36:165807 max_page_scale_factor_(-1.f) {}
danakjdd74e512015-09-21 23:07:595808 ~TestInputHandlerClient() override {}
[email protected]20d2b742013-09-26 05:41:345809
danakjdd74e512015-09-21 23:07:595810 // InputHandlerClient implementation.
5811 void WillShutdown() override {}
5812 void Animate(base::TimeTicks time) override {}
5813 void MainThreadHasStoppedFlinging() override {}
5814 void ReconcileElasticOverscrollAndRootScroll() override {}
5815 void UpdateRootLayerStateForSynchronousInputHandler(
5816 const gfx::ScrollOffset& total_scroll_offset,
5817 const gfx::ScrollOffset& max_scroll_offset,
5818 const gfx::SizeF& scrollable_size,
5819 float page_scale_factor,
5820 float min_page_scale_factor,
5821 float max_page_scale_factor) override {
[email protected]ec2322e2014-05-15 16:32:005822 DCHECK(total_scroll_offset.x() <= max_scroll_offset.x());
5823 DCHECK(total_scroll_offset.y() <= max_scroll_offset.y());
5824 last_set_scroll_offset_ = total_scroll_offset;
5825 max_scroll_offset_ = max_scroll_offset;
5826 scrollable_size_ = scrollable_size;
[email protected]20d2b742013-09-26 05:41:345827 page_scale_factor_ = page_scale_factor;
[email protected]68fe60f2014-02-12 13:49:115828 min_page_scale_factor_ = min_page_scale_factor;
5829 max_page_scale_factor_ = max_page_scale_factor;
[email protected]20d2b742013-09-26 05:41:345830 }
5831
miletusf57925d2014-10-01 19:38:135832 gfx::ScrollOffset last_set_scroll_offset() {
[email protected]0a0d1422013-05-02 09:14:525833 return last_set_scroll_offset_;
5834 }
5835
miletusf57925d2014-10-01 19:38:135836 gfx::ScrollOffset max_scroll_offset() const {
[email protected]20d2b742013-09-26 05:41:345837 return max_scroll_offset_;
5838 }
5839
5840 gfx::SizeF scrollable_size() const {
5841 return scrollable_size_;
5842 }
5843
5844 float page_scale_factor() const {
5845 return page_scale_factor_;
5846 }
5847
[email protected]68fe60f2014-02-12 13:49:115848 float min_page_scale_factor() const {
5849 return min_page_scale_factor_;
5850 }
5851
5852 float max_page_scale_factor() const {
5853 return max_page_scale_factor_;
5854 }
5855
[email protected]0a0d1422013-05-02 09:14:525856 private:
miletusf57925d2014-10-01 19:38:135857 gfx::ScrollOffset last_set_scroll_offset_;
miletusf57925d2014-10-01 19:38:135858 gfx::ScrollOffset max_scroll_offset_;
[email protected]20d2b742013-09-26 05:41:345859 gfx::SizeF scrollable_size_;
5860 float page_scale_factor_;
[email protected]68fe60f2014-02-12 13:49:115861 float min_page_scale_factor_;
5862 float max_page_scale_factor_;
[email protected]0a0d1422013-05-02 09:14:525863};
5864
5865TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
danakjdd74e512015-09-21 23:07:595866 TestInputHandlerClient scroll_watcher;
[email protected]20d2b742013-09-26 05:41:345867 host_impl_->SetViewportSize(gfx::Size(10, 20));
[email protected]35a99a12013-05-09 23:52:295868 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
jaydasikaf419bf72016-06-15 10:21:215869 LayerImpl* clip_layer =
5870 scroll_layer->test_properties()->parent->test_properties()->parent;
[email protected]adeda572014-01-31 00:49:475871 clip_layer->SetBounds(gfx::Size(10, 20));
danakj74af409e2016-07-01 00:41:485872 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]0a0d1422013-05-02 09:14:525873
danakjdd74e512015-09-21 23:07:595874 host_impl_->BindToClient(&scroll_watcher);
5875
[email protected]35a99a12013-05-09 23:52:295876 gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
sunxdb7e79432016-03-09 21:13:425877 scroll_layer->layer_tree_impl()
5878 ->property_trees()
5879 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
5880 gfx::ScrollOffset());
5881 SetScrollOffsetDelta(scroll_layer, initial_scroll_delta);
danakjdd74e512015-09-21 23:07:595882
5883 EXPECT_EQ(gfx::ScrollOffset(), scroll_watcher.last_set_scroll_offset());
5884
5885 // Requesting an update results in the current scroll offset being set.
5886 host_impl_->RequestUpdateForSynchronousInputHandler();
5887 EXPECT_EQ(gfx::ScrollOffset(initial_scroll_delta),
5888 scroll_watcher.last_set_scroll_offset());
[email protected]0a0d1422013-05-02 09:14:525889
[email protected]68fe60f2014-02-12 13:49:115890 // Setting the delegate results in the scrollable_size, max_scroll_offset,
5891 // page_scale_factor and {min|max}_page_scale_factor being set.
danakjdd74e512015-09-21 23:07:595892 EXPECT_EQ(gfx::SizeF(100, 100), scroll_watcher.scrollable_size());
5893 EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_watcher.max_scroll_offset());
5894 EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
5895 EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
5896 EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
[email protected]20d2b742013-09-26 05:41:345897
danakja342d6f3b2015-09-17 22:25:485898 // Put a page scale on the tree.
aelias58eec0812014-12-04 01:04:405899 host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 0.5f, 4.f);
danakjdd74e512015-09-21 23:07:595900 EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
5901 EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
5902 EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
danakja342d6f3b2015-09-17 22:25:485903 // Activation will update the delegate.
5904 host_impl_->ActivateSyncTree();
danakjdd74e512015-09-21 23:07:595905 EXPECT_EQ(2.f, scroll_watcher.page_scale_factor());
5906 EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
5907 EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
danakja342d6f3b2015-09-17 22:25:485908
danakja342d6f3b2015-09-17 22:25:485909 // Animating page scale can change the root offset, so it should update the
danakj4923440542015-10-29 19:34:535910 // delegate. Also resets the page scale to 1 for the rest of the test.
5911 host_impl_->LayerTreeHostImpl::StartPageScaleAnimation(
5912 gfx::Vector2d(0, 0), false, 1.f, base::TimeDelta());
danakja342d6f3b2015-09-17 22:25:485913 host_impl_->Animate();
danakjdd74e512015-09-21 23:07:595914 EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
5915 EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
5916 EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
[email protected]20d2b742013-09-26 05:41:345917
[email protected]ec2322e2014-05-15 16:32:005918 // The pinch gesture doesn't put the delegate into a state where the scroll
5919 // offset is outside of the scroll range. (this is verified by DCHECKs in the
5920 // delegate).
majidvp944a8cd2016-01-12 21:05:185921 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:035922 InputHandler::TOUCHSCREEN);
[email protected]ec2322e2014-05-15 16:32:005923 host_impl_->PinchGestureBegin();
5924 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
5925 host_impl_->PinchGestureUpdate(.5f, gfx::Point());
5926 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:185927 host_impl_->ScrollEnd(EndState().get());
[email protected]ec2322e2014-05-15 16:32:005928
danakj0481b572015-09-10 01:18:015929 // Scrolling should be relative to the offset as given by the delegate.
[email protected]35a99a12013-05-09 23:52:295930 gfx::Vector2dF scroll_delta(0.f, 10.f);
miletusf57925d2014-10-01 19:38:135931 gfx::ScrollOffset current_offset(7.f, 8.f);
[email protected]0a0d1422013-05-02 09:14:525932
tdresser81e84c672016-01-18 23:21:225933 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:035934 host_impl_
5935 ->ScrollBegin(BeginState(gfx::Point()).get(),
5936 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:225937 .thread);
danakjdd74e512015-09-21 23:07:595938 host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
[email protected]0a0d1422013-05-02 09:14:525939
majidvp944a8cd2016-01-12 21:05:185940 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
miletusf57925d2014-10-01 19:38:135941 EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta),
danakjdd74e512015-09-21 23:07:595942 scroll_watcher.last_set_scroll_offset());
[email protected]0a0d1422013-05-02 09:14:525943
miletusf57925d2014-10-01 19:38:135944 current_offset = gfx::ScrollOffset(42.f, 41.f);
danakjdd74e512015-09-21 23:07:595945 host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
majidvp944a8cd2016-01-12 21:05:185946 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
miletusf57925d2014-10-01 19:38:135947 EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta),
danakjdd74e512015-09-21 23:07:595948 scroll_watcher.last_set_scroll_offset());
majidvp944a8cd2016-01-12 21:05:185949 host_impl_->ScrollEnd(EndState().get());
danakjdd74e512015-09-21 23:07:595950 host_impl_->SetSynchronousInputHandlerRootScrollOffset(gfx::ScrollOffset());
[email protected]0a0d1422013-05-02 09:14:525951
[email protected]7d1b07e2013-10-01 17:31:305952 // Forces a full tree synchronization and ensures that the scroll delegate
5953 // sees the correct size of the new tree.
5954 gfx::Size new_size(42, 24);
5955 host_impl_->CreatePendingTree();
bokan0c33a092015-07-29 18:27:565956 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
[email protected]7d1b07e2013-10-01 17:31:305957 CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size);
danakj74af409e2016-07-01 00:41:485958 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
[email protected]fc20d142014-07-01 00:49:155959 host_impl_->ActivateSyncTree();
danakjddaec912015-09-25 19:38:405960 EXPECT_EQ(gfx::SizeF(new_size), scroll_watcher.scrollable_size());
[email protected]7d1b07e2013-10-01 17:31:305961
danakjdd74e512015-09-21 23:07:595962 // Tear down the LayerTreeHostImpl before the InputHandlerClient.
danakjee6547a22016-07-01 20:41:505963 host_impl_->ReleaseOutputSurface();
5964 host_impl_ = nullptr;
[email protected]0a0d1422013-05-02 09:14:525965}
5966
[email protected]b4a3d462014-06-17 09:17:085967void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) {
5968 const gfx::Transform target_space_transform =
5969 layer->draw_properties().target_space_transform;
5970 EXPECT_TRUE(target_space_transform.IsScaleOrTranslation());
5971 gfx::Point translated_point;
5972 target_space_transform.TransformPoint(&translated_point);
5973 gfx::Point expected_point = gfx::Point() - ToRoundedVector2d(scroll_delta);
5974 EXPECT_EQ(expected_point.ToString(), translated_point.ToString());
5975}
5976
5977TEST_F(LayerTreeHostImplTest,
5978 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) {
[email protected]b4a3d462014-06-17 09:17:085979 host_impl_->SetViewportSize(gfx::Size(10, 20));
5980 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
jaydasikaf419bf72016-06-15 10:21:215981 LayerImpl* clip_layer =
5982 scroll_layer->test_properties()->parent->test_properties()->parent;
[email protected]b4a3d462014-06-17 09:17:085983 clip_layer->SetBounds(gfx::Size(10, 20));
jaydasikad7dea632015-11-06 04:40:125984 scroll_layer->SetDrawsContent(true);
[email protected]b4a3d462014-06-17 09:17:085985
5986 // Draw first frame to clear any pending draws and check scroll.
5987 DrawFrame();
5988 CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f));
5989 EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
5990
5991 // Set external scroll delta on delegate and notify LayerTreeHost.
miletusf57925d2014-10-01 19:38:135992 gfx::ScrollOffset scroll_offset(10.f, 10.f);
danakjdd74e512015-09-21 23:07:595993 host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
danakj74af409e2016-07-01 00:41:485994 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]b4a3d462014-06-17 09:17:085995
5996 // Check scroll delta reflected in layer.
boliu7d5dbab2014-10-10 20:05:475997 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:485998 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:455999 host_impl_->DrawLayers(&frame);
boliu7d5dbab2014-10-10 20:05:476000 host_impl_->DidDrawAllLayers(frame);
6001 EXPECT_FALSE(frame.has_no_damage);
miletusf57925d2014-10-01 19:38:136002 CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset));
[email protected]b4a3d462014-06-17 09:17:086003}
6004
[email protected]a2b5ded2013-05-20 21:32:536005TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
ccameron36d091f2014-11-07 03:18:506006 InputHandlerScrollResult scroll_result;
[email protected]a2b5ded2013-05-20 21:32:536007 SetupScrollAndContentsLayers(gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:486008 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6009
[email protected]a2b5ded2013-05-20 21:32:536010 host_impl_->SetViewportSize(gfx::Size(50, 50));
aelias58eec0812014-12-04 01:04:406011 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:366012 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:536013 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536014
6015 // In-bounds scrolling does not affect overscroll.
tdresser81e84c672016-01-18 23:21:226016 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186017 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:226018 InputHandler::WHEEL)
6019 .thread);
majidvp944a8cd2016-01-12 21:05:186020 scroll_result = host_impl_->ScrollBy(
6021 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
ccameron36d091f2014-11-07 03:18:506022 EXPECT_TRUE(scroll_result.did_scroll);
6023 EXPECT_FALSE(scroll_result.did_overscroll_root);
6024 EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536025 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536026
6027 // Overscroll events are reflected immediately.
majidvp944a8cd2016-01-12 21:05:186028 scroll_result = host_impl_->ScrollBy(
6029 UpdateState(gfx::Point(), gfx::Vector2d(0, 50)).get());
ccameron36d091f2014-11-07 03:18:506030 EXPECT_TRUE(scroll_result.did_scroll);
6031 EXPECT_TRUE(scroll_result.did_overscroll_root);
6032 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536033 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506034 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6035 host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536036
[email protected]2bd503f2013-07-23 05:35:296037 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
majidvp944a8cd2016-01-12 21:05:186038 scroll_result = host_impl_->ScrollBy(
6039 UpdateState(gfx::Point(), gfx::Vector2d(0, -50)).get());
ccameron36d091f2014-11-07 03:18:506040 EXPECT_TRUE(scroll_result.did_scroll);
6041 EXPECT_FALSE(scroll_result.did_overscroll_root);
6042 EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536043 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506044 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6045 host_impl_->accumulated_root_overscroll());
6046
majidvp944a8cd2016-01-12 21:05:186047 scroll_result = host_impl_->ScrollBy(
6048 UpdateState(gfx::Point(), gfx::Vector2d(0, -10)).get());
ccameron36d091f2014-11-07 03:18:506049 EXPECT_FALSE(scroll_result.did_scroll);
6050 EXPECT_TRUE(scroll_result.did_overscroll_root);
6051 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536052 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506053 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6054 host_impl_->accumulated_root_overscroll());
6055
majidvp944a8cd2016-01-12 21:05:186056 scroll_result = host_impl_->ScrollBy(
6057 UpdateState(gfx::Point(), gfx::Vector2d(10, 0)).get());
ccameron36d091f2014-11-07 03:18:506058 EXPECT_TRUE(scroll_result.did_scroll);
6059 EXPECT_FALSE(scroll_result.did_overscroll_root);
6060 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296061 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506062 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6063 host_impl_->accumulated_root_overscroll());
6064
majidvp944a8cd2016-01-12 21:05:186065 scroll_result = host_impl_->ScrollBy(
6066 UpdateState(gfx::Point(), gfx::Vector2d(-15, 0)).get());
ccameron36d091f2014-11-07 03:18:506067 EXPECT_TRUE(scroll_result.did_scroll);
6068 EXPECT_TRUE(scroll_result.did_overscroll_root);
6069 EXPECT_EQ(gfx::Vector2dF(-5, 0), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296070 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506071 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6072 host_impl_->accumulated_root_overscroll());
6073
majidvp944a8cd2016-01-12 21:05:186074 scroll_result = host_impl_->ScrollBy(
6075 UpdateState(gfx::Point(), gfx::Vector2d(0, 60)).get());
ccameron36d091f2014-11-07 03:18:506076 EXPECT_TRUE(scroll_result.did_scroll);
6077 EXPECT_TRUE(scroll_result.did_overscroll_root);
6078 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296079 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506080 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6081 host_impl_->accumulated_root_overscroll());
6082
majidvp944a8cd2016-01-12 21:05:186083 scroll_result = host_impl_->ScrollBy(
6084 UpdateState(gfx::Point(), gfx::Vector2d(10, -60)).get());
ccameron36d091f2014-11-07 03:18:506085 EXPECT_TRUE(scroll_result.did_scroll);
6086 EXPECT_TRUE(scroll_result.did_overscroll_root);
6087 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
[email protected]2bd503f2013-07-23 05:35:296088 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506089 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6090 host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:536091
6092 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
6093 // as no scroll occurs.
majidvp944a8cd2016-01-12 21:05:186094 scroll_result = host_impl_->ScrollBy(
6095 UpdateState(gfx::Point(), gfx::Vector2d(0, -20)).get());
ccameron36d091f2014-11-07 03:18:506096 EXPECT_FALSE(scroll_result.did_scroll);
6097 EXPECT_TRUE(scroll_result.did_overscroll_root);
6098 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536099 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506100 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6101 host_impl_->accumulated_root_overscroll());
6102
majidvp944a8cd2016-01-12 21:05:186103 scroll_result = host_impl_->ScrollBy(
6104 UpdateState(gfx::Point(), gfx::Vector2d(0, -20)).get());
ccameron36d091f2014-11-07 03:18:506105 EXPECT_FALSE(scroll_result.did_scroll);
6106 EXPECT_TRUE(scroll_result.did_overscroll_root);
6107 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536108 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506109 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6110 host_impl_->accumulated_root_overscroll());
6111
[email protected]a2b5ded2013-05-20 21:32:536112 // Overscroll resets on valid scroll.
majidvp944a8cd2016-01-12 21:05:186113 scroll_result = host_impl_->ScrollBy(
6114 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
ccameron36d091f2014-11-07 03:18:506115 EXPECT_TRUE(scroll_result.did_scroll);
6116 EXPECT_FALSE(scroll_result.did_overscroll_root);
6117 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536118 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506119 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6120 host_impl_->accumulated_root_overscroll());
6121
majidvp944a8cd2016-01-12 21:05:186122 scroll_result = host_impl_->ScrollBy(
6123 UpdateState(gfx::Point(), gfx::Vector2d(0, -20)).get());
ccameron36d091f2014-11-07 03:18:506124 EXPECT_TRUE(scroll_result.did_scroll);
6125 EXPECT_TRUE(scroll_result.did_overscroll_root);
6126 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
[email protected]a2b5ded2013-05-20 21:32:536127 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
ccameron36d091f2014-11-07 03:18:506128 EXPECT_EQ(scroll_result.accumulated_root_overscroll,
6129 host_impl_->accumulated_root_overscroll());
6130
majidvp944a8cd2016-01-12 21:05:186131 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536132}
6133
6134
6135TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
6136 // Scroll child layers beyond their maximum scroll range and make sure root
6137 // overscroll does not accumulate.
tdresserdeeba3f2015-07-10 19:26:586138 InputHandlerScrollResult scroll_result;
[email protected]a2b5ded2013-05-20 21:32:536139 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:486140 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:476141 LayerImpl::Create(host_impl_->active_tree(), 4);
jaydasika6b5a32bf2016-04-22 21:56:366142 root_clip->test_properties()->force_render_surface = true;
awoloszyne83f28c2014-12-22 15:40:006143
danakj60bc3bc2016-04-09 00:24:486144 std::unique_ptr<LayerImpl> root =
[email protected]adeda572014-01-31 00:49:476145 CreateScrollableLayer(1, surface_size, root_clip.get());
[email protected]a2b5ded2013-05-20 21:32:536146
danakj60bc3bc2016-04-09 00:24:486147 std::unique_ptr<LayerImpl> grand_child =
[email protected]adeda572014-01-31 00:49:476148 CreateScrollableLayer(3, surface_size, root_clip.get());
[email protected]a2b5ded2013-05-20 21:32:536149
danakj60bc3bc2016-04-09 00:24:486150 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:476151 CreateScrollableLayer(2, surface_size, root_clip.get());
6152 LayerImpl* grand_child_layer = grand_child.get();
jaydasika89f7b5a2016-06-22 02:08:396153 child->test_properties()->AddChild(std::move(grand_child));
[email protected]a2b5ded2013-05-20 21:32:536154
[email protected]adeda572014-01-31 00:49:476155 LayerImpl* child_layer = child.get();
jaydasika89f7b5a2016-06-22 02:08:396156 root->test_properties()->AddChild(std::move(child));
6157 root_clip->test_properties()->AddChild(std::move(root));
danakj74af409e2016-07-01 00:41:486158 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip));
6159 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6160 host_impl_->active_tree()->DidBecomeActive();
6161
sunxdb7e79432016-03-09 21:13:426162 child_layer->layer_tree_impl()
6163 ->property_trees()
6164 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
6165 gfx::ScrollOffset(0, 3));
6166 grand_child_layer->layer_tree_impl()
6167 ->property_trees()
6168 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
6169 gfx::ScrollOffset(0, 2));
danakj74af409e2016-07-01 00:41:486170
[email protected]a2b5ded2013-05-20 21:32:536171 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:366172 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:536173 {
6174 gfx::Vector2d scroll_delta(0, -10);
tdresser81e84c672016-01-18 23:21:226175 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186176 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:226177 InputHandler::NON_BUBBLING_GESTURE)
6178 .thread);
majidvp944a8cd2016-01-12 21:05:186179 scroll_result =
6180 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586181 EXPECT_TRUE(scroll_result.did_scroll);
6182 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536183 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186184 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536185
[email protected]a2b5ded2013-05-20 21:32:536186 // The next time we scroll we should only scroll the parent, but overscroll
6187 // should still not reach the root layer.
6188 scroll_delta = gfx::Vector2d(0, -30);
tdresser81e84c672016-01-18 23:21:226189 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186190 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:226191 InputHandler::NON_BUBBLING_GESTURE)
6192 .thread);
[email protected]adeda572014-01-31 00:49:476193 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
[email protected]a2b5ded2013-05-20 21:32:536194 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186195 scroll_result =
6196 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586197 EXPECT_TRUE(scroll_result.did_scroll);
6198 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]adeda572014-01-31 00:49:476199 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_layer);
[email protected]a2b5ded2013-05-20 21:32:536200 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186201 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536202
6203 // After scrolling the parent, another scroll on the opposite direction
[email protected]635b0e92014-04-02 21:48:016204 // should scroll the child.
[email protected]a2b5ded2013-05-20 21:32:536205 scroll_delta = gfx::Vector2d(0, 70);
tdresser81e84c672016-01-18 23:21:226206 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186207 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:226208 InputHandler::NON_BUBBLING_GESTURE)
6209 .thread);
[email protected]adeda572014-01-31 00:49:476210 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
majidvp944a8cd2016-01-12 21:05:186211 scroll_result =
6212 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586213 EXPECT_TRUE(scroll_result.did_scroll);
6214 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]adeda572014-01-31 00:49:476215 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
[email protected]a2b5ded2013-05-20 21:32:536216 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186217 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536218 }
6219}
6220
6221TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
6222 // When we try to scroll a non-scrollable child layer, the scroll delta
6223 // should be applied to one of its ancestors if possible. Overscroll should
6224 // be reflected only when it has bubbled up to the root scrolling layer.
tdresserdeeba3f2015-07-10 19:26:586225 InputHandlerScrollResult scroll_result;
bokan1f86d8f2015-07-30 16:08:546226 SetupScrollAndContentsLayers(gfx::Size(20, 20));
danakj74af409e2016-07-01 00:41:486227 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6228
[email protected]ce2e8112013-11-28 07:44:366229 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:536230 {
6231 gfx::Vector2d scroll_delta(0, 8);
tdresser81e84c672016-01-18 23:21:226232 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186233 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
tdresser81e84c672016-01-18 23:21:226234 InputHandler::WHEEL)
6235 .thread);
majidvp944a8cd2016-01-12 21:05:186236 scroll_result =
6237 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586238 EXPECT_TRUE(scroll_result.did_scroll);
6239 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536240 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186241 scroll_result =
6242 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586243 EXPECT_TRUE(scroll_result.did_scroll);
6244 EXPECT_TRUE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536245 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186246 scroll_result =
6247 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
tdresserdeeba3f2015-07-10 19:26:586248 EXPECT_FALSE(scroll_result.did_scroll);
6249 EXPECT_TRUE(scroll_result.did_overscroll_root);
[email protected]a2b5ded2013-05-20 21:32:536250 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186251 host_impl_->ScrollEnd(EndState().get());
[email protected]a2b5ded2013-05-20 21:32:536252 }
6253}
6254
[email protected]34d43432013-09-26 20:04:106255TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
tdresserdeeba3f2015-07-10 19:26:586256 InputHandlerScrollResult scroll_result;
weiliangc8f4ef0d2015-11-27 00:15:556257 LayerTreeSettings settings = DefaultSettings();
[email protected]ce2e8112013-11-28 07:44:366258 CreateHostImpl(settings, CreateOutputSurface());
[email protected]34d43432013-09-26 20:04:106259
[email protected]adeda572014-01-31 00:49:476260 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50));
jaydasikaf419bf72016-06-15 10:21:216261 LayerImpl* clip_layer =
6262 scroll_layer->test_properties()->parent->test_properties()->parent;
danakj74af409e2016-07-01 00:41:486263
[email protected]adeda572014-01-31 00:49:476264 clip_layer->SetBounds(gfx::Size(50, 50));
danakj74af409e2016-07-01 00:41:486265 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6266
[email protected]34d43432013-09-26 20:04:106267 host_impl_->SetViewportSize(gfx::Size(50, 50));
aelias58eec0812014-12-04 01:04:406268 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:366269 DrawFrame();
[email protected]34d43432013-09-26 20:04:106270 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
[email protected]34d43432013-09-26 20:04:106271
6272 // Even though the layer can't scroll the overscroll still happens.
tdresser81e84c672016-01-18 23:21:226273 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186274 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:226275 InputHandler::WHEEL)
6276 .thread);
majidvp944a8cd2016-01-12 21:05:186277 scroll_result = host_impl_->ScrollBy(
6278 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
tdresserdeeba3f2015-07-10 19:26:586279 EXPECT_FALSE(scroll_result.did_scroll);
6280 EXPECT_TRUE(scroll_result.did_overscroll_root);
[email protected]34d43432013-09-26 20:04:106281 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
[email protected]34d43432013-09-26 20:04:106282}
[email protected]a2b5ded2013-05-20 21:32:536283
[email protected]5b8a865c2014-04-03 00:35:516284TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
tdresserdeeba3f2015-07-10 19:26:586285 InputHandlerScrollResult scroll_result;
bokan1f86d8f2015-07-30 16:08:546286 SetupScrollAndContentsLayers(gfx::Size(200, 200));
danakj74af409e2016-07-01 00:41:486287 host_impl_->active_tree()->BuildPropertyTreesForTesting();
awoloszyne83f28c2014-12-22 15:40:006288
[email protected]485a42dc2014-03-26 22:44:346289 DrawFrame();
6290 {
[email protected]5b8a865c2014-04-03 00:35:516291 // Edge glow effect should be applicable only upon reaching Edges
6292 // of the content. unnecessary glow effect calls shouldn't be
6293 // called while scrolling up without reaching the edge of the content.
tdresser81e84c672016-01-18 23:21:226294 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186295 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
tdresser81e84c672016-01-18 23:21:226296 InputHandler::WHEEL)
6297 .thread);
majidvp944a8cd2016-01-12 21:05:186298 scroll_result = host_impl_->ScrollBy(
6299 UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
tdresserdeeba3f2015-07-10 19:26:586300 EXPECT_TRUE(scroll_result.did_scroll);
6301 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]485a42dc2014-03-26 22:44:346302 EXPECT_EQ(gfx::Vector2dF().ToString(),
6303 host_impl_->accumulated_root_overscroll().ToString());
majidvp944a8cd2016-01-12 21:05:186304 scroll_result = host_impl_->ScrollBy(
6305 UpdateState(gfx::Point(), gfx::Vector2dF(0, -2.30f)).get());
tdresserdeeba3f2015-07-10 19:26:586306 EXPECT_TRUE(scroll_result.did_scroll);
6307 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]485a42dc2014-03-26 22:44:346308 EXPECT_EQ(gfx::Vector2dF().ToString(),
6309 host_impl_->accumulated_root_overscroll().ToString());
majidvp944a8cd2016-01-12 21:05:186310 host_impl_->ScrollEnd(EndState().get());
[email protected]5b8a865c2014-04-03 00:35:516311 // unusedrootDelta should be subtracted from applied delta so that
6312 // unwanted glow effect calls are not called.
tdresser81e84c672016-01-18 23:21:226313 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
6314 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6315 InputHandler::NON_BUBBLING_GESTURE)
6316 .thread);
6317 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
6318 host_impl_->FlingScrollBegin().thread);
majidvp944a8cd2016-01-12 21:05:186319 scroll_result = host_impl_->ScrollBy(
6320 UpdateState(gfx::Point(), gfx::Vector2dF(0, 20)).get());
tdresserdeeba3f2015-07-10 19:26:586321 EXPECT_TRUE(scroll_result.did_scroll);
6322 EXPECT_TRUE(scroll_result.did_overscroll_root);
jaydasikad7dea632015-11-06 04:40:126323 EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
6324 host_impl_->accumulated_root_overscroll());
[email protected]5b8a865c2014-04-03 00:35:516325
majidvp944a8cd2016-01-12 21:05:186326 scroll_result = host_impl_->ScrollBy(
6327 UpdateState(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f)).get());
tdresserdeeba3f2015-07-10 19:26:586328 EXPECT_FALSE(scroll_result.did_scroll);
6329 EXPECT_FALSE(scroll_result.did_overscroll_root);
jaydasikad7dea632015-11-06 04:40:126330 EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
6331 host_impl_->accumulated_root_overscroll());
majidvp944a8cd2016-01-12 21:05:186332 host_impl_->ScrollEnd(EndState().get());
[email protected]9328ede2014-04-04 07:45:526333 // TestCase to check kEpsilon, which prevents minute values to trigger
6334 // gloweffect without reaching edge.
tdresser81e84c672016-01-18 23:21:226335 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:186336 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
tdresser81e84c672016-01-18 23:21:226337 InputHandler::WHEEL)
6338 .thread);
majidvp944a8cd2016-01-12 21:05:186339 scroll_result = host_impl_->ScrollBy(
6340 UpdateState(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f)).get());
tdresserdeeba3f2015-07-10 19:26:586341 EXPECT_FALSE(scroll_result.did_scroll);
6342 EXPECT_FALSE(scroll_result.did_overscroll_root);
[email protected]9328ede2014-04-04 07:45:526343 EXPECT_EQ(gfx::Vector2dF().ToString(),
6344 host_impl_->accumulated_root_overscroll().ToString());
majidvp944a8cd2016-01-12 21:05:186345 host_impl_->ScrollEnd(EndState().get());
[email protected]485a42dc2014-03-26 22:44:346346 }
6347}
6348
eseckler59eeb022016-07-05 10:45:176349TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) {
6350 InputHandlerScrollResult scroll_result;
6351 LayerTreeSettings settings = DefaultSettings();
6352 CreateHostImpl(settings, CreateOutputSurface());
6353
6354 const gfx::Size content_size(50, 50);
6355 const gfx::Size viewport_size(50, 50);
6356 CreateBasicVirtualViewportLayers(viewport_size, content_size);
6357
6358 LayerImpl* scroll_layer =
6359 host_impl_->active_tree()->InnerViewportScrollLayer();
6360 scroll_layer->set_main_thread_scrolling_reasons(
6361 MainThreadScrollingReason::kThreadedScrollingDisabled);
6362 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6363
6364 DrawFrame();
6365
6366 // Overscroll initiated outside layers will be handled by the main thread.
6367 EXPECT_EQ(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6368 gfx::PointF(0, 60)));
6369 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD,
6370 host_impl_
6371 ->ScrollBegin(BeginState(gfx::Point(0, 60)).get(),
6372 InputHandler::WHEEL)
6373 .thread);
6374
6375 // Overscroll initiated inside layers will be handled by the main thread.
6376 EXPECT_NE(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6377 gfx::PointF(0, 0)));
6378 EXPECT_EQ(
6379 InputHandler::SCROLL_ON_MAIN_THREAD,
6380 host_impl_
6381 ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::WHEEL)
6382 .thread);
6383}
6384
bokanbc115b42016-08-22 13:46:326385// Test that scrolls chain correctly when a child scroller on the page (e.g. a
6386// scrolling div) is set as the outer viewport. This happens in the
6387// rootScroller proposal.
6388TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
6389 const gfx::Size content_size(200, 200);
6390 const gfx::Size viewport_size(100, 100);
6391
6392 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
6393
6394 LayerImpl* content_layer =
6395 CreateBasicVirtualViewportLayers(viewport_size, content_size);
6396 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
6397 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
6398
6399 LayerImpl* scroll_layer = nullptr;
6400 LayerImpl* child_scroll_layer = nullptr;
6401
6402 // Initialization: Add two nested scrolling layers, simulating a scrolling div
6403 // with another scrolling div inside it. Set the outer "div" to be the outer
6404 // viewport.
6405 {
6406 std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
6407 clip->SetBounds(content_size);
6408 clip->SetPosition(gfx::PointF());
6409
6410 std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
6411 scroll->SetBounds(gfx::Size(400, 400));
6412 scroll->SetScrollClipLayer(clip->id());
6413 scroll->SetDrawsContent(true);
6414
6415 std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 12);
6416 clip2->SetBounds(gfx::Size(300, 300));
6417 clip2->SetPosition(gfx::PointF());
6418 clip2->SetDrawsContent(true);
6419
6420 std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13);
6421 scroll2->SetBounds(gfx::Size(500, 500));
6422 scroll2->SetScrollClipLayer(clip2->id());
6423 scroll2->SetDrawsContent(true);
6424
6425 scroll_layer = scroll.get();
6426 child_scroll_layer = scroll2.get();
6427
6428 clip2->test_properties()->AddChild(std::move(scroll2));
6429 scroll->test_properties()->AddChild(std::move(clip2));
6430
6431 clip->test_properties()->AddChild(std::move(scroll));
6432 content_layer->test_properties()->AddChild(std::move(clip));
6433 layer_tree_impl->SetViewportLayersFromIds(
6434 Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(),
6435 inner_scroll_layer->id(), scroll_layer->id());
6436 layer_tree_impl->BuildPropertyTreesForTesting();
6437 }
6438
6439 // Scroll should target the nested scrolling layer in the content and then
6440 // chain to the parent scrolling layer which is now set as the outer
6441 // viewport. The original outer viewport layer shouldn't get any scroll here.
6442 {
6443 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6444 InputHandler::TOUCHSCREEN);
6445 host_impl_->ScrollBy(
6446 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
6447 host_impl_->ScrollEnd(EndState().get());
6448
6449 EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
6450 child_scroll_layer->CurrentScrollOffset());
6451
6452 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6453 InputHandler::TOUCHSCREEN);
6454 host_impl_->ScrollBy(
6455 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
6456 host_impl_->ScrollEnd(EndState().get());
6457
6458 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
6459 outer_scroll_layer->CurrentScrollOffset());
6460
6461 EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
6462 scroll_layer->CurrentScrollOffset());
6463 }
6464
6465 // Now that the nested scrolling layers are fully scrolled, further scrolls
6466 // would normally chain up to the "outer viewport" but since we've set the
6467 // scrolling content as the outer viewport, it should stop chaining there.
6468 {
6469 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6470 InputHandler::TOUCHSCREEN);
6471 host_impl_->ScrollBy(
6472 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
6473 host_impl_->ScrollEnd(EndState().get());
6474
6475 EXPECT_VECTOR_EQ(gfx::Vector2dF(),
6476 outer_scroll_layer->CurrentScrollOffset());
6477 }
6478
6479 // Zoom into the page by a 2X factor so that the inner viewport becomes
6480 // scrollable.
6481 float min_page_scale = 1.f, max_page_scale = 4.f;
6482 float page_scale_factor = 2.f;
6483 host_impl_->active_tree()->PushPageScaleFromMainThread(
6484 page_scale_factor, min_page_scale, max_page_scale);
6485 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
6486
6487 // Reset the parent scrolling layer (i.e. the current outer viewport) so that
6488 // we can ensure viewport scrolling works correctly.
6489 scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0));
6490
6491 // Scrolling the content layer should now scroll the inner viewport first,
6492 // and then chain up to the current outer viewport (i.e. the parent scroll
6493 // layer).
6494 {
6495 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6496 InputHandler::TOUCHSCREEN);
6497 host_impl_->ScrollBy(
6498 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
6499 host_impl_->ScrollEnd(EndState().get());
6500
6501 EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
6502 inner_scroll_layer->CurrentScrollOffset());
6503
6504 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
6505 InputHandler::TOUCHSCREEN);
6506 host_impl_->ScrollBy(
6507 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
6508 host_impl_->ScrollEnd(EndState().get());
6509
6510 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
6511 outer_scroll_layer->CurrentScrollOffset());
6512 EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
6513 scroll_layer->CurrentScrollOffset());
6514 }
6515}
6516
eseckler59eeb022016-07-05 10:45:176517TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) {
6518 InputHandlerScrollResult scroll_result;
6519 LayerTreeSettings settings = DefaultSettings();
6520 CreateHostImpl(settings, CreateOutputSurface());
6521
6522 const gfx::Size content_size(50, 50);
6523 const gfx::Size viewport_size(50, 50);
6524 CreateBasicVirtualViewportLayers(viewport_size, content_size);
6525
6526 // By default, no main thread scrolling reasons should exist.
6527 LayerImpl* scroll_layer =
6528 host_impl_->active_tree()->InnerViewportScrollLayer();
6529 EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
6530 scroll_layer->main_thread_scrolling_reasons());
6531
6532 DrawFrame();
6533
6534 // Overscroll initiated outside layers will be handled by the impl thread.
6535 EXPECT_EQ(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6536 gfx::PointF(0, 60)));
6537 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
6538 host_impl_
6539 ->ScrollBegin(BeginState(gfx::Point(0, 60)).get(),
6540 InputHandler::WHEEL)
6541 .thread);
6542
6543 // Overscroll initiated inside layers will be handled by the impl thread.
6544 EXPECT_NE(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
6545 gfx::PointF(0, 0)));
6546 EXPECT_EQ(
6547 InputHandler::SCROLL_ON_IMPL_THREAD,
6548 host_impl_
6549 ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::WHEEL)
6550 .thread);
6551}
6552
[email protected]96baf3e2012-10-22 23:09:556553class BlendStateCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:426554 public:
danakj60bc3bc2016-04-09 00:24:486555 static std::unique_ptr<LayerImpl> Create(
6556 LayerTreeImpl* tree_impl,
6557 int id,
6558 ResourceProvider* resource_provider) {
6559 return base::WrapUnique(
danakjf446a072014-09-27 21:55:486560 new BlendStateCheckLayer(tree_impl, id, resource_provider));
[email protected]aa043632013-03-25 03:39:426561 }
[email protected]94f206c12012-08-25 00:09:146562
dcheng716bedf2014-10-21 09:51:086563 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:086564 AppendQuadsData* append_quads_data) override {
[email protected]aa043632013-03-25 03:39:426565 quads_appended_ = true;
[email protected]94f206c12012-08-25 00:09:146566
[email protected]aa043632013-03-25 03:39:426567 gfx::Rect opaque_rect;
6568 if (contents_opaque())
6569 opaque_rect = quad_rect_;
6570 else
6571 opaque_rect = opaque_content_rect_;
[email protected]9bf06c72014-03-07 18:16:246572 gfx::Rect visible_quad_rect = quad_rect_;
[email protected]94f206c12012-08-25 00:09:146573
[email protected]c6707fd2014-06-23 05:50:366574 SharedQuadState* shared_quad_state =
6575 render_pass->CreateAndAppendSharedQuadState();
[email protected]9be1adc2014-05-07 15:39:416576 PopulateSharedQuadState(shared_quad_state);
6577
[email protected]f7030c32014-07-03 18:54:346578 TileDrawQuad* test_blending_draw_quad =
6579 render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
[email protected]aa043632013-03-25 03:39:426580 test_blending_draw_quad->SetNew(shared_quad_state,
6581 quad_rect_,
6582 opaque_rect,
[email protected]9bf06c72014-03-07 18:16:246583 visible_quad_rect,
[email protected]aa043632013-03-25 03:39:426584 resource_id_,
6585 gfx::RectF(0.f, 0.f, 1.f, 1.f),
6586 gfx::Size(1, 1),
jackhou24229612014-12-13 23:41:006587 false,
[email protected]aa043632013-03-25 03:39:426588 false);
6589 test_blending_draw_quad->visible_rect = quad_visible_rect_;
6590 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
6591 EXPECT_EQ(has_render_surface_, !!render_surface());
[email protected]aa043632013-03-25 03:39:426592 }
[email protected]94f206c12012-08-25 00:09:146593
[email protected]aa043632013-03-25 03:39:426594 void SetExpectation(bool blend, bool has_render_surface) {
6595 blend_ = blend;
6596 has_render_surface_ = has_render_surface;
6597 quads_appended_ = false;
6598 }
[email protected]94f206c12012-08-25 00:09:146599
[email protected]aa043632013-03-25 03:39:426600 bool quads_appended() const { return quads_appended_; }
[email protected]94f206c12012-08-25 00:09:146601
[email protected]0023fc72014-01-10 20:05:066602 void SetQuadRect(const gfx::Rect& rect) { quad_rect_ = rect; }
6603 void SetQuadVisibleRect(const gfx::Rect& rect) { quad_visible_rect_ = rect; }
6604 void SetOpaqueContentRect(const gfx::Rect& rect) {
6605 opaque_content_rect_ = rect;
6606 }
[email protected]94f206c12012-08-25 00:09:146607
[email protected]aa043632013-03-25 03:39:426608 private:
6609 BlendStateCheckLayer(LayerTreeImpl* tree_impl,
6610 int id,
6611 ResourceProvider* resource_provider)
6612 : LayerImpl(tree_impl, id),
6613 blend_(false),
6614 has_render_surface_(false),
6615 quads_appended_(false),
6616 quad_rect_(5, 5, 5, 5),
6617 quad_visible_rect_(5, 5, 5, 5),
6618 resource_id_(resource_provider->CreateResource(
6619 gfx::Size(1, 1),
ericrk7c030992015-02-20 01:39:386620 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
ccameronb4d92362016-08-12 07:33:266621 RGBA_8888,
6622 gfx::ColorSpace())) {
[email protected]aa043632013-03-25 03:39:426623 resource_provider->AllocateForTesting(resource_id_);
[email protected]aa043632013-03-25 03:39:426624 SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:426625 SetDrawsContent(true);
6626 }
[email protected]94f206c12012-08-25 00:09:146627
[email protected]aa043632013-03-25 03:39:426628 bool blend_;
6629 bool has_render_surface_;
6630 bool quads_appended_;
6631 gfx::Rect quad_rect_;
6632 gfx::Rect opaque_content_rect_;
6633 gfx::Rect quad_visible_rect_;
jbaumanbbd425e2015-05-19 00:33:356634 ResourceId resource_id_;
[email protected]94f206c12012-08-25 00:09:146635};
6636
[email protected]aa043632013-03-25 03:39:426637TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
6638 {
danakj60bc3bc2016-04-09 00:24:486639 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:426640 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:426641 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:426642 root->SetDrawsContent(false);
jaydasika6b5a32bf2016-04-22 21:56:366643 root->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:596644 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
[email protected]aa043632013-03-25 03:39:426645 }
jaydasikabf1875a2016-06-28 03:39:596646 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
[email protected]94f206c12012-08-25 00:09:146647
jaydasika89f7b5a2016-06-22 02:08:396648 root->test_properties()->AddChild(BlendStateCheckLayer::Create(
6649 host_impl_->active_tree(), 2, host_impl_->resource_provider()));
[email protected]aa043632013-03-25 03:39:426650 BlendStateCheckLayer* layer1 =
jaydasikafc66cfb2016-06-10 04:34:226651 static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]);
[email protected]aa043632013-03-25 03:39:426652 layer1->SetPosition(gfx::PointF(2.f, 2.f));
[email protected]94f206c12012-08-25 00:09:146653
[email protected]aa043632013-03-25 03:39:426654 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:146655
[email protected]aa043632013-03-25 03:39:426656 // Opaque layer, drawn without blending.
6657 layer1->SetContentsOpaque(true);
6658 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146659 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486660 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6661 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456662 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426663 EXPECT_TRUE(layer1->quads_appended());
6664 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146665
[email protected]aa043632013-03-25 03:39:426666 // Layer with translucent content and painting, so drawn with blending.
6667 layer1->SetContentsOpaque(false);
6668 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146669 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486670 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6671 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456672 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426673 EXPECT_TRUE(layer1->quads_appended());
6674 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146675
[email protected]aa043632013-03-25 03:39:426676 // Layer with translucent opacity, drawn with blending.
6677 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186678 layer1->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356679 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426680 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146681 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486682 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6683 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456684 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426685 EXPECT_TRUE(layer1->quads_appended());
6686 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146687
[email protected]aa043632013-03-25 03:39:426688 // Layer with translucent opacity and painting, drawn with blending.
6689 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186690 layer1->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356691 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426692 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146693 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486694 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6695 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456696 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426697 EXPECT_TRUE(layer1->quads_appended());
6698 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146699
jaydasika89f7b5a2016-06-22 02:08:396700 layer1->test_properties()->AddChild(BlendStateCheckLayer::Create(
6701 host_impl_->active_tree(), 3, host_impl_->resource_provider()));
jaydasikafc66cfb2016-06-10 04:34:226702 BlendStateCheckLayer* layer2 = static_cast<BlendStateCheckLayer*>(
6703 layer1->test_properties()->children[0]);
[email protected]aa043632013-03-25 03:39:426704 layer2->SetPosition(gfx::PointF(4.f, 4.f));
[email protected]94f206c12012-08-25 00:09:146705
[email protected]aa043632013-03-25 03:39:426706 // 2 opaque layers, drawn without blending.
6707 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186708 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356709 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426710 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146711 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426712 layer2->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186713 layer2->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356714 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426715 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146716 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486717 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6718 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456719 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426720 EXPECT_TRUE(layer1->quads_appended());
6721 EXPECT_TRUE(layer2->quads_appended());
6722 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146723
[email protected]aa043632013-03-25 03:39:426724 // Parent layer with translucent content, drawn with blending.
6725 // Child layer with opaque content, drawn without blending.
6726 layer1->SetContentsOpaque(false);
6727 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146728 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426729 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146730 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486731 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6732 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456733 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426734 EXPECT_TRUE(layer1->quads_appended());
6735 EXPECT_TRUE(layer2->quads_appended());
6736 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146737
[email protected]aa043632013-03-25 03:39:426738 // Parent layer with translucent content but opaque painting, drawn without
6739 // blending.
6740 // Child layer with opaque content, drawn without blending.
6741 layer1->SetContentsOpaque(true);
6742 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146743 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426744 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146745 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486746 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6747 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456748 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426749 EXPECT_TRUE(layer1->quads_appended());
6750 EXPECT_TRUE(layer2->quads_appended());
6751 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146752
[email protected]aa043632013-03-25 03:39:426753 // Parent layer with translucent opacity and opaque content. Since it has a
6754 // drawing child, it's drawn to a render surface which carries the opacity,
6755 // so it's itself drawn without blending.
6756 // Child layer with opaque content, drawn without blending (parent surface
6757 // carries the inherited opacity).
6758 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186759 layer1->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356760 layer1->NoteLayerPropertyChanged();
jaydasika6b5a32bf2016-04-22 21:56:366761 layer1->test_properties()->force_render_surface = true;
[email protected]aa043632013-03-25 03:39:426762 layer1->SetExpectation(false, true);
Dana Jansensc46d3742015-06-18 01:33:146763 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426764 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146765 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]ad63b2f2014-08-11 17:39:546766 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
jaydasikabf1875a2016-06-28 03:39:596767 host_impl_->active_tree()->root_layer_for_testing());
danakj74af409e2016-07-01 00:41:486768 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6769 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456770 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426771 EXPECT_TRUE(layer1->quads_appended());
6772 EXPECT_TRUE(layer2->quads_appended());
6773 host_impl_->DidDrawAllLayers(frame);
jaydasika6b5a32bf2016-04-22 21:56:366774 layer1->test_properties()->force_render_surface = false;
[email protected]94f206c12012-08-25 00:09:146775
[email protected]aa043632013-03-25 03:39:426776 // Draw again, but with child non-opaque, to make sure
6777 // layer1 not culled.
6778 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186779 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356780 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426781 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146782 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426783 layer2->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186784 layer2->test_properties()->opacity = 0.5f;
jaydasika16515f52016-03-01 00:28:356785 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426786 layer2->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146787 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486788 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6789 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456790 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426791 EXPECT_TRUE(layer1->quads_appended());
6792 EXPECT_TRUE(layer2->quads_appended());
6793 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146794
[email protected]aa043632013-03-25 03:39:426795 // A second way of making the child non-opaque.
6796 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186797 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356798 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426799 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146800 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426801 layer2->SetContentsOpaque(false);
jaydasikaab317e02016-06-01 00:53:186802 layer2->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356803 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426804 layer2->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146805 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486806 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6807 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456808 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426809 EXPECT_TRUE(layer1->quads_appended());
6810 EXPECT_TRUE(layer2->quads_appended());
6811 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146812
[email protected]aa043632013-03-25 03:39:426813 // And when the layer says its not opaque but is painted opaque, it is not
6814 // blended.
6815 layer1->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186816 layer1->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356817 layer1->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426818 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146819 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
[email protected]aa043632013-03-25 03:39:426820 layer2->SetContentsOpaque(true);
jaydasikaab317e02016-06-01 00:53:186821 layer2->test_properties()->opacity = 1.f;
jaydasika16515f52016-03-01 00:28:356822 layer2->NoteLayerPropertyChanged();
[email protected]aa043632013-03-25 03:39:426823 layer2->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146824 layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486825 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6826 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456827 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426828 EXPECT_TRUE(layer1->quads_appended());
6829 EXPECT_TRUE(layer2->quads_appended());
6830 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146831
[email protected]aa043632013-03-25 03:39:426832 // Layer with partially opaque contents, drawn with blending.
6833 layer1->SetContentsOpaque(false);
6834 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6835 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
6836 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6837 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146838 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486839 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6840 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456841 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426842 EXPECT_TRUE(layer1->quads_appended());
6843 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146844
[email protected]aa043632013-03-25 03:39:426845 // Layer with partially opaque contents partially culled, drawn with blending.
6846 layer1->SetContentsOpaque(false);
6847 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6848 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
6849 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6850 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146851 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486852 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6853 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456854 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426855 EXPECT_TRUE(layer1->quads_appended());
6856 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146857
[email protected]aa043632013-03-25 03:39:426858 // Layer with partially opaque contents culled, drawn with blending.
6859 layer1->SetContentsOpaque(false);
6860 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6861 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
6862 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6863 layer1->SetExpectation(true, false);
Dana Jansensc46d3742015-06-18 01:33:146864 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486865 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6866 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456867 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426868 EXPECT_TRUE(layer1->quads_appended());
6869 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146870
[email protected]aa043632013-03-25 03:39:426871 // Layer with partially opaque contents and translucent contents culled, drawn
6872 // without blending.
6873 layer1->SetContentsOpaque(false);
6874 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
6875 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
6876 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
6877 layer1->SetExpectation(false, false);
Dana Jansensc46d3742015-06-18 01:33:146878 layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
danakj74af409e2016-07-01 00:41:486879 host_impl_->active_tree()->BuildPropertyTreesForTesting();
6880 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:456881 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:426882 EXPECT_TRUE(layer1->quads_appended());
6883 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:146884}
6885
sadrul32d10972016-07-30 05:26:216886static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) {
6887 host_impl->active_tree()->BuildPropertyTreesForTesting();
6888 LayerTreeHostImpl::FrameData frame;
6889 EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame));
6890 host_impl->DrawLayers(&frame);
sadrul32d10972016-07-30 05:26:216891 host_impl->DidDrawAllLayers(frame);
6892 return frame.may_contain_video;
6893}
6894
6895TEST_F(LayerTreeHostImplTest, MayContainVideo) {
6896 gfx::Size big_size(1000, 1000);
6897 host_impl_->SetViewportSize(big_size);
6898
6899 int layer_id = 1;
6900 host_impl_->active_tree()->SetRootLayerForTesting(
6901 DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++));
6902 DidDrawCheckLayer* root =
6903 static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin());
6904
6905 root->test_properties()->AddChild(
6906 DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++));
6907 DidDrawCheckLayer* video_layer =
6908 static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
6909 video_layer->set_may_contain_video(true);
6910 EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6911
6912 // Test with the video layer occluded.
6913 root->test_properties()->AddChild(
6914 DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++));
6915 DidDrawCheckLayer* large_layer =
6916 static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
6917 large_layer->SetBounds(big_size);
6918 large_layer->SetContentsOpaque(true);
6919 EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6920
6921 // Remove the large layer.
6922 root->test_properties()->RemoveChild(large_layer);
6923 EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6924
6925 // Move the video layer so it goes beyond the root.
6926 video_layer->SetPosition(gfx::PointF(100.f, 100.f));
6927 EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6928
6929 video_layer->SetPosition(gfx::PointF(0.f, 0.f));
6930 video_layer->NoteLayerPropertyChanged();
6931 EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
6932}
6933
[email protected]6133cc232013-07-30 18:47:076934class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
[email protected]ce2e8112013-11-28 07:44:366935 protected:
[email protected]9f4f6a32013-09-04 21:35:126936 LayerTreeHostImplViewportCoveredTest() :
6937 gutter_quad_material_(DrawQuad::SOLID_COLOR),
6938 child_(NULL),
6939 did_activate_pending_tree_(false) {}
6940
danakj60bc3bc2016-04-09 00:24:486941 std::unique_ptr<OutputSurface> CreateFakeOutputSurface(bool software) {
danakj6021ec32016-07-22 22:16:086942 if (software)
6943 return FakeOutputSurface::CreateDelegatingSoftware();
danakjf33ceec2016-07-20 20:04:456944 return FakeOutputSurface::CreateDelegating3d();
[email protected]6133cc232013-07-30 18:47:076945 }
[email protected]94f206c12012-08-25 00:09:146946
[email protected]6133cc232013-07-30 18:47:076947 void SetupActiveTreeLayers() {
6948 host_impl_->active_tree()->set_background_color(SK_ColorGRAY);
jaydasikabf1875a2016-06-28 03:39:596949 host_impl_->active_tree()->SetRootLayerForTesting(
[email protected]6133cc232013-07-30 18:47:076950 LayerImpl::Create(host_impl_->active_tree(), 1));
jaydasika6b5a32bf2016-04-22 21:56:366951 host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:596952 ->root_layer_for_testing()
jaydasika6b5a32bf2016-04-22 21:56:366953 ->test_properties()
6954 ->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:596955 host_impl_->active_tree()
6956 ->root_layer_for_testing()
6957 ->test_properties()
6958 ->AddChild(BlendStateCheckLayer::Create(
6959 host_impl_->active_tree(), 2, host_impl_->resource_provider()));
jaydasikafc66cfb2016-06-10 04:34:226960 child_ = static_cast<BlendStateCheckLayer*>(host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:596961 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:226962 ->test_properties()
6963 ->children[0]);
[email protected]6133cc232013-07-30 18:47:076964 child_->SetExpectation(false, false);
6965 child_->SetContentsOpaque(true);
6966 }
[email protected]94f206c12012-08-25 00:09:146967
[email protected]6133cc232013-07-30 18:47:076968 // Expect no gutter rects.
6969 void TestLayerCoversFullViewport() {
6970 gfx::Rect layer_rect(viewport_size_);
danakja2fdbc702015-10-20 23:05:246971 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:076972 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:076973 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
6974 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:486975 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:146976
[email protected]aa043632013-03-25 03:39:426977 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:486978 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]aa043632013-03-25 03:39:426979 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:146980
[email protected]9f4f6a32013-09-04 21:35:126981 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:426982 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:126983 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:146984
[email protected]9f4f6a32013-09-04 21:35:126985 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:426986 host_impl_->DidDrawAllLayers(frame);
6987 }
[email protected]94f206c12012-08-25 00:09:146988
[email protected]6133cc232013-07-30 18:47:076989 // Expect fullscreen gutter rect.
boliu7097ee5b2015-12-17 03:16:096990 void SetUpEmptylayer() {
[email protected]aa043632013-03-25 03:39:426991 gfx::Rect layer_rect(0, 0, 0, 0);
danakja2fdbc702015-10-20 23:05:246992 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:076993 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:076994 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
6995 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:486996 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:096997 }
[email protected]94f206c12012-08-25 00:09:146998
boliu7097ee5b2015-12-17 03:16:096999 void VerifyEmptyLayerRenderPasses(const RenderPassList& render_passes) {
7000 ASSERT_EQ(1u, render_passes.size());
7001
7002 EXPECT_EQ(1u, CountGutterQuads(render_passes[0]->quad_list));
7003 EXPECT_EQ(1u, render_passes[0]->quad_list.size());
7004 ValidateTextureDrawQuads(render_passes[0]->quad_list);
7005
7006 VerifyQuadsExactlyCoverViewport(render_passes[0]->quad_list);
7007 }
7008
7009 void TestEmptyLayer() {
7010 SetUpEmptylayer();
[email protected]aa043632013-03-25 03:39:427011 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487012 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
boliu7097ee5b2015-12-17 03:16:097013 VerifyEmptyLayerRenderPasses(frame.render_passes);
[email protected]aa043632013-03-25 03:39:427014 host_impl_->DidDrawAllLayers(frame);
7015 }
[email protected]94f206c12012-08-25 00:09:147016
boliu7097ee5b2015-12-17 03:16:097017 void TestEmptyLayerWithOnDraw() {
7018 SetUpEmptylayer();
7019 gfx::Transform identity;
7020 gfx::Rect viewport(viewport_size_);
7021 bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:597022 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:097023 VerifyEmptyLayerRenderPasses(last_on_draw_render_passes_);
7024 }
7025
[email protected]6133cc232013-07-30 18:47:077026 // Expect four surrounding gutter rects.
boliu7097ee5b2015-12-17 03:16:097027 void SetUpLayerInMiddleOfViewport() {
[email protected]aa043632013-03-25 03:39:427028 gfx::Rect layer_rect(500, 500, 200, 200);
danakja2fdbc702015-10-20 23:05:247029 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:077030 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:077031 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
7032 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:487033 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:097034 }
[email protected]94f206c12012-08-25 00:09:147035
boliu7097ee5b2015-12-17 03:16:097036 void VerifyLayerInMiddleOfViewport(const RenderPassList& render_passes) {
7037 ASSERT_EQ(1u, render_passes.size());
7038
7039 EXPECT_EQ(4u, CountGutterQuads(render_passes[0]->quad_list));
7040 EXPECT_EQ(5u, render_passes[0]->quad_list.size());
7041 ValidateTextureDrawQuads(render_passes[0]->quad_list);
7042
7043 VerifyQuadsExactlyCoverViewport(render_passes[0]->quad_list);
7044 }
7045
7046 void TestLayerInMiddleOfViewport() {
7047 SetUpLayerInMiddleOfViewport();
[email protected]aa043632013-03-25 03:39:427048 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487049 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
boliu7097ee5b2015-12-17 03:16:097050 VerifyLayerInMiddleOfViewport(frame.render_passes);
[email protected]aa043632013-03-25 03:39:427051 host_impl_->DidDrawAllLayers(frame);
7052 }
[email protected]6133cc232013-07-30 18:47:077053
boliu7097ee5b2015-12-17 03:16:097054 void TestLayerInMiddleOfViewportWithOnDraw() {
7055 SetUpLayerInMiddleOfViewport();
7056 gfx::Transform identity;
7057 gfx::Rect viewport(viewport_size_);
7058 bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:597059 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:097060 VerifyLayerInMiddleOfViewport(last_on_draw_render_passes_);
7061 }
7062
[email protected]6133cc232013-07-30 18:47:077063 // Expect no gutter rects.
boliu7097ee5b2015-12-17 03:16:097064 void SetUpLayerIsLargerThanViewport() {
[email protected]6133cc232013-07-30 18:47:077065 gfx::Rect layer_rect(viewport_size_.width() + 10,
7066 viewport_size_.height() + 10);
danakja2fdbc702015-10-20 23:05:247067 child_->SetPosition(gfx::PointF(layer_rect.origin()));
[email protected]6133cc232013-07-30 18:47:077068 child_->SetBounds(layer_rect.size());
[email protected]6133cc232013-07-30 18:47:077069 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
7070 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
danakj74af409e2016-07-01 00:41:487071 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:097072 }
[email protected]6133cc232013-07-30 18:47:077073
boliu7097ee5b2015-12-17 03:16:097074 void VerifyLayerIsLargerThanViewport(const RenderPassList& render_passes) {
7075 ASSERT_EQ(1u, render_passes.size());
7076
7077 EXPECT_EQ(0u, CountGutterQuads(render_passes[0]->quad_list));
7078 EXPECT_EQ(1u, render_passes[0]->quad_list.size());
7079 ValidateTextureDrawQuads(render_passes[0]->quad_list);
7080 }
7081
7082 void TestLayerIsLargerThanViewport() {
7083 SetUpLayerIsLargerThanViewport();
[email protected]6133cc232013-07-30 18:47:077084 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487085 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
boliu7097ee5b2015-12-17 03:16:097086 VerifyLayerIsLargerThanViewport(frame.render_passes);
[email protected]6133cc232013-07-30 18:47:077087 host_impl_->DidDrawAllLayers(frame);
7088 }
7089
boliu7097ee5b2015-12-17 03:16:097090 void TestLayerIsLargerThanViewportWithOnDraw() {
7091 SetUpLayerIsLargerThanViewport();
7092 gfx::Transform identity;
7093 gfx::Rect viewport(viewport_size_);
7094 bool resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:597095 host_impl_->OnDraw(identity, viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:097096 VerifyLayerIsLargerThanViewport(last_on_draw_render_passes_);
7097 }
7098
dcheng716bedf2014-10-21 09:51:087099 void DidActivateSyncTree() override { did_activate_pending_tree_ = true; }
[email protected]6133cc232013-07-30 18:47:077100
[email protected]9f4f6a32013-09-04 21:35:127101 void set_gutter_quad_material(DrawQuad::Material material) {
7102 gutter_quad_material_ = material;
7103 }
[email protected]64348ea2014-01-29 22:58:267104 void set_gutter_texture_size(const gfx::Size& gutter_texture_size) {
[email protected]9f4f6a32013-09-04 21:35:127105 gutter_texture_size_ = gutter_texture_size;
7106 }
7107
[email protected]6133cc232013-07-30 18:47:077108 protected:
[email protected]9f4f6a32013-09-04 21:35:127109 size_t CountGutterQuads(const QuadList& quad_list) {
7110 size_t num_gutter_quads = 0;
vmpstra2e89432016-07-20 02:05:347111 for (auto* quad : quad_list) {
weiliangc48805fce2014-10-29 20:30:127112 num_gutter_quads += (quad->material == gutter_quad_material_) ? 1 : 0;
[email protected]9f4f6a32013-09-04 21:35:127113 }
7114 return num_gutter_quads;
7115 }
7116
7117 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) {
7118 LayerTestCommon::VerifyQuadsExactlyCoverRect(
7119 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_)));
7120 }
7121
7122 // Make sure that the texture coordinates match their expectations.
7123 void ValidateTextureDrawQuads(const QuadList& quad_list) {
vmpstra2e89432016-07-20 02:05:347124 for (auto* quad : quad_list) {
weiliangc48805fce2014-10-29 20:30:127125 if (quad->material != DrawQuad::TEXTURE_CONTENT)
[email protected]9f4f6a32013-09-04 21:35:127126 continue;
weiliangc48805fce2014-10-29 20:30:127127 const TextureDrawQuad* texture_quad = TextureDrawQuad::MaterialCast(quad);
ajuma1d48e012015-09-25 22:24:167128 gfx::SizeF gutter_texture_size_pixels =
7129 gfx::ScaleSize(gfx::SizeF(gutter_texture_size_),
7130 host_impl_->active_tree()->device_scale_factor());
weiliangc7eb7ee62014-10-07 00:04:407131 EXPECT_EQ(texture_quad->uv_top_left.x(),
7132 texture_quad->rect.x() / gutter_texture_size_pixels.width());
7133 EXPECT_EQ(texture_quad->uv_top_left.y(),
7134 texture_quad->rect.y() / gutter_texture_size_pixels.height());
7135 EXPECT_EQ(
7136 texture_quad->uv_bottom_right.x(),
7137 texture_quad->rect.right() / gutter_texture_size_pixels.width());
7138 EXPECT_EQ(
7139 texture_quad->uv_bottom_right.y(),
7140 texture_quad->rect.bottom() / gutter_texture_size_pixels.height());
[email protected]9f4f6a32013-09-04 21:35:127141 }
7142 }
7143
[email protected]64348ea2014-01-29 22:58:267144 gfx::Size DipSizeToPixelSize(const gfx::Size& size) {
ajuma1d48e012015-09-25 22:24:167145 return gfx::ScaleToRoundedSize(
7146 size, host_impl_->active_tree()->device_scale_factor());
[email protected]9f4f6a32013-09-04 21:35:127147 }
7148
7149 DrawQuad::Material gutter_quad_material_;
7150 gfx::Size gutter_texture_size_;
[email protected]6133cc232013-07-30 18:47:077151 gfx::Size viewport_size_;
7152 BlendStateCheckLayer* child_;
7153 bool did_activate_pending_tree_;
7154};
7155
7156TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) {
[email protected]ce2e8112013-11-28 07:44:367157 viewport_size_ = gfx::Size(1000, 1000);
7158
boliu8ca83902015-10-23 04:36:137159 bool software = false;
7160 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]6133cc232013-07-30 18:47:077161
[email protected]9f4f6a32013-09-04 21:35:127162 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:077163 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097164 EXPECT_SCOPED(TestLayerCoversFullViewport());
7165 EXPECT_SCOPED(TestEmptyLayer());
7166 EXPECT_SCOPED(TestLayerInMiddleOfViewport());
7167 EXPECT_SCOPED(TestLayerIsLargerThanViewport());
[email protected]94f206c12012-08-25 00:09:147168}
7169
[email protected]9f4f6a32013-09-04 21:35:127170TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
[email protected]ce2e8112013-11-28 07:44:367171 viewport_size_ = gfx::Size(1000, 1000);
7172
boliu8ca83902015-10-23 04:36:137173 bool software = false;
7174 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]9f4f6a32013-09-04 21:35:127175
ajuma1d48e012015-09-25 22:24:167176 host_impl_->active_tree()->SetDeviceScaleFactor(2.f);
[email protected]9f4f6a32013-09-04 21:35:127177 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
7178 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097179 EXPECT_SCOPED(TestLayerCoversFullViewport());
7180 EXPECT_SCOPED(TestEmptyLayer());
7181 EXPECT_SCOPED(TestLayerInMiddleOfViewport());
7182 EXPECT_SCOPED(TestLayerIsLargerThanViewport());
[email protected]9f4f6a32013-09-04 21:35:127183}
7184
[email protected]6133cc232013-07-30 18:47:077185TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
[email protected]ce2e8112013-11-28 07:44:367186 viewport_size_ = gfx::Size(1000, 1000);
[email protected]ce2e8112013-11-28 07:44:367187
boliu8ca83902015-10-23 04:36:137188 bool software = true;
7189 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]6133cc232013-07-30 18:47:077190
7191 // Pending tree to force active_tree size invalid. Not used otherwise.
7192 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:127193 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:077194 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
7195
7196 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097197 EXPECT_SCOPED(TestEmptyLayerWithOnDraw());
7198 EXPECT_SCOPED(TestLayerInMiddleOfViewportWithOnDraw());
7199 EXPECT_SCOPED(TestLayerIsLargerThanViewportWithOnDraw());
[email protected]6133cc232013-07-30 18:47:077200}
7201
7202TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) {
[email protected]ce2e8112013-11-28 07:44:367203 viewport_size_ = gfx::Size(1000, 1000);
[email protected]ce2e8112013-11-28 07:44:367204
boliu8ca83902015-10-23 04:36:137205 bool software = true;
7206 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(software));
[email protected]6133cc232013-07-30 18:47:077207
7208 // Set larger viewport and activate it to active tree.
7209 host_impl_->CreatePendingTree();
7210 gfx::Size larger_viewport(viewport_size_.width() + 100,
7211 viewport_size_.height() + 100);
[email protected]9f4f6a32013-09-04 21:35:127212 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport));
[email protected]6133cc232013-07-30 18:47:077213 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
[email protected]fc20d142014-07-01 00:49:157214 host_impl_->ActivateSyncTree();
[email protected]6133cc232013-07-30 18:47:077215 EXPECT_TRUE(did_activate_pending_tree_);
7216 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid());
7217
7218 // Shrink pending tree viewport without activating.
7219 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:127220 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:077221 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
7222
7223 SetupActiveTreeLayers();
boliu7097ee5b2015-12-17 03:16:097224 EXPECT_SCOPED(TestEmptyLayerWithOnDraw());
7225 EXPECT_SCOPED(TestLayerInMiddleOfViewportWithOnDraw());
7226 EXPECT_SCOPED(TestLayerIsLargerThanViewportWithOnDraw());
[email protected]6133cc232013-07-30 18:47:077227}
[email protected]94f206c12012-08-25 00:09:147228
[email protected]96baf3e2012-10-22 23:09:557229class FakeDrawableLayerImpl: public LayerImpl {
[email protected]aa043632013-03-25 03:39:427230 public:
danakj60bc3bc2016-04-09 00:24:487231 static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
7232 return base::WrapUnique(new FakeDrawableLayerImpl(tree_impl, id));
[email protected]aa043632013-03-25 03:39:427233 }
7234 protected:
7235 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id)
7236 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:147237};
7238
[email protected]94f206c12012-08-25 00:09:147239// Make sure damage tracking propagates all the way to the graphics context,
[email protected]aa043632013-03-25 03:39:427240// where it should request to swap only the sub-buffer that is damaged.
7241TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
[email protected]d9a54602013-12-10 07:01:597242 scoped_refptr<TestContextProvider> context_provider(
[email protected]4bf41752013-11-05 01:34:327243 TestContextProvider::Create());
[email protected]d9a54602013-12-10 07:01:597244 context_provider->BindToCurrentThread();
7245 context_provider->TestContext3d()->set_have_post_sub_buffer(true);
[email protected]0634cdd42013-08-16 00:46:097246
danakj60bc3bc2016-04-09 00:24:487247 std::unique_ptr<FakeOutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457248 FakeOutputSurface::CreateDelegating3d(context_provider));
sievers06680482014-10-10 20:21:507249 FakeOutputSurface* fake_output_surface = output_surface.get();
[email protected]94f206c12012-08-25 00:09:147250
[email protected]aa043632013-03-25 03:39:427251 // This test creates its own LayerTreeHostImpl, so
7252 // that we can force partial swap enabled.
weiliangc8f4ef0d2015-11-27 00:15:557253 LayerTreeSettings settings = DefaultSettings();
jbaumanc5be44c2014-11-20 22:17:127254 settings.renderer_settings.partial_swap_enabled = true;
danakj60bc3bc2016-04-09 00:24:487255 std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl =
reveman34b7a1522015-03-23 20:27:477256 LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:167257 settings, this, &task_runner_provider_, &stats_instrumentation_,
loysoab32ee72016-06-08 03:33:187258 &shared_bitmap_manager_, NULL, &task_graph_runner_,
7259 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
sievers71c62dd52015-10-07 01:44:397260 layer_tree_host_impl->SetVisible(true);
revemand180dfc32015-09-24 00:19:437261 layer_tree_host_impl->InitializeRenderer(output_surface.get());
mithro0bdb49d2015-05-27 13:08:017262 layer_tree_host_impl->WillBeginImplFrame(
7263 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
[email protected]18ce59702013-04-09 04:58:407264 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
[email protected]94f206c12012-08-25 00:09:147265
danakj60bc3bc2016-04-09 00:24:487266 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:427267 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
jaydasika6b5a32bf2016-04-22 21:56:367268 root->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:487269 std::unique_ptr<LayerImpl> child =
[email protected]aa043632013-03-25 03:39:427270 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
7271 child->SetPosition(gfx::PointF(12.f, 13.f));
[email protected]aa043632013-03-25 03:39:427272 child->SetBounds(gfx::Size(14, 15));
[email protected]aa043632013-03-25 03:39:427273 child->SetDrawsContent(true);
[email protected]aa043632013-03-25 03:39:427274 root->SetBounds(gfx::Size(500, 500));
[email protected]aa043632013-03-25 03:39:427275 root->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397276 root->test_properties()->AddChild(std::move(child));
jaydasikabf1875a2016-06-28 03:39:597277 layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487278 layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:147279
[email protected]aa043632013-03-25 03:39:427280 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:147281
[email protected]aa043632013-03-25 03:39:427282 // First frame, the entire screen should get swapped.
[email protected]2aae96792014-05-15 23:10:507283 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457284 layer_tree_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427285 layer_tree_host_impl->DidDrawAllLayers(frame);
danakjf33ceec2016-07-20 20:04:457286 gfx::Rect expected_swap_rect(500, 500);
sievers06680482014-10-10 20:21:507287 EXPECT_EQ(expected_swap_rect.ToString(),
7288 fake_output_surface->last_swap_rect().ToString());
[email protected]d9a54602013-12-10 07:01:597289
[email protected]aa043632013-03-25 03:39:427290 // Second frame, only the damaged area should get swapped. Damage should be
danakjf33ceec2016-07-20 20:04:457291 // the union of old and new child rects: gfx::Rect(26, 28).
jaydasikaadfec8e2016-02-17 02:46:117292 layer_tree_host_impl->active_tree()
jaydasikabf1875a2016-06-28 03:39:597293 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:227294 ->test_properties()
7295 ->children[0]
7296 ->SetPosition(gfx::PointF());
7297 layer_tree_host_impl->active_tree()
jaydasikabf1875a2016-06-28 03:39:597298 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:227299 ->test_properties()
7300 ->children[0]
jaydasikaadfec8e2016-02-17 02:46:117301 ->NoteLayerPropertyChanged();
danakj74af409e2016-07-01 00:41:487302 layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
[email protected]2aae96792014-05-15 23:10:507303 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457304 layer_tree_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427305 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147306
danakjf33ceec2016-07-20 20:04:457307 expected_swap_rect = gfx::Rect(26, 28);
[email protected]d9a54602013-12-10 07:01:597308 EXPECT_EQ(expected_swap_rect.ToString(),
sievers06680482014-10-10 20:21:507309 fake_output_surface->last_swap_rect().ToString());
[email protected]d9a54602013-12-10 07:01:597310
[email protected]18ce59702013-04-09 04:58:407311 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427312 // This will damage everything.
jaydasikabf1875a2016-06-28 03:39:597313 layer_tree_host_impl->active_tree()
7314 ->root_layer_for_testing()
7315 ->SetBackgroundColor(SK_ColorBLACK);
[email protected]2aae96792014-05-15 23:10:507316 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457317 layer_tree_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427318 host_impl_->DidDrawAllLayers(frame);
[email protected]d9a54602013-12-10 07:01:597319
danakjf33ceec2016-07-20 20:04:457320 expected_swap_rect = gfx::Rect(10, 10);
sievers06680482014-10-10 20:21:507321 EXPECT_EQ(expected_swap_rect.ToString(),
7322 fake_output_surface->last_swap_rect().ToString());
danakjee6547a22016-07-01 20:41:507323
7324 layer_tree_host_impl->ReleaseOutputSurface();
[email protected]94f206c12012-08-25 00:09:147325}
7326
[email protected]aa043632013-03-25 03:39:427327TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
danakj60bc3bc2016-04-09 00:24:487328 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:427329 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:487330 std::unique_ptr<LayerImpl> child =
[email protected]aa043632013-03-25 03:39:427331 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]aa043632013-03-25 03:39:427332 child->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427333 child->SetDrawsContent(true);
[email protected]aa043632013-03-25 03:39:427334 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427335 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:367336 root->test_properties()->force_render_surface = true;
jaydasika89f7b5a2016-06-22 02:08:397337 root->test_properties()->AddChild(std::move(child));
[email protected]94f206c12012-08-25 00:09:147338
jaydasikabf1875a2016-06-28 03:39:597339 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487340 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:147341
[email protected]aa043632013-03-25 03:39:427342 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:147343
danakj74af409e2016-07-01 00:41:487344 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]aa043632013-03-25 03:39:427345 EXPECT_EQ(1u, frame.render_surface_layer_list->size());
7346 EXPECT_EQ(1u, frame.render_passes.size());
7347 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147348}
7349
[email protected]96baf3e2012-10-22 23:09:557350class FakeLayerWithQuads : public LayerImpl {
[email protected]aa043632013-03-25 03:39:427351 public:
danakj60bc3bc2016-04-09 00:24:487352 static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
7353 return base::WrapUnique(new FakeLayerWithQuads(tree_impl, id));
[email protected]aa043632013-03-25 03:39:427354 }
[email protected]94f206c12012-08-25 00:09:147355
dcheng716bedf2014-10-21 09:51:087356 void AppendQuads(RenderPass* render_pass,
dcheng716bedf2014-10-21 09:51:087357 AppendQuadsData* append_quads_data) override {
[email protected]c6707fd2014-06-23 05:50:367358 SharedQuadState* shared_quad_state =
7359 render_pass->CreateAndAppendSharedQuadState();
[email protected]9be1adc2014-05-07 15:39:417360 PopulateSharedQuadState(shared_quad_state);
[email protected]94f206c12012-08-25 00:09:147361
[email protected]aa043632013-03-25 03:39:427362 SkColor gray = SkColorSetRGB(100, 100, 100);
Dana Jansensc46d3742015-06-18 01:33:147363 gfx::Rect quad_rect(bounds());
[email protected]9bf06c72014-03-07 18:16:247364 gfx::Rect visible_quad_rect(quad_rect);
[email protected]f7030c32014-07-03 18:54:347365 SolidColorDrawQuad* my_quad =
7366 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
[email protected]9bf06c72014-03-07 18:16:247367 my_quad->SetNew(
7368 shared_quad_state, quad_rect, visible_quad_rect, gray, false);
[email protected]aa043632013-03-25 03:39:427369 }
[email protected]94f206c12012-08-25 00:09:147370
[email protected]aa043632013-03-25 03:39:427371 private:
7372 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id)
7373 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:147374};
7375
danakj60bc3bc2016-04-09 00:24:487376static std::unique_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
weiliangc8f4ef0d2015-11-27 00:15:557377 LayerTreeSettings settings,
[email protected]aa043632013-03-25 03:39:427378 bool partial_swap,
7379 LayerTreeHostImplClient* client,
khushalsagarb64b360d2015-10-21 19:25:167380 TaskRunnerProvider* task_runner_provider,
[email protected]4e2eb352014-03-20 17:25:457381 SharedBitmapManager* manager,
danakjcf610582015-06-16 22:48:567382 TaskGraphRunner* task_graph_runner,
revemand180dfc32015-09-24 00:19:437383 RenderingStatsInstrumentation* stats_instrumentation,
7384 OutputSurface* output_surface) {
jbaumanc5be44c2014-11-20 22:17:127385 settings.renderer_settings.partial_swap_enabled = partial_swap;
danakj60bc3bc2016-04-09 00:24:487386 std::unique_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:167387 settings, client, task_runner_provider, stats_instrumentation, manager,
loysoab32ee72016-06-08 03:33:187388 nullptr, task_graph_runner,
7389 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
sievers71c62dd52015-10-07 01:44:397390 my_host_impl->SetVisible(true);
revemand180dfc32015-09-24 00:19:437391 my_host_impl->InitializeRenderer(output_surface);
mithro0bdb49d2015-05-27 13:08:017392 my_host_impl->WillBeginImplFrame(
7393 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
[email protected]18ce59702013-04-09 04:58:407394 my_host_impl->SetViewportSize(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:147395
[email protected]aa043632013-03-25 03:39:427396 /*
7397 Layers are created as follows:
[email protected]94f206c12012-08-25 00:09:147398
[email protected]aa043632013-03-25 03:39:427399 +--------------------+
7400 | 1 |
7401 | +-----------+ |
7402 | | 2 | |
7403 | | +-------------------+
7404 | | | 3 |
7405 | | +-------------------+
7406 | | | |
7407 | +-----------+ |
7408 | |
7409 | |
7410 +--------------------+
[email protected]94f206c12012-08-25 00:09:147411
[email protected]aa043632013-03-25 03:39:427412 Layers 1, 2 have render surfaces
7413 */
danakj60bc3bc2016-04-09 00:24:487414 std::unique_ptr<LayerImpl> root =
[email protected]aa043632013-03-25 03:39:427415 LayerImpl::Create(my_host_impl->active_tree(), 1);
danakj60bc3bc2016-04-09 00:24:487416 std::unique_ptr<LayerImpl> child =
[email protected]aa043632013-03-25 03:39:427417 LayerImpl::Create(my_host_impl->active_tree(), 2);
danakj60bc3bc2016-04-09 00:24:487418 std::unique_ptr<LayerImpl> grand_child =
[email protected]aa043632013-03-25 03:39:427419 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3);
[email protected]94f206c12012-08-25 00:09:147420
[email protected]aa043632013-03-25 03:39:427421 gfx::Rect root_rect(0, 0, 100, 100);
7422 gfx::Rect child_rect(10, 10, 50, 50);
7423 gfx::Rect grand_child_rect(5, 5, 150, 150);
[email protected]94f206c12012-08-25 00:09:147424
jaydasika6b5a32bf2016-04-22 21:56:367425 root->test_properties()->force_render_surface = true;
danakja2fdbc702015-10-20 23:05:247426 root->SetPosition(gfx::PointF(root_rect.origin()));
[email protected]aa043632013-03-25 03:39:427427 root->SetBounds(root_rect.size());
danakj64767d902015-06-19 00:10:437428 root->draw_properties().visible_layer_rect = root_rect;
[email protected]aa043632013-03-25 03:39:427429 root->SetDrawsContent(false);
[email protected]94f206c12012-08-25 00:09:147430
[email protected]aa043632013-03-25 03:39:427431 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
jaydasikaab317e02016-06-01 00:53:187432 child->test_properties()->opacity = 0.5f;
[email protected]aa043632013-03-25 03:39:427433 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
danakj64767d902015-06-19 00:10:437434 child->draw_properties().visible_layer_rect = child_rect;
[email protected]aa043632013-03-25 03:39:427435 child->SetDrawsContent(false);
jaydasika6b5a32bf2016-04-22 21:56:367436 child->test_properties()->force_render_surface = true;
[email protected]94f206c12012-08-25 00:09:147437
danakja2fdbc702015-10-20 23:05:247438 grand_child->SetPosition(gfx::PointF(grand_child_rect.origin()));
[email protected]aa043632013-03-25 03:39:427439 grand_child->SetBounds(grand_child_rect.size());
danakj64767d902015-06-19 00:10:437440 grand_child->draw_properties().visible_layer_rect = grand_child_rect;
[email protected]aa043632013-03-25 03:39:427441 grand_child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:147442
jaydasika89f7b5a2016-06-22 02:08:397443 child->test_properties()->AddChild(std::move(grand_child));
7444 root->test_properties()->AddChild(std::move(child));
[email protected]94f206c12012-08-25 00:09:147445
jaydasikabf1875a2016-06-28 03:39:597446 my_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487447 my_host_impl->active_tree()->BuildPropertyTreesForTesting();
danakja04855a2015-11-18 20:39:107448 return my_host_impl;
[email protected]94f206c12012-08-25 00:09:147449}
7450
[email protected]aa043632013-03-25 03:39:427451TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
danakjcf610582015-06-16 22:48:567452 TestSharedBitmapManager shared_bitmap_manager;
7453 TestTaskGraphRunner task_graph_runner;
revemand180dfc32015-09-24 00:19:437454 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
7455 provider->BindToCurrentThread();
7456 provider->TestContext3d()->set_have_post_sub_buffer(true);
danakj60bc3bc2016-04-09 00:24:487457 std::unique_ptr<OutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457458 FakeOutputSurface::CreateDelegating3d(provider));
danakj60bc3bc2016-04-09 00:24:487459 std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity(
weiliangc8f4ef0d2015-11-27 00:15:557460 DefaultSettings(), true, this, &task_runner_provider_,
7461 &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_,
7462 output_surface.get());
[email protected]aa043632013-03-25 03:39:427463 {
7464 LayerTreeHostImpl::FrameData frame;
[email protected]2aae96792014-05-15 23:10:507465 EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
[email protected]94f206c12012-08-25 00:09:147466
[email protected]aa043632013-03-25 03:39:427467 // Verify all quads have been computed
7468 ASSERT_EQ(2U, frame.render_passes.size());
7469 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
7470 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
7471 EXPECT_EQ(DrawQuad::SOLID_COLOR,
weiliangc032e929d2014-09-26 01:55:017472 frame.render_passes[0]->quad_list.front()->material);
[email protected]aa043632013-03-25 03:39:427473 EXPECT_EQ(DrawQuad::RENDER_PASS,
weiliangc032e929d2014-09-26 01:55:017474 frame.render_passes[1]->quad_list.front()->material);
[email protected]94f206c12012-08-25 00:09:147475
mithro248d1722015-05-05 05:23:457476 my_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427477 my_host_impl->DidDrawAllLayers(frame);
7478 }
danakjee6547a22016-07-01 20:41:507479 my_host_impl->ReleaseOutputSurface();
[email protected]94f206c12012-08-25 00:09:147480}
7481
[email protected]aa043632013-03-25 03:39:427482TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
danakjcf610582015-06-16 22:48:567483 TestSharedBitmapManager shared_bitmap_manager;
7484 TestTaskGraphRunner task_graph_runner;
revemand180dfc32015-09-24 00:19:437485 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
7486 provider->BindToCurrentThread();
7487 provider->TestContext3d()->set_have_post_sub_buffer(true);
danakj60bc3bc2016-04-09 00:24:487488 std::unique_ptr<OutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457489 FakeOutputSurface::CreateDelegating3d(provider));
danakj60bc3bc2016-04-09 00:24:487490 std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity(
weiliangc8f4ef0d2015-11-27 00:15:557491 DefaultSettings(), false, this, &task_runner_provider_,
7492 &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_,
7493 output_surface.get());
[email protected]aa043632013-03-25 03:39:427494 {
7495 LayerTreeHostImpl::FrameData frame;
[email protected]2aae96792014-05-15 23:10:507496 EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
[email protected]94f206c12012-08-25 00:09:147497
[email protected]aa043632013-03-25 03:39:427498 // Verify all quads have been computed
7499 ASSERT_EQ(2U, frame.render_passes.size());
7500 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
7501 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
7502 EXPECT_EQ(DrawQuad::SOLID_COLOR,
weiliangc032e929d2014-09-26 01:55:017503 frame.render_passes[0]->quad_list.front()->material);
[email protected]aa043632013-03-25 03:39:427504 EXPECT_EQ(DrawQuad::RENDER_PASS,
weiliangc032e929d2014-09-26 01:55:017505 frame.render_passes[1]->quad_list.front()->material);
[email protected]94f206c12012-08-25 00:09:147506
mithro248d1722015-05-05 05:23:457507 my_host_impl->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427508 my_host_impl->DidDrawAllLayers(frame);
7509 }
danakjee6547a22016-07-01 20:41:507510 my_host_impl->ReleaseOutputSurface();
[email protected]94f206c12012-08-25 00:09:147511}
7512
[email protected]aa043632013-03-25 03:39:427513TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
danakj60bc3bc2016-04-09 00:24:487514 std::unique_ptr<TestWebGraphicsContext3D> context =
[email protected]aa043632013-03-25 03:39:427515 TestWebGraphicsContext3D::Create();
7516 TestWebGraphicsContext3D* context3d = context.get();
danakj60bc3bc2016-04-09 00:24:487517 std::unique_ptr<OutputSurface> output_surface(
danakjf33ceec2016-07-20 20:04:457518 FakeOutputSurface::CreateDelegating3d(std::move(context)));
danakja04855a2015-11-18 20:39:107519 CreateHostImpl(DefaultSettings(), std::move(output_surface));
[email protected]d993b602013-01-04 02:08:127520
danakj60bc3bc2016-04-09 00:24:487521 std::unique_ptr<LayerImpl> root_layer =
[email protected]aa043632013-03-25 03:39:427522 LayerImpl::Create(host_impl_->active_tree(), 1);
7523 root_layer->SetBounds(gfx::Size(10, 10));
jaydasika6b5a32bf2016-04-22 21:56:367524 root_layer->test_properties()->force_render_surface = true;
[email protected]94f206c12012-08-25 00:09:147525
[email protected]aa043632013-03-25 03:39:427526 scoped_refptr<VideoFrame> softwareFrame =
7527 media::VideoFrame::CreateColorFrame(
7528 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
7529 FakeVideoFrameProvider provider;
7530 provider.set_frame(softwareFrame);
danakj60bc3bc2016-04-09 00:24:487531 std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
[email protected]f78c3e82014-08-08 01:24:477532 host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0);
[email protected]aa043632013-03-25 03:39:427533 video_layer->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427534 video_layer->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397535 root_layer->test_properties()->AddChild(std::move(video_layer));
[email protected]94f206c12012-08-25 00:09:147536
jaydasikabf1875a2016-06-28 03:39:597537 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer));
danakj74af409e2016-07-01 00:41:487538 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]94f206c12012-08-25 00:09:147539
[email protected]aa043632013-03-25 03:39:427540 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]d993b602013-01-04 02:08:127541
[email protected]aa043632013-03-25 03:39:427542 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487543 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457544 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427545 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147546
[email protected]aa043632013-03-25 03:39:427547 EXPECT_GT(context3d->NumTextures(), 0u);
[email protected]94f206c12012-08-25 00:09:147548
[email protected]aa043632013-03-25 03:39:427549 // Kill the layer tree.
rockot2176f922016-06-08 19:18:327550 host_impl_->active_tree()->DetachLayers();
[email protected]aa043632013-03-25 03:39:427551 // There should be no textures left in use after.
7552 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]94f206c12012-08-25 00:09:147553}
7554
[email protected]c8756fbe2013-02-12 01:53:497555class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:427556 public:
[email protected]0f9969982014-01-11 02:26:377557 MOCK_METHOD1(useProgram, void(GLuint program));
7558 MOCK_METHOD4(drawElements, void(GLenum mode,
7559 GLsizei count,
7560 GLenum type,
7561 GLintptr offset));
[email protected]94f206c12012-08-25 00:09:147562};
7563
[email protected]aa043632013-03-25 03:39:427564TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
[email protected]aa043632013-03-25 03:39:427565 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:487566 host_impl_->active_tree()->BuildPropertyTreesForTesting();
7567
[email protected]aa043632013-03-25 03:39:427568 host_impl_->active_tree()->set_background_color(SK_ColorWHITE);
[email protected]94f206c12012-08-25 00:09:147569
[email protected]aa043632013-03-25 03:39:427570 // Verify one quad is drawn when transparent background set is not set.
7571 host_impl_->active_tree()->set_has_transparent_background(false);
[email protected]aa043632013-03-25 03:39:427572 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487573 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjf33ceec2016-07-20 20:04:457574 {
7575 const auto& root_pass = frame.render_passes.back();
7576 ASSERT_EQ(1u, root_pass->quad_list.size());
7577 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.front()->material);
7578 }
mithro248d1722015-05-05 05:23:457579 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427580 host_impl_->DidDrawAllLayers(frame);
danakjf33ceec2016-07-20 20:04:457581
7582 // Cause damage so we would draw something if possible.
danakjb902c672016-08-17 02:33:547583 host_impl_->SetFullViewportDamage();
[email protected]94f206c12012-08-25 00:09:147584
[email protected]aa043632013-03-25 03:39:427585 // Verify no quads are drawn when transparent background is set.
7586 host_impl_->active_tree()->set_has_transparent_background(true);
danakjb902c672016-08-17 02:33:547587 host_impl_->SetFullViewportDamage();
danakj74af409e2016-07-01 00:41:487588 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjf33ceec2016-07-20 20:04:457589 {
7590 const auto& root_pass = frame.render_passes.back();
7591 ASSERT_EQ(0u, root_pass->quad_list.size());
7592 }
mithro248d1722015-05-05 05:23:457593 host_impl_->DrawLayers(&frame);
[email protected]aa043632013-03-25 03:39:427594 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:147595}
7596
[email protected]aa043632013-03-25 03:39:427597class LayerTreeHostImplTestWithDelegatingRenderer
7598 : public LayerTreeHostImplTest {
7599 protected:
danakj60bc3bc2016-04-09 00:24:487600 std::unique_ptr<OutputSurface> CreateOutputSurface() override {
danakjf446a072014-09-27 21:55:487601 return FakeOutputSurface::CreateDelegating3d();
[email protected]aa043632013-03-25 03:39:427602 }
7603
danakj5e6ff6d2015-09-05 04:43:447604 void DrawFrameAndTestDamage(const gfx::Rect& expected_damage) {
[email protected]e0341352013-04-06 05:01:207605 bool expect_to_draw = !expected_damage.IsEmpty();
7606
[email protected]aa043632013-03-25 03:39:427607 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487608 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]aa043632013-03-25 03:39:427609
[email protected]e0341352013-04-06 05:01:207610 if (!expect_to_draw) {
7611 // With no damage, we don't draw, and no quads are created.
7612 ASSERT_EQ(0u, frame.render_passes.size());
7613 } else {
7614 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]aa043632013-03-25 03:39:427615
[email protected]e0341352013-04-06 05:01:207616 // Verify the damage rect for the root render pass.
vmpstra370ef52015-11-18 10:41:287617 const RenderPass* root_render_pass = frame.render_passes.back().get();
hush6b614212014-12-04 22:37:327618 EXPECT_EQ(expected_damage, root_render_pass->damage_rect);
[email protected]e0341352013-04-06 05:01:207619
7620 // Verify the root and child layers' quads are generated and not being
7621 // culled.
7622 ASSERT_EQ(2u, root_render_pass->quad_list.size());
7623
jaydasikafc66cfb2016-06-10 04:34:227624 LayerImpl* child = host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:597625 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:227626 ->test_properties()
7627 ->children[0];
danakj5e6ff6d2015-09-05 04:43:447628 gfx::Rect expected_child_visible_rect(child->bounds());
hush6b614212014-12-04 22:37:327629 EXPECT_EQ(expected_child_visible_rect,
7630 root_render_pass->quad_list.front()->visible_rect);
[email protected]e0341352013-04-06 05:01:207631
jaydasikabf1875a2016-06-28 03:39:597632 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
danakj5e6ff6d2015-09-05 04:43:447633 gfx::Rect expected_root_visible_rect(root->bounds());
hush6b614212014-12-04 22:37:327634 EXPECT_EQ(expected_root_visible_rect,
7635 root_render_pass->quad_list.ElementAt(1)->visible_rect);
[email protected]e0341352013-04-06 05:01:207636 }
[email protected]aa043632013-03-25 03:39:427637
danakjaecfcfba2016-09-07 22:33:187638 EXPECT_EQ(expect_to_draw, host_impl_->DrawLayers(&frame));
[email protected]aa043632013-03-25 03:39:427639 host_impl_->DidDrawAllLayers(frame);
[email protected]aa043632013-03-25 03:39:427640 }
7641};
7642
7643TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
danakj60bc3bc2016-04-09 00:24:487644 std::unique_ptr<SolidColorLayerImpl> root =
[email protected]aa043632013-03-25 03:39:427645 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:427646 root->SetPosition(gfx::PointF());
7647 root->SetBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:427648 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:367649 root->test_properties()->force_render_surface = true;
[email protected]e0341352013-04-06 05:01:207650
7651 // Child layer is in the bottom right corner.
danakj60bc3bc2016-04-09 00:24:487652 std::unique_ptr<SolidColorLayerImpl> child =
[email protected]e0341352013-04-06 05:01:207653 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]e0341352013-04-06 05:01:207654 child->SetPosition(gfx::PointF(9.f, 9.f));
7655 child->SetBounds(gfx::Size(1, 1));
[email protected]e0341352013-04-06 05:01:207656 child->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397657 root->test_properties()->AddChild(std::move(child));
[email protected]e0341352013-04-06 05:01:207658
jaydasikabf1875a2016-06-28 03:39:597659 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:487660 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]aa043632013-03-25 03:39:427661
7662 // Draw a frame. In the first frame, the entire viewport should be damaged.
[email protected]54af03522013-09-05 00:43:287663 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
[email protected]aa043632013-03-25 03:39:427664 DrawFrameAndTestDamage(full_frame_damage);
7665
[email protected]e0341352013-04-06 05:01:207666 // The second frame has damage that doesn't touch the child layer. Its quads
7667 // should still be generated.
7668 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
jaydasikabf1875a2016-06-28 03:39:597669 host_impl_->active_tree()->root_layer_for_testing()->SetUpdateRect(
7670 small_damage);
[email protected]e0341352013-04-06 05:01:207671 DrawFrameAndTestDamage(small_damage);
7672
7673 // The third frame should have no damage, so no quads should be generated.
[email protected]aa043632013-03-25 03:39:427674 gfx::Rect no_damage;
7675 DrawFrameAndTestDamage(no_damage);
[email protected]ea9d8f22012-12-08 03:39:297676}
7677
[email protected]46b79d52013-09-07 04:29:297678class GLRendererWithSetupQuadForAntialiasing : public GLRenderer {
7679 public:
timav8a72a922014-11-07 00:47:217680 using GLRenderer::ShouldAntialiasQuad;
[email protected]46b79d52013-09-07 04:29:297681};
7682
7683TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
7684 // Due to precision issues (especially on Android), sometimes far
7685 // away quads can end up thinking they need AA.
7686 float device_scale_factor = 4.f / 3.f;
[email protected]46b79d52013-09-07 04:29:297687 gfx::Size root_size(2000, 1000);
7688 gfx::Size device_viewport_size =
danakjddaec912015-09-25 19:38:407689 gfx::ScaleToCeiledSize(root_size, device_scale_factor);
[email protected]46b79d52013-09-07 04:29:297690 host_impl_->SetViewportSize(device_viewport_size);
7691
7692 host_impl_->CreatePendingTree();
ajuma1d48e012015-09-25 22:24:167693 host_impl_->pending_tree()->SetDeviceScaleFactor(device_scale_factor);
aelias58eec0812014-12-04 01:04:407694 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f,
7695 16.f);
[email protected]46b79d52013-09-07 04:29:297696
danakj60bc3bc2016-04-09 00:24:487697 std::unique_ptr<LayerImpl> scoped_root =
[email protected]46b79d52013-09-07 04:29:297698 LayerImpl::Create(host_impl_->pending_tree(), 1);
7699 LayerImpl* root = scoped_root.get();
jaydasika6b5a32bf2016-04-22 21:56:367700 root->test_properties()->force_render_surface = true;
[email protected]46b79d52013-09-07 04:29:297701
jaydasikabf1875a2016-06-28 03:39:597702 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root));
[email protected]46b79d52013-09-07 04:29:297703
danakj60bc3bc2016-04-09 00:24:487704 std::unique_ptr<LayerImpl> scoped_scrolling_layer =
[email protected]46b79d52013-09-07 04:29:297705 LayerImpl::Create(host_impl_->pending_tree(), 2);
7706 LayerImpl* scrolling_layer = scoped_scrolling_layer.get();
jaydasika89f7b5a2016-06-22 02:08:397707 root->test_properties()->AddChild(std::move(scoped_scrolling_layer));
[email protected]46b79d52013-09-07 04:29:297708
7709 gfx::Size content_layer_bounds(100000, 100);
vmpstr41d68f882016-03-30 01:20:237710 scoped_refptr<FakeRasterSource> raster_source(
7711 FakeRasterSource::CreateFilled(content_layer_bounds));
[email protected]46b79d52013-09-07 04:29:297712
danakj60bc3bc2016-04-09 00:24:487713 std::unique_ptr<FakePictureLayerImpl> scoped_content_layer =
hendrikw9d909aa72014-11-11 20:19:527714 FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(),
vmpstr856740262015-09-24 00:25:257715 3, raster_source);
[email protected]46b79d52013-09-07 04:29:297716 LayerImpl* content_layer = scoped_content_layer.get();
jaydasika89f7b5a2016-06-22 02:08:397717 scrolling_layer->test_properties()->AddChild(std::move(scoped_content_layer));
[email protected]46b79d52013-09-07 04:29:297718 content_layer->SetBounds(content_layer_bounds);
7719 content_layer->SetDrawsContent(true);
7720
7721 root->SetBounds(root_size);
7722
miletusf57925d2014-10-01 19:38:137723 gfx::ScrollOffset scroll_offset(100000, 0);
[email protected]adeda572014-01-31 00:49:477724 scrolling_layer->SetScrollClipLayer(root->id());
danakj74af409e2016-07-01 00:41:487725 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
7726
sunxdb7e79432016-03-09 21:13:427727 scrolling_layer->layer_tree_impl()
7728 ->property_trees()
7729 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scrolling_layer->id(),
7730 scroll_offset);
[email protected]fc20d142014-07-01 00:49:157731 host_impl_->ActivateSyncTree();
[email protected]46b79d52013-09-07 04:29:297732
enneaf5bda32015-02-19 01:27:367733 bool update_lcd_text = false;
7734 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
[email protected]46b79d52013-09-07 04:29:297735 ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
7736
7737 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487738 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
[email protected]46b79d52013-09-07 04:29:297739
7740 ASSERT_EQ(1u, frame.render_passes.size());
7741 ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
weiliangc032e929d2014-09-26 01:55:017742 const DrawQuad* quad = frame.render_passes[0]->quad_list.front();
[email protected]46b79d52013-09-07 04:29:297743
roscaf519af22015-06-17 20:57:107744 bool clipped = false, force_aa = false;
7745 gfx::QuadF device_layer_quad = MathUtil::MapQuad(
danakj64767d902015-06-19 00:10:437746 quad->shared_quad_state->quad_to_target_transform,
danakj5e6ff6d2015-09-05 04:43:447747 gfx::QuadF(gfx::RectF(quad->shared_quad_state->visible_quad_layer_rect)),
7748 &clipped);
roscaf519af22015-06-17 20:57:107749 EXPECT_FALSE(clipped);
[email protected]46b79d52013-09-07 04:29:297750 bool antialiased =
timav8a72a922014-11-07 00:47:217751 GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
roscaf519af22015-06-17 20:57:107752 device_layer_quad, clipped, force_aa);
[email protected]46b79d52013-09-07 04:29:297753 EXPECT_FALSE(antialiased);
7754
mithro248d1722015-05-05 05:23:457755 host_impl_->DrawLayers(&frame);
[email protected]46b79d52013-09-07 04:29:297756 host_impl_->DidDrawAllLayers(frame);
7757}
7758
[email protected]bb1e2822013-04-17 22:06:017759class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
7760 public:
7761 CompositorFrameMetadataTest()
7762 : swap_buffers_complete_(0) {}
7763
dcheng716bedf2014-10-21 09:51:087764 void DidSwapBuffersCompleteOnImplThread() override {
[email protected]bb1e2822013-04-17 22:06:017765 swap_buffers_complete_++;
7766 }
7767
7768 int swap_buffers_complete_;
7769};
7770
7771TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
7772 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:487773 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]bb1e2822013-04-17 22:06:017774 {
7775 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:487776 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:457777 host_impl_->DrawLayers(&frame);
[email protected]bb1e2822013-04-17 22:06:017778 host_impl_->DidDrawAllLayers(frame);
7779 }
fsamuelb62b78222016-07-15 01:14:147780 host_impl_->ReclaimResources(ReturnedResourceArray());
[email protected]c14902662014-04-18 05:06:117781 host_impl_->DidSwapBuffersComplete();
[email protected]bb1e2822013-04-17 22:06:017782 EXPECT_EQ(swap_buffers_complete_, 1);
7783}
7784
[email protected]fbe89f72013-05-21 07:24:247785class CountingSoftwareDevice : public SoftwareOutputDevice {
7786 public:
7787 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
7788
dcheng716bedf2014-10-21 09:51:087789 SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
[email protected]fbe89f72013-05-21 07:24:247790 ++frames_began_;
7791 return SoftwareOutputDevice::BeginPaint(damage_rect);
7792 }
jbauman95f741352015-08-07 02:10:347793 void EndPaint() override {
7794 SoftwareOutputDevice::EndPaint();
[email protected]fbe89f72013-05-21 07:24:247795 ++frames_ended_;
[email protected]fbe89f72013-05-21 07:24:247796 }
7797
7798 int frames_began_, frames_ended_;
7799};
7800
[email protected]ffbb2212013-06-02 23:47:597801TEST_F(LayerTreeHostImplTest,
7802 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) {
[email protected]50644642013-06-20 13:58:557803 set_reduce_memory_result(false);
danakj6021ec32016-07-22 22:16:087804 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
7805 FakeOutputSurface::CreateDelegatingSoftware()));
[email protected]ffbb2212013-06-02 23:47:597806
[email protected]c05dfbb2014-07-10 22:49:047807 const gfx::Transform external_transform;
7808 const gfx::Rect external_viewport;
[email protected]c05dfbb2014-07-10 22:49:047809 const bool resourceless_software_draw = true;
boliu7097ee5b2015-12-17 03:16:097810 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
7811 external_transform);
[email protected]ffbb2212013-06-02 23:47:597812
7813 // SolidColorLayerImpl will be drawn.
danakj60bc3bc2016-04-09 00:24:487814 std::unique_ptr<SolidColorLayerImpl> root_layer =
[email protected]ffbb2212013-06-02 23:47:597815 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
7816
7817 // VideoLayerImpl will not be drawn.
7818 FakeVideoFrameProvider provider;
danakj60bc3bc2016-04-09 00:24:487819 std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
[email protected]f78c3e82014-08-08 01:24:477820 host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0);
[email protected]ffbb2212013-06-02 23:47:597821 video_layer->SetBounds(gfx::Size(10, 10));
[email protected]ffbb2212013-06-02 23:47:597822 video_layer->SetDrawsContent(true);
jaydasika89f7b5a2016-06-22 02:08:397823 root_layer->test_properties()->AddChild(std::move(video_layer));
danakja04855a2015-11-18 20:39:107824 SetupRootLayerImpl(std::move(root_layer));
danakj74af409e2016-07-01 00:41:487825 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ffbb2212013-06-02 23:47:597826
boliu31c233ed2016-07-29 05:38:597827 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:097828 resourceless_software_draw);
[email protected]ffbb2212013-06-02 23:47:597829
boliu7097ee5b2015-12-17 03:16:097830 EXPECT_EQ(1u, last_on_draw_frame_->will_draw_layers.size());
jaydasikabf1875a2016-06-28 03:39:597831 EXPECT_EQ(host_impl_->active_tree()->root_layer_for_testing(),
boliu7097ee5b2015-12-17 03:16:097832 last_on_draw_frame_->will_draw_layers[0]);
[email protected]ffbb2212013-06-02 23:47:597833}
7834
danakjaa5c4912016-09-10 00:28:237835// Checks that we use the memory limits provided.
7836TEST_F(LayerTreeHostImplTest, MemoryLimits) {
danakjee6547a22016-07-01 20:41:507837 host_impl_->ReleaseOutputSurface();
7838 host_impl_ = nullptr;
7839
danakjaa5c4912016-09-10 00:28:237840 const size_t kGpuByteLimit = 1234321;
7841 const size_t kSoftwareByteLimit = 4321234;
7842 const size_t kGpuResourceLimit = 2345432;
7843 const size_t kSoftwareResourceLimit = 5432345;
7844 const gpu::MemoryAllocation::PriorityCutoff kGpuCutoff =
7845 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
7846 const gpu::MemoryAllocation::PriorityCutoff kSoftwareCutoff =
7847 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
7848
7849 const TileMemoryLimitPolicy kGpuTileCutoff =
7850 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(kGpuCutoff);
7851 const TileMemoryLimitPolicy kSoftwareTileCutoff =
7852 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
7853 kSoftwareCutoff);
7854 const TileMemoryLimitPolicy kNothingTileCutoff =
7855 ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
7856 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
7857 EXPECT_NE(kGpuTileCutoff, kNothingTileCutoff);
7858 EXPECT_NE(kSoftwareTileCutoff, kNothingTileCutoff);
7859
weiliangc8f4ef0d2015-11-27 00:15:557860 LayerTreeSettings settings = DefaultSettings();
danakjaa5c4912016-09-10 00:28:237861 settings.gpu_memory_policy =
7862 ManagedMemoryPolicy(kGpuByteLimit, kGpuCutoff, kGpuResourceLimit);
7863 settings.software_memory_policy = ManagedMemoryPolicy(
7864 kSoftwareByteLimit, kSoftwareCutoff, kSoftwareResourceLimit);
reveman34b7a1522015-03-23 20:27:477865 host_impl_ = LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:167866 settings, this, &task_runner_provider_, &stats_instrumentation_,
7867 &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_,
loysoab32ee72016-06-08 03:33:187868 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
[email protected]fd32d122013-06-29 13:11:047869
danakjaa5c4912016-09-10 00:28:237870 // Gpu compositing.
revemand180dfc32015-09-24 00:19:437871 output_surface_ =
danakjf33ceec2016-07-20 20:04:457872 FakeOutputSurface::CreateDelegating3d(TestWebGraphicsContext3D::Create());
sievers71c62dd52015-10-07 01:44:397873 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:437874 host_impl_->InitializeRenderer(output_surface_.get());
danakjaa5c4912016-09-10 00:28:237875 {
7876 const auto& state = host_impl_->global_tile_state();
7877 EXPECT_EQ(kGpuByteLimit, state.hard_memory_limit_in_bytes);
7878 EXPECT_EQ(kGpuResourceLimit, state.num_resources_limit);
7879 EXPECT_EQ(kGpuTileCutoff, state.memory_limit_policy);
7880 }
7881
7882 // Not visible, drops to 0.
7883 host_impl_->SetVisible(false);
7884 {
7885 const auto& state = host_impl_->global_tile_state();
7886 EXPECT_EQ(0u, state.hard_memory_limit_in_bytes);
7887 EXPECT_EQ(kGpuResourceLimit, state.num_resources_limit);
7888 EXPECT_EQ(kNothingTileCutoff, state.memory_limit_policy);
7889 }
7890
7891 // Visible, is the gpu limit again.
7892 host_impl_->SetVisible(true);
7893 {
7894 const auto& state = host_impl_->global_tile_state();
7895 EXPECT_EQ(kGpuByteLimit, state.hard_memory_limit_in_bytes);
7896 EXPECT_EQ(kGpuResourceLimit, state.num_resources_limit);
7897 }
7898
7899 // Software compositing.
7900 host_impl_->ReleaseOutputSurface();
7901 output_surface_ = FakeOutputSurface::CreateDelegatingSoftware();
7902 host_impl_->InitializeRenderer(output_surface_.get());
7903 {
7904 const auto& state = host_impl_->global_tile_state();
7905 EXPECT_EQ(kSoftwareByteLimit, state.hard_memory_limit_in_bytes);
7906 EXPECT_EQ(kSoftwareResourceLimit, state.num_resources_limit);
7907 EXPECT_EQ(kSoftwareTileCutoff, state.memory_limit_policy);
7908 }
7909
7910 // Not visible, drops to 0.
7911 host_impl_->SetVisible(false);
7912 {
7913 const auto& state = host_impl_->global_tile_state();
7914 EXPECT_EQ(0u, state.hard_memory_limit_in_bytes);
7915 EXPECT_EQ(kSoftwareResourceLimit, state.num_resources_limit);
7916 EXPECT_EQ(kNothingTileCutoff, state.memory_limit_policy);
7917 }
7918
7919 // Visible, is the software limit again.
7920 host_impl_->SetVisible(true);
7921 {
7922 const auto& state = host_impl_->global_tile_state();
7923 EXPECT_EQ(kSoftwareByteLimit, state.hard_memory_limit_in_bytes);
7924 EXPECT_EQ(kSoftwareResourceLimit, state.num_resources_limit);
7925 EXPECT_EQ(kSoftwareTileCutoff, state.memory_limit_policy);
7926 }
[email protected]fd32d122013-06-29 13:11:047927}
7928
[email protected]10608052014-05-13 21:30:037929TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) {
7930 ASSERT_TRUE(host_impl_->active_tree());
7931
sohan.jyoti9d1e4202014-09-23 21:02:337932 // RequiresHighResToDraw is set when new output surface is used.
vmpstr61ed94a12014-10-09 04:49:307933 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
sohan.jyoti9d1e4202014-09-23 21:02:337934
vmpstr61ed94a12014-10-09 04:49:307935 host_impl_->ResetRequiresHighResToDraw();
sohan.jyoti9d1e4202014-09-23 21:02:337936
[email protected]10608052014-05-13 21:30:037937 host_impl_->SetVisible(false);
vmpstr61ed94a12014-10-09 04:49:307938 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037939 host_impl_->SetVisible(true);
vmpstr61ed94a12014-10-09 04:49:307940 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037941 host_impl_->SetVisible(false);
vmpstr61ed94a12014-10-09 04:49:307942 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037943
vmpstr61ed94a12014-10-09 04:49:307944 host_impl_->ResetRequiresHighResToDraw();
[email protected]10608052014-05-13 21:30:037945
vmpstr61ed94a12014-10-09 04:49:307946 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037947 host_impl_->SetVisible(true);
vmpstr61ed94a12014-10-09 04:49:307948 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]10608052014-05-13 21:30:037949}
7950
[email protected]13525d62014-05-20 21:22:047951TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
7952 ASSERT_TRUE(host_impl_->active_tree());
7953 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
7954
sohan.jyoti9d1e4202014-09-23 21:02:337955 // RequiresHighResToDraw is set when new output surface is used.
vmpstr61ed94a12014-10-09 04:49:307956 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
sohan.jyoti9d1e4202014-09-23 21:02:337957
vmpstr61ed94a12014-10-09 04:49:307958 host_impl_->ResetRequiresHighResToDraw();
sohan.jyoti9d1e4202014-09-23 21:02:337959
senorblanco9c04acb2015-05-15 19:41:327960 host_impl_->SetContentIsSuitableForGpuRasterization(true);
7961 host_impl_->SetHasGpuRasterizationTrigger(false);
danakj1a86f6d62016-08-17 20:10:407962 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307963 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
senorblanco9c04acb2015-05-15 19:41:327964 host_impl_->SetHasGpuRasterizationTrigger(true);
danakj1a86f6d62016-08-17 20:10:407965 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307966 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
senorblanco9c04acb2015-05-15 19:41:327967 host_impl_->SetHasGpuRasterizationTrigger(false);
danakj1a86f6d62016-08-17 20:10:407968 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307969 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]13525d62014-05-20 21:22:047970
vmpstr61ed94a12014-10-09 04:49:307971 host_impl_->ResetRequiresHighResToDraw();
[email protected]13525d62014-05-20 21:22:047972
vmpstr61ed94a12014-10-09 04:49:307973 EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
senorblanco9c04acb2015-05-15 19:41:327974 host_impl_->SetHasGpuRasterizationTrigger(true);
danakj1a86f6d62016-08-17 20:10:407975 host_impl_->CommitComplete();
vmpstr61ed94a12014-10-09 04:49:307976 EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
[email protected]13525d62014-05-20 21:22:047977}
7978
vmiura59ea9b4042014-12-09 20:50:397979class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest {
[email protected]222c6782013-09-05 22:24:497980 public:
danakjaeb95062014-11-14 01:35:367981 void SetUp() override {
danakj431a1202015-06-17 19:09:337982 fake_host_impl_ =
khushalsagarb64b360d2015-10-21 19:25:167983 new FakeLayerTreeHostImpl(LayerTreeSettings(), &task_runner_provider_,
danakj431a1202015-06-17 19:09:337984 &shared_bitmap_manager_, &task_graph_runner_);
[email protected]222c6782013-09-05 22:24:497985 host_impl_.reset(fake_host_impl_);
revemand180dfc32015-09-24 00:19:437986 output_surface_ = CreateOutputSurface();
sievers71c62dd52015-10-07 01:44:397987 host_impl_->SetVisible(true);
revemand180dfc32015-09-24 00:19:437988 host_impl_->InitializeRenderer(output_surface_.get());
[email protected]222c6782013-09-05 22:24:497989 host_impl_->SetViewportSize(gfx::Size(10, 10));
7990 }
7991
7992 FakeLayerTreeHostImpl* fake_host_impl_;
7993};
7994
vmiura59ea9b4042014-12-09 20:50:397995TEST_F(LayerTreeHostImplTestPrepareTiles, PrepareTilesWhenInvisible) {
vmiura59ea9b4042014-12-09 20:50:397996 EXPECT_TRUE(fake_host_impl_->prepare_tiles_needed());
sievers71c62dd52015-10-07 01:44:397997 host_impl_->SetVisible(false);
vmiura59ea9b4042014-12-09 20:50:397998 EXPECT_FALSE(fake_host_impl_->prepare_tiles_needed());
sievers71c62dd52015-10-07 01:44:397999 host_impl_->SetVisible(true);
8000 EXPECT_TRUE(fake_host_impl_->prepare_tiles_needed());
[email protected]222c6782013-09-05 22:24:498001}
8002
[email protected]c9280762013-08-01 06:28:578003TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
danakj60bc3bc2016-04-09 00:24:488004 std::unique_ptr<TestWebGraphicsContext3D> context =
[email protected]c9280762013-08-01 06:28:578005 TestWebGraphicsContext3D::Create();
8006 TestWebGraphicsContext3D* context3d = context.get();
danakj60bc3bc2016-04-09 00:24:488007 std::unique_ptr<FakeOutputSurface> output_surface =
danakjf33ceec2016-07-20 20:04:458008 FakeOutputSurface::CreateDelegating3d();
danakja04855a2015-11-18 20:39:108009 CreateHostImpl(DefaultSettings(), std::move(output_surface));
[email protected]c9280762013-08-01 06:28:578010
8011 EXPECT_EQ(0u, context3d->NumTextures());
8012
8013 UIResourceId ui_resource_id = 1;
[email protected]0046982c2014-03-25 22:00:518014 bool is_opaque = false;
8015 UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
[email protected]c9280762013-08-01 06:28:578016 host_impl_->CreateUIResource(ui_resource_id, bitmap);
8017 EXPECT_EQ(1u, context3d->NumTextures());
jbaumanbbd425e2015-05-19 00:33:358018 ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
[email protected]c9280762013-08-01 06:28:578019 EXPECT_NE(0u, id1);
8020
8021 // Multiple requests with the same id is allowed. The previous texture is
8022 // deleted.
8023 host_impl_->CreateUIResource(ui_resource_id, bitmap);
8024 EXPECT_EQ(1u, context3d->NumTextures());
jbaumanbbd425e2015-05-19 00:33:358025 ResourceId id2 = host_impl_->ResourceIdForUIResource(ui_resource_id);
[email protected]c9280762013-08-01 06:28:578026 EXPECT_NE(0u, id2);
8027 EXPECT_NE(id1, id2);
8028
8029 // Deleting invalid UIResourceId is allowed and does not change state.
8030 host_impl_->DeleteUIResource(-1);
8031 EXPECT_EQ(1u, context3d->NumTextures());
8032
8033 // Should return zero for invalid UIResourceId. Number of textures should
8034 // not change.
8035 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
8036 EXPECT_EQ(1u, context3d->NumTextures());
8037
8038 host_impl_->DeleteUIResource(ui_resource_id);
8039 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
8040 EXPECT_EQ(0u, context3d->NumTextures());
8041
8042 // Should not change state for multiple deletion on one UIResourceId
8043 host_impl_->DeleteUIResource(ui_resource_id);
8044 EXPECT_EQ(0u, context3d->NumTextures());
8045}
8046
[email protected]6be50ba82013-11-08 12:04:128047TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
danakj60bc3bc2016-04-09 00:24:488048 std::unique_ptr<TestWebGraphicsContext3D> context =
[email protected]6be50ba82013-11-08 12:04:128049 TestWebGraphicsContext3D::Create();
8050 TestWebGraphicsContext3D* context3d = context.get();
danakjf33ceec2016-07-20 20:04:458051 CreateHostImpl(DefaultSettings(), FakeOutputSurface::CreateDelegating3d());
[email protected]6be50ba82013-11-08 12:04:128052
8053 EXPECT_EQ(0u, context3d->NumTextures());
8054
[email protected]80ee2332014-02-06 18:31:078055 gfx::Size size(4, 4);
8056 // SkImageInfo has no support for ETC1. The |info| below contains the right
8057 // total pixel size for the bitmap but not the right height and width. The
8058 // correct width/height are passed directly to UIResourceBitmap.
[email protected]7bc1c512014-01-23 01:15:278059 SkImageInfo info =
[email protected]80ee2332014-02-06 18:31:078060 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType);
tomhudson992ec28b2016-04-27 16:45:398061 sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::NewAllocate(info, 0, 0));
[email protected]7bc1c512014-01-23 01:15:278062 pixel_ref->setImmutable();
tomhudson992ec28b2016-04-27 16:45:398063 UIResourceBitmap bitmap(std::move(pixel_ref), size);
[email protected]6be50ba82013-11-08 12:04:128064 UIResourceId ui_resource_id = 1;
8065 host_impl_->CreateUIResource(ui_resource_id, bitmap);
8066 EXPECT_EQ(1u, context3d->NumTextures());
jbaumanbbd425e2015-05-19 00:33:358067 ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
[email protected]6be50ba82013-11-08 12:04:128068 EXPECT_NE(0u, id1);
8069}
8070
danakj60bc3bc2016-04-09 00:24:488071void ShutdownReleasesContext_Callback(
8072 std::unique_ptr<CopyOutputResult> result) {}
[email protected]ea468c6c2013-09-10 08:25:118073
8074TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
8075 scoped_refptr<TestContextProvider> context_provider =
8076 TestContextProvider::Create();
8077
danakjf33ceec2016-07-20 20:04:458078 CreateHostImpl(
8079 DefaultSettings(),
8080 base::MakeUnique<TestDelegatingOutputSurface>(
8081 context_provider, TestContextProvider::CreateWorker(),
8082 FakeOutputSurface::Create3d(context_provider), nullptr, nullptr,
8083 RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(),
danakj014316e2016-08-04 18:40:268084 true /* synchronous_composite */,
8085 false /* force_disable_reclaim_resources */));
[email protected]ea468c6c2013-09-10 08:25:118086
8087 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
8088
jaydasikabf1875a2016-06-28 03:39:598089 LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing();
ajumae6f541b2016-05-31 16:50:508090 root->test_properties()->copy_requests.push_back(
8091 CopyOutputRequest::CreateRequest(
8092 base::Bind(&ShutdownReleasesContext_Callback)));
danakj74af409e2016-07-01 00:41:488093 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]ea468c6c2013-09-10 08:25:118094
8095 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:488096 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
mithro248d1722015-05-05 05:23:458097 host_impl_->DrawLayers(&frame);
[email protected]ea468c6c2013-09-10 08:25:118098 host_impl_->DidDrawAllLayers(frame);
[email protected]ea468c6c2013-09-10 08:25:118099
8100 // The CopyOutputResult's callback has a ref on the ContextProvider and a
8101 // texture in a texture mailbox.
8102 EXPECT_FALSE(context_provider->HasOneRef());
8103 EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
8104
danakjee6547a22016-07-01 20:41:508105 host_impl_->ReleaseOutputSurface();
danakjf446a072014-09-27 21:55:488106 host_impl_ = nullptr;
[email protected]ea468c6c2013-09-10 08:25:118107
8108 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
8109 // released, and the texture deleted.
8110 EXPECT_TRUE(context_provider->HasOneRef());
8111 EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
8112}
8113
[email protected]df0c42342013-10-08 20:52:128114TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) {
8115 // When flinging via touch, only the child should scroll (we should not
8116 // bubble).
8117 gfx::Size surface_size(10, 10);
8118 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:488119 std::unique_ptr<LayerImpl> root_ptr =
sunxd676696572016-01-07 16:28:308120 LayerImpl::Create(host_impl_->active_tree(), 4);
danakj60bc3bc2016-04-09 00:24:488121 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:478122 LayerImpl::Create(host_impl_->active_tree(), 3);
jaydasika6b5a32bf2016-04-22 21:56:368123 root_clip->test_properties()->force_render_surface = true;
awoloszyne83f28c2014-12-22 15:40:008124
danakj60bc3bc2016-04-09 00:24:488125 std::unique_ptr<LayerImpl> root_scroll =
[email protected]adeda572014-01-31 00:49:478126 CreateScrollableLayer(1, content_size, root_clip.get());
jaydasikaca2605e2016-04-23 02:52:528127 root_scroll->test_properties()->is_container_for_fixed_position_layers = true;
danakj60bc3bc2016-04-09 00:24:488128 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:478129 CreateScrollableLayer(2, content_size, root_clip.get());
[email protected]df0c42342013-10-08 20:52:128130
jaydasika89f7b5a2016-06-22 02:08:398131 root_scroll->test_properties()->AddChild(std::move(child));
sunxd676696572016-01-07 16:28:308132 int root_id = root_scroll->id();
jaydasika89f7b5a2016-06-22 02:08:398133 root_clip->test_properties()->AddChild(std::move(root_scroll));
8134 root_ptr->test_properties()->AddChild(std::move(root_clip));
[email protected]df0c42342013-10-08 20:52:128135
8136 host_impl_->SetViewportSize(surface_size);
jaydasikabf1875a2016-06-28 03:39:598137 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr));
sunxd676696572016-01-07 16:28:308138 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 1,
ccameron8230b68b2014-11-21 19:25:188139 Layer::INVALID_ID);
danakj74af409e2016-07-01 00:41:488140 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]df0c42342013-10-08 20:52:128141 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:368142 DrawFrame();
[email protected]df0c42342013-10-08 20:52:128143 {
tdresser81e84c672016-01-18 23:21:228144 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038145 host_impl_
8146 ->ScrollBegin(BeginState(gfx::Point()).get(),
8147 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228148 .thread);
[email protected]df0c42342013-10-08 20:52:128149
tdresser81e84c672016-01-18 23:21:228150 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
8151 host_impl_->FlingScrollBegin().thread);
[email protected]df0c42342013-10-08 20:52:128152
8153 gfx::Vector2d scroll_delta(0, 100);
majidvp944a8cd2016-01-12 21:05:188154 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
8155 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]df0c42342013-10-08 20:52:128156
majidvp944a8cd2016-01-12 21:05:188157 host_impl_->ScrollEnd(EndState().get());
[email protected]df0c42342013-10-08 20:52:128158
danakj60bc3bc2016-04-09 00:24:488159 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]df0c42342013-10-08 20:52:128160 host_impl_->ProcessScrollDeltas();
8161
8162 // Only the child should have scrolled.
8163 ASSERT_EQ(1u, scroll_info->scrolls.size());
[email protected]adeda572014-01-31 00:49:478164 ExpectNone(*scroll_info.get(), root_id);
[email protected]df0c42342013-10-08 20:52:128165 }
8166}
8167
tdressera3b162b82015-09-29 17:51:438168TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) {
[email protected]db102612013-12-20 22:04:128169 // Scroll a child layer beyond its maximum scroll range and make sure the
8170 // the scroll doesn't bubble up to the parent layer.
[email protected]d41d7cb92013-10-15 16:08:098171 gfx::Size surface_size(10, 10);
danakj60bc3bc2016-04-09 00:24:488172 std::unique_ptr<LayerImpl> root =
8173 LayerImpl::Create(host_impl_->active_tree(), 1);
jaydasika6b5a32bf2016-04-22 21:56:368174 root->test_properties()->force_render_surface = true;
[email protected]d41d7cb92013-10-15 16:08:098175
danakj74af409e2016-07-01 00:41:488176 std::unique_ptr<LayerImpl> root_scrolling_owned =
8177 CreateScrollableLayer(2, surface_size, root.get());
8178 auto* root_scrolling = root_scrolling_owned.get();
8179 root->test_properties()->AddChild(std::move(root_scrolling_owned));
8180
8181 std::unique_ptr<LayerImpl> child_owned =
8182 CreateScrollableLayer(3, surface_size, root.get());
8183 auto* child = child_owned.get();
8184 root_scrolling->test_properties()->AddChild(std::move(child_owned));
8185
8186 std::unique_ptr<LayerImpl> grand_child_owned =
[email protected]adeda572014-01-31 00:49:478187 CreateScrollableLayer(4, surface_size, root.get());
danakj74af409e2016-07-01 00:41:488188 auto* grand_child = grand_child_owned.get();
8189 child->test_properties()->AddChild(std::move(grand_child_owned));
8190
8191 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
8192 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8193 host_impl_->active_tree()->DidBecomeActive();
8194
8195 child->layer_tree_impl()
8196 ->property_trees()
8197 ->scroll_tree.UpdateScrollOffsetBaseForTesting(child->id(),
8198 gfx::ScrollOffset(0, 4));
sunxdb7e79432016-03-09 21:13:428199 grand_child->layer_tree_impl()
8200 ->property_trees()
8201 ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->id(),
8202 gfx::ScrollOffset(0, 2));
[email protected]d41d7cb92013-10-15 16:08:098203
[email protected]db102612013-12-20 22:04:128204 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:368205 DrawFrame();
[email protected]d41d7cb92013-10-15 16:08:098206 {
danakj60bc3bc2016-04-09 00:24:488207 std::unique_ptr<ScrollAndScaleSet> scroll_info;
jaydasikafc66cfb2016-06-10 04:34:228208 LayerImpl* child = host_impl_->active_tree()
jaydasikabf1875a2016-06-28 03:39:598209 ->root_layer_for_testing()
jaydasikafc66cfb2016-06-10 04:34:228210 ->test_properties()
8211 ->children[0]
8212 ->test_properties()
8213 ->children[0];
8214 LayerImpl* grand_child = child->test_properties()->children[0];
[email protected]db102612013-12-20 22:04:128215
8216 gfx::Vector2d scroll_delta(0, -2);
tdresser81e84c672016-01-18 23:21:228217 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038218 host_impl_
8219 ->ScrollBegin(BeginState(gfx::Point()).get(),
8220 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228221 .thread);
majidvp944a8cd2016-01-12 21:05:188222 EXPECT_TRUE(
8223 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8224 .did_scroll);
[email protected]d41d7cb92013-10-15 16:08:098225
[email protected]db102612013-12-20 22:04:128226 // The grand child should have scrolled up to its limit.
[email protected]d41d7cb92013-10-15 16:08:098227 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]db102612013-12-20 22:04:128228 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:188229 EXPECT_TRUE(
8230 ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
[email protected]db102612013-12-20 22:04:128231 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
8232
tdressera3b162b82015-09-29 17:51:438233 // The locked scrolling layer should remain set as the grand child.
majidvp944a8cd2016-01-12 21:05:188234 EXPECT_FALSE(
8235 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8236 .did_scroll);
[email protected]db102612013-12-20 22:04:128237 scroll_info = host_impl_->ProcessScrollDeltas();
tdressera3b162b82015-09-29 17:51:438238 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:188239 EXPECT_TRUE(
8240 ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
tdressera3b162b82015-09-29 17:51:438241 ExpectNone(*scroll_info, child->id());
[email protected]db102612013-12-20 22:04:128242 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
8243
tdresser81e84c672016-01-18 23:21:228244 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
8245 host_impl_->FlingScrollBegin().thread);
majidvp944a8cd2016-01-12 21:05:188246 EXPECT_FALSE(
8247 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8248 .did_scroll);
tdressera3b162b82015-09-29 17:51:438249 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
[email protected]db102612013-12-20 22:04:128250
tdressera3b162b82015-09-29 17:51:438251 // The child should not have scrolled.
[email protected]db102612013-12-20 22:04:128252 scroll_info = host_impl_->ProcessScrollDeltas();
tdressera3b162b82015-09-29 17:51:438253 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:188254 EXPECT_TRUE(
8255 ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
tdressera3b162b82015-09-29 17:51:438256 ExpectNone(*scroll_info, child->id());
[email protected]db102612013-12-20 22:04:128257
8258 // As the locked layer is at it's limit, no further scrolling can occur.
majidvp944a8cd2016-01-12 21:05:188259 EXPECT_FALSE(
8260 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
8261 .did_scroll);
tdressera3b162b82015-09-29 17:51:438262 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
majidvp944a8cd2016-01-12 21:05:188263 host_impl_->ScrollEnd(EndState().get());
[email protected]d41d7cb92013-10-15 16:08:098264 }
8265}
8266
tdressera3b162b82015-09-29 17:51:438267TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) {
8268 // When flinging via wheel, we shouldn't bubble.
[email protected]df0c42342013-10-08 20:52:128269 gfx::Size surface_size(10, 10);
8270 gfx::Size content_size(20, 20);
danakj60bc3bc2016-04-09 00:24:488271 std::unique_ptr<LayerImpl> root_clip =
[email protected]adeda572014-01-31 00:49:478272 LayerImpl::Create(host_impl_->active_tree(), 3);
jaydasika6b5a32bf2016-04-22 21:56:368273 root_clip->test_properties()->force_render_surface = true;
danakj60bc3bc2016-04-09 00:24:488274 std::unique_ptr<LayerImpl> root_scroll =
[email protected]adeda572014-01-31 00:49:478275 CreateScrollableLayer(1, content_size, root_clip.get());
8276 int root_scroll_id = root_scroll->id();
danakj60bc3bc2016-04-09 00:24:488277 std::unique_ptr<LayerImpl> child =
[email protected]adeda572014-01-31 00:49:478278 CreateScrollableLayer(2, content_size, root_clip.get());
[email protected]df0c42342013-10-08 20:52:128279
jaydasika89f7b5a2016-06-22 02:08:398280 root_scroll->test_properties()->AddChild(std::move(child));
8281 root_clip->test_properties()->AddChild(std::move(root_scroll));
[email protected]df0c42342013-10-08 20:52:128282
jaydasikabf1875a2016-06-28 03:39:598283 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip));
danakj74af409e2016-07-01 00:41:488284 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]df0c42342013-10-08 20:52:128285 host_impl_->active_tree()->DidBecomeActive();
danakj74af409e2016-07-01 00:41:488286
8287 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:368288 DrawFrame();
[email protected]df0c42342013-10-08 20:52:128289 {
tdresser81e84c672016-01-18 23:21:228290 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188291 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228292 InputHandler::WHEEL)
8293 .thread);
[email protected]df0c42342013-10-08 20:52:128294
tdresser81e84c672016-01-18 23:21:228295 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
8296 host_impl_->FlingScrollBegin().thread);
[email protected]df0c42342013-10-08 20:52:128297
8298 gfx::Vector2d scroll_delta(0, 100);
majidvp944a8cd2016-01-12 21:05:188299 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
8300 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
[email protected]df0c42342013-10-08 20:52:128301
majidvp944a8cd2016-01-12 21:05:188302 host_impl_->ScrollEnd(EndState().get());
[email protected]df0c42342013-10-08 20:52:128303
danakj60bc3bc2016-04-09 00:24:488304 std::unique_ptr<ScrollAndScaleSet> scroll_info =
[email protected]df0c42342013-10-08 20:52:128305 host_impl_->ProcessScrollDeltas();
8306
tdressera3b162b82015-09-29 17:51:438307 // The root shouldn't have scrolled.
8308 ASSERT_EQ(1u, scroll_info->scrolls.size());
8309 ExpectNone(*scroll_info.get(), root_scroll_id);
[email protected]df0c42342013-10-08 20:52:128310 }
8311}
8312
[email protected]05ba53c2014-04-16 21:22:518313TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) {
8314 // If we ray cast a scroller that is not on the first layer's ancestor chain,
ericrk7c030992015-02-20 01:39:388315 // we should return SCROLL_UNKNOWN.
[email protected]05ba53c2014-04-16 21:22:518316 gfx::Size content_size(100, 100);
8317 SetupScrollAndContentsLayers(content_size);
8318
8319 int scroll_layer_id = 2;
8320 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108321 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]05ba53c2014-04-16 21:22:518322 scroll_layer->SetDrawsContent(true);
8323
8324 int page_scale_layer_id = 5;
8325 LayerImpl* page_scale_layer =
vollickcb3f6b12016-03-01 23:44:108326 host_impl_->active_tree()->LayerById(page_scale_layer_id);
[email protected]05ba53c2014-04-16 21:22:518327
8328 int occluder_layer_id = 6;
danakj60bc3bc2016-04-09 00:24:488329 std::unique_ptr<LayerImpl> occluder_layer =
[email protected]05ba53c2014-04-16 21:22:518330 LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
8331 occluder_layer->SetDrawsContent(true);
8332 occluder_layer->SetBounds(content_size);
[email protected]05ba53c2014-04-16 21:22:518333 occluder_layer->SetPosition(gfx::PointF());
[email protected]05ba53c2014-04-16 21:22:518334
8335 // The parent of the occluder is *above* the scroller.
jaydasika89f7b5a2016-06-22 02:08:398336 page_scale_layer->test_properties()->AddChild(std::move(occluder_layer));
danakj74af409e2016-07-01 00:41:488337 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]05ba53c2014-04-16 21:22:518338
8339 DrawFrame();
8340
tdresser81e84c672016-01-18 23:21:228341 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
8342 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
8343 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
danakj35904762016-01-21 20:49:408344 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
tdresser81e84c672016-01-18 23:21:228345 status.main_thread_scrolling_reasons);
[email protected]05ba53c2014-04-16 21:22:518346}
8347
8348TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
8349 // If we ray cast a scroller this is on the first layer's ancestor chain, but
8350 // is not the first scroller we encounter when walking up from the layer, we
ericrk7c030992015-02-20 01:39:388351 // should also return SCROLL_UNKNOWN.
[email protected]05ba53c2014-04-16 21:22:518352 gfx::Size content_size(100, 100);
8353 SetupScrollAndContentsLayers(content_size);
8354
8355 int scroll_layer_id = 2;
8356 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108357 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]05ba53c2014-04-16 21:22:518358 scroll_layer->SetDrawsContent(true);
8359
8360 int occluder_layer_id = 6;
danakj60bc3bc2016-04-09 00:24:488361 std::unique_ptr<LayerImpl> occluder_layer =
[email protected]05ba53c2014-04-16 21:22:518362 LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
8363 occluder_layer->SetDrawsContent(true);
8364 occluder_layer->SetBounds(content_size);
[email protected]28336d52014-05-12 19:07:288365 occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f));
[email protected]05ba53c2014-04-16 21:22:518366
8367 int child_scroll_clip_layer_id = 7;
danakj60bc3bc2016-04-09 00:24:488368 std::unique_ptr<LayerImpl> child_scroll_clip =
[email protected]05ba53c2014-04-16 21:22:518369 LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id);
8370
8371 int child_scroll_layer_id = 8;
danakj60bc3bc2016-04-09 00:24:488372 std::unique_ptr<LayerImpl> child_scroll = CreateScrollableLayer(
[email protected]05ba53c2014-04-16 21:22:518373 child_scroll_layer_id, content_size, child_scroll_clip.get());
8374
[email protected]28336d52014-05-12 19:07:288375 child_scroll->SetPosition(gfx::PointF(10.f, 10.f));
[email protected]05ba53c2014-04-16 21:22:518376
jaydasika89f7b5a2016-06-22 02:08:398377 child_scroll->test_properties()->AddChild(std::move(occluder_layer));
8378 child_scroll_clip->test_properties()->AddChild(std::move(child_scroll));
8379 scroll_layer->test_properties()->AddChild(std::move(child_scroll_clip));
danakj74af409e2016-07-01 00:41:488380 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]05ba53c2014-04-16 21:22:518381
8382 DrawFrame();
8383
tdresser81e84c672016-01-18 23:21:228384 InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
8385 BeginState(gfx::Point()).get(), InputHandler::WHEEL);
8386 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
danakj35904762016-01-21 20:49:408387 EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
tdresser81e84c672016-01-18 23:21:228388 status.main_thread_scrolling_reasons);
[email protected]05ba53c2014-04-16 21:22:518389}
8390
majidvp6cfcc362015-03-06 20:46:398391TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) {
[email protected]28336d52014-05-12 19:07:288392 gfx::Size content_size(100, 100);
8393 SetupScrollAndContentsLayers(content_size);
8394
vollickcb3f6b12016-03-01 23:44:108395 LayerImpl* root = host_impl_->active_tree()->LayerById(1);
[email protected]28336d52014-05-12 19:07:288396
8397 int scroll_layer_id = 2;
8398 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108399 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]28336d52014-05-12 19:07:288400
8401 int child_scroll_layer_id = 7;
danakj60bc3bc2016-04-09 00:24:488402 std::unique_ptr<LayerImpl> child_scroll =
[email protected]28336d52014-05-12 19:07:288403 CreateScrollableLayer(child_scroll_layer_id, content_size, root);
8404 child_scroll->SetDrawsContent(false);
8405
jaydasika89f7b5a2016-06-22 02:08:398406 scroll_layer->test_properties()->AddChild(std::move(child_scroll));
danakj74af409e2016-07-01 00:41:488407 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]28336d52014-05-12 19:07:288408
8409 DrawFrame();
8410
8411 // We should not have scrolled |child_scroll| even though we technically "hit"
8412 // it. The reason for this is that if the scrolling the scroll would not move
8413 // any layer that is a drawn RSLL member, then we can ignore the hit.
8414 //
ericrk7c030992015-02-20 01:39:388415 // Why SCROLL_STARTED? In this case, it's because we've bubbled out and
majidvp6cfcc362015-03-06 20:46:398416 // started scrolling the inner viewport.
tdresser81e84c672016-01-18 23:21:228417 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188418 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228419 InputHandler::WHEEL)
8420 .thread);
[email protected]28336d52014-05-12 19:07:288421
8422 EXPECT_EQ(2, host_impl_->CurrentlyScrollingLayer()->id());
8423}
8424
majidvp6cfcc362015-03-06 20:46:398425TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleDescendent) {
8426 gfx::Size content_size(100, 100);
8427 SetupScrollAndContentsLayers(content_size);
8428
vollickcb3f6b12016-03-01 23:44:108429 LayerImpl* root = host_impl_->active_tree()->LayerById(1);
8430 LayerImpl* root_scroll_layer = host_impl_->active_tree()->LayerById(2);
majidvp6cfcc362015-03-06 20:46:398431
danakj60bc3bc2016-04-09 00:24:488432 std::unique_ptr<LayerImpl> invisible_scroll_layer =
majidvp6cfcc362015-03-06 20:46:398433 CreateScrollableLayer(7, content_size, root);
8434 invisible_scroll_layer->SetDrawsContent(false);
8435
danakj60bc3bc2016-04-09 00:24:488436 std::unique_ptr<LayerImpl> child_layer =
majidvp6cfcc362015-03-06 20:46:398437 LayerImpl::Create(host_impl_->active_tree(), 8);
8438 child_layer->SetDrawsContent(false);
8439
danakj60bc3bc2016-04-09 00:24:488440 std::unique_ptr<LayerImpl> grand_child_layer =
majidvp6cfcc362015-03-06 20:46:398441 LayerImpl::Create(host_impl_->active_tree(), 9);
8442 grand_child_layer->SetDrawsContent(true);
8443 grand_child_layer->SetBounds(content_size);
majidvp6cfcc362015-03-06 20:46:398444 // Move the grand child so it's not hit by our test point.
8445 grand_child_layer->SetPosition(gfx::PointF(10.f, 10.f));
8446
jaydasika89f7b5a2016-06-22 02:08:398447 child_layer->test_properties()->AddChild(std::move(grand_child_layer));
8448 invisible_scroll_layer->test_properties()->AddChild(std::move(child_layer));
8449 root_scroll_layer->test_properties()->AddChild(
8450 std::move(invisible_scroll_layer));
danakj74af409e2016-07-01 00:41:488451 host_impl_->active_tree()->BuildPropertyTreesForTesting();
majidvp6cfcc362015-03-06 20:46:398452
8453 DrawFrame();
8454
8455 // We should have scrolled |invisible_scroll_layer| as it was hit and it has
8456 // a descendant which is a drawn RSLL member.
tdresser81e84c672016-01-18 23:21:228457 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188458 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228459 InputHandler::WHEEL)
8460 .thread);
majidvp6cfcc362015-03-06 20:46:398461
8462 EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id());
8463}
8464
[email protected]28336d52014-05-12 19:07:288465TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) {
8466 // This test case is very similar to the one above with one key difference:
8467 // the invisible scroller has a scroll child that is indeed draw contents.
8468 // If we attempt to initiate a gesture scroll off of the visible scroll child
8469 // we should still start the scroll child.
8470 gfx::Size content_size(100, 100);
8471 SetupScrollAndContentsLayers(content_size);
8472
vollickcb3f6b12016-03-01 23:44:108473 LayerImpl* root = host_impl_->active_tree()->LayerById(1);
[email protected]28336d52014-05-12 19:07:288474
8475 int scroll_layer_id = 2;
8476 LayerImpl* scroll_layer =
vollickcb3f6b12016-03-01 23:44:108477 host_impl_->active_tree()->LayerById(scroll_layer_id);
[email protected]28336d52014-05-12 19:07:288478
8479 int scroll_child_id = 6;
danakj60bc3bc2016-04-09 00:24:488480 std::unique_ptr<LayerImpl> scroll_child =
[email protected]28336d52014-05-12 19:07:288481 LayerImpl::Create(host_impl_->active_tree(), scroll_child_id);
8482 scroll_child->SetDrawsContent(true);
8483 scroll_child->SetBounds(content_size);
[email protected]28336d52014-05-12 19:07:288484 // Move the scroll child so it's not hit by our test point.
8485 scroll_child->SetPosition(gfx::PointF(10.f, 10.f));
[email protected]28336d52014-05-12 19:07:288486
8487 int invisible_scroll_layer_id = 7;
danakj60bc3bc2016-04-09 00:24:488488 std::unique_ptr<LayerImpl> invisible_scroll =
[email protected]28336d52014-05-12 19:07:288489 CreateScrollableLayer(invisible_scroll_layer_id, content_size, root);
8490 invisible_scroll->SetDrawsContent(false);
8491
8492 int container_id = 8;
danakj60bc3bc2016-04-09 00:24:488493 std::unique_ptr<LayerImpl> container =
[email protected]28336d52014-05-12 19:07:288494 LayerImpl::Create(host_impl_->active_tree(), container_id);
8495
danakj60bc3bc2016-04-09 00:24:488496 std::unique_ptr<std::set<LayerImpl*>> scroll_children(
8497 new std::set<LayerImpl*>);
[email protected]28336d52014-05-12 19:07:288498 scroll_children->insert(scroll_child.get());
jaydasika1c0a27d42016-04-28 01:54:568499 invisible_scroll->test_properties()->scroll_children.reset(
8500 scroll_children.release());
[email protected]28336d52014-05-12 19:07:288501
jaydasika1c0a27d42016-04-28 01:54:568502 scroll_child->test_properties()->scroll_parent = invisible_scroll.get();
[email protected]28336d52014-05-12 19:07:288503
jaydasika89f7b5a2016-06-22 02:08:398504 container->test_properties()->AddChild(std::move(invisible_scroll));
8505 container->test_properties()->AddChild(std::move(scroll_child));
[email protected]28336d52014-05-12 19:07:288506
jaydasika89f7b5a2016-06-22 02:08:398507 scroll_layer->test_properties()->AddChild(std::move(container));
danakj74af409e2016-07-01 00:41:488508 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]28336d52014-05-12 19:07:288509
8510 DrawFrame();
8511
majidvp6cfcc362015-03-06 20:46:398512 // We should have scrolled |child_scroll| even though it is invisible.
8513 // The reason for this is that if the scrolling the scroll would move a layer
8514 // that is a drawn RSLL member, then we should accept this hit.
tdresser81e84c672016-01-18 23:21:228515 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188516 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228517 InputHandler::WHEEL)
8518 .thread);
[email protected]28336d52014-05-12 19:07:288519
8520 EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id());
8521}
8522
[email protected]d359203a2013-11-29 06:16:558523// Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
danakjaecfcfba2016-09-07 22:33:188524// in CompositorFrameMetadata.
[email protected]d359203a2013-11-29 06:16:558525TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
danakj60bc3bc2016-04-09 00:24:488526 std::unique_ptr<SolidColorLayerImpl> root =
[email protected]d359203a2013-11-29 06:16:558527 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]d359203a2013-11-29 06:16:558528 root->SetPosition(gfx::PointF());
8529 root->SetBounds(gfx::Size(10, 10));
[email protected]d359203a2013-11-29 06:16:558530 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:368531 root->test_properties()->force_render_surface = true;
[email protected]d359203a2013-11-29 06:16:558532
jaydasikabf1875a2016-06-28 03:39:598533 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:488534 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]d359203a2013-11-29 06:16:558535
8536 FakeOutputSurface* fake_output_surface =
8537 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
8538
[email protected]d359203a2013-11-29 06:16:558539 ui::LatencyInfo latency_info;
8540 latency_info.AddLatencyNumber(
8541 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0);
danakj60bc3bc2016-04-09 00:24:488542 std::unique_ptr<SwapPromise> swap_promise(
[email protected]6be422b2013-12-08 06:47:318543 new LatencyInfoSwapPromise(latency_info));
danakja04855a2015-11-18 20:39:108544 host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
[email protected]d359203a2013-11-29 06:16:558545
8546 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
8547 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:488548 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjaecfcfba2016-09-07 22:33:188549 EXPECT_TRUE(host_impl_->DrawLayers(&frame));
[email protected]d359203a2013-11-29 06:16:558550 host_impl_->DidDrawAllLayers(frame);
[email protected]d359203a2013-11-29 06:16:558551
[email protected]b76029b2014-01-02 22:56:508552 const std::vector<ui::LatencyInfo>& metadata_latency_after =
fsamueld63137a2016-06-24 23:39:518553 fake_output_surface->last_sent_frame()->metadata.latency_info;
[email protected]b76029b2014-01-02 22:56:508554 EXPECT_EQ(1u, metadata_latency_after.size());
8555 EXPECT_TRUE(metadata_latency_after[0].FindLatency(
[email protected]d359203a2013-11-29 06:16:558556 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL));
8557}
8558
[email protected]19aec372014-07-01 19:08:498559TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
8560 int root_layer_id = 1;
danakj60bc3bc2016-04-09 00:24:488561 std::unique_ptr<SolidColorLayerImpl> root =
[email protected]19aec372014-07-01 19:08:498562 SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
8563 root->SetPosition(gfx::PointF());
8564 root->SetBounds(gfx::Size(10, 10));
[email protected]19aec372014-07-01 19:08:498565 root->SetDrawsContent(true);
jaydasika6b5a32bf2016-04-22 21:56:368566 root->test_properties()->force_render_surface = true;
[email protected]19aec372014-07-01 19:08:498567
jaydasikabf1875a2016-06-28 03:39:598568 host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
danakj74af409e2016-07-01 00:41:488569 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]19aec372014-07-01 19:08:498570
8571 // Ensure the default frame selection bounds are empty.
8572 FakeOutputSurface* fake_output_surface =
8573 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
[email protected]19aec372014-07-01 19:08:498574
8575 // Plumb the layer-local selection bounds.
danakja2fdbc702015-10-20 23:05:248576 gfx::Point selection_top(5, 0);
8577 gfx::Point selection_bottom(5, 5);
jdduke449b5292015-04-23 19:36:448578 LayerSelection selection;
fsamuel5ca57df2016-06-04 00:34:558579 selection.start.type = gfx::SelectionBound::CENTER;
jdduke449b5292015-04-23 19:36:448580 selection.start.layer_id = root_layer_id;
8581 selection.start.edge_bottom = selection_bottom;
8582 selection.start.edge_top = selection_top;
8583 selection.end = selection.start;
8584 host_impl_->active_tree()->RegisterSelection(selection);
[email protected]19aec372014-07-01 19:08:498585
8586 // Trigger a draw-swap sequence.
8587 host_impl_->SetNeedsRedraw();
8588
8589 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
8590 LayerTreeHostImpl::FrameData frame;
danakj74af409e2016-07-01 00:41:488591 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
danakjaecfcfba2016-09-07 22:33:188592 EXPECT_TRUE(host_impl_->DrawLayers(&frame));
[email protected]19aec372014-07-01 19:08:498593 host_impl_->DidDrawAllLayers(frame);
[email protected]19aec372014-07-01 19:08:498594
8595 // Ensure the selection bounds have propagated to the frame metadata.
fsamuel5ca57df2016-06-04 00:34:558596 const Selection<gfx::SelectionBound>& selection_after =
fsamueld63137a2016-06-24 23:39:518597 fake_output_surface->last_sent_frame()->metadata.selection;
fsamuel5ca57df2016-06-04 00:34:558598 EXPECT_EQ(selection.start.type, selection_after.start.type());
8599 EXPECT_EQ(selection.end.type, selection_after.end.type());
8600 EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom());
8601 EXPECT_EQ(gfx::PointF(selection_top), selection_after.start.edge_top());
8602 EXPECT_TRUE(selection_after.start.visible());
8603 EXPECT_TRUE(selection_after.start.visible());
[email protected]19aec372014-07-01 19:08:498604}
8605
[email protected]6be422b2013-12-08 06:47:318606class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
8607 public:
8608 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
8609 LayerTreeHostImpl* layer_tree_host_impl,
8610 int* set_needs_commit_count,
[email protected]dab0a422014-08-13 16:09:468611 int* set_needs_redraw_count,
8612 int* forward_to_main_count)
[email protected]6be422b2013-12-08 06:47:318613 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
8614 set_needs_commit_count_(set_needs_commit_count),
[email protected]dab0a422014-08-13 16:09:468615 set_needs_redraw_count_(set_needs_redraw_count),
8616 forward_to_main_count_(forward_to_main_count) {}
[email protected]6be422b2013-12-08 06:47:318617
dcheng716bedf2014-10-21 09:51:088618 ~SimpleSwapPromiseMonitor() override {}
[email protected]6be422b2013-12-08 06:47:318619
dcheng716bedf2014-10-21 09:51:088620 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
[email protected]6be422b2013-12-08 06:47:318621
dcheng716bedf2014-10-21 09:51:088622 void OnSetNeedsRedrawOnImpl() override { (*set_needs_redraw_count_)++; }
[email protected]6be422b2013-12-08 06:47:318623
dcheng716bedf2014-10-21 09:51:088624 void OnForwardScrollUpdateToMainThreadOnImpl() override {
[email protected]dab0a422014-08-13 16:09:468625 (*forward_to_main_count_)++;
8626 }
8627
[email protected]6be422b2013-12-08 06:47:318628 private:
8629 int* set_needs_commit_count_;
8630 int* set_needs_redraw_count_;
[email protected]dab0a422014-08-13 16:09:468631 int* forward_to_main_count_;
[email protected]6be422b2013-12-08 06:47:318632};
8633
8634TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) {
8635 int set_needs_commit_count = 0;
8636 int set_needs_redraw_count = 0;
[email protected]dab0a422014-08-13 16:09:468637 int forward_to_main_count = 0;
[email protected]6be422b2013-12-08 06:47:318638
8639 {
danakj60bc3bc2016-04-09 00:24:488640 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8641 new SimpleSwapPromiseMonitor(
8642 NULL, host_impl_.get(), &set_needs_commit_count,
8643 &set_needs_redraw_count, &forward_to_main_count));
[email protected]6be422b2013-12-08 06:47:318644 host_impl_->SetNeedsRedraw();
8645 EXPECT_EQ(0, set_needs_commit_count);
8646 EXPECT_EQ(1, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468647 EXPECT_EQ(0, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318648 }
8649
8650 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
8651 // monitored.
8652 host_impl_->SetNeedsRedraw();
8653 EXPECT_EQ(0, set_needs_commit_count);
8654 EXPECT_EQ(1, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468655 EXPECT_EQ(0, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318656
8657 {
danakj60bc3bc2016-04-09 00:24:488658 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8659 new SimpleSwapPromiseMonitor(
8660 NULL, host_impl_.get(), &set_needs_commit_count,
8661 &set_needs_redraw_count, &forward_to_main_count));
[email protected]6be422b2013-12-08 06:47:318662 host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10));
8663 EXPECT_EQ(0, set_needs_commit_count);
8664 EXPECT_EQ(2, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468665 EXPECT_EQ(0, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318666 }
8667
8668 {
danakj60bc3bc2016-04-09 00:24:488669 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8670 new SimpleSwapPromiseMonitor(
8671 NULL, host_impl_.get(), &set_needs_commit_count,
8672 &set_needs_redraw_count, &forward_to_main_count));
[email protected]6be422b2013-12-08 06:47:318673 // Empty damage rect won't signal the monitor.
8674 host_impl_->SetNeedsRedrawRect(gfx::Rect());
8675 EXPECT_EQ(0, set_needs_commit_count);
8676 EXPECT_EQ(2, set_needs_redraw_count);
[email protected]dab0a422014-08-13 16:09:468677 EXPECT_EQ(0, forward_to_main_count);
8678 }
8679
8680 {
8681 set_needs_commit_count = 0;
8682 set_needs_redraw_count = 0;
8683 forward_to_main_count = 0;
danakj60bc3bc2016-04-09 00:24:488684 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
8685 new SimpleSwapPromiseMonitor(
8686 NULL, host_impl_.get(), &set_needs_commit_count,
8687 &set_needs_redraw_count, &forward_to_main_count));
dtapuskaf024e552016-02-03 01:19:468688 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]dab0a422014-08-13 16:09:468689
8690 // Scrolling normally should not trigger any forwarding.
tdresser81e84c672016-01-18 23:21:228691 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038692 host_impl_
8693 ->ScrollBegin(BeginState(gfx::Point()).get(),
8694 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228695 .thread);
ccameron36d091f2014-11-07 03:18:508696 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188697 host_impl_->ScrollBy(
8698 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
8699 .did_scroll);
8700 host_impl_->ScrollEnd(EndState().get());
[email protected]dab0a422014-08-13 16:09:468701
8702 EXPECT_EQ(0, set_needs_commit_count);
8703 EXPECT_EQ(1, set_needs_redraw_count);
8704 EXPECT_EQ(0, forward_to_main_count);
8705
8706 // Scrolling with a scroll handler should defer the swap to the main
8707 // thread.
dtapuskaf024e552016-02-03 01:19:468708 host_impl_->active_tree()->set_have_scroll_event_handlers(true);
tdresser81e84c672016-01-18 23:21:228709 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038710 host_impl_
8711 ->ScrollBegin(BeginState(gfx::Point()).get(),
8712 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228713 .thread);
ccameron36d091f2014-11-07 03:18:508714 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188715 host_impl_->ScrollBy(
8716 UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
8717 .did_scroll);
8718 host_impl_->ScrollEnd(EndState().get());
[email protected]dab0a422014-08-13 16:09:468719
8720 EXPECT_EQ(0, set_needs_commit_count);
8721 EXPECT_EQ(2, set_needs_redraw_count);
8722 EXPECT_EQ(1, forward_to_main_count);
[email protected]6be422b2013-12-08 06:47:318723 }
8724}
8725
[email protected]68d3fc12014-02-18 16:31:088726class LayerTreeHostImplWithTopControlsTest : public LayerTreeHostImplTest {
8727 public:
danakjaeb95062014-11-14 01:35:368728 void SetUp() override {
[email protected]68d3fc12014-02-18 16:31:088729 LayerTreeSettings settings = DefaultSettings();
[email protected]68d3fc12014-02-18 16:31:088730 CreateHostImpl(settings, CreateOutputSurface());
dtrainorcb7779b82014-12-04 01:08:028731 host_impl_->active_tree()->set_top_controls_height(top_controls_height_);
aelias6004fe02015-02-07 21:43:018732 host_impl_->sync_tree()->set_top_controls_height(top_controls_height_);
8733 host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f);
[email protected]68d3fc12014-02-18 16:31:088734 }
[email protected]f42cffb2014-03-08 18:03:258735
8736 protected:
8737 static const int top_controls_height_;
[email protected]68d3fc12014-02-18 16:31:088738};
8739
[email protected]f42cffb2014-03-08 18:03:258740const int LayerTreeHostImplWithTopControlsTest::top_controls_height_ = 50;
8741
[email protected]68d3fc12014-02-18 16:31:088742TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) {
sunxdb7e79432016-03-09 21:13:428743 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
8744 scroll_layer->layer_tree_impl()
8745 ->property_trees()
8746 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
8747 gfx::ScrollOffset(0, 10));
danakj12e2f6e2015-08-19 22:25:448748 BeginFrameArgs begin_frame_args =
8749 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
8750 host_impl_->WillBeginImplFrame(begin_frame_args);
8751 host_impl_->Animate();
[email protected]68d3fc12014-02-18 16:31:088752 EXPECT_FALSE(did_request_redraw_);
danakj12e2f6e2015-08-19 22:25:448753 host_impl_->DidFinishImplFrame();
[email protected]68d3fc12014-02-18 16:31:088754}
8755
dtrainorcb7779b82014-12-04 01:08:028756TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsHeightIsCommitted) {
8757 SetupScrollAndContentsLayers(gfx::Size(100, 100));
8758 EXPECT_FALSE(did_request_redraw_);
8759 host_impl_->CreatePendingTree();
8760 host_impl_->sync_tree()->set_top_controls_height(100);
8761 host_impl_->ActivateSyncTree();
aelias6004fe02015-02-07 21:43:018762 EXPECT_EQ(100, host_impl_->top_controls_manager()->TopControlsHeight());
dtrainorcb7779b82014-12-04 01:08:028763}
8764
8765TEST_F(LayerTreeHostImplWithTopControlsTest,
8766 TopControlsStayFullyVisibleOnHeightChange) {
8767 SetupScrollAndContentsLayers(gfx::Size(100, 100));
aelias6004fe02015-02-07 21:43:018768 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset());
dtrainorcb7779b82014-12-04 01:08:028769
8770 host_impl_->CreatePendingTree();
8771 host_impl_->sync_tree()->set_top_controls_height(0);
8772 host_impl_->ActivateSyncTree();
aelias6004fe02015-02-07 21:43:018773 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset());
dtrainorcb7779b82014-12-04 01:08:028774
8775 host_impl_->CreatePendingTree();
8776 host_impl_->sync_tree()->set_top_controls_height(50);
8777 host_impl_->ActivateSyncTree();
aelias6004fe02015-02-07 21:43:018778 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset());
dtrainorcb7779b82014-12-04 01:08:028779}
8780
[email protected]43b8f982014-04-30 21:24:338781TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) {
sunxdb7e79432016-03-09 21:13:428782 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
8783 scroll_layer->layer_tree_impl()
8784 ->property_trees()
8785 ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
8786 gfx::ScrollOffset(0, 10));
[email protected]43b8f982014-04-30 21:24:338787 host_impl_->DidChangeTopControlsPosition();
danakja18e826a2015-12-03 00:27:038788 EXPECT_TRUE(did_request_next_frame_);
[email protected]43b8f982014-04-30 21:24:338789 EXPECT_TRUE(did_request_redraw_);
8790}
8791
[email protected]f42cffb2014-03-08 18:03:258792TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) {
tdresser7befa9c2015-07-16 17:47:288793 InputHandlerScrollResult result;
[email protected]f42cffb2014-03-08 18:03:258794 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:488795 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8796
[email protected]f42cffb2014-03-08 18:03:258797 host_impl_->SetViewportSize(gfx::Size(100, 100));
bokan55b2f152014-09-15 14:47:598798 host_impl_->top_controls_manager()->UpdateTopControlsState(
8799 BOTH, SHOWN, false);
[email protected]f42cffb2014-03-08 18:03:258800 DrawFrame();
8801
tdresser81e84c672016-01-18 23:21:228802 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038803 host_impl_
8804 ->ScrollBegin(BeginState(gfx::Point()).get(),
8805 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228806 .thread);
bokan88eae012014-09-09 20:40:428807 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258808 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518809 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258810
8811 // Scroll just the top controls and verify that the scroll succeeds.
8812 const float residue = 10;
8813 float offset = top_controls_height_ - residue;
majidvp944a8cd2016-01-12 21:05:188814 result = host_impl_->ScrollBy(
8815 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288816 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
8817 EXPECT_TRUE(result.did_scroll);
lof84c1f962df2015-03-10 19:03:438818 EXPECT_FLOAT_EQ(-offset,
8819 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258820 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518821 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258822
8823 // Scroll across the boundary
8824 const float content_scroll = 20;
8825 offset = residue + content_scroll;
majidvp944a8cd2016-01-12 21:05:188826 result = host_impl_->ScrollBy(
8827 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288828 EXPECT_TRUE(result.did_scroll);
8829 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
[email protected]f42cffb2014-03-08 18:03:258830 EXPECT_EQ(-top_controls_height_,
bokan88eae012014-09-09 20:40:428831 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258832 EXPECT_EQ(gfx::Vector2dF(0, content_scroll).ToString(),
aeliasf998da82015-02-03 01:40:518833 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258834
8835 // Now scroll back to the top of the content
8836 offset = -content_scroll;
majidvp944a8cd2016-01-12 21:05:188837 result = host_impl_->ScrollBy(
8838 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288839 EXPECT_TRUE(result.did_scroll);
8840 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
[email protected]f42cffb2014-03-08 18:03:258841 EXPECT_EQ(-top_controls_height_,
bokan88eae012014-09-09 20:40:428842 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258843 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518844 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258845
8846 // And scroll the top controls completely into view
8847 offset = -top_controls_height_;
majidvp944a8cd2016-01-12 21:05:188848 result = host_impl_->ScrollBy(
8849 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288850 EXPECT_TRUE(result.did_scroll);
8851 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
bokan88eae012014-09-09 20:40:428852 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258853 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518854 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258855
8856 // And attempt to scroll past the end
majidvp944a8cd2016-01-12 21:05:188857 result = host_impl_->ScrollBy(
8858 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
tdresser7befa9c2015-07-16 17:47:288859 EXPECT_FALSE(result.did_scroll);
8860 EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, -50));
bokan88eae012014-09-09 20:40:428861 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]f42cffb2014-03-08 18:03:258862 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518863 scroll_layer->CurrentScrollOffset().ToString());
[email protected]f42cffb2014-03-08 18:03:258864
majidvp944a8cd2016-01-12 21:05:188865 host_impl_->ScrollEnd(EndState().get());
[email protected]f42cffb2014-03-08 18:03:258866}
8867
jdduke7f366ae2015-07-17 00:36:028868TEST_F(LayerTreeHostImplWithTopControlsTest, WheelUnhandledByTopControls) {
8869 SetupScrollAndContentsLayers(gfx::Size(100, 200));
bokan0c33a092015-07-29 18:27:568870 host_impl_->SetViewportSize(gfx::Size(50, 100));
8871 host_impl_->active_tree()->set_top_controls_shrink_blink_size(true);
jdduke7f366ae2015-07-17 00:36:028872 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
8873 false);
8874 DrawFrame();
8875
bokan0c33a092015-07-29 18:27:568876 LayerImpl* viewport_layer = host_impl_->InnerViewportScrollLayer();
jdduke7f366ae2015-07-17 00:36:028877
tdresser81e84c672016-01-18 23:21:228878 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:188879 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:228880 InputHandler::WHEEL)
8881 .thread);
jdduke7f366ae2015-07-17 00:36:028882 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
8883 EXPECT_VECTOR_EQ(gfx::Vector2dF(), viewport_layer->CurrentScrollOffset());
8884
8885 // Wheel scrolls should not affect the top controls, and should pass
8886 // directly through to the viewport.
8887 const float delta = top_controls_height_;
8888 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188889 host_impl_->ScrollBy(
8890 UpdateState(gfx::Point(), gfx::Vector2d(0, delta)).get())
8891 .did_scroll);
jdduke7f366ae2015-07-17 00:36:028892 EXPECT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
8893 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, delta),
8894 viewport_layer->CurrentScrollOffset());
8895
8896 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188897 host_impl_->ScrollBy(
8898 UpdateState(gfx::Point(), gfx::Vector2d(0, delta)).get())
8899 .did_scroll);
jdduke7f366ae2015-07-17 00:36:028900 EXPECT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
8901 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, delta * 2),
8902 viewport_layer->CurrentScrollOffset());
8903}
8904
[email protected]ac3446d2014-08-13 08:51:208905TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) {
8906 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:488907 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8908
[email protected]ac3446d2014-08-13 08:51:208909 host_impl_->SetViewportSize(gfx::Size(100, 200));
bokan55b2f152014-09-15 14:47:598910 host_impl_->top_controls_manager()->UpdateTopControlsState(
8911 BOTH, SHOWN, false);
[email protected]ac3446d2014-08-13 08:51:208912 DrawFrame();
8913
tdresser81e84c672016-01-18 23:21:228914 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038915 host_impl_
8916 ->ScrollBegin(BeginState(gfx::Point()).get(),
8917 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:228918 .thread);
bokan88eae012014-09-09 20:40:428919 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:208920 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518921 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:208922
8923 // Scroll the top controls partially.
8924 const float residue = 35;
8925 float offset = top_controls_height_ - residue;
ccameron36d091f2014-11-07 03:18:508926 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:188927 host_impl_->ScrollBy(
8928 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
8929 .did_scroll);
lof84c1f962df2015-03-10 19:03:438930 EXPECT_FLOAT_EQ(-offset,
8931 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:208932 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518933 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:208934
8935 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:038936 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:208937 did_request_commit_ = false;
8938
8939 // End the scroll while the controls are still offset from their limit.
majidvp944a8cd2016-01-12 21:05:188940 host_impl_->ScrollEnd(EndState().get());
loyso8b876b72016-01-08 04:27:388941 ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:038942 EXPECT_TRUE(did_request_next_frame_);
[email protected]ac3446d2014-08-13 08:51:208943 EXPECT_TRUE(did_request_redraw_);
8944 EXPECT_FALSE(did_request_commit_);
8945
8946 // The top controls should properly animate until finished, despite the scroll
8947 // offset being at the origin.
danakj12e2f6e2015-08-19 22:25:448948 BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(
8949 BEGINFRAME_FROM_HERE, base::TimeTicks::Now());
danakja18e826a2015-12-03 00:27:038950 while (did_request_next_frame_) {
[email protected]ac3446d2014-08-13 08:51:208951 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:038952 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:208953 did_request_commit_ = false;
8954
8955 float old_offset =
bokan88eae012014-09-09 20:40:428956 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:208957
danakj12e2f6e2015-08-19 22:25:448958 begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5);
8959 host_impl_->WillBeginImplFrame(begin_frame_args);
8960 host_impl_->Animate();
[email protected]ac3446d2014-08-13 08:51:208961 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:518962 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:208963
8964 float new_offset =
bokan88eae012014-09-09 20:40:428965 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:208966
8967 // No commit is needed as the controls are animating the content offset,
8968 // not the scroll offset.
8969 EXPECT_FALSE(did_request_commit_);
8970
8971 if (new_offset != old_offset)
8972 EXPECT_TRUE(did_request_redraw_);
8973
8974 if (new_offset != 0) {
loyso8b876b72016-01-08 04:27:388975 EXPECT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:038976 EXPECT_TRUE(did_request_next_frame_);
[email protected]ac3446d2014-08-13 08:51:208977 }
danakj12e2f6e2015-08-19 22:25:448978 host_impl_->DidFinishImplFrame();
[email protected]ac3446d2014-08-13 08:51:208979 }
loyso8b876b72016-01-08 04:27:388980 EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation());
[email protected]ac3446d2014-08-13 08:51:208981}
8982
8983TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) {
8984 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:488985 host_impl_->active_tree()->BuildPropertyTreesForTesting();
8986
[email protected]ac3446d2014-08-13 08:51:208987 host_impl_->SetViewportSize(gfx::Size(100, 100));
bokan55b2f152014-09-15 14:47:598988 host_impl_->top_controls_manager()->UpdateTopControlsState(
8989 BOTH, SHOWN, false);
[email protected]ac3446d2014-08-13 08:51:208990 float initial_scroll_offset = 50;
sunxdb7e79432016-03-09 21:13:428991 scroll_layer->layer_tree_impl()
8992 ->property_trees()
8993 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
8994 scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset));
[email protected]ac3446d2014-08-13 08:51:208995 DrawFrame();
8996
tdresser81e84c672016-01-18 23:21:228997 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:038998 host_impl_
8999 ->ScrollBegin(BeginState(gfx::Point()).get(),
9000 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229001 .thread);
bokan88eae012014-09-09 20:40:429002 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:209003 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
aeliasf998da82015-02-03 01:40:519004 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:209005
9006 // Scroll the top controls partially.
9007 const float residue = 15;
9008 float offset = top_controls_height_ - residue;
ccameron36d091f2014-11-07 03:18:509009 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189010 host_impl_->ScrollBy(
9011 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9012 .did_scroll);
lof84c1f962df2015-03-10 19:03:439013 EXPECT_FLOAT_EQ(-offset,
9014 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:209015 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
aeliasf998da82015-02-03 01:40:519016 scroll_layer->CurrentScrollOffset().ToString());
[email protected]ac3446d2014-08-13 08:51:209017
9018 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039019 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:209020 did_request_commit_ = false;
9021
9022 // End the scroll while the controls are still offset from the limit.
majidvp944a8cd2016-01-12 21:05:189023 host_impl_->ScrollEnd(EndState().get());
loyso8b876b72016-01-08 04:27:389024 ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:039025 EXPECT_TRUE(did_request_next_frame_);
[email protected]ac3446d2014-08-13 08:51:209026 EXPECT_TRUE(did_request_redraw_);
9027 EXPECT_FALSE(did_request_commit_);
9028
9029 // Animate the top controls to the limit.
danakj12e2f6e2015-08-19 22:25:449030 BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(
9031 BEGINFRAME_FROM_HERE, base::TimeTicks::Now());
danakja18e826a2015-12-03 00:27:039032 while (did_request_next_frame_) {
[email protected]ac3446d2014-08-13 08:51:209033 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039034 did_request_next_frame_ = false;
[email protected]ac3446d2014-08-13 08:51:209035 did_request_commit_ = false;
9036
9037 float old_offset =
bokan88eae012014-09-09 20:40:429038 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:209039
danakj12e2f6e2015-08-19 22:25:449040 begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5);
9041 host_impl_->WillBeginImplFrame(begin_frame_args);
9042 host_impl_->Animate();
[email protected]ac3446d2014-08-13 08:51:209043
9044 float new_offset =
bokan88eae012014-09-09 20:40:429045 host_impl_->top_controls_manager()->ControlsTopOffset();
[email protected]ac3446d2014-08-13 08:51:209046
9047 if (new_offset != old_offset) {
9048 EXPECT_TRUE(did_request_redraw_);
9049 EXPECT_TRUE(did_request_commit_);
9050 }
danakj12e2f6e2015-08-19 22:25:449051 host_impl_->DidFinishImplFrame();
[email protected]ac3446d2014-08-13 08:51:209052 }
loyso8b876b72016-01-08 04:27:389053 EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation());
majidvpfb80e432015-02-23 14:15:509054 EXPECT_EQ(-top_controls_height_,
9055 host_impl_->top_controls_manager()->ControlsTopOffset());
9056}
9057
9058TEST_F(LayerTreeHostImplWithTopControlsTest,
9059 TopControlsAnimationAfterMainThreadFlingStopped) {
9060 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:489061 host_impl_->active_tree()->BuildPropertyTreesForTesting();
9062
majidvpfb80e432015-02-23 14:15:509063 host_impl_->SetViewportSize(gfx::Size(100, 100));
9064 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
9065 false);
9066 float initial_scroll_offset = 50;
sunxdb7e79432016-03-09 21:13:429067 scroll_layer->layer_tree_impl()
9068 ->property_trees()
9069 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
9070 scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset));
majidvpfb80e432015-02-23 14:15:509071 DrawFrame();
9072
tdresser81e84c672016-01-18 23:21:229073 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039074 host_impl_
9075 ->ScrollBegin(BeginState(gfx::Point()).get(),
9076 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229077 .thread);
majidvpfb80e432015-02-23 14:15:509078 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
9079 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
9080 scroll_layer->CurrentScrollOffset().ToString());
9081
9082 // Scroll the top controls partially.
9083 const float residue = 15;
9084 float offset = top_controls_height_ - residue;
9085 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189086 host_impl_->ScrollBy(
9087 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9088 .did_scroll);
lof84c1f962df2015-03-10 19:03:439089 EXPECT_FLOAT_EQ(-offset,
9090 host_impl_->top_controls_manager()->ControlsTopOffset());
majidvpfb80e432015-02-23 14:15:509091 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
9092 scroll_layer->CurrentScrollOffset().ToString());
9093
9094 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039095 did_request_next_frame_ = false;
majidvpfb80e432015-02-23 14:15:509096 did_request_commit_ = false;
9097
9098 // End the fling while the controls are still offset from the limit.
9099 host_impl_->MainThreadHasStoppedFlinging();
loyso8b876b72016-01-08 04:27:389100 ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation());
danakja18e826a2015-12-03 00:27:039101 EXPECT_TRUE(did_request_next_frame_);
majidvpfb80e432015-02-23 14:15:509102 EXPECT_TRUE(did_request_redraw_);
9103 EXPECT_FALSE(did_request_commit_);
9104
9105 // Animate the top controls to the limit.
danakj12e2f6e2015-08-19 22:25:449106 BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(
9107 BEGINFRAME_FROM_HERE, base::TimeTicks::Now());
danakja18e826a2015-12-03 00:27:039108 while (did_request_next_frame_) {
majidvpfb80e432015-02-23 14:15:509109 did_request_redraw_ = false;
danakja18e826a2015-12-03 00:27:039110 did_request_next_frame_ = false;
majidvpfb80e432015-02-23 14:15:509111 did_request_commit_ = false;
9112
9113 float old_offset = host_impl_->top_controls_manager()->ControlsTopOffset();
9114
danakj12e2f6e2015-08-19 22:25:449115 begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5);
9116 host_impl_->WillBeginImplFrame(begin_frame_args);
9117 host_impl_->Animate();
majidvpfb80e432015-02-23 14:15:509118
9119 float new_offset = host_impl_->top_controls_manager()->ControlsTopOffset();
9120
9121 if (new_offset != old_offset) {
9122 EXPECT_TRUE(did_request_redraw_);
9123 EXPECT_TRUE(did_request_commit_);
9124 }
danakj12e2f6e2015-08-19 22:25:449125 host_impl_->DidFinishImplFrame();
majidvpfb80e432015-02-23 14:15:509126 }
loyso8b876b72016-01-08 04:27:389127 EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation());
majidvpfb80e432015-02-23 14:15:509128 EXPECT_EQ(-top_controls_height_,
9129 host_impl_->top_controls_manager()->ControlsTopOffset());
[email protected]ac3446d2014-08-13 08:51:209130}
9131
sujiths.s344435e2014-11-08 03:04:039132TEST_F(LayerTreeHostImplWithTopControlsTest,
9133 TopControlsScrollDeltaInOverScroll) {
tdresser96f4a2b2015-07-15 14:11:549134 // Verifies that the overscroll delta should not have accumulated in
sujiths.s344435e2014-11-08 03:04:039135 // the top controls if we do a hide and show without releasing finger.
sujiths.s344435e2014-11-08 03:04:039136 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
danakj74af409e2016-07-01 00:41:489137 host_impl_->active_tree()->BuildPropertyTreesForTesting();
9138
sujiths.s344435e2014-11-08 03:04:039139 host_impl_->SetViewportSize(gfx::Size(100, 100));
9140 host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
9141 false);
sunxd22ecae62016-02-11 21:38:129142 DrawFrame();
sujiths.s344435e2014-11-08 03:04:039143
tdresser81e84c672016-01-18 23:21:229144 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039145 host_impl_
9146 ->ScrollBegin(BeginState(gfx::Point()).get(),
9147 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229148 .thread);
sujiths.s344435e2014-11-08 03:04:039149 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
9150
9151 float offset = 50;
9152 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189153 host_impl_->ScrollBy(
9154 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9155 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039156 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
9157 EXPECT_EQ(gfx::Vector2dF().ToString(),
aeliasf998da82015-02-03 01:40:519158 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039159
9160 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189161 host_impl_->ScrollBy(
9162 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9163 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039164 EXPECT_EQ(gfx::Vector2dF(0, offset).ToString(),
aeliasf998da82015-02-03 01:40:519165 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039166
9167 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189168 host_impl_->ScrollBy(
9169 UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
9170 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039171
9172 // Should have fully scrolled
9173 EXPECT_EQ(gfx::Vector2dF(0, scroll_layer->MaxScrollOffset().y()).ToString(),
aeliasf998da82015-02-03 01:40:519174 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039175
9176 float overscrollamount = 10;
9177
9178 // Overscroll the content
9179 EXPECT_FALSE(
majidvp944a8cd2016-01-12 21:05:189180 host_impl_->ScrollBy(UpdateState(gfx::Point(),
9181 gfx::Vector2d(0, overscrollamount))
9182 .get())
sujiths.s344435e2014-11-08 03:04:039183 .did_scroll);
9184 EXPECT_EQ(gfx::Vector2dF(0, 2 * offset).ToString(),
aeliasf998da82015-02-03 01:40:519185 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039186 EXPECT_EQ(gfx::Vector2dF(0, overscrollamount).ToString(),
9187 host_impl_->accumulated_root_overscroll().ToString());
9188
majidvp944a8cd2016-01-12 21:05:189189 EXPECT_TRUE(host_impl_->ScrollBy(UpdateState(gfx::Point(),
9190 gfx::Vector2d(0, -2 * offset))
9191 .get())
sujiths.s344435e2014-11-08 03:04:039192 .did_scroll);
9193 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
aeliasf998da82015-02-03 01:40:519194 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039195 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
9196
9197 EXPECT_TRUE(
majidvp944a8cd2016-01-12 21:05:189198 host_impl_->ScrollBy(
9199 UpdateState(gfx::Point(), gfx::Vector2d(0, -offset)).get())
9200 .did_scroll);
sujiths.s344435e2014-11-08 03:04:039201 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
aeliasf998da82015-02-03 01:40:519202 scroll_layer->CurrentScrollOffset().ToString());
sujiths.s344435e2014-11-08 03:04:039203
9204 // Top controls should be fully visible
9205 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
9206
majidvp944a8cd2016-01-12 21:05:189207 host_impl_->ScrollEnd(EndState().get());
sujiths.s344435e2014-11-08 03:04:039208}
9209
bokanbc115b42016-08-22 13:46:329210// Tests that when we set a child scroller (e.g. a scrolling div) as the outer
9211// viewport, scrolling it controls the top controls.
9212TEST_F(LayerTreeHostImplTopControlsTest,
9213 ReplacedOuterViewportScrollsTopControls) {
9214 const gfx::Size scroll_content_size(400, 400);
9215 const gfx::Size root_layer_size(200, 200);
9216 const gfx::Size viewport_size(100, 100);
9217
9218 SetupTopControlsAndScrollLayerWithVirtualViewport(
9219 viewport_size, viewport_size, root_layer_size);
9220
9221 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9222 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9223 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
9224 LayerImpl* scroll_layer = nullptr;
9225
9226 // Initialization: Add a child scrolling layer to the outer scroll layer and
9227 // set its scroll layer as the outer viewport. This simulates setting a
9228 // scrolling element as the root scroller on the page.
9229 {
9230 std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10);
9231 clip->SetBounds(root_layer_size);
9232 clip->SetPosition(gfx::PointF());
9233
9234 std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11);
9235 scroll->SetBounds(scroll_content_size);
9236 scroll->SetScrollClipLayer(clip->id());
9237 scroll->SetDrawsContent(true);
9238
9239 scroll_layer = scroll.get();
9240
9241 clip->test_properties()->AddChild(std::move(scroll));
9242 outer_scroll->test_properties()->AddChild(std::move(clip));
9243 layer_tree_impl->SetViewportLayersFromIds(
9244 Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(),
9245 inner_scroll->id(), scroll_layer->id());
9246 layer_tree_impl->BuildPropertyTreesForTesting();
9247 DrawFrame();
9248 }
9249
9250 ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
9251
9252 // Scrolling should scroll the child content and the top controls. The
9253 // original outer viewport should get no scroll.
9254 {
9255 host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
9256 InputHandler::TOUCHSCREEN);
9257 host_impl_->ScrollBy(
9258 UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
9259 host_impl_->ScrollEnd(EndState().get());
9260
9261 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll->CurrentScrollOffset());
9262 EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 50.f),
9263 scroll_layer->CurrentScrollOffset());
9264 EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
9265 }
9266}
9267
[email protected]09a6f2c2014-02-20 20:19:149268class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
9269 public:
9270 void SetupVirtualViewportLayers(const gfx::Size& content_size,
9271 const gfx::Size& outer_viewport,
9272 const gfx::Size& inner_viewport) {
9273 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
9274 const int kOuterViewportClipLayerId = 6;
9275 const int kOuterViewportScrollLayerId = 7;
9276 const int kInnerViewportScrollLayerId = 2;
9277 const int kInnerViewportClipLayerId = 4;
9278 const int kPageScaleLayerId = 5;
9279
danakj60bc3bc2016-04-09 00:24:489280 std::unique_ptr<LayerImpl> inner_scroll =
[email protected]09a6f2c2014-02-20 20:19:149281 LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId);
jaydasikaca2605e2016-04-23 02:52:529282 inner_scroll->test_properties()->is_container_for_fixed_position_layers =
9283 true;
sunxdb7e79432016-03-09 21:13:429284 inner_scroll->layer_tree_impl()
9285 ->property_trees()
9286 ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(),
9287 gfx::ScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149288
danakj60bc3bc2016-04-09 00:24:489289 std::unique_ptr<LayerImpl> inner_clip =
[email protected]09a6f2c2014-02-20 20:19:149290 LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
9291 inner_clip->SetBounds(inner_viewport);
9292
danakj60bc3bc2016-04-09 00:24:489293 std::unique_ptr<LayerImpl> page_scale =
[email protected]09a6f2c2014-02-20 20:19:149294 LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
9295
9296 inner_scroll->SetScrollClipLayer(inner_clip->id());
9297 inner_scroll->SetBounds(outer_viewport);
[email protected]09a6f2c2014-02-20 20:19:149298 inner_scroll->SetPosition(gfx::PointF());
[email protected]09a6f2c2014-02-20 20:19:149299
danakj60bc3bc2016-04-09 00:24:489300 std::unique_ptr<LayerImpl> outer_clip =
[email protected]09a6f2c2014-02-20 20:19:149301 LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
9302 outer_clip->SetBounds(outer_viewport);
jaydasikaca2605e2016-04-23 02:52:529303 outer_clip->test_properties()->is_container_for_fixed_position_layers =
9304 true;
[email protected]09a6f2c2014-02-20 20:19:149305
danakj60bc3bc2016-04-09 00:24:489306 std::unique_ptr<LayerImpl> outer_scroll =
[email protected]09a6f2c2014-02-20 20:19:149307 LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
9308 outer_scroll->SetScrollClipLayer(outer_clip->id());
sunxdb7e79432016-03-09 21:13:429309 outer_scroll->layer_tree_impl()
9310 ->property_trees()
9311 ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
9312 gfx::ScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149313 outer_scroll->SetBounds(content_size);
[email protected]09a6f2c2014-02-20 20:19:149314 outer_scroll->SetPosition(gfx::PointF());
[email protected]09a6f2c2014-02-20 20:19:149315
danakj60bc3bc2016-04-09 00:24:489316 std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, 8);
[email protected]09a6f2c2014-02-20 20:19:149317 contents->SetDrawsContent(true);
9318 contents->SetBounds(content_size);
[email protected]09a6f2c2014-02-20 20:19:149319 contents->SetPosition(gfx::PointF());
[email protected]09a6f2c2014-02-20 20:19:149320
jaydasika89f7b5a2016-06-22 02:08:399321 outer_scroll->test_properties()->AddChild(std::move(contents));
9322 outer_clip->test_properties()->AddChild(std::move(outer_scroll));
9323 inner_scroll->test_properties()->AddChild(std::move(outer_clip));
9324 page_scale->test_properties()->AddChild(std::move(inner_scroll));
9325 inner_clip->test_properties()->AddChild(std::move(page_scale));
[email protected]09a6f2c2014-02-20 20:19:149326
jaydasika6b5a32bf2016-04-22 21:56:369327 inner_clip->test_properties()->force_render_surface = true;
jaydasikabf1875a2016-06-28 03:39:599328 layer_tree_impl->SetRootLayerForTesting(std::move(inner_clip));
ccameron8230b68b2014-11-21 19:25:189329 layer_tree_impl->SetViewportLayersFromIds(
9330 Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId,
9331 kOuterViewportScrollLayerId);
[email protected]09a6f2c2014-02-20 20:19:149332
danakj74af409e2016-07-01 00:41:489333 host_impl_->active_tree()->BuildPropertyTreesForTesting();
[email protected]09a6f2c2014-02-20 20:19:149334 host_impl_->active_tree()->DidBecomeActive();
9335 }
9336};
9337
hush33370e12015-04-07 03:49:509338TEST_F(LayerTreeHostImplVirtualViewportTest, ScrollBothInnerAndOuterLayer) {
9339 gfx::Size content_size = gfx::Size(100, 160);
9340 gfx::Size outer_viewport = gfx::Size(50, 80);
9341 gfx::Size inner_viewport = gfx::Size(25, 40);
9342
9343 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9344
hush33370e12015-04-07 03:49:509345 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9346 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
danakj74af409e2016-07-01 00:41:489347
hush33370e12015-04-07 03:49:509348 DrawFrame();
9349 {
9350 gfx::ScrollOffset inner_expected;
9351 gfx::ScrollOffset outer_expected;
9352 EXPECT_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9353 EXPECT_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
9354
9355 gfx::ScrollOffset current_offset(70.f, 100.f);
9356
danakjdd74e512015-09-21 23:07:599357 host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
hush33370e12015-04-07 03:49:509358 EXPECT_EQ(gfx::ScrollOffset(25.f, 40.f), inner_scroll->MaxScrollOffset());
9359 EXPECT_EQ(gfx::ScrollOffset(50.f, 80.f), outer_scroll->MaxScrollOffset());
9360
9361 // Outer viewport scrolls first. Then the rest is applied to the inner
9362 // viewport.
9363 EXPECT_EQ(gfx::ScrollOffset(20.f, 20.f),
9364 inner_scroll->CurrentScrollOffset());
9365 EXPECT_EQ(gfx::ScrollOffset(50.f, 80.f),
9366 outer_scroll->CurrentScrollOffset());
9367 }
9368}
9369
[email protected]09a6f2c2014-02-20 20:19:149370TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) {
bokan1f01388f2015-09-15 20:55:549371 gfx::Size content_size = gfx::Size(200, 320);
9372 gfx::Size outer_viewport = gfx::Size(100, 160);
9373 gfx::Size inner_viewport = gfx::Size(50, 80);
[email protected]09a6f2c2014-02-20 20:19:149374
9375 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9376
9377 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9378 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
danakj74af409e2016-07-01 00:41:489379
[email protected]09a6f2c2014-02-20 20:19:149380 DrawFrame();
9381 {
9382 gfx::Vector2dF inner_expected;
9383 gfx::Vector2dF outer_expected;
aeliasf998da82015-02-03 01:40:519384 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9385 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149386
bokan1f01388f2015-09-15 20:55:549387 // Scrolling the viewport always sets the outer scroll layer as the
9388 // currently scrolling layer.
tdresser81e84c672016-01-18 23:21:229389 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039390 host_impl_
9391 ->ScrollBegin(BeginState(gfx::Point()).get(),
9392 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229393 .thread);
tdressera3f3a942015-09-28 21:15:399394 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
tdresser81e84c672016-01-18 23:21:229395 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9396 host_impl_->FlingScrollBegin().thread);
tdressera3f3a942015-09-28 21:15:399397 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149398
bokan1f01388f2015-09-15 20:55:549399 gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f,
9400 inner_viewport.height() / 2.f);
majidvp944a8cd2016-01-12 21:05:189401 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549402 inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
tdressera3f3a942015-09-28 21:15:399403 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149404
majidvp944a8cd2016-01-12 21:05:189405 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499406 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke2491ebe2015-08-10 15:41:159407 EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149408
aeliasf998da82015-02-03 01:40:519409 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9410 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149411
bokan1f01388f2015-09-15 20:55:549412 // Fling past the inner viewport boundry, make sure outer viewport scrolls.
tdresser81e84c672016-01-18 23:21:229413 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039414 host_impl_
9415 ->ScrollBegin(BeginState(gfx::Point()).get(),
9416 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229417 .thread);
tdressera3f3a942015-09-28 21:15:399418 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
tdresser81e84c672016-01-18 23:21:229419 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9420 host_impl_->FlingScrollBegin().thread);
tdressera3f3a942015-09-28 21:15:399421 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149422
majidvp944a8cd2016-01-12 21:05:189423 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549424 inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
tdressera3f3a942015-09-28 21:15:399425 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149426
majidvp944a8cd2016-01-12 21:05:189427 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549428 outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
tdressera3f3a942015-09-28 21:15:399429 EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149430
majidvp944a8cd2016-01-12 21:05:189431 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499432 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke2491ebe2015-08-10 15:41:159433 EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer());
[email protected]09a6f2c2014-02-20 20:19:149434
aeliasf998da82015-02-03 01:40:519435 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9436 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
[email protected]09a6f2c2014-02-20 20:19:149437 }
9438}
9439
jddukea7173dd2014-11-19 22:05:289440TEST_F(LayerTreeHostImplVirtualViewportTest,
9441 DiagonalScrollBubblesPerfectlyToInner) {
bokan1f01388f2015-09-15 20:55:549442 gfx::Size content_size = gfx::Size(200, 320);
9443 gfx::Size outer_viewport = gfx::Size(100, 160);
9444 gfx::Size inner_viewport = gfx::Size(50, 80);
jddukea7173dd2014-11-19 22:05:289445
9446 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9447
9448 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9449 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
danakj74af409e2016-07-01 00:41:489450
jddukea7173dd2014-11-19 22:05:289451 DrawFrame();
9452 {
9453 gfx::Vector2dF inner_expected;
9454 gfx::Vector2dF outer_expected;
aeliasf998da82015-02-03 01:40:519455 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9456 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
jddukea7173dd2014-11-19 22:05:289457
bokan1f01388f2015-09-15 20:55:549458 // Make sure the scroll goes to the inner viewport first.
tdresser81e84c672016-01-18 23:21:229459 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039460 host_impl_
9461 ->ScrollBegin(BeginState(gfx::Point()).get(),
9462 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229463 .thread);
9464 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9465 host_impl_->FlingScrollBegin().thread);
dtapuska40e8aff2016-03-11 21:45:039466 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9467 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289468
9469 // Scroll near the edge of the outer viewport.
bokan1f01388f2015-09-15 20:55:549470 gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f,
9471 inner_viewport.height() / 2.f);
majidvp944a8cd2016-01-12 21:05:189472 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
bokan1f01388f2015-09-15 20:55:549473 inner_expected += scroll_delta;
dtapuska40e8aff2016-03-11 21:45:039474 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9475 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289476
aeliasf998da82015-02-03 01:40:519477 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9478 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
jddukea7173dd2014-11-19 22:05:289479
9480 // Now diagonal scroll across the outer viewport boundary in a single event.
9481 // The entirety of the scroll should be consumed, as bubbling between inner
9482 // and outer viewport layers is perfect.
majidvp944a8cd2016-01-12 21:05:189483 host_impl_->ScrollBy(
9484 UpdateState(gfx::Point(), gfx::ScaleVector2d(scroll_delta, 2)).get());
dtapuska40e8aff2016-03-11 21:45:039485 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9486 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289487 outer_expected += scroll_delta;
9488 inner_expected += scroll_delta;
majidvp944a8cd2016-01-12 21:05:189489 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499490 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke366df482015-05-05 01:07:569491 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
dtapuska40e8aff2016-03-11 21:45:039492 gfx::Point(), InputHandler::TOUCHSCREEN));
jddukea7173dd2014-11-19 22:05:289493
aeliasf998da82015-02-03 01:40:519494 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
9495 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
jddukea7173dd2014-11-19 22:05:289496 }
9497}
9498
jdduke14ffa6b2014-12-06 07:12:409499TEST_F(LayerTreeHostImplVirtualViewportTest,
tdressera3b162b82015-09-29 17:51:439500 TouchFlingDoesntSwitchScrollingLayer) {
jdduke14ffa6b2014-12-06 07:12:409501 gfx::Size content_size = gfx::Size(100, 160);
9502 gfx::Size outer_viewport = gfx::Size(50, 80);
9503 gfx::Size inner_viewport = gfx::Size(25, 40);
9504
9505 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9506
9507 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9508 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9509
danakj60bc3bc2016-04-09 00:24:489510 std::unique_ptr<LayerImpl> child =
jdduke14ffa6b2014-12-06 07:12:409511 CreateScrollableLayer(10, outer_viewport, outer_scroll);
9512 LayerImpl* child_scroll = child.get();
jaydasika89f7b5a2016-06-22 02:08:399513 outer_scroll->test_properties()->children[0]->test_properties()->AddChild(
9514 std::move(child));
danakj74af409e2016-07-01 00:41:489515 host_impl_->active_tree()->BuildPropertyTreesForTesting();
jdduke14ffa6b2014-12-06 07:12:409516
9517 DrawFrame();
9518 {
danakj60bc3bc2016-04-09 00:24:489519 std::unique_ptr<ScrollAndScaleSet> scroll_info;
jdduke14ffa6b2014-12-06 07:12:409520
9521 gfx::Vector2d scroll_delta(0, inner_viewport.height());
tdresser81e84c672016-01-18 23:21:229522 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039523 host_impl_
9524 ->ScrollBegin(BeginState(gfx::Point()).get(),
9525 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229526 .thread);
majidvp944a8cd2016-01-12 21:05:189527 EXPECT_TRUE(
9528 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
9529 .did_scroll);
dtapuska40e8aff2016-03-11 21:45:039530 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9531 gfx::Point(), InputHandler::TOUCHSCREEN));
jdduke14ffa6b2014-12-06 07:12:409532
9533 // The child should have scrolled up to its limit.
9534 scroll_info = host_impl_->ProcessScrollDeltas();
9535 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:189536 EXPECT_TRUE(
9537 ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
jdduke14ffa6b2014-12-06 07:12:409538 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
9539
tdressera3b162b82015-09-29 17:51:439540 // The fling have no effect on the currently scrolling layer.
tdresser81e84c672016-01-18 23:21:229541 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
9542 host_impl_->FlingScrollBegin().thread);
majidvp944a8cd2016-01-12 21:05:189543 EXPECT_FALSE(
9544 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
9545 .did_scroll);
tdressera3b162b82015-09-29 17:51:439546 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
dtapuska40e8aff2016-03-11 21:45:039547 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
9548 gfx::Point(), InputHandler::TOUCHSCREEN));
jdduke14ffa6b2014-12-06 07:12:409549
tdressera3b162b82015-09-29 17:51:439550 // The inner viewport shouldn't have scrolled.
jdduke14ffa6b2014-12-06 07:12:409551 scroll_info = host_impl_->ProcessScrollDeltas();
tdressera3b162b82015-09-29 17:51:439552 ASSERT_EQ(1u, scroll_info->scrolls.size());
tdresser99977952015-07-02 19:49:189553 EXPECT_TRUE(
9554 ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
tdressera3b162b82015-09-29 17:51:439555 ExpectNone(*scroll_info, inner_scroll->id());
jdduke14ffa6b2014-12-06 07:12:409556
9557 // As the locked layer is at its limit, no further scrolling can occur.
majidvp944a8cd2016-01-12 21:05:189558 EXPECT_FALSE(
9559 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get())
9560 .did_scroll);
tdressera3b162b82015-09-29 17:51:439561 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
majidvp944a8cd2016-01-12 21:05:189562 host_impl_->ScrollEnd(EndState().get());
sahel7adc4a72016-08-25 19:53:499563 host_impl_->ClearCurrentlyScrollingLayerForTesting();
jdduke366df482015-05-05 01:07:569564 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
dtapuska40e8aff2016-03-11 21:45:039565 gfx::Point(), InputHandler::TOUCHSCREEN));
jdduke14ffa6b2014-12-06 07:12:409566 }
9567}
9568
hush1c873232015-06-23 21:22:119569TEST_F(LayerTreeHostImplVirtualViewportTest,
9570 ScrollBeginEventThatTargetsViewportLayerSkipsHitTest) {
9571 gfx::Size content_size = gfx::Size(100, 160);
9572 gfx::Size outer_viewport = gfx::Size(50, 80);
9573 gfx::Size inner_viewport = gfx::Size(25, 40);
9574
9575 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
9576
9577 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
9578 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9579
danakj60bc3bc2016-04-09 00:24:489580 std::unique_ptr<LayerImpl> child =
hush1c873232015-06-23 21:22:119581 CreateScrollableLayer(10, outer_viewport, outer_scroll);
9582 LayerImpl* child_scroll = child.get();
jaydasika89f7b5a2016-06-22 02:08:399583 outer_scroll->test_properties()->children[0]->test_properties()->AddChild(
9584 std::move(child));
danakj74af409e2016-07-01 00:41:489585 host_impl_->active_tree()->BuildPropertyTreesForTesting();
hush1c873232015-06-23 21:22:119586
9587 DrawFrame();
9588
tdresser81e84c672016-01-18 23:21:229589 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039590 host_impl_
9591 ->RootScrollBegin(BeginState(gfx::Point()).get(),
9592 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229593 .thread);
hush1c873232015-06-23 21:22:119594 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
majidvp944a8cd2016-01-12 21:05:189595 host_impl_->ScrollEnd(EndState().get());
tdresser81e84c672016-01-18 23:21:229596 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039597 host_impl_
9598 ->ScrollBegin(BeginState(gfx::Point()).get(),
9599 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229600 .thread);
hush1c873232015-06-23 21:22:119601 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
majidvp944a8cd2016-01-12 21:05:189602 host_impl_->ScrollEnd(EndState().get());
hush1c873232015-06-23 21:22:119603}
9604
hugo.holgerssone5e7aa92015-08-17 14:07:199605TEST_F(LayerTreeHostImplVirtualViewportTest,
9606 NoOverscrollWhenInnerViewportCantScroll) {
9607 InputHandlerScrollResult scroll_result;
9608 gfx::Size content_size = gfx::Size(100, 160);
9609 gfx::Size outer_viewport = gfx::Size(50, 80);
9610 gfx::Size inner_viewport = gfx::Size(25, 40);
9611 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
hugo.holgerssone5e7aa92015-08-17 14:07:199612 // Make inner viewport unscrollable.
9613 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
9614 inner_scroll->set_user_scrollable_horizontal(false);
9615 inner_scroll->set_user_scrollable_vertical(false);
danakj74af409e2016-07-01 00:41:489616 host_impl_->active_tree()->BuildPropertyTreesForTesting();
9617
sunxd2668bea62016-03-17 00:49:479618 DrawFrame();
hugo.holgerssone5e7aa92015-08-17 14:07:199619
9620 // Ensure inner viewport doesn't react to scrolls (test it's unscrollable).
9621 EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset());
tdresser81e84c672016-01-18 23:21:229622 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
dtapuska40e8aff2016-03-11 21:45:039623 host_impl_
9624 ->ScrollBegin(BeginState(gfx::Point()).get(),
9625 InputHandler::TOUCHSCREEN)
tdresser81e84c672016-01-18 23:21:229626 .thread);
majidvp944a8cd2016-01-12 21:05:189627 scroll_result = host_impl_->ScrollBy(
9628 UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
hugo.holgerssone5e7aa92015-08-17 14:07:199629 EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset());
9630
9631 // When inner viewport is unscrollable, a fling gives zero overscroll.
9632 EXPECT_FALSE(scroll_result.did_overscroll_root);
9633 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
9634}
9635
[email protected]4bb0f312014-02-25 02:02:329636class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest {
9637 public:
danakjaeb95062014-11-14 01:35:369638 void SetUp() override {
[email protected]4bb0f312014-02-25 02:02:329639 LayerTreeSettings settings = DefaultSettings();
[email protected]4bb0f312014-02-25 02:02:329640 settings.max_memory_for_prepaint_percentage = 50;
9641 CreateHostImpl(settings, CreateOutputSurface());
9642 }
9643};
9644
9645TEST_F(LayerTreeHostImplWithImplicitLimitsTest, ImplicitMemoryLimits) {
9646 // Set up a memory policy and percentages which could cause
9647 // 32-bit integer overflows.
9648 ManagedMemoryPolicy mem_policy(300 * 1024 * 1024); // 300MB
9649
9650 // Verify implicit limits are calculated correctly with no overflows
9651 host_impl_->SetMemoryPolicy(mem_policy);
9652 EXPECT_EQ(host_impl_->global_tile_state().hard_memory_limit_in_bytes,
9653 300u * 1024u * 1024u);
9654 EXPECT_EQ(host_impl_->global_tile_state().soft_memory_limit_in_bytes,
9655 150u * 1024u * 1024u);
[email protected]4bb0f312014-02-25 02:02:329656}
9657
[email protected]ea12b5502014-06-24 21:37:369658TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) {
9659 const gfx::Size layer_size(100, 100);
9660 gfx::Transform external_transform;
9661 const gfx::Rect external_viewport(layer_size);
[email protected]c05dfbb2014-07-10 22:49:049662 const bool resourceless_software_draw = false;
[email protected]ea12b5502014-06-24 21:37:369663 LayerImpl* layer = SetupScrollAndContentsLayers(layer_size);
jaydasikad7dea632015-11-06 04:40:129664 layer->SetDrawsContent(true);
[email protected]ea12b5502014-06-24 21:37:369665
boliu7097ee5b2015-12-17 03:16:099666 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9667 external_transform);
boliu31c233ed2016-07-29 05:38:599668 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099669 resourceless_software_draw);
[email protected]ea12b5502014-06-24 21:37:369670 EXPECT_TRANSFORMATION_MATRIX_EQ(
9671 external_transform, layer->draw_properties().target_space_transform);
9672
9673 external_transform.Translate(20, 20);
boliu7097ee5b2015-12-17 03:16:099674 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9675 external_transform);
boliu31c233ed2016-07-29 05:38:599676 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099677 resourceless_software_draw);
[email protected]ea12b5502014-06-24 21:37:369678 EXPECT_TRANSFORMATION_MATRIX_EQ(
9679 external_transform, layer->draw_properties().target_space_transform);
9680}
9681
boliudaa9bdb2015-10-17 15:11:499682TEST_F(LayerTreeHostImplTest, ExternalTransformSetNeedsRedraw) {
9683 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:489684 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliudaa9bdb2015-10-17 15:11:499685
boliu7097ee5b2015-12-17 03:16:099686 const gfx::Size viewport_size(100, 100);
9687 host_impl_->SetViewportSize(viewport_size);
9688
9689 const gfx::Transform transform_for_tile_priority;
9690 const gfx::Transform draw_transform;
9691 const gfx::Rect viewport_for_tile_priority1(viewport_size);
9692 const gfx::Rect viewport_for_tile_priority2(50, 50);
9693 const gfx::Rect draw_viewport(viewport_size);
boliudaa9bdb2015-10-17 15:11:499694 bool resourceless_software_draw = false;
9695
boliu7097ee5b2015-12-17 03:16:099696 // Clear any damage.
9697 host_impl_->SetExternalTilePriorityConstraints(viewport_for_tile_priority1,
9698 transform_for_tile_priority);
boliu31c233ed2016-07-29 05:38:599699 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099700 last_on_draw_frame_.reset();
boliudaa9bdb2015-10-17 15:11:499701
9702 // Setting new constraints needs redraw.
9703 did_request_redraw_ = false;
boliu7097ee5b2015-12-17 03:16:099704 host_impl_->SetExternalTilePriorityConstraints(viewport_for_tile_priority2,
9705 transform_for_tile_priority);
boliudaa9bdb2015-10-17 15:11:499706 EXPECT_TRUE(did_request_redraw_);
boliu31c233ed2016-07-29 05:38:599707 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099708 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
9709}
boliudaa9bdb2015-10-17 15:11:499710
boliu7097ee5b2015-12-17 03:16:099711TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) {
9712 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:489713 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliudaa9bdb2015-10-17 15:11:499714
boliu7097ee5b2015-12-17 03:16:099715 const gfx::Size viewport_size(100, 100);
9716 host_impl_->SetViewportSize(viewport_size);
9717
9718 const gfx::Transform draw_transform;
9719 const gfx::Rect draw_viewport1(viewport_size);
9720 const gfx::Rect draw_viewport2(50, 50);
boliu7097ee5b2015-12-17 03:16:099721 bool resourceless_software_draw = false;
9722
9723 // Clear any damage.
boliu31c233ed2016-07-29 05:38:599724 host_impl_->OnDraw(draw_transform, draw_viewport1,
boliu7097ee5b2015-12-17 03:16:099725 resourceless_software_draw);
9726 last_on_draw_frame_.reset();
9727
9728 // Same draw params does not swap.
boliudaa9bdb2015-10-17 15:11:499729 did_request_redraw_ = false;
boliu31c233ed2016-07-29 05:38:599730 host_impl_->OnDraw(draw_transform, draw_viewport1,
boliu7097ee5b2015-12-17 03:16:099731 resourceless_software_draw);
9732 EXPECT_FALSE(did_request_redraw_);
9733 EXPECT_TRUE(last_on_draw_frame_->has_no_damage);
9734 last_on_draw_frame_.reset();
9735
9736 // Different draw params does swap.
9737 did_request_redraw_ = false;
boliu31c233ed2016-07-29 05:38:599738 host_impl_->OnDraw(draw_transform, draw_viewport2,
boliu7097ee5b2015-12-17 03:16:099739 resourceless_software_draw);
9740 EXPECT_TRUE(did_request_redraw_);
9741 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
9742}
9743
9744class ResourcelessSoftwareLayerTreeHostImplTest : public LayerTreeHostImplTest {
9745 protected:
danakj60bc3bc2016-04-09 00:24:489746 std::unique_ptr<OutputSurface> CreateOutputSurface() override {
danakj554c98a2016-07-08 00:25:079747 return FakeOutputSurface::CreateDelegating3d();
boliu7097ee5b2015-12-17 03:16:099748 }
9749};
9750
9751TEST_F(ResourcelessSoftwareLayerTreeHostImplTest,
9752 ResourcelessSoftwareSetNeedsRedraw) {
9753 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
danakj74af409e2016-07-01 00:41:489754 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu7097ee5b2015-12-17 03:16:099755
9756 const gfx::Size viewport_size(100, 100);
9757 host_impl_->SetViewportSize(viewport_size);
9758
9759 const gfx::Transform draw_transform;
9760 const gfx::Rect draw_viewport(viewport_size);
boliu7097ee5b2015-12-17 03:16:099761 bool resourceless_software_draw = false;
9762
9763 // Clear any damage.
boliu31c233ed2016-07-29 05:38:599764 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099765 last_on_draw_frame_.reset();
9766
9767 // Always swap even if same draw params.
boliudaa9bdb2015-10-17 15:11:499768 resourceless_software_draw = true;
boliu31c233ed2016-07-29 05:38:599769 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099770 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
9771 last_on_draw_frame_.reset();
boliudaa9bdb2015-10-17 15:11:499772
boliu7097ee5b2015-12-17 03:16:099773 // Next hardware draw has damage.
boliudaa9bdb2015-10-17 15:11:499774 resourceless_software_draw = false;
boliu31c233ed2016-07-29 05:38:599775 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu7097ee5b2015-12-17 03:16:099776 EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
boliudaa9bdb2015-10-17 15:11:499777}
9778
boliu99b904a2016-01-26 22:18:019779TEST_F(ResourcelessSoftwareLayerTreeHostImplTest,
9780 ResourcelessSoftwareDrawSkipsUpdateTiles) {
9781 const gfx::Size viewport_size(100, 100);
9782 host_impl_->SetViewportSize(viewport_size);
9783
9784 host_impl_->CreatePendingTree();
vmpstr41d68f882016-03-30 01:20:239785 scoped_refptr<FakeRasterSource> raster_source(
9786 FakeRasterSource::CreateFilled(viewport_size));
danakj60bc3bc2016-04-09 00:24:489787 std::unique_ptr<FakePictureLayerImpl> layer(
boliu99b904a2016-01-26 22:18:019788 FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(),
9789 11, raster_source));
9790 layer->SetBounds(viewport_size);
9791 layer->SetDrawsContent(true);
jaydasikabf1875a2016-06-28 03:39:599792 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer));
boliu99b904a2016-01-26 22:18:019793
danakj74af409e2016-07-01 00:41:489794 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
boliu99b904a2016-01-26 22:18:019795 host_impl_->ActivateSyncTree();
9796
9797 const gfx::Transform draw_transform;
9798 const gfx::Rect draw_viewport(viewport_size);
boliu99b904a2016-01-26 22:18:019799 bool resourceless_software_draw = false;
9800
9801 // Regular draw causes UpdateTiles.
9802 did_request_prepare_tiles_ = false;
boliu31c233ed2016-07-29 05:38:599803 host_impl_->OnDraw(draw_transform, draw_viewport, resourceless_software_draw);
boliu99b904a2016-01-26 22:18:019804 EXPECT_TRUE(did_request_prepare_tiles_);
9805 host_impl_->PrepareTiles();
9806
9807 // Resourceless draw skips UpdateTiles.
9808 const gfx::Rect new_draw_viewport(50, 50);
9809 resourceless_software_draw = true;
9810 did_request_prepare_tiles_ = false;
boliu31c233ed2016-07-29 05:38:599811 host_impl_->OnDraw(draw_transform, new_draw_viewport,
boliu99b904a2016-01-26 22:18:019812 resourceless_software_draw);
9813 EXPECT_FALSE(did_request_prepare_tiles_);
9814}
9815
boliu5a1970d2016-02-08 21:58:019816TEST_F(LayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) {
9817 EXPECT_FALSE(host_impl_->CommitToActiveTree());
9818 const gfx::Size layer_size(100, 100);
9819 host_impl_->SetViewportSize(layer_size);
9820 bool update_lcd_text = false;
9821
9822 // Set up active and pending tree.
9823 host_impl_->CreatePendingTree();
jaydasikabf1875a2016-06-28 03:39:599824 host_impl_->pending_tree()->SetRootLayerForTesting(
boliu5a1970d2016-02-08 21:58:019825 LayerImpl::Create(host_impl_->pending_tree(), 1));
danakj74af409e2016-07-01 00:41:489826 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
boliu5a1970d2016-02-08 21:58:019827 host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text);
9828
9829 host_impl_->ActivateSyncTree();
danakj74af409e2016-07-01 00:41:489830 host_impl_->active_tree()->BuildPropertyTreesForTesting();
boliu5a1970d2016-02-08 21:58:019831 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9832
9833 host_impl_->CreatePendingTree();
9834 host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text);
9835 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9836
9837 EXPECT_FALSE(host_impl_->pending_tree()->needs_update_draw_properties());
9838 EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
9839
9840 // Update external constraints should set_needs_update_draw_properties on
9841 // both trees.
9842 gfx::Transform external_transform;
9843 gfx::Rect external_viewport(10, 20);
9844 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9845 external_transform);
9846 EXPECT_TRUE(host_impl_->pending_tree()->needs_update_draw_properties());
9847 EXPECT_TRUE(host_impl_->active_tree()->needs_update_draw_properties());
9848}
9849
ajumaed5bee12015-10-21 13:06:329850TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) {
9851 const gfx::Size layer_size(100, 100);
9852 SetupScrollAndContentsLayers(layer_size);
jaydasikafc66cfb2016-06-10 04:34:229853 LayerImpl* content_layer = host_impl_->active_tree()
9854 ->OuterViewportScrollLayer()
9855 ->test_properties()
9856 ->children[0];
ajumaed5bee12015-10-21 13:06:329857
9858 bool update_lcd_text = false;
9859
9860 host_impl_->SetViewportSize(gfx::Size(90, 90));
9861 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9862 EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect());
9863
9864 gfx::Transform external_transform;
9865 gfx::Rect external_viewport(10, 20);
ajumaed5bee12015-10-21 13:06:329866 bool resourceless_software_draw = false;
boliu7097ee5b2015-12-17 03:16:099867 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9868 external_transform);
boliu31c233ed2016-07-29 05:38:599869 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099870 resourceless_software_draw);
ajumaed5bee12015-10-21 13:06:329871 EXPECT_EQ(gfx::Rect(10, 20), content_layer->visible_layer_rect());
9872
9873 // Clear the external viewport.
9874 external_viewport = gfx::Rect();
boliu7097ee5b2015-12-17 03:16:099875 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9876 external_transform);
ajumaed5bee12015-10-21 13:06:329877
boliu31c233ed2016-07-29 05:38:599878 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099879 resourceless_software_draw);
ajumaed5bee12015-10-21 13:06:329880 EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect());
9881}
9882
jaydasikaf18cd962015-10-23 17:29:069883TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) {
9884 const gfx::Size layer_size(100, 100);
9885 SetupScrollAndContentsLayers(layer_size);
jaydasikafc66cfb2016-06-10 04:34:229886 LayerImpl* content_layer = host_impl_->active_tree()
9887 ->OuterViewportScrollLayer()
9888 ->test_properties()
9889 ->children[0];
jaydasikaf18cd962015-10-23 17:29:069890
9891 bool update_lcd_text = false;
9892
9893 host_impl_->SetViewportSize(gfx::Size(50, 50));
9894 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9895 EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect());
9896
9897 gfx::Transform external_transform;
9898 external_transform.Translate(10, 10);
9899 external_transform.Scale(2, 2);
9900 gfx::Rect external_viewport;
jaydasikaf18cd962015-10-23 17:29:069901 bool resourceless_software_draw = false;
boliu7097ee5b2015-12-17 03:16:099902 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9903 external_transform);
jaydasikaf18cd962015-10-23 17:29:069904
9905 // Visible rects should now be shifted and scaled because of the external
9906 // transform.
boliu31c233ed2016-07-29 05:38:599907 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099908 resourceless_software_draw);
jaydasikaf18cd962015-10-23 17:29:069909 EXPECT_EQ(gfx::Rect(20, 20), content_layer->visible_layer_rect());
9910
9911 // Clear the external transform.
9912 external_transform = gfx::Transform();
boliu7097ee5b2015-12-17 03:16:099913 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9914 external_transform);
jaydasikaf18cd962015-10-23 17:29:069915
boliu31c233ed2016-07-29 05:38:599916 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099917 resourceless_software_draw);
jaydasikaf18cd962015-10-23 17:29:069918 EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect());
9919}
9920
jaydasika049b3fb2015-10-23 21:21:579921TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) {
9922 const gfx::Size layer_size(100, 100);
9923 SetupScrollAndContentsLayers(layer_size);
jaydasikafc66cfb2016-06-10 04:34:229924 LayerImpl* content_layer = host_impl_->active_tree()
9925 ->OuterViewportScrollLayer()
9926 ->test_properties()
9927 ->children[0];
jaydasika89f7b5a2016-06-22 02:08:399928 content_layer->test_properties()->AddChild(
9929 LayerImpl::Create(host_impl_->active_tree(), 100));
vollickcb3f6b12016-03-01 23:44:109930 LayerImpl* test_layer = host_impl_->active_tree()->LayerById(100);
jaydasika6b5a32bf2016-04-22 21:56:369931 test_layer->test_properties()->force_render_surface = true;
jaydasika049b3fb2015-10-23 21:21:579932 test_layer->SetDrawsContent(true);
9933 test_layer->SetBounds(layer_size);
9934 gfx::Transform perspective_transform;
9935 perspective_transform.ApplyPerspectiveDepth(2);
jaydasika10d43fc2016-08-18 04:06:049936 test_layer->test_properties()->transform = perspective_transform;
danakj74af409e2016-07-01 00:41:489937 host_impl_->active_tree()->BuildPropertyTreesForTesting();
jaydasika049b3fb2015-10-23 21:21:579938
jaydasika049b3fb2015-10-23 21:21:579939 bool update_lcd_text = false;
9940
9941 host_impl_->SetViewportSize(gfx::Size(50, 50));
9942 host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text);
9943 TransformNode* node =
9944 host_impl_->active_tree()->property_trees()->transform_tree.Node(
9945 test_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:439946 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
jaydasika049b3fb2015-10-23 21:21:579947
9948 gfx::Transform external_transform;
9949 external_transform.Translate(10, 10);
9950 external_transform.Scale(2, 2);
9951 gfx::Rect external_viewport;
jaydasika049b3fb2015-10-23 21:21:579952 bool resourceless_software_draw = false;
boliu7097ee5b2015-12-17 03:16:099953 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9954 external_transform);
jaydasika049b3fb2015-10-23 21:21:579955
9956 // Transform node's sublayer scale should include the device transform scale.
boliu31c233ed2016-07-29 05:38:599957 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099958 resourceless_software_draw);
jaydasika049b3fb2015-10-23 21:21:579959 node = host_impl_->active_tree()->property_trees()->transform_tree.Node(
9960 test_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:439961 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f));
jaydasika049b3fb2015-10-23 21:21:579962
9963 // Clear the external transform.
9964 external_transform = gfx::Transform();
boliu7097ee5b2015-12-17 03:16:099965 host_impl_->SetExternalTilePriorityConstraints(external_viewport,
9966 external_transform);
jaydasika049b3fb2015-10-23 21:21:579967
boliu31c233ed2016-07-29 05:38:599968 host_impl_->OnDraw(external_transform, external_viewport,
boliu7097ee5b2015-12-17 03:16:099969 resourceless_software_draw);
jaydasika049b3fb2015-10-23 21:21:579970 node = host_impl_->active_tree()->property_trees()->transform_tree.Node(
9971 test_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:439972 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
jaydasika049b3fb2015-10-23 21:21:579973}
9974
[email protected]749cbc62014-07-10 01:06:359975TEST_F(LayerTreeHostImplTest, ScrollAnimated) {
ymalik99740e852016-04-07 04:18:139976 const gfx::Size content_size(1000, 1000);
9977 const gfx::Size viewport_size(50, 100);
9978 CreateBasicVirtualViewportLayers(viewport_size, content_size);
skobesde5abdb82015-10-20 19:16:349979
[email protected]749cbc62014-07-10 01:06:359980 DrawFrame();
9981
9982 base::TimeTicks start_time =
9983 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
9984
danakj12e2f6e2015-08-19 22:25:449985 BeginFrameArgs begin_frame_args =
9986 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
9987
tdresser81e84c672016-01-18 23:21:229988 EXPECT_EQ(
9989 InputHandler::SCROLL_ON_IMPL_THREAD,
9990 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
[email protected]749cbc62014-07-10 01:06:359991
9992 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
skobesde5abdb82015-10-20 19:16:349993 EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer);
[email protected]749cbc62014-07-10 01:06:359994
danakj12e2f6e2015-08-19 22:25:449995 begin_frame_args.frame_time = start_time;
9996 host_impl_->WillBeginImplFrame(begin_frame_args);
9997 host_impl_->Animate();
[email protected]749cbc62014-07-10 01:06:359998 host_impl_->UpdateAnimationState(true);
9999
aeliasf998da82015-02-03 01:40:5110000 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
danakj12e2f6e2015-08-19 22:25:4410001 host_impl_->DidFinishImplFrame();
[email protected]749cbc62014-07-10 01:06:3510002
danakj12e2f6e2015-08-19 22:25:4410003 begin_frame_args.frame_time =
10004 start_time + base::TimeDelta::FromMilliseconds(50);
10005 host_impl_->WillBeginImplFrame(begin_frame_args);
10006 host_impl_->Animate();
[email protected]749cbc62014-07-10 01:06:3510007 host_impl_->UpdateAnimationState(true);
10008
aeliasf998da82015-02-03 01:40:5110009 float y = scrolling_layer->CurrentScrollOffset().y();
[email protected]749cbc62014-07-10 01:06:3510010 EXPECT_TRUE(y > 1 && y < 49);
10011
[email protected]7a7d5be2014-07-18 22:37:2610012 // Update target.
tdresser81e84c672016-01-18 23:21:2210013 EXPECT_EQ(
10014 InputHandler::SCROLL_ON_IMPL_THREAD,
10015 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
danakj12e2f6e2015-08-19 22:25:4410016 host_impl_->DidFinishImplFrame();
[email protected]7a7d5be2014-07-18 22:37:2610017
danakj12e2f6e2015-08-19 22:25:4410018 begin_frame_args.frame_time =
10019 start_time + base::TimeDelta::FromMilliseconds(200);
10020 host_impl_->WillBeginImplFrame(begin_frame_args);
10021 host_impl_->Animate();
[email protected]749cbc62014-07-10 01:06:3510022 host_impl_->UpdateAnimationState(true);
10023
aeliasf998da82015-02-03 01:40:5110024 y = scrolling_layer->CurrentScrollOffset().y();
[email protected]7a7d5be2014-07-18 22:37:2610025 EXPECT_TRUE(y > 50 && y < 100);
10026 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410027 host_impl_->DidFinishImplFrame();
[email protected]7a7d5be2014-07-18 22:37:2610028
danakj12e2f6e2015-08-19 22:25:4410029 begin_frame_args.frame_time =
10030 start_time + base::TimeDelta::FromMilliseconds(250);
10031 host_impl_->WillBeginImplFrame(begin_frame_args);
10032 host_impl_->Animate();
[email protected]7a7d5be2014-07-18 22:37:2610033 host_impl_->UpdateAnimationState(true);
10034
miletusf57925d2014-10-01 19:38:1310035 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
aeliasf998da82015-02-03 01:40:5110036 scrolling_layer->CurrentScrollOffset());
[email protected]749cbc62014-07-10 01:06:3510037 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410038 host_impl_->DidFinishImplFrame();
[email protected]749cbc62014-07-10 01:06:3510039}
10040
sahelebcfc332016-09-01 00:13:3710041TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) {
10042 const gfx::Size content_size(1000, 1000);
10043 const gfx::Size viewport_size(50, 100);
10044 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10045
10046 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10047 host_impl_->ScrollAnimatedBegin(gfx::Point()).thread);
10048
10049 // The second ScrollAnimatedBegin should not get ignored.
10050 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10051 host_impl_->ScrollAnimatedBegin(gfx::Point()).thread);
10052}
10053
ymalik04da03c2016-08-18 18:38:1610054// Verfify that a smooth scroll animation doesn't jump when UpdateTarget gets
10055// called before the animation is started.
10056TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) {
10057 const gfx::Size content_size(1000, 1000);
10058 const gfx::Size viewport_size(50, 100);
10059 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10060
10061 DrawFrame();
10062
10063 base::TimeTicks start_time =
10064 base::TimeTicks() + base::TimeDelta::FromMilliseconds(200);
10065
10066 BeginFrameArgs begin_frame_args =
10067 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10068 begin_frame_args.frame_time = start_time;
10069 host_impl_->WillBeginImplFrame(begin_frame_args);
10070 host_impl_->UpdateAnimationState(true);
10071 host_impl_->DidFinishImplFrame();
10072
10073 EXPECT_EQ(
10074 InputHandler::SCROLL_ON_IMPL_THREAD,
10075 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
10076 // This will call ScrollOffsetAnimationCurve::UpdateTarget while the animation
10077 // created above is in state ANIMATION::WAITING_FOR_TARGET_AVAILABILITY and
10078 // doesn't have a start time.
10079 EXPECT_EQ(
10080 InputHandler::SCROLL_ON_IMPL_THREAD,
10081 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100)).thread);
10082
10083 begin_frame_args.frame_time =
10084 start_time + base::TimeDelta::FromMilliseconds(250);
10085 // This is when the animation above gets promoted to STARTING.
10086 host_impl_->WillBeginImplFrame(begin_frame_args);
10087 host_impl_->UpdateAnimationState(true);
10088 host_impl_->DidFinishImplFrame();
10089
10090 begin_frame_args.frame_time =
10091 start_time + base::TimeDelta::FromMilliseconds(300);
10092 // This is when the animation above gets ticked.
10093 host_impl_->WillBeginImplFrame(begin_frame_args);
10094 host_impl_->UpdateAnimationState(true);
10095 host_impl_->DidFinishImplFrame();
10096
10097 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10098 EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer);
10099
10100 // Verify no jump.
10101 float y = scrolling_layer->CurrentScrollOffset().y();
10102 EXPECT_TRUE(y > 1 && y < 49);
10103}
10104
ymalikddfc3522016-09-05 18:40:3710105TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) {
10106 const gfx::Size content_size(1000, 1000);
10107 const gfx::Size viewport_size(50, 100);
10108 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10109
10110 DrawFrame();
10111
10112 base::TimeTicks start_time =
10113 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10114 BeginFrameArgs begin_frame_args =
10115 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10116
10117 // Create animation with a 100ms delay.
10118 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10119 host_impl_
10120 ->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100),
10121 base::TimeDelta::FromMilliseconds(100))
10122 .thread);
10123 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10124 EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer);
10125
10126 // First tick, animation is started.
10127 begin_frame_args.frame_time = start_time;
10128 host_impl_->WillBeginImplFrame(begin_frame_args);
10129 host_impl_->UpdateAnimationState(true);
10130 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10131 host_impl_->DidFinishImplFrame();
10132
10133 // Second tick after 50ms, animation should be half way done since
10134 // the duration due to delay is 100ms.
10135 begin_frame_args.frame_time =
10136 start_time + base::TimeDelta::FromMilliseconds(50);
10137 host_impl_->WillBeginImplFrame(begin_frame_args);
10138 host_impl_->UpdateAnimationState(true);
10139 EXPECT_EQ(50, scrolling_layer->CurrentScrollOffset().y());
10140 host_impl_->DidFinishImplFrame();
10141
10142 // Update target.
10143 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10144 host_impl_
10145 ->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100),
10146 base::TimeDelta::FromMilliseconds(150))
10147 .thread);
10148
10149 // Third tick after 100ms, should be at the target position since update
10150 // target was called with a large value of jank.
10151 begin_frame_args.frame_time =
10152 start_time + base::TimeDelta::FromMilliseconds(100);
10153 host_impl_->WillBeginImplFrame(begin_frame_args);
10154 host_impl_->UpdateAnimationState(true);
10155 EXPECT_LT(100, scrolling_layer->CurrentScrollOffset().y());
10156}
10157
ymalik0f4192062016-01-14 17:18:3510158// Test that a smooth scroll offset animation is aborted when followed by a
10159// non-smooth scroll offset animation.
10160TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) {
ymalik399b4762016-01-25 16:10:1710161 const gfx::Size content_size(1000, 1000);
10162 const gfx::Size viewport_size(500, 500);
10163 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10164
ymalik0f4192062016-01-14 17:18:3510165 DrawFrame();
10166
10167 base::TimeTicks start_time =
10168 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10169
10170 BeginFrameArgs begin_frame_args =
10171 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10172
10173 // Perform animated scroll.
tdresser81e84c672016-01-18 23:21:2210174 EXPECT_EQ(
10175 InputHandler::SCROLL_ON_IMPL_THREAD,
10176 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
ymalik0f4192062016-01-14 17:18:3510177
10178 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10179
10180 begin_frame_args.frame_time = start_time;
10181 host_impl_->WillBeginImplFrame(begin_frame_args);
10182 host_impl_->Animate();
10183 host_impl_->UpdateAnimationState(true);
10184
10185 EXPECT_TRUE(host_impl_->animation_host()->HasAnyAnimationTargetingProperty(
vollickef2ae922016-06-29 17:54:2710186 scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET));
ymalik0f4192062016-01-14 17:18:3510187
10188 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10189 host_impl_->DidFinishImplFrame();
10190
10191 begin_frame_args.frame_time =
10192 start_time + base::TimeDelta::FromMilliseconds(50);
10193 host_impl_->WillBeginImplFrame(begin_frame_args);
10194 host_impl_->Animate();
10195 host_impl_->UpdateAnimationState(true);
10196
10197 float y = scrolling_layer->CurrentScrollOffset().y();
10198 EXPECT_TRUE(y > 1 && y < 49);
10199
10200 // Perform instant scroll.
tdresser81e84c672016-01-18 23:21:2210201 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
ymalik0f4192062016-01-14 17:18:3510202 host_impl_->ScrollBegin(BeginState(gfx::Point(0, y)).get(),
tdresser81e84c672016-01-18 23:21:2210203 InputHandler::WHEEL)
10204 .thread);
ymalik0f4192062016-01-14 17:18:3510205 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y),
10206 InputHandler::WHEEL));
10207 host_impl_->ScrollBy(
10208 UpdateState(gfx::Point(0, y), gfx::Vector2d(0, 50)).get());
10209 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y + 50),
10210 InputHandler::WHEEL));
danakj60bc3bc2016-04-09 00:24:4810211 std::unique_ptr<ScrollState> scroll_state_end = EndState();
tdresserebe6e34c2016-02-10 18:46:0610212 host_impl_->ScrollEnd(scroll_state_end.get());
sahel7adc4a72016-08-25 19:53:4910213 host_impl_->ClearCurrentlyScrollingLayerForTesting();
ymalik0f4192062016-01-14 17:18:3510214 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
10215 InputHandler::WHEEL));
10216
10217 // The instant scroll should have marked the smooth scroll animation as
10218 // aborted.
loysodb73537f2016-03-14 05:07:4510219 EXPECT_FALSE(host_impl_->animation_host()->HasActiveAnimationForTesting(
vollickef2ae922016-06-29 17:54:2710220 scrolling_layer->element_id()));
ymalik0f4192062016-01-14 17:18:3510221
10222 EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(0, y + 50),
10223 scrolling_layer->CurrentScrollOffset());
10224 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
10225 host_impl_->DidFinishImplFrame();
10226}
10227
ymalik4c34ac552016-05-26 00:58:2910228// Test that a smooth scroll offset animation is marked finished when aborted
10229// with the needs_completion flag. The animation is then finished on the
ymalik6581bb3e2016-03-01 07:32:0710230// main thread.
10231TEST_F(LayerTreeHostImplTimelinesTest,
10232 ScrollAnimatedFinishedByMainThreadScrollingReason) {
10233 const gfx::Size content_size(1000, 1000);
10234 const gfx::Size viewport_size(500, 500);
10235 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10236
10237 DrawFrame();
10238
10239 base::TimeTicks start_time =
10240 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10241
10242 BeginFrameArgs begin_frame_args =
10243 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10244
10245 // Perform animated scroll.
10246 EXPECT_EQ(
10247 InputHandler::SCROLL_ON_IMPL_THREAD,
10248 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 100)).thread);
10249
10250 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10251
10252 begin_frame_args.frame_time = start_time;
10253 host_impl_->WillBeginImplFrame(begin_frame_args);
10254 host_impl_->Animate();
10255 host_impl_->UpdateAnimationState(true);
10256
10257 EXPECT_TRUE(host_impl_->animation_host()->HasAnyAnimationTargetingProperty(
vollickef2ae922016-06-29 17:54:2710258 scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET));
ymalik6581bb3e2016-03-01 07:32:0710259
10260 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10261 host_impl_->DidFinishImplFrame();
10262
10263 begin_frame_args.frame_time =
10264 start_time + base::TimeDelta::FromMilliseconds(50);
10265 host_impl_->WillBeginImplFrame(begin_frame_args);
10266 host_impl_->Animate();
10267 host_impl_->UpdateAnimationState(true);
10268
10269 float y = scrolling_layer->CurrentScrollOffset().y();
10270 EXPECT_TRUE(y > 1 && y < 49);
10271
ymalik4c34ac552016-05-26 00:58:2910272 // Abort animation.
10273 host_impl_->animation_host()->ScrollAnimationAbort(true /*needs_completion*/);
ymalik6581bb3e2016-03-01 07:32:0710274 host_impl_->UpdateAnimationState(true);
10275
ymalik4c34ac552016-05-26 00:58:2910276 // Aborting with the needs completion param should have marked the smooth
10277 // scroll animation as finished.
loysodb73537f2016-03-14 05:07:4510278 EXPECT_FALSE(host_impl_->animation_host()->HasActiveAnimationForTesting(
vollickef2ae922016-06-29 17:54:2710279 scrolling_layer->element_id()));
ymalik6581bb3e2016-03-01 07:32:0710280 EXPECT_TRUE(y > 1 && y < 49);
10281 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
10282 host_impl_->DidFinishImplFrame();
10283}
10284
loysoce3bb822015-07-08 02:40:4710285// Evolved from LayerTreeHostImplTest.ScrollAnimated.
10286TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) {
ymalik399b4762016-01-25 16:10:1710287 const gfx::Size content_size(1000, 1000);
10288 const gfx::Size viewport_size(500, 500);
10289 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10290
loysoce3bb822015-07-08 02:40:4710291 DrawFrame();
10292
10293 base::TimeTicks start_time =
10294 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10295
danakj12e2f6e2015-08-19 22:25:4410296 BeginFrameArgs begin_frame_args =
10297 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10298
tdresser81e84c672016-01-18 23:21:2210299 EXPECT_EQ(
10300 InputHandler::SCROLL_ON_IMPL_THREAD,
10301 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
loysoce3bb822015-07-08 02:40:4710302
10303 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
danakj12e2f6e2015-08-19 22:25:4410304 begin_frame_args.frame_time = start_time;
10305 host_impl_->WillBeginImplFrame(begin_frame_args);
10306 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710307 host_impl_->UpdateAnimationState(true);
10308
10309 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
danakj12e2f6e2015-08-19 22:25:4410310 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710311
danakj12e2f6e2015-08-19 22:25:4410312 begin_frame_args.frame_time =
10313 start_time + base::TimeDelta::FromMilliseconds(50);
10314 host_impl_->WillBeginImplFrame(begin_frame_args);
10315 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710316 host_impl_->UpdateAnimationState(true);
10317
10318 float y = scrolling_layer->CurrentScrollOffset().y();
10319 EXPECT_TRUE(y > 1 && y < 49);
10320
10321 // Update target.
tdresser81e84c672016-01-18 23:21:2210322 EXPECT_EQ(
10323 InputHandler::SCROLL_ON_IMPL_THREAD,
10324 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread);
danakj12e2f6e2015-08-19 22:25:4410325 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710326
danakj12e2f6e2015-08-19 22:25:4410327 begin_frame_args.frame_time =
10328 start_time + base::TimeDelta::FromMilliseconds(200);
10329 host_impl_->WillBeginImplFrame(begin_frame_args);
10330 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710331 host_impl_->UpdateAnimationState(true);
10332
10333 y = scrolling_layer->CurrentScrollOffset().y();
10334 EXPECT_TRUE(y > 50 && y < 100);
10335 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410336 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710337
danakj12e2f6e2015-08-19 22:25:4410338 begin_frame_args.frame_time =
10339 start_time + base::TimeDelta::FromMilliseconds(250);
10340 host_impl_->WillBeginImplFrame(begin_frame_args);
10341 host_impl_->Animate();
loysoce3bb822015-07-08 02:40:4710342 host_impl_->UpdateAnimationState(true);
10343
10344 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
10345 scrolling_layer->CurrentScrollOffset());
10346 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
danakj12e2f6e2015-08-19 22:25:4410347 host_impl_->DidFinishImplFrame();
loysoce3bb822015-07-08 02:40:4710348}
10349
ymalik99740e852016-04-07 04:18:1310350// Test that the scroll delta for an animated scroll is distributed correctly
10351// between the inner and outer viewport.
10352TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
10353 const gfx::Size content_size(200, 200);
10354 const gfx::Size viewport_size(100, 100);
10355 CreateBasicVirtualViewportLayers(viewport_size, content_size);
danakj74af409e2016-07-01 00:41:4810356 host_impl_->active_tree()->BuildPropertyTreesForTesting();
ymalik99740e852016-04-07 04:18:1310357
10358 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
10359 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
10360
10361 // Zoom into the page by a 2X factor
10362 float min_page_scale = 1.f, max_page_scale = 4.f;
10363 float page_scale_factor = 2.f;
ymalik99740e852016-04-07 04:18:1310364 host_impl_->active_tree()->PushPageScaleFromMainThread(
10365 page_scale_factor, min_page_scale, max_page_scale);
10366 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
10367
10368 // Scroll by a small amount, there should be no bubbling to the outer
10369 // viewport.
10370 base::TimeTicks start_time =
10371 base::TimeTicks() + base::TimeDelta::FromMilliseconds(250);
10372 BeginFrameArgs begin_frame_args =
10373 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10374 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
10375 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(10.f, 20.f))
10376 .thread);
10377 host_impl_->Animate();
10378 host_impl_->UpdateAnimationState(true);
10379 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10380
10381 BeginImplFrameAndAnimate(begin_frame_args, start_time);
10382 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10),
10383 inner_scroll_layer->CurrentScrollOffset());
10384 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10385 outer_scroll_layer->CurrentScrollOffset());
10386 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset());
10387
10388 // Scroll by the inner viewport's max scroll extent, the remainder
10389 // should bubble up to the outer viewport.
10390 EXPECT_EQ(
10391 InputHandler::SCROLL_ON_IMPL_THREAD,
10392 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(100.f, 100.f))
10393 .thread);
10394 host_impl_->Animate();
10395 host_impl_->UpdateAnimationState(true);
10396 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10397
10398 BeginImplFrameAndAnimate(begin_frame_args,
10399 start_time + base::TimeDelta::FromMilliseconds(350));
10400 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
10401 inner_scroll_layer->CurrentScrollOffset());
10402 EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10),
10403 outer_scroll_layer->CurrentScrollOffset());
10404
10405 // Scroll by the outer viewport's max scroll extent, it should all go to the
10406 // outer viewport.
10407 EXPECT_EQ(
10408 InputHandler::SCROLL_ON_IMPL_THREAD,
10409 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(190.f, 180.f))
10410 .thread);
10411 host_impl_->Animate();
10412 host_impl_->UpdateAnimationState(true);
10413 EXPECT_EQ(outer_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10414
10415 BeginImplFrameAndAnimate(begin_frame_args,
10416 start_time + base::TimeDelta::FromMilliseconds(850));
10417 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
10418 inner_scroll_layer->CurrentScrollOffset());
10419 EXPECT_VECTOR_EQ(gfx::Vector2dF(100, 100),
10420 outer_scroll_layer->CurrentScrollOffset());
10421
10422 // Scroll upwards by the max scroll extent. The inner viewport should animate
10423 // and the remainder should bubble to the outer viewport.
10424 EXPECT_EQ(
10425 InputHandler::SCROLL_ON_IMPL_THREAD,
10426 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(-110.f, -120.f))
10427 .thread);
10428 host_impl_->Animate();
10429 host_impl_->UpdateAnimationState(true);
10430 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10431
10432 BeginImplFrameAndAnimate(
10433 begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1200));
10434 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10435 inner_scroll_layer->CurrentScrollOffset());
10436 EXPECT_VECTOR_EQ(gfx::Vector2dF(95, 90),
10437 outer_scroll_layer->CurrentScrollOffset());
10438}
10439
10440// Test that the correct viewport scroll layer is updated when the target offset
10441// is updated.
10442TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) {
10443 const gfx::Size content_size(200, 200);
10444 const gfx::Size viewport_size(100, 100);
10445 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10446
10447 LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
10448 LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
10449
10450 // Zoom into the page by a 2X factor
10451 float min_page_scale = 1.f, max_page_scale = 4.f;
10452 float page_scale_factor = 2.f;
ymalik99740e852016-04-07 04:18:1310453 host_impl_->active_tree()->PushPageScaleFromMainThread(
10454 page_scale_factor, min_page_scale, max_page_scale);
10455 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
10456
10457 // Scroll the inner viewport.
10458 base::TimeTicks start_time =
10459 base::TimeTicks() + base::TimeDelta::FromMilliseconds(50);
10460 BeginFrameArgs begin_frame_args =
10461 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10462 EXPECT_EQ(
10463 InputHandler::SCROLL_ON_IMPL_THREAD,
10464 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(90, 90)).thread);
10465 host_impl_->Animate();
10466 host_impl_->UpdateAnimationState(true);
10467 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10468
10469 BeginImplFrameAndAnimate(begin_frame_args, start_time);
10470 float inner_x = inner_scroll_layer->CurrentScrollOffset().x();
10471 float inner_y = inner_scroll_layer->CurrentScrollOffset().y();
10472 EXPECT_TRUE(inner_x > 0 && inner_x < 45);
10473 EXPECT_TRUE(inner_y > 0 && inner_y < 45);
10474 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10475 outer_scroll_layer->CurrentScrollOffset());
10476
10477 // Update target.
10478 EXPECT_EQ(
10479 InputHandler::SCROLL_ON_IMPL_THREAD,
10480 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread);
10481 host_impl_->Animate();
10482 host_impl_->UpdateAnimationState(true);
10483 EXPECT_EQ(inner_scroll_layer, host_impl_->CurrentlyScrollingLayer());
10484
10485 // Verify that all the delta is applied to the inner viewport and nothing is
10486 // carried forward.
10487 BeginImplFrameAndAnimate(begin_frame_args,
10488 start_time + base::TimeDelta::FromMilliseconds(350));
10489 EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
10490 inner_scroll_layer->CurrentScrollOffset());
10491 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
10492 outer_scroll_layer->CurrentScrollOffset());
10493 EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset());
10494}
10495
ymalik399b4762016-01-25 16:10:1710496// Test that smooth scroll offset animation doesn't happen for non user
10497// scrollable layers.
10498TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) {
10499 const gfx::Size content_size(1000, 1000);
10500 const gfx::Size viewport_size(500, 500);
10501 CreateBasicVirtualViewportLayers(viewport_size, content_size);
10502
10503 host_impl_->OuterViewportScrollLayer()->set_user_scrollable_vertical(true);
10504 host_impl_->OuterViewportScrollLayer()->set_user_scrollable_horizontal(false);
danakj74af409e2016-07-01 00:41:4810505 host_impl_->active_tree()->BuildPropertyTreesForTesting();
ymalik399b4762016-01-25 16:10:1710506
10507 DrawFrame();
10508
10509 base::TimeTicks start_time =
10510 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10511
10512 BeginFrameArgs begin_frame_args =
10513 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10514
10515 EXPECT_EQ(
10516 InputHandler::SCROLL_ON_IMPL_THREAD,
10517 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread);
10518
10519 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10520 begin_frame_args.frame_time = start_time;
10521 host_impl_->WillBeginImplFrame(begin_frame_args);
10522 host_impl_->Animate();
10523 host_impl_->UpdateAnimationState(true);
10524
10525 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
10526 host_impl_->DidFinishImplFrame();
10527
10528 begin_frame_args.frame_time =
10529 start_time + base::TimeDelta::FromMilliseconds(50);
10530 host_impl_->WillBeginImplFrame(begin_frame_args);
10531 host_impl_->Animate();
10532 host_impl_->UpdateAnimationState(true);
10533
10534 // Should not have scrolled horizontally.
10535 EXPECT_EQ(0, scrolling_layer->CurrentScrollOffset().x());
10536 float y = scrolling_layer->CurrentScrollOffset().y();
10537 EXPECT_TRUE(y > 1 && y < 49);
10538
10539 // Update target.
10540 EXPECT_EQ(
10541 InputHandler::SCROLL_ON_IMPL_THREAD,
10542 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread);
10543 host_impl_->DidFinishImplFrame();
10544
10545 begin_frame_args.frame_time =
10546 start_time + base::TimeDelta::FromMilliseconds(200);
10547 host_impl_->WillBeginImplFrame(begin_frame_args);
10548 host_impl_->Animate();
10549 host_impl_->UpdateAnimationState(true);
10550
10551 y = scrolling_layer->CurrentScrollOffset().y();
10552 EXPECT_TRUE(y > 50 && y < 100);
10553 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
10554 host_impl_->DidFinishImplFrame();
10555
10556 begin_frame_args.frame_time =
10557 start_time + base::TimeDelta::FromMilliseconds(250);
10558 host_impl_->WillBeginImplFrame(begin_frame_args);
10559 host_impl_->Animate();
10560 host_impl_->UpdateAnimationState(true);
10561
10562 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
10563 scrolling_layer->CurrentScrollOffset());
10564 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
10565 host_impl_->DidFinishImplFrame();
10566}
10567
skobes4d7f47cc82016-05-04 22:05:4110568// Test that smooth scrolls clamp correctly when bounds change mid-animation.
10569TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) {
10570 const gfx::Size old_content_size(1000, 1000);
10571 const gfx::Size new_content_size(750, 750);
10572 const gfx::Size viewport_size(500, 500);
10573
10574 LayerImpl* content_layer =
10575 CreateBasicVirtualViewportLayers(viewport_size, old_content_size);
danakj74af409e2016-07-01 00:41:4810576
skobes4d7f47cc82016-05-04 22:05:4110577 DrawFrame();
10578
10579 base::TimeTicks start_time =
10580 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
10581 BeginFrameArgs begin_frame_args =
10582 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10583
10584 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(500, 500));
10585 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
10586
10587 begin_frame_args.frame_time = start_time;
10588 host_impl_->WillBeginImplFrame(begin_frame_args);
10589 host_impl_->Animate();
10590 host_impl_->UpdateAnimationState(true);
10591 host_impl_->DidFinishImplFrame();
10592
10593 content_layer->SetBounds(new_content_size);
10594 scrolling_layer->SetBounds(new_content_size);
danakj74af409e2016-07-01 00:41:4810595 host_impl_->active_tree()->BuildPropertyTreesForTesting();
10596
skobes4d7f47cc82016-05-04 22:05:4110597 DrawFrame();
10598
10599 begin_frame_args.frame_time =
10600 start_time + base::TimeDelta::FromMilliseconds(200);
10601 host_impl_->WillBeginImplFrame(begin_frame_args);
10602 host_impl_->Animate();
10603 host_impl_->UpdateAnimationState(true);
10604 host_impl_->DidFinishImplFrame();
10605
10606 EXPECT_EQ(gfx::ScrollOffset(250, 250),
10607 scrolling_layer->CurrentScrollOffset());
10608}
10609
hendrikw72abb582015-05-08 18:19:5310610TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
10611 host_impl_->CreatePendingTree();
10612
10613 Region empty_invalidation;
vmpstr41d68f882016-03-30 01:20:2310614 scoped_refptr<RasterSource> raster_source_with_tiles(
10615 FakeRasterSource::CreateFilled(gfx::Size(10, 10)));
hendrikw72abb582015-05-08 18:19:5310616
danakj60bc3bc2016-04-09 00:24:4810617 std::unique_ptr<FakePictureLayerImpl> layer =
hendrikw72abb582015-05-08 18:19:5310618 FakePictureLayerImpl::Create(host_impl_->pending_tree(), 11);
10619 layer->SetBounds(gfx::Size(10, 10));
10620 layer->set_gpu_raster_max_texture_size(host_impl_->device_viewport_size());
10621 layer->SetDrawsContent(true);
vmpstr856740262015-09-24 00:25:2510622 layer->tilings()->AddTiling(1.0f, raster_source_with_tiles);
10623 layer->UpdateRasterSource(raster_source_with_tiles, &empty_invalidation,
10624 nullptr);
hendrikw72abb582015-05-08 18:19:5310625 layer->tilings()->tiling_at(0)->set_resolution(
10626 TileResolution::HIGH_RESOLUTION);
10627 layer->tilings()->tiling_at(0)->CreateAllTilesForTesting();
vmpstrcf111332016-05-04 21:20:4310628 layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0,
10629 Occlusion(), true);
jaydasikabf1875a2016-06-28 03:39:5910630 host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer));
hendrikw72abb582015-05-08 18:19:5310631
10632 FakePictureLayerImpl* root_layer = static_cast<FakePictureLayerImpl*>(
jaydasikabf1875a2016-06-28 03:39:5910633 host_impl_->pending_tree()->root_layer_for_testing());
hendrikw72abb582015-05-08 18:19:5310634
10635 root_layer->set_has_valid_tile_priorities(true);
danakj60bc3bc2016-04-09 00:24:4810636 std::unique_ptr<RasterTilePriorityQueue> non_empty_raster_priority_queue_all =
hendrikw72abb582015-05-08 18:19:5310637 host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES,
10638 RasterTilePriorityQueue::Type::ALL);
10639 EXPECT_FALSE(non_empty_raster_priority_queue_all->IsEmpty());
10640
10641 root_layer->set_has_valid_tile_priorities(false);
danakj60bc3bc2016-04-09 00:24:4810642 std::unique_ptr<RasterTilePriorityQueue> empty_raster_priority_queue_all =
hendrikw72abb582015-05-08 18:19:5310643 host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES,
10644 RasterTilePriorityQueue::Type::ALL);
10645 EXPECT_TRUE(empty_raster_priority_queue_all->IsEmpty());
10646}
10647
[email protected]db2e29c2014-08-06 05:58:2510648TEST_F(LayerTreeHostImplTest, DidBecomeActive) {
10649 host_impl_->CreatePendingTree();
10650 host_impl_->ActivateSyncTree();
10651 host_impl_->CreatePendingTree();
10652
10653 LayerTreeImpl* pending_tree = host_impl_->pending_tree();
10654
danakj60bc3bc2016-04-09 00:24:4810655 std::unique_ptr<FakePictureLayerImpl> pending_layer =
[email protected]db2e29c2014-08-06 05:58:2510656 FakePictureLayerImpl::Create(pending_tree, 10);
[email protected]db2e29c2014-08-06 05:58:2510657 FakePictureLayerImpl* raw_pending_layer = pending_layer.get();
jaydasikabf1875a2016-06-28 03:39:5910658 pending_tree->SetRootLayerForTesting(std::move(pending_layer));
jaydasikabf1875a2016-06-28 03:39:5910659 ASSERT_EQ(raw_pending_layer, pending_tree->root_layer_for_testing());
[email protected]db2e29c2014-08-06 05:58:2510660
10661 EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count());
10662 pending_tree->DidBecomeActive();
10663 EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count());
10664
danakj60bc3bc2016-04-09 00:24:4810665 std::unique_ptr<FakePictureLayerImpl> mask_layer =
[email protected]db2e29c2014-08-06 05:58:2510666 FakePictureLayerImpl::Create(pending_tree, 11);
[email protected]db2e29c2014-08-06 05:58:2510667 FakePictureLayerImpl* raw_mask_layer = mask_layer.get();
ajuma1d4026a32016-06-14 13:18:5010668 raw_pending_layer->test_properties()->SetMaskLayer(std::move(mask_layer));
10669 ASSERT_EQ(raw_mask_layer, raw_pending_layer->test_properties()->mask_layer);
danakj74af409e2016-07-01 00:41:4810670 pending_tree->BuildPropertyTreesForTesting();
[email protected]db2e29c2014-08-06 05:58:2510671
10672 EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count());
10673 EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count());
10674 pending_tree->DidBecomeActive();
10675 EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count());
10676 EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count());
10677
danakj60bc3bc2016-04-09 00:24:4810678 std::unique_ptr<FakePictureLayerImpl> replica_layer =
[email protected]db2e29c2014-08-06 05:58:2510679 FakePictureLayerImpl::Create(pending_tree, 12);
danakj60bc3bc2016-04-09 00:24:4810680 std::unique_ptr<FakePictureLayerImpl> replica_mask_layer =
[email protected]db2e29c2014-08-06 05:58:2510681 FakePictureLayerImpl::Create(pending_tree, 13);
[email protected]db2e29c2014-08-06 05:58:2510682 FakePictureLayerImpl* raw_replica_mask_layer = replica_mask_layer.get();
ajuma1d4026a32016-06-14 13:18:5010683 replica_layer->test_properties()->SetMaskLayer(std::move(replica_mask_layer));
10684 raw_pending_layer->test_properties()->SetReplicaLayer(
10685 std::move(replica_layer));
10686 ASSERT_EQ(raw_replica_mask_layer, raw_pending_layer->test_properties()
10687 ->replica_layer->test_properties()
10688 ->mask_layer);
danakj74af409e2016-07-01 00:41:4810689 pending_tree->BuildPropertyTreesForTesting();
[email protected]db2e29c2014-08-06 05:58:2510690
10691 EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count());
10692 EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count());
10693 EXPECT_EQ(0u, raw_replica_mask_layer->did_become_active_call_count());
10694 pending_tree->DidBecomeActive();
10695 EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count());
10696 EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count());
10697 EXPECT_EQ(1u, raw_replica_mask_layer->did_become_active_call_count());
10698}
10699
lanweid17d0742014-12-01 18:58:5210700TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) {
10701 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
10702 host_impl_->SetViewportSize(gfx::Size(50, 50));
10703 DrawFrame();
10704
10705 EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer());
10706
10707 float min_page_scale = 1.f, max_page_scale = 4.f;
10708 float page_scale_factor = 1.f;
10709
10710 // The scroll deltas should have the page scale factor applied.
10711 {
aelias58eec0812014-12-04 01:04:4010712 host_impl_->active_tree()->PushPageScaleFromMainThread(
lanweid17d0742014-12-01 18:58:5210713 page_scale_factor, min_page_scale, max_page_scale);
danakj5ad246cd2015-09-12 01:04:5010714 host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
sunxdb7e79432016-03-09 21:13:4210715 SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
lanweid17d0742014-12-01 18:58:5210716
10717 float page_scale_delta = 2.f;
majidvp944a8cd2016-01-12 21:05:1810718 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
dtapuska40e8aff2016-03-11 21:45:0310719 InputHandler::TOUCHSCREEN);
lanweid17d0742014-12-01 18:58:5210720 host_impl_->PinchGestureBegin();
10721 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
10722 host_impl_->PinchGestureEnd();
majidvp944a8cd2016-01-12 21:05:1810723 host_impl_->ScrollEnd(EndState().get());
lanweid17d0742014-12-01 18:58:5210724
10725 gfx::Vector2dF scroll_delta(0, 5);
tdresser81e84c672016-01-18 23:21:2210726 EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
majidvp944a8cd2016-01-12 21:05:1810727 host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
tdresser81e84c672016-01-18 23:21:2210728 InputHandler::WHEEL)
10729 .thread);
aeliasf998da82015-02-03 01:40:5110730 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
lanweid17d0742014-12-01 18:58:5210731
majidvp944a8cd2016-01-12 21:05:1810732 host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
10733 host_impl_->ScrollEnd(EndState().get());
aeliasf998da82015-02-03 01:40:5110734 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 2.5),
10735 scroll_layer->CurrentScrollOffset());
lanweid17d0742014-12-01 18:58:5210736 }
10737}
10738
[email protected]0e0b7fd92014-08-08 22:53:1110739class LayerTreeHostImplCountingLostSurfaces : public LayerTreeHostImplTest {
10740 public:
10741 LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {}
dcheng716bedf2014-10-21 09:51:0810742 void DidLoseOutputSurfaceOnImplThread() override { num_lost_surfaces_++; }
[email protected]0e0b7fd92014-08-08 22:53:1110743
10744 protected:
10745 int num_lost_surfaces_;
10746};
10747
10748TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) {
[email protected]0e0b7fd92014-08-08 22:53:1110749 // Really we just need at least one client notification each time
10750 // we go from having a valid output surface to not having a valid output
10751 // surface.
10752 EXPECT_EQ(0, num_lost_surfaces_);
[email protected]0e0b7fd92014-08-08 22:53:1110753 host_impl_->DidLoseOutputSurface();
[email protected]0e0b7fd92014-08-08 22:53:1110754 EXPECT_EQ(1, num_lost_surfaces_);
10755 host_impl_->DidLoseOutputSurface();
dnetob71e30c2014-08-25 23:27:2010756 EXPECT_LE(1, num_lost_surfaces_);
[email protected]0e0b7fd92014-08-08 22:53:1110757}
10758
danakj61902b82015-10-30 00:30:2610759size_t CountRenderPassesWithId(const RenderPassList& list, RenderPassId id) {
vmpstra370ef52015-11-18 10:41:2810760 return std::count_if(
10761 list.begin(), list.end(),
danakj60bc3bc2016-04-09 00:24:4810762 [id](const std::unique_ptr<RenderPass>& p) { return p->id == id; });
danakj61902b82015-10-30 00:30:2610763}
10764
danakj112d3a102015-04-14 18:24:4910765TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) {
10766 LayerTreeHostImpl::FrameData frame;
10767 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810768 RenderPass* pass3 = 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* pass2 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910771 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810772 RenderPass* pass1 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910773
10774 pass1->SetNew(RenderPassId(1, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10775 pass2->SetNew(RenderPassId(2, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10776 pass3->SetNew(RenderPassId(3, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10777
danakj112d3a102015-04-14 18:24:4910778 // Add a quad to each pass so they aren't empty.
10779 SolidColorDrawQuad* color_quad;
10780 color_quad = pass1->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10781 color_quad->material = DrawQuad::SOLID_COLOR;
10782 color_quad = pass2->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10783 color_quad->material = DrawQuad::SOLID_COLOR;
10784 color_quad = pass3->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10785 color_quad->material = DrawQuad::SOLID_COLOR;
10786
10787 // pass3 is referenced by pass2.
10788 RenderPassDrawQuad* rpdq =
10789 pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10790 rpdq->material = DrawQuad::RENDER_PASS;
10791 rpdq->render_pass_id = pass3->id;
10792
10793 // But pass2 is not referenced by pass1. So pass2 and pass3 should be culled.
10794 FakeLayerTreeHostImpl::RemoveRenderPasses(&frame);
danakj112d3a102015-04-14 18:24:4910795 EXPECT_EQ(1u, frame.render_passes.size());
danakj61902b82015-10-30 00:30:2610796 EXPECT_EQ(1u,
10797 CountRenderPassesWithId(frame.render_passes, RenderPassId(1, 0)));
10798 EXPECT_EQ(0u,
10799 CountRenderPassesWithId(frame.render_passes, RenderPassId(2, 0)));
10800 EXPECT_EQ(0u,
10801 CountRenderPassesWithId(frame.render_passes, RenderPassId(3, 0)));
danakj112d3a102015-04-14 18:24:4910802 EXPECT_EQ(RenderPassId(1, 0), frame.render_passes[0]->id);
10803}
10804
10805TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) {
10806 LayerTreeHostImpl::FrameData frame;
10807 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810808 RenderPass* pass3 = 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* pass2 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910811 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810812 RenderPass* pass1 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910813
10814 pass1->SetNew(RenderPassId(1, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10815 pass2->SetNew(RenderPassId(2, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10816 pass3->SetNew(RenderPassId(3, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10817
danakj112d3a102015-04-14 18:24:4910818 // pass1 is not empty, but pass2 and pass3 are.
10819 SolidColorDrawQuad* color_quad;
10820 color_quad = pass1->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
10821 color_quad->material = DrawQuad::SOLID_COLOR;
10822
10823 // pass3 is referenced by pass2.
10824 RenderPassDrawQuad* rpdq =
10825 pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10826 rpdq->material = DrawQuad::RENDER_PASS;
10827 rpdq->render_pass_id = pass3->id;
10828
10829 // pass2 is referenced by pass1.
10830 rpdq = pass1->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10831 rpdq->material = DrawQuad::RENDER_PASS;
10832 rpdq->render_pass_id = pass2->id;
10833
10834 // Since pass3 is empty it should be removed. Then pass2 is empty too, and
10835 // should be removed.
10836 FakeLayerTreeHostImpl::RemoveRenderPasses(&frame);
danakj112d3a102015-04-14 18:24:4910837 EXPECT_EQ(1u, frame.render_passes.size());
danakj61902b82015-10-30 00:30:2610838 EXPECT_EQ(1u,
10839 CountRenderPassesWithId(frame.render_passes, RenderPassId(1, 0)));
10840 EXPECT_EQ(0u,
10841 CountRenderPassesWithId(frame.render_passes, RenderPassId(2, 0)));
10842 EXPECT_EQ(0u,
10843 CountRenderPassesWithId(frame.render_passes, RenderPassId(3, 0)));
danakj112d3a102015-04-14 18:24:4910844 EXPECT_EQ(RenderPassId(1, 0), frame.render_passes[0]->id);
10845 // The RenderPassDrawQuad should be removed from pass1.
10846 EXPECT_EQ(1u, pass1->quad_list.size());
10847 EXPECT_EQ(DrawQuad::SOLID_COLOR, pass1->quad_list.ElementAt(0)->material);
10848}
10849
10850TEST_F(LayerTreeHostImplTest, DoNotRemoveEmptyRootRenderPass) {
10851 LayerTreeHostImpl::FrameData frame;
10852 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810853 RenderPass* pass3 = 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* pass2 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910856 frame.render_passes.push_back(RenderPass::Create());
vmpstra370ef52015-11-18 10:41:2810857 RenderPass* pass1 = frame.render_passes.back().get();
danakj112d3a102015-04-14 18:24:4910858
10859 pass1->SetNew(RenderPassId(1, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10860 pass2->SetNew(RenderPassId(2, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10861 pass3->SetNew(RenderPassId(3, 0), gfx::Rect(), gfx::Rect(), gfx::Transform());
10862
danakj112d3a102015-04-14 18:24:4910863 // pass3 is referenced by pass2.
10864 RenderPassDrawQuad* rpdq =
10865 pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10866 rpdq->material = DrawQuad::RENDER_PASS;
10867 rpdq->render_pass_id = pass3->id;
10868
10869 // pass2 is referenced by pass1.
10870 rpdq = pass1->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
10871 rpdq->material = DrawQuad::RENDER_PASS;
10872 rpdq->render_pass_id = pass2->id;
10873
10874 // Since pass3 is empty it should be removed. Then pass2 is empty too, and
10875 // should be removed. Then pass1 is empty too, but it's the root so it should
10876 // not be removed.
10877 FakeLayerTreeHostImpl::RemoveRenderPasses(&frame);
danakj112d3a102015-04-14 18:24:4910878 EXPECT_EQ(1u, frame.render_passes.size());
danakj61902b82015-10-30 00:30:2610879 EXPECT_EQ(1u,
10880 CountRenderPassesWithId(frame.render_passes, RenderPassId(1, 0)));
10881 EXPECT_EQ(0u,
10882 CountRenderPassesWithId(frame.render_passes, RenderPassId(2, 0)));
10883 EXPECT_EQ(0u,
10884 CountRenderPassesWithId(frame.render_passes, RenderPassId(3, 0)));
danakj112d3a102015-04-14 18:24:4910885 EXPECT_EQ(RenderPassId(1, 0), frame.render_passes[0]->id);
10886 // The RenderPassDrawQuad should be removed from pass1.
10887 EXPECT_EQ(0u, pass1->quad_list.size());
10888}
10889
sunnypsc052ba992015-05-05 00:42:2910890class FakeVideoFrameController : public VideoFrameController {
10891 public:
10892 void OnBeginFrame(const BeginFrameArgs& args) override {
10893 begin_frame_args_ = args;
dalecurtise8024c42015-05-29 21:22:3510894 did_draw_frame_ = false;
sunnypsc052ba992015-05-05 00:42:2910895 }
10896
dalecurtise8024c42015-05-29 21:22:3510897 void DidDrawFrame() override { did_draw_frame_ = true; }
10898
10899 const BeginFrameArgs& begin_frame_args() const { return begin_frame_args_; }
10900
10901 bool did_draw_frame() const { return did_draw_frame_; }
sunnypsc052ba992015-05-05 00:42:2910902
10903 private:
10904 BeginFrameArgs begin_frame_args_;
dalecurtise8024c42015-05-29 21:22:3510905 bool did_draw_frame_ = false;
sunnypsc052ba992015-05-05 00:42:2910906};
10907
10908TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
10909 BeginFrameArgs begin_frame_args =
10910 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10911 FakeVideoFrameController controller;
10912
10913 host_impl_->WillBeginImplFrame(begin_frame_args);
10914 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10915 host_impl_->AddVideoFrameController(&controller);
10916 EXPECT_TRUE(controller.begin_frame_args().IsValid());
mithro51693e382015-05-07 23:52:4110917 host_impl_->DidFinishImplFrame();
dalecurtise8024c42015-05-29 21:22:3510918
10919 EXPECT_FALSE(controller.did_draw_frame());
10920 LayerTreeHostImpl::FrameData frame;
10921 host_impl_->DidDrawAllLayers(frame);
10922 EXPECT_TRUE(controller.did_draw_frame());
10923
10924 controller.OnBeginFrame(begin_frame_args);
10925 EXPECT_FALSE(controller.did_draw_frame());
10926 host_impl_->RemoveVideoFrameController(&controller);
10927 host_impl_->DidDrawAllLayers(frame);
10928 EXPECT_FALSE(controller.did_draw_frame());
sunnypsc052ba992015-05-05 00:42:2910929}
10930
10931TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
10932 BeginFrameArgs begin_frame_args =
10933 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10934 FakeVideoFrameController controller;
10935
10936 host_impl_->WillBeginImplFrame(begin_frame_args);
mithro51693e382015-05-07 23:52:4110937 host_impl_->DidFinishImplFrame();
sunnypsc052ba992015-05-05 00:42:2910938
10939 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10940 host_impl_->AddVideoFrameController(&controller);
10941 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10942
10943 begin_frame_args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
10944 EXPECT_FALSE(controller.begin_frame_args().IsValid());
10945 host_impl_->WillBeginImplFrame(begin_frame_args);
10946 EXPECT_TRUE(controller.begin_frame_args().IsValid());
dalecurtise8024c42015-05-29 21:22:3510947
10948 EXPECT_FALSE(controller.did_draw_frame());
10949 LayerTreeHostImpl::FrameData frame;
10950 host_impl_->DidDrawAllLayers(frame);
10951 EXPECT_TRUE(controller.did_draw_frame());
10952
10953 controller.OnBeginFrame(begin_frame_args);
10954 EXPECT_FALSE(controller.did_draw_frame());
10955 host_impl_->RemoveVideoFrameController(&controller);
10956 host_impl_->DidDrawAllLayers(frame);
10957 EXPECT_FALSE(controller.did_draw_frame());
sunnypsc052ba992015-05-05 00:42:2910958}
10959
senorblancofb88a4e2015-05-08 17:28:4110960TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) {
10961 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
10962
senorblanco9c04acb2015-05-15 19:41:3210963 host_impl_->SetHasGpuRasterizationTrigger(true);
10964 host_impl_->SetContentIsSuitableForGpuRasterization(true);
danakj1a86f6d62016-08-17 20:10:4010965 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110966 EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
10967 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
10968
senorblanco9c04acb2015-05-15 19:41:3210969 host_impl_->SetHasGpuRasterizationTrigger(false);
10970 host_impl_->SetContentIsSuitableForGpuRasterization(true);
danakj1a86f6d62016-08-17 20:10:4010971 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110972 EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT,
10973 host_impl_->gpu_rasterization_status());
10974 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
10975
senorblanco9c04acb2015-05-15 19:41:3210976 host_impl_->SetHasGpuRasterizationTrigger(true);
10977 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4010978 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110979 EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT,
10980 host_impl_->gpu_rasterization_status());
10981 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
10982 EXPECT_FALSE(host_impl_->use_msaa());
10983
danakj60bc3bc2016-04-09 00:24:4810984 std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa =
senorblancofb88a4e2015-05-08 17:28:4110985 TestWebGraphicsContext3D::Create();
10986 context_with_msaa->SetMaxSamples(8);
10987
10988 LayerTreeSettings msaaSettings = GpuRasterizationEnabledSettings();
10989 msaaSettings.gpu_rasterization_msaa_sample_count = 4;
10990 EXPECT_TRUE(CreateHostImpl(
danakjf33ceec2016-07-20 20:04:4510991 msaaSettings,
10992 FakeOutputSurface::CreateDelegating3d(std::move(context_with_msaa))));
senorblanco9c04acb2015-05-15 19:41:3210993 host_impl_->SetHasGpuRasterizationTrigger(true);
10994 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4010995 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4110996 EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
10997 host_impl_->gpu_rasterization_status());
10998 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
10999 EXPECT_TRUE(host_impl_->use_msaa());
11000
11001 LayerTreeSettings settings = DefaultSettings();
11002 settings.gpu_rasterization_enabled = false;
danakjf33ceec2016-07-20 20:04:4511003 EXPECT_TRUE(
11004 CreateHostImpl(settings, FakeOutputSurface::CreateDelegating3d()));
senorblanco9c04acb2015-05-15 19:41:3211005 host_impl_->SetHasGpuRasterizationTrigger(true);
11006 host_impl_->SetContentIsSuitableForGpuRasterization(true);
danakj1a86f6d62016-08-17 20:10:4011007 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4111008 EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE,
11009 host_impl_->gpu_rasterization_status());
11010 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
11011
11012 settings.gpu_rasterization_forced = true;
danakjf33ceec2016-07-20 20:04:4511013 EXPECT_TRUE(
11014 CreateHostImpl(settings, FakeOutputSurface::CreateDelegating3d()));
senorblancofb88a4e2015-05-08 17:28:4111015
senorblanco9c04acb2015-05-15 19:41:3211016 host_impl_->SetHasGpuRasterizationTrigger(false);
11017 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4011018 host_impl_->CommitComplete();
senorblancofb88a4e2015-05-08 17:28:4111019 EXPECT_EQ(GpuRasterizationStatus::ON_FORCED,
11020 host_impl_->gpu_rasterization_status());
11021 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
11022}
11023
ericrkd72af43d2016-03-18 21:44:3111024class MsaaIsSlowLayerTreeHostImplTest : public LayerTreeHostImplTest {
11025 public:
11026 void CreateHostImplWithMsaaIsSlow(bool msaa_is_slow) {
11027 LayerTreeSettings settings = DefaultSettings();
11028 settings.gpu_rasterization_enabled = true;
11029 settings.gpu_rasterization_msaa_sample_count = 4;
11030 auto context_provider = TestContextProvider::Create();
11031 context_provider->UnboundTestContext3d()->SetMaxSamples(4);
11032 context_provider->UnboundTestContext3d()->set_msaa_is_slow(msaa_is_slow);
11033 auto msaa_is_normal_output_surface =
danakjf33ceec2016-07-20 20:04:4511034 FakeOutputSurface::CreateDelegating3d(context_provider);
ericrkd72af43d2016-03-18 21:44:3111035 EXPECT_TRUE(
11036 CreateHostImpl(settings, std::move(msaa_is_normal_output_surface)));
11037 }
11038};
11039
11040TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) {
11041 // Ensure that without the msaa_is_slow cap we raster unsuitable content with
11042 // msaa.
11043 CreateHostImplWithMsaaIsSlow(false);
11044 host_impl_->SetHasGpuRasterizationTrigger(true);
11045 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4011046 host_impl_->CommitComplete();
ericrkd72af43d2016-03-18 21:44:3111047 EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
11048 host_impl_->gpu_rasterization_status());
11049 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
11050
11051 // Ensure that with the msaa_is_slow cap we don't raster unsuitable content
11052 // with msaa.
11053 CreateHostImplWithMsaaIsSlow(true);
11054 host_impl_->SetHasGpuRasterizationTrigger(true);
11055 host_impl_->SetContentIsSuitableForGpuRasterization(false);
danakj1a86f6d62016-08-17 20:10:4011056 host_impl_->CommitComplete();
ericrkd72af43d2016-03-18 21:44:3111057 EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT,
11058 host_impl_->gpu_rasterization_status());
11059 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
11060}
11061
ericrk17ec17f2015-05-19 19:50:5111062// A mock output surface which lets us detect calls to ForceReclaimResources.
11063class MockReclaimResourcesOutputSurface : public FakeOutputSurface {
11064 public:
danakjc070bf552016-08-10 22:41:5511065 MockReclaimResourcesOutputSurface()
11066 : FakeOutputSurface(TestContextProvider::Create(),
11067 TestContextProvider::CreateWorker(),
11068 true) {}
ericrk17ec17f2015-05-19 19:50:5111069
11070 MOCK_METHOD0(ForceReclaimResources, void());
ericrk17ec17f2015-05-19 19:50:5111071};
11072
11073// Display::Draw (and the planned Display Scheduler) currently rely on resources
11074// being reclaimed to block drawing between BeginCommit / Swap. This test
11075// ensures that BeginCommit triggers ForceReclaimResources. See
11076// crbug.com/489515.
11077TEST_F(LayerTreeHostImplTest, BeginCommitReclaimsResources) {
danakjc070bf552016-08-10 22:41:5511078 auto output_surface = base::MakeUnique<MockReclaimResourcesOutputSurface>();
ericrk17ec17f2015-05-19 19:50:5111079 // Hold an unowned pointer to the output surface to use for mock expectations.
11080 MockReclaimResourcesOutputSurface* mock_output_surface = output_surface.get();
11081
danakja04855a2015-11-18 20:39:1011082 CreateHostImpl(DefaultSettings(), std::move(output_surface));
ericrk17ec17f2015-05-19 19:50:5111083 EXPECT_CALL(*mock_output_surface, ForceReclaimResources()).Times(1);
11084 host_impl_->BeginCommit();
11085}
11086
jaydasika0c1fd602015-10-07 17:59:5211087TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
11088 // Check page scale factor update in property trees when an update is made
11089 // on the active tree.
11090 host_impl_->CreatePendingTree();
11091 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f);
11092 CreateScrollAndContentsLayers(host_impl_->pending_tree(),
11093 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:4811094 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasika0c1fd602015-10-07 17:59:5211095 host_impl_->ActivateSyncTree();
11096 DrawFrame();
11097
11098 host_impl_->CreatePendingTree();
11099 host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
11100 LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer();
11101
11102 TransformNode* active_tree_node =
11103 host_impl_->active_tree()->property_trees()->transform_tree.Node(
11104 page_scale_layer->transform_tree_index());
sunxdcfccd1b32016-02-11 00:54:2011105 // SetPageScaleOnActiveTree also updates the factors in property trees.
trchendba8b1502016-07-08 09:47:0111106 EXPECT_EQ(active_tree_node->post_local_scale_factor, 2.f);
jaydasika0c1fd602015-10-07 17:59:5211107 EXPECT_EQ(host_impl_->active_tree()->current_page_scale_factor(), 2.f);
11108
11109 TransformNode* pending_tree_node =
11110 host_impl_->pending_tree()->property_trees()->transform_tree.Node(
11111 page_scale_layer->transform_tree_index());
trchendba8b1502016-07-08 09:47:0111112 EXPECT_EQ(pending_tree_node->post_local_scale_factor, 1.f);
jaydasika0c1fd602015-10-07 17:59:5211113 EXPECT_EQ(host_impl_->pending_tree()->current_page_scale_factor(), 2.f);
11114
11115 host_impl_->pending_tree()->UpdateDrawProperties(false);
11116 pending_tree_node =
11117 host_impl_->pending_tree()->property_trees()->transform_tree.Node(
11118 page_scale_layer->transform_tree_index());
trchendba8b1502016-07-08 09:47:0111119 EXPECT_EQ(pending_tree_node->post_local_scale_factor, 2.f);
jaydasika0c1fd602015-10-07 17:59:5211120
11121 host_impl_->ActivateSyncTree();
11122 host_impl_->active_tree()->UpdateDrawProperties(false);
11123 active_tree_node =
11124 host_impl_->active_tree()->property_trees()->transform_tree.Node(
11125 page_scale_layer->transform_tree_index());
trchendba8b1502016-07-08 09:47:0111126 EXPECT_EQ(active_tree_node->post_local_scale_factor, 2.f);
jaydasika0c1fd602015-10-07 17:59:5211127}
11128
jaydasikafbb9f43a2015-10-22 20:44:0811129TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) {
11130 // Checks that the sublayer scale of a transform node in the subtree of the
11131 // page scale layer is updated without a property tree rebuild.
11132 host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f);
11133 CreateScrollAndContentsLayers(host_impl_->active_tree(), gfx::Size(100, 100));
11134 LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer();
jaydasika89f7b5a2016-06-22 02:08:3911135 page_scale_layer->test_properties()->AddChild(
11136 LayerImpl::Create(host_impl_->active_tree(), 100));
jaydasikafbb9f43a2015-10-22 20:44:0811137
11138 LayerImpl* in_subtree_of_page_scale_layer =
vollickcb3f6b12016-03-01 23:44:1011139 host_impl_->active_tree()->LayerById(100);
jaydasika6b5a32bf2016-04-22 21:56:3611140 in_subtree_of_page_scale_layer->test_properties()->force_render_surface =
11141 true;
danakj74af409e2016-07-01 00:41:4811142 host_impl_->active_tree()->BuildPropertyTreesForTesting();
11143
jaydasikafbb9f43a2015-10-22 20:44:0811144 DrawFrame();
danakj74af409e2016-07-01 00:41:4811145
jaydasikafbb9f43a2015-10-22 20:44:0811146 TransformNode* node =
11147 host_impl_->active_tree()->property_trees()->transform_tree.Node(
11148 in_subtree_of_page_scale_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:4311149 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
jaydasikafbb9f43a2015-10-22 20:44:0811150
11151 host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
danakj74af409e2016-07-01 00:41:4811152
jaydasikafbb9f43a2015-10-22 20:44:0811153 DrawFrame();
danakj74af409e2016-07-01 00:41:4811154
vollickcb3f6b12016-03-01 23:44:1011155 in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100);
jaydasikafbb9f43a2015-10-22 20:44:0811156 node = host_impl_->active_tree()->property_trees()->transform_tree.Node(
11157 in_subtree_of_page_scale_layer->transform_tree_index());
jaydasika6be761602016-07-18 20:11:4311158 EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f));
jaydasikafbb9f43a2015-10-22 20:44:0811159}
11160
jaydasikacb93d1c2015-12-09 23:52:4611161TEST_F(LayerTreeHostImplTest, JitterTest) {
11162 host_impl_->SetViewportSize(gfx::Size(100, 100));
11163
11164 host_impl_->CreatePendingTree();
11165 CreateScrollAndContentsLayers(host_impl_->pending_tree(),
11166 gfx::Size(100, 100));
danakj74af409e2016-07-01 00:41:4811167 host_impl_->pending_tree()->BuildPropertyTreesForTesting();
jaydasikacb93d1c2015-12-09 23:52:4611168
11169 host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
jaydasikacb93d1c2015-12-09 23:52:4611170 const int scroll = 5;
11171 int accumulated_scroll = 0;
11172 for (int i = 0; i < host_impl_->pending_tree()->kFixedPointHitsThreshold + 1;
11173 ++i) {
11174 host_impl_->ActivateSyncTree();
majidvp944a8cd2016-01-12 21:05:1811175 host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
dtapuska40e8aff2016-03-11 21:45:0311176 InputHandler::TOUCHSCREEN);
majidvp944a8cd2016-01-12 21:05:1811177 host_impl_->ScrollBy(
11178 UpdateState(gfx::Point(), gfx::Vector2dF(0, scroll)).get());
jaydasikacb93d1c2015-12-09 23:52:4611179 accumulated_scroll += scroll;
majidvp944a8cd2016-01-12 21:05:1811180 host_impl_->ScrollEnd(EndState().get());
jaydasikacb93d1c2015-12-09 23:52:4611181 host_impl_->active_tree()->UpdateDrawProperties(false);
11182
11183 host_impl_->CreatePendingTree();
11184 host_impl_->pending_tree()->set_source_frame_number(i + 1);
jaydasikafc66cfb2016-06-10 04:34:2211185 LayerImpl* content_layer = host_impl_->pending_tree()
11186 ->OuterViewportScrollLayer()
11187 ->test_properties()
11188 ->children[0];
jaydasikacb93d1c2015-12-09 23:52:4611189 // The scroll done on the active tree is undone on the pending tree.
11190 gfx::Transform translate;
11191 translate.Translate(0, accumulated_scroll);
jaydasika10d43fc2016-08-18 04:06:0411192 content_layer->test_properties()->transform = translate;
jaydasikacb93d1c2015-12-09 23:52:4611193
11194 LayerTreeImpl* pending_tree = host_impl_->pending_tree();
11195 pending_tree->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
vollickcb3f6b12016-03-01 23:44:1011196 LayerImpl* last_scrolled_layer = pending_tree->LayerById(
jaydasikacb93d1c2015-12-09 23:52:4611197 host_impl_->active_tree()->LastScrolledLayerId());
sunxdc36713a2016-03-03 22:31:1011198
11199 // When building property trees from impl side, the builder uses the scroll
11200 // offset of layer_impl to initialize the scroll offset in scroll tree:
11201 // scroll_tree.synced_scroll_offset.PushFromMainThread(
11202 // layer->CurrentScrollOffset()).
11203 // However, layer_impl does not store scroll_offset, so it is using scroll
11204 // tree's scroll offset to initialize itself. Usually this approach works
11205 // because this is a simple assignment. However if scroll_offset's pending
11206 // delta is not zero, the delta would be counted twice.
11207 // This hacking here is to restore the damaged scroll offset.
11208 gfx::ScrollOffset pending_base =
sunxdc044b11a2016-03-16 16:23:2011209 pending_tree->property_trees()
11210 ->scroll_tree.GetScrollOffsetBaseForTesting(
11211 last_scrolled_layer->id());
danakj74af409e2016-07-01 00:41:4811212 pending_tree->BuildPropertyTreesForTesting();
sunxdc044b11a2016-03-16 16:23:2011213 pending_tree->property_trees()
11214 ->scroll_tree.UpdateScrollOffsetBaseForTesting(
11215 last_scrolled_layer->id(), pending_base);
jaydasika69dc9412016-06-25 00:34:5711216 pending_tree->LayerById(content_layer->id())->SetNeedsPushProperties();
sunxdc36713a2016-03-03 22:31:1011217
11218 pending_tree->set_needs_update_draw_properties();
11219 pending_tree->UpdateDrawProperties(false);
jaydasikaeaa8d0852016-03-29 23:55:3911220 float jitter = LayerTreeHostCommon::CalculateLayerJitter(content_layer);
jaydasikacb93d1c2015-12-09 23:52:4611221 // There should not be any jitter measured till we hit the fixed point hits
11222 // threshold.
11223 float expected_jitter =
11224 (i == pending_tree->kFixedPointHitsThreshold) ? 500 : 0;
11225 EXPECT_EQ(jitter, expected_jitter);
11226 }
11227}
11228
ericrk563e1a0152016-05-02 18:54:0611229// Checks that if we lose a GPU raster enabled OutputSurface and replace it
11230// with a software OutputSurface, LayerTreeHostImpl correctly re-computes GPU
11231// rasterization status.
11232TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnOutputSurfaceChange) {
danakjee6547a22016-07-01 20:41:5011233 host_impl_->ReleaseOutputSurface();
11234 host_impl_ = nullptr;
11235
ericrk563e1a0152016-05-02 18:54:0611236 LayerTreeSettings settings = DefaultSettings();
11237 settings.gpu_rasterization_forced = true;
11238
11239 host_impl_ = LayerTreeHostImpl::Create(
11240 settings, this, &task_runner_provider_, &stats_instrumentation_,
11241 &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_,
loysoab32ee72016-06-08 03:33:1811242 AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0);
ericrk563e1a0152016-05-02 18:54:0611243 host_impl_->SetVisible(true);
11244
11245 // InitializeRenderer with a gpu-raster enabled output surface.
11246 auto gpu_raster_output_surface =
danakjf33ceec2016-07-20 20:04:4511247 FakeOutputSurface::CreateDelegating3d(TestWebGraphicsContext3D::Create());
ericrk563e1a0152016-05-02 18:54:0611248 host_impl_->InitializeRenderer(gpu_raster_output_surface.get());
11249 EXPECT_TRUE(host_impl_->use_gpu_rasterization());
11250
11251 // Re-initialize with a software output surface.
danakj6021ec32016-07-22 22:16:0811252 output_surface_ = FakeOutputSurface::CreateDelegatingSoftware();
ericrk563e1a0152016-05-02 18:54:0611253 host_impl_->InitializeRenderer(output_surface_.get());
11254 EXPECT_FALSE(host_impl_->use_gpu_rasterization());
11255}
11256
[email protected]ba565742012-11-10 09:29:4811257} // namespace
11258} // namespace cc