blob: e8bd22a15a9c66f74a08013f9a68a173d0ecda39 [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
[email protected]ac7c7f52012-11-08 06:26:507#include <cmath>
8
[email protected]59cb7b352012-10-30 06:45:489#include "base/bind.h"
[email protected]65bfd9972012-10-19 03:39:3710#include "base/command_line.h"
[email protected]14c1c232013-06-11 17:52:4411#include "base/containers/hash_tables.h"
[email protected]03c43ec2013-08-30 02:41:3212#include "base/containers/scoped_ptr_hash_map.h"
[email protected]bf1cfd9a2013-09-26 05:43:0213#include "cc/animation/scrollbar_animation_controller_thinning.h"
[email protected]681ccff2013-03-18 06:13:5214#include "cc/base/math_util.h"
[email protected]3052b10f2013-03-18 07:41:2115#include "cc/input/top_controls_manager.h"
[email protected]cc3cfaa2013-03-18 09:05:5216#include "cc/layers/delegated_renderer_layer_impl.h"
17#include "cc/layers/heads_up_display_layer_impl.h"
18#include "cc/layers/io_surface_layer_impl.h"
19#include "cc/layers/layer_impl.h"
[email protected]3a83478b2013-08-22 20:55:1720#include "cc/layers/painted_scrollbar_layer_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5221#include "cc/layers/quad_sink.h"
[email protected]50761e92013-03-29 20:51:2822#include "cc/layers/render_surface_impl.h"
[email protected]cc3cfaa2013-03-18 09:05:5223#include "cc/layers/solid_color_layer_impl.h"
24#include "cc/layers/texture_layer_impl.h"
25#include "cc/layers/tiled_layer_impl.h"
26#include "cc/layers/video_layer_impl.h"
[email protected]df3c24c92013-06-19 03:54:3527#include "cc/output/begin_frame_args.h"
[email protected]bb1e2822013-04-17 22:06:0128#include "cc/output/compositor_frame_ack.h"
[email protected]7f0d825f2013-03-18 07:24:3029#include "cc/output/compositor_frame_metadata.h"
[email protected]ea468c6c2013-09-10 08:25:1130#include "cc/output/copy_output_request.h"
31#include "cc/output/copy_output_result.h"
[email protected]7f0d825f2013-03-18 07:24:3032#include "cc/output/gl_renderer.h"
[email protected]89e82672013-03-18 07:50:5633#include "cc/quads/render_pass_draw_quad.h"
34#include "cc/quads/solid_color_draw_quad.h"
35#include "cc/quads/texture_draw_quad.h"
36#include "cc/quads/tile_draw_quad.h"
[email protected]6be50ba82013-11-08 12:04:1237#include "cc/resources/etc1_pixel_ref.h"
[email protected]e12dd0e2013-03-18 08:24:4038#include "cc/resources/layer_tiling_data.h"
[email protected]101441ce2012-10-16 01:45:0339#include "cc/test/animation_test_common.h"
[email protected]222c6782013-09-05 22:24:4940#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]a46f32932012-12-07 21:43:1641#include "cc/test/fake_output_surface.h"
[email protected]0634cdd42013-08-16 00:46:0942#include "cc/test/fake_output_surface_client.h"
[email protected]46b79d52013-09-07 04:29:2943#include "cc/test/fake_picture_layer_impl.h"
44#include "cc/test/fake_picture_pile_impl.h"
[email protected]61de5812012-11-08 07:03:4445#include "cc/test/fake_proxy.h"
[email protected]372bad5f2013-03-21 16:38:4346#include "cc/test/fake_rendering_stats_instrumentation.h"
[email protected]d993b602013-01-04 02:08:1247#include "cc/test/fake_video_frame_provider.h"
[email protected]101441ce2012-10-16 01:45:0348#include "cc/test/geometry_test_utils.h"
49#include "cc/test/layer_test_common.h"
50#include "cc/test/render_pass_test_common.h"
[email protected]c2610b9f2013-10-31 06:54:5951#include "cc/test/test_web_graphics_context_3d.h"
[email protected]556fd292013-03-18 08:03:0452#include "cc/trees/layer_tree_impl.h"
53#include "cc/trees/single_thread_proxy.h"
[email protected]59cb7b352012-10-30 06:45:4854#include "media/base/media.h"
[email protected]7f0c53db2012-10-02 00:23:1855#include "testing/gmock/include/gmock/gmock.h"
56#include "testing/gtest/include/gtest/gtest.h"
[email protected]de2cf8c2013-10-25 19:46:4657#include "ui/gfx/frame_time.h"
[email protected]46b79d52013-09-07 04:29:2958#include "ui/gfx/rect_conversions.h"
[email protected]aad0a0072012-11-01 18:15:5859#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1360#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1461
[email protected]94f206c12012-08-25 00:09:1462using ::testing::Mock;
63using ::testing::Return;
64using ::testing::AnyNumber;
65using ::testing::AtLeast;
66using ::testing::_;
[email protected]568285b2013-01-07 23:19:1967using media::VideoFrame;
[email protected]94f206c12012-08-25 00:09:1468
[email protected]ba565742012-11-10 09:29:4869namespace cc {
[email protected]94f206c12012-08-25 00:09:1470namespace {
71
[email protected]c2d0c5a2013-02-26 04:43:3672class LayerTreeHostImplTest : public testing::Test,
[email protected]9bdcfd642012-11-14 21:24:2673 public LayerTreeHostImplClient {
[email protected]aa043632013-03-25 03:39:4274 public:
75 LayerTreeHostImplTest()
[email protected]810d40b72013-06-20 18:26:1576 : proxy_(),
[email protected]aa043632013-03-25 03:39:4277 always_impl_thread_(&proxy_),
78 always_main_thread_blocked_(&proxy_),
79 on_can_draw_state_changed_called_(false),
[email protected]4f48f6e2013-08-27 06:33:3880 did_notify_ready_to_activate_(false),
[email protected]aa043632013-03-25 03:39:4281 did_request_commit_(false),
82 did_request_redraw_(false),
[email protected]c48536a52013-09-14 00:02:0883 did_request_manage_tiles_(false),
[email protected]aa043632013-03-25 03:39:4284 did_upload_visible_tile_(false),
[email protected]d9ca99e2013-08-28 21:49:4885 did_lose_output_surface_(false),
[email protected]fd32d122013-06-29 13:11:0486 reduce_memory_result_(true),
87 current_limit_bytes_(0),
88 current_priority_cutoff_value_(0) {
[email protected]aa043632013-03-25 03:39:4289 media::InitializeMediaLibraryForTesting();
90 }
[email protected]1c0c9bc2012-10-08 22:41:4891
[email protected]ce2e8112013-11-28 07:44:3692 LayerTreeSettings DefaultSettings() {
[email protected]96baf3e2012-10-22 23:09:5593 LayerTreeSettings settings;
[email protected]aa043632013-03-25 03:39:4294 settings.minimum_occlusion_tracking_size = gfx::Size();
[email protected]50644642013-06-20 13:58:5595 settings.impl_side_painting = true;
[email protected]b796c34f2013-11-01 11:52:3496 settings.texture_id_allocation_chunk_size = 1;
[email protected]ce2e8112013-11-28 07:44:3697 return settings;
98 }
[email protected]94f206c12012-08-25 00:09:1499
[email protected]ce2e8112013-11-28 07:44:36100 virtual void SetUp() OVERRIDE {
101 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
[email protected]aa043632013-03-25 03:39:42102 }
[email protected]94f206c12012-08-25 00:09:14103
[email protected]aa043632013-03-25 03:39:42104 virtual void TearDown() OVERRIDE {}
[email protected]94f206c12012-08-25 00:09:14105
[email protected]d9ca99e2013-08-28 21:49:48106 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {
107 did_lose_output_surface_ = true;
108 }
[email protected]4d7e46a2013-11-08 05:33:40109 virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42110 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
[email protected]daea3d42013-10-23 17:04:50111 virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42112 virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {
113 on_can_draw_state_changed_called_ = true;
114 }
[email protected]4f48f6e2013-08-27 06:33:38115 virtual void NotifyReadyToActivate() OVERRIDE {
116 did_notify_ready_to_activate_ = true;
117 host_impl_->ActivatePendingTree();
[email protected]aa043632013-03-25 03:39:42118 }
119 virtual void SetNeedsRedrawOnImplThread() OVERRIDE {
120 did_request_redraw_ = true;
121 }
[email protected]1cd9f5552013-04-26 04:22:03122 virtual void SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) OVERRIDE {
123 did_request_redraw_ = true;
124 }
[email protected]c48536a52013-09-14 00:02:08125 virtual void SetNeedsManageTilesOnImplThread() OVERRIDE {
126 did_request_manage_tiles_ = true;
127 }
[email protected]aa043632013-03-25 03:39:42128 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE {
129 did_upload_visible_tile_ = true;
130 }
131 virtual void SetNeedsCommitOnImplThread() OVERRIDE {
132 did_request_commit_ = true;
133 }
[email protected]aa043632013-03-25 03:39:42134 virtual void PostAnimationEventsToMainThreadOnImplThread(
135 scoped_ptr<AnimationEventsVector> events,
136 base::Time wall_clock_time) OVERRIDE {}
137 virtual bool ReduceContentsTextureMemoryOnImplThread(
138 size_t limit_bytes, int priority_cutoff) OVERRIDE {
[email protected]fd32d122013-06-29 13:11:04139 current_limit_bytes_ = limit_bytes;
140 current_priority_cutoff_value_ = priority_cutoff;
[email protected]aa043632013-03-25 03:39:42141 return reduce_memory_result_;
142 }
[email protected]aa043632013-03-25 03:39:42143 virtual void SendManagedMemoryStats() OVERRIDE {}
144 virtual bool IsInsideDraw() OVERRIDE { return false; }
145 virtual void RenewTreePriority() OVERRIDE {}
146 virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay)
[email protected]21c9dee72013-06-15 01:20:05147 OVERRIDE { requested_scrollbar_animation_delay_ = delay; }
[email protected]2a61ad52013-05-13 14:01:29148 virtual void DidActivatePendingTree() OVERRIDE {}
[email protected]bac0e552013-11-05 22:38:51149 virtual void DidManageTiles() OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42150
151 void set_reduce_memory_result(bool reduce_memory_result) {
152 reduce_memory_result_ = reduce_memory_result;
153 }
154
[email protected]ce2e8112013-11-28 07:44:36155 bool CreateHostImpl(const LayerTreeSettings& settings,
156 scoped_ptr<OutputSurface> output_surface) {
[email protected]a7f35682013-10-22 23:05:57157 host_impl_ = LayerTreeHostImpl::Create(
158 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]ce2e8112013-11-28 07:44:36159 bool init = host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:40160 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]ce2e8112013-11-28 07:44:36161 return init;
[email protected]aa043632013-03-25 03:39:42162 }
163
164 void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) {
165 root->SetAnchorPoint(gfx::PointF());
166 root->SetPosition(gfx::PointF());
167 root->SetBounds(gfx::Size(10, 10));
168 root->SetContentBounds(gfx::Size(10, 10));
169 root->SetDrawsContent(true);
170 root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
171 host_impl_->active_tree()->SetRootLayer(root.Pass());
172 }
173
174 static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) {
[email protected]1960a712013-04-30 17:06:47175 ASSERT_EQ(layer->ScrollDelta(), gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:42176 for (size_t i = 0; i < layer->children().size(); ++i)
177 ExpectClearedScrollDeltasRecursive(layer->children()[i]);
178 }
179
180 static void ExpectContains(const ScrollAndScaleSet& scroll_info,
181 int id,
182 gfx::Vector2d scroll_delta) {
183 int times_encountered = 0;
184
185 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
186 if (scroll_info.scrolls[i].layer_id != id)
187 continue;
188 EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta);
189 times_encountered++;
190 }
191
[email protected]df0c42342013-10-08 20:52:12192 ASSERT_EQ(1, times_encountered);
[email protected]aa043632013-03-25 03:39:42193 }
194
195 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
196 int times_encountered = 0;
197
198 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
199 if (scroll_info.scrolls[i].layer_id != id)
200 continue;
201 times_encountered++;
202 }
203
204 ASSERT_EQ(0, times_encountered);
205 }
206
[email protected]7d1b07e2013-10-01 17:31:30207 LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl,
208 gfx::Size content_size) {
[email protected]aa043632013-03-25 03:39:42209 scoped_ptr<LayerImpl> root =
[email protected]7d1b07e2013-10-01 17:31:30210 LayerImpl::Create(layer_tree_impl, 1);
[email protected]aa043632013-03-25 03:39:42211 root->SetBounds(content_size);
212 root->SetContentBounds(content_size);
213 root->SetPosition(gfx::PointF());
214 root->SetAnchorPoint(gfx::PointF());
215
[email protected]35a99a12013-05-09 23:52:29216 scoped_ptr<LayerImpl> scroll =
[email protected]7d1b07e2013-10-01 17:31:30217 LayerImpl::Create(layer_tree_impl, 2);
[email protected]35a99a12013-05-09 23:52:29218 LayerImpl* scroll_layer = scroll.get();
219 scroll->SetScrollable(true);
220 scroll->SetScrollOffset(gfx::Vector2d());
221 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
[email protected]a2b5ded2013-05-20 21:32:53222 content_size.height()));
[email protected]35a99a12013-05-09 23:52:29223 scroll->SetBounds(content_size);
224 scroll->SetContentBounds(content_size);
225 scroll->SetPosition(gfx::PointF());
226 scroll->SetAnchorPoint(gfx::PointF());
227
228 scoped_ptr<LayerImpl> contents =
[email protected]7d1b07e2013-10-01 17:31:30229 LayerImpl::Create(layer_tree_impl, 3);
[email protected]aa043632013-03-25 03:39:42230 contents->SetDrawsContent(true);
231 contents->SetBounds(content_size);
232 contents->SetContentBounds(content_size);
233 contents->SetPosition(gfx::PointF());
234 contents->SetAnchorPoint(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29235
236 scroll->AddChild(contents.Pass());
237 root->AddChild(scroll.Pass());
238
[email protected]7d1b07e2013-10-01 17:31:30239 layer_tree_impl->SetRootLayer(root.Pass());
240 return scroll_layer;
241 }
242
243 LayerImpl* SetupScrollAndContentsLayers(gfx::Size content_size) {
244 LayerImpl* scroll_layer = CreateScrollAndContentsLayers(
245 host_impl_->active_tree(), content_size);
[email protected]aa043632013-03-25 03:39:42246 host_impl_->active_tree()->DidBecomeActive();
[email protected]35a99a12013-05-09 23:52:29247 return scroll_layer;
[email protected]aa043632013-03-25 03:39:42248 }
249
250 scoped_ptr<LayerImpl> CreateScrollableLayer(int id, gfx::Size size) {
251 scoped_ptr<LayerImpl> layer =
252 LayerImpl::Create(host_impl_->active_tree(), id);
253 layer->SetScrollable(true);
254 layer->SetDrawsContent(true);
255 layer->SetBounds(size);
256 layer->SetContentBounds(size);
257 layer->SetMaxScrollOffset(gfx::Vector2d(size.width() * 2,
258 size.height() * 2));
259 return layer.Pass();
260 }
261
[email protected]fbe89f72013-05-21 07:24:24262 void DrawFrame() {
[email protected]aa043632013-03-25 03:39:42263 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:20264 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:46265 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:42266 host_impl_->DidDrawAllLayers(frame);
267 }
268
269 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor);
270 void pinch_zoom_pan_viewport_test(float device_scale_factor);
271 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor);
272 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
273 float device_scale_factor);
274
[email protected]6133cc232013-07-30 18:47:07275 void CheckNotifyCalledIfCanDrawChanged(bool always_draw) {
276 // Note: It is not possible to disable the renderer once it has been set,
277 // so we do not need to test that disabling the renderer notifies us
278 // that can_draw changed.
279 EXPECT_FALSE(host_impl_->CanDraw());
280 on_can_draw_state_changed_called_ = false;
281
282 // Set up the root layer, which allows us to draw.
283 SetupScrollAndContentsLayers(gfx::Size(100, 100));
284 EXPECT_TRUE(host_impl_->CanDraw());
285 EXPECT_TRUE(on_can_draw_state_changed_called_);
286 on_can_draw_state_changed_called_ = false;
287
288 // Toggle the root layer to make sure it toggles can_draw
289 host_impl_->active_tree()->SetRootLayer(scoped_ptr<LayerImpl>());
290 EXPECT_FALSE(host_impl_->CanDraw());
291 EXPECT_TRUE(on_can_draw_state_changed_called_);
292 on_can_draw_state_changed_called_ = false;
293
294 SetupScrollAndContentsLayers(gfx::Size(100, 100));
295 EXPECT_TRUE(host_impl_->CanDraw());
296 EXPECT_TRUE(on_can_draw_state_changed_called_);
297 on_can_draw_state_changed_called_ = false;
298
299 // Toggle the device viewport size to make sure it toggles can_draw.
300 host_impl_->SetViewportSize(gfx::Size());
301 if (always_draw) {
302 EXPECT_TRUE(host_impl_->CanDraw());
303 } else {
304 EXPECT_FALSE(host_impl_->CanDraw());
305 }
306 EXPECT_TRUE(on_can_draw_state_changed_called_);
307 on_can_draw_state_changed_called_ = false;
308
309 host_impl_->SetViewportSize(gfx::Size(100, 100));
310 EXPECT_TRUE(host_impl_->CanDraw());
311 EXPECT_TRUE(on_can_draw_state_changed_called_);
312 on_can_draw_state_changed_called_ = false;
313
314 // Toggle contents textures purged without causing any evictions,
315 // and make sure that it does not change can_draw.
316 set_reduce_memory_result(false);
317 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:07318 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]6133cc232013-07-30 18:47:07319 EXPECT_TRUE(host_impl_->CanDraw());
320 EXPECT_FALSE(on_can_draw_state_changed_called_);
321 on_can_draw_state_changed_called_ = false;
322
323 // Toggle contents textures purged to make sure it toggles can_draw.
324 set_reduce_memory_result(true);
325 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:07326 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]6133cc232013-07-30 18:47:07327 if (always_draw) {
328 EXPECT_TRUE(host_impl_->CanDraw());
329 } else {
330 EXPECT_FALSE(host_impl_->CanDraw());
331 }
332 EXPECT_TRUE(on_can_draw_state_changed_called_);
333 on_can_draw_state_changed_called_ = false;
334
335 host_impl_->active_tree()->ResetContentsTexturesPurged();
336 EXPECT_TRUE(host_impl_->CanDraw());
337 EXPECT_TRUE(on_can_draw_state_changed_called_);
338 on_can_draw_state_changed_called_ = false;
339 }
340
[email protected]bf1cfd9a2013-09-26 05:43:02341 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
342
[email protected]aa043632013-03-25 03:39:42343 protected:
344 virtual scoped_ptr<OutputSurface> CreateOutputSurface() {
345 return CreateFakeOutputSurface();
346 }
347
348 void DrawOneFrame() {
349 LayerTreeHostImpl::FrameData frame_data;
[email protected]e0341352013-04-06 05:01:20350 host_impl_->PrepareToDraw(&frame_data, gfx::Rect());
[email protected]aa043632013-03-25 03:39:42351 host_impl_->DidDrawAllLayers(frame_data);
352 }
353
354 FakeProxy proxy_;
355 DebugScopedSetImplThread always_impl_thread_;
356 DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
357
358 scoped_ptr<LayerTreeHostImpl> host_impl_;
359 FakeRenderingStatsInstrumentation stats_instrumentation_;
360 bool on_can_draw_state_changed_called_;
[email protected]4f48f6e2013-08-27 06:33:38361 bool did_notify_ready_to_activate_;
[email protected]aa043632013-03-25 03:39:42362 bool did_request_commit_;
363 bool did_request_redraw_;
[email protected]c48536a52013-09-14 00:02:08364 bool did_request_manage_tiles_;
[email protected]aa043632013-03-25 03:39:42365 bool did_upload_visible_tile_;
[email protected]d9ca99e2013-08-28 21:49:48366 bool did_lose_output_surface_;
[email protected]aa043632013-03-25 03:39:42367 bool reduce_memory_result_;
[email protected]21c9dee72013-06-15 01:20:05368 base::TimeDelta requested_scrollbar_animation_delay_;
[email protected]fd32d122013-06-29 13:11:04369 size_t current_limit_bytes_;
370 int current_priority_cutoff_value_;
[email protected]aa043632013-03-25 03:39:42371};
372
[email protected]6133cc232013-07-30 18:47:07373TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
374 bool always_draw = false;
375 CheckNotifyCalledIfCanDrawChanged(always_draw);
376}
377
378TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) {
[email protected]0634cdd42013-08-16 00:46:09379 scoped_ptr<FakeOutputSurface> output_surface(
380 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
[email protected]ce2e8112013-11-28 07:44:36381 CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>());
[email protected]6133cc232013-07-30 18:47:07382
383 bool always_draw = true;
384 CheckNotifyCalledIfCanDrawChanged(always_draw);
385}
386
[email protected]aa043632013-03-25 03:39:42387TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) {
388 ASSERT_FALSE(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:14389
[email protected]aa043632013-03-25 03:39:42390 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
391 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
[email protected]94f206c12012-08-25 00:09:14392}
393
[email protected]aa043632013-03-25 03:39:42394TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
395 {
396 scoped_ptr<LayerImpl> root =
397 LayerImpl::Create(host_impl_->active_tree(), 1);
398 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2));
399 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3));
400 root->children()[1]->AddChild(
401 LayerImpl::Create(host_impl_->active_tree(), 4));
402 root->children()[1]->AddChild(
403 LayerImpl::Create(host_impl_->active_tree(), 5));
404 root->children()[1]->children()[0]->AddChild(
405 LayerImpl::Create(host_impl_->active_tree(), 6));
406 host_impl_->active_tree()->SetRootLayer(root.Pass());
407 }
408 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:14409
[email protected]aa043632013-03-25 03:39:42410 ExpectClearedScrollDeltasRecursive(root);
[email protected]0ede3bb2012-12-09 09:14:39411
[email protected]aa043632013-03-25 03:39:42412 scoped_ptr<ScrollAndScaleSet> scroll_info;
413
414 scroll_info = host_impl_->ProcessScrollDeltas();
415 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
416 ExpectClearedScrollDeltasRecursive(root);
417
418 scroll_info = host_impl_->ProcessScrollDeltas();
419 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
420 ExpectClearedScrollDeltasRecursive(root);
[email protected]94f206c12012-08-25 00:09:14421}
422
[email protected]aa043632013-03-25 03:39:42423TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
424 gfx::Vector2d scroll_offset(20, 30);
425 gfx::Vector2d scroll_delta(11, -15);
426 {
427 scoped_ptr<LayerImpl> root =
428 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]d30700f12013-07-31 08:21:01429 root->SetMaxScrollOffset(gfx::Vector2d(100, 100));
[email protected]aa043632013-03-25 03:39:42430 root->SetScrollOffset(scroll_offset);
431 root->SetScrollable(true);
[email protected]aa043632013-03-25 03:39:42432 root->ScrollBy(scroll_delta);
433 host_impl_->active_tree()->SetRootLayer(root.Pass());
434 }
435 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:14436
[email protected]aa043632013-03-25 03:39:42437 scoped_ptr<ScrollAndScaleSet> scroll_info;
[email protected]94f206c12012-08-25 00:09:14438
[email protected]aa043632013-03-25 03:39:42439 scroll_info = host_impl_->ProcessScrollDeltas();
440 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
441 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta);
442 ExpectContains(*scroll_info, root->id(), scroll_delta);
[email protected]94f206c12012-08-25 00:09:14443
[email protected]aa043632013-03-25 03:39:42444 gfx::Vector2d scroll_delta2(-5, 27);
445 root->ScrollBy(scroll_delta2);
446 scroll_info = host_impl_->ProcessScrollDeltas();
447 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
448 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
449 ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2);
450
451 root->ScrollBy(gfx::Vector2d());
452 scroll_info = host_impl_->ProcessScrollDeltas();
453 EXPECT_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
[email protected]94f206c12012-08-25 00:09:14454}
455
[email protected]aa043632013-03-25 03:39:42456TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
457 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40458 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36459 DrawFrame();
[email protected]94f206c12012-08-25 00:09:14460
[email protected]5ff3c9782013-04-29 17:35:12461 EXPECT_EQ(InputHandler::ScrollStarted,
462 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42463 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
464 host_impl_->ScrollEnd();
465 EXPECT_TRUE(did_request_redraw_);
466 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:14467}
468
[email protected]aa043632013-03-25 03:39:42469TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
470 // We should not crash when trying to scroll an empty layer tree.
[email protected]5ff3c9782013-04-29 17:35:12471 EXPECT_EQ(InputHandler::ScrollIgnored,
472 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:14473}
474
[email protected]aa043632013-03-25 03:39:42475TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
[email protected]0634cdd42013-08-16 00:46:09476 scoped_ptr<TestWebGraphicsContext3D> context_owned =
477 TestWebGraphicsContext3D::Create();
478 context_owned->set_times_make_current_succeeds(0);
479
480 scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d(
481 context_owned.Pass()));
[email protected]94f206c12012-08-25 00:09:14482
[email protected]ce2e8112013-11-28 07:44:36483 // Initialization will fail.
484 EXPECT_FALSE(CreateHostImpl(DefaultSettings(),
485 output_surface.PassAs<OutputSurface>()));
[email protected]a90aa702012-11-07 04:48:24486
[email protected]aa043632013-03-25 03:39:42487 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:14488
[email protected]aa043632013-03-25 03:39:42489 // We should not crash when trying to scroll after the renderer initialization
490 // fails.
[email protected]5ff3c9782013-04-29 17:35:12491 EXPECT_EQ(InputHandler::ScrollIgnored,
492 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:14493}
494
[email protected]aa043632013-03-25 03:39:42495TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
[email protected]35a99a12013-05-09 23:52:29496 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40497 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36498 DrawFrame();
[email protected]a9710962012-11-14 20:11:02499
[email protected]aa043632013-03-25 03:39:42500 // We should not crash if the tree is replaced while we are scrolling.
[email protected]5ff3c9782013-04-29 17:35:12501 EXPECT_EQ(InputHandler::ScrollStarted,
502 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42503 host_impl_->active_tree()->DetachLayerTree();
504
[email protected]35a99a12013-05-09 23:52:29505 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42506
507 // We should still be scrolling, because the scrolled layer also exists in the
508 // new tree.
509 gfx::Vector2d scroll_delta(0, 10);
510 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
511 host_impl_->ScrollEnd();
512 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]35a99a12013-05-09 23:52:29513 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta);
[email protected]aa043632013-03-25 03:39:42514}
515
516TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndScroll) {
517 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40518 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36519 DrawFrame();
[email protected]aa043632013-03-25 03:39:42520
521 // We should be able to scroll even if the root layer loses its render surface
522 // after the most recent render.
523 host_impl_->active_tree()->root_layer()->ClearRenderSurface();
524 host_impl_->active_tree()->set_needs_update_draw_properties();
525
[email protected]5ff3c9782013-04-29 17:35:12526 EXPECT_EQ(InputHandler::ScrollStarted,
527 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42528}
529
530TEST_F(LayerTreeHostImplTest, WheelEventHandlers) {
531 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40532 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36533 DrawFrame();
[email protected]aa043632013-03-25 03:39:42534 LayerImpl* root = host_impl_->active_tree()->root_layer();
535
536 root->SetHaveWheelEventHandlers(true);
537
538 // With registered event handlers, wheel scrolls have to go to the main
539 // thread.
[email protected]5ff3c9782013-04-29 17:35:12540 EXPECT_EQ(InputHandler::ScrollOnMainThread,
541 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42542
543 // But gesture scrolls can still be handled.
[email protected]5ff3c9782013-04-29 17:35:12544 EXPECT_EQ(InputHandler::ScrollStarted,
545 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42546}
547
[email protected]7c45d8152013-04-23 18:27:21548TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) {
549 SetupScrollAndContentsLayers(gfx::Size(100, 100));
550 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36551 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21552
553 // Ignore the fling since no layer is being scrolled
[email protected]5ff3c9782013-04-29 17:35:12554 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21555 host_impl_->FlingScrollBegin());
556
557 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12558 EXPECT_EQ(InputHandler::ScrollStarted,
559 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]7c45d8152013-04-23 18:27:21560
561 // Now the fling should go ahead since we've started scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12562 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]7c45d8152013-04-23 18:27:21563 host_impl_->FlingScrollBegin());
564}
565
566TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) {
567 SetupScrollAndContentsLayers(gfx::Size(100, 100));
568 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36569 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21570
571 // Ignore the fling since no layer is being scrolled
[email protected]5ff3c9782013-04-29 17:35:12572 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21573 host_impl_->FlingScrollBegin());
574
575 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12576 EXPECT_EQ(InputHandler::ScrollStarted,
577 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]7c45d8152013-04-23 18:27:21578
579 // Now the fling should go ahead since we've started scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12580 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]7c45d8152013-04-23 18:27:21581 host_impl_->FlingScrollBegin());
582}
583
584TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) {
585 SetupScrollAndContentsLayers(gfx::Size(100, 100));
586 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36587 DrawFrame();
[email protected]7c45d8152013-04-23 18:27:21588 LayerImpl* root = host_impl_->active_tree()->root_layer();
589
590 root->SetShouldScrollOnMainThread(true);
591
592 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12593 EXPECT_EQ(InputHandler::ScrollOnMainThread,
594 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]7c45d8152013-04-23 18:27:21595
596 // The fling should be ignored since there's no layer being scrolled impl-side
[email protected]5ff3c9782013-04-29 17:35:12597 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21598 host_impl_->FlingScrollBegin());
599}
600
[email protected]aa043632013-03-25 03:39:42601TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
602 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40603 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36604 DrawFrame();
[email protected]aa043632013-03-25 03:39:42605 LayerImpl* root = host_impl_->active_tree()->root_layer();
606
607 root->SetShouldScrollOnMainThread(true);
608
[email protected]5ff3c9782013-04-29 17:35:12609 EXPECT_EQ(InputHandler::ScrollOnMainThread,
610 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
611 EXPECT_EQ(InputHandler::ScrollOnMainThread,
612 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42613}
614
615TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
616 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40617 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42618
619 LayerImpl* root = host_impl_->active_tree()->root_layer();
620 root->SetContentsScale(2.f, 2.f);
621 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
622
[email protected]ce2e8112013-11-28 07:44:36623 DrawFrame();
[email protected]aa043632013-03-25 03:39:42624
625 // All scroll types inside the non-fast scrollable region should fail.
[email protected]5ff3c9782013-04-29 17:35:12626 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42627 host_impl_->ScrollBegin(gfx::Point(25, 25),
[email protected]5ff3c9782013-04-29 17:35:12628 InputHandler::Wheel));
629 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42630 host_impl_->ScrollBegin(gfx::Point(25, 25),
[email protected]5ff3c9782013-04-29 17:35:12631 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42632
633 // All scroll types outside this region should succeed.
[email protected]5ff3c9782013-04-29 17:35:12634 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42635 host_impl_->ScrollBegin(gfx::Point(75, 75),
[email protected]5ff3c9782013-04-29 17:35:12636 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42637 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
638 host_impl_->ScrollEnd();
[email protected]5ff3c9782013-04-29 17:35:12639 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42640 host_impl_->ScrollBegin(gfx::Point(75, 75),
[email protected]5ff3c9782013-04-29 17:35:12641 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42642 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
643 host_impl_->ScrollEnd();
644}
645
646TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
647 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40648 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42649
650 LayerImpl* root = host_impl_->active_tree()->root_layer();
651 root->SetContentsScale(2.f, 2.f);
652 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
653 root->SetPosition(gfx::PointF(-25.f, 0.f));
654
[email protected]ce2e8112013-11-28 07:44:36655 DrawFrame();
[email protected]aa043632013-03-25 03:39:42656
657 // This point would fall into the non-fast scrollable region except that we've
658 // moved the layer down by 25 pixels.
[email protected]5ff3c9782013-04-29 17:35:12659 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42660 host_impl_->ScrollBegin(gfx::Point(40, 10),
[email protected]5ff3c9782013-04-29 17:35:12661 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42662 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
663 host_impl_->ScrollEnd();
664
665 // This point is still inside the non-fast region.
[email protected]5ff3c9782013-04-29 17:35:12666 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42667 host_impl_->ScrollBegin(gfx::Point(10, 10),
[email protected]5ff3c9782013-04-29 17:35:12668 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42669}
670
671TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
672 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40673 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42674
[email protected]ce2e8112013-11-28 07:44:36675 DrawFrame();
[email protected]aa043632013-03-25 03:39:42676
[email protected]5ff3c9782013-04-29 17:35:12677 EXPECT_EQ(InputHandler::ScrollStarted,
678 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42679
680 // Trying to scroll to the left/top will not succeed.
681 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
682 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
683 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
684
685 // Scrolling to the right/bottom will succeed.
686 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
687 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
688 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
689
690 // Scrolling to left/top will now succeed.
691 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
692 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
693 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
694
695 // Scrolling diagonally against an edge will succeed.
696 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
697 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
698 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
699
700 // Trying to scroll more than the available space will also succeed.
701 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
702}
703
704TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) {
705 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
[email protected]18ce59702013-04-09 04:58:40706 host_impl_->SetViewportSize(gfx::Size(100, 1000));
[email protected]aa043632013-03-25 03:39:42707
[email protected]ce2e8112013-11-28 07:44:36708 DrawFrame();
[email protected]aa043632013-03-25 03:39:42709
[email protected]5ff3c9782013-04-29 17:35:12710 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42711 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:12712 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42713
714 // Trying to scroll without a vertical scrollbar will fail.
715 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49716 gfx::Point(), SCROLL_FORWARD));
[email protected]aa043632013-03-25 03:39:42717 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49718 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:42719
[email protected]3a83478b2013-08-22 20:55:17720 scoped_ptr<cc::PaintedScrollbarLayerImpl> vertical_scrollbar(
721 cc::PaintedScrollbarLayerImpl::Create(
[email protected]aa043632013-03-25 03:39:42722 host_impl_->active_tree(),
723 20,
[email protected]c28df4c12013-05-22 17:36:49724 VERTICAL));
[email protected]aa043632013-03-25 03:39:42725 vertical_scrollbar->SetBounds(gfx::Size(15, 1000));
726 host_impl_->RootScrollLayer()->SetVerticalScrollbarLayer(
727 vertical_scrollbar.get());
728
729 // Trying to scroll with a vertical scrollbar will succeed.
730 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49731 gfx::Point(), SCROLL_FORWARD));
[email protected]1960a712013-04-30 17:06:47732 EXPECT_FLOAT_EQ(875.f, host_impl_->RootScrollLayer()->ScrollDelta().y());
[email protected]aa043632013-03-25 03:39:42733 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49734 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:42735}
736
[email protected]59a7d552013-10-22 03:36:43737TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
738 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
739 host_impl_->SetViewportSize(gfx::Size(100, 100));
740
741 gfx::Size overflow_size(400, 400);
742 ASSERT_EQ(1u, scroll_layer->children().size());
743 LayerImpl* overflow = scroll_layer->children()[0];
744 overflow->SetBounds(overflow_size);
745 overflow->SetContentBounds(overflow_size);
746 overflow->SetScrollable(true);
747 overflow->SetMaxScrollOffset(gfx::Vector2d(overflow_size.width(),
748 overflow_size.height()));
749 overflow->SetScrollOffset(gfx::Vector2d());
750 overflow->SetPosition(gfx::PointF());
751 overflow->SetAnchorPoint(gfx::PointF());
752
[email protected]ce2e8112013-11-28 07:44:36753 DrawFrame();
[email protected]59a7d552013-10-22 03:36:43754 gfx::Point scroll_position(10, 10);
755
756 EXPECT_EQ(InputHandler::ScrollStarted,
757 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
758 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
759 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->TotalScrollOffset());
760
761 gfx::Vector2dF scroll_delta(10, 10);
762 host_impl_->ScrollBy(scroll_position, scroll_delta);
763 host_impl_->ScrollEnd();
764 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
765 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset());
766
767 overflow->set_user_scrollable_horizontal(false);
768
769 EXPECT_EQ(InputHandler::ScrollStarted,
770 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
771 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
772 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset());
773
774 host_impl_->ScrollBy(scroll_position, scroll_delta);
775 host_impl_->ScrollEnd();
776 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset());
777 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
778
779 overflow->set_user_scrollable_vertical(false);
780
781 EXPECT_EQ(InputHandler::ScrollStarted,
782 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
783 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset());
784 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
785
786 host_impl_->ScrollBy(scroll_position, scroll_delta);
787 host_impl_->ScrollEnd();
788 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer->TotalScrollOffset());
789 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
790}
791
[email protected]aa043632013-03-25 03:39:42792TEST_F(LayerTreeHostImplTest,
793 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) {
794 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40795 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36796 DrawFrame();
[email protected]aa043632013-03-25 03:39:42797
798 // We should be able to hit test for touch event handlers even if the root
799 // layer loses its render surface after the most recent render.
800 host_impl_->active_tree()->root_layer()->ClearRenderSurface();
801 host_impl_->active_tree()->set_needs_update_draw_properties();
802
803 EXPECT_EQ(host_impl_->HaveTouchEventHandlersAt(gfx::Point()), false);
804}
805
806TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
[email protected]35a99a12013-05-09 23:52:29807 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40808 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36809 DrawFrame();
[email protected]aa043632013-03-25 03:39:42810
[email protected]35a99a12013-05-09 23:52:29811 EXPECT_EQ(scroll_layer, host_impl_->RootScrollLayer());
[email protected]aa043632013-03-25 03:39:42812
813 float min_page_scale = 1.f, max_page_scale = 4.f;
[email protected]aa043632013-03-25 03:39:42814
815 // The impl-based pinch zoom should adjust the max scroll position.
816 {
817 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
818 min_page_scale,
819 max_page_scale);
820 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]aa043632013-03-25 03:39:42821 scroll_layer->SetScrollDelta(gfx::Vector2d());
822
823 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57824 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42825 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
826 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57827 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42828 EXPECT_TRUE(did_request_redraw_);
829 EXPECT_TRUE(did_request_commit_);
830
831 scoped_ptr<ScrollAndScaleSet> scroll_info =
832 host_impl_->ProcessScrollDeltas();
833 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
834
[email protected]35a99a12013-05-09 23:52:29835 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(),
836 scroll_layer->max_scroll_offset().ToString());
[email protected]aa043632013-03-25 03:39:42837 }
838
839 // Scrolling after a pinch gesture should always be in local space. The
840 // scroll deltas do not have the page scale factor applied.
841 {
842 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
843 min_page_scale,
844 max_page_scale);
845 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]aa043632013-03-25 03:39:42846 scroll_layer->SetScrollDelta(gfx::Vector2d());
847
848 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57849 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42850 host_impl_->PinchGestureBegin();
851 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
852 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57853 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42854
855 gfx::Vector2d scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:12856 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42857 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:12858 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42859 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
860 host_impl_->ScrollEnd();
[email protected]a9710962012-11-14 20:11:02861
[email protected]aa043632013-03-25 03:39:42862 scoped_ptr<ScrollAndScaleSet> scroll_info =
863 host_impl_->ProcessScrollDeltas();
864 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:29865 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:42866 scroll_delta);
867 }
[email protected]a9710962012-11-14 20:11:02868}
869
[email protected]aa043632013-03-25 03:39:42870TEST_F(LayerTreeHostImplTest, PinchGesture) {
871 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40872 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:36873 DrawFrame();
[email protected]be782f52013-03-23 21:36:14874
[email protected]aa043632013-03-25 03:39:42875 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
876 DCHECK(scroll_layer);
[email protected]be782f52013-03-23 21:36:14877
[email protected]aa043632013-03-25 03:39:42878 float min_page_scale = 1.f;
879 float max_page_scale = 4.f;
[email protected]be782f52013-03-23 21:36:14880
[email protected]aa043632013-03-25 03:39:42881 // Basic pinch zoom in gesture
882 {
883 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
884 min_page_scale,
885 max_page_scale);
[email protected]aa043632013-03-25 03:39:42886 scroll_layer->SetScrollDelta(gfx::Vector2d());
[email protected]be782f52013-03-23 21:36:14887
[email protected]aa043632013-03-25 03:39:42888 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57889 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42890 host_impl_->PinchGestureBegin();
891 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
892 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57893 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42894 EXPECT_TRUE(did_request_redraw_);
895 EXPECT_TRUE(did_request_commit_);
[email protected]be782f52013-03-23 21:36:14896
[email protected]aa043632013-03-25 03:39:42897 scoped_ptr<ScrollAndScaleSet> scroll_info =
898 host_impl_->ProcessScrollDeltas();
899 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
900 }
901
902 // Zoom-in clamping
903 {
904 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
905 min_page_scale,
906 max_page_scale);
[email protected]aa043632013-03-25 03:39:42907 scroll_layer->SetScrollDelta(gfx::Vector2d());
908 float page_scale_delta = 10.f;
909
[email protected]9ec24df2013-08-09 23:32:57910 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42911 host_impl_->PinchGestureBegin();
912 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
913 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57914 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42915
916 scoped_ptr<ScrollAndScaleSet> scroll_info =
917 host_impl_->ProcessScrollDeltas();
918 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale);
919 }
920
921 // Zoom-out clamping
922 {
923 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
924 min_page_scale,
925 max_page_scale);
[email protected]aa043632013-03-25 03:39:42926 scroll_layer->SetScrollDelta(gfx::Vector2d());
927 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
928
929 float page_scale_delta = 0.1f;
[email protected]9ec24df2013-08-09 23:32:57930 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42931 host_impl_->PinchGestureBegin();
932 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
933 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57934 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42935
936 scoped_ptr<ScrollAndScaleSet> scroll_info =
937 host_impl_->ProcessScrollDeltas();
938 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
939
940 EXPECT_TRUE(scroll_info->scrolls.empty());
941 }
942
943 // Two-finger panning should not happen based on pinch events only
944 {
945 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
946 min_page_scale,
947 max_page_scale);
[email protected]aa043632013-03-25 03:39:42948 scroll_layer->SetScrollDelta(gfx::Vector2d());
949 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20));
950
951 float page_scale_delta = 1.f;
[email protected]9ec24df2013-08-09 23:32:57952 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42953 host_impl_->PinchGestureBegin();
954 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
955 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
956 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57957 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42958
959 scoped_ptr<ScrollAndScaleSet> scroll_info =
960 host_impl_->ProcessScrollDeltas();
961 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
962 EXPECT_TRUE(scroll_info->scrolls.empty());
963 }
964
965 // Two-finger panning should work with interleaved scroll events
966 {
967 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
968 min_page_scale,
969 max_page_scale);
[email protected]aa043632013-03-25 03:39:42970 scroll_layer->SetScrollDelta(gfx::Vector2d());
971 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20));
972
973 float page_scale_delta = 1.f;
[email protected]9ec24df2013-08-09 23:32:57974 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42975 host_impl_->PinchGestureBegin();
976 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
977 host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
978 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
979 host_impl_->PinchGestureEnd();
980 host_impl_->ScrollEnd();
981
982 scoped_ptr<ScrollAndScaleSet> scroll_info =
983 host_impl_->ProcessScrollDeltas();
984 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
985 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10));
986 }
[email protected]9ec24df2013-08-09 23:32:57987
988 // Two-finger panning should work when starting fully zoomed out.
989 {
990 host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f,
991 0.5f,
992 4.f);
993 scroll_layer->SetScrollDelta(gfx::Vector2d());
994 scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0));
995 host_impl_->active_tree()->UpdateMaxScrollOffset();
996
997 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture);
998 host_impl_->PinchGestureBegin();
999 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
1000 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
1001 host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1002 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
1003 host_impl_->PinchGestureEnd();
1004 host_impl_->ScrollEnd();
1005
1006 scoped_ptr<ScrollAndScaleSet> scroll_info =
1007 host_impl_->ProcessScrollDeltas();
1008 EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
1009 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20));
1010 }
[email protected]be782f52013-03-23 21:36:141011}
1012
[email protected]aa043632013-03-25 03:39:421013TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
1014 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401015 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:361016 DrawFrame();
[email protected]df8f44f2013-01-08 08:00:311017
[email protected]aa043632013-03-25 03:39:421018 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
1019 DCHECK(scroll_layer);
[email protected]df8f44f2013-01-08 08:00:311020
[email protected]aa043632013-03-25 03:39:421021 float min_page_scale = 0.5f;
1022 float max_page_scale = 4.f;
1023 base::TimeTicks start_time = base::TimeTicks() +
1024 base::TimeDelta::FromSeconds(1);
1025 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1026 base::TimeTicks halfway_through_animation = start_time + duration / 2;
1027 base::TimeTicks end_time = start_time + duration;
[email protected]aa043632013-03-25 03:39:421028
1029 // Non-anchor zoom-in
1030 {
1031 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1032 min_page_scale,
1033 max_page_scale);
[email protected]aa043632013-03-25 03:39:421034 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
1035
[email protected]34e1b512013-09-26 17:32:331036 host_impl_->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f, duration);
1037 did_request_redraw_ = false;
1038 host_impl_->Animate(start_time, base::Time());
1039 EXPECT_TRUE(did_request_redraw_);
1040
1041 did_request_redraw_ = false;
[email protected]aa043632013-03-25 03:39:421042 host_impl_->Animate(halfway_through_animation, base::Time());
1043 EXPECT_TRUE(did_request_redraw_);
[email protected]34e1b512013-09-26 17:32:331044
1045 did_request_redraw_ = false;
1046 did_request_commit_ = false;
[email protected]aa043632013-03-25 03:39:421047 host_impl_->Animate(end_time, base::Time());
1048 EXPECT_TRUE(did_request_commit_);
1049
1050 scoped_ptr<ScrollAndScaleSet> scroll_info =
1051 host_impl_->ProcessScrollDeltas();
1052 EXPECT_EQ(scroll_info->page_scale_delta, 2);
1053 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1054 }
1055
1056 // Anchor zoom-out
1057 {
1058 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1059 min_page_scale,
1060 max_page_scale);
[email protected]aa043632013-03-25 03:39:421061 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
1062
[email protected]34e1b512013-09-26 17:32:331063 host_impl_->StartPageScaleAnimation(
1064 gfx::Vector2d(25, 25), true, min_page_scale, duration);
1065 did_request_redraw_ = false;
1066 host_impl_->Animate(start_time, base::Time());
1067 EXPECT_TRUE(did_request_redraw_);
1068
1069 did_request_redraw_ = false;
1070 did_request_commit_ = false;
[email protected]aa043632013-03-25 03:39:421071 host_impl_->Animate(end_time, base::Time());
1072 EXPECT_TRUE(did_request_redraw_);
1073 EXPECT_TRUE(did_request_commit_);
1074
1075 scoped_ptr<ScrollAndScaleSet> scroll_info =
1076 host_impl_->ProcessScrollDeltas();
1077 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
1078 // Pushed to (0,0) via clamping against contents layer size.
1079 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1080 }
[email protected]df8f44f2013-01-08 08:00:311081}
1082
[email protected]aa043632013-03-25 03:39:421083TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
1084 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401085 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]ce2e8112013-11-28 07:44:361086 DrawFrame();
[email protected]1c0c9bc2012-10-08 22:41:481087
[email protected]aa043632013-03-25 03:39:421088 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
1089 DCHECK(scroll_layer);
[email protected]1c0c9bc2012-10-08 22:41:481090
[email protected]aa043632013-03-25 03:39:421091 float min_page_scale = 0.5f;
1092 float max_page_scale = 4.f;
1093 base::TimeTicks start_time = base::TimeTicks() +
1094 base::TimeDelta::FromSeconds(1);
1095 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1096 base::TimeTicks halfway_through_animation = start_time + duration / 2;
1097 base::TimeTicks end_time = start_time + duration;
[email protected]1c0c9bc2012-10-08 22:41:481098
[email protected]aa043632013-03-25 03:39:421099 // Anchor zoom with unchanged page scale should not change scroll or scale.
1100 {
1101 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1102 min_page_scale,
1103 max_page_scale);
[email protected]aa043632013-03-25 03:39:421104 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
[email protected]c60279472013-01-30 12:10:511105
[email protected]34e1b512013-09-26 17:32:331106 host_impl_->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f, duration);
1107 host_impl_->Animate(start_time, base::Time());
[email protected]aa043632013-03-25 03:39:421108 host_impl_->Animate(halfway_through_animation, base::Time());
1109 EXPECT_TRUE(did_request_redraw_);
1110 host_impl_->Animate(end_time, base::Time());
1111 EXPECT_TRUE(did_request_commit_);
[email protected]c60279472013-01-30 12:10:511112
[email protected]aa043632013-03-25 03:39:421113 scoped_ptr<ScrollAndScaleSet> scroll_info =
1114 host_impl_->ProcessScrollDeltas();
1115 EXPECT_EQ(scroll_info->page_scale_delta, 1);
1116 ExpectNone(*scroll_info, scroll_layer->id());
1117 }
[email protected]1c0c9bc2012-10-08 22:41:481118}
1119
[email protected]21c9dee72013-06-15 01:20:051120class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
1121 public:
1122 LayerTreeHostImplOverridePhysicalTime(
1123 const LayerTreeSettings& settings,
1124 LayerTreeHostImplClient* client,
1125 Proxy* proxy,
1126 RenderingStatsInstrumentation* rendering_stats_instrumentation)
1127 : LayerTreeHostImpl(settings,
1128 client,
1129 proxy,
[email protected]a7f35682013-10-22 23:05:571130 rendering_stats_instrumentation,
1131 NULL) {}
[email protected]21c9dee72013-06-15 01:20:051132
1133 virtual base::TimeTicks CurrentPhysicalTimeTicks() const OVERRIDE {
1134 return fake_current_physical_time_;
1135 }
1136
1137 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) {
1138 fake_current_physical_time_ = fake_now;
1139 }
1140
1141 private:
1142 base::TimeTicks fake_current_physical_time_;
1143};
1144
1145TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
1146 LayerTreeSettings settings;
[email protected]fea161872013-08-27 22:34:591147 settings.scrollbar_animator = LayerTreeSettings::LinearFade;
[email protected]21c9dee72013-06-15 01:20:051148 settings.scrollbar_linear_fade_delay_ms = 20;
1149 settings.scrollbar_linear_fade_length_ms = 20;
1150
[email protected]4f0f43a2013-07-31 17:44:441151 gfx::Size viewport_size(10, 10);
1152 gfx::Size content_size(100, 100);
1153
[email protected]21c9dee72013-06-15 01:20:051154 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =
1155 new LayerTreeHostImplOverridePhysicalTime(
1156 settings, this, &proxy_, &stats_instrumentation_);
[email protected]ce2e8112013-11-28 07:44:361157 host_impl_ = make_scoped_ptr(host_impl_override_time);
[email protected]21c9dee72013-06-15 01:20:051158 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]4f0f43a2013-07-31 17:44:441159 host_impl_->SetViewportSize(viewport_size);
[email protected]21c9dee72013-06-15 01:20:051160
[email protected]21c9dee72013-06-15 01:20:051161 scoped_ptr<LayerImpl> root =
1162 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]4f0f43a2013-07-31 17:44:441163 root->SetBounds(viewport_size);
[email protected]21c9dee72013-06-15 01:20:051164
1165 scoped_ptr<LayerImpl> scroll =
1166 LayerImpl::Create(host_impl_->active_tree(), 2);
1167 scroll->SetScrollable(true);
1168 scroll->SetScrollOffset(gfx::Vector2d());
1169 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
1170 content_size.height()));
1171 scroll->SetBounds(content_size);
1172 scroll->SetContentBounds(content_size);
1173
1174 scoped_ptr<LayerImpl> contents =
1175 LayerImpl::Create(host_impl_->active_tree(), 3);
1176 contents->SetDrawsContent(true);
1177 contents->SetBounds(content_size);
1178 contents->SetContentBounds(content_size);
1179
[email protected]3a83478b2013-08-22 20:55:171180 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
1181 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 4, VERTICAL);
[email protected]21c9dee72013-06-15 01:20:051182 scroll->SetVerticalScrollbarLayer(scrollbar.get());
1183
1184 scroll->AddChild(contents.Pass());
1185 root->AddChild(scroll.Pass());
1186 root->AddChild(scrollbar.PassAs<LayerImpl>());
1187
1188 host_impl_->active_tree()->SetRootLayer(root.Pass());
1189 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:361190 DrawFrame();
[email protected]21c9dee72013-06-15 01:20:051191
[email protected]de2cf8c2013-10-25 19:46:461192 base::TimeTicks fake_now = gfx::FrameTime::Now();
[email protected]21c9dee72013-06-15 01:20:051193 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1194
1195 // If no scroll happened recently, StartScrollbarAnimation should have no
1196 // effect.
1197 host_impl_->StartScrollbarAnimation();
1198 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1199 EXPECT_FALSE(did_request_redraw_);
1200
[email protected]cdc07002013-09-06 22:33:461201 // If no scroll happened during a scroll gesture, StartScrollbarAnimation
1202 // should have no effect.
[email protected]21c9dee72013-06-15 01:20:051203 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1204 host_impl_->ScrollEnd();
1205 host_impl_->StartScrollbarAnimation();
[email protected]cdc07002013-09-06 22:33:461206 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1207 EXPECT_FALSE(did_request_redraw_);
1208
1209 // After a scroll, a fade animation should be scheduled about 20ms from now.
1210 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1211 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1212 host_impl_->ScrollEnd();
1213 did_request_redraw_ = false;
1214 host_impl_->StartScrollbarAnimation();
[email protected]21c9dee72013-06-15 01:20:051215 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1216 requested_scrollbar_animation_delay_);
1217 EXPECT_FALSE(did_request_redraw_);
1218 requested_scrollbar_animation_delay_ = base::TimeDelta();
1219
1220 // After the fade begins, we should start getting redraws instead of a
1221 // scheduled animation.
1222 fake_now += base::TimeDelta::FromMilliseconds(25);
1223 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1224 host_impl_->StartScrollbarAnimation();
1225 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1226 EXPECT_TRUE(did_request_redraw_);
1227 did_request_redraw_ = false;
1228
1229 // If no scroll happened recently, StartScrollbarAnimation should have no
1230 // effect.
1231 fake_now += base::TimeDelta::FromMilliseconds(25);
1232 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1233 host_impl_->StartScrollbarAnimation();
1234 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1235 EXPECT_FALSE(did_request_redraw_);
1236
1237 // Setting the scroll offset outside a scroll should also cause the scrollbar
1238 // to appear and to schedule a fade.
1239 host_impl_->RootScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
1240 host_impl_->StartScrollbarAnimation();
1241 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1242 requested_scrollbar_animation_delay_);
1243 EXPECT_FALSE(did_request_redraw_);
1244 requested_scrollbar_animation_delay_ = base::TimeDelta();
1245
1246 // None of the above should have called CurrentFrameTimeTicks, so if we call
1247 // it now we should get the current time.
1248 fake_now += base::TimeDelta::FromMilliseconds(10);
1249 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1250 EXPECT_EQ(fake_now, host_impl_->CurrentFrameTimeTicks());
1251}
1252
[email protected]bf1cfd9a2013-09-26 05:43:021253void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1254 float device_scale_factor) {
1255 LayerTreeSettings settings;
1256 settings.scrollbar_animator = LayerTreeSettings::Thinning;
1257
1258 gfx::Size viewport_size(300, 200);
1259 gfx::Size device_viewport_size = gfx::ToFlooredSize(
1260 gfx::ScaleSize(viewport_size, device_scale_factor));
1261 gfx::Size content_size(1000, 1000);
1262
[email protected]ce2e8112013-11-28 07:44:361263 CreateHostImpl(settings, CreateOutputSurface());
[email protected]bf1cfd9a2013-09-26 05:43:021264 host_impl_->SetDeviceScaleFactor(device_scale_factor);
1265 host_impl_->SetViewportSize(device_viewport_size);
1266
1267 scoped_ptr<LayerImpl> root =
1268 LayerImpl::Create(host_impl_->active_tree(), 1);
1269 root->SetBounds(viewport_size);
1270
1271 scoped_ptr<LayerImpl> scroll =
1272 LayerImpl::Create(host_impl_->active_tree(), 2);
1273 scroll->SetScrollable(true);
1274 scroll->SetScrollOffset(gfx::Vector2d());
1275 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
1276 content_size.height()));
1277 scroll->SetBounds(content_size);
1278 scroll->SetContentBounds(content_size);
1279
1280 scoped_ptr<LayerImpl> contents =
1281 LayerImpl::Create(host_impl_->active_tree(), 3);
1282 contents->SetDrawsContent(true);
1283 contents->SetBounds(content_size);
1284 contents->SetContentBounds(content_size);
1285
1286 // The scrollbar is on the right side.
1287 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
1288 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL);
[email protected]f620b0e72013-10-01 21:38:241289 scrollbar->SetDrawsContent(true);
1290 scrollbar->SetBounds(gfx::Size(15, viewport_size.height()));
[email protected]bf1cfd9a2013-09-26 05:43:021291 scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height()));
1292 scrollbar->SetPosition(gfx::Point(285, 0));
1293 scroll->SetVerticalScrollbarLayer(scrollbar.get());
1294
1295 scroll->AddChild(contents.Pass());
1296 root->AddChild(scroll.Pass());
1297 root->AddChild(scrollbar.PassAs<LayerImpl>());
1298
1299 host_impl_->active_tree()->SetRootLayer(root.Pass());
1300 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:361301 DrawFrame();
[email protected]bf1cfd9a2013-09-26 05:43:021302
1303 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1304 ASSERT_TRUE(root_scroll->scrollbar_animation_controller());
1305 ScrollbarAnimationControllerThinning* scrollbar_animation_controller =
1306 static_cast<ScrollbarAnimationControllerThinning*>(
1307 root_scroll->scrollbar_animation_controller());
1308 scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
1309
1310 host_impl_->MouseMoveAt(gfx::Point(1, 1));
[email protected]534236b2013-10-25 21:19:201311 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021312
[email protected]bf1cfd9a2013-09-26 05:43:021313 host_impl_->MouseMoveAt(gfx::Point(200, 50));
[email protected]534236b2013-10-25 21:19:201314 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021315
[email protected]bf1cfd9a2013-09-26 05:43:021316 host_impl_->MouseMoveAt(gfx::Point(184, 100));
[email protected]534236b2013-10-25 21:19:201317 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021318
1319 scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
[email protected]bf1cfd9a2013-09-26 05:43:021320 host_impl_->MouseMoveAt(gfx::Point(184, 100));
[email protected]534236b2013-10-25 21:19:201321 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]f620b0e72013-10-01 21:38:241322
1323 did_request_redraw_ = false;
1324 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1325 host_impl_->MouseMoveAt(gfx::Point(290, 100));
1326 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1327 host_impl_->MouseMoveAt(gfx::Point(290, 120));
1328 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1329 host_impl_->MouseMoveAt(gfx::Point(150, 120));
1330 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021331}
1332
1333TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
1334 SetupMouseMoveAtWithDeviceScale(1.f);
1335}
1336
1337TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
1338 SetupMouseMoveAtWithDeviceScale(2.f);
1339}
1340
[email protected]aa043632013-03-25 03:39:421341TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
1342 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401343 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:421344 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:361345 DrawFrame();
[email protected]aa043632013-03-25 03:39:421346 {
1347 CompositorFrameMetadata metadata =
1348 host_impl_->MakeCompositorFrameMetadata();
1349 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
1350 EXPECT_EQ(1.f, metadata.page_scale_factor);
1351 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.viewport_size);
1352 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1353 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1354 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1355 }
[email protected]94f206c12012-08-25 00:09:141356
[email protected]aa043632013-03-25 03:39:421357 // Scrolling should update metadata immediately.
[email protected]5ff3c9782013-04-29 17:35:121358 EXPECT_EQ(InputHandler::ScrollStarted,
1359 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421360 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1361 {
1362 CompositorFrameMetadata metadata =
1363 host_impl_->MakeCompositorFrameMetadata();
1364 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1365 }
1366 host_impl_->ScrollEnd();
1367 {
1368 CompositorFrameMetadata metadata =
1369 host_impl_->MakeCompositorFrameMetadata();
1370 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1371 }
[email protected]94f206c12012-08-25 00:09:141372
[email protected]aa043632013-03-25 03:39:421373 // Page scale should update metadata correctly (shrinking only the viewport).
[email protected]9ec24df2013-08-09 23:32:571374 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:421375 host_impl_->PinchGestureBegin();
1376 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
1377 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:571378 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:421379 {
1380 CompositorFrameMetadata metadata =
1381 host_impl_->MakeCompositorFrameMetadata();
1382 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1383 EXPECT_EQ(2.f, metadata.page_scale_factor);
1384 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.viewport_size);
1385 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1386 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1387 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1388 }
[email protected]94f206c12012-08-25 00:09:141389
[email protected]aa043632013-03-25 03:39:421390 // Likewise if set from the main thread.
1391 host_impl_->ProcessScrollDeltas();
1392 host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f);
1393 host_impl_->active_tree()->SetPageScaleDelta(1.f);
1394 {
1395 CompositorFrameMetadata metadata =
1396 host_impl_->MakeCompositorFrameMetadata();
1397 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1398 EXPECT_EQ(4.f, metadata.page_scale_factor);
1399 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.viewport_size);
1400 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1401 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1402 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1403 }
[email protected]f2b5a5be2013-01-08 00:34:361404}
1405
[email protected]96baf3e2012-10-22 23:09:551406class DidDrawCheckLayer : public TiledLayerImpl {
[email protected]aa043632013-03-25 03:39:421407 public:
1408 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
1409 return scoped_ptr<LayerImpl>(new DidDrawCheckLayer(tree_impl, id));
1410 }
[email protected]94f206c12012-08-25 00:09:141411
[email protected]ffbb2212013-06-02 23:47:591412 virtual bool WillDraw(DrawMode draw_mode, ResourceProvider* provider)
1413 OVERRIDE {
1414 will_draw_called_ = true;
1415 if (will_draw_returns_false_)
1416 return false;
1417 return TiledLayerImpl::WillDraw(draw_mode, provider);
1418 }
1419
1420 virtual void AppendQuads(QuadSink* quad_sink,
1421 AppendQuadsData* append_quads_data) OVERRIDE {
1422 append_quads_called_ = true;
1423 TiledLayerImpl::AppendQuads(quad_sink, append_quads_data);
1424 }
1425
[email protected]bf691c22013-03-26 21:15:061426 virtual void DidDraw(ResourceProvider* provider) OVERRIDE {
[email protected]aa043632013-03-25 03:39:421427 did_draw_called_ = true;
[email protected]ffbb2212013-06-02 23:47:591428 TiledLayerImpl::DidDraw(provider);
[email protected]aa043632013-03-25 03:39:421429 }
[email protected]94f206c12012-08-25 00:09:141430
[email protected]aa043632013-03-25 03:39:421431 bool will_draw_called() const { return will_draw_called_; }
[email protected]ffbb2212013-06-02 23:47:591432 bool append_quads_called() const { return append_quads_called_; }
1433 bool did_draw_called() const { return did_draw_called_; }
1434
1435 void set_will_draw_returns_false() { will_draw_returns_false_ = true; }
[email protected]94f206c12012-08-25 00:09:141436
[email protected]aa043632013-03-25 03:39:421437 void ClearDidDrawCheck() {
[email protected]aa043632013-03-25 03:39:421438 will_draw_called_ = false;
[email protected]ffbb2212013-06-02 23:47:591439 append_quads_called_ = false;
1440 did_draw_called_ = false;
[email protected]aa043632013-03-25 03:39:421441 }
[email protected]94f206c12012-08-25 00:09:141442
[email protected]aa043632013-03-25 03:39:421443 protected:
1444 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id)
1445 : TiledLayerImpl(tree_impl, id),
[email protected]ffbb2212013-06-02 23:47:591446 will_draw_returns_false_(false),
1447 will_draw_called_(false),
1448 append_quads_called_(false),
1449 did_draw_called_(false) {
[email protected]aa043632013-03-25 03:39:421450 SetAnchorPoint(gfx::PointF());
1451 SetBounds(gfx::Size(10, 10));
1452 SetContentBounds(gfx::Size(10, 10));
1453 SetDrawsContent(true);
1454 set_skips_draw(false);
1455 draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
[email protected]94f206c12012-08-25 00:09:141456
[email protected]aa043632013-03-25 03:39:421457 scoped_ptr<LayerTilingData> tiler =
1458 LayerTilingData::Create(gfx::Size(100, 100),
1459 LayerTilingData::HAS_BORDER_TEXELS);
1460 tiler->SetBounds(content_bounds());
1461 SetTilingData(*tiler.get());
1462 }
[email protected]94f206c12012-08-25 00:09:141463
[email protected]aa043632013-03-25 03:39:421464 private:
[email protected]ffbb2212013-06-02 23:47:591465 bool will_draw_returns_false_;
[email protected]aa043632013-03-25 03:39:421466 bool will_draw_called_;
[email protected]ffbb2212013-06-02 23:47:591467 bool append_quads_called_;
1468 bool did_draw_called_;
[email protected]94f206c12012-08-25 00:09:141469};
1470
[email protected]ffbb2212013-06-02 23:47:591471TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
1472 // The root layer is always drawn, so run this test on a child layer that
1473 // will be masked out by the root layer's bounds.
1474 host_impl_->active_tree()->SetRootLayer(
1475 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1476 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1477 host_impl_->active_tree()->root_layer());
1478
1479 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1480 DidDrawCheckLayer* layer =
1481 static_cast<DidDrawCheckLayer*>(root->children()[0]);
1482
1483 {
1484 LayerTreeHostImpl::FrameData frame;
1485 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
[email protected]de2cf8c2013-10-25 19:46:461486 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ffbb2212013-06-02 23:47:591487 host_impl_->DidDrawAllLayers(frame);
1488
1489 EXPECT_TRUE(layer->will_draw_called());
1490 EXPECT_TRUE(layer->append_quads_called());
1491 EXPECT_TRUE(layer->did_draw_called());
1492 }
1493
1494 {
1495 LayerTreeHostImpl::FrameData frame;
1496
1497 layer->set_will_draw_returns_false();
1498 layer->ClearDidDrawCheck();
1499
1500 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
[email protected]de2cf8c2013-10-25 19:46:461501 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ffbb2212013-06-02 23:47:591502 host_impl_->DidDrawAllLayers(frame);
1503
1504 EXPECT_TRUE(layer->will_draw_called());
1505 EXPECT_FALSE(layer->append_quads_called());
1506 EXPECT_FALSE(layer->did_draw_called());
1507 }
1508}
1509
[email protected]aa043632013-03-25 03:39:421510TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
1511 // The root layer is always drawn, so run this test on a child layer that
1512 // will be masked out by the root layer's bounds.
1513 host_impl_->active_tree()->SetRootLayer(
1514 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1515 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1516 host_impl_->active_tree()->root_layer());
1517 root->SetMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141518
[email protected]aa043632013-03-25 03:39:421519 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1520 DidDrawCheckLayer* layer =
1521 static_cast<DidDrawCheckLayer*>(root->children()[0]);
1522 // Ensure visible_content_rect for layer is empty.
1523 layer->SetPosition(gfx::PointF(100.f, 100.f));
1524 layer->SetBounds(gfx::Size(10, 10));
1525 layer->SetContentBounds(gfx::Size(10, 10));
[email protected]94f206c12012-08-25 00:09:141526
[email protected]aa043632013-03-25 03:39:421527 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141528
[email protected]aa043632013-03-25 03:39:421529 EXPECT_FALSE(layer->will_draw_called());
1530 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141531
[email protected]e0341352013-04-06 05:01:201532 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461533 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421534 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141535
[email protected]aa043632013-03-25 03:39:421536 EXPECT_FALSE(layer->will_draw_called());
1537 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141538
[email protected]aa043632013-03-25 03:39:421539 EXPECT_TRUE(layer->visible_content_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:141540
[email protected]aa043632013-03-25 03:39:421541 // Ensure visible_content_rect for layer is not empty
1542 layer->SetPosition(gfx::PointF());
[email protected]94f206c12012-08-25 00:09:141543
[email protected]aa043632013-03-25 03:39:421544 EXPECT_FALSE(layer->will_draw_called());
1545 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141546
[email protected]e0341352013-04-06 05:01:201547 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461548 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421549 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141550
[email protected]aa043632013-03-25 03:39:421551 EXPECT_TRUE(layer->will_draw_called());
1552 EXPECT_TRUE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141553
[email protected]aa043632013-03-25 03:39:421554 EXPECT_FALSE(layer->visible_content_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:141555}
1556
[email protected]aa043632013-03-25 03:39:421557TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
1558 gfx::Size big_size(1000, 1000);
[email protected]18ce59702013-04-09 04:58:401559 host_impl_->SetViewportSize(big_size);
[email protected]94f206c12012-08-25 00:09:141560
[email protected]aa043632013-03-25 03:39:421561 host_impl_->active_tree()->SetRootLayer(
1562 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1563 DidDrawCheckLayer* root =
1564 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:141565
[email protected]aa043632013-03-25 03:39:421566 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1567 DidDrawCheckLayer* occluded_layer =
1568 static_cast<DidDrawCheckLayer*>(root->children()[0]);
[email protected]94f206c12012-08-25 00:09:141569
[email protected]aa043632013-03-25 03:39:421570 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1571 DidDrawCheckLayer* top_layer =
1572 static_cast<DidDrawCheckLayer*>(root->children()[1]);
1573 // This layer covers the occluded_layer above. Make this layer large so it can
1574 // occlude.
1575 top_layer->SetBounds(big_size);
1576 top_layer->SetContentBounds(big_size);
1577 top_layer->SetContentsOpaque(true);
[email protected]94f206c12012-08-25 00:09:141578
[email protected]aa043632013-03-25 03:39:421579 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141580
[email protected]aa043632013-03-25 03:39:421581 EXPECT_FALSE(occluded_layer->will_draw_called());
1582 EXPECT_FALSE(occluded_layer->did_draw_called());
1583 EXPECT_FALSE(top_layer->will_draw_called());
1584 EXPECT_FALSE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141585
[email protected]e0341352013-04-06 05:01:201586 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461587 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421588 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141589
[email protected]aa043632013-03-25 03:39:421590 EXPECT_FALSE(occluded_layer->will_draw_called());
1591 EXPECT_FALSE(occluded_layer->did_draw_called());
1592 EXPECT_TRUE(top_layer->will_draw_called());
1593 EXPECT_TRUE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141594}
1595
[email protected]aa043632013-03-25 03:39:421596TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
1597 host_impl_->active_tree()->SetRootLayer(
1598 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1599 DidDrawCheckLayer* root =
1600 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:141601
[email protected]aa043632013-03-25 03:39:421602 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1603 DidDrawCheckLayer* layer1 =
1604 static_cast<DidDrawCheckLayer*>(root->children()[0]);
[email protected]94f206c12012-08-25 00:09:141605
[email protected]aa043632013-03-25 03:39:421606 layer1->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1607 DidDrawCheckLayer* layer2 =
1608 static_cast<DidDrawCheckLayer*>(layer1->children()[0]);
[email protected]94f206c12012-08-25 00:09:141609
[email protected]aa043632013-03-25 03:39:421610 layer1->SetOpacity(0.3f);
1611 layer1->SetPreserves3d(false);
[email protected]94f206c12012-08-25 00:09:141612
[email protected]aa043632013-03-25 03:39:421613 EXPECT_FALSE(root->did_draw_called());
1614 EXPECT_FALSE(layer1->did_draw_called());
1615 EXPECT_FALSE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141616
[email protected]aa043632013-03-25 03:39:421617 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:201618 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461619 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421620 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141621
[email protected]aa043632013-03-25 03:39:421622 EXPECT_TRUE(root->did_draw_called());
1623 EXPECT_TRUE(layer1->did_draw_called());
1624 EXPECT_TRUE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141625
[email protected]aa043632013-03-25 03:39:421626 EXPECT_NE(root->render_surface(), layer1->render_surface());
1627 EXPECT_TRUE(!!layer1->render_surface());
[email protected]94f206c12012-08-25 00:09:141628}
1629
1630class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
[email protected]aa043632013-03-25 03:39:421631 public:
1632 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
1633 int id,
1634 bool tile_missing,
1635 bool skips_draw,
1636 bool animating,
1637 ResourceProvider* resource_provider) {
1638 return scoped_ptr<LayerImpl>(new MissingTextureAnimatingLayer(
1639 tree_impl,
1640 id,
1641 tile_missing,
1642 skips_draw,
1643 animating,
1644 resource_provider));
1645 }
[email protected]94f206c12012-08-25 00:09:141646
[email protected]aa043632013-03-25 03:39:421647 private:
1648 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl,
1649 int id,
1650 bool tile_missing,
1651 bool skips_draw,
1652 bool animating,
1653 ResourceProvider* resource_provider)
1654 : DidDrawCheckLayer(tree_impl, id) {
1655 scoped_ptr<LayerTilingData> tiling_data =
1656 LayerTilingData::Create(gfx::Size(10, 10),
1657 LayerTilingData::NO_BORDER_TEXELS);
1658 tiling_data->SetBounds(bounds());
1659 SetTilingData(*tiling_data.get());
1660 set_skips_draw(skips_draw);
1661 if (!tile_missing) {
1662 ResourceProvider::ResourceId resource =
[email protected]cdccc7d42013-05-03 17:15:071663 resource_provider->CreateResource(gfx::Size(1, 1),
[email protected]efa48412013-09-05 15:30:161664 GL_CLAMP_TO_EDGE,
[email protected]27a41fe2013-09-19 05:05:141665 ResourceProvider::TextureUsageAny,
1666 RGBA_8888);
[email protected]aa043632013-03-25 03:39:421667 resource_provider->AllocateForTesting(resource);
1668 PushTileProperties(0, 0, resource, gfx::Rect(), false);
[email protected]94f206c12012-08-25 00:09:141669 }
[email protected]aa043632013-03-25 03:39:421670 if (animating)
1671 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1672 }
[email protected]94f206c12012-08-25 00:09:141673};
1674
[email protected]aa043632013-03-25 03:39:421675TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
1676 // When the texture is not missing, we draw as usual.
1677 host_impl_->active_tree()->SetRootLayer(
1678 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1679 DidDrawCheckLayer* root =
1680 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1681 root->AddChild(
1682 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1683 2,
1684 false,
1685 false,
1686 true,
1687 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141688
[email protected]aa043632013-03-25 03:39:421689 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141690
[email protected]e0341352013-04-06 05:01:201691 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461692 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421693 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141694
[email protected]aa043632013-03-25 03:39:421695 // When a texture is missing and we're not animating, we draw as usual with
1696 // checkerboarding.
1697 host_impl_->active_tree()->SetRootLayer(
1698 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1699 root =
1700 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1701 root->AddChild(
1702 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1703 4,
1704 true,
1705 false,
1706 false,
1707 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141708
[email protected]e0341352013-04-06 05:01:201709 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461710 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421711 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141712
[email protected]aa043632013-03-25 03:39:421713 // When a texture is missing and we're animating, we don't want to draw
1714 // anything.
1715 host_impl_->active_tree()->SetRootLayer(
1716 DidDrawCheckLayer::Create(host_impl_->active_tree(), 5));
1717 root =
1718 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1719 root->AddChild(
1720 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1721 6,
1722 true,
1723 false,
1724 true,
1725 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141726
[email protected]e0341352013-04-06 05:01:201727 EXPECT_FALSE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461728 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421729 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141730
[email protected]aa043632013-03-25 03:39:421731 // When the layer skips draw and we're animating, we still draw the frame.
1732 host_impl_->active_tree()->SetRootLayer(
1733 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7));
1734 root =
1735 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1736 root->AddChild(
1737 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1738 8,
1739 false,
1740 true,
1741 true,
1742 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141743
[email protected]e0341352013-04-06 05:01:201744 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461745 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421746 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141747}
1748
[email protected]aa043632013-03-25 03:39:421749TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
1750 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1751 root->SetScrollable(false);
1752 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]ce2e8112013-11-28 07:44:361753 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141754
[email protected]aa043632013-03-25 03:39:421755 // Scroll event is ignored because layer is not scrollable.
[email protected]5ff3c9782013-04-29 17:35:121756 EXPECT_EQ(InputHandler::ScrollIgnored,
1757 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421758 EXPECT_FALSE(did_request_redraw_);
1759 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141760}
1761
[email protected]aa043632013-03-25 03:39:421762TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) {
1763 LayerTreeSettings settings;
1764 settings.calculate_top_controls_position = true;
1765 settings.top_controls_height = 50;
[email protected]c8415bf92013-02-17 18:57:271766
[email protected]ce2e8112013-11-28 07:44:361767 CreateHostImpl(settings, CreateOutputSurface());
[email protected]c8415bf92013-02-17 18:57:271768
[email protected]aa043632013-03-25 03:39:421769 gfx::Size layer_size(5, 5);
1770 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1771 root->SetScrollable(true);
1772 root->SetMaxScrollOffset(gfx::Vector2d(layer_size.width(),
1773 layer_size.height()));
1774 root->SetBounds(layer_size);
1775 root->SetContentBounds(layer_size);
1776 root->SetPosition(gfx::PointF());
1777 root->SetAnchorPoint(gfx::PointF());
[email protected]e0341352013-04-06 05:01:201778 root->SetDrawsContent(false);
[email protected]aa043632013-03-25 03:39:421779 host_impl_->active_tree()->SetRootLayer(root.Pass());
1780 host_impl_->active_tree()->FindRootScrollLayer();
[email protected]ce2e8112013-11-28 07:44:361781 DrawFrame();
[email protected]c8415bf92013-02-17 18:57:271782
[email protected]5ff3c9782013-04-29 17:35:121783 EXPECT_EQ(InputHandler::ScrollIgnored,
1784 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]c8415bf92013-02-17 18:57:271785
[email protected]aa043632013-03-25 03:39:421786 host_impl_->top_controls_manager()->ScrollBegin();
1787 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
1788 host_impl_->top_controls_manager()->ScrollEnd();
1789 EXPECT_EQ(host_impl_->top_controls_manager()->content_top_offset(), 0.f);
[email protected]c8415bf92013-02-17 18:57:271790
[email protected]5ff3c9782013-04-29 17:35:121791 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421792 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:121793 InputHandler::Gesture));
[email protected]c8415bf92013-02-17 18:57:271794}
1795
[email protected]aa043632013-03-25 03:39:421796TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
1797 // Test the configuration where a non-composited root layer is embedded in a
1798 // scrollable outer layer.
1799 gfx::Size surface_size(10, 10);
[email protected]94f206c12012-08-25 00:09:141800
[email protected]aa043632013-03-25 03:39:421801 scoped_ptr<LayerImpl> content_layer =
1802 LayerImpl::Create(host_impl_->active_tree(), 1);
1803 content_layer->SetDrawsContent(true);
1804 content_layer->SetPosition(gfx::PointF());
1805 content_layer->SetAnchorPoint(gfx::PointF());
1806 content_layer->SetBounds(surface_size);
1807 content_layer->SetContentBounds(gfx::Size(surface_size.width() * 2,
1808 surface_size.height() * 2));
1809 content_layer->SetContentsScale(2.f, 2.f);
[email protected]94f206c12012-08-25 00:09:141810
[email protected]aa043632013-03-25 03:39:421811 scoped_ptr<LayerImpl> scroll_layer =
1812 LayerImpl::Create(host_impl_->active_tree(), 2);
1813 scroll_layer->SetScrollable(true);
1814 scroll_layer->SetMaxScrollOffset(gfx::Vector2d(surface_size.width(),
1815 surface_size.height()));
1816 scroll_layer->SetBounds(surface_size);
1817 scroll_layer->SetContentBounds(surface_size);
1818 scroll_layer->SetPosition(gfx::PointF());
1819 scroll_layer->SetAnchorPoint(gfx::PointF());
1820 scroll_layer->AddChild(content_layer.Pass());
[email protected]94f206c12012-08-25 00:09:141821
[email protected]aa043632013-03-25 03:39:421822 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass());
[email protected]18ce59702013-04-09 04:58:401823 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:361824 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141825
[email protected]5ff3c9782013-04-29 17:35:121826 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421827 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121828 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421829 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1830 host_impl_->ScrollEnd();
1831 EXPECT_TRUE(did_request_redraw_);
1832 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141833}
1834
[email protected]aa043632013-03-25 03:39:421835TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
1836 gfx::Size surface_size(10, 10);
1837 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1838 root->SetBounds(surface_size);
1839 root->SetContentBounds(surface_size);
1840 root->AddChild(CreateScrollableLayer(2, surface_size));
1841 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:401842 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:361843 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141844
[email protected]5ff3c9782013-04-29 17:35:121845 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421846 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121847 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421848 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1849 host_impl_->ScrollEnd();
1850 EXPECT_TRUE(did_request_redraw_);
1851 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141852}
1853
[email protected]aa043632013-03-25 03:39:421854TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
1855 gfx::Size surface_size(10, 10);
1856 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1857 root->AddChild(CreateScrollableLayer(2, surface_size));
1858 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:401859 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:361860 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141861
[email protected]aa043632013-03-25 03:39:421862 // Scroll event is ignored because the input coordinate is outside the layer
1863 // boundaries.
[email protected]5ff3c9782013-04-29 17:35:121864 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]aa043632013-03-25 03:39:421865 host_impl_->ScrollBegin(gfx::Point(15, 5),
[email protected]5ff3c9782013-04-29 17:35:121866 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421867 EXPECT_FALSE(did_request_redraw_);
1868 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141869}
1870
[email protected]aa043632013-03-25 03:39:421871TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
1872 gfx::Size surface_size(10, 10);
1873 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1874 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
[email protected]18ce59702013-04-09 04:58:401875 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:141876
[email protected]aa043632013-03-25 03:39:421877 gfx::Transform matrix;
1878 matrix.RotateAboutXAxis(180.0);
1879 child->SetTransform(matrix);
1880 child->SetDoubleSided(false);
[email protected]94f206c12012-08-25 00:09:141881
[email protected]aa043632013-03-25 03:39:421882 root->AddChild(child.Pass());
1883 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]ce2e8112013-11-28 07:44:361884 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141885
[email protected]aa043632013-03-25 03:39:421886 // Scroll event is ignored because the scrollable layer is not facing the
1887 // viewer and there is nothing scrollable behind it.
[email protected]5ff3c9782013-04-29 17:35:121888 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]aa043632013-03-25 03:39:421889 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121890 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421891 EXPECT_FALSE(did_request_redraw_);
1892 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141893}
1894
[email protected]aa043632013-03-25 03:39:421895TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
1896 gfx::Size surface_size(10, 10);
1897 scoped_ptr<LayerImpl> content_layer = CreateScrollableLayer(1, surface_size);
1898 content_layer->SetShouldScrollOnMainThread(true);
1899 content_layer->SetScrollable(false);
[email protected]94f206c12012-08-25 00:09:141900
[email protected]aa043632013-03-25 03:39:421901 scoped_ptr<LayerImpl> scroll_layer = CreateScrollableLayer(2, surface_size);
1902 scroll_layer->AddChild(content_layer.Pass());
[email protected]94f206c12012-08-25 00:09:141903
[email protected]aa043632013-03-25 03:39:421904 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass());
[email protected]18ce59702013-04-09 04:58:401905 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:361906 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141907
[email protected]aa043632013-03-25 03:39:421908 // Scrolling fails because the content layer is asking to be scrolled on the
1909 // main thread.
[email protected]5ff3c9782013-04-29 17:35:121910 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:421911 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121912 InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:141913}
1914
[email protected]aa043632013-03-25 03:39:421915TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
1916 gfx::Size surface_size(10, 10);
1917 float page_scale = 2.f;
[email protected]9781afa2013-07-17 23:15:321918 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1919 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
1920 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421921 host_impl_->active_tree()->SetRootLayer(root.Pass());
1922 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401923 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:361924 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141925
[email protected]9781afa2013-07-17 23:15:321926 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1927
[email protected]aa043632013-03-25 03:39:421928 gfx::Vector2d scroll_delta(0, 10);
1929 gfx::Vector2d expected_scroll_delta = scroll_delta;
[email protected]9781afa2013-07-17 23:15:321930 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset();
[email protected]5ff3c9782013-04-29 17:35:121931 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421932 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121933 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421934 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1935 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141936
[email protected]aa043632013-03-25 03:39:421937 // Set new page scale from main thread.
1938 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
1939 page_scale,
1940 page_scale);
[email protected]94f206c12012-08-25 00:09:141941
[email protected]aa043632013-03-25 03:39:421942 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:321943 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:141944
[email protected]aa043632013-03-25 03:39:421945 // The scroll range should also have been updated.
[email protected]9781afa2013-07-17 23:15:321946 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset());
[email protected]94f206c12012-08-25 00:09:141947
[email protected]aa043632013-03-25 03:39:421948 // The page scale delta remains constant because the impl thread did not
1949 // scale.
[email protected]f2136262013-04-26 21:10:191950 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:141951}
1952
[email protected]aa043632013-03-25 03:39:421953TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
1954 gfx::Size surface_size(10, 10);
1955 float page_scale = 2.f;
[email protected]9781afa2013-07-17 23:15:321956 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1957 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
1958 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421959 host_impl_->active_tree()->SetRootLayer(root.Pass());
1960 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401961 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421962 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale);
[email protected]ce2e8112013-11-28 07:44:361963 DrawFrame();
[email protected]94f206c12012-08-25 00:09:141964
[email protected]9781afa2013-07-17 23:15:321965 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1966
[email protected]aa043632013-03-25 03:39:421967 gfx::Vector2d scroll_delta(0, 10);
1968 gfx::Vector2d expected_scroll_delta = scroll_delta;
[email protected]9781afa2013-07-17 23:15:321969 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset();
[email protected]5ff3c9782013-04-29 17:35:121970 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421971 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121972 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421973 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1974 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141975
[email protected]aa043632013-03-25 03:39:421976 // Set new page scale on impl thread by pinching.
[email protected]9ec24df2013-08-09 23:32:571977 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:421978 host_impl_->PinchGestureBegin();
1979 host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
1980 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:571981 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:421982 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:141983
[email protected]aa043632013-03-25 03:39:421984 // The scroll delta is not scaled because the main thread did not scale.
1985 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:321986 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:141987
[email protected]aa043632013-03-25 03:39:421988 // The scroll range should also have been updated.
[email protected]9781afa2013-07-17 23:15:321989 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset());
[email protected]94f206c12012-08-25 00:09:141990
[email protected]aa043632013-03-25 03:39:421991 // The page scale delta should match the new scale on the impl side.
[email protected]f2136262013-04-26 21:10:191992 EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:141993}
1994
[email protected]aa043632013-03-25 03:39:421995TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
1996 gfx::Size surface_size(10, 10);
1997 float default_page_scale = 1.f;
1998 gfx::Transform default_page_scale_matrix;
[email protected]3209161d2013-03-29 19:17:341999 default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
[email protected]1c0c9bc2012-10-08 22:41:482000
[email protected]aa043632013-03-25 03:39:422001 float new_page_scale = 2.f;
2002 gfx::Transform new_page_scale_matrix;
2003 new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
[email protected]94f206c12012-08-25 00:09:142004
[email protected]aa043632013-03-25 03:39:422005 // Create a normal scrollable root layer and another scrollable child layer.
[email protected]35a99a12013-05-09 23:52:292006 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
[email protected]aa043632013-03-25 03:39:422007 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]35a99a12013-05-09 23:52:292008 LayerImpl* child = scroll->children()[0];
[email protected]94f206c12012-08-25 00:09:142009
[email protected]aa043632013-03-25 03:39:422010 scoped_ptr<LayerImpl> scrollable_child =
[email protected]35a99a12013-05-09 23:52:292011 CreateScrollableLayer(4, surface_size);
[email protected]aa043632013-03-25 03:39:422012 child->AddChild(scrollable_child.Pass());
2013 LayerImpl* grand_child = child->children()[0];
[email protected]94f206c12012-08-25 00:09:142014
[email protected]aa043632013-03-25 03:39:422015 // Set new page scale on impl thread by pinching.
[email protected]9ec24df2013-08-09 23:32:572016 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:422017 host_impl_->PinchGestureBegin();
2018 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
2019 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:572020 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:422021 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:142022
[email protected]f2136262013-04-26 21:10:192023 EXPECT_EQ(1.f, root->contents_scale_x());
2024 EXPECT_EQ(1.f, root->contents_scale_y());
[email protected]35a99a12013-05-09 23:52:292025 EXPECT_EQ(1.f, scroll->contents_scale_x());
2026 EXPECT_EQ(1.f, scroll->contents_scale_y());
[email protected]f2136262013-04-26 21:10:192027 EXPECT_EQ(1.f, child->contents_scale_x());
2028 EXPECT_EQ(1.f, child->contents_scale_y());
2029 EXPECT_EQ(1.f, grand_child->contents_scale_x());
2030 EXPECT_EQ(1.f, grand_child->contents_scale_y());
[email protected]94f206c12012-08-25 00:09:142031
[email protected]aa043632013-03-25 03:39:422032 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
2033 // the page scale delta on the root layer is applied hierarchically.
2034 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:202035 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462036 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422037 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142038
[email protected]35a99a12013-05-09 23:52:292039 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0));
2040 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(1, 1));
2041 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(0, 0));
2042 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(1, 1));
[email protected]aa043632013-03-25 03:39:422043 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(0, 0));
2044 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(1, 1));
2045 EXPECT_EQ(new_page_scale,
2046 grand_child->draw_transform().matrix().getDouble(0, 0));
2047 EXPECT_EQ(new_page_scale,
2048 grand_child->draw_transform().matrix().getDouble(1, 1));
[email protected]94f206c12012-08-25 00:09:142049}
2050
[email protected]aa043632013-03-25 03:39:422051TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
2052 gfx::Size surface_size(10, 10);
2053 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]9781afa2013-07-17 23:15:322054 scoped_ptr<LayerImpl> root_scrolling =
2055 LayerImpl::Create(host_impl_->active_tree(), 2);
2056 root_scrolling->SetBounds(surface_size);
2057 root_scrolling->SetContentBounds(surface_size);
2058 root_scrolling->SetScrollable(true);
2059 root->AddChild(root_scrolling.Pass());
2060 int child_scroll_layer_id = 3;
2061 scoped_ptr<LayerImpl> child_scrolling =
2062 CreateScrollableLayer(child_scroll_layer_id, surface_size);
2063 LayerImpl* child = child_scrolling.get();
2064 root->AddChild(child_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:422065 host_impl_->active_tree()->SetRootLayer(root.Pass());
2066 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402067 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362068 DrawFrame();
[email protected]94f206c12012-08-25 00:09:142069
[email protected]aa043632013-03-25 03:39:422070 gfx::Vector2d scroll_delta(0, 10);
2071 gfx::Vector2d expected_scroll_delta(scroll_delta);
2072 gfx::Vector2d expected_max_scroll(child->max_scroll_offset());
[email protected]5ff3c9782013-04-29 17:35:122073 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422074 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122075 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422076 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2077 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142078
[email protected]aa043632013-03-25 03:39:422079 float page_scale = 2.f;
2080 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
2081 1.f,
2082 page_scale);
[email protected]94f206c12012-08-25 00:09:142083
[email protected]aa043632013-03-25 03:39:422084 DrawOneFrame();
[email protected]1c0c9bc2012-10-08 22:41:482085
[email protected]aa043632013-03-25 03:39:422086 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:322087 ExpectContains(
2088 *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142089
[email protected]aa043632013-03-25 03:39:422090 // The scroll range should not have changed.
2091 EXPECT_EQ(child->max_scroll_offset(), expected_max_scroll);
[email protected]94f206c12012-08-25 00:09:142092
[email protected]aa043632013-03-25 03:39:422093 // The page scale delta remains constant because the impl thread did not
2094 // scale.
[email protected]f2136262013-04-26 21:10:192095 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:142096}
2097
[email protected]aa043632013-03-25 03:39:422098TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
2099 // Scroll a child layer beyond its maximum scroll range and make sure the
2100 // parent layer is scrolled on the axis on which the child was unable to
2101 // scroll.
2102 gfx::Size surface_size(10, 10);
2103 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size);
[email protected]94f206c12012-08-25 00:09:142104
[email protected]aa043632013-03-25 03:39:422105 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size);
2106 grand_child->SetScrollOffset(gfx::Vector2d(0, 5));
[email protected]94f206c12012-08-25 00:09:142107
[email protected]aa043632013-03-25 03:39:422108 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
2109 child->SetScrollOffset(gfx::Vector2d(3, 0));
2110 child->AddChild(grand_child.Pass());
[email protected]94f206c12012-08-25 00:09:142111
[email protected]aa043632013-03-25 03:39:422112 root->AddChild(child.Pass());
2113 host_impl_->active_tree()->SetRootLayer(root.Pass());
2114 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402115 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362116 DrawFrame();
[email protected]aa043632013-03-25 03:39:422117 {
2118 gfx::Vector2d scroll_delta(-8, -7);
[email protected]5ff3c9782013-04-29 17:35:122119 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472120 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122121 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422122 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2123 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142124
[email protected]aa043632013-03-25 03:39:422125 scoped_ptr<ScrollAndScaleSet> scroll_info =
2126 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:142127
[email protected]aa043632013-03-25 03:39:422128 // The grand child should have scrolled up to its limit.
2129 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
2130 LayerImpl* grand_child = child->children()[0];
2131 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5));
[email protected]94f206c12012-08-25 00:09:142132
[email protected]aa043632013-03-25 03:39:422133 // The child should have only scrolled on the other axis.
2134 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0));
2135 }
[email protected]94f206c12012-08-25 00:09:142136}
2137
[email protected]aa043632013-03-25 03:39:422138TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
2139 // Scroll a child layer beyond its maximum scroll range and make sure the
2140 // the scroll doesn't bubble up to the parent layer.
2141 gfx::Size surface_size(10, 10);
[email protected]9781afa2013-07-17 23:15:322142 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2143 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
[email protected]7dfa6862013-01-31 01:29:092144
[email protected]9781afa2013-07-17 23:15:322145 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(4, surface_size);
[email protected]aa043632013-03-25 03:39:422146 grand_child->SetScrollOffset(gfx::Vector2d(0, 2));
[email protected]7dfa6862013-01-31 01:29:092147
[email protected]9781afa2013-07-17 23:15:322148 scoped_ptr<LayerImpl> child = CreateScrollableLayer(3, surface_size);
[email protected]aa043632013-03-25 03:39:422149 child->SetScrollOffset(gfx::Vector2d(0, 3));
2150 child->AddChild(grand_child.Pass());
[email protected]7dfa6862013-01-31 01:29:092151
[email protected]9781afa2013-07-17 23:15:322152 root_scrolling->AddChild(child.Pass());
2153 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:422154 host_impl_->active_tree()->SetRootLayer(root.Pass());
2155 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402156 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362157 DrawFrame();
[email protected]aa043632013-03-25 03:39:422158 {
2159 gfx::Vector2d scroll_delta(0, -10);
[email protected]5ff3c9782013-04-29 17:35:122160 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472161 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122162 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422163 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2164 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092165
[email protected]aa043632013-03-25 03:39:422166 scoped_ptr<ScrollAndScaleSet> scroll_info =
2167 host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092168
[email protected]aa043632013-03-25 03:39:422169 // The grand child should have scrolled up to its limit.
[email protected]9781afa2013-07-17 23:15:322170 LayerImpl* child =
2171 host_impl_->active_tree()->root_layer()->children()[0]->children()[0];
[email protected]aa043632013-03-25 03:39:422172 LayerImpl* grand_child = child->children()[0];
2173 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
[email protected]7dfa6862013-01-31 01:29:092174
[email protected]aa043632013-03-25 03:39:422175 // The child should not have scrolled.
2176 ExpectNone(*scroll_info.get(), child->id());
[email protected]7dfa6862013-01-31 01:29:092177
[email protected]aa043632013-03-25 03:39:422178 // The next time we scroll we should only scroll the parent.
2179 scroll_delta = gfx::Vector2d(0, -3);
[email protected]5ff3c9782013-04-29 17:35:122180 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422181 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122182 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422183 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2184 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2185 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
2186 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092187
[email protected]aa043632013-03-25 03:39:422188 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092189
[email protected]aa043632013-03-25 03:39:422190 // The child should have scrolled up to its limit.
2191 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
[email protected]7dfa6862013-01-31 01:29:092192
[email protected]aa043632013-03-25 03:39:422193 // The grand child should not have scrolled.
2194 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
[email protected]7dfa6862013-01-31 01:29:092195
[email protected]aa043632013-03-25 03:39:422196 // After scrolling the parent, another scroll on the opposite direction
2197 // should still scroll the child.
2198 scroll_delta = gfx::Vector2d(0, 7);
[email protected]5ff3c9782013-04-29 17:35:122199 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422200 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122201 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422202 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2203 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2204 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2205 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092206
[email protected]aa043632013-03-25 03:39:422207 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092208
[email protected]aa043632013-03-25 03:39:422209 // The grand child should have scrolled.
2210 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5));
[email protected]7dfa6862013-01-31 01:29:092211
[email protected]aa043632013-03-25 03:39:422212 // The child should not have scrolled.
2213 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
[email protected]f4937272013-02-07 05:54:502214
2215
[email protected]aa043632013-03-25 03:39:422216 // Scrolling should be adjusted from viewport space.
2217 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f);
2218 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]f4937272013-02-07 05:54:502219
[email protected]aa043632013-03-25 03:39:422220 scroll_delta = gfx::Vector2d(0, -2);
[email protected]5ff3c9782013-04-29 17:35:122221 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422222 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122223 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422224 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer());
2225 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2226 host_impl_->ScrollEnd();
[email protected]f4937272013-02-07 05:54:502227
[email protected]aa043632013-03-25 03:39:422228 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]f4937272013-02-07 05:54:502229
[email protected]aa043632013-03-25 03:39:422230 // Should have scrolled by half the amount in layer space (5 - 2/2)
2231 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4));
2232 }
[email protected]7dfa6862013-01-31 01:29:092233}
2234
[email protected]aa043632013-03-25 03:39:422235TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
2236 // When we try to scroll a non-scrollable child layer, the scroll delta
2237 // should be applied to one of its ancestors if possible.
2238 gfx::Size surface_size(10, 10);
2239 gfx::Size content_size(20, 20);
2240 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
2241 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
[email protected]94f206c12012-08-25 00:09:142242
[email protected]aa043632013-03-25 03:39:422243 child->SetScrollable(false);
2244 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:142245
[email protected]18ce59702013-04-09 04:58:402246 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422247 host_impl_->active_tree()->SetRootLayer(root.Pass());
2248 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:362249 DrawFrame();
[email protected]aa043632013-03-25 03:39:422250 {
2251 gfx::Vector2d scroll_delta(0, 4);
[email protected]5ff3c9782013-04-29 17:35:122252 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422253 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122254 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422255 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2256 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142257
[email protected]aa043632013-03-25 03:39:422258 scoped_ptr<ScrollAndScaleSet> scroll_info =
2259 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:142260
[email protected]aa043632013-03-25 03:39:422261 // Only the root should have scrolled.
2262 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
2263 ExpectContains(*scroll_info.get(),
2264 host_impl_->active_tree()->root_layer()->id(),
2265 scroll_delta);
2266 }
[email protected]94f206c12012-08-25 00:09:142267}
2268
[email protected]aa043632013-03-25 03:39:422269TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
2270 gfx::Size surface_size(10, 10);
2271 host_impl_->active_tree()->SetRootLayer(
2272 CreateScrollableLayer(1, surface_size));
2273 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402274 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:142275
[email protected]aa043632013-03-25 03:39:422276 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2277 // synchronization.
[email protected]ce2e8112013-11-28 07:44:362278 DrawFrame();
[email protected]aa043632013-03-25 03:39:422279 host_impl_->active_tree()->DetachLayerTree();
2280 host_impl_->active_tree()->SetRootLayer(
2281 CreateScrollableLayer(2, surface_size));
2282 host_impl_->active_tree()->DidBecomeActive();
[email protected]94f206c12012-08-25 00:09:142283
[email protected]aa043632013-03-25 03:39:422284 // Scrolling should still work even though we did not draw yet.
[email protected]5ff3c9782013-04-29 17:35:122285 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422286 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122287 InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:142288}
2289
[email protected]aa043632013-03-25 03:39:422290TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:292291 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:142292
[email protected]aa043632013-03-25 03:39:422293 // Rotate the root layer 90 degrees counter-clockwise about its center.
2294 gfx::Transform rotate_transform;
2295 rotate_transform.Rotate(-90.0);
2296 host_impl_->active_tree()->root_layer()->SetTransform(rotate_transform);
[email protected]94f206c12012-08-25 00:09:142297
[email protected]aa043632013-03-25 03:39:422298 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402299 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362300 DrawFrame();
[email protected]94f206c12012-08-25 00:09:142301
[email protected]aa043632013-03-25 03:39:422302 // Scroll to the right in screen coordinates with a gesture.
2303 gfx::Vector2d gesture_scroll_delta(10, 0);
[email protected]5ff3c9782013-04-29 17:35:122304 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422305 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122306 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422307 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2308 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142309
[email protected]aa043632013-03-25 03:39:422310 // The layer should have scrolled down in its local coordinates.
2311 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
2312 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292313 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422314 gfx::Vector2d(0, gesture_scroll_delta.x()));
[email protected]94f206c12012-08-25 00:09:142315
[email protected]aa043632013-03-25 03:39:422316 // Reset and scroll down with the wheel.
[email protected]35a99a12013-05-09 23:52:292317 scroll_layer->SetScrollDelta(gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:422318 gfx::Vector2d wheel_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122319 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422320 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122321 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422322 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
2323 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142324
[email protected]aa043632013-03-25 03:39:422325 // The layer should have scrolled down in its local coordinates.
2326 scroll_info = host_impl_->ProcessScrollDeltas();
2327 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292328 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422329 wheel_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142330}
2331
[email protected]aa043632013-03-25 03:39:422332TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:292333 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
2334 int child_layer_id = 4;
[email protected]aa043632013-03-25 03:39:422335 float child_layer_angle = -20.f;
[email protected]94f206c12012-08-25 00:09:142336
[email protected]aa043632013-03-25 03:39:422337 // Create a child layer that is rotated to a non-axis-aligned angle.
2338 scoped_ptr<LayerImpl> child = CreateScrollableLayer(
2339 child_layer_id,
[email protected]35a99a12013-05-09 23:52:292340 scroll_layer->content_bounds());
[email protected]aa043632013-03-25 03:39:422341 gfx::Transform rotate_transform;
2342 rotate_transform.Translate(-50.0, -50.0);
2343 rotate_transform.Rotate(child_layer_angle);
2344 rotate_transform.Translate(50.0, 50.0);
2345 child->SetTransform(rotate_transform);
[email protected]94f206c12012-08-25 00:09:142346
[email protected]aa043632013-03-25 03:39:422347 // Only allow vertical scrolling.
2348 child->SetMaxScrollOffset(gfx::Vector2d(0, child->content_bounds().height()));
[email protected]35a99a12013-05-09 23:52:292349 scroll_layer->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:142350
[email protected]aa043632013-03-25 03:39:422351 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402352 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362353 DrawFrame();
[email protected]aa043632013-03-25 03:39:422354 {
[email protected]94f206c12012-08-25 00:09:142355 // Scroll down in screen coordinates with a gesture.
[email protected]aa043632013-03-25 03:39:422356 gfx::Vector2d gesture_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122357 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]803f6b52013-09-12 00:51:262358 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122359 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422360 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2361 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142362
[email protected]aa043632013-03-25 03:39:422363 // The child layer should have scrolled down in its local coordinates an
2364 // amount proportional to the angle between it and the input scroll delta.
2365 gfx::Vector2d expected_scroll_delta(
2366 0,
2367 gesture_scroll_delta.y() *
2368 std::cos(MathUtil::Deg2Rad(child_layer_angle)));
2369 scoped_ptr<ScrollAndScaleSet> scroll_info =
2370 host_impl_->ProcessScrollDeltas();
2371 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142372
[email protected]35a99a12013-05-09 23:52:292373 // The root scroll layer should not have scrolled, because the input delta
2374 // was close to the layer's axis of movement.
[email protected]aa043632013-03-25 03:39:422375 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
2376 }
2377 {
2378 // Now reset and scroll the same amount horizontally.
[email protected]35a99a12013-05-09 23:52:292379 scroll_layer->children()[1]->SetScrollDelta(
[email protected]aa043632013-03-25 03:39:422380 gfx::Vector2dF());
2381 gfx::Vector2d gesture_scroll_delta(10, 0);
[email protected]5ff3c9782013-04-29 17:35:122382 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]803f6b52013-09-12 00:51:262383 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122384 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422385 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2386 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142387
[email protected]aa043632013-03-25 03:39:422388 // The child layer should have scrolled down in its local coordinates an
2389 // amount proportional to the angle between it and the input scroll delta.
2390 gfx::Vector2d expected_scroll_delta(
2391 0,
2392 -gesture_scroll_delta.x() *
2393 std::sin(MathUtil::Deg2Rad(child_layer_angle)));
2394 scoped_ptr<ScrollAndScaleSet> scroll_info =
2395 host_impl_->ProcessScrollDeltas();
2396 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
2397
[email protected]35a99a12013-05-09 23:52:292398 // The root scroll layer should have scrolled more, since the input scroll
2399 // delta was mostly orthogonal to the child layer's vertical scroll axis.
[email protected]aa043632013-03-25 03:39:422400 gfx::Vector2d expected_root_scroll_delta(
2401 gesture_scroll_delta.x() *
2402 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2),
2403 0);
2404 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292405 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422406 expected_root_scroll_delta);
2407 }
2408}
2409
2410TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
[email protected]35a99a12013-05-09 23:52:292411 LayerImpl* scroll_layer =
2412 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:422413
2414 // Scale the layer to twice its normal size.
2415 int scale = 2;
2416 gfx::Transform scale_transform;
2417 scale_transform.Scale(scale, scale);
[email protected]35a99a12013-05-09 23:52:292418 scroll_layer->SetTransform(scale_transform);
[email protected]aa043632013-03-25 03:39:422419
2420 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402421 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362422 DrawFrame();
[email protected]aa043632013-03-25 03:39:422423
2424 // Scroll down in screen coordinates with a gesture.
2425 gfx::Vector2d scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122426 EXPECT_EQ(InputHandler::ScrollStarted,
2427 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422428 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2429 host_impl_->ScrollEnd();
2430
2431 // The layer should have scrolled down in its local coordinates, but half the
2432 // amount.
2433 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
2434 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292435 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422436 gfx::Vector2d(0, scroll_delta.y() / scale));
2437
2438 // Reset and scroll down with the wheel.
[email protected]35a99a12013-05-09 23:52:292439 scroll_layer->SetScrollDelta(gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:422440 gfx::Vector2d wheel_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122441 EXPECT_EQ(InputHandler::ScrollStarted,
2442 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422443 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
2444 host_impl_->ScrollEnd();
2445
2446 // The scale should not have been applied to the scroll delta.
2447 scroll_info = host_impl_->ProcessScrollDeltas();
2448 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292449 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422450 wheel_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142451}
2452
[email protected]0a0d1422013-05-02 09:14:522453class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
2454 public:
[email protected]20d2b742013-09-26 05:41:342455 TestScrollOffsetDelegate() : page_scale_factor_(0.f) {}
2456
[email protected]0a0d1422013-05-02 09:14:522457 virtual ~TestScrollOffsetDelegate() {}
2458
[email protected]20d2b742013-09-26 05:41:342459 virtual void SetMaxScrollOffset(gfx::Vector2dF max_scroll_offset) OVERRIDE {
2460 max_scroll_offset_ = max_scroll_offset;
2461 }
2462
[email protected]0a0d1422013-05-02 09:14:522463 virtual void SetTotalScrollOffset(gfx::Vector2dF new_value) OVERRIDE {
2464 last_set_scroll_offset_ = new_value;
2465 }
2466
2467 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
2468 return getter_return_value_;
2469 }
2470
[email protected]251699b2013-10-09 00:21:262471 virtual bool IsExternalFlingActive() const OVERRIDE { return false; }
2472
[email protected]22f200a2013-10-09 18:08:292473 virtual void SetTotalPageScaleFactor(float page_scale_factor) OVERRIDE {
[email protected]20d2b742013-09-26 05:41:342474 page_scale_factor_ = page_scale_factor;
2475 }
2476
2477 virtual void SetScrollableSize(gfx::SizeF scrollable_size) OVERRIDE {
2478 scrollable_size_ = scrollable_size;
2479 }
2480
[email protected]0a0d1422013-05-02 09:14:522481 gfx::Vector2dF last_set_scroll_offset() {
2482 return last_set_scroll_offset_;
2483 }
2484
2485 void set_getter_return_value(gfx::Vector2dF value) {
2486 getter_return_value_ = value;
2487 }
2488
[email protected]20d2b742013-09-26 05:41:342489 gfx::Vector2dF max_scroll_offset() const {
2490 return max_scroll_offset_;
2491 }
2492
2493 gfx::SizeF scrollable_size() const {
2494 return scrollable_size_;
2495 }
2496
2497 float page_scale_factor() const {
2498 return page_scale_factor_;
2499 }
2500
[email protected]0a0d1422013-05-02 09:14:522501 private:
2502 gfx::Vector2dF last_set_scroll_offset_;
2503 gfx::Vector2dF getter_return_value_;
[email protected]20d2b742013-09-26 05:41:342504 gfx::Vector2dF max_scroll_offset_;
2505 gfx::SizeF scrollable_size_;
2506 float page_scale_factor_;
[email protected]0a0d1422013-05-02 09:14:522507};
2508
2509TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
2510 TestScrollOffsetDelegate scroll_delegate;
[email protected]20d2b742013-09-26 05:41:342511 host_impl_->SetViewportSize(gfx::Size(10, 20));
[email protected]35a99a12013-05-09 23:52:292512 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]0a0d1422013-05-02 09:14:522513
2514 // Setting the delegate results in the current scroll offset being set.
[email protected]35a99a12013-05-09 23:52:292515 gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
2516 scroll_layer->SetScrollOffset(gfx::Vector2d());
2517 scroll_layer->SetScrollDelta(initial_scroll_delta);
[email protected]0a0d1422013-05-02 09:14:522518 host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
[email protected]35a99a12013-05-09 23:52:292519 EXPECT_EQ(initial_scroll_delta.ToString(),
2520 scroll_delegate.last_set_scroll_offset().ToString());
[email protected]0a0d1422013-05-02 09:14:522521
[email protected]20d2b742013-09-26 05:41:342522 // Setting the delegate results in the scrollable_size, max_scroll_offset and
2523 // page_scale being set.
2524 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size());
2525 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate.max_scroll_offset());
2526 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
2527
2528 // Updating page scale immediately updates the delegate.
2529 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 0.5f, 4.f);
2530 EXPECT_EQ(2.f, scroll_delegate.page_scale_factor());
[email protected]22f200a2013-10-09 18:08:292531 host_impl_->active_tree()->SetPageScaleDelta(1.5f);
2532 EXPECT_EQ(3.f, scroll_delegate.page_scale_factor());
2533 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]20d2b742013-09-26 05:41:342534 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
2535 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
2536
[email protected]0a0d1422013-05-02 09:14:522537 // Scrolling should be relative to the offset as returned by the delegate.
[email protected]35a99a12013-05-09 23:52:292538 gfx::Vector2dF scroll_delta(0.f, 10.f);
2539 gfx::Vector2dF current_offset(7.f, 8.f);
[email protected]0a0d1422013-05-02 09:14:522540
2541 scroll_delegate.set_getter_return_value(current_offset);
2542 EXPECT_EQ(InputHandler::ScrollStarted,
2543 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2544
2545 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2546 EXPECT_EQ(current_offset + scroll_delta,
2547 scroll_delegate.last_set_scroll_offset());
2548
[email protected]35a99a12013-05-09 23:52:292549 current_offset = gfx::Vector2dF(42.f, 41.f);
[email protected]0a0d1422013-05-02 09:14:522550 scroll_delegate.set_getter_return_value(current_offset);
2551 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2552 EXPECT_EQ(current_offset + scroll_delta,
2553 scroll_delegate.last_set_scroll_offset());
2554 host_impl_->ScrollEnd();
2555
[email protected]7d1b07e2013-10-01 17:31:302556 // Forces a full tree synchronization and ensures that the scroll delegate
2557 // sees the correct size of the new tree.
2558 gfx::Size new_size(42, 24);
2559 host_impl_->CreatePendingTree();
2560 CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size);
2561 host_impl_->ActivatePendingTree();
2562 EXPECT_EQ(new_size, scroll_delegate.scrollable_size());
2563
[email protected]0a0d1422013-05-02 09:14:522564 // Un-setting the delegate should propagate the delegate's current offset to
2565 // the root scrollable layer.
[email protected]35a99a12013-05-09 23:52:292566 current_offset = gfx::Vector2dF(13.f, 12.f);
[email protected]0a0d1422013-05-02 09:14:522567 scroll_delegate.set_getter_return_value(current_offset);
2568 host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
2569
[email protected]35a99a12013-05-09 23:52:292570 EXPECT_EQ(current_offset.ToString(),
2571 scroll_layer->TotalScrollOffset().ToString());
[email protected]0a0d1422013-05-02 09:14:522572}
2573
[email protected]a2b5ded2013-05-20 21:32:532574TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
2575 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2576 host_impl_->SetViewportSize(gfx::Size(50, 50));
2577 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:362578 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:532579 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2580 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2581
2582 // In-bounds scrolling does not affect overscroll.
2583 EXPECT_EQ(InputHandler::ScrollStarted,
2584 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2585 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2586 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2587 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2588
2589 // Overscroll events are reflected immediately.
2590 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
2591 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
2592 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2593
[email protected]2bd503f2013-07-23 05:35:292594 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
[email protected]a2b5ded2013-05-20 21:32:532595 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
2596 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
2597 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
2598 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
[email protected]2bd503f2013-07-23 05:35:292599 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
2600 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
2601 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
2602 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll());
2603 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
2604 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll());
2605 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
2606 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:532607
2608 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
2609 // as no scroll occurs.
2610 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2611 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll());
2612 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2613 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll());
2614 // Overscroll resets on valid scroll.
2615 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2616 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
2617 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2618 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
2619 host_impl_->ScrollEnd();
2620
2621 EXPECT_EQ(InputHandler::ScrollStarted,
2622 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2623 // Fling velocity is reflected immediately.
2624 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0));
2625 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2626 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2627 EXPECT_EQ(gfx::Vector2dF(0, -20), host_impl_->accumulated_root_overscroll());
2628 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2629}
2630
2631
2632TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
2633 // Scroll child layers beyond their maximum scroll range and make sure root
2634 // overscroll does not accumulate.
2635 gfx::Size surface_size(10, 10);
2636 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size);
2637
2638 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size);
2639 grand_child->SetScrollOffset(gfx::Vector2d(0, 2));
2640
2641 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
2642 child->SetScrollOffset(gfx::Vector2d(0, 3));
2643 child->AddChild(grand_child.Pass());
2644
2645 root->AddChild(child.Pass());
2646 host_impl_->active_tree()->SetRootLayer(root.Pass());
2647 host_impl_->active_tree()->DidBecomeActive();
2648 host_impl_->SetViewportSize(surface_size);
[email protected]ce2e8112013-11-28 07:44:362649 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:532650 {
2651 gfx::Vector2d scroll_delta(0, -10);
2652 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472653 host_impl_->ScrollBegin(gfx::Point(),
[email protected]a2b5ded2013-05-20 21:32:532654 InputHandler::NonBubblingGesture));
2655 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2656 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2657 host_impl_->ScrollEnd();
2658
2659 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
2660 LayerImpl* grand_child = child->children()[0];
2661
2662 // The next time we scroll we should only scroll the parent, but overscroll
2663 // should still not reach the root layer.
2664 scroll_delta = gfx::Vector2d(0, -30);
2665 EXPECT_EQ(InputHandler::ScrollStarted,
2666 host_impl_->ScrollBegin(gfx::Point(5, 5),
2667 InputHandler::NonBubblingGesture));
2668 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2669 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2670 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2671 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
2672 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2673 host_impl_->ScrollEnd();
2674
2675 // After scrolling the parent, another scroll on the opposite direction
2676 // should scroll the child, resetting the fling velocity.
2677 scroll_delta = gfx::Vector2d(0, 70);
2678 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0));
2679 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2680 EXPECT_EQ(InputHandler::ScrollStarted,
2681 host_impl_->ScrollBegin(gfx::Point(5, 5),
2682 InputHandler::NonBubblingGesture));
2683 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2684 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2685 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2686 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2687 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2688 host_impl_->ScrollEnd();
2689 }
2690}
2691
2692TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
2693 // When we try to scroll a non-scrollable child layer, the scroll delta
2694 // should be applied to one of its ancestors if possible. Overscroll should
2695 // be reflected only when it has bubbled up to the root scrolling layer.
2696 gfx::Size surface_size(10, 10);
2697 gfx::Size content_size(20, 20);
2698 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
2699 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
2700
2701 child->SetScrollable(false);
2702 root->AddChild(child.Pass());
2703
2704 host_impl_->SetViewportSize(surface_size);
2705 host_impl_->active_tree()->SetRootLayer(root.Pass());
2706 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:362707 DrawFrame();
[email protected]a2b5ded2013-05-20 21:32:532708 {
2709 gfx::Vector2d scroll_delta(0, 8);
2710 EXPECT_EQ(InputHandler::ScrollStarted,
2711 host_impl_->ScrollBegin(gfx::Point(5, 5),
2712 InputHandler::Wheel));
2713 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2714 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2715 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2716 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
2717 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2718 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
2719 host_impl_->ScrollEnd();
2720 }
2721}
2722
[email protected]34d43432013-09-26 20:04:102723TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
2724 LayerTreeSettings settings;
2725 settings.always_overscroll = true;
[email protected]ce2e8112013-11-28 07:44:362726 CreateHostImpl(settings, CreateOutputSurface());
[email protected]34d43432013-09-26 20:04:102727
2728 SetupScrollAndContentsLayers(gfx::Size(50, 50));
2729 host_impl_->SetViewportSize(gfx::Size(50, 50));
2730 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
[email protected]ce2e8112013-11-28 07:44:362731 DrawFrame();
[email protected]34d43432013-09-26 20:04:102732 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2733 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2734
2735 // Even though the layer can't scroll the overscroll still happens.
2736 EXPECT_EQ(InputHandler::ScrollStarted,
2737 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2738 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2739 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
2740 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2741}
[email protected]a2b5ded2013-05-20 21:32:532742
[email protected]96baf3e2012-10-22 23:09:552743class BlendStateCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:422744 public:
2745 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
2746 int id,
2747 ResourceProvider* resource_provider) {
2748 return scoped_ptr<LayerImpl>(new BlendStateCheckLayer(tree_impl,
2749 id,
2750 resource_provider));
2751 }
[email protected]94f206c12012-08-25 00:09:142752
[email protected]aa043632013-03-25 03:39:422753 virtual void AppendQuads(QuadSink* quad_sink,
2754 AppendQuadsData* append_quads_data) OVERRIDE {
2755 quads_appended_ = true;
[email protected]94f206c12012-08-25 00:09:142756
[email protected]aa043632013-03-25 03:39:422757 gfx::Rect opaque_rect;
2758 if (contents_opaque())
2759 opaque_rect = quad_rect_;
2760 else
2761 opaque_rect = opaque_content_rect_;
[email protected]94f206c12012-08-25 00:09:142762
[email protected]aa043632013-03-25 03:39:422763 SharedQuadState* shared_quad_state =
2764 quad_sink->UseSharedQuadState(CreateSharedQuadState());
2765 scoped_ptr<TileDrawQuad> test_blending_draw_quad = TileDrawQuad::Create();
2766 test_blending_draw_quad->SetNew(shared_quad_state,
2767 quad_rect_,
2768 opaque_rect,
2769 resource_id_,
2770 gfx::RectF(0.f, 0.f, 1.f, 1.f),
2771 gfx::Size(1, 1),
2772 false);
2773 test_blending_draw_quad->visible_rect = quad_visible_rect_;
2774 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
2775 EXPECT_EQ(has_render_surface_, !!render_surface());
2776 quad_sink->Append(test_blending_draw_quad.PassAs<DrawQuad>(),
2777 append_quads_data);
2778 }
[email protected]94f206c12012-08-25 00:09:142779
[email protected]aa043632013-03-25 03:39:422780 void SetExpectation(bool blend, bool has_render_surface) {
2781 blend_ = blend;
2782 has_render_surface_ = has_render_surface;
2783 quads_appended_ = false;
2784 }
[email protected]94f206c12012-08-25 00:09:142785
[email protected]aa043632013-03-25 03:39:422786 bool quads_appended() const { return quads_appended_; }
[email protected]94f206c12012-08-25 00:09:142787
[email protected]aa043632013-03-25 03:39:422788 void SetQuadRect(gfx::Rect rect) { quad_rect_ = rect; }
2789 void SetQuadVisibleRect(gfx::Rect rect) { quad_visible_rect_ = rect; }
2790 void SetOpaqueContentRect(gfx::Rect rect) { opaque_content_rect_ = rect; }
[email protected]94f206c12012-08-25 00:09:142791
[email protected]aa043632013-03-25 03:39:422792 private:
2793 BlendStateCheckLayer(LayerTreeImpl* tree_impl,
2794 int id,
2795 ResourceProvider* resource_provider)
2796 : LayerImpl(tree_impl, id),
2797 blend_(false),
2798 has_render_surface_(false),
2799 quads_appended_(false),
2800 quad_rect_(5, 5, 5, 5),
2801 quad_visible_rect_(5, 5, 5, 5),
2802 resource_id_(resource_provider->CreateResource(
2803 gfx::Size(1, 1),
[email protected]efa48412013-09-05 15:30:162804 GL_CLAMP_TO_EDGE,
[email protected]27a41fe2013-09-19 05:05:142805 ResourceProvider::TextureUsageAny,
2806 RGBA_8888)) {
[email protected]aa043632013-03-25 03:39:422807 resource_provider->AllocateForTesting(resource_id_);
2808 SetAnchorPoint(gfx::PointF());
2809 SetBounds(gfx::Size(10, 10));
2810 SetContentBounds(gfx::Size(10, 10));
2811 SetDrawsContent(true);
2812 }
[email protected]94f206c12012-08-25 00:09:142813
[email protected]aa043632013-03-25 03:39:422814 bool blend_;
2815 bool has_render_surface_;
2816 bool quads_appended_;
2817 gfx::Rect quad_rect_;
2818 gfx::Rect opaque_content_rect_;
2819 gfx::Rect quad_visible_rect_;
2820 ResourceProvider::ResourceId resource_id_;
[email protected]94f206c12012-08-25 00:09:142821};
2822
[email protected]aa043632013-03-25 03:39:422823TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
2824 {
2825 scoped_ptr<LayerImpl> root =
2826 LayerImpl::Create(host_impl_->active_tree(), 1);
2827 root->SetAnchorPoint(gfx::PointF());
2828 root->SetBounds(gfx::Size(10, 10));
2829 root->SetContentBounds(root->bounds());
2830 root->SetDrawsContent(false);
2831 host_impl_->active_tree()->SetRootLayer(root.Pass());
2832 }
2833 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:142834
[email protected]aa043632013-03-25 03:39:422835 root->AddChild(
2836 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2837 2,
2838 host_impl_->resource_provider()));
2839 BlendStateCheckLayer* layer1 =
2840 static_cast<BlendStateCheckLayer*>(root->children()[0]);
2841 layer1->SetPosition(gfx::PointF(2.f, 2.f));
[email protected]94f206c12012-08-25 00:09:142842
[email protected]aa043632013-03-25 03:39:422843 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:142844
[email protected]aa043632013-03-25 03:39:422845 // Opaque layer, drawn without blending.
2846 layer1->SetContentsOpaque(true);
2847 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202848 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2849 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462850 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422851 EXPECT_TRUE(layer1->quads_appended());
2852 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142853
[email protected]aa043632013-03-25 03:39:422854 // Layer with translucent content and painting, so drawn with blending.
2855 layer1->SetContentsOpaque(false);
2856 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202857 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2858 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462859 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422860 EXPECT_TRUE(layer1->quads_appended());
2861 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142862
[email protected]aa043632013-03-25 03:39:422863 // Layer with translucent opacity, drawn with blending.
2864 layer1->SetContentsOpaque(true);
2865 layer1->SetOpacity(0.5f);
2866 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202867 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2868 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462869 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422870 EXPECT_TRUE(layer1->quads_appended());
2871 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142872
[email protected]aa043632013-03-25 03:39:422873 // Layer with translucent opacity and painting, drawn with blending.
2874 layer1->SetContentsOpaque(true);
2875 layer1->SetOpacity(0.5f);
2876 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202877 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2878 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462879 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422880 EXPECT_TRUE(layer1->quads_appended());
2881 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142882
[email protected]aa043632013-03-25 03:39:422883 layer1->AddChild(
2884 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2885 3,
2886 host_impl_->resource_provider()));
2887 BlendStateCheckLayer* layer2 =
2888 static_cast<BlendStateCheckLayer*>(layer1->children()[0]);
2889 layer2->SetPosition(gfx::PointF(4.f, 4.f));
[email protected]94f206c12012-08-25 00:09:142890
[email protected]aa043632013-03-25 03:39:422891 // 2 opaque layers, drawn without blending.
2892 layer1->SetContentsOpaque(true);
2893 layer1->SetOpacity(1.f);
2894 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202895 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422896 layer2->SetContentsOpaque(true);
2897 layer2->SetOpacity(1.f);
2898 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202899 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2900 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462901 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422902 EXPECT_TRUE(layer1->quads_appended());
2903 EXPECT_TRUE(layer2->quads_appended());
2904 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142905
[email protected]aa043632013-03-25 03:39:422906 // Parent layer with translucent content, drawn with blending.
2907 // Child layer with opaque content, drawn without blending.
2908 layer1->SetContentsOpaque(false);
2909 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202910 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422911 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202912 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2913 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462914 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422915 EXPECT_TRUE(layer1->quads_appended());
2916 EXPECT_TRUE(layer2->quads_appended());
2917 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142918
[email protected]aa043632013-03-25 03:39:422919 // Parent layer with translucent content but opaque painting, drawn without
2920 // blending.
2921 // Child layer with opaque content, drawn without blending.
2922 layer1->SetContentsOpaque(true);
2923 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202924 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422925 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202926 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2927 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462928 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422929 EXPECT_TRUE(layer1->quads_appended());
2930 EXPECT_TRUE(layer2->quads_appended());
2931 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142932
[email protected]aa043632013-03-25 03:39:422933 // Parent layer with translucent opacity and opaque content. Since it has a
2934 // drawing child, it's drawn to a render surface which carries the opacity,
2935 // so it's itself drawn without blending.
2936 // Child layer with opaque content, drawn without blending (parent surface
2937 // carries the inherited opacity).
2938 layer1->SetContentsOpaque(true);
2939 layer1->SetOpacity(0.5f);
2940 layer1->SetExpectation(false, true);
[email protected]e0341352013-04-06 05:01:202941 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422942 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202943 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2944 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462945 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422946 EXPECT_TRUE(layer1->quads_appended());
2947 EXPECT_TRUE(layer2->quads_appended());
2948 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142949
[email protected]aa043632013-03-25 03:39:422950 // Draw again, but with child non-opaque, to make sure
2951 // layer1 not culled.
2952 layer1->SetContentsOpaque(true);
2953 layer1->SetOpacity(1.f);
2954 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202955 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422956 layer2->SetContentsOpaque(true);
2957 layer2->SetOpacity(0.5f);
2958 layer2->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202959 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2960 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462961 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422962 EXPECT_TRUE(layer1->quads_appended());
2963 EXPECT_TRUE(layer2->quads_appended());
2964 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142965
[email protected]aa043632013-03-25 03:39:422966 // A second way of making the child non-opaque.
2967 layer1->SetContentsOpaque(true);
2968 layer1->SetOpacity(1.f);
2969 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202970 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422971 layer2->SetContentsOpaque(false);
2972 layer2->SetOpacity(1.f);
2973 layer2->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202974 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2975 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462976 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422977 EXPECT_TRUE(layer1->quads_appended());
2978 EXPECT_TRUE(layer2->quads_appended());
2979 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142980
[email protected]aa043632013-03-25 03:39:422981 // And when the layer says its not opaque but is painted opaque, it is not
2982 // blended.
2983 layer1->SetContentsOpaque(true);
2984 layer1->SetOpacity(1.f);
2985 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202986 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422987 layer2->SetContentsOpaque(true);
2988 layer2->SetOpacity(1.f);
2989 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202990 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2991 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462992 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422993 EXPECT_TRUE(layer1->quads_appended());
2994 EXPECT_TRUE(layer2->quads_appended());
2995 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142996
[email protected]aa043632013-03-25 03:39:422997 // Layer with partially opaque contents, drawn with blending.
2998 layer1->SetContentsOpaque(false);
2999 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3000 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
3001 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3002 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:203003 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3004 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463005 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423006 EXPECT_TRUE(layer1->quads_appended());
3007 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143008
[email protected]aa043632013-03-25 03:39:423009 // Layer with partially opaque contents partially culled, drawn with blending.
3010 layer1->SetContentsOpaque(false);
3011 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3012 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
3013 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3014 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:203015 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3016 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463017 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423018 EXPECT_TRUE(layer1->quads_appended());
3019 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143020
[email protected]aa043632013-03-25 03:39:423021 // Layer with partially opaque contents culled, drawn with blending.
3022 layer1->SetContentsOpaque(false);
3023 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3024 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
3025 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3026 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:203027 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3028 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463029 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423030 EXPECT_TRUE(layer1->quads_appended());
3031 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143032
[email protected]aa043632013-03-25 03:39:423033 // Layer with partially opaque contents and translucent contents culled, drawn
3034 // without blending.
3035 layer1->SetContentsOpaque(false);
3036 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3037 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
3038 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3039 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:203040 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3041 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463042 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423043 EXPECT_TRUE(layer1->quads_appended());
3044 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143045}
3046
[email protected]6133cc232013-07-30 18:47:073047class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
[email protected]ce2e8112013-11-28 07:44:363048 protected:
[email protected]9f4f6a32013-09-04 21:35:123049 LayerTreeHostImplViewportCoveredTest() :
3050 gutter_quad_material_(DrawQuad::SOLID_COLOR),
3051 child_(NULL),
3052 did_activate_pending_tree_(false) {}
3053
[email protected]ce2e8112013-11-28 07:44:363054 scoped_ptr<OutputSurface> CreateFakeOutputSurface(bool always_draw) {
3055 if (always_draw) {
3056 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d()
3057 .PassAs<OutputSurface>();
3058 }
3059 return FakeOutputSurface::Create3d().PassAs<OutputSurface>();
[email protected]6133cc232013-07-30 18:47:073060 }
[email protected]94f206c12012-08-25 00:09:143061
[email protected]6133cc232013-07-30 18:47:073062 void SetupActiveTreeLayers() {
3063 host_impl_->active_tree()->set_background_color(SK_ColorGRAY);
3064 host_impl_->active_tree()->SetRootLayer(
3065 LayerImpl::Create(host_impl_->active_tree(), 1));
3066 host_impl_->active_tree()->root_layer()->AddChild(
3067 BlendStateCheckLayer::Create(host_impl_->active_tree(),
3068 2,
3069 host_impl_->resource_provider()));
3070 child_ = static_cast<BlendStateCheckLayer*>(
3071 host_impl_->active_tree()->root_layer()->children()[0]);
3072 child_->SetExpectation(false, false);
3073 child_->SetContentsOpaque(true);
3074 }
[email protected]94f206c12012-08-25 00:09:143075
[email protected]6133cc232013-07-30 18:47:073076 // Expect no gutter rects.
3077 void TestLayerCoversFullViewport() {
3078 gfx::Rect layer_rect(viewport_size_);
3079 child_->SetPosition(layer_rect.origin());
3080 child_->SetBounds(layer_rect.size());
3081 child_->SetContentBounds(layer_rect.size());
3082 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3083 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:143084
[email protected]aa043632013-03-25 03:39:423085 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203086 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423087 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143088
[email protected]9f4f6a32013-09-04 21:35:123089 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:423090 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123091 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:143092
[email protected]9f4f6a32013-09-04 21:35:123093 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:423094 host_impl_->DidDrawAllLayers(frame);
3095 }
[email protected]94f206c12012-08-25 00:09:143096
[email protected]6133cc232013-07-30 18:47:073097 // Expect fullscreen gutter rect.
3098 void TestEmptyLayer() {
[email protected]aa043632013-03-25 03:39:423099 gfx::Rect layer_rect(0, 0, 0, 0);
[email protected]6133cc232013-07-30 18:47:073100 child_->SetPosition(layer_rect.origin());
3101 child_->SetBounds(layer_rect.size());
3102 child_->SetContentBounds(layer_rect.size());
3103 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3104 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:143105
[email protected]aa043632013-03-25 03:39:423106 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203107 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423108 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143109
[email protected]9f4f6a32013-09-04 21:35:123110 EXPECT_EQ(1u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:423111 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123112 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:143113
[email protected]9f4f6a32013-09-04 21:35:123114 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:423115 host_impl_->DidDrawAllLayers(frame);
3116 }
[email protected]94f206c12012-08-25 00:09:143117
[email protected]6133cc232013-07-30 18:47:073118 // Expect four surrounding gutter rects.
3119 void TestLayerInMiddleOfViewport() {
[email protected]aa043632013-03-25 03:39:423120 gfx::Rect layer_rect(500, 500, 200, 200);
[email protected]6133cc232013-07-30 18:47:073121 child_->SetPosition(layer_rect.origin());
3122 child_->SetBounds(layer_rect.size());
3123 child_->SetContentBounds(layer_rect.size());
3124 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3125 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:143126
[email protected]aa043632013-03-25 03:39:423127 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203128 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423129 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143130
[email protected]9f4f6a32013-09-04 21:35:123131 EXPECT_EQ(4u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:423132 EXPECT_EQ(5u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123133 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:143134
[email protected]9f4f6a32013-09-04 21:35:123135 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:423136 host_impl_->DidDrawAllLayers(frame);
3137 }
[email protected]6133cc232013-07-30 18:47:073138
3139 // Expect no gutter rects.
3140 void TestLayerIsLargerThanViewport() {
3141 gfx::Rect layer_rect(viewport_size_.width() + 10,
3142 viewport_size_.height() + 10);
3143 child_->SetPosition(layer_rect.origin());
3144 child_->SetBounds(layer_rect.size());
3145 child_->SetContentBounds(layer_rect.size());
3146 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3147 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
3148
3149 LayerTreeHostImpl::FrameData frame;
3150 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
3151 ASSERT_EQ(1u, frame.render_passes.size());
3152
[email protected]9f4f6a32013-09-04 21:35:123153 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]6133cc232013-07-30 18:47:073154 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123155 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]6133cc232013-07-30 18:47:073156
3157 host_impl_->DidDrawAllLayers(frame);
3158 }
3159
3160 virtual void DidActivatePendingTree() OVERRIDE {
3161 did_activate_pending_tree_ = true;
3162 }
3163
[email protected]9f4f6a32013-09-04 21:35:123164 void set_gutter_quad_material(DrawQuad::Material material) {
3165 gutter_quad_material_ = material;
3166 }
3167 void set_gutter_texture_size(gfx::Size gutter_texture_size) {
3168 gutter_texture_size_ = gutter_texture_size;
3169 }
3170
[email protected]6133cc232013-07-30 18:47:073171 protected:
[email protected]9f4f6a32013-09-04 21:35:123172 size_t CountGutterQuads(const QuadList& quad_list) {
3173 size_t num_gutter_quads = 0;
3174 for (size_t i = 0; i < quad_list.size(); ++i) {
3175 num_gutter_quads += (quad_list[i]->material ==
3176 gutter_quad_material_) ? 1 : 0;
3177 }
3178 return num_gutter_quads;
3179 }
3180
3181 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) {
3182 LayerTestCommon::VerifyQuadsExactlyCoverRect(
3183 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_)));
3184 }
3185
3186 // Make sure that the texture coordinates match their expectations.
3187 void ValidateTextureDrawQuads(const QuadList& quad_list) {
3188 for (size_t i = 0; i < quad_list.size(); ++i) {
3189 if (quad_list[i]->material != DrawQuad::TEXTURE_CONTENT)
3190 continue;
3191 const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(quad_list[i]);
3192 gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize(
3193 gutter_texture_size_, host_impl_->device_scale_factor());
3194 EXPECT_EQ(quad->uv_top_left.x(),
3195 quad->rect.x() / gutter_texture_size_pixels.width());
3196 EXPECT_EQ(quad->uv_top_left.y(),
3197 quad->rect.y() / gutter_texture_size_pixels.height());
3198 EXPECT_EQ(quad->uv_bottom_right.x(),
3199 quad->rect.right() / gutter_texture_size_pixels.width());
3200 EXPECT_EQ(quad->uv_bottom_right.y(),
3201 quad->rect.bottom() / gutter_texture_size_pixels.height());
3202 }
3203 }
3204
3205 gfx::Size DipSizeToPixelSize(gfx::Size size) {
3206 return gfx::ToRoundedSize(
3207 gfx::ScaleSize(size, host_impl_->device_scale_factor()));
3208 }
3209
3210 DrawQuad::Material gutter_quad_material_;
3211 gfx::Size gutter_texture_size_;
[email protected]6133cc232013-07-30 18:47:073212 gfx::Size viewport_size_;
3213 BlendStateCheckLayer* child_;
3214 bool did_activate_pending_tree_;
3215};
3216
3217TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) {
[email protected]ce2e8112013-11-28 07:44:363218 viewport_size_ = gfx::Size(1000, 1000);
3219
[email protected]6133cc232013-07-30 18:47:073220 bool always_draw = false;
[email protected]ce2e8112013-11-28 07:44:363221 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
[email protected]6133cc232013-07-30 18:47:073222
[email protected]9f4f6a32013-09-04 21:35:123223 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073224 SetupActiveTreeLayers();
3225 TestLayerCoversFullViewport();
3226 TestEmptyLayer();
3227 TestLayerInMiddleOfViewport();
3228 TestLayerIsLargerThanViewport();
[email protected]94f206c12012-08-25 00:09:143229}
3230
[email protected]9f4f6a32013-09-04 21:35:123231TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
[email protected]ce2e8112013-11-28 07:44:363232 viewport_size_ = gfx::Size(1000, 1000);
3233
[email protected]9f4f6a32013-09-04 21:35:123234 bool always_draw = false;
[email protected]ce2e8112013-11-28 07:44:363235 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
[email protected]9f4f6a32013-09-04 21:35:123236
3237 host_impl_->SetDeviceScaleFactor(2.f);
3238 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3239 SetupActiveTreeLayers();
3240 TestLayerCoversFullViewport();
3241 TestEmptyLayer();
3242 TestLayerInMiddleOfViewport();
3243 TestLayerIsLargerThanViewport();
3244}
3245
3246TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
[email protected]ce2e8112013-11-28 07:44:363247 viewport_size_ = gfx::Size(1000, 1000);
3248
[email protected]9f4f6a32013-09-04 21:35:123249 bool always_draw = false;
[email protected]ce2e8112013-11-28 07:44:363250 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
[email protected]9f4f6a32013-09-04 21:35:123251
3252 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3253 SetupActiveTreeLayers();
3254
[email protected]741fba422013-09-20 03:34:143255 SkBitmap skbitmap;
3256 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
3257 skbitmap.allocPixels();
3258 skbitmap.setImmutable();
3259
[email protected]9f4f6a32013-09-04 21:35:123260 // Specify an overhang bitmap to use.
[email protected]e0a601e2013-10-24 04:30:303261 UIResourceBitmap ui_resource_bitmap(skbitmap);
3262 ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
[email protected]9f4f6a32013-09-04 21:35:123263 UIResourceId ui_resource_id = 12345;
3264 host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
3265 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
3266 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT);
3267 set_gutter_texture_size(gfx::Size(32, 32));
3268
3269 TestLayerCoversFullViewport();
3270 TestEmptyLayer();
3271 TestLayerInMiddleOfViewport();
3272 TestLayerIsLargerThanViewport();
3273
3274 // Change the resource size.
3275 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16));
3276 set_gutter_texture_size(gfx::Size(128, 16));
3277
3278 TestLayerCoversFullViewport();
3279 TestEmptyLayer();
3280 TestLayerInMiddleOfViewport();
3281 TestLayerIsLargerThanViewport();
3282
3283 // Change the device scale factor
3284 host_impl_->SetDeviceScaleFactor(2.f);
3285 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3286
3287 TestLayerCoversFullViewport();
3288 TestEmptyLayer();
3289 TestLayerInMiddleOfViewport();
3290 TestLayerIsLargerThanViewport();
3291}
3292
[email protected]6133cc232013-07-30 18:47:073293TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
[email protected]ce2e8112013-11-28 07:44:363294 viewport_size_ = gfx::Size(1000, 1000);
3295
[email protected]6133cc232013-07-30 18:47:073296 bool always_draw = true;
[email protected]ce2e8112013-11-28 07:44:363297 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
[email protected]6133cc232013-07-30 18:47:073298
3299 // Pending tree to force active_tree size invalid. Not used otherwise.
3300 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:123301 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073302 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
3303
3304 SetupActiveTreeLayers();
3305 TestEmptyLayer();
3306 TestLayerInMiddleOfViewport();
3307 TestLayerIsLargerThanViewport();
3308}
3309
3310TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) {
[email protected]ce2e8112013-11-28 07:44:363311 viewport_size_ = gfx::Size(1000, 1000);
3312
[email protected]6133cc232013-07-30 18:47:073313 bool always_draw = true;
[email protected]ce2e8112013-11-28 07:44:363314 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
[email protected]6133cc232013-07-30 18:47:073315
3316 // Set larger viewport and activate it to active tree.
3317 host_impl_->CreatePendingTree();
3318 gfx::Size larger_viewport(viewport_size_.width() + 100,
3319 viewport_size_.height() + 100);
[email protected]9f4f6a32013-09-04 21:35:123320 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport));
[email protected]6133cc232013-07-30 18:47:073321 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
[email protected]4f48f6e2013-08-27 06:33:383322 host_impl_->ActivatePendingTree();
[email protected]6133cc232013-07-30 18:47:073323 EXPECT_TRUE(did_activate_pending_tree_);
3324 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid());
3325
3326 // Shrink pending tree viewport without activating.
3327 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:123328 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073329 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
3330
3331 SetupActiveTreeLayers();
3332 TestEmptyLayer();
3333 TestLayerInMiddleOfViewport();
3334 TestLayerIsLargerThanViewport();
3335}
[email protected]94f206c12012-08-25 00:09:143336
[email protected]96baf3e2012-10-22 23:09:553337class FakeDrawableLayerImpl: public LayerImpl {
[email protected]aa043632013-03-25 03:39:423338 public:
3339 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3340 return scoped_ptr<LayerImpl>(new FakeDrawableLayerImpl(tree_impl, id));
3341 }
3342 protected:
3343 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id)
3344 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:143345};
3346
3347// Only reshape when we know we are going to draw. Otherwise, the reshape
3348// can leave the window at the wrong size if we never draw and the proper
3349// viewport size is never set.
[email protected]aa043632013-03-25 03:39:423350TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
[email protected]4bf41752013-11-05 01:34:323351 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
3352 scoped_ptr<OutputSurface> output_surface(
3353 FakeOutputSurface::Create3d(provider));
[email protected]ce2e8112013-11-28 07:44:363354 CreateHostImpl(DefaultSettings(), output_surface.Pass());
[email protected]94f206c12012-08-25 00:09:143355
[email protected]aa043632013-03-25 03:39:423356 scoped_ptr<LayerImpl> root =
3357 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
3358 root->SetAnchorPoint(gfx::PointF());
3359 root->SetBounds(gfx::Size(10, 10));
[email protected]e0341352013-04-06 05:01:203360 root->SetContentBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423361 root->SetDrawsContent(true);
3362 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]4bf41752013-11-05 01:34:323363 EXPECT_FALSE(provider->TestContext3d()->reshape_called());
3364 provider->TestContext3d()->clear_reshape_called();
[email protected]94f206c12012-08-25 00:09:143365
[email protected]aa043632013-03-25 03:39:423366 LayerTreeHostImpl::FrameData frame;
[email protected]94c40e6292013-05-24 22:01:503367 host_impl_->SetViewportSize(gfx::Size(10, 10));
3368 host_impl_->SetDeviceScaleFactor(1.f);
[email protected]e0341352013-04-06 05:01:203369 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463370 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]4bf41752013-11-05 01:34:323371 EXPECT_TRUE(provider->TestContext3d()->reshape_called());
3372 EXPECT_EQ(provider->TestContext3d()->width(), 10);
3373 EXPECT_EQ(provider->TestContext3d()->height(), 10);
3374 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f);
[email protected]aa043632013-03-25 03:39:423375 host_impl_->DidDrawAllLayers(frame);
[email protected]4bf41752013-11-05 01:34:323376 provider->TestContext3d()->clear_reshape_called();
[email protected]94c40e6292013-05-24 22:01:503377
3378 host_impl_->SetViewportSize(gfx::Size(20, 30));
3379 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463380 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]4bf41752013-11-05 01:34:323381 EXPECT_TRUE(provider->TestContext3d()->reshape_called());
3382 EXPECT_EQ(provider->TestContext3d()->width(), 20);
3383 EXPECT_EQ(provider->TestContext3d()->height(), 30);
3384 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f);
[email protected]94c40e6292013-05-24 22:01:503385 host_impl_->DidDrawAllLayers(frame);
[email protected]4bf41752013-11-05 01:34:323386 provider->TestContext3d()->clear_reshape_called();
[email protected]94c40e6292013-05-24 22:01:503387
3388 host_impl_->SetDeviceScaleFactor(2.f);
3389 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463390 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]4bf41752013-11-05 01:34:323391 EXPECT_TRUE(provider->TestContext3d()->reshape_called());
3392 EXPECT_EQ(provider->TestContext3d()->width(), 20);
3393 EXPECT_EQ(provider->TestContext3d()->height(), 30);
3394 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 2.f);
[email protected]94c40e6292013-05-24 22:01:503395 host_impl_->DidDrawAllLayers(frame);
[email protected]4bf41752013-11-05 01:34:323396 provider->TestContext3d()->clear_reshape_called();
[email protected]94f206c12012-08-25 00:09:143397}
3398
[email protected]94f206c12012-08-25 00:09:143399// Make sure damage tracking propagates all the way to the graphics context,
[email protected]aa043632013-03-25 03:39:423400// where it should request to swap only the sub-buffer that is damaged.
3401TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
[email protected]4bf41752013-11-05 01:34:323402 scoped_refptr<TestContextProvider> provider(
3403 TestContextProvider::Create());
3404 scoped_ptr<OutputSurface> output_surface(
3405 FakeOutputSurface::Create3d(provider));
[email protected]0634cdd42013-08-16 00:46:093406
[email protected]4bf41752013-11-05 01:34:323407 provider->BindToCurrentThread();
3408 TestWebGraphicsContext3D* context = provider->TestContext3d();
3409 context->set_have_post_sub_buffer(true);
[email protected]94f206c12012-08-25 00:09:143410
[email protected]aa043632013-03-25 03:39:423411 // This test creates its own LayerTreeHostImpl, so
3412 // that we can force partial swap enabled.
3413 LayerTreeSettings settings;
3414 settings.partial_swap_enabled = true;
3415 scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl =
[email protected]a7f35682013-10-22 23:05:573416 LayerTreeHostImpl::Create(
3417 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]aa043632013-03-25 03:39:423418 layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403419 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
[email protected]94f206c12012-08-25 00:09:143420
[email protected]aa043632013-03-25 03:39:423421 scoped_ptr<LayerImpl> root =
3422 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
3423 scoped_ptr<LayerImpl> child =
3424 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
3425 child->SetPosition(gfx::PointF(12.f, 13.f));
3426 child->SetAnchorPoint(gfx::PointF());
3427 child->SetBounds(gfx::Size(14, 15));
3428 child->SetContentBounds(gfx::Size(14, 15));
3429 child->SetDrawsContent(true);
3430 root->SetAnchorPoint(gfx::PointF());
3431 root->SetBounds(gfx::Size(500, 500));
3432 root->SetContentBounds(gfx::Size(500, 500));
3433 root->SetDrawsContent(true);
3434 root->AddChild(child.Pass());
3435 layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143436
[email protected]aa043632013-03-25 03:39:423437 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143438
[email protected]aa043632013-03-25 03:39:423439 // First frame, the entire screen should get swapped.
[email protected]e0341352013-04-06 05:01:203440 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463441 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423442 layer_tree_host_impl->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203443 layer_tree_host_impl->SwapBuffers(frame);
[email protected]4bf41752013-11-05 01:34:323444 gfx::Rect actual_swap_rect = context->update_rect();
[email protected]aa043632013-03-25 03:39:423445 gfx::Rect expected_swap_rect = gfx::Rect(0, 0, 500, 500);
3446 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3447 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3448 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3449 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]4bf41752013-11-05 01:34:323450 EXPECT_EQ(context->last_update_type(),
3451 TestWebGraphicsContext3D::PrepareTexture);
[email protected]aa043632013-03-25 03:39:423452 // Second frame, only the damaged area should get swapped. Damage should be
3453 // the union of old and new child rects.
3454 // expected damage rect: gfx::Rect(26, 28);
3455 // expected swap rect: vertically flipped, with origin at bottom left corner.
3456 layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
3457 gfx::PointF());
[email protected]e0341352013-04-06 05:01:203458 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463459 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423460 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203461 layer_tree_host_impl->SwapBuffers(frame);
[email protected]4bf41752013-11-05 01:34:323462 actual_swap_rect = context->update_rect();
[email protected]aa043632013-03-25 03:39:423463 expected_swap_rect = gfx::Rect(0, 500-28, 26, 28);
3464 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3465 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3466 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3467 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]4bf41752013-11-05 01:34:323468 EXPECT_EQ(context->last_update_type(),
3469 TestWebGraphicsContext3D::PostSubBuffer);
[email protected]94f206c12012-08-25 00:09:143470
[email protected]aa043632013-03-25 03:39:423471 // Make sure that partial swap is constrained to the viewport dimensions
3472 // expected damage rect: gfx::Rect(500, 500);
3473 // expected swap rect: flipped damage rect, but also clamped to viewport
[email protected]18ce59702013-04-09 04:58:403474 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423475 // This will damage everything.
[email protected]35a99a12013-05-09 23:52:293476 layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor(
3477 SK_ColorBLACK);
[email protected]e0341352013-04-06 05:01:203478 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463479 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423480 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203481 layer_tree_host_impl->SwapBuffers(frame);
[email protected]4bf41752013-11-05 01:34:323482 actual_swap_rect = context->update_rect();
[email protected]aa043632013-03-25 03:39:423483 expected_swap_rect = gfx::Rect(10, 10);
3484 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3485 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3486 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3487 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]4bf41752013-11-05 01:34:323488 EXPECT_EQ(context->last_update_type(),
3489 TestWebGraphicsContext3D::PrepareTexture);
[email protected]94f206c12012-08-25 00:09:143490}
3491
[email protected]aa043632013-03-25 03:39:423492TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
3493 scoped_ptr<LayerImpl> root =
3494 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
3495 scoped_ptr<LayerImpl> child =
3496 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
3497 child->SetAnchorPoint(gfx::PointF());
3498 child->SetBounds(gfx::Size(10, 10));
3499 child->SetContentBounds(gfx::Size(10, 10));
3500 child->SetDrawsContent(true);
3501 root->SetAnchorPoint(gfx::PointF());
3502 root->SetBounds(gfx::Size(10, 10));
3503 root->SetContentBounds(gfx::Size(10, 10));
3504 root->SetDrawsContent(true);
[email protected]35a99a12013-05-09 23:52:293505 root->SetForceRenderSurface(true);
[email protected]aa043632013-03-25 03:39:423506 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:143507
[email protected]aa043632013-03-25 03:39:423508 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143509
[email protected]aa043632013-03-25 03:39:423510 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143511
[email protected]e0341352013-04-06 05:01:203512 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423513 EXPECT_EQ(1u, frame.render_surface_layer_list->size());
3514 EXPECT_EQ(1u, frame.render_passes.size());
3515 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143516}
3517
[email protected]96baf3e2012-10-22 23:09:553518class FakeLayerWithQuads : public LayerImpl {
[email protected]aa043632013-03-25 03:39:423519 public:
3520 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3521 return scoped_ptr<LayerImpl>(new FakeLayerWithQuads(tree_impl, id));
3522 }
[email protected]94f206c12012-08-25 00:09:143523
[email protected]aa043632013-03-25 03:39:423524 virtual void AppendQuads(QuadSink* quad_sink,
3525 AppendQuadsData* append_quads_data) OVERRIDE {
3526 SharedQuadState* shared_quad_state =
3527 quad_sink->UseSharedQuadState(CreateSharedQuadState());
[email protected]94f206c12012-08-25 00:09:143528
[email protected]aa043632013-03-25 03:39:423529 SkColor gray = SkColorSetRGB(100, 100, 100);
[email protected]2c7c6702013-03-26 03:14:053530 gfx::Rect quad_rect(content_bounds());
[email protected]aa043632013-03-25 03:39:423531 scoped_ptr<SolidColorDrawQuad> my_quad = SolidColorDrawQuad::Create();
[email protected]10a30b12013-05-02 16:42:113532 my_quad->SetNew(shared_quad_state, quad_rect, gray, false);
[email protected]aa043632013-03-25 03:39:423533 quad_sink->Append(my_quad.PassAs<DrawQuad>(), append_quads_data);
3534 }
[email protected]94f206c12012-08-25 00:09:143535
[email protected]aa043632013-03-25 03:39:423536 private:
3537 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id)
3538 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:143539};
3540
[email protected]c8756fbe2013-02-12 01:53:493541class MockContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423542 public:
[email protected]c32e27082013-11-07 06:58:203543 MOCK_METHOD1(useProgram, void(blink::WebGLId program));
3544 MOCK_METHOD5(uniform4f, void(blink::WGC3Dint location,
3545 blink::WGC3Dfloat x,
3546 blink::WGC3Dfloat y,
3547 blink::WGC3Dfloat z,
3548 blink::WGC3Dfloat w));
3549 MOCK_METHOD4(uniformMatrix4fv, void(blink::WGC3Dint location,
3550 blink::WGC3Dsizei count,
3551 blink::WGC3Dboolean transpose,
3552 const blink::WGC3Dfloat* value));
3553 MOCK_METHOD4(drawElements, void(blink::WGC3Denum mode,
3554 blink::WGC3Dsizei count,
3555 blink::WGC3Denum type,
3556 blink::WGC3Dintptr offset));
3557 MOCK_METHOD0(getRequestableExtensionsCHROMIUM, blink::WebString());
3558 MOCK_METHOD1(enable, void(blink::WGC3Denum cap));
3559 MOCK_METHOD1(disable, void(blink::WGC3Denum cap));
3560 MOCK_METHOD4(scissor, void(blink::WGC3Dint x,
3561 blink::WGC3Dint y,
3562 blink::WGC3Dsizei width,
3563 blink::WGC3Dsizei height));
[email protected]94f206c12012-08-25 00:09:143564};
3565
3566class MockContextHarness {
[email protected]aa043632013-03-25 03:39:423567 private:
3568 MockContext* context_;
[email protected]bf691c22013-03-26 21:15:063569
[email protected]aa043632013-03-25 03:39:423570 public:
[email protected]bf691c22013-03-26 21:15:063571 explicit MockContextHarness(MockContext* context)
[email protected]aa043632013-03-25 03:39:423572 : context_(context) {
[email protected]41de22822013-08-29 04:16:173573 context_->set_have_post_sub_buffer(true);
3574
[email protected]aa043632013-03-25 03:39:423575 // Catch "uninteresting" calls
3576 EXPECT_CALL(*context_, useProgram(_))
3577 .Times(0);
[email protected]94f206c12012-08-25 00:09:143578
[email protected]aa043632013-03-25 03:39:423579 EXPECT_CALL(*context_, drawElements(_, _, _, _))
3580 .Times(0);
[email protected]94f206c12012-08-25 00:09:143581
[email protected]aa043632013-03-25 03:39:423582 // These are not asserted
3583 EXPECT_CALL(*context_, uniformMatrix4fv(_, _, _, _))
3584 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143585
[email protected]aa043632013-03-25 03:39:423586 EXPECT_CALL(*context_, uniform4f(_, _, _, _, _))
3587 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143588
[email protected]aa043632013-03-25 03:39:423589 // Any un-sanctioned calls to enable() are OK
3590 EXPECT_CALL(*context_, enable(_))
3591 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143592
[email protected]aa043632013-03-25 03:39:423593 // Any un-sanctioned calls to disable() are OK
3594 EXPECT_CALL(*context_, disable(_))
3595 .WillRepeatedly(Return());
3596 }
[email protected]94f206c12012-08-25 00:09:143597
[email protected]aa043632013-03-25 03:39:423598 void MustDrawSolidQuad() {
3599 EXPECT_CALL(*context_, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0))
3600 .WillOnce(Return())
3601 .RetiresOnSaturation();
[email protected]94f206c12012-08-25 00:09:143602
[email protected]aa043632013-03-25 03:39:423603 EXPECT_CALL(*context_, useProgram(_))
3604 .WillOnce(Return())
3605 .RetiresOnSaturation();
[email protected]aa043632013-03-25 03:39:423606 }
[email protected]94f206c12012-08-25 00:09:143607
[email protected]aa043632013-03-25 03:39:423608 void MustSetScissor(int x, int y, int width, int height) {
3609 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
3610 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143611
[email protected]aa043632013-03-25 03:39:423612 EXPECT_CALL(*context_, scissor(x, y, width, height))
3613 .Times(AtLeast(1))
3614 .WillRepeatedly(Return());
3615 }
[email protected]94f206c12012-08-25 00:09:143616
[email protected]aa043632013-03-25 03:39:423617 void MustSetNoScissor() {
3618 EXPECT_CALL(*context_, disable(GL_SCISSOR_TEST))
3619 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143620
[email protected]aa043632013-03-25 03:39:423621 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
3622 .Times(0);
[email protected]94f206c12012-08-25 00:09:143623
[email protected]aa043632013-03-25 03:39:423624 EXPECT_CALL(*context_, scissor(_, _, _, _))
3625 .Times(0);
3626 }
[email protected]94f206c12012-08-25 00:09:143627};
3628
[email protected]aa043632013-03-25 03:39:423629TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
[email protected]0634cdd42013-08-16 00:46:093630 scoped_ptr<MockContext> mock_context_owned(new MockContext);
3631 MockContext* mock_context = mock_context_owned.get();
3632
3633 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3634 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423635 MockContextHarness harness(mock_context);
[email protected]94f206c12012-08-25 00:09:143636
[email protected]aa043632013-03-25 03:39:423637 // Run test case
[email protected]ce2e8112013-11-28 07:44:363638 LayerTreeSettings settings = DefaultSettings();
3639 settings.partial_swap_enabled = false;
3640 CreateHostImpl(settings, output_surface.Pass());
[email protected]aa043632013-03-25 03:39:423641 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
[email protected]94f206c12012-08-25 00:09:143642
[email protected]aa043632013-03-25 03:39:423643 // Without partial swap, and no clipping, no scissor is set.
3644 harness.MustDrawSolidQuad();
3645 harness.MustSetNoScissor();
3646 {
3647 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203648 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463649 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423650 host_impl_->DidDrawAllLayers(frame);
3651 }
3652 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]dc462d782012-11-21 21:43:013653
[email protected]aa043632013-03-25 03:39:423654 // Without partial swap, but a layer does clip its subtree, one scissor is
3655 // set.
3656 host_impl_->active_tree()->root_layer()->SetMasksToBounds(true);
3657 harness.MustDrawSolidQuad();
3658 harness.MustSetScissor(0, 0, 10, 10);
3659 {
3660 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203661 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463662 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423663 host_impl_->DidDrawAllLayers(frame);
3664 }
3665 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143666}
3667
[email protected]aa043632013-03-25 03:39:423668TEST_F(LayerTreeHostImplTest, PartialSwap) {
[email protected]0634cdd42013-08-16 00:46:093669 scoped_ptr<MockContext> context_owned(new MockContext);
3670 MockContext* mock_context = context_owned.get();
3671 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3672 context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423673 MockContextHarness harness(mock_context);
[email protected]94f206c12012-08-25 00:09:143674
[email protected]ce2e8112013-11-28 07:44:363675 LayerTreeSettings settings = DefaultSettings();
3676 settings.partial_swap_enabled = true;
3677 CreateHostImpl(settings, output_surface.Pass());
[email protected]aa043632013-03-25 03:39:423678 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
[email protected]94f206c12012-08-25 00:09:143679
[email protected]aa043632013-03-25 03:39:423680 // The first frame is not a partially-swapped one.
3681 harness.MustSetScissor(0, 0, 10, 10);
3682 harness.MustDrawSolidQuad();
3683 {
3684 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203685 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463686 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423687 host_impl_->DidDrawAllLayers(frame);
3688 }
3689 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143690
[email protected]aa043632013-03-25 03:39:423691 // Damage a portion of the frame.
3692 host_impl_->active_tree()->root_layer()->set_update_rect(
3693 gfx::Rect(0, 0, 2, 3));
[email protected]94f206c12012-08-25 00:09:143694
[email protected]aa043632013-03-25 03:39:423695 // The second frame will be partially-swapped (the y coordinates are flipped).
3696 harness.MustSetScissor(0, 7, 2, 3);
3697 harness.MustDrawSolidQuad();
3698 {
3699 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203700 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463701 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423702 host_impl_->DidDrawAllLayers(frame);
3703 }
3704 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143705}
3706
[email protected]aa043632013-03-25 03:39:423707static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
3708 bool partial_swap,
3709 LayerTreeHostImplClient* client,
3710 Proxy* proxy,
3711 RenderingStatsInstrumentation* stats_instrumentation) {
[email protected]4bf41752013-11-05 01:34:323712 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
3713 scoped_ptr<OutputSurface> output_surface(
3714 FakeOutputSurface::Create3d(provider));
3715 provider->BindToCurrentThread();
3716 provider->TestContext3d()->set_have_post_sub_buffer(true);
[email protected]94f206c12012-08-25 00:09:143717
[email protected]aa043632013-03-25 03:39:423718 LayerTreeSettings settings;
3719 settings.partial_swap_enabled = partial_swap;
[email protected]a7f35682013-10-22 23:05:573720 scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
3721 settings, client, proxy, stats_instrumentation, NULL);
[email protected]aa043632013-03-25 03:39:423722 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403723 my_host_impl->SetViewportSize(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:143724
[email protected]aa043632013-03-25 03:39:423725 /*
3726 Layers are created as follows:
[email protected]94f206c12012-08-25 00:09:143727
[email protected]aa043632013-03-25 03:39:423728 +--------------------+
3729 | 1 |
3730 | +-----------+ |
3731 | | 2 | |
3732 | | +-------------------+
3733 | | | 3 |
3734 | | +-------------------+
3735 | | | |
3736 | +-----------+ |
3737 | |
3738 | |
3739 +--------------------+
[email protected]94f206c12012-08-25 00:09:143740
[email protected]aa043632013-03-25 03:39:423741 Layers 1, 2 have render surfaces
3742 */
3743 scoped_ptr<LayerImpl> root =
3744 LayerImpl::Create(my_host_impl->active_tree(), 1);
3745 scoped_ptr<LayerImpl> child =
3746 LayerImpl::Create(my_host_impl->active_tree(), 2);
3747 scoped_ptr<LayerImpl> grand_child =
3748 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3);
[email protected]94f206c12012-08-25 00:09:143749
[email protected]aa043632013-03-25 03:39:423750 gfx::Rect root_rect(0, 0, 100, 100);
3751 gfx::Rect child_rect(10, 10, 50, 50);
3752 gfx::Rect grand_child_rect(5, 5, 150, 150);
[email protected]94f206c12012-08-25 00:09:143753
[email protected]aa043632013-03-25 03:39:423754 root->CreateRenderSurface();
3755 root->SetAnchorPoint(gfx::PointF());
3756 root->SetPosition(root_rect.origin());
3757 root->SetBounds(root_rect.size());
3758 root->SetContentBounds(root->bounds());
3759 root->draw_properties().visible_content_rect = root_rect;
3760 root->SetDrawsContent(false);
3761 root->render_surface()->SetContentRect(gfx::Rect(root_rect.size()));
[email protected]94f206c12012-08-25 00:09:143762
[email protected]aa043632013-03-25 03:39:423763 child->SetAnchorPoint(gfx::PointF());
3764 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
3765 child->SetOpacity(0.5f);
3766 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
3767 child->SetContentBounds(child->bounds());
3768 child->draw_properties().visible_content_rect = child_rect;
3769 child->SetDrawsContent(false);
3770 child->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:143771
[email protected]aa043632013-03-25 03:39:423772 grand_child->SetAnchorPoint(gfx::PointF());
3773 grand_child->SetPosition(grand_child_rect.origin());
3774 grand_child->SetBounds(grand_child_rect.size());
3775 grand_child->SetContentBounds(grand_child->bounds());
3776 grand_child->draw_properties().visible_content_rect = grand_child_rect;
3777 grand_child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143778
[email protected]aa043632013-03-25 03:39:423779 child->AddChild(grand_child.Pass());
3780 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:143781
[email protected]aa043632013-03-25 03:39:423782 my_host_impl->active_tree()->SetRootLayer(root.Pass());
3783 return my_host_impl.Pass();
[email protected]94f206c12012-08-25 00:09:143784}
3785
[email protected]aa043632013-03-25 03:39:423786TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
3787 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3788 SetupLayersForOpacity(true, this, &proxy_, &stats_instrumentation_);
3789 {
3790 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203791 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143792
[email protected]aa043632013-03-25 03:39:423793 // Verify all quads have been computed
3794 ASSERT_EQ(2U, frame.render_passes.size());
3795 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
3796 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
3797 EXPECT_EQ(DrawQuad::SOLID_COLOR,
3798 frame.render_passes[0]->quad_list[0]->material);
3799 EXPECT_EQ(DrawQuad::RENDER_PASS,
3800 frame.render_passes[1]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:143801
[email protected]de2cf8c2013-10-25 19:46:463802 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423803 my_host_impl->DidDrawAllLayers(frame);
3804 }
[email protected]94f206c12012-08-25 00:09:143805}
3806
[email protected]aa043632013-03-25 03:39:423807TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
3808 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3809 SetupLayersForOpacity(false, this, &proxy_, &stats_instrumentation_);
3810 {
3811 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203812 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143813
[email protected]aa043632013-03-25 03:39:423814 // Verify all quads have been computed
3815 ASSERT_EQ(2U, frame.render_passes.size());
3816 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
3817 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
3818 EXPECT_EQ(DrawQuad::SOLID_COLOR,
3819 frame.render_passes[0]->quad_list[0]->material);
3820 EXPECT_EQ(DrawQuad::RENDER_PASS,
3821 frame.render_passes[1]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:143822
[email protected]de2cf8c2013-10-25 19:46:463823 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423824 my_host_impl->DidDrawAllLayers(frame);
3825 }
[email protected]94f206c12012-08-25 00:09:143826}
3827
[email protected]aa043632013-03-25 03:39:423828TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
3829 scoped_ptr<TestWebGraphicsContext3D> context =
3830 TestWebGraphicsContext3D::Create();
3831 TestWebGraphicsContext3D* context3d = context.get();
[email protected]0634cdd42013-08-16 00:46:093832 scoped_ptr<OutputSurface> output_surface(
3833 FakeOutputSurface::Create3d(context.Pass()));
[email protected]ce2e8112013-11-28 07:44:363834 CreateHostImpl(DefaultSettings(), output_surface.Pass());
[email protected]d993b602013-01-04 02:08:123835
[email protected]aa043632013-03-25 03:39:423836 scoped_ptr<LayerImpl> root_layer =
3837 LayerImpl::Create(host_impl_->active_tree(), 1);
3838 root_layer->SetBounds(gfx::Size(10, 10));
3839 root_layer->SetAnchorPoint(gfx::PointF());
[email protected]94f206c12012-08-25 00:09:143840
[email protected]aa043632013-03-25 03:39:423841 scoped_refptr<VideoFrame> softwareFrame =
3842 media::VideoFrame::CreateColorFrame(
3843 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
3844 FakeVideoFrameProvider provider;
3845 provider.set_frame(softwareFrame);
3846 scoped_ptr<VideoLayerImpl> video_layer =
3847 VideoLayerImpl::Create(host_impl_->active_tree(), 4, &provider);
3848 video_layer->SetBounds(gfx::Size(10, 10));
3849 video_layer->SetAnchorPoint(gfx::PointF());
3850 video_layer->SetContentBounds(gfx::Size(10, 10));
3851 video_layer->SetDrawsContent(true);
3852 root_layer->AddChild(video_layer.PassAs<LayerImpl>());
[email protected]94f206c12012-08-25 00:09:143853
[email protected]aa043632013-03-25 03:39:423854 scoped_ptr<IOSurfaceLayerImpl> io_surface_layer =
3855 IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5);
3856 io_surface_layer->SetBounds(gfx::Size(10, 10));
3857 io_surface_layer->SetAnchorPoint(gfx::PointF());
3858 io_surface_layer->SetContentBounds(gfx::Size(10, 10));
3859 io_surface_layer->SetDrawsContent(true);
3860 io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10));
3861 root_layer->AddChild(io_surface_layer.PassAs<LayerImpl>());
[email protected]94f206c12012-08-25 00:09:143862
[email protected]aa043632013-03-25 03:39:423863 host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
[email protected]94f206c12012-08-25 00:09:143864
[email protected]aa043632013-03-25 03:39:423865 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]d993b602013-01-04 02:08:123866
[email protected]aa043632013-03-25 03:39:423867 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203868 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463869 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423870 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203871 host_impl_->SwapBuffers(frame);
[email protected]94f206c12012-08-25 00:09:143872
[email protected]aa043632013-03-25 03:39:423873 EXPECT_GT(context3d->NumTextures(), 0u);
[email protected]94f206c12012-08-25 00:09:143874
[email protected]aa043632013-03-25 03:39:423875 // Kill the layer tree.
3876 host_impl_->active_tree()->SetRootLayer(
3877 LayerImpl::Create(host_impl_->active_tree(), 100));
3878 // There should be no textures left in use after.
3879 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]94f206c12012-08-25 00:09:143880}
3881
[email protected]c8756fbe2013-02-12 01:53:493882class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423883 public:
[email protected]c32e27082013-11-07 06:58:203884 MOCK_METHOD1(useProgram, void(blink::WebGLId program));
3885 MOCK_METHOD4(drawElements, void(blink::WGC3Denum mode,
3886 blink::WGC3Dsizei count,
3887 blink::WGC3Denum type,
3888 blink::WGC3Dintptr offset));
[email protected]94f206c12012-08-25 00:09:143889};
3890
[email protected]aa043632013-03-25 03:39:423891TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
[email protected]0634cdd42013-08-16 00:46:093892 scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned(
3893 new MockDrawQuadsToFillScreenContext);
3894 MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get();
3895
3896 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3897 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]94f206c12012-08-25 00:09:143898
[email protected]aa043632013-03-25 03:39:423899 // Run test case
[email protected]ce2e8112013-11-28 07:44:363900 LayerTreeSettings settings = DefaultSettings();
3901 settings.partial_swap_enabled = false;
3902 CreateHostImpl(settings, output_surface.Pass());
[email protected]aa043632013-03-25 03:39:423903 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
3904 host_impl_->active_tree()->set_background_color(SK_ColorWHITE);
[email protected]94f206c12012-08-25 00:09:143905
[email protected]aa043632013-03-25 03:39:423906 // Verify one quad is drawn when transparent background set is not set.
3907 host_impl_->active_tree()->set_has_transparent_background(false);
3908 EXPECT_CALL(*mock_context, useProgram(_))
3909 .Times(1);
3910 EXPECT_CALL(*mock_context, drawElements(_, _, _, _))
3911 .Times(1);
3912 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203913 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463914 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423915 host_impl_->DidDrawAllLayers(frame);
3916 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143917
[email protected]aa043632013-03-25 03:39:423918 // Verify no quads are drawn when transparent background is set.
3919 host_impl_->active_tree()->set_has_transparent_background(true);
[email protected]e0341352013-04-06 05:01:203920 host_impl_->SetFullRootLayerDamage();
3921 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463922 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423923 host_impl_->DidDrawAllLayers(frame);
3924 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143925}
3926
[email protected]aa043632013-03-25 03:39:423927TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
3928 set_reduce_memory_result(false);
[email protected]b1969fa2012-10-17 20:16:293929
[email protected]d7626ffd2013-03-29 00:17:423930 // If changing the memory limit wouldn't result in changing what was
3931 // committed, then no commit should be requested.
[email protected]aa043632013-03-25 03:39:423932 set_reduce_memory_result(false);
[email protected]d7626ffd2013-03-29 00:17:423933 host_impl_->set_max_memory_needed_bytes(
3934 host_impl_->memory_allocation_limit_bytes() - 1);
[email protected]fd32d122013-06-29 13:11:043935 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073936 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]d7626ffd2013-03-29 00:17:423937 EXPECT_FALSE(did_request_commit_);
3938 did_request_commit_ = false;
3939
3940 // If changing the memory limit would result in changing what was
3941 // committed, then a commit should be requested, even though nothing was
3942 // evicted.
3943 set_reduce_memory_result(false);
3944 host_impl_->set_max_memory_needed_bytes(
3945 host_impl_->memory_allocation_limit_bytes());
[email protected]fd32d122013-06-29 13:11:043946 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073947 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]aa043632013-03-25 03:39:423948 EXPECT_TRUE(did_request_commit_);
3949 did_request_commit_ = false;
[email protected]b1969fa2012-10-17 20:16:293950
[email protected]aa043632013-03-25 03:39:423951 // Especially if changing the memory limit caused evictions, we need
3952 // to re-commit.
3953 set_reduce_memory_result(true);
[email protected]d7626ffd2013-03-29 00:17:423954 host_impl_->set_max_memory_needed_bytes(1);
[email protected]fd32d122013-06-29 13:11:043955 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073956 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]aa043632013-03-25 03:39:423957 EXPECT_TRUE(did_request_commit_);
3958 did_request_commit_ = false;
[email protected]b1969fa2012-10-17 20:16:293959
[email protected]aa043632013-03-25 03:39:423960 // But if we set it to the same value that it was before, we shouldn't
3961 // re-commit.
[email protected]fd32d122013-06-29 13:11:043962 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073963 host_impl_->memory_allocation_limit_bytes()));
[email protected]aa043632013-03-25 03:39:423964 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:143965}
3966
[email protected]aa043632013-03-25 03:39:423967class LayerTreeHostImplTestWithDelegatingRenderer
3968 : public LayerTreeHostImplTest {
3969 protected:
3970 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
3971 return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>();
3972 }
3973
3974 void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) {
[email protected]e0341352013-04-06 05:01:203975 bool expect_to_draw = !expected_damage.IsEmpty();
3976
[email protected]aa043632013-03-25 03:39:423977 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203978 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423979
[email protected]e0341352013-04-06 05:01:203980 if (!expect_to_draw) {
3981 // With no damage, we don't draw, and no quads are created.
3982 ASSERT_EQ(0u, frame.render_passes.size());
3983 } else {
3984 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]aa043632013-03-25 03:39:423985
[email protected]e0341352013-04-06 05:01:203986 // Verify the damage rect for the root render pass.
3987 const RenderPass* root_render_pass = frame.render_passes.back();
3988 EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect);
3989
3990 // Verify the root and child layers' quads are generated and not being
3991 // culled.
3992 ASSERT_EQ(2u, root_render_pass->quad_list.size());
3993
3994 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
3995 gfx::RectF expected_child_visible_rect(child->content_bounds());
3996 EXPECT_RECT_EQ(expected_child_visible_rect,
3997 root_render_pass->quad_list[0]->visible_rect);
3998
3999 LayerImpl* root = host_impl_->active_tree()->root_layer();
4000 gfx::RectF expected_root_visible_rect(root->content_bounds());
4001 EXPECT_RECT_EQ(expected_root_visible_rect,
4002 root_render_pass->quad_list[1]->visible_rect);
4003 }
[email protected]aa043632013-03-25 03:39:424004
[email protected]de2cf8c2013-10-25 19:46:464005 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424006 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:204007 EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame));
[email protected]aa043632013-03-25 03:39:424008 }
4009};
4010
4011TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
4012 scoped_ptr<SolidColorLayerImpl> root =
4013 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
4014 root->SetAnchorPoint(gfx::PointF());
4015 root->SetPosition(gfx::PointF());
4016 root->SetBounds(gfx::Size(10, 10));
4017 root->SetContentBounds(gfx::Size(10, 10));
4018 root->SetDrawsContent(true);
[email protected]e0341352013-04-06 05:01:204019
4020 // Child layer is in the bottom right corner.
4021 scoped_ptr<SolidColorLayerImpl> child =
4022 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
4023 child->SetAnchorPoint(gfx::PointF(0.f, 0.f));
4024 child->SetPosition(gfx::PointF(9.f, 9.f));
4025 child->SetBounds(gfx::Size(1, 1));
4026 child->SetContentBounds(gfx::Size(1, 1));
4027 child->SetDrawsContent(true);
4028 root->AddChild(child.PassAs<LayerImpl>());
4029
[email protected]aa043632013-03-25 03:39:424030 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>());
4031
4032 // Draw a frame. In the first frame, the entire viewport should be damaged.
[email protected]54af03522013-09-05 00:43:284033 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
[email protected]aa043632013-03-25 03:39:424034 DrawFrameAndTestDamage(full_frame_damage);
4035
[email protected]e0341352013-04-06 05:01:204036 // The second frame has damage that doesn't touch the child layer. Its quads
4037 // should still be generated.
4038 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
4039 host_impl_->active_tree()->root_layer()->set_update_rect(small_damage);
4040 DrawFrameAndTestDamage(small_damage);
4041
4042 // The third frame should have no damage, so no quads should be generated.
[email protected]aa043632013-03-25 03:39:424043 gfx::Rect no_damage;
4044 DrawFrameAndTestDamage(no_damage);
[email protected]ea9d8f22012-12-08 03:39:294045}
4046
[email protected]05dea302013-01-15 08:30:414047class FakeMaskLayerImpl : public LayerImpl {
[email protected]aa043632013-03-25 03:39:424048 public:
4049 static scoped_ptr<FakeMaskLayerImpl> Create(LayerTreeImpl* tree_impl,
4050 int id) {
4051 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id));
4052 }
[email protected]05dea302013-01-15 08:30:414053
[email protected]aa043632013-03-25 03:39:424054 virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE {
4055 return 0;
4056 }
[email protected]05dea302013-01-15 08:30:414057
[email protected]aa043632013-03-25 03:39:424058 private:
4059 FakeMaskLayerImpl(LayerTreeImpl* tree_impl, int id)
4060 : LayerImpl(tree_impl, id) {}
[email protected]05dea302013-01-15 08:30:414061};
4062
[email protected]aa043632013-03-25 03:39:424063TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
[email protected]35a99a12013-05-09 23:52:294064 LayerTreeSettings settings;
4065 settings.layer_transforms_should_scale_layer_contents = true;
[email protected]ce2e8112013-11-28 07:44:364066 CreateHostImpl(settings, CreateOutputSurface());
[email protected]35a99a12013-05-09 23:52:294067
[email protected]aa043632013-03-25 03:39:424068 // Root
4069 // |
4070 // +-- Scaling Layer (adds a 2x scale)
4071 // |
4072 // +-- Content Layer
4073 // +--Mask
4074 scoped_ptr<LayerImpl> scoped_root =
4075 LayerImpl::Create(host_impl_->active_tree(), 1);
4076 LayerImpl* root = scoped_root.get();
4077 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
[email protected]05dea302013-01-15 08:30:414078
[email protected]aa043632013-03-25 03:39:424079 scoped_ptr<LayerImpl> scoped_scaling_layer =
4080 LayerImpl::Create(host_impl_->active_tree(), 2);
4081 LayerImpl* scaling_layer = scoped_scaling_layer.get();
4082 root->AddChild(scoped_scaling_layer.Pass());
[email protected]05dea302013-01-15 08:30:414083
[email protected]aa043632013-03-25 03:39:424084 scoped_ptr<LayerImpl> scoped_content_layer =
4085 LayerImpl::Create(host_impl_->active_tree(), 3);
4086 LayerImpl* content_layer = scoped_content_layer.get();
4087 scaling_layer->AddChild(scoped_content_layer.Pass());
[email protected]05dea302013-01-15 08:30:414088
[email protected]aa043632013-03-25 03:39:424089 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4090 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
4091 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4092 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
[email protected]05dea302013-01-15 08:30:414093
[email protected]aa043632013-03-25 03:39:424094 gfx::Size root_size(100, 100);
4095 root->SetBounds(root_size);
4096 root->SetContentBounds(root_size);
4097 root->SetPosition(gfx::PointF());
4098 root->SetAnchorPoint(gfx::PointF());
[email protected]05dea302013-01-15 08:30:414099
[email protected]aa043632013-03-25 03:39:424100 gfx::Size scaling_layer_size(50, 50);
4101 scaling_layer->SetBounds(scaling_layer_size);
4102 scaling_layer->SetContentBounds(scaling_layer_size);
4103 scaling_layer->SetPosition(gfx::PointF());
4104 scaling_layer->SetAnchorPoint(gfx::PointF());
4105 gfx::Transform scale;
4106 scale.Scale(2.f, 2.f);
4107 scaling_layer->SetTransform(scale);
[email protected]05dea302013-01-15 08:30:414108
[email protected]aa043632013-03-25 03:39:424109 content_layer->SetBounds(scaling_layer_size);
4110 content_layer->SetContentBounds(scaling_layer_size);
4111 content_layer->SetPosition(gfx::PointF());
4112 content_layer->SetAnchorPoint(gfx::PointF());
4113 content_layer->SetDrawsContent(true);
[email protected]05dea302013-01-15 08:30:414114
[email protected]aa043632013-03-25 03:39:424115 mask_layer->SetBounds(scaling_layer_size);
4116 mask_layer->SetContentBounds(scaling_layer_size);
4117 mask_layer->SetPosition(gfx::PointF());
4118 mask_layer->SetAnchorPoint(gfx::PointF());
4119 mask_layer->SetDrawsContent(true);
[email protected]05dea302013-01-15 08:30:414120
4121
[email protected]aa043632013-03-25 03:39:424122 // Check that the tree scaling is correctly taken into account for the mask,
4123 // that should fully map onto the quad.
4124 float device_scale_factor = 1.f;
[email protected]18ce59702013-04-09 04:58:404125 host_impl_->SetViewportSize(root_size);
[email protected]a7dffcf2013-03-29 08:54:014126 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4127 {
[email protected]aa043632013-03-25 03:39:424128 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204129 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:414130
[email protected]aa043632013-03-25 03:39:424131 ASSERT_EQ(1u, frame.render_passes.size());
4132 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4133 ASSERT_EQ(DrawQuad::RENDER_PASS,
4134 frame.render_passes[0]->quad_list[0]->material);
4135 const RenderPassDrawQuad* render_pass_quad =
4136 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4137 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4138 render_pass_quad->rect.ToString());
4139 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4140 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:414141
[email protected]de2cf8c2013-10-25 19:46:464142 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424143 host_impl_->DidDrawAllLayers(frame);
4144 }
[email protected]05dea302013-01-15 08:30:414145
4146
[email protected]aa043632013-03-25 03:39:424147 // Applying a DSF should change the render surface size, but won't affect
4148 // which part of the mask is used.
4149 device_scale_factor = 2.f;
4150 gfx::Size device_viewport =
4151 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
[email protected]18ce59702013-04-09 04:58:404152 host_impl_->SetViewportSize(device_viewport);
[email protected]aa043632013-03-25 03:39:424153 host_impl_->SetDeviceScaleFactor(device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014154 host_impl_->active_tree()->set_needs_update_draw_properties();
4155 {
[email protected]aa043632013-03-25 03:39:424156 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204157 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:414158
[email protected]aa043632013-03-25 03:39:424159 ASSERT_EQ(1u, frame.render_passes.size());
4160 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4161 ASSERT_EQ(DrawQuad::RENDER_PASS,
4162 frame.render_passes[0]->quad_list[0]->material);
4163 const RenderPassDrawQuad* render_pass_quad =
4164 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4165 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4166 render_pass_quad->rect.ToString());
4167 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4168 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:414169
[email protected]de2cf8c2013-10-25 19:46:464170 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424171 host_impl_->DidDrawAllLayers(frame);
4172 }
[email protected]05dea302013-01-15 08:30:414173
4174
[email protected]aa043632013-03-25 03:39:424175 // Applying an equivalent content scale on the content layer and the mask
4176 // should still result in the same part of the mask being used.
4177 gfx::Size content_bounds =
4178 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size,
4179 device_scale_factor));
4180 content_layer->SetContentBounds(content_bounds);
4181 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4182 mask_layer->SetContentBounds(content_bounds);
4183 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014184 host_impl_->active_tree()->set_needs_update_draw_properties();
4185 {
[email protected]aa043632013-03-25 03:39:424186 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204187 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:414188
[email protected]aa043632013-03-25 03:39:424189 ASSERT_EQ(1u, frame.render_passes.size());
4190 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4191 ASSERT_EQ(DrawQuad::RENDER_PASS,
4192 frame.render_passes[0]->quad_list[0]->material);
4193 const RenderPassDrawQuad* render_pass_quad =
4194 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4195 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4196 render_pass_quad->rect.ToString());
4197 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4198 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554199
[email protected]de2cf8c2013-10-25 19:46:464200 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424201 host_impl_->DidDrawAllLayers(frame);
4202 }
[email protected]8611f012013-01-17 03:44:554203}
4204
[email protected]aa043632013-03-25 03:39:424205TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
4206 // The mask layer has bounds 100x100 but is attached to a layer with bounds
4207 // 50x50.
[email protected]8611f012013-01-17 03:44:554208
[email protected]aa043632013-03-25 03:39:424209 scoped_ptr<LayerImpl> scoped_root =
4210 LayerImpl::Create(host_impl_->active_tree(), 1);
4211 LayerImpl* root = scoped_root.get();
4212 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
[email protected]8611f012013-01-17 03:44:554213
[email protected]aa043632013-03-25 03:39:424214 scoped_ptr<LayerImpl> scoped_content_layer =
4215 LayerImpl::Create(host_impl_->active_tree(), 3);
4216 LayerImpl* content_layer = scoped_content_layer.get();
4217 root->AddChild(scoped_content_layer.Pass());
[email protected]8611f012013-01-17 03:44:554218
[email protected]aa043632013-03-25 03:39:424219 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4220 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
4221 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4222 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
[email protected]8611f012013-01-17 03:44:554223
[email protected]aa043632013-03-25 03:39:424224 gfx::Size root_size(100, 100);
4225 root->SetBounds(root_size);
4226 root->SetContentBounds(root_size);
4227 root->SetPosition(gfx::PointF());
4228 root->SetAnchorPoint(gfx::PointF());
[email protected]8611f012013-01-17 03:44:554229
[email protected]aa043632013-03-25 03:39:424230 gfx::Size layer_size(50, 50);
4231 content_layer->SetBounds(layer_size);
4232 content_layer->SetContentBounds(layer_size);
4233 content_layer->SetPosition(gfx::PointF());
4234 content_layer->SetAnchorPoint(gfx::PointF());
4235 content_layer->SetDrawsContent(true);
[email protected]8611f012013-01-17 03:44:554236
[email protected]aa043632013-03-25 03:39:424237 gfx::Size mask_size(100, 100);
4238 mask_layer->SetBounds(mask_size);
4239 mask_layer->SetContentBounds(mask_size);
4240 mask_layer->SetPosition(gfx::PointF());
4241 mask_layer->SetAnchorPoint(gfx::PointF());
4242 mask_layer->SetDrawsContent(true);
[email protected]8611f012013-01-17 03:44:554243
[email protected]aa043632013-03-25 03:39:424244 // Check that the mask fills the surface.
4245 float device_scale_factor = 1.f;
[email protected]18ce59702013-04-09 04:58:404246 host_impl_->SetViewportSize(root_size);
[email protected]a7dffcf2013-03-29 08:54:014247 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4248 {
[email protected]aa043632013-03-25 03:39:424249 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204250 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554251
[email protected]aa043632013-03-25 03:39:424252 ASSERT_EQ(1u, frame.render_passes.size());
4253 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4254 ASSERT_EQ(DrawQuad::RENDER_PASS,
4255 frame.render_passes[0]->quad_list[0]->material);
4256 const RenderPassDrawQuad* render_pass_quad =
4257 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4258 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4259 render_pass_quad->rect.ToString());
4260 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4261 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554262
[email protected]de2cf8c2013-10-25 19:46:464263 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424264 host_impl_->DidDrawAllLayers(frame);
4265 }
[email protected]8611f012013-01-17 03:44:554266
[email protected]aa043632013-03-25 03:39:424267 // Applying a DSF should change the render surface size, but won't affect
4268 // which part of the mask is used.
4269 device_scale_factor = 2.f;
4270 gfx::Size device_viewport =
4271 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
[email protected]18ce59702013-04-09 04:58:404272 host_impl_->SetViewportSize(device_viewport);
[email protected]aa043632013-03-25 03:39:424273 host_impl_->SetDeviceScaleFactor(device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014274 host_impl_->active_tree()->set_needs_update_draw_properties();
4275 {
[email protected]aa043632013-03-25 03:39:424276 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204277 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554278
[email protected]aa043632013-03-25 03:39:424279 ASSERT_EQ(1u, frame.render_passes.size());
4280 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4281 ASSERT_EQ(DrawQuad::RENDER_PASS,
4282 frame.render_passes[0]->quad_list[0]->material);
4283 const RenderPassDrawQuad* render_pass_quad =
4284 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4285 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4286 render_pass_quad->rect.ToString());
4287 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4288 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554289
[email protected]de2cf8c2013-10-25 19:46:464290 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424291 host_impl_->DidDrawAllLayers(frame);
4292 }
[email protected]8611f012013-01-17 03:44:554293
[email protected]aa043632013-03-25 03:39:424294 // Applying an equivalent content scale on the content layer and the mask
4295 // should still result in the same part of the mask being used.
4296 gfx::Size layer_size_large =
4297 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
4298 content_layer->SetContentBounds(layer_size_large);
4299 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4300 gfx::Size mask_size_large =
4301 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
4302 mask_layer->SetContentBounds(mask_size_large);
4303 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014304 host_impl_->active_tree()->set_needs_update_draw_properties();
4305 {
[email protected]aa043632013-03-25 03:39:424306 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204307 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554308
[email protected]aa043632013-03-25 03:39:424309 ASSERT_EQ(1u, frame.render_passes.size());
4310 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4311 ASSERT_EQ(DrawQuad::RENDER_PASS,
4312 frame.render_passes[0]->quad_list[0]->material);
4313 const RenderPassDrawQuad* render_pass_quad =
4314 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4315 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4316 render_pass_quad->rect.ToString());
4317 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4318 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554319
[email protected]de2cf8c2013-10-25 19:46:464320 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424321 host_impl_->DidDrawAllLayers(frame);
4322 }
[email protected]8611f012013-01-17 03:44:554323
[email protected]8591a642013-04-17 18:48:564324 // Applying a different contents scale to the mask layer means it will have
4325 // a larger texture, but it should use the same tex coords to cover the
4326 // layer it masks.
[email protected]aa043632013-03-25 03:39:424327 mask_layer->SetContentBounds(mask_size);
[email protected]8591a642013-04-17 18:48:564328 mask_layer->SetContentsScale(1.f, 1.f);
[email protected]a7dffcf2013-03-29 08:54:014329 host_impl_->active_tree()->set_needs_update_draw_properties();
4330 {
[email protected]aa043632013-03-25 03:39:424331 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204332 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554333
[email protected]aa043632013-03-25 03:39:424334 ASSERT_EQ(1u, frame.render_passes.size());
4335 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4336 ASSERT_EQ(DrawQuad::RENDER_PASS,
4337 frame.render_passes[0]->quad_list[0]->material);
4338 const RenderPassDrawQuad* render_pass_quad =
4339 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4340 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4341 render_pass_quad->rect.ToString());
4342 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4343 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:414344
[email protected]de2cf8c2013-10-25 19:46:464345 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424346 host_impl_->DidDrawAllLayers(frame);
4347 }
[email protected]05dea302013-01-15 08:30:414348}
4349
[email protected]8591a642013-04-17 18:48:564350TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
4351 // The replica's mask layer has bounds 100x100 but the replica is of a
4352 // layer with bounds 50x50.
4353
4354 scoped_ptr<LayerImpl> scoped_root =
4355 LayerImpl::Create(host_impl_->active_tree(), 1);
4356 LayerImpl* root = scoped_root.get();
4357 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
4358
4359 scoped_ptr<LayerImpl> scoped_content_layer =
4360 LayerImpl::Create(host_impl_->active_tree(), 3);
4361 LayerImpl* content_layer = scoped_content_layer.get();
4362 root->AddChild(scoped_content_layer.Pass());
4363
4364 scoped_ptr<LayerImpl> scoped_replica_layer =
4365 LayerImpl::Create(host_impl_->active_tree(), 2);
4366 LayerImpl* replica_layer = scoped_replica_layer.get();
4367 content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
4368
4369 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4370 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
4371 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4372 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
4373
4374 gfx::Size root_size(100, 100);
4375 root->SetBounds(root_size);
4376 root->SetContentBounds(root_size);
4377 root->SetPosition(gfx::PointF());
4378 root->SetAnchorPoint(gfx::PointF());
4379
4380 gfx::Size layer_size(50, 50);
4381 content_layer->SetBounds(layer_size);
4382 content_layer->SetContentBounds(layer_size);
4383 content_layer->SetPosition(gfx::PointF());
4384 content_layer->SetAnchorPoint(gfx::PointF());
4385 content_layer->SetDrawsContent(true);
4386
4387 gfx::Size mask_size(100, 100);
4388 mask_layer->SetBounds(mask_size);
4389 mask_layer->SetContentBounds(mask_size);
4390 mask_layer->SetPosition(gfx::PointF());
4391 mask_layer->SetAnchorPoint(gfx::PointF());
4392 mask_layer->SetDrawsContent(true);
4393
4394 // Check that the mask fills the surface.
4395 float device_scale_factor = 1.f;
4396 host_impl_->SetViewportSize(root_size);
4397 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4398 {
4399 LayerTreeHostImpl::FrameData frame;
4400 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4401
4402 ASSERT_EQ(1u, frame.render_passes.size());
4403 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4404 ASSERT_EQ(DrawQuad::RENDER_PASS,
4405 frame.render_passes[0]->quad_list[1]->material);
4406 const RenderPassDrawQuad* replica_quad =
4407 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4408 EXPECT_TRUE(replica_quad->is_replica);
4409 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4410 replica_quad->rect.ToString());
4411 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4412 replica_quad->mask_uv_rect.ToString());
4413
[email protected]de2cf8c2013-10-25 19:46:464414 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564415 host_impl_->DidDrawAllLayers(frame);
4416 }
4417
4418 // Applying a DSF should change the render surface size, but won't affect
4419 // which part of the mask is used.
4420 device_scale_factor = 2.f;
4421 gfx::Size device_viewport =
4422 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
4423 host_impl_->SetViewportSize(device_viewport);
4424 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4425 host_impl_->active_tree()->set_needs_update_draw_properties();
4426 {
4427 LayerTreeHostImpl::FrameData frame;
4428 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4429
4430 ASSERT_EQ(1u, frame.render_passes.size());
4431 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4432 ASSERT_EQ(DrawQuad::RENDER_PASS,
4433 frame.render_passes[0]->quad_list[1]->material);
4434 const RenderPassDrawQuad* replica_quad =
4435 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4436 EXPECT_TRUE(replica_quad->is_replica);
4437 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4438 replica_quad->rect.ToString());
4439 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4440 replica_quad->mask_uv_rect.ToString());
4441
[email protected]de2cf8c2013-10-25 19:46:464442 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564443 host_impl_->DidDrawAllLayers(frame);
4444 }
4445
4446 // Applying an equivalent content scale on the content layer and the mask
4447 // should still result in the same part of the mask being used.
4448 gfx::Size layer_size_large =
4449 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
4450 content_layer->SetContentBounds(layer_size_large);
4451 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4452 gfx::Size mask_size_large =
4453 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
4454 mask_layer->SetContentBounds(mask_size_large);
4455 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4456 host_impl_->active_tree()->set_needs_update_draw_properties();
4457 {
4458 LayerTreeHostImpl::FrameData frame;
4459 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4460
4461 ASSERT_EQ(1u, frame.render_passes.size());
4462 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4463 ASSERT_EQ(DrawQuad::RENDER_PASS,
4464 frame.render_passes[0]->quad_list[1]->material);
4465 const RenderPassDrawQuad* replica_quad =
4466 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4467 EXPECT_TRUE(replica_quad->is_replica);
4468 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4469 replica_quad->rect.ToString());
4470 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4471 replica_quad->mask_uv_rect.ToString());
4472
[email protected]de2cf8c2013-10-25 19:46:464473 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564474 host_impl_->DidDrawAllLayers(frame);
4475 }
4476
4477 // Applying a different contents scale to the mask layer means it will have
4478 // a larger texture, but it should use the same tex coords to cover the
4479 // layer it masks.
4480 mask_layer->SetContentBounds(mask_size);
4481 mask_layer->SetContentsScale(1.f, 1.f);
4482 host_impl_->active_tree()->set_needs_update_draw_properties();
4483 {
4484 LayerTreeHostImpl::FrameData frame;
4485 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4486
4487 ASSERT_EQ(1u, frame.render_passes.size());
4488 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4489 ASSERT_EQ(DrawQuad::RENDER_PASS,
4490 frame.render_passes[0]->quad_list[1]->material);
4491 const RenderPassDrawQuad* replica_quad =
4492 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4493 EXPECT_TRUE(replica_quad->is_replica);
4494 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4495 replica_quad->rect.ToString());
4496 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4497 replica_quad->mask_uv_rect.ToString());
4498
[email protected]de2cf8c2013-10-25 19:46:464499 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564500 host_impl_->DidDrawAllLayers(frame);
4501 }
4502}
4503
4504TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) {
4505 // The replica is of a layer with bounds 50x50, but it has a child that causes
4506 // the surface bounds to be larger.
4507
4508 scoped_ptr<LayerImpl> scoped_root =
4509 LayerImpl::Create(host_impl_->active_tree(), 1);
4510 LayerImpl* root = scoped_root.get();
4511 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
4512
4513 scoped_ptr<LayerImpl> scoped_content_layer =
4514 LayerImpl::Create(host_impl_->active_tree(), 2);
4515 LayerImpl* content_layer = scoped_content_layer.get();
4516 root->AddChild(scoped_content_layer.Pass());
4517
4518 scoped_ptr<LayerImpl> scoped_content_child_layer =
4519 LayerImpl::Create(host_impl_->active_tree(), 3);
4520 LayerImpl* content_child_layer = scoped_content_child_layer.get();
4521 content_layer->AddChild(scoped_content_child_layer.Pass());
4522
4523 scoped_ptr<LayerImpl> scoped_replica_layer =
4524 LayerImpl::Create(host_impl_->active_tree(), 4);
4525 LayerImpl* replica_layer = scoped_replica_layer.get();
4526 content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
4527
4528 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4529 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5);
4530 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4531 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
4532
4533 gfx::Size root_size(100, 100);
4534 root->SetBounds(root_size);
4535 root->SetContentBounds(root_size);
4536 root->SetPosition(gfx::PointF());
4537 root->SetAnchorPoint(gfx::PointF());
4538
4539 gfx::Size layer_size(50, 50);
4540 content_layer->SetBounds(layer_size);
4541 content_layer->SetContentBounds(layer_size);
4542 content_layer->SetPosition(gfx::PointF());
4543 content_layer->SetAnchorPoint(gfx::PointF());
4544 content_layer->SetDrawsContent(true);
4545
4546 gfx::Size child_size(50, 50);
4547 content_child_layer->SetBounds(child_size);
4548 content_child_layer->SetContentBounds(child_size);
4549 content_child_layer->SetPosition(gfx::Point(50, 0));
4550 content_child_layer->SetAnchorPoint(gfx::PointF());
4551 content_child_layer->SetDrawsContent(true);
4552
4553 gfx::Size mask_size(50, 50);
4554 mask_layer->SetBounds(mask_size);
4555 mask_layer->SetContentBounds(mask_size);
4556 mask_layer->SetPosition(gfx::PointF());
4557 mask_layer->SetAnchorPoint(gfx::PointF());
4558 mask_layer->SetDrawsContent(true);
4559
4560 float device_scale_factor = 1.f;
4561 host_impl_->SetViewportSize(root_size);
4562 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4563 {
4564 LayerTreeHostImpl::FrameData frame;
4565 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4566
4567 ASSERT_EQ(1u, frame.render_passes.size());
4568 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4569
4570 // The surface is 100x50.
4571 ASSERT_EQ(DrawQuad::RENDER_PASS,
4572 frame.render_passes[0]->quad_list[0]->material);
4573 const RenderPassDrawQuad* render_pass_quad =
4574 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4575 EXPECT_FALSE(render_pass_quad->is_replica);
4576 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
4577 render_pass_quad->rect.ToString());
4578
4579 // The mask covers the owning layer only.
4580 ASSERT_EQ(DrawQuad::RENDER_PASS,
4581 frame.render_passes[0]->quad_list[1]->material);
4582 const RenderPassDrawQuad* replica_quad =
4583 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4584 EXPECT_TRUE(replica_quad->is_replica);
4585 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
4586 replica_quad->rect.ToString());
4587 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
4588 replica_quad->mask_uv_rect.ToString());
4589
[email protected]de2cf8c2013-10-25 19:46:464590 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564591 host_impl_->DidDrawAllLayers(frame);
4592 }
4593
4594 // Move the child to (-50, 0) instead. Now the mask should be moved to still
4595 // cover the layer being replicated.
4596 content_child_layer->SetPosition(gfx::Point(-50, 0));
4597 {
4598 LayerTreeHostImpl::FrameData frame;
4599 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4600
4601 ASSERT_EQ(1u, frame.render_passes.size());
4602 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4603
4604 // The surface is 100x50 with its origin at (-50, 0).
4605 ASSERT_EQ(DrawQuad::RENDER_PASS,
4606 frame.render_passes[0]->quad_list[0]->material);
4607 const RenderPassDrawQuad* render_pass_quad =
4608 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4609 EXPECT_FALSE(render_pass_quad->is_replica);
4610 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
4611 render_pass_quad->rect.ToString());
4612
4613 // The mask covers the owning layer only.
4614 ASSERT_EQ(DrawQuad::RENDER_PASS,
4615 frame.render_passes[0]->quad_list[1]->material);
4616 const RenderPassDrawQuad* replica_quad =
4617 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4618 EXPECT_TRUE(replica_quad->is_replica);
4619 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
4620 replica_quad->rect.ToString());
4621 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
4622 replica_quad->mask_uv_rect.ToString());
4623
[email protected]de2cf8c2013-10-25 19:46:464624 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564625 host_impl_->DidDrawAllLayers(frame);
4626 }
4627}
4628
4629TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) {
4630 // The masked layer has bounds 50x50, but it has a child that causes
4631 // the surface bounds to be larger. It also has a parent that clips the
4632 // masked layer and its surface.
4633
4634 scoped_ptr<LayerImpl> scoped_root =
4635 LayerImpl::Create(host_impl_->active_tree(), 1);
4636 LayerImpl* root = scoped_root.get();
4637 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
4638
4639 scoped_ptr<LayerImpl> scoped_clipping_layer =
4640 LayerImpl::Create(host_impl_->active_tree(), 2);
4641 LayerImpl* clipping_layer = scoped_clipping_layer.get();
4642 root->AddChild(scoped_clipping_layer.Pass());
4643
4644 scoped_ptr<LayerImpl> scoped_content_layer =
4645 LayerImpl::Create(host_impl_->active_tree(), 3);
4646 LayerImpl* content_layer = scoped_content_layer.get();
4647 clipping_layer->AddChild(scoped_content_layer.Pass());
4648
4649 scoped_ptr<LayerImpl> scoped_content_child_layer =
4650 LayerImpl::Create(host_impl_->active_tree(), 4);
4651 LayerImpl* content_child_layer = scoped_content_child_layer.get();
4652 content_layer->AddChild(scoped_content_child_layer.Pass());
4653
4654 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4655 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6);
4656 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4657 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
4658
4659 gfx::Size root_size(100, 100);
4660 root->SetBounds(root_size);
4661 root->SetContentBounds(root_size);
4662 root->SetPosition(gfx::PointF());
4663 root->SetAnchorPoint(gfx::PointF());
4664
4665 gfx::Rect clipping_rect(20, 10, 10, 20);
4666 clipping_layer->SetBounds(clipping_rect.size());
4667 clipping_layer->SetContentBounds(clipping_rect.size());
4668 clipping_layer->SetPosition(clipping_rect.origin());
4669 clipping_layer->SetAnchorPoint(gfx::PointF());
4670 clipping_layer->SetMasksToBounds(true);
4671
4672 gfx::Size layer_size(50, 50);
4673 content_layer->SetBounds(layer_size);
4674 content_layer->SetContentBounds(layer_size);
4675 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
4676 content_layer->SetAnchorPoint(gfx::PointF());
4677 content_layer->SetDrawsContent(true);
4678
4679 gfx::Size child_size(50, 50);
4680 content_child_layer->SetBounds(child_size);
4681 content_child_layer->SetContentBounds(child_size);
4682 content_child_layer->SetPosition(gfx::Point(50, 0));
4683 content_child_layer->SetAnchorPoint(gfx::PointF());
4684 content_child_layer->SetDrawsContent(true);
4685
4686 gfx::Size mask_size(100, 100);
4687 mask_layer->SetBounds(mask_size);
4688 mask_layer->SetContentBounds(mask_size);
4689 mask_layer->SetPosition(gfx::PointF());
4690 mask_layer->SetAnchorPoint(gfx::PointF());
4691 mask_layer->SetDrawsContent(true);
4692
4693 float device_scale_factor = 1.f;
4694 host_impl_->SetViewportSize(root_size);
4695 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4696 {
4697 LayerTreeHostImpl::FrameData frame;
4698 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4699
4700 ASSERT_EQ(1u, frame.render_passes.size());
4701 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4702
4703 // The surface is clipped to 10x20.
4704 ASSERT_EQ(DrawQuad::RENDER_PASS,
4705 frame.render_passes[0]->quad_list[0]->material);
4706 const RenderPassDrawQuad* render_pass_quad =
4707 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4708 EXPECT_FALSE(render_pass_quad->is_replica);
4709 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
4710 render_pass_quad->rect.ToString());
4711
4712 // The masked layer is 50x50, but the surface size is 10x20. So the texture
4713 // coords in the mask are scaled by 10/50 and 20/50.
4714 // The surface is clipped to (20,10) so the mask texture coords are offset
4715 // by 20/50 and 10/50
4716 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f),
4717 1.f / 50.f).ToString(),
4718 render_pass_quad->mask_uv_rect.ToString());
4719
[email protected]de2cf8c2013-10-25 19:46:464720 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564721 host_impl_->DidDrawAllLayers(frame);
4722 }
4723}
4724
[email protected]46b79d52013-09-07 04:29:294725class GLRendererWithSetupQuadForAntialiasing : public GLRenderer {
4726 public:
4727 using GLRenderer::SetupQuadForAntialiasing;
4728};
4729
4730TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
4731 // Due to precision issues (especially on Android), sometimes far
4732 // away quads can end up thinking they need AA.
4733 float device_scale_factor = 4.f / 3.f;
4734 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4735 gfx::Size root_size(2000, 1000);
4736 gfx::Size device_viewport_size =
4737 gfx::ToCeiledSize(gfx::ScaleSize(root_size, device_scale_factor));
4738 host_impl_->SetViewportSize(device_viewport_size);
4739
4740 host_impl_->CreatePendingTree();
4741 host_impl_->pending_tree()
4742 ->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f);
4743
4744 scoped_ptr<LayerImpl> scoped_root =
4745 LayerImpl::Create(host_impl_->pending_tree(), 1);
4746 LayerImpl* root = scoped_root.get();
4747
4748 host_impl_->pending_tree()->SetRootLayer(scoped_root.Pass());
4749
4750 scoped_ptr<LayerImpl> scoped_scrolling_layer =
4751 LayerImpl::Create(host_impl_->pending_tree(), 2);
4752 LayerImpl* scrolling_layer = scoped_scrolling_layer.get();
4753 root->AddChild(scoped_scrolling_layer.Pass());
4754
4755 gfx::Size content_layer_bounds(100000, 100);
4756 gfx::Size pile_tile_size(3000, 3000);
4757 scoped_refptr<FakePicturePileImpl> pile(FakePicturePileImpl::CreateFilledPile(
4758 pile_tile_size, content_layer_bounds));
4759
4760 scoped_ptr<FakePictureLayerImpl> scoped_content_layer =
4761 FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile);
4762 LayerImpl* content_layer = scoped_content_layer.get();
4763 scrolling_layer->AddChild(scoped_content_layer.PassAs<LayerImpl>());
4764 content_layer->SetBounds(content_layer_bounds);
4765 content_layer->SetDrawsContent(true);
4766
4767 root->SetBounds(root_size);
4768
4769 gfx::Vector2d scroll_offset(100000, 0);
4770 scrolling_layer->SetScrollable(true);
4771 scrolling_layer->SetMaxScrollOffset(scroll_offset);
4772 scrolling_layer->SetScrollOffset(scroll_offset);
4773
4774 host_impl_->ActivatePendingTree();
4775
4776 host_impl_->active_tree()->UpdateDrawProperties();
4777 ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
4778
4779 LayerTreeHostImpl::FrameData frame;
4780 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4781
4782 ASSERT_EQ(1u, frame.render_passes.size());
4783 ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
4784 const DrawQuad* quad = frame.render_passes[0]->quad_list[0];
4785
4786 float edge[24];
4787 gfx::QuadF device_layer_quad;
4788 bool antialiased =
4789 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
4790 quad->quadTransform(), quad, &device_layer_quad, edge);
4791 EXPECT_FALSE(antialiased);
4792
[email protected]de2cf8c2013-10-25 19:46:464793 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]46b79d52013-09-07 04:29:294794 host_impl_->DidDrawAllLayers(frame);
4795}
4796
4797
[email protected]bb1e2822013-04-17 22:06:014798class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
4799 public:
4800 CompositorFrameMetadataTest()
4801 : swap_buffers_complete_(0) {}
4802
[email protected]bb1e2822013-04-17 22:06:014803 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {
4804 swap_buffers_complete_++;
4805 }
4806
4807 int swap_buffers_complete_;
4808};
4809
4810TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
4811 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
4812 {
4813 LayerTreeHostImpl::FrameData frame;
4814 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4815 host_impl_->DrawLayers(&frame, base::TimeTicks());
4816 host_impl_->DidDrawAllLayers(frame);
4817 }
4818 CompositorFrameAck ack;
[email protected]a7335e0b2013-09-18 09:34:514819 host_impl_->ReclaimResources(&ack);
4820 host_impl_->OnSwapBuffersComplete();
[email protected]bb1e2822013-04-17 22:06:014821 EXPECT_EQ(swap_buffers_complete_, 1);
4822}
4823
[email protected]fbe89f72013-05-21 07:24:244824class CountingSoftwareDevice : public SoftwareOutputDevice {
4825 public:
4826 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
4827
4828 virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE {
4829 ++frames_began_;
4830 return SoftwareOutputDevice::BeginPaint(damage_rect);
4831 }
4832 virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE {
4833 ++frames_ended_;
4834 SoftwareOutputDevice::EndPaint(frame_data);
4835 }
4836
4837 int frames_began_, frames_ended_;
4838};
4839
4840TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) {
[email protected]50644642013-06-20 13:58:554841 // No main thread evictions in resourceless software mode.
4842 set_reduce_memory_result(false);
[email protected]fbe89f72013-05-21 07:24:244843 CountingSoftwareDevice* software_device = new CountingSoftwareDevice();
4844 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL(
4845 scoped_ptr<SoftwareOutputDevice>(software_device)).release();
[email protected]ce2e8112013-11-28 07:44:364846 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
4847 scoped_ptr<OutputSurface>(output_surface)));
4848 host_impl_->SetViewportSize(gfx::Size(50, 50));
4849
4850 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]fbe89f72013-05-21 07:24:244851
4852 output_surface->set_forced_draw_to_software_device(true);
4853 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice());
4854
4855 EXPECT_EQ(0, software_device->frames_began_);
4856 EXPECT_EQ(0, software_device->frames_ended_);
4857
4858 DrawFrame();
4859
4860 EXPECT_EQ(1, software_device->frames_began_);
4861 EXPECT_EQ(1, software_device->frames_ended_);
[email protected]15cc9922013-05-24 07:31:474862
4863 // Call other API methods that are likely to hit NULL pointer in this mode.
4864 EXPECT_TRUE(host_impl_->AsValue());
4865 EXPECT_TRUE(host_impl_->ActivationStateAsValue());
[email protected]fbe89f72013-05-21 07:24:244866}
4867
[email protected]ffbb2212013-06-02 23:47:594868TEST_F(LayerTreeHostImplTest,
4869 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) {
[email protected]50644642013-06-20 13:58:554870 set_reduce_memory_result(false);
[email protected]ffbb2212013-06-02 23:47:594871 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL(
4872 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())).release();
[email protected]ce2e8112013-11-28 07:44:364873 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
4874 scoped_ptr<OutputSurface>(output_surface)));
[email protected]ffbb2212013-06-02 23:47:594875
4876 output_surface->set_forced_draw_to_software_device(true);
4877 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice());
4878
4879 // SolidColorLayerImpl will be drawn.
4880 scoped_ptr<SolidColorLayerImpl> root_layer =
4881 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
4882
4883 // VideoLayerImpl will not be drawn.
4884 FakeVideoFrameProvider provider;
4885 scoped_ptr<VideoLayerImpl> video_layer =
4886 VideoLayerImpl::Create(host_impl_->active_tree(), 2, &provider);
4887 video_layer->SetBounds(gfx::Size(10, 10));
4888 video_layer->SetContentBounds(gfx::Size(10, 10));
4889 video_layer->SetDrawsContent(true);
4890 root_layer->AddChild(video_layer.PassAs<LayerImpl>());
4891 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>());
4892
4893 LayerTreeHostImpl::FrameData frame;
4894 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:464895 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ffbb2212013-06-02 23:47:594896 host_impl_->DidDrawAllLayers(frame);
4897
4898 EXPECT_EQ(1u, frame.will_draw_layers.size());
4899 EXPECT_EQ(host_impl_->active_tree()->root_layer(), frame.will_draw_layers[0]);
4900}
4901
[email protected]d9ca99e2013-08-28 21:49:484902class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest {
4903 protected:
4904 virtual void SetUp() OVERRIDE {
4905 LayerTreeHostImplTest::SetUp();
[email protected]2b154b22013-06-07 09:03:274906
[email protected]d9ca99e2013-08-28 21:49:484907 set_reduce_memory_result(false);
[email protected]2b154b22013-06-07 09:03:274908
[email protected]d9ca99e2013-08-28 21:49:484909 scoped_ptr<FakeOutputSurface> output_surface(
4910 FakeOutputSurface::CreateDeferredGL(
4911 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())));
4912 output_surface_ = output_surface.get();
4913
[email protected]ce2e8112013-11-28 07:44:364914 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
4915 output_surface.PassAs<OutputSurface>()));
[email protected]d9ca99e2013-08-28 21:49:484916
4917 scoped_ptr<SolidColorLayerImpl> root_layer =
4918 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
4919 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>());
4920
4921 onscreen_context_provider_ = TestContextProvider::Create();
4922 offscreen_context_provider_ = TestContextProvider::Create();
4923 }
4924
4925 FakeOutputSurface* output_surface_;
4926 scoped_refptr<TestContextProvider> onscreen_context_provider_;
4927 scoped_refptr<TestContextProvider> offscreen_context_provider_;
4928};
4929
4930
4931TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) {
[email protected]2b154b22013-06-07 09:03:274932 // Software draw.
4933 DrawFrame();
4934
[email protected]b5174d712013-08-28 08:10:434935 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4936 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4937
[email protected]2b154b22013-06-07 09:03:274938 // DeferredInitialize and hardware draw.
[email protected]d9ca99e2013-08-28 21:49:484939 EXPECT_TRUE(output_surface_->InitializeAndSetContext3d(
4940 onscreen_context_provider_, offscreen_context_provider_));
4941 EXPECT_EQ(onscreen_context_provider_,
[email protected]b5174d712013-08-28 08:10:434942 host_impl_->output_surface()->context_provider());
[email protected]d9ca99e2013-08-28 21:49:484943 EXPECT_EQ(offscreen_context_provider_,
[email protected]b5174d712013-08-28 08:10:434944 host_impl_->offscreen_context_provider());
[email protected]2b154b22013-06-07 09:03:274945
4946 // Defer intialized GL draw.
4947 DrawFrame();
[email protected]50af3c22013-07-13 03:50:204948
4949 // Revert back to software.
[email protected]d9ca99e2013-08-28 21:49:484950 output_surface_->ReleaseGL();
[email protected]b5174d712013-08-28 08:10:434951 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4952 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4953
4954 // Software draw again.
[email protected]50af3c22013-07-13 03:50:204955 DrawFrame();
[email protected]2b154b22013-06-07 09:03:274956}
4957
[email protected]d9ca99e2013-08-28 21:49:484958TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_0) {
4959 // Software draw.
4960 DrawFrame();
4961
4962 // Fail initialization of the onscreen context before the OutputSurface binds
4963 // it to the thread.
4964 onscreen_context_provider_->UnboundTestContext3d()
4965 ->set_times_make_current_succeeds(0);
4966
4967 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4968 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4969 EXPECT_FALSE(did_lose_output_surface_);
4970
4971 // DeferredInitialize fails.
4972 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
4973 onscreen_context_provider_, offscreen_context_provider_));
4974 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4975 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4976
4977 // Software draw again.
4978 DrawFrame();
4979}
4980
4981TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_1) {
4982 // Software draw.
4983 DrawFrame();
4984
4985 // Fail initialization of the onscreen context after the OutputSurface binds
4986 // it to the thread.
4987 onscreen_context_provider_->UnboundTestContext3d()
4988 ->set_times_make_current_succeeds(2);
4989
4990 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4991 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4992 EXPECT_FALSE(did_lose_output_surface_);
4993
4994 // DeferredInitialize fails.
4995 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
4996 onscreen_context_provider_, offscreen_context_provider_));
4997 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4998 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4999
5000 // We lose the output surface.
5001 EXPECT_TRUE(did_lose_output_surface_);
5002}
5003
5004TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_2) {
5005 // Software draw.
5006 DrawFrame();
5007
5008 // Fail initialization of the onscreen context after the OutputSurface binds
5009 // it to the thread and during renderer initialization.
5010 onscreen_context_provider_->UnboundTestContext3d()
5011 ->set_times_make_current_succeeds(1);
5012
5013 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5014 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5015 EXPECT_FALSE(did_lose_output_surface_);
5016
5017 // DeferredInitialize fails.
5018 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
5019 onscreen_context_provider_, offscreen_context_provider_));
5020 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5021 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5022
5023 // We lose the output surface.
5024 EXPECT_TRUE(did_lose_output_surface_);
5025}
5026
5027TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) {
5028 // Software draw.
5029 DrawFrame();
5030
5031 // Fail initialization of the offscreen context.
5032 offscreen_context_provider_->UnboundTestContext3d()
5033 ->set_times_make_current_succeeds(0);
5034
5035 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5036 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5037 EXPECT_FALSE(did_lose_output_surface_);
5038
5039 // DeferredInitialize fails.
5040 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
5041 onscreen_context_provider_, offscreen_context_provider_));
5042 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5043 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5044
5045 // We lose the output surface.
5046 EXPECT_TRUE(did_lose_output_surface_);
5047}
5048
[email protected]fd32d122013-06-29 13:11:045049// Checks that we have a non-0 default allocation if we pass a context that
5050// doesn't support memory management extensions.
5051TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
5052 LayerTreeSettings settings;
[email protected]a7f35682013-10-22 23:05:575053 host_impl_ = LayerTreeHostImpl::Create(
5054 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]fd32d122013-06-29 13:11:045055
[email protected]0634cdd42013-08-16 00:46:095056 scoped_ptr<OutputSurface> output_surface(
[email protected]41de22822013-08-29 04:16:175057 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
[email protected]0634cdd42013-08-16 00:46:095058 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]fd32d122013-06-29 13:11:045059 EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes());
5060}
5061
5062TEST_F(LayerTreeHostImplTest, MemoryPolicy) {
5063 ManagedMemoryPolicy policy1(
[email protected]0b8ef2842013-11-01 09:53:355064 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000);
5065 int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
5066 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING);
5067 int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
5068 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
[email protected]fd32d122013-06-29 13:11:045069
5070 host_impl_->SetVisible(true);
[email protected]3f2ff112013-08-03 02:41:075071 host_impl_->SetMemoryPolicy(policy1);
[email protected]fd32d122013-06-29 13:11:045072 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
[email protected]0b8ef2842013-11-01 09:53:355073 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:045074
5075 host_impl_->SetVisible(false);
[email protected]0b8ef2842013-11-01 09:53:355076 EXPECT_EQ(0u, current_limit_bytes_);
5077 EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:045078
5079 host_impl_->SetVisible(true);
5080 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
[email protected]0b8ef2842013-11-01 09:53:355081 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:045082}
5083
[email protected]222c6782013-09-05 22:24:495084class LayerTreeHostImplTestManageTiles : public LayerTreeHostImplTest {
5085 public:
5086 virtual void SetUp() OVERRIDE {
5087 LayerTreeSettings settings;
5088 settings.impl_side_painting = true;
5089
5090 fake_host_impl_ = new FakeLayerTreeHostImpl(settings, &proxy_);
5091 host_impl_.reset(fake_host_impl_);
5092 host_impl_->InitializeRenderer(CreateOutputSurface());
5093 host_impl_->SetViewportSize(gfx::Size(10, 10));
5094 }
5095
5096 FakeLayerTreeHostImpl* fake_host_impl_;
5097};
5098
5099TEST_F(LayerTreeHostImplTestManageTiles, ManageTilesWhenInvisible) {
[email protected]c48536a52013-09-14 00:02:085100 fake_host_impl_->DidModifyTilePriorities();
[email protected]222c6782013-09-05 22:24:495101 EXPECT_TRUE(fake_host_impl_->manage_tiles_needed());
5102 fake_host_impl_->SetVisible(false);
5103 EXPECT_FALSE(fake_host_impl_->manage_tiles_needed());
5104}
5105
[email protected]c9280762013-08-01 06:28:575106TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
5107 scoped_ptr<TestWebGraphicsContext3D> context =
5108 TestWebGraphicsContext3D::Create();
5109 TestWebGraphicsContext3D* context3d = context.get();
[email protected]0634cdd42013-08-16 00:46:095110 scoped_ptr<OutputSurface> output_surface = CreateFakeOutputSurface();
[email protected]ce2e8112013-11-28 07:44:365111 CreateHostImpl(DefaultSettings(), output_surface.Pass());
[email protected]c9280762013-08-01 06:28:575112
5113 EXPECT_EQ(0u, context3d->NumTextures());
5114
[email protected]741fba422013-09-20 03:34:145115 SkBitmap skbitmap;
5116 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
5117 skbitmap.allocPixels();
5118 skbitmap.setImmutable();
5119
[email protected]c9280762013-08-01 06:28:575120 UIResourceId ui_resource_id = 1;
[email protected]741fba422013-09-20 03:34:145121 UIResourceBitmap bitmap(skbitmap);
[email protected]c9280762013-08-01 06:28:575122 host_impl_->CreateUIResource(ui_resource_id, bitmap);
5123 EXPECT_EQ(1u, context3d->NumTextures());
5124 ResourceProvider::ResourceId id1 =
5125 host_impl_->ResourceIdForUIResource(ui_resource_id);
5126 EXPECT_NE(0u, id1);
5127
5128 // Multiple requests with the same id is allowed. The previous texture is
5129 // deleted.
5130 host_impl_->CreateUIResource(ui_resource_id, bitmap);
5131 EXPECT_EQ(1u, context3d->NumTextures());
5132 ResourceProvider::ResourceId id2 =
5133 host_impl_->ResourceIdForUIResource(ui_resource_id);
5134 EXPECT_NE(0u, id2);
5135 EXPECT_NE(id1, id2);
5136
5137 // Deleting invalid UIResourceId is allowed and does not change state.
5138 host_impl_->DeleteUIResource(-1);
5139 EXPECT_EQ(1u, context3d->NumTextures());
5140
5141 // Should return zero for invalid UIResourceId. Number of textures should
5142 // not change.
5143 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
5144 EXPECT_EQ(1u, context3d->NumTextures());
5145
5146 host_impl_->DeleteUIResource(ui_resource_id);
5147 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
5148 EXPECT_EQ(0u, context3d->NumTextures());
5149
5150 // Should not change state for multiple deletion on one UIResourceId
5151 host_impl_->DeleteUIResource(ui_resource_id);
5152 EXPECT_EQ(0u, context3d->NumTextures());
5153}
5154
[email protected]6be50ba82013-11-08 12:04:125155TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
5156 scoped_ptr<TestWebGraphicsContext3D> context =
5157 TestWebGraphicsContext3D::Create();
5158 TestWebGraphicsContext3D* context3d = context.get();
5159 scoped_ptr<OutputSurface> output_surface = CreateFakeOutputSurface();
[email protected]ce2e8112013-11-28 07:44:365160 CreateHostImpl(DefaultSettings(), output_surface.Pass());
[email protected]6be50ba82013-11-08 12:04:125161
5162 EXPECT_EQ(0u, context3d->NumTextures());
5163
5164 scoped_ptr<uint8_t[]> pixels(new uint8_t[8]);
5165 skia::RefPtr<ETC1PixelRef> etc1_pixel_ref =
5166 skia::AdoptRef(new ETC1PixelRef(pixels.Pass()));
5167 UIResourceBitmap bitmap(etc1_pixel_ref, gfx::Size(4, 4));
5168
5169 UIResourceId ui_resource_id = 1;
5170 host_impl_->CreateUIResource(ui_resource_id, bitmap);
5171 EXPECT_EQ(1u, context3d->NumTextures());
5172 ResourceProvider::ResourceId id1 =
5173 host_impl_->ResourceIdForUIResource(ui_resource_id);
5174 EXPECT_NE(0u, id1);
5175}
5176
[email protected]ea468c6c2013-09-10 08:25:115177void ShutdownReleasesContext_Callback(scoped_ptr<CopyOutputResult> result) {
5178}
5179
5180TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
5181 scoped_refptr<TestContextProvider> context_provider =
5182 TestContextProvider::Create();
5183
[email protected]ce2e8112013-11-28 07:44:365184 CreateHostImpl(
5185 DefaultSettings(),
5186 FakeOutputSurface::Create3d(context_provider).PassAs<OutputSurface>());
[email protected]ea468c6c2013-09-10 08:25:115187
5188 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
5189
5190 ScopedPtrVector<CopyOutputRequest> requests;
5191 requests.push_back(CopyOutputRequest::CreateRequest(
5192 base::Bind(&ShutdownReleasesContext_Callback)));
5193
5194 host_impl_->active_tree()->root_layer()->PassCopyRequests(&requests);
5195
5196 LayerTreeHostImpl::FrameData frame;
5197 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:465198 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ea468c6c2013-09-10 08:25:115199 host_impl_->DidDrawAllLayers(frame);
5200
5201 // The CopyOutputResult's callback has a ref on the ContextProvider and a
5202 // texture in a texture mailbox.
5203 EXPECT_FALSE(context_provider->HasOneRef());
5204 EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
5205
5206 host_impl_.reset();
5207
5208 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
5209 // released, and the texture deleted.
5210 EXPECT_TRUE(context_provider->HasOneRef());
5211 EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
5212}
5213
[email protected]df0c42342013-10-08 20:52:125214TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) {
5215 // When flinging via touch, only the child should scroll (we should not
5216 // bubble).
5217 gfx::Size surface_size(10, 10);
5218 gfx::Size content_size(20, 20);
5219 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
5220 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
5221
5222 root->AddChild(child.Pass());
5223
5224 host_impl_->SetViewportSize(surface_size);
5225 host_impl_->active_tree()->SetRootLayer(root.Pass());
5226 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:365227 DrawFrame();
[email protected]df0c42342013-10-08 20:52:125228 {
5229 EXPECT_EQ(InputHandler::ScrollStarted,
5230 host_impl_->ScrollBegin(gfx::Point(),
5231 InputHandler::Gesture));
5232
5233 EXPECT_EQ(InputHandler::ScrollStarted,
5234 host_impl_->FlingScrollBegin());
5235
5236 gfx::Vector2d scroll_delta(0, 100);
5237 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5238 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5239
5240 host_impl_->ScrollEnd();
5241
5242 scoped_ptr<ScrollAndScaleSet> scroll_info =
5243 host_impl_->ProcessScrollDeltas();
5244
5245 // Only the child should have scrolled.
5246 ASSERT_EQ(1u, scroll_info->scrolls.size());
5247 ExpectNone(*scroll_info.get(),
5248 host_impl_->active_tree()->root_layer()->id());
5249 }
5250}
5251
[email protected]d41d7cb92013-10-15 16:08:095252TEST_F(LayerTreeHostImplTest, TouchFlingShouldBubbleIfPrecedingScrollBubbled) {
5253 // When flinging via touch, bubble scrolls if the touch scroll
5254 // immediately preceding the fling bubbled.
5255 gfx::Size surface_size(10, 10);
5256 gfx::Size root_content_size(10, 20);
5257 gfx::Size child_content_size(40, 40);
5258 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, root_content_size);
5259 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, child_content_size);
5260
5261 root->AddChild(child.Pass());
5262
5263 host_impl_->SetViewportSize(surface_size);
5264 host_impl_->active_tree()->SetRootLayer(root.Pass());
5265 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:365266 DrawFrame();
[email protected]d41d7cb92013-10-15 16:08:095267 {
5268 EXPECT_EQ(InputHandler::ScrollStarted,
5269 host_impl_->ScrollBegin(gfx::Point(),
5270 InputHandler::Gesture));
5271
5272 // Touch scroll before starting the fling. The second scroll should bubble.
5273 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 100)));
5274 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 5)));
5275
5276 scoped_ptr<ScrollAndScaleSet> scroll_info =
5277 host_impl_->ProcessScrollDeltas();
5278
5279 // The root should have (partially) scrolled.
5280 EXPECT_EQ(2u, scroll_info->scrolls.size());
5281 ExpectContains(*scroll_info.get(),
5282 host_impl_->active_tree()->root_layer()->id(),
5283 gfx::Vector2d(0, 5));
5284
5285 EXPECT_EQ(InputHandler::ScrollStarted,
5286 host_impl_->FlingScrollBegin());
5287
5288 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 5)));
5289 host_impl_->ScrollEnd();
5290
5291 // The root should have (fully) scrolled from the fling.
5292 scroll_info = host_impl_->ProcessScrollDeltas();
5293 EXPECT_EQ(2u, scroll_info->scrolls.size());
5294 ExpectContains(*scroll_info.get(),
5295 host_impl_->active_tree()->root_layer()->id(),
5296 gfx::Vector2d(0, 10));
5297 }
5298}
5299
[email protected]df0c42342013-10-08 20:52:125300TEST_F(LayerTreeHostImplTest, WheelFlingShouldBubble) {
5301 // When flinging via wheel, the root should eventually scroll (we should
5302 // bubble).
5303 gfx::Size surface_size(10, 10);
5304 gfx::Size content_size(20, 20);
5305 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
5306 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
5307
5308 root->AddChild(child.Pass());
5309
5310 host_impl_->SetViewportSize(surface_size);
5311 host_impl_->active_tree()->SetRootLayer(root.Pass());
5312 host_impl_->active_tree()->DidBecomeActive();
[email protected]ce2e8112013-11-28 07:44:365313 DrawFrame();
[email protected]df0c42342013-10-08 20:52:125314 {
5315 EXPECT_EQ(InputHandler::ScrollStarted,
5316 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
5317
5318 EXPECT_EQ(InputHandler::ScrollStarted,
5319 host_impl_->FlingScrollBegin());
5320
5321 gfx::Vector2d scroll_delta(0, 100);
5322 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5323 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5324
5325 host_impl_->ScrollEnd();
5326
5327 scoped_ptr<ScrollAndScaleSet> scroll_info =
5328 host_impl_->ProcessScrollDeltas();
5329
[email protected]d41d7cb92013-10-15 16:08:095330 // The root should have scrolled.
[email protected]df0c42342013-10-08 20:52:125331 ASSERT_EQ(2u, scroll_info->scrolls.size());
5332 ExpectContains(*scroll_info.get(),
5333 host_impl_->active_tree()->root_layer()->id(),
5334 gfx::Vector2d(0, 10));
5335 }
5336}
5337
[email protected]d359203a2013-11-29 06:16:555338// Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
5339// to CompositorFrameMetadata after SwapBuffers();
5340TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
5341 scoped_ptr<SolidColorLayerImpl> root =
5342 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
5343 root->SetAnchorPoint(gfx::PointF());
5344 root->SetPosition(gfx::PointF());
5345 root->SetBounds(gfx::Size(10, 10));
5346 root->SetContentBounds(gfx::Size(10, 10));
5347 root->SetDrawsContent(true);
5348
5349 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>());
5350
5351 FakeOutputSurface* fake_output_surface =
5352 static_cast<FakeOutputSurface*>(host_impl_->output_surface());
5353
5354 const ui::LatencyInfo& metadata_latency_before =
5355 fake_output_surface->last_sent_frame().metadata.latency_info;
5356 EXPECT_FALSE(metadata_latency_before.FindLatency(
5357 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL));
5358
5359 ui::LatencyInfo latency_info;
5360 latency_info.AddLatencyNumber(
5361 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0);
5362 host_impl_->SetLatencyInfoForInputEvent(latency_info);
5363
5364 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
5365 LayerTreeHostImpl::FrameData frame;
5366 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
5367 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5368 host_impl_->DidDrawAllLayers(frame);
5369 EXPECT_TRUE(host_impl_->SwapBuffers(frame));
5370
5371 const ui::LatencyInfo& metadata_latency_after =
5372 fake_output_surface->last_sent_frame().metadata.latency_info;
5373 EXPECT_TRUE(metadata_latency_after.FindLatency(
5374 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL));
5375}
5376
[email protected]ba565742012-11-10 09:29:485377} // namespace
5378} // namespace cc