blob: a01b2565725f1370a0188447e2365d8fdbda530a [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]89e8267a2013-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]e12dd0e2013-03-18 08:24:4037#include "cc/resources/layer_tiling_data.h"
[email protected]101441ce2012-10-16 01:45:0338#include "cc/test/animation_test_common.h"
[email protected]222c6782013-09-05 22:24:4939#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]a46f32932012-12-07 21:43:1640#include "cc/test/fake_output_surface.h"
[email protected]0634cdd42013-08-16 00:46:0941#include "cc/test/fake_output_surface_client.h"
[email protected]46b79d52013-09-07 04:29:2942#include "cc/test/fake_picture_layer_impl.h"
43#include "cc/test/fake_picture_pile_impl.h"
[email protected]61de5812012-11-08 07:03:4444#include "cc/test/fake_proxy.h"
[email protected]372bad5f2013-03-21 16:38:4345#include "cc/test/fake_rendering_stats_instrumentation.h"
[email protected]d993b602013-01-04 02:08:1246#include "cc/test/fake_video_frame_provider.h"
[email protected]101441ce2012-10-16 01:45:0347#include "cc/test/geometry_test_utils.h"
48#include "cc/test/layer_test_common.h"
49#include "cc/test/render_pass_test_common.h"
[email protected]c2610b9f2013-10-31 06:54:5950#include "cc/test/test_web_graphics_context_3d.h"
[email protected]556fd292013-03-18 08:03:0451#include "cc/trees/layer_tree_impl.h"
52#include "cc/trees/single_thread_proxy.h"
[email protected]59cb7b352012-10-30 06:45:4853#include "media/base/media.h"
[email protected]7f0c53db2012-10-02 00:23:1854#include "testing/gmock/include/gmock/gmock.h"
55#include "testing/gtest/include/gtest/gtest.h"
[email protected]de2cf8c2013-10-25 19:46:4656#include "ui/gfx/frame_time.h"
[email protected]46b79d52013-09-07 04:29:2957#include "ui/gfx/rect_conversions.h"
[email protected]aad0a0072012-11-01 18:15:5858#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1359#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1460
[email protected]94f206c12012-08-25 00:09:1461using ::testing::Mock;
62using ::testing::Return;
63using ::testing::AnyNumber;
64using ::testing::AtLeast;
65using ::testing::_;
[email protected]568285b2013-01-07 23:19:1966using media::VideoFrame;
[email protected]94f206c12012-08-25 00:09:1467
[email protected]ba565742012-11-10 09:29:4868namespace cc {
[email protected]94f206c12012-08-25 00:09:1469namespace {
70
[email protected]c2d0c5a2013-02-26 04:43:3671class LayerTreeHostImplTest : public testing::Test,
[email protected]9bdcfd642012-11-14 21:24:2672 public LayerTreeHostImplClient {
[email protected]aa043632013-03-25 03:39:4273 public:
74 LayerTreeHostImplTest()
[email protected]810d40b72013-06-20 18:26:1575 : proxy_(),
[email protected]aa043632013-03-25 03:39:4276 always_impl_thread_(&proxy_),
77 always_main_thread_blocked_(&proxy_),
78 on_can_draw_state_changed_called_(false),
[email protected]4f48f6e2013-08-27 06:33:3879 did_notify_ready_to_activate_(false),
[email protected]aa043632013-03-25 03:39:4280 did_request_commit_(false),
81 did_request_redraw_(false),
[email protected]c48536a52013-09-14 00:02:0882 did_request_manage_tiles_(false),
[email protected]aa043632013-03-25 03:39:4283 did_upload_visible_tile_(false),
[email protected]d9ca99e2013-08-28 21:49:4884 did_lose_output_surface_(false),
[email protected]fd32d122013-06-29 13:11:0485 reduce_memory_result_(true),
86 current_limit_bytes_(0),
87 current_priority_cutoff_value_(0) {
[email protected]aa043632013-03-25 03:39:4288 media::InitializeMediaLibraryForTesting();
89 }
[email protected]1c0c9bc2012-10-08 22:41:4890
[email protected]aa043632013-03-25 03:39:4291 virtual void SetUp() OVERRIDE {
[email protected]96baf3e2012-10-22 23:09:5592 LayerTreeSettings settings;
[email protected]aa043632013-03-25 03:39:4293 settings.minimum_occlusion_tracking_size = gfx::Size();
[email protected]50644642013-06-20 13:58:5594 settings.impl_side_painting = true;
[email protected]b796c34f2013-11-01 11:52:3495 settings.texture_id_allocation_chunk_size = 1;
[email protected]94f206c12012-08-25 00:09:1496
[email protected]a7f35682013-10-22 23:05:5797 host_impl_ = LayerTreeHostImpl::Create(
98 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]aa043632013-03-25 03:39:4299 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]18ce59702013-04-09 04:58:40100 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:42101 }
[email protected]94f206c12012-08-25 00:09:14102
[email protected]aa043632013-03-25 03:39:42103 virtual void TearDown() OVERRIDE {}
[email protected]94f206c12012-08-25 00:09:14104
[email protected]d9ca99e2013-08-28 21:49:48105 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {
106 did_lose_output_surface_ = true;
107 }
[email protected]aa043632013-03-25 03:39:42108 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
[email protected]daea3d42013-10-23 17:04:50109 virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42110 virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {
111 on_can_draw_state_changed_called_ = true;
112 }
[email protected]4f48f6e2013-08-27 06:33:38113 virtual void NotifyReadyToActivate() OVERRIDE {
114 did_notify_ready_to_activate_ = true;
115 host_impl_->ActivatePendingTree();
[email protected]aa043632013-03-25 03:39:42116 }
117 virtual void SetNeedsRedrawOnImplThread() OVERRIDE {
118 did_request_redraw_ = true;
119 }
[email protected]1cd9f5552013-04-26 04:22:03120 virtual void SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) OVERRIDE {
121 did_request_redraw_ = true;
122 }
[email protected]c48536a52013-09-14 00:02:08123 virtual void SetNeedsManageTilesOnImplThread() OVERRIDE {
124 did_request_manage_tiles_ = true;
125 }
[email protected]aa043632013-03-25 03:39:42126 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE {
127 did_upload_visible_tile_ = true;
128 }
129 virtual void SetNeedsCommitOnImplThread() OVERRIDE {
130 did_request_commit_ = true;
131 }
[email protected]aa043632013-03-25 03:39:42132 virtual void PostAnimationEventsToMainThreadOnImplThread(
133 scoped_ptr<AnimationEventsVector> events,
134 base::Time wall_clock_time) OVERRIDE {}
135 virtual bool ReduceContentsTextureMemoryOnImplThread(
136 size_t limit_bytes, int priority_cutoff) OVERRIDE {
[email protected]fd32d122013-06-29 13:11:04137 current_limit_bytes_ = limit_bytes;
138 current_priority_cutoff_value_ = priority_cutoff;
[email protected]aa043632013-03-25 03:39:42139 return reduce_memory_result_;
140 }
[email protected]aa043632013-03-25 03:39:42141 virtual void SendManagedMemoryStats() OVERRIDE {}
142 virtual bool IsInsideDraw() OVERRIDE { return false; }
143 virtual void RenewTreePriority() OVERRIDE {}
144 virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay)
[email protected]21c9dee72013-06-15 01:20:05145 OVERRIDE { requested_scrollbar_animation_delay_ = delay; }
[email protected]2a61ad52013-05-13 14:01:29146 virtual void DidActivatePendingTree() OVERRIDE {}
[email protected]bac0e552013-11-05 22:38:51147 virtual void DidManageTiles() OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42148
149 void set_reduce_memory_result(bool reduce_memory_result) {
150 reduce_memory_result_ = reduce_memory_result;
151 }
152
153 void CreateLayerTreeHost(bool partial_swap,
154 scoped_ptr<OutputSurface> output_surface) {
155 LayerTreeSettings settings;
156 settings.minimum_occlusion_tracking_size = gfx::Size();
157 settings.partial_swap_enabled = partial_swap;
158
[email protected]a7f35682013-10-22 23:05:57159 host_impl_ = LayerTreeHostImpl::Create(
160 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]aa043632013-03-25 03:39:42161
162 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:40163 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:42164 }
165
166 void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) {
167 root->SetAnchorPoint(gfx::PointF());
168 root->SetPosition(gfx::PointF());
169 root->SetBounds(gfx::Size(10, 10));
170 root->SetContentBounds(gfx::Size(10, 10));
171 root->SetDrawsContent(true);
172 root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
173 host_impl_->active_tree()->SetRootLayer(root.Pass());
174 }
175
176 static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) {
[email protected]1960a712013-04-30 17:06:47177 ASSERT_EQ(layer->ScrollDelta(), gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:42178 for (size_t i = 0; i < layer->children().size(); ++i)
179 ExpectClearedScrollDeltasRecursive(layer->children()[i]);
180 }
181
182 static void ExpectContains(const ScrollAndScaleSet& scroll_info,
183 int id,
184 gfx::Vector2d scroll_delta) {
185 int times_encountered = 0;
186
187 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
188 if (scroll_info.scrolls[i].layer_id != id)
189 continue;
190 EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta);
191 times_encountered++;
192 }
193
[email protected]df0c42342013-10-08 20:52:12194 ASSERT_EQ(1, times_encountered);
[email protected]aa043632013-03-25 03:39:42195 }
196
197 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
198 int times_encountered = 0;
199
200 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
201 if (scroll_info.scrolls[i].layer_id != id)
202 continue;
203 times_encountered++;
204 }
205
206 ASSERT_EQ(0, times_encountered);
207 }
208
[email protected]7d1b07e2013-10-01 17:31:30209 LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl,
210 gfx::Size content_size) {
[email protected]aa043632013-03-25 03:39:42211 scoped_ptr<LayerImpl> root =
[email protected]7d1b07e2013-10-01 17:31:30212 LayerImpl::Create(layer_tree_impl, 1);
[email protected]aa043632013-03-25 03:39:42213 root->SetBounds(content_size);
214 root->SetContentBounds(content_size);
215 root->SetPosition(gfx::PointF());
216 root->SetAnchorPoint(gfx::PointF());
217
[email protected]35a99a12013-05-09 23:52:29218 scoped_ptr<LayerImpl> scroll =
[email protected]7d1b07e2013-10-01 17:31:30219 LayerImpl::Create(layer_tree_impl, 2);
[email protected]35a99a12013-05-09 23:52:29220 LayerImpl* scroll_layer = scroll.get();
221 scroll->SetScrollable(true);
222 scroll->SetScrollOffset(gfx::Vector2d());
223 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
[email protected]a2b5ded2013-05-20 21:32:53224 content_size.height()));
[email protected]35a99a12013-05-09 23:52:29225 scroll->SetBounds(content_size);
226 scroll->SetContentBounds(content_size);
227 scroll->SetPosition(gfx::PointF());
228 scroll->SetAnchorPoint(gfx::PointF());
229
230 scoped_ptr<LayerImpl> contents =
[email protected]7d1b07e2013-10-01 17:31:30231 LayerImpl::Create(layer_tree_impl, 3);
[email protected]aa043632013-03-25 03:39:42232 contents->SetDrawsContent(true);
233 contents->SetBounds(content_size);
234 contents->SetContentBounds(content_size);
235 contents->SetPosition(gfx::PointF());
236 contents->SetAnchorPoint(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29237
238 scroll->AddChild(contents.Pass());
239 root->AddChild(scroll.Pass());
240
[email protected]7d1b07e2013-10-01 17:31:30241 layer_tree_impl->SetRootLayer(root.Pass());
242 return scroll_layer;
243 }
244
245 LayerImpl* SetupScrollAndContentsLayers(gfx::Size content_size) {
246 LayerImpl* scroll_layer = CreateScrollAndContentsLayers(
247 host_impl_->active_tree(), content_size);
[email protected]aa043632013-03-25 03:39:42248 host_impl_->active_tree()->DidBecomeActive();
[email protected]35a99a12013-05-09 23:52:29249 return scroll_layer;
[email protected]aa043632013-03-25 03:39:42250 }
251
252 scoped_ptr<LayerImpl> CreateScrollableLayer(int id, gfx::Size size) {
253 scoped_ptr<LayerImpl> layer =
254 LayerImpl::Create(host_impl_->active_tree(), id);
255 layer->SetScrollable(true);
256 layer->SetDrawsContent(true);
257 layer->SetBounds(size);
258 layer->SetContentBounds(size);
259 layer->SetMaxScrollOffset(gfx::Vector2d(size.width() * 2,
260 size.height() * 2));
261 return layer.Pass();
262 }
263
264 void InitializeRendererAndDrawFrame() {
265 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]fbe89f72013-05-21 07:24:24266 DrawFrame();
267 }
268
269 void DrawFrame() {
[email protected]aa043632013-03-25 03:39:42270 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:20271 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:46272 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:42273 host_impl_->DidDrawAllLayers(frame);
274 }
275
276 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor);
277 void pinch_zoom_pan_viewport_test(float device_scale_factor);
278 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor);
279 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
280 float device_scale_factor);
281
[email protected]6133cc232013-07-30 18:47:07282 void CheckNotifyCalledIfCanDrawChanged(bool always_draw) {
283 // Note: It is not possible to disable the renderer once it has been set,
284 // so we do not need to test that disabling the renderer notifies us
285 // that can_draw changed.
286 EXPECT_FALSE(host_impl_->CanDraw());
287 on_can_draw_state_changed_called_ = false;
288
289 // Set up the root layer, which allows us to draw.
290 SetupScrollAndContentsLayers(gfx::Size(100, 100));
291 EXPECT_TRUE(host_impl_->CanDraw());
292 EXPECT_TRUE(on_can_draw_state_changed_called_);
293 on_can_draw_state_changed_called_ = false;
294
295 // Toggle the root layer to make sure it toggles can_draw
296 host_impl_->active_tree()->SetRootLayer(scoped_ptr<LayerImpl>());
297 EXPECT_FALSE(host_impl_->CanDraw());
298 EXPECT_TRUE(on_can_draw_state_changed_called_);
299 on_can_draw_state_changed_called_ = false;
300
301 SetupScrollAndContentsLayers(gfx::Size(100, 100));
302 EXPECT_TRUE(host_impl_->CanDraw());
303 EXPECT_TRUE(on_can_draw_state_changed_called_);
304 on_can_draw_state_changed_called_ = false;
305
306 // Toggle the device viewport size to make sure it toggles can_draw.
307 host_impl_->SetViewportSize(gfx::Size());
308 if (always_draw) {
309 EXPECT_TRUE(host_impl_->CanDraw());
310 } else {
311 EXPECT_FALSE(host_impl_->CanDraw());
312 }
313 EXPECT_TRUE(on_can_draw_state_changed_called_);
314 on_can_draw_state_changed_called_ = false;
315
316 host_impl_->SetViewportSize(gfx::Size(100, 100));
317 EXPECT_TRUE(host_impl_->CanDraw());
318 EXPECT_TRUE(on_can_draw_state_changed_called_);
319 on_can_draw_state_changed_called_ = false;
320
321 // Toggle contents textures purged without causing any evictions,
322 // and make sure that it does not change can_draw.
323 set_reduce_memory_result(false);
324 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:07325 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]6133cc232013-07-30 18:47:07326 EXPECT_TRUE(host_impl_->CanDraw());
327 EXPECT_FALSE(on_can_draw_state_changed_called_);
328 on_can_draw_state_changed_called_ = false;
329
330 // Toggle contents textures purged to make sure it toggles can_draw.
331 set_reduce_memory_result(true);
332 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:07333 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]6133cc232013-07-30 18:47:07334 if (always_draw) {
335 EXPECT_TRUE(host_impl_->CanDraw());
336 } else {
337 EXPECT_FALSE(host_impl_->CanDraw());
338 }
339 EXPECT_TRUE(on_can_draw_state_changed_called_);
340 on_can_draw_state_changed_called_ = false;
341
342 host_impl_->active_tree()->ResetContentsTexturesPurged();
343 EXPECT_TRUE(host_impl_->CanDraw());
344 EXPECT_TRUE(on_can_draw_state_changed_called_);
345 on_can_draw_state_changed_called_ = false;
346 }
347
[email protected]bf1cfd9a2013-09-26 05:43:02348 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
349
[email protected]aa043632013-03-25 03:39:42350 protected:
351 virtual scoped_ptr<OutputSurface> CreateOutputSurface() {
352 return CreateFakeOutputSurface();
353 }
354
355 void DrawOneFrame() {
356 LayerTreeHostImpl::FrameData frame_data;
[email protected]e0341352013-04-06 05:01:20357 host_impl_->PrepareToDraw(&frame_data, gfx::Rect());
[email protected]aa043632013-03-25 03:39:42358 host_impl_->DidDrawAllLayers(frame_data);
359 }
360
361 FakeProxy proxy_;
362 DebugScopedSetImplThread always_impl_thread_;
363 DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
364
365 scoped_ptr<LayerTreeHostImpl> host_impl_;
366 FakeRenderingStatsInstrumentation stats_instrumentation_;
367 bool on_can_draw_state_changed_called_;
[email protected]4f48f6e2013-08-27 06:33:38368 bool did_notify_ready_to_activate_;
[email protected]aa043632013-03-25 03:39:42369 bool did_request_commit_;
370 bool did_request_redraw_;
[email protected]c48536a52013-09-14 00:02:08371 bool did_request_manage_tiles_;
[email protected]aa043632013-03-25 03:39:42372 bool did_upload_visible_tile_;
[email protected]d9ca99e2013-08-28 21:49:48373 bool did_lose_output_surface_;
[email protected]aa043632013-03-25 03:39:42374 bool reduce_memory_result_;
[email protected]21c9dee72013-06-15 01:20:05375 base::TimeDelta requested_scrollbar_animation_delay_;
[email protected]fd32d122013-06-29 13:11:04376 size_t current_limit_bytes_;
377 int current_priority_cutoff_value_;
[email protected]aa043632013-03-25 03:39:42378};
379
[email protected]6133cc232013-07-30 18:47:07380TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
381 bool always_draw = false;
382 CheckNotifyCalledIfCanDrawChanged(always_draw);
383}
384
385TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) {
386 LayerTreeSettings settings;
387 settings.impl_side_painting = true;
388 host_impl_ = LayerTreeHostImpl::Create(
[email protected]a7f35682013-10-22 23:05:57389 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]0634cdd42013-08-16 00:46:09390
391 scoped_ptr<FakeOutputSurface> output_surface(
392 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
393
[email protected]6133cc232013-07-30 18:47:07394 host_impl_->InitializeRenderer(
[email protected]0634cdd42013-08-16 00:46:09395 output_surface.PassAs<OutputSurface>());
[email protected]6133cc232013-07-30 18:47:07396 host_impl_->SetViewportSize(gfx::Size(10, 10));
397
398 bool always_draw = true;
399 CheckNotifyCalledIfCanDrawChanged(always_draw);
400}
401
[email protected]aa043632013-03-25 03:39:42402TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) {
403 ASSERT_FALSE(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:14404
[email protected]aa043632013-03-25 03:39:42405 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
406 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
[email protected]94f206c12012-08-25 00:09:14407}
408
[email protected]aa043632013-03-25 03:39:42409TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
410 {
411 scoped_ptr<LayerImpl> root =
412 LayerImpl::Create(host_impl_->active_tree(), 1);
413 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2));
414 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3));
415 root->children()[1]->AddChild(
416 LayerImpl::Create(host_impl_->active_tree(), 4));
417 root->children()[1]->AddChild(
418 LayerImpl::Create(host_impl_->active_tree(), 5));
419 root->children()[1]->children()[0]->AddChild(
420 LayerImpl::Create(host_impl_->active_tree(), 6));
421 host_impl_->active_tree()->SetRootLayer(root.Pass());
422 }
423 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:14424
[email protected]aa043632013-03-25 03:39:42425 ExpectClearedScrollDeltasRecursive(root);
[email protected]0ede3bb2012-12-09 09:14:39426
[email protected]aa043632013-03-25 03:39:42427 scoped_ptr<ScrollAndScaleSet> scroll_info;
428
429 scroll_info = host_impl_->ProcessScrollDeltas();
430 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
431 ExpectClearedScrollDeltasRecursive(root);
432
433 scroll_info = host_impl_->ProcessScrollDeltas();
434 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
435 ExpectClearedScrollDeltasRecursive(root);
[email protected]94f206c12012-08-25 00:09:14436}
437
[email protected]aa043632013-03-25 03:39:42438TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
439 gfx::Vector2d scroll_offset(20, 30);
440 gfx::Vector2d scroll_delta(11, -15);
441 {
442 scoped_ptr<LayerImpl> root =
443 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]d30700f12013-07-31 08:21:01444 root->SetMaxScrollOffset(gfx::Vector2d(100, 100));
[email protected]aa043632013-03-25 03:39:42445 root->SetScrollOffset(scroll_offset);
446 root->SetScrollable(true);
[email protected]aa043632013-03-25 03:39:42447 root->ScrollBy(scroll_delta);
448 host_impl_->active_tree()->SetRootLayer(root.Pass());
449 }
450 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:14451
[email protected]aa043632013-03-25 03:39:42452 scoped_ptr<ScrollAndScaleSet> scroll_info;
[email protected]94f206c12012-08-25 00:09:14453
[email protected]aa043632013-03-25 03:39:42454 scroll_info = host_impl_->ProcessScrollDeltas();
455 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
456 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta);
457 ExpectContains(*scroll_info, root->id(), scroll_delta);
[email protected]94f206c12012-08-25 00:09:14458
[email protected]aa043632013-03-25 03:39:42459 gfx::Vector2d scroll_delta2(-5, 27);
460 root->ScrollBy(scroll_delta2);
461 scroll_info = host_impl_->ProcessScrollDeltas();
462 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
463 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
464 ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2);
465
466 root->ScrollBy(gfx::Vector2d());
467 scroll_info = host_impl_->ProcessScrollDeltas();
468 EXPECT_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
[email protected]94f206c12012-08-25 00:09:14469}
470
[email protected]aa043632013-03-25 03:39:42471TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
472 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40473 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42474 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:14475
[email protected]5ff3c9782013-04-29 17:35:12476 EXPECT_EQ(InputHandler::ScrollStarted,
477 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42478 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
479 host_impl_->ScrollEnd();
480 EXPECT_TRUE(did_request_redraw_);
481 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:14482}
483
[email protected]aa043632013-03-25 03:39:42484TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
485 // We should not crash when trying to scroll an empty layer tree.
[email protected]5ff3c9782013-04-29 17:35:12486 EXPECT_EQ(InputHandler::ScrollIgnored,
487 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:14488}
489
[email protected]aa043632013-03-25 03:39:42490TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
491 LayerTreeSettings settings;
[email protected]a7f35682013-10-22 23:05:57492 host_impl_ = LayerTreeHostImpl::Create(
493 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]0634cdd42013-08-16 00:46:09494 scoped_ptr<TestWebGraphicsContext3D> context_owned =
495 TestWebGraphicsContext3D::Create();
496 context_owned->set_times_make_current_succeeds(0);
497
498 scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d(
499 context_owned.Pass()));
[email protected]94f206c12012-08-25 00:09:14500
[email protected]aa043632013-03-25 03:39:42501 // Initialization will fail here.
[email protected]0634cdd42013-08-16 00:46:09502 host_impl_->InitializeRenderer(output_surface.PassAs<OutputSurface>());
[email protected]18ce59702013-04-09 04:58:40503 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]a90aa702012-11-07 04:48:24504
[email protected]aa043632013-03-25 03:39:42505 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:14506
[email protected]aa043632013-03-25 03:39:42507 // We should not crash when trying to scroll after the renderer initialization
508 // fails.
[email protected]5ff3c9782013-04-29 17:35:12509 EXPECT_EQ(InputHandler::ScrollIgnored,
510 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:14511}
512
[email protected]aa043632013-03-25 03:39:42513TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
[email protected]35a99a12013-05-09 23:52:29514 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40515 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42516 InitializeRendererAndDrawFrame();
[email protected]a9710962012-11-14 20:11:02517
[email protected]aa043632013-03-25 03:39:42518 // We should not crash if the tree is replaced while we are scrolling.
[email protected]5ff3c9782013-04-29 17:35:12519 EXPECT_EQ(InputHandler::ScrollStarted,
520 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42521 host_impl_->active_tree()->DetachLayerTree();
522
[email protected]35a99a12013-05-09 23:52:29523 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42524
525 // We should still be scrolling, because the scrolled layer also exists in the
526 // new tree.
527 gfx::Vector2d scroll_delta(0, 10);
528 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
529 host_impl_->ScrollEnd();
530 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]35a99a12013-05-09 23:52:29531 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta);
[email protected]aa043632013-03-25 03:39:42532}
533
534TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndScroll) {
535 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40536 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42537 InitializeRendererAndDrawFrame();
538
539 // We should be able to scroll even if the root layer loses its render surface
540 // after the most recent render.
541 host_impl_->active_tree()->root_layer()->ClearRenderSurface();
542 host_impl_->active_tree()->set_needs_update_draw_properties();
543
[email protected]5ff3c9782013-04-29 17:35:12544 EXPECT_EQ(InputHandler::ScrollStarted,
545 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42546}
547
548TEST_F(LayerTreeHostImplTest, WheelEventHandlers) {
549 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40550 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42551 InitializeRendererAndDrawFrame();
552 LayerImpl* root = host_impl_->active_tree()->root_layer();
553
554 root->SetHaveWheelEventHandlers(true);
555
556 // With registered event handlers, wheel scrolls have to go to the main
557 // thread.
[email protected]5ff3c9782013-04-29 17:35:12558 EXPECT_EQ(InputHandler::ScrollOnMainThread,
559 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42560
561 // But gesture scrolls can still be handled.
[email protected]5ff3c9782013-04-29 17:35:12562 EXPECT_EQ(InputHandler::ScrollStarted,
563 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42564}
565
[email protected]7c45d8152013-04-23 18:27:21566TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) {
567 SetupScrollAndContentsLayers(gfx::Size(100, 100));
568 host_impl_->SetViewportSize(gfx::Size(50, 50));
569 InitializeRendererAndDrawFrame();
570
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::Gesture));
[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, FlingOnlyWhenScrollingTouchpad) {
585 SetupScrollAndContentsLayers(gfx::Size(100, 100));
586 host_impl_->SetViewportSize(gfx::Size(50, 50));
587 InitializeRendererAndDrawFrame();
588
589 // Ignore the fling since no layer is being scrolled
[email protected]5ff3c9782013-04-29 17:35:12590 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21591 host_impl_->FlingScrollBegin());
592
593 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12594 EXPECT_EQ(InputHandler::ScrollStarted,
595 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]7c45d8152013-04-23 18:27:21596
597 // Now the fling should go ahead since we've started scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12598 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]7c45d8152013-04-23 18:27:21599 host_impl_->FlingScrollBegin());
600}
601
602TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) {
603 SetupScrollAndContentsLayers(gfx::Size(100, 100));
604 host_impl_->SetViewportSize(gfx::Size(50, 50));
605 InitializeRendererAndDrawFrame();
606 LayerImpl* root = host_impl_->active_tree()->root_layer();
607
608 root->SetShouldScrollOnMainThread(true);
609
610 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12611 EXPECT_EQ(InputHandler::ScrollOnMainThread,
612 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]7c45d8152013-04-23 18:27:21613
614 // The fling should be ignored since there's no layer being scrolled impl-side
[email protected]5ff3c9782013-04-29 17:35:12615 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21616 host_impl_->FlingScrollBegin());
617}
618
[email protected]aa043632013-03-25 03:39:42619TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
620 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40621 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42622 InitializeRendererAndDrawFrame();
623 LayerImpl* root = host_impl_->active_tree()->root_layer();
624
625 root->SetShouldScrollOnMainThread(true);
626
[email protected]5ff3c9782013-04-29 17:35:12627 EXPECT_EQ(InputHandler::ScrollOnMainThread,
628 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
629 EXPECT_EQ(InputHandler::ScrollOnMainThread,
630 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42631}
632
633TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
634 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40635 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42636
637 LayerImpl* root = host_impl_->active_tree()->root_layer();
638 root->SetContentsScale(2.f, 2.f);
639 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
640
641 InitializeRendererAndDrawFrame();
642
643 // All scroll types inside the non-fast scrollable region should fail.
[email protected]5ff3c9782013-04-29 17:35:12644 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42645 host_impl_->ScrollBegin(gfx::Point(25, 25),
[email protected]5ff3c9782013-04-29 17:35:12646 InputHandler::Wheel));
647 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42648 host_impl_->ScrollBegin(gfx::Point(25, 25),
[email protected]5ff3c9782013-04-29 17:35:12649 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42650
651 // All scroll types outside this region should succeed.
[email protected]5ff3c9782013-04-29 17:35:12652 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42653 host_impl_->ScrollBegin(gfx::Point(75, 75),
[email protected]5ff3c9782013-04-29 17:35:12654 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42655 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
656 host_impl_->ScrollEnd();
[email protected]5ff3c9782013-04-29 17:35:12657 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42658 host_impl_->ScrollBegin(gfx::Point(75, 75),
[email protected]5ff3c9782013-04-29 17:35:12659 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42660 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
661 host_impl_->ScrollEnd();
662}
663
664TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
665 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40666 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42667
668 LayerImpl* root = host_impl_->active_tree()->root_layer();
669 root->SetContentsScale(2.f, 2.f);
670 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
671 root->SetPosition(gfx::PointF(-25.f, 0.f));
672
673 InitializeRendererAndDrawFrame();
674
675 // This point would fall into the non-fast scrollable region except that we've
676 // moved the layer down by 25 pixels.
[email protected]5ff3c9782013-04-29 17:35:12677 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42678 host_impl_->ScrollBegin(gfx::Point(40, 10),
[email protected]5ff3c9782013-04-29 17:35:12679 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42680 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
681 host_impl_->ScrollEnd();
682
683 // This point is still inside the non-fast region.
[email protected]5ff3c9782013-04-29 17:35:12684 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42685 host_impl_->ScrollBegin(gfx::Point(10, 10),
[email protected]5ff3c9782013-04-29 17:35:12686 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42687}
688
689TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
690 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40691 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42692
693 InitializeRendererAndDrawFrame();
694
[email protected]5ff3c9782013-04-29 17:35:12695 EXPECT_EQ(InputHandler::ScrollStarted,
696 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42697
698 // Trying to scroll to the left/top will not succeed.
699 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
700 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
701 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
702
703 // Scrolling to the right/bottom will succeed.
704 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
705 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
706 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
707
708 // Scrolling to left/top will now succeed.
709 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
710 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
711 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
712
713 // Scrolling diagonally against an edge will succeed.
714 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
715 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
716 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
717
718 // Trying to scroll more than the available space will also succeed.
719 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
720}
721
722TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) {
723 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
[email protected]18ce59702013-04-09 04:58:40724 host_impl_->SetViewportSize(gfx::Size(100, 1000));
[email protected]aa043632013-03-25 03:39:42725
726 InitializeRendererAndDrawFrame();
727
[email protected]5ff3c9782013-04-29 17:35:12728 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42729 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:12730 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42731
732 // Trying to scroll without a vertical scrollbar will fail.
733 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49734 gfx::Point(), SCROLL_FORWARD));
[email protected]aa043632013-03-25 03:39:42735 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49736 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:42737
[email protected]3a83478b2013-08-22 20:55:17738 scoped_ptr<cc::PaintedScrollbarLayerImpl> vertical_scrollbar(
739 cc::PaintedScrollbarLayerImpl::Create(
[email protected]aa043632013-03-25 03:39:42740 host_impl_->active_tree(),
741 20,
[email protected]c28df4c12013-05-22 17:36:49742 VERTICAL));
[email protected]aa043632013-03-25 03:39:42743 vertical_scrollbar->SetBounds(gfx::Size(15, 1000));
744 host_impl_->RootScrollLayer()->SetVerticalScrollbarLayer(
745 vertical_scrollbar.get());
746
747 // Trying to scroll with a vertical scrollbar will succeed.
748 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49749 gfx::Point(), SCROLL_FORWARD));
[email protected]1960a712013-04-30 17:06:47750 EXPECT_FLOAT_EQ(875.f, host_impl_->RootScrollLayer()->ScrollDelta().y());
[email protected]aa043632013-03-25 03:39:42751 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49752 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:42753}
754
[email protected]59a7d552013-10-22 03:36:43755TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
756 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
757 host_impl_->SetViewportSize(gfx::Size(100, 100));
758
759 gfx::Size overflow_size(400, 400);
760 ASSERT_EQ(1u, scroll_layer->children().size());
761 LayerImpl* overflow = scroll_layer->children()[0];
762 overflow->SetBounds(overflow_size);
763 overflow->SetContentBounds(overflow_size);
764 overflow->SetScrollable(true);
765 overflow->SetMaxScrollOffset(gfx::Vector2d(overflow_size.width(),
766 overflow_size.height()));
767 overflow->SetScrollOffset(gfx::Vector2d());
768 overflow->SetPosition(gfx::PointF());
769 overflow->SetAnchorPoint(gfx::PointF());
770
771 InitializeRendererAndDrawFrame();
772 gfx::Point scroll_position(10, 10);
773
774 EXPECT_EQ(InputHandler::ScrollStarted,
775 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
776 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
777 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->TotalScrollOffset());
778
779 gfx::Vector2dF scroll_delta(10, 10);
780 host_impl_->ScrollBy(scroll_position, scroll_delta);
781 host_impl_->ScrollEnd();
782 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
783 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset());
784
785 overflow->set_user_scrollable_horizontal(false);
786
787 EXPECT_EQ(InputHandler::ScrollStarted,
788 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
789 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
790 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset());
791
792 host_impl_->ScrollBy(scroll_position, scroll_delta);
793 host_impl_->ScrollEnd();
794 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset());
795 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
796
797 overflow->set_user_scrollable_vertical(false);
798
799 EXPECT_EQ(InputHandler::ScrollStarted,
800 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
801 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset());
802 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
803
804 host_impl_->ScrollBy(scroll_position, scroll_delta);
805 host_impl_->ScrollEnd();
806 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer->TotalScrollOffset());
807 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
808}
809
[email protected]aa043632013-03-25 03:39:42810TEST_F(LayerTreeHostImplTest,
811 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) {
812 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40813 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42814 InitializeRendererAndDrawFrame();
815
816 // We should be able to hit test for touch event handlers even if the root
817 // layer loses its render surface after the most recent render.
818 host_impl_->active_tree()->root_layer()->ClearRenderSurface();
819 host_impl_->active_tree()->set_needs_update_draw_properties();
820
821 EXPECT_EQ(host_impl_->HaveTouchEventHandlersAt(gfx::Point()), false);
822}
823
824TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
[email protected]35a99a12013-05-09 23:52:29825 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40826 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42827 InitializeRendererAndDrawFrame();
828
[email protected]35a99a12013-05-09 23:52:29829 EXPECT_EQ(scroll_layer, host_impl_->RootScrollLayer());
[email protected]aa043632013-03-25 03:39:42830
831 float min_page_scale = 1.f, max_page_scale = 4.f;
[email protected]aa043632013-03-25 03:39:42832
833 // The impl-based pinch zoom should adjust the max scroll position.
834 {
835 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
836 min_page_scale,
837 max_page_scale);
838 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]aa043632013-03-25 03:39:42839 scroll_layer->SetScrollDelta(gfx::Vector2d());
840
841 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57842 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42843 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
844 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57845 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42846 EXPECT_TRUE(did_request_redraw_);
847 EXPECT_TRUE(did_request_commit_);
848
849 scoped_ptr<ScrollAndScaleSet> scroll_info =
850 host_impl_->ProcessScrollDeltas();
851 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
852
[email protected]35a99a12013-05-09 23:52:29853 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(),
854 scroll_layer->max_scroll_offset().ToString());
[email protected]aa043632013-03-25 03:39:42855 }
856
857 // Scrolling after a pinch gesture should always be in local space. The
858 // scroll deltas do not have the page scale factor applied.
859 {
860 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
861 min_page_scale,
862 max_page_scale);
863 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]aa043632013-03-25 03:39:42864 scroll_layer->SetScrollDelta(gfx::Vector2d());
865
866 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57867 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42868 host_impl_->PinchGestureBegin();
869 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
870 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57871 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42872
873 gfx::Vector2d scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:12874 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42875 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:12876 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42877 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
878 host_impl_->ScrollEnd();
[email protected]a9710962012-11-14 20:11:02879
[email protected]aa043632013-03-25 03:39:42880 scoped_ptr<ScrollAndScaleSet> scroll_info =
881 host_impl_->ProcessScrollDeltas();
882 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:29883 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:42884 scroll_delta);
885 }
[email protected]a9710962012-11-14 20:11:02886}
887
[email protected]aa043632013-03-25 03:39:42888TEST_F(LayerTreeHostImplTest, PinchGesture) {
889 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40890 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42891 InitializeRendererAndDrawFrame();
[email protected]be782f52013-03-23 21:36:14892
[email protected]aa043632013-03-25 03:39:42893 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
894 DCHECK(scroll_layer);
[email protected]be782f52013-03-23 21:36:14895
[email protected]aa043632013-03-25 03:39:42896 float min_page_scale = 1.f;
897 float max_page_scale = 4.f;
[email protected]be782f52013-03-23 21:36:14898
[email protected]aa043632013-03-25 03:39:42899 // Basic pinch zoom in gesture
900 {
901 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
902 min_page_scale,
903 max_page_scale);
[email protected]aa043632013-03-25 03:39:42904 scroll_layer->SetScrollDelta(gfx::Vector2d());
[email protected]be782f52013-03-23 21:36:14905
[email protected]aa043632013-03-25 03:39:42906 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57907 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42908 host_impl_->PinchGestureBegin();
909 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
910 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57911 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42912 EXPECT_TRUE(did_request_redraw_);
913 EXPECT_TRUE(did_request_commit_);
[email protected]be782f52013-03-23 21:36:14914
[email protected]aa043632013-03-25 03:39:42915 scoped_ptr<ScrollAndScaleSet> scroll_info =
916 host_impl_->ProcessScrollDeltas();
917 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
918 }
919
920 // Zoom-in clamping
921 {
922 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
923 min_page_scale,
924 max_page_scale);
[email protected]aa043632013-03-25 03:39:42925 scroll_layer->SetScrollDelta(gfx::Vector2d());
926 float page_scale_delta = 10.f;
927
[email protected]9ec24df2013-08-09 23:32:57928 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42929 host_impl_->PinchGestureBegin();
930 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
931 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57932 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42933
934 scoped_ptr<ScrollAndScaleSet> scroll_info =
935 host_impl_->ProcessScrollDeltas();
936 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale);
937 }
938
939 // Zoom-out clamping
940 {
941 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
942 min_page_scale,
943 max_page_scale);
[email protected]aa043632013-03-25 03:39:42944 scroll_layer->SetScrollDelta(gfx::Vector2d());
945 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
946
947 float page_scale_delta = 0.1f;
[email protected]9ec24df2013-08-09 23:32:57948 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42949 host_impl_->PinchGestureBegin();
950 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
951 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57952 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42953
954 scoped_ptr<ScrollAndScaleSet> scroll_info =
955 host_impl_->ProcessScrollDeltas();
956 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
957
958 EXPECT_TRUE(scroll_info->scrolls.empty());
959 }
960
961 // Two-finger panning should not happen based on pinch events only
962 {
963 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
964 min_page_scale,
965 max_page_scale);
[email protected]aa043632013-03-25 03:39:42966 scroll_layer->SetScrollDelta(gfx::Vector2d());
967 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20));
968
969 float page_scale_delta = 1.f;
[email protected]9ec24df2013-08-09 23:32:57970 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42971 host_impl_->PinchGestureBegin();
972 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
973 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
974 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57975 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42976
977 scoped_ptr<ScrollAndScaleSet> scroll_info =
978 host_impl_->ProcessScrollDeltas();
979 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
980 EXPECT_TRUE(scroll_info->scrolls.empty());
981 }
982
983 // Two-finger panning should work with interleaved scroll events
984 {
985 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
986 min_page_scale,
987 max_page_scale);
[email protected]aa043632013-03-25 03:39:42988 scroll_layer->SetScrollDelta(gfx::Vector2d());
989 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20));
990
991 float page_scale_delta = 1.f;
[email protected]9ec24df2013-08-09 23:32:57992 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42993 host_impl_->PinchGestureBegin();
994 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
995 host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
996 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
997 host_impl_->PinchGestureEnd();
998 host_impl_->ScrollEnd();
999
1000 scoped_ptr<ScrollAndScaleSet> scroll_info =
1001 host_impl_->ProcessScrollDeltas();
1002 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
1003 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10));
1004 }
[email protected]9ec24df2013-08-09 23:32:571005
1006 // Two-finger panning should work when starting fully zoomed out.
1007 {
1008 host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f,
1009 0.5f,
1010 4.f);
1011 scroll_layer->SetScrollDelta(gfx::Vector2d());
1012 scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0));
1013 host_impl_->active_tree()->UpdateMaxScrollOffset();
1014
1015 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture);
1016 host_impl_->PinchGestureBegin();
1017 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
1018 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
1019 host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1020 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
1021 host_impl_->PinchGestureEnd();
1022 host_impl_->ScrollEnd();
1023
1024 scoped_ptr<ScrollAndScaleSet> scroll_info =
1025 host_impl_->ProcessScrollDeltas();
1026 EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
1027 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20));
1028 }
[email protected]be782f52013-03-23 21:36:141029}
1030
[email protected]aa043632013-03-25 03:39:421031TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
1032 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401033 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:421034 InitializeRendererAndDrawFrame();
[email protected]df8f44f2013-01-08 08:00:311035
[email protected]aa043632013-03-25 03:39:421036 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
1037 DCHECK(scroll_layer);
[email protected]df8f44f2013-01-08 08:00:311038
[email protected]aa043632013-03-25 03:39:421039 float min_page_scale = 0.5f;
1040 float max_page_scale = 4.f;
1041 base::TimeTicks start_time = base::TimeTicks() +
1042 base::TimeDelta::FromSeconds(1);
1043 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1044 base::TimeTicks halfway_through_animation = start_time + duration / 2;
1045 base::TimeTicks end_time = start_time + duration;
[email protected]aa043632013-03-25 03:39:421046
1047 // Non-anchor zoom-in
1048 {
1049 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1050 min_page_scale,
1051 max_page_scale);
[email protected]aa043632013-03-25 03:39:421052 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
1053
[email protected]34e1b512013-09-26 17:32:331054 host_impl_->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f, duration);
1055 did_request_redraw_ = false;
1056 host_impl_->Animate(start_time, base::Time());
1057 EXPECT_TRUE(did_request_redraw_);
1058
1059 did_request_redraw_ = false;
[email protected]aa043632013-03-25 03:39:421060 host_impl_->Animate(halfway_through_animation, base::Time());
1061 EXPECT_TRUE(did_request_redraw_);
[email protected]34e1b512013-09-26 17:32:331062
1063 did_request_redraw_ = false;
1064 did_request_commit_ = false;
[email protected]aa043632013-03-25 03:39:421065 host_impl_->Animate(end_time, base::Time());
1066 EXPECT_TRUE(did_request_commit_);
1067
1068 scoped_ptr<ScrollAndScaleSet> scroll_info =
1069 host_impl_->ProcessScrollDeltas();
1070 EXPECT_EQ(scroll_info->page_scale_delta, 2);
1071 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1072 }
1073
1074 // Anchor zoom-out
1075 {
1076 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1077 min_page_scale,
1078 max_page_scale);
[email protected]aa043632013-03-25 03:39:421079 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
1080
[email protected]34e1b512013-09-26 17:32:331081 host_impl_->StartPageScaleAnimation(
1082 gfx::Vector2d(25, 25), true, min_page_scale, duration);
1083 did_request_redraw_ = false;
1084 host_impl_->Animate(start_time, base::Time());
1085 EXPECT_TRUE(did_request_redraw_);
1086
1087 did_request_redraw_ = false;
1088 did_request_commit_ = false;
[email protected]aa043632013-03-25 03:39:421089 host_impl_->Animate(end_time, base::Time());
1090 EXPECT_TRUE(did_request_redraw_);
1091 EXPECT_TRUE(did_request_commit_);
1092
1093 scoped_ptr<ScrollAndScaleSet> scroll_info =
1094 host_impl_->ProcessScrollDeltas();
1095 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
1096 // Pushed to (0,0) via clamping against contents layer size.
1097 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1098 }
[email protected]df8f44f2013-01-08 08:00:311099}
1100
[email protected]aa043632013-03-25 03:39:421101TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
1102 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401103 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:421104 InitializeRendererAndDrawFrame();
[email protected]1c0c9bc2012-10-08 22:41:481105
[email protected]aa043632013-03-25 03:39:421106 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
1107 DCHECK(scroll_layer);
[email protected]1c0c9bc2012-10-08 22:41:481108
[email protected]aa043632013-03-25 03:39:421109 float min_page_scale = 0.5f;
1110 float max_page_scale = 4.f;
1111 base::TimeTicks start_time = base::TimeTicks() +
1112 base::TimeDelta::FromSeconds(1);
1113 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1114 base::TimeTicks halfway_through_animation = start_time + duration / 2;
1115 base::TimeTicks end_time = start_time + duration;
[email protected]1c0c9bc2012-10-08 22:41:481116
[email protected]aa043632013-03-25 03:39:421117 // Anchor zoom with unchanged page scale should not change scroll or scale.
1118 {
1119 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1120 min_page_scale,
1121 max_page_scale);
[email protected]aa043632013-03-25 03:39:421122 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
[email protected]c60279472013-01-30 12:10:511123
[email protected]34e1b512013-09-26 17:32:331124 host_impl_->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f, duration);
1125 host_impl_->Animate(start_time, base::Time());
[email protected]aa043632013-03-25 03:39:421126 host_impl_->Animate(halfway_through_animation, base::Time());
1127 EXPECT_TRUE(did_request_redraw_);
1128 host_impl_->Animate(end_time, base::Time());
1129 EXPECT_TRUE(did_request_commit_);
[email protected]c60279472013-01-30 12:10:511130
[email protected]aa043632013-03-25 03:39:421131 scoped_ptr<ScrollAndScaleSet> scroll_info =
1132 host_impl_->ProcessScrollDeltas();
1133 EXPECT_EQ(scroll_info->page_scale_delta, 1);
1134 ExpectNone(*scroll_info, scroll_layer->id());
1135 }
[email protected]1c0c9bc2012-10-08 22:41:481136}
1137
[email protected]21c9dee72013-06-15 01:20:051138class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
1139 public:
1140 LayerTreeHostImplOverridePhysicalTime(
1141 const LayerTreeSettings& settings,
1142 LayerTreeHostImplClient* client,
1143 Proxy* proxy,
1144 RenderingStatsInstrumentation* rendering_stats_instrumentation)
1145 : LayerTreeHostImpl(settings,
1146 client,
1147 proxy,
[email protected]a7f35682013-10-22 23:05:571148 rendering_stats_instrumentation,
1149 NULL) {}
[email protected]21c9dee72013-06-15 01:20:051150
1151 virtual base::TimeTicks CurrentPhysicalTimeTicks() const OVERRIDE {
1152 return fake_current_physical_time_;
1153 }
1154
1155 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) {
1156 fake_current_physical_time_ = fake_now;
1157 }
1158
1159 private:
1160 base::TimeTicks fake_current_physical_time_;
1161};
1162
1163TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
1164 LayerTreeSettings settings;
[email protected]fea161872013-08-27 22:34:591165 settings.scrollbar_animator = LayerTreeSettings::LinearFade;
[email protected]21c9dee72013-06-15 01:20:051166 settings.scrollbar_linear_fade_delay_ms = 20;
1167 settings.scrollbar_linear_fade_length_ms = 20;
1168
[email protected]4f0f43a2013-07-31 17:44:441169 gfx::Size viewport_size(10, 10);
1170 gfx::Size content_size(100, 100);
1171
[email protected]21c9dee72013-06-15 01:20:051172 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =
1173 new LayerTreeHostImplOverridePhysicalTime(
1174 settings, this, &proxy_, &stats_instrumentation_);
1175 host_impl_ = make_scoped_ptr<LayerTreeHostImpl>(host_impl_override_time);
1176 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]4f0f43a2013-07-31 17:44:441177 host_impl_->SetViewportSize(viewport_size);
[email protected]21c9dee72013-06-15 01:20:051178
[email protected]21c9dee72013-06-15 01:20:051179 scoped_ptr<LayerImpl> root =
1180 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]4f0f43a2013-07-31 17:44:441181 root->SetBounds(viewport_size);
[email protected]21c9dee72013-06-15 01:20:051182
1183 scoped_ptr<LayerImpl> scroll =
1184 LayerImpl::Create(host_impl_->active_tree(), 2);
1185 scroll->SetScrollable(true);
1186 scroll->SetScrollOffset(gfx::Vector2d());
1187 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
1188 content_size.height()));
1189 scroll->SetBounds(content_size);
1190 scroll->SetContentBounds(content_size);
1191
1192 scoped_ptr<LayerImpl> contents =
1193 LayerImpl::Create(host_impl_->active_tree(), 3);
1194 contents->SetDrawsContent(true);
1195 contents->SetBounds(content_size);
1196 contents->SetContentBounds(content_size);
1197
[email protected]3a83478b2013-08-22 20:55:171198 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
1199 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 4, VERTICAL);
[email protected]21c9dee72013-06-15 01:20:051200 scroll->SetVerticalScrollbarLayer(scrollbar.get());
1201
1202 scroll->AddChild(contents.Pass());
1203 root->AddChild(scroll.Pass());
1204 root->AddChild(scrollbar.PassAs<LayerImpl>());
1205
1206 host_impl_->active_tree()->SetRootLayer(root.Pass());
1207 host_impl_->active_tree()->DidBecomeActive();
1208 InitializeRendererAndDrawFrame();
1209
[email protected]de2cf8c2013-10-25 19:46:461210 base::TimeTicks fake_now = gfx::FrameTime::Now();
[email protected]21c9dee72013-06-15 01:20:051211 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1212
1213 // If no scroll happened recently, StartScrollbarAnimation should have no
1214 // effect.
1215 host_impl_->StartScrollbarAnimation();
1216 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1217 EXPECT_FALSE(did_request_redraw_);
1218
[email protected]cdc07002013-09-06 22:33:461219 // If no scroll happened during a scroll gesture, StartScrollbarAnimation
1220 // should have no effect.
[email protected]21c9dee72013-06-15 01:20:051221 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1222 host_impl_->ScrollEnd();
1223 host_impl_->StartScrollbarAnimation();
[email protected]cdc07002013-09-06 22:33:461224 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1225 EXPECT_FALSE(did_request_redraw_);
1226
1227 // After a scroll, a fade animation should be scheduled about 20ms from now.
1228 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1229 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1230 host_impl_->ScrollEnd();
1231 did_request_redraw_ = false;
1232 host_impl_->StartScrollbarAnimation();
[email protected]21c9dee72013-06-15 01:20:051233 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1234 requested_scrollbar_animation_delay_);
1235 EXPECT_FALSE(did_request_redraw_);
1236 requested_scrollbar_animation_delay_ = base::TimeDelta();
1237
1238 // After the fade begins, we should start getting redraws instead of a
1239 // scheduled animation.
1240 fake_now += base::TimeDelta::FromMilliseconds(25);
1241 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1242 host_impl_->StartScrollbarAnimation();
1243 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1244 EXPECT_TRUE(did_request_redraw_);
1245 did_request_redraw_ = false;
1246
1247 // If no scroll happened recently, StartScrollbarAnimation should have no
1248 // effect.
1249 fake_now += base::TimeDelta::FromMilliseconds(25);
1250 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1251 host_impl_->StartScrollbarAnimation();
1252 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1253 EXPECT_FALSE(did_request_redraw_);
1254
1255 // Setting the scroll offset outside a scroll should also cause the scrollbar
1256 // to appear and to schedule a fade.
1257 host_impl_->RootScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
1258 host_impl_->StartScrollbarAnimation();
1259 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1260 requested_scrollbar_animation_delay_);
1261 EXPECT_FALSE(did_request_redraw_);
1262 requested_scrollbar_animation_delay_ = base::TimeDelta();
1263
1264 // None of the above should have called CurrentFrameTimeTicks, so if we call
1265 // it now we should get the current time.
1266 fake_now += base::TimeDelta::FromMilliseconds(10);
1267 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1268 EXPECT_EQ(fake_now, host_impl_->CurrentFrameTimeTicks());
1269}
1270
[email protected]bf1cfd9a2013-09-26 05:43:021271void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1272 float device_scale_factor) {
1273 LayerTreeSettings settings;
1274 settings.scrollbar_animator = LayerTreeSettings::Thinning;
1275
1276 gfx::Size viewport_size(300, 200);
1277 gfx::Size device_viewport_size = gfx::ToFlooredSize(
1278 gfx::ScaleSize(viewport_size, device_scale_factor));
1279 gfx::Size content_size(1000, 1000);
1280
1281 host_impl_ = LayerTreeHostImpl::Create(
[email protected]a7f35682013-10-22 23:05:571282 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]bf1cfd9a2013-09-26 05:43:021283 host_impl_->InitializeRenderer(CreateOutputSurface());
1284 host_impl_->SetDeviceScaleFactor(device_scale_factor);
1285 host_impl_->SetViewportSize(device_viewport_size);
1286
1287 scoped_ptr<LayerImpl> root =
1288 LayerImpl::Create(host_impl_->active_tree(), 1);
1289 root->SetBounds(viewport_size);
1290
1291 scoped_ptr<LayerImpl> scroll =
1292 LayerImpl::Create(host_impl_->active_tree(), 2);
1293 scroll->SetScrollable(true);
1294 scroll->SetScrollOffset(gfx::Vector2d());
1295 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
1296 content_size.height()));
1297 scroll->SetBounds(content_size);
1298 scroll->SetContentBounds(content_size);
1299
1300 scoped_ptr<LayerImpl> contents =
1301 LayerImpl::Create(host_impl_->active_tree(), 3);
1302 contents->SetDrawsContent(true);
1303 contents->SetBounds(content_size);
1304 contents->SetContentBounds(content_size);
1305
1306 // The scrollbar is on the right side.
1307 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
1308 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL);
[email protected]f620b0e72013-10-01 21:38:241309 scrollbar->SetDrawsContent(true);
1310 scrollbar->SetBounds(gfx::Size(15, viewport_size.height()));
[email protected]bf1cfd9a2013-09-26 05:43:021311 scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height()));
1312 scrollbar->SetPosition(gfx::Point(285, 0));
1313 scroll->SetVerticalScrollbarLayer(scrollbar.get());
1314
1315 scroll->AddChild(contents.Pass());
1316 root->AddChild(scroll.Pass());
1317 root->AddChild(scrollbar.PassAs<LayerImpl>());
1318
1319 host_impl_->active_tree()->SetRootLayer(root.Pass());
1320 host_impl_->active_tree()->DidBecomeActive();
1321 InitializeRendererAndDrawFrame();
1322
1323 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1324 ASSERT_TRUE(root_scroll->scrollbar_animation_controller());
1325 ScrollbarAnimationControllerThinning* scrollbar_animation_controller =
1326 static_cast<ScrollbarAnimationControllerThinning*>(
1327 root_scroll->scrollbar_animation_controller());
1328 scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
1329
1330 host_impl_->MouseMoveAt(gfx::Point(1, 1));
[email protected]534236b2013-10-25 21:19:201331 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021332
[email protected]bf1cfd9a2013-09-26 05:43:021333 host_impl_->MouseMoveAt(gfx::Point(200, 50));
[email protected]534236b2013-10-25 21:19:201334 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021335
[email protected]bf1cfd9a2013-09-26 05:43:021336 host_impl_->MouseMoveAt(gfx::Point(184, 100));
[email protected]534236b2013-10-25 21:19:201337 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021338
1339 scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
[email protected]bf1cfd9a2013-09-26 05:43:021340 host_impl_->MouseMoveAt(gfx::Point(184, 100));
[email protected]534236b2013-10-25 21:19:201341 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
[email protected]f620b0e72013-10-01 21:38:241342
1343 did_request_redraw_ = false;
1344 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1345 host_impl_->MouseMoveAt(gfx::Point(290, 100));
1346 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1347 host_impl_->MouseMoveAt(gfx::Point(290, 120));
1348 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1349 host_impl_->MouseMoveAt(gfx::Point(150, 120));
1350 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
[email protected]bf1cfd9a2013-09-26 05:43:021351}
1352
1353TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
1354 SetupMouseMoveAtWithDeviceScale(1.f);
1355}
1356
1357TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
1358 SetupMouseMoveAtWithDeviceScale(2.f);
1359}
1360
[email protected]aa043632013-03-25 03:39:421361TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
1362 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401363 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:421364 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
1365 InitializeRendererAndDrawFrame();
1366 {
1367 CompositorFrameMetadata metadata =
1368 host_impl_->MakeCompositorFrameMetadata();
1369 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
1370 EXPECT_EQ(1.f, metadata.page_scale_factor);
1371 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.viewport_size);
1372 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1373 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1374 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1375 }
[email protected]94f206c12012-08-25 00:09:141376
[email protected]aa043632013-03-25 03:39:421377 // Scrolling should update metadata immediately.
[email protected]5ff3c9782013-04-29 17:35:121378 EXPECT_EQ(InputHandler::ScrollStarted,
1379 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421380 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1381 {
1382 CompositorFrameMetadata metadata =
1383 host_impl_->MakeCompositorFrameMetadata();
1384 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1385 }
1386 host_impl_->ScrollEnd();
1387 {
1388 CompositorFrameMetadata metadata =
1389 host_impl_->MakeCompositorFrameMetadata();
1390 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1391 }
[email protected]94f206c12012-08-25 00:09:141392
[email protected]aa043632013-03-25 03:39:421393 // Page scale should update metadata correctly (shrinking only the viewport).
[email protected]9ec24df2013-08-09 23:32:571394 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:421395 host_impl_->PinchGestureBegin();
1396 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
1397 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:571398 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:421399 {
1400 CompositorFrameMetadata metadata =
1401 host_impl_->MakeCompositorFrameMetadata();
1402 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1403 EXPECT_EQ(2.f, metadata.page_scale_factor);
1404 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.viewport_size);
1405 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1406 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1407 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1408 }
[email protected]94f206c12012-08-25 00:09:141409
[email protected]aa043632013-03-25 03:39:421410 // Likewise if set from the main thread.
1411 host_impl_->ProcessScrollDeltas();
1412 host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f);
1413 host_impl_->active_tree()->SetPageScaleDelta(1.f);
1414 {
1415 CompositorFrameMetadata metadata =
1416 host_impl_->MakeCompositorFrameMetadata();
1417 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1418 EXPECT_EQ(4.f, metadata.page_scale_factor);
1419 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.viewport_size);
1420 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1421 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1422 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1423 }
[email protected]f2b5a5be2013-01-08 00:34:361424}
1425
[email protected]96baf3e2012-10-22 23:09:551426class DidDrawCheckLayer : public TiledLayerImpl {
[email protected]aa043632013-03-25 03:39:421427 public:
1428 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
1429 return scoped_ptr<LayerImpl>(new DidDrawCheckLayer(tree_impl, id));
1430 }
[email protected]94f206c12012-08-25 00:09:141431
[email protected]ffbb2212013-06-02 23:47:591432 virtual bool WillDraw(DrawMode draw_mode, ResourceProvider* provider)
1433 OVERRIDE {
1434 will_draw_called_ = true;
1435 if (will_draw_returns_false_)
1436 return false;
1437 return TiledLayerImpl::WillDraw(draw_mode, provider);
1438 }
1439
1440 virtual void AppendQuads(QuadSink* quad_sink,
1441 AppendQuadsData* append_quads_data) OVERRIDE {
1442 append_quads_called_ = true;
1443 TiledLayerImpl::AppendQuads(quad_sink, append_quads_data);
1444 }
1445
[email protected]bf691c22013-03-26 21:15:061446 virtual void DidDraw(ResourceProvider* provider) OVERRIDE {
[email protected]aa043632013-03-25 03:39:421447 did_draw_called_ = true;
[email protected]ffbb2212013-06-02 23:47:591448 TiledLayerImpl::DidDraw(provider);
[email protected]aa043632013-03-25 03:39:421449 }
[email protected]94f206c12012-08-25 00:09:141450
[email protected]aa043632013-03-25 03:39:421451 bool will_draw_called() const { return will_draw_called_; }
[email protected]ffbb2212013-06-02 23:47:591452 bool append_quads_called() const { return append_quads_called_; }
1453 bool did_draw_called() const { return did_draw_called_; }
1454
1455 void set_will_draw_returns_false() { will_draw_returns_false_ = true; }
[email protected]94f206c12012-08-25 00:09:141456
[email protected]aa043632013-03-25 03:39:421457 void ClearDidDrawCheck() {
[email protected]aa043632013-03-25 03:39:421458 will_draw_called_ = false;
[email protected]ffbb2212013-06-02 23:47:591459 append_quads_called_ = false;
1460 did_draw_called_ = false;
[email protected]aa043632013-03-25 03:39:421461 }
[email protected]94f206c12012-08-25 00:09:141462
[email protected]aa043632013-03-25 03:39:421463 protected:
1464 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id)
1465 : TiledLayerImpl(tree_impl, id),
[email protected]ffbb2212013-06-02 23:47:591466 will_draw_returns_false_(false),
1467 will_draw_called_(false),
1468 append_quads_called_(false),
1469 did_draw_called_(false) {
[email protected]aa043632013-03-25 03:39:421470 SetAnchorPoint(gfx::PointF());
1471 SetBounds(gfx::Size(10, 10));
1472 SetContentBounds(gfx::Size(10, 10));
1473 SetDrawsContent(true);
1474 set_skips_draw(false);
1475 draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
[email protected]94f206c12012-08-25 00:09:141476
[email protected]aa043632013-03-25 03:39:421477 scoped_ptr<LayerTilingData> tiler =
1478 LayerTilingData::Create(gfx::Size(100, 100),
1479 LayerTilingData::HAS_BORDER_TEXELS);
1480 tiler->SetBounds(content_bounds());
1481 SetTilingData(*tiler.get());
1482 }
[email protected]94f206c12012-08-25 00:09:141483
[email protected]aa043632013-03-25 03:39:421484 private:
[email protected]ffbb2212013-06-02 23:47:591485 bool will_draw_returns_false_;
[email protected]aa043632013-03-25 03:39:421486 bool will_draw_called_;
[email protected]ffbb2212013-06-02 23:47:591487 bool append_quads_called_;
1488 bool did_draw_called_;
[email protected]94f206c12012-08-25 00:09:141489};
1490
[email protected]ffbb2212013-06-02 23:47:591491TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
1492 // The root layer is always drawn, so run this test on a child layer that
1493 // will be masked out by the root layer's bounds.
1494 host_impl_->active_tree()->SetRootLayer(
1495 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1496 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1497 host_impl_->active_tree()->root_layer());
1498
1499 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1500 DidDrawCheckLayer* layer =
1501 static_cast<DidDrawCheckLayer*>(root->children()[0]);
1502
1503 {
1504 LayerTreeHostImpl::FrameData frame;
1505 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
[email protected]de2cf8c2013-10-25 19:46:461506 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ffbb2212013-06-02 23:47:591507 host_impl_->DidDrawAllLayers(frame);
1508
1509 EXPECT_TRUE(layer->will_draw_called());
1510 EXPECT_TRUE(layer->append_quads_called());
1511 EXPECT_TRUE(layer->did_draw_called());
1512 }
1513
1514 {
1515 LayerTreeHostImpl::FrameData frame;
1516
1517 layer->set_will_draw_returns_false();
1518 layer->ClearDidDrawCheck();
1519
1520 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
[email protected]de2cf8c2013-10-25 19:46:461521 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ffbb2212013-06-02 23:47:591522 host_impl_->DidDrawAllLayers(frame);
1523
1524 EXPECT_TRUE(layer->will_draw_called());
1525 EXPECT_FALSE(layer->append_quads_called());
1526 EXPECT_FALSE(layer->did_draw_called());
1527 }
1528}
1529
[email protected]aa043632013-03-25 03:39:421530TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
1531 // The root layer is always drawn, so run this test on a child layer that
1532 // will be masked out by the root layer's bounds.
1533 host_impl_->active_tree()->SetRootLayer(
1534 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1535 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1536 host_impl_->active_tree()->root_layer());
1537 root->SetMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141538
[email protected]aa043632013-03-25 03:39:421539 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1540 DidDrawCheckLayer* layer =
1541 static_cast<DidDrawCheckLayer*>(root->children()[0]);
1542 // Ensure visible_content_rect for layer is empty.
1543 layer->SetPosition(gfx::PointF(100.f, 100.f));
1544 layer->SetBounds(gfx::Size(10, 10));
1545 layer->SetContentBounds(gfx::Size(10, 10));
[email protected]94f206c12012-08-25 00:09:141546
[email protected]aa043632013-03-25 03:39:421547 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141548
[email protected]aa043632013-03-25 03:39:421549 EXPECT_FALSE(layer->will_draw_called());
1550 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141551
[email protected]e0341352013-04-06 05:01:201552 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461553 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421554 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141555
[email protected]aa043632013-03-25 03:39:421556 EXPECT_FALSE(layer->will_draw_called());
1557 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141558
[email protected]aa043632013-03-25 03:39:421559 EXPECT_TRUE(layer->visible_content_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:141560
[email protected]aa043632013-03-25 03:39:421561 // Ensure visible_content_rect for layer is not empty
1562 layer->SetPosition(gfx::PointF());
[email protected]94f206c12012-08-25 00:09:141563
[email protected]aa043632013-03-25 03:39:421564 EXPECT_FALSE(layer->will_draw_called());
1565 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141566
[email protected]e0341352013-04-06 05:01:201567 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461568 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421569 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141570
[email protected]aa043632013-03-25 03:39:421571 EXPECT_TRUE(layer->will_draw_called());
1572 EXPECT_TRUE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141573
[email protected]aa043632013-03-25 03:39:421574 EXPECT_FALSE(layer->visible_content_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:141575}
1576
[email protected]aa043632013-03-25 03:39:421577TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
1578 gfx::Size big_size(1000, 1000);
[email protected]18ce59702013-04-09 04:58:401579 host_impl_->SetViewportSize(big_size);
[email protected]94f206c12012-08-25 00:09:141580
[email protected]aa043632013-03-25 03:39:421581 host_impl_->active_tree()->SetRootLayer(
1582 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1583 DidDrawCheckLayer* root =
1584 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:141585
[email protected]aa043632013-03-25 03:39:421586 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1587 DidDrawCheckLayer* occluded_layer =
1588 static_cast<DidDrawCheckLayer*>(root->children()[0]);
[email protected]94f206c12012-08-25 00:09:141589
[email protected]aa043632013-03-25 03:39:421590 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1591 DidDrawCheckLayer* top_layer =
1592 static_cast<DidDrawCheckLayer*>(root->children()[1]);
1593 // This layer covers the occluded_layer above. Make this layer large so it can
1594 // occlude.
1595 top_layer->SetBounds(big_size);
1596 top_layer->SetContentBounds(big_size);
1597 top_layer->SetContentsOpaque(true);
[email protected]94f206c12012-08-25 00:09:141598
[email protected]aa043632013-03-25 03:39:421599 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141600
[email protected]aa043632013-03-25 03:39:421601 EXPECT_FALSE(occluded_layer->will_draw_called());
1602 EXPECT_FALSE(occluded_layer->did_draw_called());
1603 EXPECT_FALSE(top_layer->will_draw_called());
1604 EXPECT_FALSE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141605
[email protected]e0341352013-04-06 05:01:201606 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461607 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421608 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141609
[email protected]aa043632013-03-25 03:39:421610 EXPECT_FALSE(occluded_layer->will_draw_called());
1611 EXPECT_FALSE(occluded_layer->did_draw_called());
1612 EXPECT_TRUE(top_layer->will_draw_called());
1613 EXPECT_TRUE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141614}
1615
[email protected]aa043632013-03-25 03:39:421616TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
1617 host_impl_->active_tree()->SetRootLayer(
1618 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1619 DidDrawCheckLayer* root =
1620 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:141621
[email protected]aa043632013-03-25 03:39:421622 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1623 DidDrawCheckLayer* layer1 =
1624 static_cast<DidDrawCheckLayer*>(root->children()[0]);
[email protected]94f206c12012-08-25 00:09:141625
[email protected]aa043632013-03-25 03:39:421626 layer1->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1627 DidDrawCheckLayer* layer2 =
1628 static_cast<DidDrawCheckLayer*>(layer1->children()[0]);
[email protected]94f206c12012-08-25 00:09:141629
[email protected]aa043632013-03-25 03:39:421630 layer1->SetOpacity(0.3f);
1631 layer1->SetPreserves3d(false);
[email protected]94f206c12012-08-25 00:09:141632
[email protected]aa043632013-03-25 03:39:421633 EXPECT_FALSE(root->did_draw_called());
1634 EXPECT_FALSE(layer1->did_draw_called());
1635 EXPECT_FALSE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141636
[email protected]aa043632013-03-25 03:39:421637 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:201638 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461639 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421640 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141641
[email protected]aa043632013-03-25 03:39:421642 EXPECT_TRUE(root->did_draw_called());
1643 EXPECT_TRUE(layer1->did_draw_called());
1644 EXPECT_TRUE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141645
[email protected]aa043632013-03-25 03:39:421646 EXPECT_NE(root->render_surface(), layer1->render_surface());
1647 EXPECT_TRUE(!!layer1->render_surface());
[email protected]94f206c12012-08-25 00:09:141648}
1649
1650class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
[email protected]aa043632013-03-25 03:39:421651 public:
1652 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
1653 int id,
1654 bool tile_missing,
1655 bool skips_draw,
1656 bool animating,
1657 ResourceProvider* resource_provider) {
1658 return scoped_ptr<LayerImpl>(new MissingTextureAnimatingLayer(
1659 tree_impl,
1660 id,
1661 tile_missing,
1662 skips_draw,
1663 animating,
1664 resource_provider));
1665 }
[email protected]94f206c12012-08-25 00:09:141666
[email protected]aa043632013-03-25 03:39:421667 private:
1668 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl,
1669 int id,
1670 bool tile_missing,
1671 bool skips_draw,
1672 bool animating,
1673 ResourceProvider* resource_provider)
1674 : DidDrawCheckLayer(tree_impl, id) {
1675 scoped_ptr<LayerTilingData> tiling_data =
1676 LayerTilingData::Create(gfx::Size(10, 10),
1677 LayerTilingData::NO_BORDER_TEXELS);
1678 tiling_data->SetBounds(bounds());
1679 SetTilingData(*tiling_data.get());
1680 set_skips_draw(skips_draw);
1681 if (!tile_missing) {
1682 ResourceProvider::ResourceId resource =
[email protected]cdccc7d42013-05-03 17:15:071683 resource_provider->CreateResource(gfx::Size(1, 1),
[email protected]efa48412013-09-05 15:30:161684 GL_CLAMP_TO_EDGE,
[email protected]27a41fe2013-09-19 05:05:141685 ResourceProvider::TextureUsageAny,
1686 RGBA_8888);
[email protected]aa043632013-03-25 03:39:421687 resource_provider->AllocateForTesting(resource);
1688 PushTileProperties(0, 0, resource, gfx::Rect(), false);
[email protected]94f206c12012-08-25 00:09:141689 }
[email protected]aa043632013-03-25 03:39:421690 if (animating)
1691 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1692 }
[email protected]94f206c12012-08-25 00:09:141693};
1694
[email protected]aa043632013-03-25 03:39:421695TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
1696 // When the texture is not missing, we draw as usual.
1697 host_impl_->active_tree()->SetRootLayer(
1698 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1699 DidDrawCheckLayer* root =
1700 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1701 root->AddChild(
1702 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1703 2,
1704 false,
1705 false,
1706 true,
1707 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141708
[email protected]aa043632013-03-25 03:39:421709 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141710
[email protected]e0341352013-04-06 05:01:201711 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461712 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421713 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141714
[email protected]aa043632013-03-25 03:39:421715 // When a texture is missing and we're not animating, we draw as usual with
1716 // checkerboarding.
1717 host_impl_->active_tree()->SetRootLayer(
1718 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1719 root =
1720 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1721 root->AddChild(
1722 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1723 4,
1724 true,
1725 false,
1726 false,
1727 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141728
[email protected]e0341352013-04-06 05:01:201729 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461730 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421731 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141732
[email protected]aa043632013-03-25 03:39:421733 // When a texture is missing and we're animating, we don't want to draw
1734 // anything.
1735 host_impl_->active_tree()->SetRootLayer(
1736 DidDrawCheckLayer::Create(host_impl_->active_tree(), 5));
1737 root =
1738 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1739 root->AddChild(
1740 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1741 6,
1742 true,
1743 false,
1744 true,
1745 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141746
[email protected]e0341352013-04-06 05:01:201747 EXPECT_FALSE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461748 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421749 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141750
[email protected]aa043632013-03-25 03:39:421751 // When the layer skips draw and we're animating, we still draw the frame.
1752 host_impl_->active_tree()->SetRootLayer(
1753 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7));
1754 root =
1755 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1756 root->AddChild(
1757 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1758 8,
1759 false,
1760 true,
1761 true,
1762 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141763
[email protected]e0341352013-04-06 05:01:201764 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:461765 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:421766 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141767}
1768
[email protected]aa043632013-03-25 03:39:421769TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
1770 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1771 root->SetScrollable(false);
1772 host_impl_->active_tree()->SetRootLayer(root.Pass());
1773 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141774
[email protected]aa043632013-03-25 03:39:421775 // Scroll event is ignored because layer is not scrollable.
[email protected]5ff3c9782013-04-29 17:35:121776 EXPECT_EQ(InputHandler::ScrollIgnored,
1777 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421778 EXPECT_FALSE(did_request_redraw_);
1779 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141780}
1781
[email protected]aa043632013-03-25 03:39:421782TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) {
1783 LayerTreeSettings settings;
1784 settings.calculate_top_controls_position = true;
1785 settings.top_controls_height = 50;
[email protected]c8415bf92013-02-17 18:57:271786
[email protected]a7f35682013-10-22 23:05:571787 host_impl_ = LayerTreeHostImpl::Create(
1788 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]aa043632013-03-25 03:39:421789 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]18ce59702013-04-09 04:58:401790 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]c8415bf92013-02-17 18:57:271791
[email protected]aa043632013-03-25 03:39:421792 gfx::Size layer_size(5, 5);
1793 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1794 root->SetScrollable(true);
1795 root->SetMaxScrollOffset(gfx::Vector2d(layer_size.width(),
1796 layer_size.height()));
1797 root->SetBounds(layer_size);
1798 root->SetContentBounds(layer_size);
1799 root->SetPosition(gfx::PointF());
1800 root->SetAnchorPoint(gfx::PointF());
[email protected]e0341352013-04-06 05:01:201801 root->SetDrawsContent(false);
[email protected]aa043632013-03-25 03:39:421802 host_impl_->active_tree()->SetRootLayer(root.Pass());
1803 host_impl_->active_tree()->FindRootScrollLayer();
1804 InitializeRendererAndDrawFrame();
[email protected]c8415bf92013-02-17 18:57:271805
[email protected]5ff3c9782013-04-29 17:35:121806 EXPECT_EQ(InputHandler::ScrollIgnored,
1807 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]c8415bf92013-02-17 18:57:271808
[email protected]aa043632013-03-25 03:39:421809 host_impl_->top_controls_manager()->ScrollBegin();
1810 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
1811 host_impl_->top_controls_manager()->ScrollEnd();
1812 EXPECT_EQ(host_impl_->top_controls_manager()->content_top_offset(), 0.f);
[email protected]c8415bf92013-02-17 18:57:271813
[email protected]5ff3c9782013-04-29 17:35:121814 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421815 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:121816 InputHandler::Gesture));
[email protected]c8415bf92013-02-17 18:57:271817}
1818
[email protected]aa043632013-03-25 03:39:421819TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
1820 // Test the configuration where a non-composited root layer is embedded in a
1821 // scrollable outer layer.
1822 gfx::Size surface_size(10, 10);
[email protected]94f206c12012-08-25 00:09:141823
[email protected]aa043632013-03-25 03:39:421824 scoped_ptr<LayerImpl> content_layer =
1825 LayerImpl::Create(host_impl_->active_tree(), 1);
1826 content_layer->SetDrawsContent(true);
1827 content_layer->SetPosition(gfx::PointF());
1828 content_layer->SetAnchorPoint(gfx::PointF());
1829 content_layer->SetBounds(surface_size);
1830 content_layer->SetContentBounds(gfx::Size(surface_size.width() * 2,
1831 surface_size.height() * 2));
1832 content_layer->SetContentsScale(2.f, 2.f);
[email protected]94f206c12012-08-25 00:09:141833
[email protected]aa043632013-03-25 03:39:421834 scoped_ptr<LayerImpl> scroll_layer =
1835 LayerImpl::Create(host_impl_->active_tree(), 2);
1836 scroll_layer->SetScrollable(true);
1837 scroll_layer->SetMaxScrollOffset(gfx::Vector2d(surface_size.width(),
1838 surface_size.height()));
1839 scroll_layer->SetBounds(surface_size);
1840 scroll_layer->SetContentBounds(surface_size);
1841 scroll_layer->SetPosition(gfx::PointF());
1842 scroll_layer->SetAnchorPoint(gfx::PointF());
1843 scroll_layer->AddChild(content_layer.Pass());
[email protected]94f206c12012-08-25 00:09:141844
[email protected]aa043632013-03-25 03:39:421845 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass());
[email protected]18ce59702013-04-09 04:58:401846 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421847 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141848
[email protected]5ff3c9782013-04-29 17:35:121849 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421850 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121851 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421852 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1853 host_impl_->ScrollEnd();
1854 EXPECT_TRUE(did_request_redraw_);
1855 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141856}
1857
[email protected]aa043632013-03-25 03:39:421858TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
1859 gfx::Size surface_size(10, 10);
1860 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1861 root->SetBounds(surface_size);
1862 root->SetContentBounds(surface_size);
1863 root->AddChild(CreateScrollableLayer(2, surface_size));
1864 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:401865 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421866 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141867
[email protected]5ff3c9782013-04-29 17:35:121868 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421869 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121870 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421871 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1872 host_impl_->ScrollEnd();
1873 EXPECT_TRUE(did_request_redraw_);
1874 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141875}
1876
[email protected]aa043632013-03-25 03:39:421877TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
1878 gfx::Size surface_size(10, 10);
1879 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1880 root->AddChild(CreateScrollableLayer(2, surface_size));
1881 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:401882 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421883 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141884
[email protected]aa043632013-03-25 03:39:421885 // Scroll event is ignored because the input coordinate is outside the layer
1886 // boundaries.
[email protected]5ff3c9782013-04-29 17:35:121887 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]aa043632013-03-25 03:39:421888 host_impl_->ScrollBegin(gfx::Point(15, 5),
[email protected]5ff3c9782013-04-29 17:35:121889 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421890 EXPECT_FALSE(did_request_redraw_);
1891 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141892}
1893
[email protected]aa043632013-03-25 03:39:421894TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
1895 gfx::Size surface_size(10, 10);
1896 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1897 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
[email protected]18ce59702013-04-09 04:58:401898 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:141899
[email protected]aa043632013-03-25 03:39:421900 gfx::Transform matrix;
1901 matrix.RotateAboutXAxis(180.0);
1902 child->SetTransform(matrix);
1903 child->SetDoubleSided(false);
[email protected]94f206c12012-08-25 00:09:141904
[email protected]aa043632013-03-25 03:39:421905 root->AddChild(child.Pass());
1906 host_impl_->active_tree()->SetRootLayer(root.Pass());
1907 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141908
[email protected]aa043632013-03-25 03:39:421909 // Scroll event is ignored because the scrollable layer is not facing the
1910 // viewer and there is nothing scrollable behind it.
[email protected]5ff3c9782013-04-29 17:35:121911 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]aa043632013-03-25 03:39:421912 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121913 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421914 EXPECT_FALSE(did_request_redraw_);
1915 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141916}
1917
[email protected]aa043632013-03-25 03:39:421918TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
1919 gfx::Size surface_size(10, 10);
1920 scoped_ptr<LayerImpl> content_layer = CreateScrollableLayer(1, surface_size);
1921 content_layer->SetShouldScrollOnMainThread(true);
1922 content_layer->SetScrollable(false);
[email protected]94f206c12012-08-25 00:09:141923
[email protected]aa043632013-03-25 03:39:421924 scoped_ptr<LayerImpl> scroll_layer = CreateScrollableLayer(2, surface_size);
1925 scroll_layer->AddChild(content_layer.Pass());
[email protected]94f206c12012-08-25 00:09:141926
[email protected]aa043632013-03-25 03:39:421927 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass());
[email protected]18ce59702013-04-09 04:58:401928 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421929 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141930
[email protected]aa043632013-03-25 03:39:421931 // Scrolling fails because the content layer is asking to be scrolled on the
1932 // main thread.
[email protected]5ff3c9782013-04-29 17:35:121933 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:421934 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121935 InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:141936}
1937
[email protected]aa043632013-03-25 03:39:421938TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
1939 gfx::Size surface_size(10, 10);
1940 float page_scale = 2.f;
[email protected]9781afa2013-07-17 23:15:321941 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1942 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
1943 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421944 host_impl_->active_tree()->SetRootLayer(root.Pass());
1945 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401946 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421947 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141948
[email protected]9781afa2013-07-17 23:15:321949 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1950
[email protected]aa043632013-03-25 03:39:421951 gfx::Vector2d scroll_delta(0, 10);
1952 gfx::Vector2d expected_scroll_delta = scroll_delta;
[email protected]9781afa2013-07-17 23:15:321953 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset();
[email protected]5ff3c9782013-04-29 17:35:121954 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421955 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121956 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421957 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1958 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141959
[email protected]aa043632013-03-25 03:39:421960 // Set new page scale from main thread.
1961 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
1962 page_scale,
1963 page_scale);
[email protected]94f206c12012-08-25 00:09:141964
[email protected]aa043632013-03-25 03:39:421965 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:321966 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:141967
[email protected]aa043632013-03-25 03:39:421968 // The scroll range should also have been updated.
[email protected]9781afa2013-07-17 23:15:321969 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset());
[email protected]94f206c12012-08-25 00:09:141970
[email protected]aa043632013-03-25 03:39:421971 // The page scale delta remains constant because the impl thread did not
1972 // scale.
[email protected]f2136262013-04-26 21:10:191973 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:141974}
1975
[email protected]aa043632013-03-25 03:39:421976TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
1977 gfx::Size surface_size(10, 10);
1978 float page_scale = 2.f;
[email protected]9781afa2013-07-17 23:15:321979 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1980 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
1981 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421982 host_impl_->active_tree()->SetRootLayer(root.Pass());
1983 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401984 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421985 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale);
1986 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141987
[email protected]9781afa2013-07-17 23:15:321988 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1989
[email protected]aa043632013-03-25 03:39:421990 gfx::Vector2d scroll_delta(0, 10);
1991 gfx::Vector2d expected_scroll_delta = scroll_delta;
[email protected]9781afa2013-07-17 23:15:321992 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset();
[email protected]5ff3c9782013-04-29 17:35:121993 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421994 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121995 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421996 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1997 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141998
[email protected]aa043632013-03-25 03:39:421999 // Set new page scale on impl thread by pinching.
[email protected]9ec24df2013-08-09 23:32:572000 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:422001 host_impl_->PinchGestureBegin();
2002 host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
2003 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:572004 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:422005 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:142006
[email protected]aa043632013-03-25 03:39:422007 // The scroll delta is not scaled because the main thread did not scale.
2008 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:322009 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142010
[email protected]aa043632013-03-25 03:39:422011 // The scroll range should also have been updated.
[email protected]9781afa2013-07-17 23:15:322012 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset());
[email protected]94f206c12012-08-25 00:09:142013
[email protected]aa043632013-03-25 03:39:422014 // The page scale delta should match the new scale on the impl side.
[email protected]f2136262013-04-26 21:10:192015 EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:142016}
2017
[email protected]aa043632013-03-25 03:39:422018TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
2019 gfx::Size surface_size(10, 10);
2020 float default_page_scale = 1.f;
2021 gfx::Transform default_page_scale_matrix;
[email protected]3209161d2013-03-29 19:17:342022 default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
[email protected]1c0c9bc2012-10-08 22:41:482023
[email protected]aa043632013-03-25 03:39:422024 float new_page_scale = 2.f;
2025 gfx::Transform new_page_scale_matrix;
2026 new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
[email protected]94f206c12012-08-25 00:09:142027
[email protected]aa043632013-03-25 03:39:422028 // Create a normal scrollable root layer and another scrollable child layer.
[email protected]35a99a12013-05-09 23:52:292029 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
[email protected]aa043632013-03-25 03:39:422030 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]35a99a12013-05-09 23:52:292031 LayerImpl* child = scroll->children()[0];
[email protected]94f206c12012-08-25 00:09:142032
[email protected]aa043632013-03-25 03:39:422033 scoped_ptr<LayerImpl> scrollable_child =
[email protected]35a99a12013-05-09 23:52:292034 CreateScrollableLayer(4, surface_size);
[email protected]aa043632013-03-25 03:39:422035 child->AddChild(scrollable_child.Pass());
2036 LayerImpl* grand_child = child->children()[0];
[email protected]94f206c12012-08-25 00:09:142037
[email protected]aa043632013-03-25 03:39:422038 // Set new page scale on impl thread by pinching.
[email protected]9ec24df2013-08-09 23:32:572039 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:422040 host_impl_->PinchGestureBegin();
2041 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
2042 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:572043 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:422044 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:142045
[email protected]f2136262013-04-26 21:10:192046 EXPECT_EQ(1.f, root->contents_scale_x());
2047 EXPECT_EQ(1.f, root->contents_scale_y());
[email protected]35a99a12013-05-09 23:52:292048 EXPECT_EQ(1.f, scroll->contents_scale_x());
2049 EXPECT_EQ(1.f, scroll->contents_scale_y());
[email protected]f2136262013-04-26 21:10:192050 EXPECT_EQ(1.f, child->contents_scale_x());
2051 EXPECT_EQ(1.f, child->contents_scale_y());
2052 EXPECT_EQ(1.f, grand_child->contents_scale_x());
2053 EXPECT_EQ(1.f, grand_child->contents_scale_y());
[email protected]94f206c12012-08-25 00:09:142054
[email protected]aa043632013-03-25 03:39:422055 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
2056 // the page scale delta on the root layer is applied hierarchically.
2057 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:202058 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462059 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422060 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142061
[email protected]35a99a12013-05-09 23:52:292062 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0));
2063 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(1, 1));
2064 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(0, 0));
2065 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(1, 1));
[email protected]aa043632013-03-25 03:39:422066 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(0, 0));
2067 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(1, 1));
2068 EXPECT_EQ(new_page_scale,
2069 grand_child->draw_transform().matrix().getDouble(0, 0));
2070 EXPECT_EQ(new_page_scale,
2071 grand_child->draw_transform().matrix().getDouble(1, 1));
[email protected]94f206c12012-08-25 00:09:142072}
2073
[email protected]aa043632013-03-25 03:39:422074TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
2075 gfx::Size surface_size(10, 10);
2076 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]9781afa2013-07-17 23:15:322077 scoped_ptr<LayerImpl> root_scrolling =
2078 LayerImpl::Create(host_impl_->active_tree(), 2);
2079 root_scrolling->SetBounds(surface_size);
2080 root_scrolling->SetContentBounds(surface_size);
2081 root_scrolling->SetScrollable(true);
2082 root->AddChild(root_scrolling.Pass());
2083 int child_scroll_layer_id = 3;
2084 scoped_ptr<LayerImpl> child_scrolling =
2085 CreateScrollableLayer(child_scroll_layer_id, surface_size);
2086 LayerImpl* child = child_scrolling.get();
2087 root->AddChild(child_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:422088 host_impl_->active_tree()->SetRootLayer(root.Pass());
2089 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402090 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422091 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:142092
[email protected]aa043632013-03-25 03:39:422093 gfx::Vector2d scroll_delta(0, 10);
2094 gfx::Vector2d expected_scroll_delta(scroll_delta);
2095 gfx::Vector2d expected_max_scroll(child->max_scroll_offset());
[email protected]5ff3c9782013-04-29 17:35:122096 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422097 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122098 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422099 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2100 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142101
[email protected]aa043632013-03-25 03:39:422102 float page_scale = 2.f;
2103 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
2104 1.f,
2105 page_scale);
[email protected]94f206c12012-08-25 00:09:142106
[email protected]aa043632013-03-25 03:39:422107 DrawOneFrame();
[email protected]1c0c9bc2012-10-08 22:41:482108
[email protected]aa043632013-03-25 03:39:422109 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:322110 ExpectContains(
2111 *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142112
[email protected]aa043632013-03-25 03:39:422113 // The scroll range should not have changed.
2114 EXPECT_EQ(child->max_scroll_offset(), expected_max_scroll);
[email protected]94f206c12012-08-25 00:09:142115
[email protected]aa043632013-03-25 03:39:422116 // The page scale delta remains constant because the impl thread did not
2117 // scale.
[email protected]f2136262013-04-26 21:10:192118 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:142119}
2120
[email protected]aa043632013-03-25 03:39:422121TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
2122 // Scroll a child layer beyond its maximum scroll range and make sure the
2123 // parent layer is scrolled on the axis on which the child was unable to
2124 // scroll.
2125 gfx::Size surface_size(10, 10);
2126 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size);
[email protected]94f206c12012-08-25 00:09:142127
[email protected]aa043632013-03-25 03:39:422128 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size);
2129 grand_child->SetScrollOffset(gfx::Vector2d(0, 5));
[email protected]94f206c12012-08-25 00:09:142130
[email protected]aa043632013-03-25 03:39:422131 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
2132 child->SetScrollOffset(gfx::Vector2d(3, 0));
2133 child->AddChild(grand_child.Pass());
[email protected]94f206c12012-08-25 00:09:142134
[email protected]aa043632013-03-25 03:39:422135 root->AddChild(child.Pass());
2136 host_impl_->active_tree()->SetRootLayer(root.Pass());
2137 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402138 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422139 InitializeRendererAndDrawFrame();
2140 {
2141 gfx::Vector2d scroll_delta(-8, -7);
[email protected]5ff3c9782013-04-29 17:35:122142 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472143 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122144 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422145 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2146 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142147
[email protected]aa043632013-03-25 03:39:422148 scoped_ptr<ScrollAndScaleSet> scroll_info =
2149 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:142150
[email protected]aa043632013-03-25 03:39:422151 // The grand child should have scrolled up to its limit.
2152 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
2153 LayerImpl* grand_child = child->children()[0];
2154 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5));
[email protected]94f206c12012-08-25 00:09:142155
[email protected]aa043632013-03-25 03:39:422156 // The child should have only scrolled on the other axis.
2157 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0));
2158 }
[email protected]94f206c12012-08-25 00:09:142159}
2160
[email protected]aa043632013-03-25 03:39:422161TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
2162 // Scroll a child layer beyond its maximum scroll range and make sure the
2163 // the scroll doesn't bubble up to the parent layer.
2164 gfx::Size surface_size(10, 10);
[email protected]9781afa2013-07-17 23:15:322165 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2166 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
[email protected]7dfa6862013-01-31 01:29:092167
[email protected]9781afa2013-07-17 23:15:322168 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(4, surface_size);
[email protected]aa043632013-03-25 03:39:422169 grand_child->SetScrollOffset(gfx::Vector2d(0, 2));
[email protected]7dfa6862013-01-31 01:29:092170
[email protected]9781afa2013-07-17 23:15:322171 scoped_ptr<LayerImpl> child = CreateScrollableLayer(3, surface_size);
[email protected]aa043632013-03-25 03:39:422172 child->SetScrollOffset(gfx::Vector2d(0, 3));
2173 child->AddChild(grand_child.Pass());
[email protected]7dfa6862013-01-31 01:29:092174
[email protected]9781afa2013-07-17 23:15:322175 root_scrolling->AddChild(child.Pass());
2176 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:422177 host_impl_->active_tree()->SetRootLayer(root.Pass());
2178 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402179 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422180 InitializeRendererAndDrawFrame();
2181 {
2182 gfx::Vector2d scroll_delta(0, -10);
[email protected]5ff3c9782013-04-29 17:35:122183 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472184 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122185 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422186 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2187 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092188
[email protected]aa043632013-03-25 03:39:422189 scoped_ptr<ScrollAndScaleSet> scroll_info =
2190 host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092191
[email protected]aa043632013-03-25 03:39:422192 // The grand child should have scrolled up to its limit.
[email protected]9781afa2013-07-17 23:15:322193 LayerImpl* child =
2194 host_impl_->active_tree()->root_layer()->children()[0]->children()[0];
[email protected]aa043632013-03-25 03:39:422195 LayerImpl* grand_child = child->children()[0];
2196 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
[email protected]7dfa6862013-01-31 01:29:092197
[email protected]aa043632013-03-25 03:39:422198 // The child should not have scrolled.
2199 ExpectNone(*scroll_info.get(), child->id());
[email protected]7dfa6862013-01-31 01:29:092200
[email protected]aa043632013-03-25 03:39:422201 // The next time we scroll we should only scroll the parent.
2202 scroll_delta = gfx::Vector2d(0, -3);
[email protected]5ff3c9782013-04-29 17:35:122203 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422204 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122205 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422206 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2207 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2208 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
2209 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092210
[email protected]aa043632013-03-25 03:39:422211 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092212
[email protected]aa043632013-03-25 03:39:422213 // The child should have scrolled up to its limit.
2214 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
[email protected]7dfa6862013-01-31 01:29:092215
[email protected]aa043632013-03-25 03:39:422216 // The grand child should not have scrolled.
2217 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
[email protected]7dfa6862013-01-31 01:29:092218
[email protected]aa043632013-03-25 03:39:422219 // After scrolling the parent, another scroll on the opposite direction
2220 // should still scroll the child.
2221 scroll_delta = gfx::Vector2d(0, 7);
[email protected]5ff3c9782013-04-29 17:35:122222 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422223 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122224 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422225 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2226 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2227 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2228 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092229
[email protected]aa043632013-03-25 03:39:422230 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092231
[email protected]aa043632013-03-25 03:39:422232 // The grand child should have scrolled.
2233 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5));
[email protected]7dfa6862013-01-31 01:29:092234
[email protected]aa043632013-03-25 03:39:422235 // The child should not have scrolled.
2236 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
[email protected]f4937272013-02-07 05:54:502237
2238
[email protected]aa043632013-03-25 03:39:422239 // Scrolling should be adjusted from viewport space.
2240 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f);
2241 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]f4937272013-02-07 05:54:502242
[email protected]aa043632013-03-25 03:39:422243 scroll_delta = gfx::Vector2d(0, -2);
[email protected]5ff3c9782013-04-29 17:35:122244 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422245 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122246 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422247 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer());
2248 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2249 host_impl_->ScrollEnd();
[email protected]f4937272013-02-07 05:54:502250
[email protected]aa043632013-03-25 03:39:422251 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]f4937272013-02-07 05:54:502252
[email protected]aa043632013-03-25 03:39:422253 // Should have scrolled by half the amount in layer space (5 - 2/2)
2254 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4));
2255 }
[email protected]7dfa6862013-01-31 01:29:092256}
2257
[email protected]aa043632013-03-25 03:39:422258TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
2259 // When we try to scroll a non-scrollable child layer, the scroll delta
2260 // should be applied to one of its ancestors if possible.
2261 gfx::Size surface_size(10, 10);
2262 gfx::Size content_size(20, 20);
2263 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
2264 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
[email protected]94f206c12012-08-25 00:09:142265
[email protected]aa043632013-03-25 03:39:422266 child->SetScrollable(false);
2267 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:142268
[email protected]18ce59702013-04-09 04:58:402269 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422270 host_impl_->active_tree()->SetRootLayer(root.Pass());
2271 host_impl_->active_tree()->DidBecomeActive();
2272 InitializeRendererAndDrawFrame();
2273 {
2274 gfx::Vector2d scroll_delta(0, 4);
[email protected]5ff3c9782013-04-29 17:35:122275 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422276 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122277 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422278 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2279 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142280
[email protected]aa043632013-03-25 03:39:422281 scoped_ptr<ScrollAndScaleSet> scroll_info =
2282 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:142283
[email protected]aa043632013-03-25 03:39:422284 // Only the root should have scrolled.
2285 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
2286 ExpectContains(*scroll_info.get(),
2287 host_impl_->active_tree()->root_layer()->id(),
2288 scroll_delta);
2289 }
[email protected]94f206c12012-08-25 00:09:142290}
2291
[email protected]aa043632013-03-25 03:39:422292TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
2293 gfx::Size surface_size(10, 10);
2294 host_impl_->active_tree()->SetRootLayer(
2295 CreateScrollableLayer(1, surface_size));
2296 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402297 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:142298
[email protected]aa043632013-03-25 03:39:422299 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2300 // synchronization.
2301 InitializeRendererAndDrawFrame();
2302 host_impl_->active_tree()->DetachLayerTree();
2303 host_impl_->active_tree()->SetRootLayer(
2304 CreateScrollableLayer(2, surface_size));
2305 host_impl_->active_tree()->DidBecomeActive();
[email protected]94f206c12012-08-25 00:09:142306
[email protected]aa043632013-03-25 03:39:422307 // Scrolling should still work even though we did not draw yet.
[email protected]5ff3c9782013-04-29 17:35:122308 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422309 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122310 InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:142311}
2312
[email protected]aa043632013-03-25 03:39:422313TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:292314 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:142315
[email protected]aa043632013-03-25 03:39:422316 // Rotate the root layer 90 degrees counter-clockwise about its center.
2317 gfx::Transform rotate_transform;
2318 rotate_transform.Rotate(-90.0);
2319 host_impl_->active_tree()->root_layer()->SetTransform(rotate_transform);
[email protected]94f206c12012-08-25 00:09:142320
[email protected]aa043632013-03-25 03:39:422321 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402322 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422323 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:142324
[email protected]aa043632013-03-25 03:39:422325 // Scroll to the right in screen coordinates with a gesture.
2326 gfx::Vector2d gesture_scroll_delta(10, 0);
[email protected]5ff3c9782013-04-29 17:35:122327 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422328 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122329 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422330 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2331 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142332
[email protected]aa043632013-03-25 03:39:422333 // The layer should have scrolled down in its local coordinates.
2334 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
2335 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292336 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422337 gfx::Vector2d(0, gesture_scroll_delta.x()));
[email protected]94f206c12012-08-25 00:09:142338
[email protected]aa043632013-03-25 03:39:422339 // Reset and scroll down with the wheel.
[email protected]35a99a12013-05-09 23:52:292340 scroll_layer->SetScrollDelta(gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:422341 gfx::Vector2d wheel_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122342 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422343 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122344 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422345 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
2346 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142347
[email protected]aa043632013-03-25 03:39:422348 // The layer should have scrolled down in its local coordinates.
2349 scroll_info = host_impl_->ProcessScrollDeltas();
2350 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292351 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422352 wheel_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142353}
2354
[email protected]aa043632013-03-25 03:39:422355TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:292356 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
2357 int child_layer_id = 4;
[email protected]aa043632013-03-25 03:39:422358 float child_layer_angle = -20.f;
[email protected]94f206c12012-08-25 00:09:142359
[email protected]aa043632013-03-25 03:39:422360 // Create a child layer that is rotated to a non-axis-aligned angle.
2361 scoped_ptr<LayerImpl> child = CreateScrollableLayer(
2362 child_layer_id,
[email protected]35a99a12013-05-09 23:52:292363 scroll_layer->content_bounds());
[email protected]aa043632013-03-25 03:39:422364 gfx::Transform rotate_transform;
2365 rotate_transform.Translate(-50.0, -50.0);
2366 rotate_transform.Rotate(child_layer_angle);
2367 rotate_transform.Translate(50.0, 50.0);
2368 child->SetTransform(rotate_transform);
[email protected]94f206c12012-08-25 00:09:142369
[email protected]aa043632013-03-25 03:39:422370 // Only allow vertical scrolling.
2371 child->SetMaxScrollOffset(gfx::Vector2d(0, child->content_bounds().height()));
[email protected]35a99a12013-05-09 23:52:292372 scroll_layer->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:142373
[email protected]aa043632013-03-25 03:39:422374 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402375 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422376 InitializeRendererAndDrawFrame();
2377 {
[email protected]94f206c12012-08-25 00:09:142378 // Scroll down in screen coordinates with a gesture.
[email protected]aa043632013-03-25 03:39:422379 gfx::Vector2d gesture_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122380 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]803f6b52013-09-12 00:51:262381 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122382 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422383 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2384 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142385
[email protected]aa043632013-03-25 03:39:422386 // The child layer should have scrolled down in its local coordinates an
2387 // amount proportional to the angle between it and the input scroll delta.
2388 gfx::Vector2d expected_scroll_delta(
2389 0,
2390 gesture_scroll_delta.y() *
2391 std::cos(MathUtil::Deg2Rad(child_layer_angle)));
2392 scoped_ptr<ScrollAndScaleSet> scroll_info =
2393 host_impl_->ProcessScrollDeltas();
2394 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142395
[email protected]35a99a12013-05-09 23:52:292396 // The root scroll layer should not have scrolled, because the input delta
2397 // was close to the layer's axis of movement.
[email protected]aa043632013-03-25 03:39:422398 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
2399 }
2400 {
2401 // Now reset and scroll the same amount horizontally.
[email protected]35a99a12013-05-09 23:52:292402 scroll_layer->children()[1]->SetScrollDelta(
[email protected]aa043632013-03-25 03:39:422403 gfx::Vector2dF());
2404 gfx::Vector2d gesture_scroll_delta(10, 0);
[email protected]5ff3c9782013-04-29 17:35:122405 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]803f6b52013-09-12 00:51:262406 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122407 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422408 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2409 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142410
[email protected]aa043632013-03-25 03:39:422411 // The child layer should have scrolled down in its local coordinates an
2412 // amount proportional to the angle between it and the input scroll delta.
2413 gfx::Vector2d expected_scroll_delta(
2414 0,
2415 -gesture_scroll_delta.x() *
2416 std::sin(MathUtil::Deg2Rad(child_layer_angle)));
2417 scoped_ptr<ScrollAndScaleSet> scroll_info =
2418 host_impl_->ProcessScrollDeltas();
2419 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
2420
[email protected]35a99a12013-05-09 23:52:292421 // The root scroll layer should have scrolled more, since the input scroll
2422 // delta was mostly orthogonal to the child layer's vertical scroll axis.
[email protected]aa043632013-03-25 03:39:422423 gfx::Vector2d expected_root_scroll_delta(
2424 gesture_scroll_delta.x() *
2425 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2),
2426 0);
2427 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292428 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422429 expected_root_scroll_delta);
2430 }
2431}
2432
2433TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
[email protected]35a99a12013-05-09 23:52:292434 LayerImpl* scroll_layer =
2435 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:422436
2437 // Scale the layer to twice its normal size.
2438 int scale = 2;
2439 gfx::Transform scale_transform;
2440 scale_transform.Scale(scale, scale);
[email protected]35a99a12013-05-09 23:52:292441 scroll_layer->SetTransform(scale_transform);
[email protected]aa043632013-03-25 03:39:422442
2443 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402444 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422445 InitializeRendererAndDrawFrame();
2446
2447 // Scroll down in screen coordinates with a gesture.
2448 gfx::Vector2d scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122449 EXPECT_EQ(InputHandler::ScrollStarted,
2450 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422451 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2452 host_impl_->ScrollEnd();
2453
2454 // The layer should have scrolled down in its local coordinates, but half the
2455 // amount.
2456 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
2457 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292458 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422459 gfx::Vector2d(0, scroll_delta.y() / scale));
2460
2461 // Reset and scroll down with the wheel.
[email protected]35a99a12013-05-09 23:52:292462 scroll_layer->SetScrollDelta(gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:422463 gfx::Vector2d wheel_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122464 EXPECT_EQ(InputHandler::ScrollStarted,
2465 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422466 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
2467 host_impl_->ScrollEnd();
2468
2469 // The scale should not have been applied to the scroll delta.
2470 scroll_info = host_impl_->ProcessScrollDeltas();
2471 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292472 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422473 wheel_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142474}
2475
[email protected]0a0d1422013-05-02 09:14:522476class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
2477 public:
[email protected]20d2b742013-09-26 05:41:342478 TestScrollOffsetDelegate() : page_scale_factor_(0.f) {}
2479
[email protected]0a0d1422013-05-02 09:14:522480 virtual ~TestScrollOffsetDelegate() {}
2481
[email protected]20d2b742013-09-26 05:41:342482 virtual void SetMaxScrollOffset(gfx::Vector2dF max_scroll_offset) OVERRIDE {
2483 max_scroll_offset_ = max_scroll_offset;
2484 }
2485
[email protected]0a0d1422013-05-02 09:14:522486 virtual void SetTotalScrollOffset(gfx::Vector2dF new_value) OVERRIDE {
2487 last_set_scroll_offset_ = new_value;
2488 }
2489
2490 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
2491 return getter_return_value_;
2492 }
2493
[email protected]251699b2013-10-09 00:21:262494 virtual bool IsExternalFlingActive() const OVERRIDE { return false; }
2495
[email protected]22f200a2013-10-09 18:08:292496 virtual void SetTotalPageScaleFactor(float page_scale_factor) OVERRIDE {
[email protected]20d2b742013-09-26 05:41:342497 page_scale_factor_ = page_scale_factor;
2498 }
2499
2500 virtual void SetScrollableSize(gfx::SizeF scrollable_size) OVERRIDE {
2501 scrollable_size_ = scrollable_size;
2502 }
2503
[email protected]0a0d1422013-05-02 09:14:522504 gfx::Vector2dF last_set_scroll_offset() {
2505 return last_set_scroll_offset_;
2506 }
2507
2508 void set_getter_return_value(gfx::Vector2dF value) {
2509 getter_return_value_ = value;
2510 }
2511
[email protected]20d2b742013-09-26 05:41:342512 gfx::Vector2dF max_scroll_offset() const {
2513 return max_scroll_offset_;
2514 }
2515
2516 gfx::SizeF scrollable_size() const {
2517 return scrollable_size_;
2518 }
2519
2520 float page_scale_factor() const {
2521 return page_scale_factor_;
2522 }
2523
[email protected]0a0d1422013-05-02 09:14:522524 private:
2525 gfx::Vector2dF last_set_scroll_offset_;
2526 gfx::Vector2dF getter_return_value_;
[email protected]20d2b742013-09-26 05:41:342527 gfx::Vector2dF max_scroll_offset_;
2528 gfx::SizeF scrollable_size_;
2529 float page_scale_factor_;
[email protected]0a0d1422013-05-02 09:14:522530};
2531
2532TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
2533 TestScrollOffsetDelegate scroll_delegate;
[email protected]20d2b742013-09-26 05:41:342534 host_impl_->SetViewportSize(gfx::Size(10, 20));
[email protected]35a99a12013-05-09 23:52:292535 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]0a0d1422013-05-02 09:14:522536
2537 // Setting the delegate results in the current scroll offset being set.
[email protected]35a99a12013-05-09 23:52:292538 gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
2539 scroll_layer->SetScrollOffset(gfx::Vector2d());
2540 scroll_layer->SetScrollDelta(initial_scroll_delta);
[email protected]0a0d1422013-05-02 09:14:522541 host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
[email protected]35a99a12013-05-09 23:52:292542 EXPECT_EQ(initial_scroll_delta.ToString(),
2543 scroll_delegate.last_set_scroll_offset().ToString());
[email protected]0a0d1422013-05-02 09:14:522544
[email protected]20d2b742013-09-26 05:41:342545 // Setting the delegate results in the scrollable_size, max_scroll_offset and
2546 // page_scale being set.
2547 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size());
2548 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate.max_scroll_offset());
2549 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
2550
2551 // Updating page scale immediately updates the delegate.
2552 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 0.5f, 4.f);
2553 EXPECT_EQ(2.f, scroll_delegate.page_scale_factor());
[email protected]22f200a2013-10-09 18:08:292554 host_impl_->active_tree()->SetPageScaleDelta(1.5f);
2555 EXPECT_EQ(3.f, scroll_delegate.page_scale_factor());
2556 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]20d2b742013-09-26 05:41:342557 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
2558 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
2559
[email protected]0a0d1422013-05-02 09:14:522560 // Scrolling should be relative to the offset as returned by the delegate.
[email protected]35a99a12013-05-09 23:52:292561 gfx::Vector2dF scroll_delta(0.f, 10.f);
2562 gfx::Vector2dF current_offset(7.f, 8.f);
[email protected]0a0d1422013-05-02 09:14:522563
2564 scroll_delegate.set_getter_return_value(current_offset);
2565 EXPECT_EQ(InputHandler::ScrollStarted,
2566 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2567
2568 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2569 EXPECT_EQ(current_offset + scroll_delta,
2570 scroll_delegate.last_set_scroll_offset());
2571
[email protected]35a99a12013-05-09 23:52:292572 current_offset = gfx::Vector2dF(42.f, 41.f);
[email protected]0a0d1422013-05-02 09:14:522573 scroll_delegate.set_getter_return_value(current_offset);
2574 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2575 EXPECT_EQ(current_offset + scroll_delta,
2576 scroll_delegate.last_set_scroll_offset());
2577 host_impl_->ScrollEnd();
2578
[email protected]7d1b07e2013-10-01 17:31:302579 // Forces a full tree synchronization and ensures that the scroll delegate
2580 // sees the correct size of the new tree.
2581 gfx::Size new_size(42, 24);
2582 host_impl_->CreatePendingTree();
2583 CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size);
2584 host_impl_->ActivatePendingTree();
2585 EXPECT_EQ(new_size, scroll_delegate.scrollable_size());
2586
[email protected]0a0d1422013-05-02 09:14:522587 // Un-setting the delegate should propagate the delegate's current offset to
2588 // the root scrollable layer.
[email protected]35a99a12013-05-09 23:52:292589 current_offset = gfx::Vector2dF(13.f, 12.f);
[email protected]0a0d1422013-05-02 09:14:522590 scroll_delegate.set_getter_return_value(current_offset);
2591 host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
2592
[email protected]35a99a12013-05-09 23:52:292593 EXPECT_EQ(current_offset.ToString(),
2594 scroll_layer->TotalScrollOffset().ToString());
[email protected]0a0d1422013-05-02 09:14:522595}
2596
[email protected]a2b5ded2013-05-20 21:32:532597TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
2598 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2599 host_impl_->SetViewportSize(gfx::Size(50, 50));
2600 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
2601 InitializeRendererAndDrawFrame();
2602 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2603 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2604
2605 // In-bounds scrolling does not affect overscroll.
2606 EXPECT_EQ(InputHandler::ScrollStarted,
2607 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2608 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2609 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2610 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2611
2612 // Overscroll events are reflected immediately.
2613 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
2614 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
2615 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2616
[email protected]2bd503f2013-07-23 05:35:292617 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
[email protected]a2b5ded2013-05-20 21:32:532618 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
2619 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
2620 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
2621 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
[email protected]2bd503f2013-07-23 05:35:292622 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
2623 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
2624 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
2625 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll());
2626 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
2627 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll());
2628 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
2629 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:532630
2631 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
2632 // as no scroll occurs.
2633 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2634 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll());
2635 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2636 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll());
2637 // Overscroll resets on valid scroll.
2638 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2639 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
2640 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2641 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
2642 host_impl_->ScrollEnd();
2643
2644 EXPECT_EQ(InputHandler::ScrollStarted,
2645 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2646 // Fling velocity is reflected immediately.
2647 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0));
2648 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2649 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2650 EXPECT_EQ(gfx::Vector2dF(0, -20), host_impl_->accumulated_root_overscroll());
2651 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2652}
2653
2654
2655TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
2656 // Scroll child layers beyond their maximum scroll range and make sure root
2657 // overscroll does not accumulate.
2658 gfx::Size surface_size(10, 10);
2659 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size);
2660
2661 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size);
2662 grand_child->SetScrollOffset(gfx::Vector2d(0, 2));
2663
2664 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
2665 child->SetScrollOffset(gfx::Vector2d(0, 3));
2666 child->AddChild(grand_child.Pass());
2667
2668 root->AddChild(child.Pass());
2669 host_impl_->active_tree()->SetRootLayer(root.Pass());
2670 host_impl_->active_tree()->DidBecomeActive();
2671 host_impl_->SetViewportSize(surface_size);
2672 InitializeRendererAndDrawFrame();
2673 {
2674 gfx::Vector2d scroll_delta(0, -10);
2675 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472676 host_impl_->ScrollBegin(gfx::Point(),
[email protected]a2b5ded2013-05-20 21:32:532677 InputHandler::NonBubblingGesture));
2678 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2679 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2680 host_impl_->ScrollEnd();
2681
2682 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
2683 LayerImpl* grand_child = child->children()[0];
2684
2685 // The next time we scroll we should only scroll the parent, but overscroll
2686 // should still not reach the root layer.
2687 scroll_delta = gfx::Vector2d(0, -30);
2688 EXPECT_EQ(InputHandler::ScrollStarted,
2689 host_impl_->ScrollBegin(gfx::Point(5, 5),
2690 InputHandler::NonBubblingGesture));
2691 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2692 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2693 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2694 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
2695 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2696 host_impl_->ScrollEnd();
2697
2698 // After scrolling the parent, another scroll on the opposite direction
2699 // should scroll the child, resetting the fling velocity.
2700 scroll_delta = gfx::Vector2d(0, 70);
2701 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0));
2702 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2703 EXPECT_EQ(InputHandler::ScrollStarted,
2704 host_impl_->ScrollBegin(gfx::Point(5, 5),
2705 InputHandler::NonBubblingGesture));
2706 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2707 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2708 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2709 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2710 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2711 host_impl_->ScrollEnd();
2712 }
2713}
2714
2715TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
2716 // When we try to scroll a non-scrollable child layer, the scroll delta
2717 // should be applied to one of its ancestors if possible. Overscroll should
2718 // be reflected only when it has bubbled up to the root scrolling layer.
2719 gfx::Size surface_size(10, 10);
2720 gfx::Size content_size(20, 20);
2721 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
2722 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
2723
2724 child->SetScrollable(false);
2725 root->AddChild(child.Pass());
2726
2727 host_impl_->SetViewportSize(surface_size);
2728 host_impl_->active_tree()->SetRootLayer(root.Pass());
2729 host_impl_->active_tree()->DidBecomeActive();
2730 InitializeRendererAndDrawFrame();
2731 {
2732 gfx::Vector2d scroll_delta(0, 8);
2733 EXPECT_EQ(InputHandler::ScrollStarted,
2734 host_impl_->ScrollBegin(gfx::Point(5, 5),
2735 InputHandler::Wheel));
2736 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2737 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2738 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2739 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
2740 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2741 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
2742 host_impl_->ScrollEnd();
2743 }
2744}
2745
[email protected]34d43432013-09-26 20:04:102746TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
2747 LayerTreeSettings settings;
2748 settings.always_overscroll = true;
2749 host_impl_ = LayerTreeHostImpl::Create(
[email protected]a7f35682013-10-22 23:05:572750 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]34d43432013-09-26 20:04:102751
2752 SetupScrollAndContentsLayers(gfx::Size(50, 50));
2753 host_impl_->SetViewportSize(gfx::Size(50, 50));
2754 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
2755 InitializeRendererAndDrawFrame();
2756 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2757 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2758
2759 // Even though the layer can't scroll the overscroll still happens.
2760 EXPECT_EQ(InputHandler::ScrollStarted,
2761 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2762 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2763 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
2764 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2765}
[email protected]a2b5ded2013-05-20 21:32:532766
[email protected]96baf3e2012-10-22 23:09:552767class BlendStateCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:422768 public:
2769 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
2770 int id,
2771 ResourceProvider* resource_provider) {
2772 return scoped_ptr<LayerImpl>(new BlendStateCheckLayer(tree_impl,
2773 id,
2774 resource_provider));
2775 }
[email protected]94f206c12012-08-25 00:09:142776
[email protected]aa043632013-03-25 03:39:422777 virtual void AppendQuads(QuadSink* quad_sink,
2778 AppendQuadsData* append_quads_data) OVERRIDE {
2779 quads_appended_ = true;
[email protected]94f206c12012-08-25 00:09:142780
[email protected]aa043632013-03-25 03:39:422781 gfx::Rect opaque_rect;
2782 if (contents_opaque())
2783 opaque_rect = quad_rect_;
2784 else
2785 opaque_rect = opaque_content_rect_;
[email protected]94f206c12012-08-25 00:09:142786
[email protected]aa043632013-03-25 03:39:422787 SharedQuadState* shared_quad_state =
2788 quad_sink->UseSharedQuadState(CreateSharedQuadState());
2789 scoped_ptr<TileDrawQuad> test_blending_draw_quad = TileDrawQuad::Create();
2790 test_blending_draw_quad->SetNew(shared_quad_state,
2791 quad_rect_,
2792 opaque_rect,
2793 resource_id_,
2794 gfx::RectF(0.f, 0.f, 1.f, 1.f),
2795 gfx::Size(1, 1),
2796 false);
2797 test_blending_draw_quad->visible_rect = quad_visible_rect_;
2798 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
2799 EXPECT_EQ(has_render_surface_, !!render_surface());
2800 quad_sink->Append(test_blending_draw_quad.PassAs<DrawQuad>(),
2801 append_quads_data);
2802 }
[email protected]94f206c12012-08-25 00:09:142803
[email protected]aa043632013-03-25 03:39:422804 void SetExpectation(bool blend, bool has_render_surface) {
2805 blend_ = blend;
2806 has_render_surface_ = has_render_surface;
2807 quads_appended_ = false;
2808 }
[email protected]94f206c12012-08-25 00:09:142809
[email protected]aa043632013-03-25 03:39:422810 bool quads_appended() const { return quads_appended_; }
[email protected]94f206c12012-08-25 00:09:142811
[email protected]aa043632013-03-25 03:39:422812 void SetQuadRect(gfx::Rect rect) { quad_rect_ = rect; }
2813 void SetQuadVisibleRect(gfx::Rect rect) { quad_visible_rect_ = rect; }
2814 void SetOpaqueContentRect(gfx::Rect rect) { opaque_content_rect_ = rect; }
[email protected]94f206c12012-08-25 00:09:142815
[email protected]aa043632013-03-25 03:39:422816 private:
2817 BlendStateCheckLayer(LayerTreeImpl* tree_impl,
2818 int id,
2819 ResourceProvider* resource_provider)
2820 : LayerImpl(tree_impl, id),
2821 blend_(false),
2822 has_render_surface_(false),
2823 quads_appended_(false),
2824 quad_rect_(5, 5, 5, 5),
2825 quad_visible_rect_(5, 5, 5, 5),
2826 resource_id_(resource_provider->CreateResource(
2827 gfx::Size(1, 1),
[email protected]efa48412013-09-05 15:30:162828 GL_CLAMP_TO_EDGE,
[email protected]27a41fe2013-09-19 05:05:142829 ResourceProvider::TextureUsageAny,
2830 RGBA_8888)) {
[email protected]aa043632013-03-25 03:39:422831 resource_provider->AllocateForTesting(resource_id_);
2832 SetAnchorPoint(gfx::PointF());
2833 SetBounds(gfx::Size(10, 10));
2834 SetContentBounds(gfx::Size(10, 10));
2835 SetDrawsContent(true);
2836 }
[email protected]94f206c12012-08-25 00:09:142837
[email protected]aa043632013-03-25 03:39:422838 bool blend_;
2839 bool has_render_surface_;
2840 bool quads_appended_;
2841 gfx::Rect quad_rect_;
2842 gfx::Rect opaque_content_rect_;
2843 gfx::Rect quad_visible_rect_;
2844 ResourceProvider::ResourceId resource_id_;
[email protected]94f206c12012-08-25 00:09:142845};
2846
[email protected]aa043632013-03-25 03:39:422847TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
2848 {
2849 scoped_ptr<LayerImpl> root =
2850 LayerImpl::Create(host_impl_->active_tree(), 1);
2851 root->SetAnchorPoint(gfx::PointF());
2852 root->SetBounds(gfx::Size(10, 10));
2853 root->SetContentBounds(root->bounds());
2854 root->SetDrawsContent(false);
2855 host_impl_->active_tree()->SetRootLayer(root.Pass());
2856 }
2857 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:142858
[email protected]aa043632013-03-25 03:39:422859 root->AddChild(
2860 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2861 2,
2862 host_impl_->resource_provider()));
2863 BlendStateCheckLayer* layer1 =
2864 static_cast<BlendStateCheckLayer*>(root->children()[0]);
2865 layer1->SetPosition(gfx::PointF(2.f, 2.f));
[email protected]94f206c12012-08-25 00:09:142866
[email protected]aa043632013-03-25 03:39:422867 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:142868
[email protected]aa043632013-03-25 03:39:422869 // Opaque layer, drawn without blending.
2870 layer1->SetContentsOpaque(true);
2871 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202872 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2873 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462874 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422875 EXPECT_TRUE(layer1->quads_appended());
2876 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142877
[email protected]aa043632013-03-25 03:39:422878 // Layer with translucent content and painting, so drawn with blending.
2879 layer1->SetContentsOpaque(false);
2880 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202881 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2882 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462883 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422884 EXPECT_TRUE(layer1->quads_appended());
2885 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142886
[email protected]aa043632013-03-25 03:39:422887 // Layer with translucent opacity, drawn with blending.
2888 layer1->SetContentsOpaque(true);
2889 layer1->SetOpacity(0.5f);
2890 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202891 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2892 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462893 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422894 EXPECT_TRUE(layer1->quads_appended());
2895 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142896
[email protected]aa043632013-03-25 03:39:422897 // Layer with translucent opacity and painting, drawn with blending.
2898 layer1->SetContentsOpaque(true);
2899 layer1->SetOpacity(0.5f);
2900 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202901 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2902 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462903 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422904 EXPECT_TRUE(layer1->quads_appended());
2905 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142906
[email protected]aa043632013-03-25 03:39:422907 layer1->AddChild(
2908 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2909 3,
2910 host_impl_->resource_provider()));
2911 BlendStateCheckLayer* layer2 =
2912 static_cast<BlendStateCheckLayer*>(layer1->children()[0]);
2913 layer2->SetPosition(gfx::PointF(4.f, 4.f));
[email protected]94f206c12012-08-25 00:09:142914
[email protected]aa043632013-03-25 03:39:422915 // 2 opaque layers, drawn without blending.
2916 layer1->SetContentsOpaque(true);
2917 layer1->SetOpacity(1.f);
2918 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202919 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422920 layer2->SetContentsOpaque(true);
2921 layer2->SetOpacity(1.f);
2922 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202923 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2924 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462925 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422926 EXPECT_TRUE(layer1->quads_appended());
2927 EXPECT_TRUE(layer2->quads_appended());
2928 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142929
[email protected]aa043632013-03-25 03:39:422930 // Parent layer with translucent content, drawn with blending.
2931 // Child layer with opaque content, drawn without blending.
2932 layer1->SetContentsOpaque(false);
2933 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202934 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422935 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202936 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2937 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462938 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422939 EXPECT_TRUE(layer1->quads_appended());
2940 EXPECT_TRUE(layer2->quads_appended());
2941 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142942
[email protected]aa043632013-03-25 03:39:422943 // Parent layer with translucent content but opaque painting, drawn without
2944 // blending.
2945 // Child layer with opaque content, drawn without blending.
2946 layer1->SetContentsOpaque(true);
2947 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202948 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422949 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202950 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2951 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462952 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422953 EXPECT_TRUE(layer1->quads_appended());
2954 EXPECT_TRUE(layer2->quads_appended());
2955 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142956
[email protected]aa043632013-03-25 03:39:422957 // Parent layer with translucent opacity and opaque content. Since it has a
2958 // drawing child, it's drawn to a render surface which carries the opacity,
2959 // so it's itself drawn without blending.
2960 // Child layer with opaque content, drawn without blending (parent surface
2961 // carries the inherited opacity).
2962 layer1->SetContentsOpaque(true);
2963 layer1->SetOpacity(0.5f);
2964 layer1->SetExpectation(false, true);
[email protected]e0341352013-04-06 05:01:202965 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422966 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202967 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2968 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462969 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422970 EXPECT_TRUE(layer1->quads_appended());
2971 EXPECT_TRUE(layer2->quads_appended());
2972 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142973
[email protected]aa043632013-03-25 03:39:422974 // Draw again, but with child non-opaque, to make sure
2975 // layer1 not culled.
2976 layer1->SetContentsOpaque(true);
2977 layer1->SetOpacity(1.f);
2978 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202979 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422980 layer2->SetContentsOpaque(true);
2981 layer2->SetOpacity(0.5f);
2982 layer2->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202983 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2984 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:462985 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:422986 EXPECT_TRUE(layer1->quads_appended());
2987 EXPECT_TRUE(layer2->quads_appended());
2988 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142989
[email protected]aa043632013-03-25 03:39:422990 // A second way of making the child non-opaque.
2991 layer1->SetContentsOpaque(true);
2992 layer1->SetOpacity(1.f);
2993 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202994 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422995 layer2->SetContentsOpaque(false);
2996 layer2->SetOpacity(1.f);
2997 layer2->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202998 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2999 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463000 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423001 EXPECT_TRUE(layer1->quads_appended());
3002 EXPECT_TRUE(layer2->quads_appended());
3003 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143004
[email protected]aa043632013-03-25 03:39:423005 // And when the layer says its not opaque but is painted opaque, it is not
3006 // blended.
3007 layer1->SetContentsOpaque(true);
3008 layer1->SetOpacity(1.f);
3009 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:203010 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:423011 layer2->SetContentsOpaque(true);
3012 layer2->SetOpacity(1.f);
3013 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:203014 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
3015 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463016 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423017 EXPECT_TRUE(layer1->quads_appended());
3018 EXPECT_TRUE(layer2->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, drawn with blending.
3022 layer1->SetContentsOpaque(false);
3023 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3024 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 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 partially culled, drawn with blending.
3034 layer1->SetContentsOpaque(false);
3035 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3036 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
3037 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3038 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:203039 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3040 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463041 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423042 EXPECT_TRUE(layer1->quads_appended());
3043 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143044
[email protected]aa043632013-03-25 03:39:423045 // Layer with partially opaque contents culled, drawn with blending.
3046 layer1->SetContentsOpaque(false);
3047 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3048 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
3049 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3050 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:203051 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3052 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463053 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423054 EXPECT_TRUE(layer1->quads_appended());
3055 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143056
[email protected]aa043632013-03-25 03:39:423057 // Layer with partially opaque contents and translucent contents culled, drawn
3058 // without blending.
3059 layer1->SetContentsOpaque(false);
3060 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3061 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
3062 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3063 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:203064 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
3065 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463066 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423067 EXPECT_TRUE(layer1->quads_appended());
3068 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143069}
3070
[email protected]6133cc232013-07-30 18:47:073071class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
3072 public:
[email protected]9f4f6a32013-09-04 21:35:123073 LayerTreeHostImplViewportCoveredTest() :
3074 gutter_quad_material_(DrawQuad::SOLID_COLOR),
3075 child_(NULL),
3076 did_activate_pending_tree_(false) {}
3077
[email protected]6133cc232013-07-30 18:47:073078 void CreateLayerTreeHostImpl(bool always_draw) {
3079 LayerTreeSettings settings;
3080 settings.minimum_occlusion_tracking_size = gfx::Size();
3081 settings.impl_side_painting = true;
3082 host_impl_ = LayerTreeHostImpl::Create(
[email protected]a7f35682013-10-22 23:05:573083 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]0634cdd42013-08-16 00:46:093084
3085 scoped_ptr<FakeOutputSurface> output_surface;
3086 if (always_draw)
3087 output_surface = FakeOutputSurface::CreateAlwaysDrawAndSwap3d().Pass();
3088 else
3089 output_surface = FakeOutputSurface::Create3d().Pass();
3090
3091 host_impl_->InitializeRenderer(output_surface.PassAs<OutputSurface>());
[email protected]6133cc232013-07-30 18:47:073092 viewport_size_ = gfx::Size(1000, 1000);
3093 }
[email protected]94f206c12012-08-25 00:09:143094
[email protected]6133cc232013-07-30 18:47:073095 void SetupActiveTreeLayers() {
3096 host_impl_->active_tree()->set_background_color(SK_ColorGRAY);
3097 host_impl_->active_tree()->SetRootLayer(
3098 LayerImpl::Create(host_impl_->active_tree(), 1));
3099 host_impl_->active_tree()->root_layer()->AddChild(
3100 BlendStateCheckLayer::Create(host_impl_->active_tree(),
3101 2,
3102 host_impl_->resource_provider()));
3103 child_ = static_cast<BlendStateCheckLayer*>(
3104 host_impl_->active_tree()->root_layer()->children()[0]);
3105 child_->SetExpectation(false, false);
3106 child_->SetContentsOpaque(true);
3107 }
[email protected]94f206c12012-08-25 00:09:143108
[email protected]6133cc232013-07-30 18:47:073109 // Expect no gutter rects.
3110 void TestLayerCoversFullViewport() {
3111 gfx::Rect layer_rect(viewport_size_);
3112 child_->SetPosition(layer_rect.origin());
3113 child_->SetBounds(layer_rect.size());
3114 child_->SetContentBounds(layer_rect.size());
3115 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3116 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:143117
[email protected]aa043632013-03-25 03:39:423118 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203119 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423120 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143121
[email protected]9f4f6a32013-09-04 21:35:123122 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:423123 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123124 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:143125
[email protected]9f4f6a32013-09-04 21:35:123126 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:423127 host_impl_->DidDrawAllLayers(frame);
3128 }
[email protected]94f206c12012-08-25 00:09:143129
[email protected]6133cc232013-07-30 18:47:073130 // Expect fullscreen gutter rect.
3131 void TestEmptyLayer() {
[email protected]aa043632013-03-25 03:39:423132 gfx::Rect layer_rect(0, 0, 0, 0);
[email protected]6133cc232013-07-30 18:47:073133 child_->SetPosition(layer_rect.origin());
3134 child_->SetBounds(layer_rect.size());
3135 child_->SetContentBounds(layer_rect.size());
3136 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3137 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:143138
[email protected]aa043632013-03-25 03:39:423139 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203140 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423141 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143142
[email protected]9f4f6a32013-09-04 21:35:123143 EXPECT_EQ(1u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:423144 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123145 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:143146
[email protected]9f4f6a32013-09-04 21:35:123147 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:423148 host_impl_->DidDrawAllLayers(frame);
3149 }
[email protected]94f206c12012-08-25 00:09:143150
[email protected]6133cc232013-07-30 18:47:073151 // Expect four surrounding gutter rects.
3152 void TestLayerInMiddleOfViewport() {
[email protected]aa043632013-03-25 03:39:423153 gfx::Rect layer_rect(500, 500, 200, 200);
[email protected]6133cc232013-07-30 18:47:073154 child_->SetPosition(layer_rect.origin());
3155 child_->SetBounds(layer_rect.size());
3156 child_->SetContentBounds(layer_rect.size());
3157 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3158 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:143159
[email protected]aa043632013-03-25 03:39:423160 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203161 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423162 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143163
[email protected]9f4f6a32013-09-04 21:35:123164 EXPECT_EQ(4u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:423165 EXPECT_EQ(5u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123166 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:143167
[email protected]9f4f6a32013-09-04 21:35:123168 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:423169 host_impl_->DidDrawAllLayers(frame);
3170 }
[email protected]6133cc232013-07-30 18:47:073171
3172 // Expect no gutter rects.
3173 void TestLayerIsLargerThanViewport() {
3174 gfx::Rect layer_rect(viewport_size_.width() + 10,
3175 viewport_size_.height() + 10);
3176 child_->SetPosition(layer_rect.origin());
3177 child_->SetBounds(layer_rect.size());
3178 child_->SetContentBounds(layer_rect.size());
3179 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
3180 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
3181
3182 LayerTreeHostImpl::FrameData frame;
3183 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
3184 ASSERT_EQ(1u, frame.render_passes.size());
3185
[email protected]9f4f6a32013-09-04 21:35:123186 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]6133cc232013-07-30 18:47:073187 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:123188 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]6133cc232013-07-30 18:47:073189
3190 host_impl_->DidDrawAllLayers(frame);
3191 }
3192
3193 virtual void DidActivatePendingTree() OVERRIDE {
3194 did_activate_pending_tree_ = true;
3195 }
3196
[email protected]9f4f6a32013-09-04 21:35:123197 void set_gutter_quad_material(DrawQuad::Material material) {
3198 gutter_quad_material_ = material;
3199 }
3200 void set_gutter_texture_size(gfx::Size gutter_texture_size) {
3201 gutter_texture_size_ = gutter_texture_size;
3202 }
3203
[email protected]6133cc232013-07-30 18:47:073204 protected:
[email protected]9f4f6a32013-09-04 21:35:123205 size_t CountGutterQuads(const QuadList& quad_list) {
3206 size_t num_gutter_quads = 0;
3207 for (size_t i = 0; i < quad_list.size(); ++i) {
3208 num_gutter_quads += (quad_list[i]->material ==
3209 gutter_quad_material_) ? 1 : 0;
3210 }
3211 return num_gutter_quads;
3212 }
3213
3214 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) {
3215 LayerTestCommon::VerifyQuadsExactlyCoverRect(
3216 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_)));
3217 }
3218
3219 // Make sure that the texture coordinates match their expectations.
3220 void ValidateTextureDrawQuads(const QuadList& quad_list) {
3221 for (size_t i = 0; i < quad_list.size(); ++i) {
3222 if (quad_list[i]->material != DrawQuad::TEXTURE_CONTENT)
3223 continue;
3224 const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(quad_list[i]);
3225 gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize(
3226 gutter_texture_size_, host_impl_->device_scale_factor());
3227 EXPECT_EQ(quad->uv_top_left.x(),
3228 quad->rect.x() / gutter_texture_size_pixels.width());
3229 EXPECT_EQ(quad->uv_top_left.y(),
3230 quad->rect.y() / gutter_texture_size_pixels.height());
3231 EXPECT_EQ(quad->uv_bottom_right.x(),
3232 quad->rect.right() / gutter_texture_size_pixels.width());
3233 EXPECT_EQ(quad->uv_bottom_right.y(),
3234 quad->rect.bottom() / gutter_texture_size_pixels.height());
3235 }
3236 }
3237
3238 gfx::Size DipSizeToPixelSize(gfx::Size size) {
3239 return gfx::ToRoundedSize(
3240 gfx::ScaleSize(size, host_impl_->device_scale_factor()));
3241 }
3242
3243 DrawQuad::Material gutter_quad_material_;
3244 gfx::Size gutter_texture_size_;
[email protected]6133cc232013-07-30 18:47:073245 gfx::Size viewport_size_;
3246 BlendStateCheckLayer* child_;
3247 bool did_activate_pending_tree_;
3248};
3249
3250TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) {
3251 bool always_draw = false;
3252 CreateLayerTreeHostImpl(always_draw);
3253
[email protected]9f4f6a32013-09-04 21:35:123254 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073255 SetupActiveTreeLayers();
3256 TestLayerCoversFullViewport();
3257 TestEmptyLayer();
3258 TestLayerInMiddleOfViewport();
3259 TestLayerIsLargerThanViewport();
[email protected]94f206c12012-08-25 00:09:143260}
3261
[email protected]9f4f6a32013-09-04 21:35:123262TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
3263 bool always_draw = false;
3264 CreateLayerTreeHostImpl(always_draw);
3265
3266 host_impl_->SetDeviceScaleFactor(2.f);
3267 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3268 SetupActiveTreeLayers();
3269 TestLayerCoversFullViewport();
3270 TestEmptyLayer();
3271 TestLayerInMiddleOfViewport();
3272 TestLayerIsLargerThanViewport();
3273}
3274
3275TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
3276 bool always_draw = false;
3277 CreateLayerTreeHostImpl(always_draw);
3278
3279 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3280 SetupActiveTreeLayers();
3281
[email protected]741fba422013-09-20 03:34:143282 SkBitmap skbitmap;
3283 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
3284 skbitmap.allocPixels();
3285 skbitmap.setImmutable();
3286
[email protected]9f4f6a32013-09-04 21:35:123287 // Specify an overhang bitmap to use.
[email protected]e0a601e2013-10-24 04:30:303288 UIResourceBitmap ui_resource_bitmap(skbitmap);
3289 ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
[email protected]9f4f6a32013-09-04 21:35:123290 UIResourceId ui_resource_id = 12345;
3291 host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
3292 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
3293 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT);
3294 set_gutter_texture_size(gfx::Size(32, 32));
3295
3296 TestLayerCoversFullViewport();
3297 TestEmptyLayer();
3298 TestLayerInMiddleOfViewport();
3299 TestLayerIsLargerThanViewport();
3300
3301 // Change the resource size.
3302 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16));
3303 set_gutter_texture_size(gfx::Size(128, 16));
3304
3305 TestLayerCoversFullViewport();
3306 TestEmptyLayer();
3307 TestLayerInMiddleOfViewport();
3308 TestLayerIsLargerThanViewport();
3309
3310 // Change the device scale factor
3311 host_impl_->SetDeviceScaleFactor(2.f);
3312 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3313
3314 TestLayerCoversFullViewport();
3315 TestEmptyLayer();
3316 TestLayerInMiddleOfViewport();
3317 TestLayerIsLargerThanViewport();
3318}
3319
[email protected]6133cc232013-07-30 18:47:073320TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
3321 bool always_draw = true;
3322 CreateLayerTreeHostImpl(always_draw);
3323
3324 // Pending tree to force active_tree size invalid. Not used otherwise.
3325 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:123326 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073327 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
3328
3329 SetupActiveTreeLayers();
3330 TestEmptyLayer();
3331 TestLayerInMiddleOfViewport();
3332 TestLayerIsLargerThanViewport();
3333}
3334
3335TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) {
3336 bool always_draw = true;
3337 CreateLayerTreeHostImpl(always_draw);
3338
3339 // Set larger viewport and activate it to active tree.
3340 host_impl_->CreatePendingTree();
3341 gfx::Size larger_viewport(viewport_size_.width() + 100,
3342 viewport_size_.height() + 100);
[email protected]9f4f6a32013-09-04 21:35:123343 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport));
[email protected]6133cc232013-07-30 18:47:073344 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
[email protected]4f48f6e2013-08-27 06:33:383345 host_impl_->ActivatePendingTree();
[email protected]6133cc232013-07-30 18:47:073346 EXPECT_TRUE(did_activate_pending_tree_);
3347 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid());
3348
3349 // Shrink pending tree viewport without activating.
3350 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:123351 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073352 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
3353
3354 SetupActiveTreeLayers();
3355 TestEmptyLayer();
3356 TestLayerInMiddleOfViewport();
3357 TestLayerIsLargerThanViewport();
3358}
[email protected]94f206c12012-08-25 00:09:143359
[email protected]96baf3e2012-10-22 23:09:553360class FakeDrawableLayerImpl: public LayerImpl {
[email protected]aa043632013-03-25 03:39:423361 public:
3362 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3363 return scoped_ptr<LayerImpl>(new FakeDrawableLayerImpl(tree_impl, id));
3364 }
3365 protected:
3366 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id)
3367 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:143368};
3369
3370// Only reshape when we know we are going to draw. Otherwise, the reshape
3371// can leave the window at the wrong size if we never draw and the proper
3372// viewport size is never set.
[email protected]aa043632013-03-25 03:39:423373TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
[email protected]4bf41752013-11-05 01:34:323374 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
3375 scoped_ptr<OutputSurface> output_surface(
3376 FakeOutputSurface::Create3d(provider));
[email protected]aa043632013-03-25 03:39:423377 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]94f206c12012-08-25 00:09:143378
[email protected]aa043632013-03-25 03:39:423379 scoped_ptr<LayerImpl> root =
3380 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
3381 root->SetAnchorPoint(gfx::PointF());
3382 root->SetBounds(gfx::Size(10, 10));
[email protected]e0341352013-04-06 05:01:203383 root->SetContentBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423384 root->SetDrawsContent(true);
3385 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]4bf41752013-11-05 01:34:323386 EXPECT_FALSE(provider->TestContext3d()->reshape_called());
3387 provider->TestContext3d()->clear_reshape_called();
[email protected]94f206c12012-08-25 00:09:143388
[email protected]aa043632013-03-25 03:39:423389 LayerTreeHostImpl::FrameData frame;
[email protected]94c40e6292013-05-24 22:01:503390 host_impl_->SetViewportSize(gfx::Size(10, 10));
3391 host_impl_->SetDeviceScaleFactor(1.f);
[email protected]e0341352013-04-06 05:01:203392 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463393 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]4bf41752013-11-05 01:34:323394 EXPECT_TRUE(provider->TestContext3d()->reshape_called());
3395 EXPECT_EQ(provider->TestContext3d()->width(), 10);
3396 EXPECT_EQ(provider->TestContext3d()->height(), 10);
3397 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f);
[email protected]aa043632013-03-25 03:39:423398 host_impl_->DidDrawAllLayers(frame);
[email protected]4bf41752013-11-05 01:34:323399 provider->TestContext3d()->clear_reshape_called();
[email protected]94c40e6292013-05-24 22:01:503400
3401 host_impl_->SetViewportSize(gfx::Size(20, 30));
3402 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463403 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]4bf41752013-11-05 01:34:323404 EXPECT_TRUE(provider->TestContext3d()->reshape_called());
3405 EXPECT_EQ(provider->TestContext3d()->width(), 20);
3406 EXPECT_EQ(provider->TestContext3d()->height(), 30);
3407 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f);
[email protected]94c40e6292013-05-24 22:01:503408 host_impl_->DidDrawAllLayers(frame);
[email protected]4bf41752013-11-05 01:34:323409 provider->TestContext3d()->clear_reshape_called();
[email protected]94c40e6292013-05-24 22:01:503410
3411 host_impl_->SetDeviceScaleFactor(2.f);
3412 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463413 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]4bf41752013-11-05 01:34:323414 EXPECT_TRUE(provider->TestContext3d()->reshape_called());
3415 EXPECT_EQ(provider->TestContext3d()->width(), 20);
3416 EXPECT_EQ(provider->TestContext3d()->height(), 30);
3417 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 2.f);
[email protected]94c40e6292013-05-24 22:01:503418 host_impl_->DidDrawAllLayers(frame);
[email protected]4bf41752013-11-05 01:34:323419 provider->TestContext3d()->clear_reshape_called();
[email protected]94f206c12012-08-25 00:09:143420}
3421
[email protected]94f206c12012-08-25 00:09:143422// Make sure damage tracking propagates all the way to the graphics context,
[email protected]aa043632013-03-25 03:39:423423// where it should request to swap only the sub-buffer that is damaged.
3424TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
[email protected]4bf41752013-11-05 01:34:323425 scoped_refptr<TestContextProvider> provider(
3426 TestContextProvider::Create());
3427 scoped_ptr<OutputSurface> output_surface(
3428 FakeOutputSurface::Create3d(provider));
[email protected]0634cdd42013-08-16 00:46:093429
[email protected]4bf41752013-11-05 01:34:323430 provider->BindToCurrentThread();
3431 TestWebGraphicsContext3D* context = provider->TestContext3d();
3432 context->set_have_post_sub_buffer(true);
[email protected]94f206c12012-08-25 00:09:143433
[email protected]aa043632013-03-25 03:39:423434 // This test creates its own LayerTreeHostImpl, so
3435 // that we can force partial swap enabled.
3436 LayerTreeSettings settings;
3437 settings.partial_swap_enabled = true;
3438 scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl =
[email protected]a7f35682013-10-22 23:05:573439 LayerTreeHostImpl::Create(
3440 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]aa043632013-03-25 03:39:423441 layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403442 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
[email protected]94f206c12012-08-25 00:09:143443
[email protected]aa043632013-03-25 03:39:423444 scoped_ptr<LayerImpl> root =
3445 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
3446 scoped_ptr<LayerImpl> child =
3447 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
3448 child->SetPosition(gfx::PointF(12.f, 13.f));
3449 child->SetAnchorPoint(gfx::PointF());
3450 child->SetBounds(gfx::Size(14, 15));
3451 child->SetContentBounds(gfx::Size(14, 15));
3452 child->SetDrawsContent(true);
3453 root->SetAnchorPoint(gfx::PointF());
3454 root->SetBounds(gfx::Size(500, 500));
3455 root->SetContentBounds(gfx::Size(500, 500));
3456 root->SetDrawsContent(true);
3457 root->AddChild(child.Pass());
3458 layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143459
[email protected]aa043632013-03-25 03:39:423460 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143461
[email protected]aa043632013-03-25 03:39:423462 // First frame, the entire screen should get swapped.
[email protected]e0341352013-04-06 05:01:203463 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463464 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423465 layer_tree_host_impl->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203466 layer_tree_host_impl->SwapBuffers(frame);
[email protected]4bf41752013-11-05 01:34:323467 gfx::Rect actual_swap_rect = context->update_rect();
[email protected]aa043632013-03-25 03:39:423468 gfx::Rect expected_swap_rect = gfx::Rect(0, 0, 500, 500);
3469 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3470 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3471 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3472 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]4bf41752013-11-05 01:34:323473 EXPECT_EQ(context->last_update_type(),
3474 TestWebGraphicsContext3D::PrepareTexture);
[email protected]aa043632013-03-25 03:39:423475 // Second frame, only the damaged area should get swapped. Damage should be
3476 // the union of old and new child rects.
3477 // expected damage rect: gfx::Rect(26, 28);
3478 // expected swap rect: vertically flipped, with origin at bottom left corner.
3479 layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
3480 gfx::PointF());
[email protected]e0341352013-04-06 05:01:203481 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463482 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423483 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203484 layer_tree_host_impl->SwapBuffers(frame);
[email protected]4bf41752013-11-05 01:34:323485 actual_swap_rect = context->update_rect();
[email protected]aa043632013-03-25 03:39:423486 expected_swap_rect = gfx::Rect(0, 500-28, 26, 28);
3487 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3488 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3489 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3490 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]4bf41752013-11-05 01:34:323491 EXPECT_EQ(context->last_update_type(),
3492 TestWebGraphicsContext3D::PostSubBuffer);
[email protected]94f206c12012-08-25 00:09:143493
[email protected]aa043632013-03-25 03:39:423494 // Make sure that partial swap is constrained to the viewport dimensions
3495 // expected damage rect: gfx::Rect(500, 500);
3496 // expected swap rect: flipped damage rect, but also clamped to viewport
[email protected]18ce59702013-04-09 04:58:403497 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423498 // This will damage everything.
[email protected]35a99a12013-05-09 23:52:293499 layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor(
3500 SK_ColorBLACK);
[email protected]e0341352013-04-06 05:01:203501 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463502 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423503 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203504 layer_tree_host_impl->SwapBuffers(frame);
[email protected]4bf41752013-11-05 01:34:323505 actual_swap_rect = context->update_rect();
[email protected]aa043632013-03-25 03:39:423506 expected_swap_rect = gfx::Rect(10, 10);
3507 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3508 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3509 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3510 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]4bf41752013-11-05 01:34:323511 EXPECT_EQ(context->last_update_type(),
3512 TestWebGraphicsContext3D::PrepareTexture);
[email protected]94f206c12012-08-25 00:09:143513}
3514
[email protected]aa043632013-03-25 03:39:423515TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
3516 scoped_ptr<LayerImpl> root =
3517 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
3518 scoped_ptr<LayerImpl> child =
3519 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
3520 child->SetAnchorPoint(gfx::PointF());
3521 child->SetBounds(gfx::Size(10, 10));
3522 child->SetContentBounds(gfx::Size(10, 10));
3523 child->SetDrawsContent(true);
3524 root->SetAnchorPoint(gfx::PointF());
3525 root->SetBounds(gfx::Size(10, 10));
3526 root->SetContentBounds(gfx::Size(10, 10));
3527 root->SetDrawsContent(true);
[email protected]35a99a12013-05-09 23:52:293528 root->SetForceRenderSurface(true);
[email protected]aa043632013-03-25 03:39:423529 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:143530
[email protected]aa043632013-03-25 03:39:423531 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143532
[email protected]aa043632013-03-25 03:39:423533 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143534
[email protected]e0341352013-04-06 05:01:203535 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423536 EXPECT_EQ(1u, frame.render_surface_layer_list->size());
3537 EXPECT_EQ(1u, frame.render_passes.size());
3538 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143539}
3540
[email protected]96baf3e2012-10-22 23:09:553541class FakeLayerWithQuads : public LayerImpl {
[email protected]aa043632013-03-25 03:39:423542 public:
3543 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3544 return scoped_ptr<LayerImpl>(new FakeLayerWithQuads(tree_impl, id));
3545 }
[email protected]94f206c12012-08-25 00:09:143546
[email protected]aa043632013-03-25 03:39:423547 virtual void AppendQuads(QuadSink* quad_sink,
3548 AppendQuadsData* append_quads_data) OVERRIDE {
3549 SharedQuadState* shared_quad_state =
3550 quad_sink->UseSharedQuadState(CreateSharedQuadState());
[email protected]94f206c12012-08-25 00:09:143551
[email protected]aa043632013-03-25 03:39:423552 SkColor gray = SkColorSetRGB(100, 100, 100);
[email protected]2c7c6702013-03-26 03:14:053553 gfx::Rect quad_rect(content_bounds());
[email protected]aa043632013-03-25 03:39:423554 scoped_ptr<SolidColorDrawQuad> my_quad = SolidColorDrawQuad::Create();
[email protected]10a30b12013-05-02 16:42:113555 my_quad->SetNew(shared_quad_state, quad_rect, gray, false);
[email protected]aa043632013-03-25 03:39:423556 quad_sink->Append(my_quad.PassAs<DrawQuad>(), append_quads_data);
3557 }
[email protected]94f206c12012-08-25 00:09:143558
[email protected]aa043632013-03-25 03:39:423559 private:
3560 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id)
3561 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:143562};
3563
[email protected]c8756fbe2013-02-12 01:53:493564class MockContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423565 public:
[email protected]c32e27082013-11-07 06:58:203566 MOCK_METHOD1(useProgram, void(blink::WebGLId program));
3567 MOCK_METHOD5(uniform4f, void(blink::WGC3Dint location,
3568 blink::WGC3Dfloat x,
3569 blink::WGC3Dfloat y,
3570 blink::WGC3Dfloat z,
3571 blink::WGC3Dfloat w));
3572 MOCK_METHOD4(uniformMatrix4fv, void(blink::WGC3Dint location,
3573 blink::WGC3Dsizei count,
3574 blink::WGC3Dboolean transpose,
3575 const blink::WGC3Dfloat* value));
3576 MOCK_METHOD4(drawElements, void(blink::WGC3Denum mode,
3577 blink::WGC3Dsizei count,
3578 blink::WGC3Denum type,
3579 blink::WGC3Dintptr offset));
3580 MOCK_METHOD0(getRequestableExtensionsCHROMIUM, blink::WebString());
3581 MOCK_METHOD1(enable, void(blink::WGC3Denum cap));
3582 MOCK_METHOD1(disable, void(blink::WGC3Denum cap));
3583 MOCK_METHOD4(scissor, void(blink::WGC3Dint x,
3584 blink::WGC3Dint y,
3585 blink::WGC3Dsizei width,
3586 blink::WGC3Dsizei height));
[email protected]94f206c12012-08-25 00:09:143587};
3588
3589class MockContextHarness {
[email protected]aa043632013-03-25 03:39:423590 private:
3591 MockContext* context_;
[email protected]bf691c22013-03-26 21:15:063592
[email protected]aa043632013-03-25 03:39:423593 public:
[email protected]bf691c22013-03-26 21:15:063594 explicit MockContextHarness(MockContext* context)
[email protected]aa043632013-03-25 03:39:423595 : context_(context) {
[email protected]41de22822013-08-29 04:16:173596 context_->set_have_post_sub_buffer(true);
3597
[email protected]aa043632013-03-25 03:39:423598 // Catch "uninteresting" calls
3599 EXPECT_CALL(*context_, useProgram(_))
3600 .Times(0);
[email protected]94f206c12012-08-25 00:09:143601
[email protected]aa043632013-03-25 03:39:423602 EXPECT_CALL(*context_, drawElements(_, _, _, _))
3603 .Times(0);
[email protected]94f206c12012-08-25 00:09:143604
[email protected]aa043632013-03-25 03:39:423605 // These are not asserted
3606 EXPECT_CALL(*context_, uniformMatrix4fv(_, _, _, _))
3607 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143608
[email protected]aa043632013-03-25 03:39:423609 EXPECT_CALL(*context_, uniform4f(_, _, _, _, _))
3610 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143611
[email protected]aa043632013-03-25 03:39:423612 // Any un-sanctioned calls to enable() are OK
3613 EXPECT_CALL(*context_, enable(_))
3614 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143615
[email protected]aa043632013-03-25 03:39:423616 // Any un-sanctioned calls to disable() are OK
3617 EXPECT_CALL(*context_, disable(_))
3618 .WillRepeatedly(Return());
3619 }
[email protected]94f206c12012-08-25 00:09:143620
[email protected]aa043632013-03-25 03:39:423621 void MustDrawSolidQuad() {
3622 EXPECT_CALL(*context_, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0))
3623 .WillOnce(Return())
3624 .RetiresOnSaturation();
[email protected]94f206c12012-08-25 00:09:143625
[email protected]aa043632013-03-25 03:39:423626 EXPECT_CALL(*context_, useProgram(_))
3627 .WillOnce(Return())
3628 .RetiresOnSaturation();
[email protected]aa043632013-03-25 03:39:423629 }
[email protected]94f206c12012-08-25 00:09:143630
[email protected]aa043632013-03-25 03:39:423631 void MustSetScissor(int x, int y, int width, int height) {
3632 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
3633 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143634
[email protected]aa043632013-03-25 03:39:423635 EXPECT_CALL(*context_, scissor(x, y, width, height))
3636 .Times(AtLeast(1))
3637 .WillRepeatedly(Return());
3638 }
[email protected]94f206c12012-08-25 00:09:143639
[email protected]aa043632013-03-25 03:39:423640 void MustSetNoScissor() {
3641 EXPECT_CALL(*context_, disable(GL_SCISSOR_TEST))
3642 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143643
[email protected]aa043632013-03-25 03:39:423644 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
3645 .Times(0);
[email protected]94f206c12012-08-25 00:09:143646
[email protected]aa043632013-03-25 03:39:423647 EXPECT_CALL(*context_, scissor(_, _, _, _))
3648 .Times(0);
3649 }
[email protected]94f206c12012-08-25 00:09:143650};
3651
[email protected]aa043632013-03-25 03:39:423652TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
[email protected]0634cdd42013-08-16 00:46:093653 scoped_ptr<MockContext> mock_context_owned(new MockContext);
3654 MockContext* mock_context = mock_context_owned.get();
3655
3656 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3657 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423658 MockContextHarness harness(mock_context);
[email protected]94f206c12012-08-25 00:09:143659
[email protected]aa043632013-03-25 03:39:423660 // Run test case
3661 CreateLayerTreeHost(false, output_surface.Pass());
3662 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
[email protected]94f206c12012-08-25 00:09:143663
[email protected]aa043632013-03-25 03:39:423664 // Without partial swap, and no clipping, no scissor is set.
3665 harness.MustDrawSolidQuad();
3666 harness.MustSetNoScissor();
3667 {
3668 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203669 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463670 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423671 host_impl_->DidDrawAllLayers(frame);
3672 }
3673 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]dc462d782012-11-21 21:43:013674
[email protected]aa043632013-03-25 03:39:423675 // Without partial swap, but a layer does clip its subtree, one scissor is
3676 // set.
3677 host_impl_->active_tree()->root_layer()->SetMasksToBounds(true);
3678 harness.MustDrawSolidQuad();
3679 harness.MustSetScissor(0, 0, 10, 10);
3680 {
3681 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203682 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463683 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423684 host_impl_->DidDrawAllLayers(frame);
3685 }
3686 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143687}
3688
[email protected]aa043632013-03-25 03:39:423689TEST_F(LayerTreeHostImplTest, PartialSwap) {
[email protected]0634cdd42013-08-16 00:46:093690 scoped_ptr<MockContext> context_owned(new MockContext);
3691 MockContext* mock_context = context_owned.get();
3692 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3693 context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423694 MockContextHarness harness(mock_context);
[email protected]94f206c12012-08-25 00:09:143695
[email protected]aa043632013-03-25 03:39:423696 CreateLayerTreeHost(true, output_surface.Pass());
3697 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
[email protected]94f206c12012-08-25 00:09:143698
[email protected]aa043632013-03-25 03:39:423699 // The first frame is not a partially-swapped one.
3700 harness.MustSetScissor(0, 0, 10, 10);
3701 harness.MustDrawSolidQuad();
3702 {
3703 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203704 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463705 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423706 host_impl_->DidDrawAllLayers(frame);
3707 }
3708 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143709
[email protected]aa043632013-03-25 03:39:423710 // Damage a portion of the frame.
3711 host_impl_->active_tree()->root_layer()->set_update_rect(
3712 gfx::Rect(0, 0, 2, 3));
[email protected]94f206c12012-08-25 00:09:143713
[email protected]aa043632013-03-25 03:39:423714 // The second frame will be partially-swapped (the y coordinates are flipped).
3715 harness.MustSetScissor(0, 7, 2, 3);
3716 harness.MustDrawSolidQuad();
3717 {
3718 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203719 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463720 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423721 host_impl_->DidDrawAllLayers(frame);
3722 }
3723 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143724}
3725
[email protected]aa043632013-03-25 03:39:423726static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
3727 bool partial_swap,
3728 LayerTreeHostImplClient* client,
3729 Proxy* proxy,
3730 RenderingStatsInstrumentation* stats_instrumentation) {
[email protected]4bf41752013-11-05 01:34:323731 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
3732 scoped_ptr<OutputSurface> output_surface(
3733 FakeOutputSurface::Create3d(provider));
3734 provider->BindToCurrentThread();
3735 provider->TestContext3d()->set_have_post_sub_buffer(true);
[email protected]94f206c12012-08-25 00:09:143736
[email protected]aa043632013-03-25 03:39:423737 LayerTreeSettings settings;
3738 settings.partial_swap_enabled = partial_swap;
[email protected]a7f35682013-10-22 23:05:573739 scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
3740 settings, client, proxy, stats_instrumentation, NULL);
[email protected]aa043632013-03-25 03:39:423741 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403742 my_host_impl->SetViewportSize(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:143743
[email protected]aa043632013-03-25 03:39:423744 /*
3745 Layers are created as follows:
[email protected]94f206c12012-08-25 00:09:143746
[email protected]aa043632013-03-25 03:39:423747 +--------------------+
3748 | 1 |
3749 | +-----------+ |
3750 | | 2 | |
3751 | | +-------------------+
3752 | | | 3 |
3753 | | +-------------------+
3754 | | | |
3755 | +-----------+ |
3756 | |
3757 | |
3758 +--------------------+
[email protected]94f206c12012-08-25 00:09:143759
[email protected]aa043632013-03-25 03:39:423760 Layers 1, 2 have render surfaces
3761 */
3762 scoped_ptr<LayerImpl> root =
3763 LayerImpl::Create(my_host_impl->active_tree(), 1);
3764 scoped_ptr<LayerImpl> child =
3765 LayerImpl::Create(my_host_impl->active_tree(), 2);
3766 scoped_ptr<LayerImpl> grand_child =
3767 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3);
[email protected]94f206c12012-08-25 00:09:143768
[email protected]aa043632013-03-25 03:39:423769 gfx::Rect root_rect(0, 0, 100, 100);
3770 gfx::Rect child_rect(10, 10, 50, 50);
3771 gfx::Rect grand_child_rect(5, 5, 150, 150);
[email protected]94f206c12012-08-25 00:09:143772
[email protected]aa043632013-03-25 03:39:423773 root->CreateRenderSurface();
3774 root->SetAnchorPoint(gfx::PointF());
3775 root->SetPosition(root_rect.origin());
3776 root->SetBounds(root_rect.size());
3777 root->SetContentBounds(root->bounds());
3778 root->draw_properties().visible_content_rect = root_rect;
3779 root->SetDrawsContent(false);
3780 root->render_surface()->SetContentRect(gfx::Rect(root_rect.size()));
[email protected]94f206c12012-08-25 00:09:143781
[email protected]aa043632013-03-25 03:39:423782 child->SetAnchorPoint(gfx::PointF());
3783 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
3784 child->SetOpacity(0.5f);
3785 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
3786 child->SetContentBounds(child->bounds());
3787 child->draw_properties().visible_content_rect = child_rect;
3788 child->SetDrawsContent(false);
3789 child->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:143790
[email protected]aa043632013-03-25 03:39:423791 grand_child->SetAnchorPoint(gfx::PointF());
3792 grand_child->SetPosition(grand_child_rect.origin());
3793 grand_child->SetBounds(grand_child_rect.size());
3794 grand_child->SetContentBounds(grand_child->bounds());
3795 grand_child->draw_properties().visible_content_rect = grand_child_rect;
3796 grand_child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143797
[email protected]aa043632013-03-25 03:39:423798 child->AddChild(grand_child.Pass());
3799 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:143800
[email protected]aa043632013-03-25 03:39:423801 my_host_impl->active_tree()->SetRootLayer(root.Pass());
3802 return my_host_impl.Pass();
[email protected]94f206c12012-08-25 00:09:143803}
3804
[email protected]aa043632013-03-25 03:39:423805TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
3806 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3807 SetupLayersForOpacity(true, this, &proxy_, &stats_instrumentation_);
3808 {
3809 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203810 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143811
[email protected]aa043632013-03-25 03:39:423812 // Verify all quads have been computed
3813 ASSERT_EQ(2U, frame.render_passes.size());
3814 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
3815 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
3816 EXPECT_EQ(DrawQuad::SOLID_COLOR,
3817 frame.render_passes[0]->quad_list[0]->material);
3818 EXPECT_EQ(DrawQuad::RENDER_PASS,
3819 frame.render_passes[1]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:143820
[email protected]de2cf8c2013-10-25 19:46:463821 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423822 my_host_impl->DidDrawAllLayers(frame);
3823 }
[email protected]94f206c12012-08-25 00:09:143824}
3825
[email protected]aa043632013-03-25 03:39:423826TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
3827 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3828 SetupLayersForOpacity(false, this, &proxy_, &stats_instrumentation_);
3829 {
3830 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203831 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143832
[email protected]aa043632013-03-25 03:39:423833 // Verify all quads have been computed
3834 ASSERT_EQ(2U, frame.render_passes.size());
3835 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
3836 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
3837 EXPECT_EQ(DrawQuad::SOLID_COLOR,
3838 frame.render_passes[0]->quad_list[0]->material);
3839 EXPECT_EQ(DrawQuad::RENDER_PASS,
3840 frame.render_passes[1]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:143841
[email protected]de2cf8c2013-10-25 19:46:463842 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423843 my_host_impl->DidDrawAllLayers(frame);
3844 }
[email protected]94f206c12012-08-25 00:09:143845}
3846
[email protected]aa043632013-03-25 03:39:423847TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
3848 scoped_ptr<TestWebGraphicsContext3D> context =
3849 TestWebGraphicsContext3D::Create();
3850 TestWebGraphicsContext3D* context3d = context.get();
[email protected]0634cdd42013-08-16 00:46:093851 scoped_ptr<OutputSurface> output_surface(
3852 FakeOutputSurface::Create3d(context.Pass()));
[email protected]aa043632013-03-25 03:39:423853 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]d993b602013-01-04 02:08:123854
[email protected]aa043632013-03-25 03:39:423855 scoped_ptr<LayerImpl> root_layer =
3856 LayerImpl::Create(host_impl_->active_tree(), 1);
3857 root_layer->SetBounds(gfx::Size(10, 10));
3858 root_layer->SetAnchorPoint(gfx::PointF());
[email protected]94f206c12012-08-25 00:09:143859
[email protected]aa043632013-03-25 03:39:423860 scoped_refptr<VideoFrame> softwareFrame =
3861 media::VideoFrame::CreateColorFrame(
3862 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
3863 FakeVideoFrameProvider provider;
3864 provider.set_frame(softwareFrame);
3865 scoped_ptr<VideoLayerImpl> video_layer =
3866 VideoLayerImpl::Create(host_impl_->active_tree(), 4, &provider);
3867 video_layer->SetBounds(gfx::Size(10, 10));
3868 video_layer->SetAnchorPoint(gfx::PointF());
3869 video_layer->SetContentBounds(gfx::Size(10, 10));
3870 video_layer->SetDrawsContent(true);
3871 root_layer->AddChild(video_layer.PassAs<LayerImpl>());
[email protected]94f206c12012-08-25 00:09:143872
[email protected]aa043632013-03-25 03:39:423873 scoped_ptr<IOSurfaceLayerImpl> io_surface_layer =
3874 IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5);
3875 io_surface_layer->SetBounds(gfx::Size(10, 10));
3876 io_surface_layer->SetAnchorPoint(gfx::PointF());
3877 io_surface_layer->SetContentBounds(gfx::Size(10, 10));
3878 io_surface_layer->SetDrawsContent(true);
3879 io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10));
3880 root_layer->AddChild(io_surface_layer.PassAs<LayerImpl>());
[email protected]94f206c12012-08-25 00:09:143881
[email protected]aa043632013-03-25 03:39:423882 host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
[email protected]94f206c12012-08-25 00:09:143883
[email protected]aa043632013-03-25 03:39:423884 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]d993b602013-01-04 02:08:123885
[email protected]aa043632013-03-25 03:39:423886 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203887 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463888 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423889 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203890 host_impl_->SwapBuffers(frame);
[email protected]94f206c12012-08-25 00:09:143891
[email protected]aa043632013-03-25 03:39:423892 EXPECT_GT(context3d->NumTextures(), 0u);
[email protected]94f206c12012-08-25 00:09:143893
[email protected]aa043632013-03-25 03:39:423894 // Kill the layer tree.
3895 host_impl_->active_tree()->SetRootLayer(
3896 LayerImpl::Create(host_impl_->active_tree(), 100));
3897 // There should be no textures left in use after.
3898 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]94f206c12012-08-25 00:09:143899}
3900
[email protected]c8756fbe2013-02-12 01:53:493901class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423902 public:
[email protected]c32e27082013-11-07 06:58:203903 MOCK_METHOD1(useProgram, void(blink::WebGLId program));
3904 MOCK_METHOD4(drawElements, void(blink::WGC3Denum mode,
3905 blink::WGC3Dsizei count,
3906 blink::WGC3Denum type,
3907 blink::WGC3Dintptr offset));
[email protected]94f206c12012-08-25 00:09:143908};
3909
[email protected]aa043632013-03-25 03:39:423910TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
[email protected]0634cdd42013-08-16 00:46:093911 scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned(
3912 new MockDrawQuadsToFillScreenContext);
3913 MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get();
3914
3915 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3916 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]94f206c12012-08-25 00:09:143917
[email protected]aa043632013-03-25 03:39:423918 // Run test case
3919 CreateLayerTreeHost(false, output_surface.Pass());
3920 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
3921 host_impl_->active_tree()->set_background_color(SK_ColorWHITE);
[email protected]94f206c12012-08-25 00:09:143922
[email protected]aa043632013-03-25 03:39:423923 // Verify one quad is drawn when transparent background set is not set.
3924 host_impl_->active_tree()->set_has_transparent_background(false);
3925 EXPECT_CALL(*mock_context, useProgram(_))
3926 .Times(1);
3927 EXPECT_CALL(*mock_context, drawElements(_, _, _, _))
3928 .Times(1);
3929 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203930 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463931 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423932 host_impl_->DidDrawAllLayers(frame);
3933 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143934
[email protected]aa043632013-03-25 03:39:423935 // Verify no quads are drawn when transparent background is set.
3936 host_impl_->active_tree()->set_has_transparent_background(true);
[email protected]e0341352013-04-06 05:01:203937 host_impl_->SetFullRootLayerDamage();
3938 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:463939 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:423940 host_impl_->DidDrawAllLayers(frame);
3941 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143942}
3943
[email protected]aa043632013-03-25 03:39:423944TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
3945 set_reduce_memory_result(false);
[email protected]b1969fa2012-10-17 20:16:293946
[email protected]d7626ffd2013-03-29 00:17:423947 // If changing the memory limit wouldn't result in changing what was
3948 // committed, then no commit should be requested.
[email protected]aa043632013-03-25 03:39:423949 set_reduce_memory_result(false);
[email protected]d7626ffd2013-03-29 00:17:423950 host_impl_->set_max_memory_needed_bytes(
3951 host_impl_->memory_allocation_limit_bytes() - 1);
[email protected]fd32d122013-06-29 13:11:043952 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073953 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]d7626ffd2013-03-29 00:17:423954 EXPECT_FALSE(did_request_commit_);
3955 did_request_commit_ = false;
3956
3957 // If changing the memory limit would result in changing what was
3958 // committed, then a commit should be requested, even though nothing was
3959 // evicted.
3960 set_reduce_memory_result(false);
3961 host_impl_->set_max_memory_needed_bytes(
3962 host_impl_->memory_allocation_limit_bytes());
[email protected]fd32d122013-06-29 13:11:043963 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073964 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]aa043632013-03-25 03:39:423965 EXPECT_TRUE(did_request_commit_);
3966 did_request_commit_ = false;
[email protected]b1969fa2012-10-17 20:16:293967
[email protected]aa043632013-03-25 03:39:423968 // Especially if changing the memory limit caused evictions, we need
3969 // to re-commit.
3970 set_reduce_memory_result(true);
[email protected]d7626ffd2013-03-29 00:17:423971 host_impl_->set_max_memory_needed_bytes(1);
[email protected]fd32d122013-06-29 13:11:043972 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073973 host_impl_->memory_allocation_limit_bytes() - 1));
[email protected]aa043632013-03-25 03:39:423974 EXPECT_TRUE(did_request_commit_);
3975 did_request_commit_ = false;
[email protected]b1969fa2012-10-17 20:16:293976
[email protected]aa043632013-03-25 03:39:423977 // But if we set it to the same value that it was before, we shouldn't
3978 // re-commit.
[email protected]fd32d122013-06-29 13:11:043979 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:073980 host_impl_->memory_allocation_limit_bytes()));
[email protected]aa043632013-03-25 03:39:423981 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:143982}
3983
[email protected]aa043632013-03-25 03:39:423984class LayerTreeHostImplTestWithDelegatingRenderer
3985 : public LayerTreeHostImplTest {
3986 protected:
3987 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
3988 return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>();
3989 }
3990
3991 void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) {
[email protected]e0341352013-04-06 05:01:203992 bool expect_to_draw = !expected_damage.IsEmpty();
3993
[email protected]aa043632013-03-25 03:39:423994 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203995 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423996
[email protected]e0341352013-04-06 05:01:203997 if (!expect_to_draw) {
3998 // With no damage, we don't draw, and no quads are created.
3999 ASSERT_EQ(0u, frame.render_passes.size());
4000 } else {
4001 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]aa043632013-03-25 03:39:424002
[email protected]e0341352013-04-06 05:01:204003 // Verify the damage rect for the root render pass.
4004 const RenderPass* root_render_pass = frame.render_passes.back();
4005 EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect);
4006
4007 // Verify the root and child layers' quads are generated and not being
4008 // culled.
4009 ASSERT_EQ(2u, root_render_pass->quad_list.size());
4010
4011 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
4012 gfx::RectF expected_child_visible_rect(child->content_bounds());
4013 EXPECT_RECT_EQ(expected_child_visible_rect,
4014 root_render_pass->quad_list[0]->visible_rect);
4015
4016 LayerImpl* root = host_impl_->active_tree()->root_layer();
4017 gfx::RectF expected_root_visible_rect(root->content_bounds());
4018 EXPECT_RECT_EQ(expected_root_visible_rect,
4019 root_render_pass->quad_list[1]->visible_rect);
4020 }
[email protected]aa043632013-03-25 03:39:424021
[email protected]de2cf8c2013-10-25 19:46:464022 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424023 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:204024 EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame));
[email protected]aa043632013-03-25 03:39:424025 }
4026};
4027
4028TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
4029 scoped_ptr<SolidColorLayerImpl> root =
4030 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
4031 root->SetAnchorPoint(gfx::PointF());
4032 root->SetPosition(gfx::PointF());
4033 root->SetBounds(gfx::Size(10, 10));
4034 root->SetContentBounds(gfx::Size(10, 10));
4035 root->SetDrawsContent(true);
[email protected]e0341352013-04-06 05:01:204036
4037 // Child layer is in the bottom right corner.
4038 scoped_ptr<SolidColorLayerImpl> child =
4039 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
4040 child->SetAnchorPoint(gfx::PointF(0.f, 0.f));
4041 child->SetPosition(gfx::PointF(9.f, 9.f));
4042 child->SetBounds(gfx::Size(1, 1));
4043 child->SetContentBounds(gfx::Size(1, 1));
4044 child->SetDrawsContent(true);
4045 root->AddChild(child.PassAs<LayerImpl>());
4046
[email protected]aa043632013-03-25 03:39:424047 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>());
4048
4049 // Draw a frame. In the first frame, the entire viewport should be damaged.
[email protected]54af03522013-09-05 00:43:284050 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
[email protected]aa043632013-03-25 03:39:424051 DrawFrameAndTestDamage(full_frame_damage);
4052
[email protected]e0341352013-04-06 05:01:204053 // The second frame has damage that doesn't touch the child layer. Its quads
4054 // should still be generated.
4055 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
4056 host_impl_->active_tree()->root_layer()->set_update_rect(small_damage);
4057 DrawFrameAndTestDamage(small_damage);
4058
4059 // The third frame should have no damage, so no quads should be generated.
[email protected]aa043632013-03-25 03:39:424060 gfx::Rect no_damage;
4061 DrawFrameAndTestDamage(no_damage);
[email protected]ea9d8f22012-12-08 03:39:294062}
4063
[email protected]05dea302013-01-15 08:30:414064class FakeMaskLayerImpl : public LayerImpl {
[email protected]aa043632013-03-25 03:39:424065 public:
4066 static scoped_ptr<FakeMaskLayerImpl> Create(LayerTreeImpl* tree_impl,
4067 int id) {
4068 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id));
4069 }
[email protected]05dea302013-01-15 08:30:414070
[email protected]aa043632013-03-25 03:39:424071 virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE {
4072 return 0;
4073 }
[email protected]05dea302013-01-15 08:30:414074
[email protected]aa043632013-03-25 03:39:424075 private:
4076 FakeMaskLayerImpl(LayerTreeImpl* tree_impl, int id)
4077 : LayerImpl(tree_impl, id) {}
[email protected]05dea302013-01-15 08:30:414078};
4079
[email protected]aa043632013-03-25 03:39:424080TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
[email protected]35a99a12013-05-09 23:52:294081 LayerTreeSettings settings;
4082 settings.layer_transforms_should_scale_layer_contents = true;
[email protected]a7f35682013-10-22 23:05:574083 host_impl_ = LayerTreeHostImpl::Create(
4084 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]35a99a12013-05-09 23:52:294085 host_impl_->InitializeRenderer(CreateOutputSurface());
4086 host_impl_->SetViewportSize(gfx::Size(10, 10));
4087
[email protected]aa043632013-03-25 03:39:424088 // Root
4089 // |
4090 // +-- Scaling Layer (adds a 2x scale)
4091 // |
4092 // +-- Content Layer
4093 // +--Mask
4094 scoped_ptr<LayerImpl> scoped_root =
4095 LayerImpl::Create(host_impl_->active_tree(), 1);
4096 LayerImpl* root = scoped_root.get();
4097 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
[email protected]05dea302013-01-15 08:30:414098
[email protected]aa043632013-03-25 03:39:424099 scoped_ptr<LayerImpl> scoped_scaling_layer =
4100 LayerImpl::Create(host_impl_->active_tree(), 2);
4101 LayerImpl* scaling_layer = scoped_scaling_layer.get();
4102 root->AddChild(scoped_scaling_layer.Pass());
[email protected]05dea302013-01-15 08:30:414103
[email protected]aa043632013-03-25 03:39:424104 scoped_ptr<LayerImpl> scoped_content_layer =
4105 LayerImpl::Create(host_impl_->active_tree(), 3);
4106 LayerImpl* content_layer = scoped_content_layer.get();
4107 scaling_layer->AddChild(scoped_content_layer.Pass());
[email protected]05dea302013-01-15 08:30:414108
[email protected]aa043632013-03-25 03:39:424109 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4110 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
4111 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4112 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
[email protected]05dea302013-01-15 08:30:414113
[email protected]aa043632013-03-25 03:39:424114 gfx::Size root_size(100, 100);
4115 root->SetBounds(root_size);
4116 root->SetContentBounds(root_size);
4117 root->SetPosition(gfx::PointF());
4118 root->SetAnchorPoint(gfx::PointF());
[email protected]05dea302013-01-15 08:30:414119
[email protected]aa043632013-03-25 03:39:424120 gfx::Size scaling_layer_size(50, 50);
4121 scaling_layer->SetBounds(scaling_layer_size);
4122 scaling_layer->SetContentBounds(scaling_layer_size);
4123 scaling_layer->SetPosition(gfx::PointF());
4124 scaling_layer->SetAnchorPoint(gfx::PointF());
4125 gfx::Transform scale;
4126 scale.Scale(2.f, 2.f);
4127 scaling_layer->SetTransform(scale);
[email protected]05dea302013-01-15 08:30:414128
[email protected]aa043632013-03-25 03:39:424129 content_layer->SetBounds(scaling_layer_size);
4130 content_layer->SetContentBounds(scaling_layer_size);
4131 content_layer->SetPosition(gfx::PointF());
4132 content_layer->SetAnchorPoint(gfx::PointF());
4133 content_layer->SetDrawsContent(true);
[email protected]05dea302013-01-15 08:30:414134
[email protected]aa043632013-03-25 03:39:424135 mask_layer->SetBounds(scaling_layer_size);
4136 mask_layer->SetContentBounds(scaling_layer_size);
4137 mask_layer->SetPosition(gfx::PointF());
4138 mask_layer->SetAnchorPoint(gfx::PointF());
4139 mask_layer->SetDrawsContent(true);
[email protected]05dea302013-01-15 08:30:414140
4141
[email protected]aa043632013-03-25 03:39:424142 // Check that the tree scaling is correctly taken into account for the mask,
4143 // that should fully map onto the quad.
4144 float device_scale_factor = 1.f;
[email protected]18ce59702013-04-09 04:58:404145 host_impl_->SetViewportSize(root_size);
[email protected]a7dffcf2013-03-29 08:54:014146 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4147 {
[email protected]aa043632013-03-25 03:39:424148 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204149 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:414150
[email protected]aa043632013-03-25 03:39:424151 ASSERT_EQ(1u, frame.render_passes.size());
4152 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4153 ASSERT_EQ(DrawQuad::RENDER_PASS,
4154 frame.render_passes[0]->quad_list[0]->material);
4155 const RenderPassDrawQuad* render_pass_quad =
4156 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4157 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4158 render_pass_quad->rect.ToString());
4159 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4160 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:414161
[email protected]de2cf8c2013-10-25 19:46:464162 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424163 host_impl_->DidDrawAllLayers(frame);
4164 }
[email protected]05dea302013-01-15 08:30:414165
4166
[email protected]aa043632013-03-25 03:39:424167 // Applying a DSF should change the render surface size, but won't affect
4168 // which part of the mask is used.
4169 device_scale_factor = 2.f;
4170 gfx::Size device_viewport =
4171 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
[email protected]18ce59702013-04-09 04:58:404172 host_impl_->SetViewportSize(device_viewport);
[email protected]aa043632013-03-25 03:39:424173 host_impl_->SetDeviceScaleFactor(device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014174 host_impl_->active_tree()->set_needs_update_draw_properties();
4175 {
[email protected]aa043632013-03-25 03:39:424176 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204177 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:414178
[email protected]aa043632013-03-25 03:39:424179 ASSERT_EQ(1u, frame.render_passes.size());
4180 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4181 ASSERT_EQ(DrawQuad::RENDER_PASS,
4182 frame.render_passes[0]->quad_list[0]->material);
4183 const RenderPassDrawQuad* render_pass_quad =
4184 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4185 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4186 render_pass_quad->rect.ToString());
4187 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4188 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:414189
[email protected]de2cf8c2013-10-25 19:46:464190 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424191 host_impl_->DidDrawAllLayers(frame);
4192 }
[email protected]05dea302013-01-15 08:30:414193
4194
[email protected]aa043632013-03-25 03:39:424195 // Applying an equivalent content scale on the content layer and the mask
4196 // should still result in the same part of the mask being used.
4197 gfx::Size content_bounds =
4198 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size,
4199 device_scale_factor));
4200 content_layer->SetContentBounds(content_bounds);
4201 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4202 mask_layer->SetContentBounds(content_bounds);
4203 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014204 host_impl_->active_tree()->set_needs_update_draw_properties();
4205 {
[email protected]aa043632013-03-25 03:39:424206 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204207 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:414208
[email protected]aa043632013-03-25 03:39:424209 ASSERT_EQ(1u, frame.render_passes.size());
4210 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4211 ASSERT_EQ(DrawQuad::RENDER_PASS,
4212 frame.render_passes[0]->quad_list[0]->material);
4213 const RenderPassDrawQuad* render_pass_quad =
4214 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4215 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4216 render_pass_quad->rect.ToString());
4217 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4218 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554219
[email protected]de2cf8c2013-10-25 19:46:464220 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424221 host_impl_->DidDrawAllLayers(frame);
4222 }
[email protected]8611f012013-01-17 03:44:554223}
4224
[email protected]aa043632013-03-25 03:39:424225TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
4226 // The mask layer has bounds 100x100 but is attached to a layer with bounds
4227 // 50x50.
[email protected]8611f012013-01-17 03:44:554228
[email protected]aa043632013-03-25 03:39:424229 scoped_ptr<LayerImpl> scoped_root =
4230 LayerImpl::Create(host_impl_->active_tree(), 1);
4231 LayerImpl* root = scoped_root.get();
4232 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
[email protected]8611f012013-01-17 03:44:554233
[email protected]aa043632013-03-25 03:39:424234 scoped_ptr<LayerImpl> scoped_content_layer =
4235 LayerImpl::Create(host_impl_->active_tree(), 3);
4236 LayerImpl* content_layer = scoped_content_layer.get();
4237 root->AddChild(scoped_content_layer.Pass());
[email protected]8611f012013-01-17 03:44:554238
[email protected]aa043632013-03-25 03:39:424239 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4240 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
4241 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4242 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
[email protected]8611f012013-01-17 03:44:554243
[email protected]aa043632013-03-25 03:39:424244 gfx::Size root_size(100, 100);
4245 root->SetBounds(root_size);
4246 root->SetContentBounds(root_size);
4247 root->SetPosition(gfx::PointF());
4248 root->SetAnchorPoint(gfx::PointF());
[email protected]8611f012013-01-17 03:44:554249
[email protected]aa043632013-03-25 03:39:424250 gfx::Size layer_size(50, 50);
4251 content_layer->SetBounds(layer_size);
4252 content_layer->SetContentBounds(layer_size);
4253 content_layer->SetPosition(gfx::PointF());
4254 content_layer->SetAnchorPoint(gfx::PointF());
4255 content_layer->SetDrawsContent(true);
[email protected]8611f012013-01-17 03:44:554256
[email protected]aa043632013-03-25 03:39:424257 gfx::Size mask_size(100, 100);
4258 mask_layer->SetBounds(mask_size);
4259 mask_layer->SetContentBounds(mask_size);
4260 mask_layer->SetPosition(gfx::PointF());
4261 mask_layer->SetAnchorPoint(gfx::PointF());
4262 mask_layer->SetDrawsContent(true);
[email protected]8611f012013-01-17 03:44:554263
[email protected]aa043632013-03-25 03:39:424264 // Check that the mask fills the surface.
4265 float device_scale_factor = 1.f;
[email protected]18ce59702013-04-09 04:58:404266 host_impl_->SetViewportSize(root_size);
[email protected]a7dffcf2013-03-29 08:54:014267 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4268 {
[email protected]aa043632013-03-25 03:39:424269 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204270 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554271
[email protected]aa043632013-03-25 03:39:424272 ASSERT_EQ(1u, frame.render_passes.size());
4273 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4274 ASSERT_EQ(DrawQuad::RENDER_PASS,
4275 frame.render_passes[0]->quad_list[0]->material);
4276 const RenderPassDrawQuad* render_pass_quad =
4277 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4278 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4279 render_pass_quad->rect.ToString());
4280 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4281 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554282
[email protected]de2cf8c2013-10-25 19:46:464283 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424284 host_impl_->DidDrawAllLayers(frame);
4285 }
[email protected]8611f012013-01-17 03:44:554286
[email protected]aa043632013-03-25 03:39:424287 // Applying a DSF should change the render surface size, but won't affect
4288 // which part of the mask is used.
4289 device_scale_factor = 2.f;
4290 gfx::Size device_viewport =
4291 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
[email protected]18ce59702013-04-09 04:58:404292 host_impl_->SetViewportSize(device_viewport);
[email protected]aa043632013-03-25 03:39:424293 host_impl_->SetDeviceScaleFactor(device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014294 host_impl_->active_tree()->set_needs_update_draw_properties();
4295 {
[email protected]aa043632013-03-25 03:39:424296 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204297 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554298
[email protected]aa043632013-03-25 03:39:424299 ASSERT_EQ(1u, frame.render_passes.size());
4300 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4301 ASSERT_EQ(DrawQuad::RENDER_PASS,
4302 frame.render_passes[0]->quad_list[0]->material);
4303 const RenderPassDrawQuad* render_pass_quad =
4304 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4305 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4306 render_pass_quad->rect.ToString());
4307 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4308 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554309
[email protected]de2cf8c2013-10-25 19:46:464310 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424311 host_impl_->DidDrawAllLayers(frame);
4312 }
[email protected]8611f012013-01-17 03:44:554313
[email protected]aa043632013-03-25 03:39:424314 // Applying an equivalent content scale on the content layer and the mask
4315 // should still result in the same part of the mask being used.
4316 gfx::Size layer_size_large =
4317 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
4318 content_layer->SetContentBounds(layer_size_large);
4319 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4320 gfx::Size mask_size_large =
4321 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
4322 mask_layer->SetContentBounds(mask_size_large);
4323 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:014324 host_impl_->active_tree()->set_needs_update_draw_properties();
4325 {
[email protected]aa043632013-03-25 03:39:424326 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204327 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554328
[email protected]aa043632013-03-25 03:39:424329 ASSERT_EQ(1u, frame.render_passes.size());
4330 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4331 ASSERT_EQ(DrawQuad::RENDER_PASS,
4332 frame.render_passes[0]->quad_list[0]->material);
4333 const RenderPassDrawQuad* render_pass_quad =
4334 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4335 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4336 render_pass_quad->rect.ToString());
4337 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4338 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:554339
[email protected]de2cf8c2013-10-25 19:46:464340 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424341 host_impl_->DidDrawAllLayers(frame);
4342 }
[email protected]8611f012013-01-17 03:44:554343
[email protected]8591a642013-04-17 18:48:564344 // Applying a different contents scale to the mask layer means it will have
4345 // a larger texture, but it should use the same tex coords to cover the
4346 // layer it masks.
[email protected]aa043632013-03-25 03:39:424347 mask_layer->SetContentBounds(mask_size);
[email protected]8591a642013-04-17 18:48:564348 mask_layer->SetContentsScale(1.f, 1.f);
[email protected]a7dffcf2013-03-29 08:54:014349 host_impl_->active_tree()->set_needs_update_draw_properties();
4350 {
[email protected]aa043632013-03-25 03:39:424351 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204352 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:554353
[email protected]aa043632013-03-25 03:39:424354 ASSERT_EQ(1u, frame.render_passes.size());
4355 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4356 ASSERT_EQ(DrawQuad::RENDER_PASS,
4357 frame.render_passes[0]->quad_list[0]->material);
4358 const RenderPassDrawQuad* render_pass_quad =
4359 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4360 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4361 render_pass_quad->rect.ToString());
4362 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4363 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:414364
[email protected]de2cf8c2013-10-25 19:46:464365 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]aa043632013-03-25 03:39:424366 host_impl_->DidDrawAllLayers(frame);
4367 }
[email protected]05dea302013-01-15 08:30:414368}
4369
[email protected]8591a642013-04-17 18:48:564370TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
4371 // The replica's mask layer has bounds 100x100 but the replica is of a
4372 // layer with bounds 50x50.
4373
4374 scoped_ptr<LayerImpl> scoped_root =
4375 LayerImpl::Create(host_impl_->active_tree(), 1);
4376 LayerImpl* root = scoped_root.get();
4377 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
4378
4379 scoped_ptr<LayerImpl> scoped_content_layer =
4380 LayerImpl::Create(host_impl_->active_tree(), 3);
4381 LayerImpl* content_layer = scoped_content_layer.get();
4382 root->AddChild(scoped_content_layer.Pass());
4383
4384 scoped_ptr<LayerImpl> scoped_replica_layer =
4385 LayerImpl::Create(host_impl_->active_tree(), 2);
4386 LayerImpl* replica_layer = scoped_replica_layer.get();
4387 content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
4388
4389 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4390 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
4391 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4392 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
4393
4394 gfx::Size root_size(100, 100);
4395 root->SetBounds(root_size);
4396 root->SetContentBounds(root_size);
4397 root->SetPosition(gfx::PointF());
4398 root->SetAnchorPoint(gfx::PointF());
4399
4400 gfx::Size layer_size(50, 50);
4401 content_layer->SetBounds(layer_size);
4402 content_layer->SetContentBounds(layer_size);
4403 content_layer->SetPosition(gfx::PointF());
4404 content_layer->SetAnchorPoint(gfx::PointF());
4405 content_layer->SetDrawsContent(true);
4406
4407 gfx::Size mask_size(100, 100);
4408 mask_layer->SetBounds(mask_size);
4409 mask_layer->SetContentBounds(mask_size);
4410 mask_layer->SetPosition(gfx::PointF());
4411 mask_layer->SetAnchorPoint(gfx::PointF());
4412 mask_layer->SetDrawsContent(true);
4413
4414 // Check that the mask fills the surface.
4415 float device_scale_factor = 1.f;
4416 host_impl_->SetViewportSize(root_size);
4417 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4418 {
4419 LayerTreeHostImpl::FrameData frame;
4420 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4421
4422 ASSERT_EQ(1u, frame.render_passes.size());
4423 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4424 ASSERT_EQ(DrawQuad::RENDER_PASS,
4425 frame.render_passes[0]->quad_list[1]->material);
4426 const RenderPassDrawQuad* replica_quad =
4427 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4428 EXPECT_TRUE(replica_quad->is_replica);
4429 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4430 replica_quad->rect.ToString());
4431 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4432 replica_quad->mask_uv_rect.ToString());
4433
[email protected]de2cf8c2013-10-25 19:46:464434 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564435 host_impl_->DidDrawAllLayers(frame);
4436 }
4437
4438 // Applying a DSF should change the render surface size, but won't affect
4439 // which part of the mask is used.
4440 device_scale_factor = 2.f;
4441 gfx::Size device_viewport =
4442 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
4443 host_impl_->SetViewportSize(device_viewport);
4444 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4445 host_impl_->active_tree()->set_needs_update_draw_properties();
4446 {
4447 LayerTreeHostImpl::FrameData frame;
4448 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4449
4450 ASSERT_EQ(1u, frame.render_passes.size());
4451 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4452 ASSERT_EQ(DrawQuad::RENDER_PASS,
4453 frame.render_passes[0]->quad_list[1]->material);
4454 const RenderPassDrawQuad* replica_quad =
4455 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4456 EXPECT_TRUE(replica_quad->is_replica);
4457 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4458 replica_quad->rect.ToString());
4459 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4460 replica_quad->mask_uv_rect.ToString());
4461
[email protected]de2cf8c2013-10-25 19:46:464462 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564463 host_impl_->DidDrawAllLayers(frame);
4464 }
4465
4466 // Applying an equivalent content scale on the content layer and the mask
4467 // should still result in the same part of the mask being used.
4468 gfx::Size layer_size_large =
4469 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
4470 content_layer->SetContentBounds(layer_size_large);
4471 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4472 gfx::Size mask_size_large =
4473 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
4474 mask_layer->SetContentBounds(mask_size_large);
4475 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
4476 host_impl_->active_tree()->set_needs_update_draw_properties();
4477 {
4478 LayerTreeHostImpl::FrameData frame;
4479 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4480
4481 ASSERT_EQ(1u, frame.render_passes.size());
4482 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4483 ASSERT_EQ(DrawQuad::RENDER_PASS,
4484 frame.render_passes[0]->quad_list[1]->material);
4485 const RenderPassDrawQuad* replica_quad =
4486 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4487 EXPECT_TRUE(replica_quad->is_replica);
4488 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4489 replica_quad->rect.ToString());
4490 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4491 replica_quad->mask_uv_rect.ToString());
4492
[email protected]de2cf8c2013-10-25 19:46:464493 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564494 host_impl_->DidDrawAllLayers(frame);
4495 }
4496
4497 // Applying a different contents scale to the mask layer means it will have
4498 // a larger texture, but it should use the same tex coords to cover the
4499 // layer it masks.
4500 mask_layer->SetContentBounds(mask_size);
4501 mask_layer->SetContentsScale(1.f, 1.f);
4502 host_impl_->active_tree()->set_needs_update_draw_properties();
4503 {
4504 LayerTreeHostImpl::FrameData frame;
4505 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4506
4507 ASSERT_EQ(1u, frame.render_passes.size());
4508 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4509 ASSERT_EQ(DrawQuad::RENDER_PASS,
4510 frame.render_passes[0]->quad_list[1]->material);
4511 const RenderPassDrawQuad* replica_quad =
4512 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4513 EXPECT_TRUE(replica_quad->is_replica);
4514 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4515 replica_quad->rect.ToString());
4516 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
4517 replica_quad->mask_uv_rect.ToString());
4518
[email protected]de2cf8c2013-10-25 19:46:464519 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564520 host_impl_->DidDrawAllLayers(frame);
4521 }
4522}
4523
4524TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) {
4525 // The replica is of a layer with bounds 50x50, but it has a child that causes
4526 // the surface bounds to be larger.
4527
4528 scoped_ptr<LayerImpl> scoped_root =
4529 LayerImpl::Create(host_impl_->active_tree(), 1);
4530 LayerImpl* root = scoped_root.get();
4531 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
4532
4533 scoped_ptr<LayerImpl> scoped_content_layer =
4534 LayerImpl::Create(host_impl_->active_tree(), 2);
4535 LayerImpl* content_layer = scoped_content_layer.get();
4536 root->AddChild(scoped_content_layer.Pass());
4537
4538 scoped_ptr<LayerImpl> scoped_content_child_layer =
4539 LayerImpl::Create(host_impl_->active_tree(), 3);
4540 LayerImpl* content_child_layer = scoped_content_child_layer.get();
4541 content_layer->AddChild(scoped_content_child_layer.Pass());
4542
4543 scoped_ptr<LayerImpl> scoped_replica_layer =
4544 LayerImpl::Create(host_impl_->active_tree(), 4);
4545 LayerImpl* replica_layer = scoped_replica_layer.get();
4546 content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
4547
4548 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4549 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5);
4550 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4551 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
4552
4553 gfx::Size root_size(100, 100);
4554 root->SetBounds(root_size);
4555 root->SetContentBounds(root_size);
4556 root->SetPosition(gfx::PointF());
4557 root->SetAnchorPoint(gfx::PointF());
4558
4559 gfx::Size layer_size(50, 50);
4560 content_layer->SetBounds(layer_size);
4561 content_layer->SetContentBounds(layer_size);
4562 content_layer->SetPosition(gfx::PointF());
4563 content_layer->SetAnchorPoint(gfx::PointF());
4564 content_layer->SetDrawsContent(true);
4565
4566 gfx::Size child_size(50, 50);
4567 content_child_layer->SetBounds(child_size);
4568 content_child_layer->SetContentBounds(child_size);
4569 content_child_layer->SetPosition(gfx::Point(50, 0));
4570 content_child_layer->SetAnchorPoint(gfx::PointF());
4571 content_child_layer->SetDrawsContent(true);
4572
4573 gfx::Size mask_size(50, 50);
4574 mask_layer->SetBounds(mask_size);
4575 mask_layer->SetContentBounds(mask_size);
4576 mask_layer->SetPosition(gfx::PointF());
4577 mask_layer->SetAnchorPoint(gfx::PointF());
4578 mask_layer->SetDrawsContent(true);
4579
4580 float device_scale_factor = 1.f;
4581 host_impl_->SetViewportSize(root_size);
4582 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4583 {
4584 LayerTreeHostImpl::FrameData frame;
4585 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4586
4587 ASSERT_EQ(1u, frame.render_passes.size());
4588 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4589
4590 // The surface is 100x50.
4591 ASSERT_EQ(DrawQuad::RENDER_PASS,
4592 frame.render_passes[0]->quad_list[0]->material);
4593 const RenderPassDrawQuad* render_pass_quad =
4594 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4595 EXPECT_FALSE(render_pass_quad->is_replica);
4596 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
4597 render_pass_quad->rect.ToString());
4598
4599 // The mask covers the owning layer only.
4600 ASSERT_EQ(DrawQuad::RENDER_PASS,
4601 frame.render_passes[0]->quad_list[1]->material);
4602 const RenderPassDrawQuad* replica_quad =
4603 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4604 EXPECT_TRUE(replica_quad->is_replica);
4605 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
4606 replica_quad->rect.ToString());
4607 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
4608 replica_quad->mask_uv_rect.ToString());
4609
[email protected]de2cf8c2013-10-25 19:46:464610 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564611 host_impl_->DidDrawAllLayers(frame);
4612 }
4613
4614 // Move the child to (-50, 0) instead. Now the mask should be moved to still
4615 // cover the layer being replicated.
4616 content_child_layer->SetPosition(gfx::Point(-50, 0));
4617 {
4618 LayerTreeHostImpl::FrameData frame;
4619 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4620
4621 ASSERT_EQ(1u, frame.render_passes.size());
4622 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
4623
4624 // The surface is 100x50 with its origin at (-50, 0).
4625 ASSERT_EQ(DrawQuad::RENDER_PASS,
4626 frame.render_passes[0]->quad_list[0]->material);
4627 const RenderPassDrawQuad* render_pass_quad =
4628 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4629 EXPECT_FALSE(render_pass_quad->is_replica);
4630 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
4631 render_pass_quad->rect.ToString());
4632
4633 // The mask covers the owning layer only.
4634 ASSERT_EQ(DrawQuad::RENDER_PASS,
4635 frame.render_passes[0]->quad_list[1]->material);
4636 const RenderPassDrawQuad* replica_quad =
4637 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
4638 EXPECT_TRUE(replica_quad->is_replica);
4639 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
4640 replica_quad->rect.ToString());
4641 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
4642 replica_quad->mask_uv_rect.ToString());
4643
[email protected]de2cf8c2013-10-25 19:46:464644 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564645 host_impl_->DidDrawAllLayers(frame);
4646 }
4647}
4648
4649TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) {
4650 // The masked layer has bounds 50x50, but it has a child that causes
4651 // the surface bounds to be larger. It also has a parent that clips the
4652 // masked layer and its surface.
4653
4654 scoped_ptr<LayerImpl> scoped_root =
4655 LayerImpl::Create(host_impl_->active_tree(), 1);
4656 LayerImpl* root = scoped_root.get();
4657 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
4658
4659 scoped_ptr<LayerImpl> scoped_clipping_layer =
4660 LayerImpl::Create(host_impl_->active_tree(), 2);
4661 LayerImpl* clipping_layer = scoped_clipping_layer.get();
4662 root->AddChild(scoped_clipping_layer.Pass());
4663
4664 scoped_ptr<LayerImpl> scoped_content_layer =
4665 LayerImpl::Create(host_impl_->active_tree(), 3);
4666 LayerImpl* content_layer = scoped_content_layer.get();
4667 clipping_layer->AddChild(scoped_content_layer.Pass());
4668
4669 scoped_ptr<LayerImpl> scoped_content_child_layer =
4670 LayerImpl::Create(host_impl_->active_tree(), 4);
4671 LayerImpl* content_child_layer = scoped_content_child_layer.get();
4672 content_layer->AddChild(scoped_content_child_layer.Pass());
4673
4674 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
4675 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6);
4676 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
4677 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
4678
4679 gfx::Size root_size(100, 100);
4680 root->SetBounds(root_size);
4681 root->SetContentBounds(root_size);
4682 root->SetPosition(gfx::PointF());
4683 root->SetAnchorPoint(gfx::PointF());
4684
4685 gfx::Rect clipping_rect(20, 10, 10, 20);
4686 clipping_layer->SetBounds(clipping_rect.size());
4687 clipping_layer->SetContentBounds(clipping_rect.size());
4688 clipping_layer->SetPosition(clipping_rect.origin());
4689 clipping_layer->SetAnchorPoint(gfx::PointF());
4690 clipping_layer->SetMasksToBounds(true);
4691
4692 gfx::Size layer_size(50, 50);
4693 content_layer->SetBounds(layer_size);
4694 content_layer->SetContentBounds(layer_size);
4695 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
4696 content_layer->SetAnchorPoint(gfx::PointF());
4697 content_layer->SetDrawsContent(true);
4698
4699 gfx::Size child_size(50, 50);
4700 content_child_layer->SetBounds(child_size);
4701 content_child_layer->SetContentBounds(child_size);
4702 content_child_layer->SetPosition(gfx::Point(50, 0));
4703 content_child_layer->SetAnchorPoint(gfx::PointF());
4704 content_child_layer->SetDrawsContent(true);
4705
4706 gfx::Size mask_size(100, 100);
4707 mask_layer->SetBounds(mask_size);
4708 mask_layer->SetContentBounds(mask_size);
4709 mask_layer->SetPosition(gfx::PointF());
4710 mask_layer->SetAnchorPoint(gfx::PointF());
4711 mask_layer->SetDrawsContent(true);
4712
4713 float device_scale_factor = 1.f;
4714 host_impl_->SetViewportSize(root_size);
4715 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4716 {
4717 LayerTreeHostImpl::FrameData frame;
4718 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4719
4720 ASSERT_EQ(1u, frame.render_passes.size());
4721 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
4722
4723 // The surface is clipped to 10x20.
4724 ASSERT_EQ(DrawQuad::RENDER_PASS,
4725 frame.render_passes[0]->quad_list[0]->material);
4726 const RenderPassDrawQuad* render_pass_quad =
4727 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4728 EXPECT_FALSE(render_pass_quad->is_replica);
4729 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
4730 render_pass_quad->rect.ToString());
4731
4732 // The masked layer is 50x50, but the surface size is 10x20. So the texture
4733 // coords in the mask are scaled by 10/50 and 20/50.
4734 // The surface is clipped to (20,10) so the mask texture coords are offset
4735 // by 20/50 and 10/50
4736 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f),
4737 1.f / 50.f).ToString(),
4738 render_pass_quad->mask_uv_rect.ToString());
4739
[email protected]de2cf8c2013-10-25 19:46:464740 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]8591a642013-04-17 18:48:564741 host_impl_->DidDrawAllLayers(frame);
4742 }
4743}
4744
[email protected]46b79d52013-09-07 04:29:294745class GLRendererWithSetupQuadForAntialiasing : public GLRenderer {
4746 public:
4747 using GLRenderer::SetupQuadForAntialiasing;
4748};
4749
4750TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
4751 // Due to precision issues (especially on Android), sometimes far
4752 // away quads can end up thinking they need AA.
4753 float device_scale_factor = 4.f / 3.f;
4754 host_impl_->SetDeviceScaleFactor(device_scale_factor);
4755 gfx::Size root_size(2000, 1000);
4756 gfx::Size device_viewport_size =
4757 gfx::ToCeiledSize(gfx::ScaleSize(root_size, device_scale_factor));
4758 host_impl_->SetViewportSize(device_viewport_size);
4759
4760 host_impl_->CreatePendingTree();
4761 host_impl_->pending_tree()
4762 ->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f);
4763
4764 scoped_ptr<LayerImpl> scoped_root =
4765 LayerImpl::Create(host_impl_->pending_tree(), 1);
4766 LayerImpl* root = scoped_root.get();
4767
4768 host_impl_->pending_tree()->SetRootLayer(scoped_root.Pass());
4769
4770 scoped_ptr<LayerImpl> scoped_scrolling_layer =
4771 LayerImpl::Create(host_impl_->pending_tree(), 2);
4772 LayerImpl* scrolling_layer = scoped_scrolling_layer.get();
4773 root->AddChild(scoped_scrolling_layer.Pass());
4774
4775 gfx::Size content_layer_bounds(100000, 100);
4776 gfx::Size pile_tile_size(3000, 3000);
4777 scoped_refptr<FakePicturePileImpl> pile(FakePicturePileImpl::CreateFilledPile(
4778 pile_tile_size, content_layer_bounds));
4779
4780 scoped_ptr<FakePictureLayerImpl> scoped_content_layer =
4781 FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile);
4782 LayerImpl* content_layer = scoped_content_layer.get();
4783 scrolling_layer->AddChild(scoped_content_layer.PassAs<LayerImpl>());
4784 content_layer->SetBounds(content_layer_bounds);
4785 content_layer->SetDrawsContent(true);
4786
4787 root->SetBounds(root_size);
4788
4789 gfx::Vector2d scroll_offset(100000, 0);
4790 scrolling_layer->SetScrollable(true);
4791 scrolling_layer->SetMaxScrollOffset(scroll_offset);
4792 scrolling_layer->SetScrollOffset(scroll_offset);
4793
4794 host_impl_->ActivatePendingTree();
4795
4796 host_impl_->active_tree()->UpdateDrawProperties();
4797 ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
4798
4799 LayerTreeHostImpl::FrameData frame;
4800 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4801
4802 ASSERT_EQ(1u, frame.render_passes.size());
4803 ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
4804 const DrawQuad* quad = frame.render_passes[0]->quad_list[0];
4805
4806 float edge[24];
4807 gfx::QuadF device_layer_quad;
4808 bool antialiased =
4809 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
4810 quad->quadTransform(), quad, &device_layer_quad, edge);
4811 EXPECT_FALSE(antialiased);
4812
[email protected]de2cf8c2013-10-25 19:46:464813 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]46b79d52013-09-07 04:29:294814 host_impl_->DidDrawAllLayers(frame);
4815}
4816
4817
[email protected]bb1e2822013-04-17 22:06:014818class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
4819 public:
4820 CompositorFrameMetadataTest()
4821 : swap_buffers_complete_(0) {}
4822
[email protected]bb1e2822013-04-17 22:06:014823 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {
4824 swap_buffers_complete_++;
4825 }
4826
4827 int swap_buffers_complete_;
4828};
4829
4830TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
4831 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
4832 {
4833 LayerTreeHostImpl::FrameData frame;
4834 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
4835 host_impl_->DrawLayers(&frame, base::TimeTicks());
4836 host_impl_->DidDrawAllLayers(frame);
4837 }
4838 CompositorFrameAck ack;
[email protected]a7335e0b2013-09-18 09:34:514839 host_impl_->ReclaimResources(&ack);
4840 host_impl_->OnSwapBuffersComplete();
[email protected]bb1e2822013-04-17 22:06:014841 EXPECT_EQ(swap_buffers_complete_, 1);
4842}
4843
[email protected]fbe89f72013-05-21 07:24:244844class CountingSoftwareDevice : public SoftwareOutputDevice {
4845 public:
4846 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
4847
4848 virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE {
4849 ++frames_began_;
4850 return SoftwareOutputDevice::BeginPaint(damage_rect);
4851 }
4852 virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE {
4853 ++frames_ended_;
4854 SoftwareOutputDevice::EndPaint(frame_data);
4855 }
4856
4857 int frames_began_, frames_ended_;
4858};
4859
4860TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) {
[email protected]50644642013-06-20 13:58:554861 // No main thread evictions in resourceless software mode.
4862 set_reduce_memory_result(false);
[email protected]fbe89f72013-05-21 07:24:244863 SetupScrollAndContentsLayers(gfx::Size(100, 100));
4864 host_impl_->SetViewportSize(gfx::Size(50, 50));
4865 CountingSoftwareDevice* software_device = new CountingSoftwareDevice();
4866 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL(
4867 scoped_ptr<SoftwareOutputDevice>(software_device)).release();
[email protected]50644642013-06-20 13:58:554868 EXPECT_TRUE(host_impl_->InitializeRenderer(
4869 scoped_ptr<OutputSurface>(output_surface)));
[email protected]fbe89f72013-05-21 07:24:244870
4871 output_surface->set_forced_draw_to_software_device(true);
4872 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice());
4873
4874 EXPECT_EQ(0, software_device->frames_began_);
4875 EXPECT_EQ(0, software_device->frames_ended_);
4876
4877 DrawFrame();
4878
4879 EXPECT_EQ(1, software_device->frames_began_);
4880 EXPECT_EQ(1, software_device->frames_ended_);
[email protected]15cc9922013-05-24 07:31:474881
4882 // Call other API methods that are likely to hit NULL pointer in this mode.
4883 EXPECT_TRUE(host_impl_->AsValue());
4884 EXPECT_TRUE(host_impl_->ActivationStateAsValue());
[email protected]fbe89f72013-05-21 07:24:244885}
4886
[email protected]ffbb2212013-06-02 23:47:594887TEST_F(LayerTreeHostImplTest,
4888 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) {
[email protected]50644642013-06-20 13:58:554889 set_reduce_memory_result(false);
[email protected]ffbb2212013-06-02 23:47:594890 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL(
4891 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())).release();
4892 host_impl_->InitializeRenderer(
4893 scoped_ptr<OutputSurface>(output_surface));
4894
4895 output_surface->set_forced_draw_to_software_device(true);
4896 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice());
4897
4898 // SolidColorLayerImpl will be drawn.
4899 scoped_ptr<SolidColorLayerImpl> root_layer =
4900 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
4901
4902 // VideoLayerImpl will not be drawn.
4903 FakeVideoFrameProvider provider;
4904 scoped_ptr<VideoLayerImpl> video_layer =
4905 VideoLayerImpl::Create(host_impl_->active_tree(), 2, &provider);
4906 video_layer->SetBounds(gfx::Size(10, 10));
4907 video_layer->SetContentBounds(gfx::Size(10, 10));
4908 video_layer->SetDrawsContent(true);
4909 root_layer->AddChild(video_layer.PassAs<LayerImpl>());
4910 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>());
4911
4912 LayerTreeHostImpl::FrameData frame;
4913 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:464914 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ffbb2212013-06-02 23:47:594915 host_impl_->DidDrawAllLayers(frame);
4916
4917 EXPECT_EQ(1u, frame.will_draw_layers.size());
4918 EXPECT_EQ(host_impl_->active_tree()->root_layer(), frame.will_draw_layers[0]);
4919}
4920
[email protected]d9ca99e2013-08-28 21:49:484921class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest {
4922 protected:
4923 virtual void SetUp() OVERRIDE {
4924 LayerTreeHostImplTest::SetUp();
[email protected]2b154b22013-06-07 09:03:274925
[email protected]d9ca99e2013-08-28 21:49:484926 set_reduce_memory_result(false);
[email protected]2b154b22013-06-07 09:03:274927
[email protected]d9ca99e2013-08-28 21:49:484928 scoped_ptr<FakeOutputSurface> output_surface(
4929 FakeOutputSurface::CreateDeferredGL(
4930 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())));
4931 output_surface_ = output_surface.get();
4932
4933 EXPECT_TRUE(host_impl_->InitializeRenderer(
4934 output_surface.PassAs<OutputSurface>()));
4935
4936 scoped_ptr<SolidColorLayerImpl> root_layer =
4937 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
4938 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>());
4939
4940 onscreen_context_provider_ = TestContextProvider::Create();
4941 offscreen_context_provider_ = TestContextProvider::Create();
4942 }
4943
4944 FakeOutputSurface* output_surface_;
4945 scoped_refptr<TestContextProvider> onscreen_context_provider_;
4946 scoped_refptr<TestContextProvider> offscreen_context_provider_;
4947};
4948
4949
4950TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) {
[email protected]2b154b22013-06-07 09:03:274951 // Software draw.
4952 DrawFrame();
4953
[email protected]b5174d712013-08-28 08:10:434954 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4955 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4956
[email protected]2b154b22013-06-07 09:03:274957 // DeferredInitialize and hardware draw.
[email protected]d9ca99e2013-08-28 21:49:484958 EXPECT_TRUE(output_surface_->InitializeAndSetContext3d(
4959 onscreen_context_provider_, offscreen_context_provider_));
4960 EXPECT_EQ(onscreen_context_provider_,
[email protected]b5174d712013-08-28 08:10:434961 host_impl_->output_surface()->context_provider());
[email protected]d9ca99e2013-08-28 21:49:484962 EXPECT_EQ(offscreen_context_provider_,
[email protected]b5174d712013-08-28 08:10:434963 host_impl_->offscreen_context_provider());
[email protected]2b154b22013-06-07 09:03:274964
4965 // Defer intialized GL draw.
4966 DrawFrame();
[email protected]50af3c22013-07-13 03:50:204967
4968 // Revert back to software.
[email protected]d9ca99e2013-08-28 21:49:484969 output_surface_->ReleaseGL();
[email protected]b5174d712013-08-28 08:10:434970 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4971 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4972
4973 // Software draw again.
[email protected]50af3c22013-07-13 03:50:204974 DrawFrame();
[email protected]2b154b22013-06-07 09:03:274975}
4976
[email protected]d9ca99e2013-08-28 21:49:484977TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_0) {
4978 // Software draw.
4979 DrawFrame();
4980
4981 // Fail initialization of the onscreen context before the OutputSurface binds
4982 // it to the thread.
4983 onscreen_context_provider_->UnboundTestContext3d()
4984 ->set_times_make_current_succeeds(0);
4985
4986 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4987 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4988 EXPECT_FALSE(did_lose_output_surface_);
4989
4990 // DeferredInitialize fails.
4991 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
4992 onscreen_context_provider_, offscreen_context_provider_));
4993 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
4994 EXPECT_FALSE(host_impl_->offscreen_context_provider());
4995
4996 // Software draw again.
4997 DrawFrame();
4998}
4999
5000TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_1) {
5001 // Software draw.
5002 DrawFrame();
5003
5004 // Fail initialization of the onscreen context after the OutputSurface binds
5005 // it to the thread.
5006 onscreen_context_provider_->UnboundTestContext3d()
5007 ->set_times_make_current_succeeds(2);
5008
5009 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5010 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5011 EXPECT_FALSE(did_lose_output_surface_);
5012
5013 // DeferredInitialize fails.
5014 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
5015 onscreen_context_provider_, offscreen_context_provider_));
5016 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5017 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5018
5019 // We lose the output surface.
5020 EXPECT_TRUE(did_lose_output_surface_);
5021}
5022
5023TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_2) {
5024 // Software draw.
5025 DrawFrame();
5026
5027 // Fail initialization of the onscreen context after the OutputSurface binds
5028 // it to the thread and during renderer initialization.
5029 onscreen_context_provider_->UnboundTestContext3d()
5030 ->set_times_make_current_succeeds(1);
5031
5032 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5033 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5034 EXPECT_FALSE(did_lose_output_surface_);
5035
5036 // DeferredInitialize fails.
5037 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
5038 onscreen_context_provider_, offscreen_context_provider_));
5039 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5040 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5041
5042 // We lose the output surface.
5043 EXPECT_TRUE(did_lose_output_surface_);
5044}
5045
5046TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) {
5047 // Software draw.
5048 DrawFrame();
5049
5050 // Fail initialization of the offscreen context.
5051 offscreen_context_provider_->UnboundTestContext3d()
5052 ->set_times_make_current_succeeds(0);
5053
5054 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5055 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5056 EXPECT_FALSE(did_lose_output_surface_);
5057
5058 // DeferredInitialize fails.
5059 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
5060 onscreen_context_provider_, offscreen_context_provider_));
5061 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
5062 EXPECT_FALSE(host_impl_->offscreen_context_provider());
5063
5064 // We lose the output surface.
5065 EXPECT_TRUE(did_lose_output_surface_);
5066}
5067
[email protected]fd32d122013-06-29 13:11:045068// Checks that we have a non-0 default allocation if we pass a context that
5069// doesn't support memory management extensions.
5070TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
5071 LayerTreeSettings settings;
[email protected]a7f35682013-10-22 23:05:575072 host_impl_ = LayerTreeHostImpl::Create(
5073 settings, this, &proxy_, &stats_instrumentation_, NULL);
[email protected]fd32d122013-06-29 13:11:045074
[email protected]0634cdd42013-08-16 00:46:095075 scoped_ptr<OutputSurface> output_surface(
[email protected]41de22822013-08-29 04:16:175076 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
[email protected]0634cdd42013-08-16 00:46:095077 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]fd32d122013-06-29 13:11:045078 EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes());
5079}
5080
5081TEST_F(LayerTreeHostImplTest, MemoryPolicy) {
5082 ManagedMemoryPolicy policy1(
[email protected]0b8ef2842013-11-01 09:53:355083 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000);
5084 int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
5085 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING);
5086 int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
5087 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
[email protected]fd32d122013-06-29 13:11:045088
5089 host_impl_->SetVisible(true);
[email protected]3f2ff112013-08-03 02:41:075090 host_impl_->SetMemoryPolicy(policy1);
[email protected]fd32d122013-06-29 13:11:045091 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
[email protected]0b8ef2842013-11-01 09:53:355092 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:045093
5094 host_impl_->SetVisible(false);
[email protected]0b8ef2842013-11-01 09:53:355095 EXPECT_EQ(0u, current_limit_bytes_);
5096 EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:045097
5098 host_impl_->SetVisible(true);
5099 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
[email protected]0b8ef2842013-11-01 09:53:355100 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:045101}
5102
[email protected]222c6782013-09-05 22:24:495103class LayerTreeHostImplTestManageTiles : public LayerTreeHostImplTest {
5104 public:
5105 virtual void SetUp() OVERRIDE {
5106 LayerTreeSettings settings;
5107 settings.impl_side_painting = true;
5108
5109 fake_host_impl_ = new FakeLayerTreeHostImpl(settings, &proxy_);
5110 host_impl_.reset(fake_host_impl_);
5111 host_impl_->InitializeRenderer(CreateOutputSurface());
5112 host_impl_->SetViewportSize(gfx::Size(10, 10));
5113 }
5114
5115 FakeLayerTreeHostImpl* fake_host_impl_;
5116};
5117
5118TEST_F(LayerTreeHostImplTestManageTiles, ManageTilesWhenInvisible) {
[email protected]c48536a52013-09-14 00:02:085119 fake_host_impl_->DidModifyTilePriorities();
[email protected]222c6782013-09-05 22:24:495120 EXPECT_TRUE(fake_host_impl_->manage_tiles_needed());
5121 fake_host_impl_->SetVisible(false);
5122 EXPECT_FALSE(fake_host_impl_->manage_tiles_needed());
5123}
5124
[email protected]c9280762013-08-01 06:28:575125TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
5126 scoped_ptr<TestWebGraphicsContext3D> context =
5127 TestWebGraphicsContext3D::Create();
5128 TestWebGraphicsContext3D* context3d = context.get();
[email protected]0634cdd42013-08-16 00:46:095129 scoped_ptr<OutputSurface> output_surface = CreateFakeOutputSurface();
[email protected]c9280762013-08-01 06:28:575130 host_impl_->InitializeRenderer(output_surface.Pass());
5131
5132 EXPECT_EQ(0u, context3d->NumTextures());
5133
[email protected]741fba422013-09-20 03:34:145134 SkBitmap skbitmap;
5135 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
5136 skbitmap.allocPixels();
5137 skbitmap.setImmutable();
5138
[email protected]c9280762013-08-01 06:28:575139 UIResourceId ui_resource_id = 1;
[email protected]741fba422013-09-20 03:34:145140 UIResourceBitmap bitmap(skbitmap);
[email protected]c9280762013-08-01 06:28:575141 host_impl_->CreateUIResource(ui_resource_id, bitmap);
5142 EXPECT_EQ(1u, context3d->NumTextures());
5143 ResourceProvider::ResourceId id1 =
5144 host_impl_->ResourceIdForUIResource(ui_resource_id);
5145 EXPECT_NE(0u, id1);
5146
5147 // Multiple requests with the same id is allowed. The previous texture is
5148 // deleted.
5149 host_impl_->CreateUIResource(ui_resource_id, bitmap);
5150 EXPECT_EQ(1u, context3d->NumTextures());
5151 ResourceProvider::ResourceId id2 =
5152 host_impl_->ResourceIdForUIResource(ui_resource_id);
5153 EXPECT_NE(0u, id2);
5154 EXPECT_NE(id1, id2);
5155
5156 // Deleting invalid UIResourceId is allowed and does not change state.
5157 host_impl_->DeleteUIResource(-1);
5158 EXPECT_EQ(1u, context3d->NumTextures());
5159
5160 // Should return zero for invalid UIResourceId. Number of textures should
5161 // not change.
5162 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
5163 EXPECT_EQ(1u, context3d->NumTextures());
5164
5165 host_impl_->DeleteUIResource(ui_resource_id);
5166 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
5167 EXPECT_EQ(0u, context3d->NumTextures());
5168
5169 // Should not change state for multiple deletion on one UIResourceId
5170 host_impl_->DeleteUIResource(ui_resource_id);
5171 EXPECT_EQ(0u, context3d->NumTextures());
5172}
5173
[email protected]ea468c6c2013-09-10 08:25:115174void ShutdownReleasesContext_Callback(scoped_ptr<CopyOutputResult> result) {
5175}
5176
5177TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
5178 scoped_refptr<TestContextProvider> context_provider =
5179 TestContextProvider::Create();
5180
[email protected]a7f35682013-10-22 23:05:575181 host_impl_ = LayerTreeHostImpl::Create(
5182 LayerTreeSettings(), this, &proxy_, &stats_instrumentation_, NULL);
5183 host_impl_->InitializeRenderer(FakeOutputSurface::Create3d(context_provider)
5184 .PassAs<OutputSurface>());
[email protected]ea468c6c2013-09-10 08:25:115185 host_impl_->SetViewportSize(gfx::Size(10, 10));
5186
5187 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
5188
5189 ScopedPtrVector<CopyOutputRequest> requests;
5190 requests.push_back(CopyOutputRequest::CreateRequest(
5191 base::Bind(&ShutdownReleasesContext_Callback)));
5192
5193 host_impl_->active_tree()->root_layer()->PassCopyRequests(&requests);
5194
5195 LayerTreeHostImpl::FrameData frame;
5196 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]de2cf8c2013-10-25 19:46:465197 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
[email protected]ea468c6c2013-09-10 08:25:115198 host_impl_->DidDrawAllLayers(frame);
5199
5200 // The CopyOutputResult's callback has a ref on the ContextProvider and a
5201 // texture in a texture mailbox.
5202 EXPECT_FALSE(context_provider->HasOneRef());
5203 EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
5204
5205 host_impl_.reset();
5206
5207 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
5208 // released, and the texture deleted.
5209 EXPECT_TRUE(context_provider->HasOneRef());
5210 EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
5211}
5212
[email protected]df0c42342013-10-08 20:52:125213TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) {
5214 // When flinging via touch, only the child should scroll (we should not
5215 // bubble).
5216 gfx::Size surface_size(10, 10);
5217 gfx::Size content_size(20, 20);
5218 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
5219 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
5220
5221 root->AddChild(child.Pass());
5222
5223 host_impl_->SetViewportSize(surface_size);
5224 host_impl_->active_tree()->SetRootLayer(root.Pass());
5225 host_impl_->active_tree()->DidBecomeActive();
5226 InitializeRendererAndDrawFrame();
5227 {
5228 EXPECT_EQ(InputHandler::ScrollStarted,
5229 host_impl_->ScrollBegin(gfx::Point(),
5230 InputHandler::Gesture));
5231
5232 EXPECT_EQ(InputHandler::ScrollStarted,
5233 host_impl_->FlingScrollBegin());
5234
5235 gfx::Vector2d scroll_delta(0, 100);
5236 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5237 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5238
5239 host_impl_->ScrollEnd();
5240
5241 scoped_ptr<ScrollAndScaleSet> scroll_info =
5242 host_impl_->ProcessScrollDeltas();
5243
5244 // Only the child should have scrolled.
5245 ASSERT_EQ(1u, scroll_info->scrolls.size());
5246 ExpectNone(*scroll_info.get(),
5247 host_impl_->active_tree()->root_layer()->id());
5248 }
5249}
5250
[email protected]d41d7cb92013-10-15 16:08:095251TEST_F(LayerTreeHostImplTest, TouchFlingShouldBubbleIfPrecedingScrollBubbled) {
5252 // When flinging via touch, bubble scrolls if the touch scroll
5253 // immediately preceding the fling bubbled.
5254 gfx::Size surface_size(10, 10);
5255 gfx::Size root_content_size(10, 20);
5256 gfx::Size child_content_size(40, 40);
5257 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, root_content_size);
5258 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, child_content_size);
5259
5260 root->AddChild(child.Pass());
5261
5262 host_impl_->SetViewportSize(surface_size);
5263 host_impl_->active_tree()->SetRootLayer(root.Pass());
5264 host_impl_->active_tree()->DidBecomeActive();
5265 InitializeRendererAndDrawFrame();
5266 {
5267 EXPECT_EQ(InputHandler::ScrollStarted,
5268 host_impl_->ScrollBegin(gfx::Point(),
5269 InputHandler::Gesture));
5270
5271 // Touch scroll before starting the fling. The second scroll should bubble.
5272 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 100)));
5273 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 5)));
5274
5275 scoped_ptr<ScrollAndScaleSet> scroll_info =
5276 host_impl_->ProcessScrollDeltas();
5277
5278 // The root should have (partially) scrolled.
5279 EXPECT_EQ(2u, scroll_info->scrolls.size());
5280 ExpectContains(*scroll_info.get(),
5281 host_impl_->active_tree()->root_layer()->id(),
5282 gfx::Vector2d(0, 5));
5283
5284 EXPECT_EQ(InputHandler::ScrollStarted,
5285 host_impl_->FlingScrollBegin());
5286
5287 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 5)));
5288 host_impl_->ScrollEnd();
5289
5290 // The root should have (fully) scrolled from the fling.
5291 scroll_info = host_impl_->ProcessScrollDeltas();
5292 EXPECT_EQ(2u, scroll_info->scrolls.size());
5293 ExpectContains(*scroll_info.get(),
5294 host_impl_->active_tree()->root_layer()->id(),
5295 gfx::Vector2d(0, 10));
5296 }
5297}
5298
[email protected]df0c42342013-10-08 20:52:125299TEST_F(LayerTreeHostImplTest, WheelFlingShouldBubble) {
5300 // When flinging via wheel, the root should eventually scroll (we should
5301 // bubble).
5302 gfx::Size surface_size(10, 10);
5303 gfx::Size content_size(20, 20);
5304 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
5305 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
5306
5307 root->AddChild(child.Pass());
5308
5309 host_impl_->SetViewportSize(surface_size);
5310 host_impl_->active_tree()->SetRootLayer(root.Pass());
5311 host_impl_->active_tree()->DidBecomeActive();
5312 InitializeRendererAndDrawFrame();
5313 {
5314 EXPECT_EQ(InputHandler::ScrollStarted,
5315 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
5316
5317 EXPECT_EQ(InputHandler::ScrollStarted,
5318 host_impl_->FlingScrollBegin());
5319
5320 gfx::Vector2d scroll_delta(0, 100);
5321 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5322 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
5323
5324 host_impl_->ScrollEnd();
5325
5326 scoped_ptr<ScrollAndScaleSet> scroll_info =
5327 host_impl_->ProcessScrollDeltas();
5328
[email protected]d41d7cb92013-10-15 16:08:095329 // The root should have scrolled.
[email protected]df0c42342013-10-08 20:52:125330 ASSERT_EQ(2u, scroll_info->scrolls.size());
5331 ExpectContains(*scroll_info.get(),
5332 host_impl_->active_tree()->root_layer()->id(),
5333 gfx::Vector2d(0, 10));
5334 }
5335}
5336
[email protected]ba565742012-11-10 09:29:485337} // namespace
5338} // namespace cc