blob: 1e73b313a501209e3efaa76edcbe985baaa0dbfd [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]681ccff2013-03-18 06:13:5213#include "cc/base/math_util.h"
[email protected]95fc42142013-08-13 19:31:0514#include "cc/debug/test_web_graphics_context_3d.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"
30#include "cc/output/gl_renderer.h"
[email protected]89e82672013-03-18 07:50:5631#include "cc/quads/render_pass_draw_quad.h"
32#include "cc/quads/solid_color_draw_quad.h"
33#include "cc/quads/texture_draw_quad.h"
34#include "cc/quads/tile_draw_quad.h"
[email protected]e12dd0e2013-03-18 08:24:4035#include "cc/resources/layer_tiling_data.h"
[email protected]101441ce2012-10-16 01:45:0336#include "cc/test/animation_test_common.h"
[email protected]a46f32932012-12-07 21:43:1637#include "cc/test/fake_output_surface.h"
[email protected]0634cdd42013-08-16 00:46:0938#include "cc/test/fake_output_surface_client.h"
[email protected]61de5812012-11-08 07:03:4439#include "cc/test/fake_proxy.h"
[email protected]372bad5f2013-03-21 16:38:4340#include "cc/test/fake_rendering_stats_instrumentation.h"
[email protected]d993b602013-01-04 02:08:1241#include "cc/test/fake_video_frame_provider.h"
[email protected]101441ce2012-10-16 01:45:0342#include "cc/test/geometry_test_utils.h"
43#include "cc/test/layer_test_common.h"
44#include "cc/test/render_pass_test_common.h"
[email protected]556fd292013-03-18 08:03:0445#include "cc/trees/layer_tree_impl.h"
46#include "cc/trees/single_thread_proxy.h"
[email protected]59cb7b352012-10-30 06:45:4847#include "media/base/media.h"
[email protected]7f0c53db2012-10-02 00:23:1848#include "testing/gmock/include/gmock/gmock.h"
49#include "testing/gtest/include/gtest/gtest.h"
[email protected]aad0a0072012-11-01 18:15:5850#include "ui/gfx/size_conversions.h"
[email protected]c9c1ebe2012-11-05 20:46:1351#include "ui/gfx/vector2d_conversions.h"
[email protected]94f206c12012-08-25 00:09:1452
[email protected]94f206c12012-08-25 00:09:1453using ::testing::Mock;
54using ::testing::Return;
55using ::testing::AnyNumber;
56using ::testing::AtLeast;
57using ::testing::_;
[email protected]568285b2013-01-07 23:19:1958using media::VideoFrame;
[email protected]94f206c12012-08-25 00:09:1459
[email protected]ba565742012-11-10 09:29:4860namespace cc {
[email protected]94f206c12012-08-25 00:09:1461namespace {
62
[email protected]c2d0c5a2013-02-26 04:43:3663class LayerTreeHostImplTest : public testing::Test,
[email protected]9bdcfd642012-11-14 21:24:2664 public LayerTreeHostImplClient {
[email protected]aa043632013-03-25 03:39:4265 public:
66 LayerTreeHostImplTest()
[email protected]810d40b72013-06-20 18:26:1567 : proxy_(),
[email protected]aa043632013-03-25 03:39:4268 always_impl_thread_(&proxy_),
69 always_main_thread_blocked_(&proxy_),
70 on_can_draw_state_changed_called_(false),
[email protected]4f48f6e2013-08-27 06:33:3871 did_notify_ready_to_activate_(false),
[email protected]aa043632013-03-25 03:39:4272 did_request_commit_(false),
73 did_request_redraw_(false),
74 did_upload_visible_tile_(false),
[email protected]d9ca99e2013-08-28 21:49:4875 did_lose_output_surface_(false),
[email protected]fd32d122013-06-29 13:11:0476 reduce_memory_result_(true),
77 current_limit_bytes_(0),
78 current_priority_cutoff_value_(0) {
[email protected]aa043632013-03-25 03:39:4279 media::InitializeMediaLibraryForTesting();
80 }
[email protected]1c0c9bc2012-10-08 22:41:4881
[email protected]aa043632013-03-25 03:39:4282 virtual void SetUp() OVERRIDE {
[email protected]96baf3e2012-10-22 23:09:5583 LayerTreeSettings settings;
[email protected]aa043632013-03-25 03:39:4284 settings.minimum_occlusion_tracking_size = gfx::Size();
[email protected]50644642013-06-20 13:58:5585 settings.impl_side_painting = true;
86 settings.solid_color_scrollbars = true;
[email protected]94f206c12012-08-25 00:09:1487
[email protected]aa043632013-03-25 03:39:4288 host_impl_ = LayerTreeHostImpl::Create(settings,
89 this,
90 &proxy_,
91 &stats_instrumentation_);
92 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]18ce59702013-04-09 04:58:4093 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:4294 }
[email protected]94f206c12012-08-25 00:09:1495
[email protected]aa043632013-03-25 03:39:4296 virtual void TearDown() OVERRIDE {}
[email protected]94f206c12012-08-25 00:09:1497
[email protected]d9ca99e2013-08-28 21:49:4898 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {
99 did_lose_output_surface_ = true;
100 }
[email protected]aa043632013-03-25 03:39:42101 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
[email protected]df3c24c92013-06-19 03:54:35102 virtual void BeginFrameOnImplThread(const BeginFrameArgs& args)
[email protected]c8cbae72013-05-23 10:45:03103 OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42104 virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {
105 on_can_draw_state_changed_called_ = true;
106 }
[email protected]4f48f6e2013-08-27 06:33:38107 virtual void NotifyReadyToActivate() OVERRIDE {
108 did_notify_ready_to_activate_ = true;
109 host_impl_->ActivatePendingTree();
[email protected]aa043632013-03-25 03:39:42110 }
111 virtual void SetNeedsRedrawOnImplThread() OVERRIDE {
112 did_request_redraw_ = true;
113 }
[email protected]1cd9f5552013-04-26 04:22:03114 virtual void SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) OVERRIDE {
115 did_request_redraw_ = true;
116 }
[email protected]aa043632013-03-25 03:39:42117 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE {
118 did_upload_visible_tile_ = true;
119 }
120 virtual void SetNeedsCommitOnImplThread() OVERRIDE {
121 did_request_commit_ = true;
122 }
[email protected]aa043632013-03-25 03:39:42123 virtual void PostAnimationEventsToMainThreadOnImplThread(
124 scoped_ptr<AnimationEventsVector> events,
125 base::Time wall_clock_time) OVERRIDE {}
126 virtual bool ReduceContentsTextureMemoryOnImplThread(
127 size_t limit_bytes, int priority_cutoff) OVERRIDE {
[email protected]fd32d122013-06-29 13:11:04128 current_limit_bytes_ = limit_bytes;
129 current_priority_cutoff_value_ = priority_cutoff;
[email protected]aa043632013-03-25 03:39:42130 return reduce_memory_result_;
131 }
132 virtual void ReduceWastedContentsTextureMemoryOnImplThread() OVERRIDE {}
133 virtual void SendManagedMemoryStats() OVERRIDE {}
134 virtual bool IsInsideDraw() OVERRIDE { return false; }
135 virtual void RenewTreePriority() OVERRIDE {}
136 virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay)
[email protected]21c9dee72013-06-15 01:20:05137 OVERRIDE { requested_scrollbar_animation_delay_ = delay; }
[email protected]2a61ad52013-05-13 14:01:29138 virtual void DidActivatePendingTree() OVERRIDE {}
[email protected]aa043632013-03-25 03:39:42139
140 void set_reduce_memory_result(bool reduce_memory_result) {
141 reduce_memory_result_ = reduce_memory_result;
142 }
143
144 void CreateLayerTreeHost(bool partial_swap,
145 scoped_ptr<OutputSurface> output_surface) {
146 LayerTreeSettings settings;
147 settings.minimum_occlusion_tracking_size = gfx::Size();
148 settings.partial_swap_enabled = partial_swap;
149
150 host_impl_ = LayerTreeHostImpl::Create(settings,
151 this,
152 &proxy_,
153 &stats_instrumentation_);
154
155 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:40156 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:42157 }
158
159 void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) {
160 root->SetAnchorPoint(gfx::PointF());
161 root->SetPosition(gfx::PointF());
162 root->SetBounds(gfx::Size(10, 10));
163 root->SetContentBounds(gfx::Size(10, 10));
164 root->SetDrawsContent(true);
165 root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
166 host_impl_->active_tree()->SetRootLayer(root.Pass());
167 }
168
169 static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) {
[email protected]1960a712013-04-30 17:06:47170 ASSERT_EQ(layer->ScrollDelta(), gfx::Vector2d());
[email protected]aa043632013-03-25 03:39:42171 for (size_t i = 0; i < layer->children().size(); ++i)
172 ExpectClearedScrollDeltasRecursive(layer->children()[i]);
173 }
174
175 static void ExpectContains(const ScrollAndScaleSet& scroll_info,
176 int id,
177 gfx::Vector2d scroll_delta) {
178 int times_encountered = 0;
179
180 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
181 if (scroll_info.scrolls[i].layer_id != id)
182 continue;
183 EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta);
184 times_encountered++;
185 }
186
187 ASSERT_EQ(times_encountered, 1);
188 }
189
190 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
191 int times_encountered = 0;
192
193 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
194 if (scroll_info.scrolls[i].layer_id != id)
195 continue;
196 times_encountered++;
197 }
198
199 ASSERT_EQ(0, times_encountered);
200 }
201
[email protected]35a99a12013-05-09 23:52:29202 LayerImpl* SetupScrollAndContentsLayers(gfx::Size content_size) {
[email protected]aa043632013-03-25 03:39:42203 scoped_ptr<LayerImpl> root =
204 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]aa043632013-03-25 03:39:42205 root->SetBounds(content_size);
206 root->SetContentBounds(content_size);
207 root->SetPosition(gfx::PointF());
208 root->SetAnchorPoint(gfx::PointF());
209
[email protected]35a99a12013-05-09 23:52:29210 scoped_ptr<LayerImpl> scroll =
[email protected]aa043632013-03-25 03:39:42211 LayerImpl::Create(host_impl_->active_tree(), 2);
[email protected]35a99a12013-05-09 23:52:29212 LayerImpl* scroll_layer = scroll.get();
213 scroll->SetScrollable(true);
214 scroll->SetScrollOffset(gfx::Vector2d());
215 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
[email protected]a2b5ded2013-05-20 21:32:53216 content_size.height()));
[email protected]35a99a12013-05-09 23:52:29217 scroll->SetBounds(content_size);
218 scroll->SetContentBounds(content_size);
219 scroll->SetPosition(gfx::PointF());
220 scroll->SetAnchorPoint(gfx::PointF());
221
222 scoped_ptr<LayerImpl> contents =
223 LayerImpl::Create(host_impl_->active_tree(), 3);
[email protected]aa043632013-03-25 03:39:42224 contents->SetDrawsContent(true);
225 contents->SetBounds(content_size);
226 contents->SetContentBounds(content_size);
227 contents->SetPosition(gfx::PointF());
228 contents->SetAnchorPoint(gfx::PointF());
[email protected]35a99a12013-05-09 23:52:29229
230 scroll->AddChild(contents.Pass());
231 root->AddChild(scroll.Pass());
232
[email protected]aa043632013-03-25 03:39:42233 host_impl_->active_tree()->SetRootLayer(root.Pass());
234 host_impl_->active_tree()->DidBecomeActive();
[email protected]35a99a12013-05-09 23:52:29235 return scroll_layer;
[email protected]aa043632013-03-25 03:39:42236 }
237
238 scoped_ptr<LayerImpl> CreateScrollableLayer(int id, gfx::Size size) {
239 scoped_ptr<LayerImpl> layer =
240 LayerImpl::Create(host_impl_->active_tree(), id);
241 layer->SetScrollable(true);
242 layer->SetDrawsContent(true);
243 layer->SetBounds(size);
244 layer->SetContentBounds(size);
245 layer->SetMaxScrollOffset(gfx::Vector2d(size.width() * 2,
246 size.height() * 2));
247 return layer.Pass();
248 }
249
250 void InitializeRendererAndDrawFrame() {
251 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]fbe89f72013-05-21 07:24:24252 DrawFrame();
253 }
254
255 void DrawFrame() {
[email protected]aa043632013-03-25 03:39:42256 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:20257 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:42258 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
259 host_impl_->DidDrawAllLayers(frame);
260 }
261
262 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor);
263 void pinch_zoom_pan_viewport_test(float device_scale_factor);
264 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor);
265 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
266 float device_scale_factor);
267
[email protected]6133cc232013-07-30 18:47:07268 void CheckNotifyCalledIfCanDrawChanged(bool always_draw) {
269 // Note: It is not possible to disable the renderer once it has been set,
270 // so we do not need to test that disabling the renderer notifies us
271 // that can_draw changed.
272 EXPECT_FALSE(host_impl_->CanDraw());
273 on_can_draw_state_changed_called_ = false;
274
275 // Set up the root layer, which allows us to draw.
276 SetupScrollAndContentsLayers(gfx::Size(100, 100));
277 EXPECT_TRUE(host_impl_->CanDraw());
278 EXPECT_TRUE(on_can_draw_state_changed_called_);
279 on_can_draw_state_changed_called_ = false;
280
281 // Toggle the root layer to make sure it toggles can_draw
282 host_impl_->active_tree()->SetRootLayer(scoped_ptr<LayerImpl>());
283 EXPECT_FALSE(host_impl_->CanDraw());
284 EXPECT_TRUE(on_can_draw_state_changed_called_);
285 on_can_draw_state_changed_called_ = false;
286
287 SetupScrollAndContentsLayers(gfx::Size(100, 100));
288 EXPECT_TRUE(host_impl_->CanDraw());
289 EXPECT_TRUE(on_can_draw_state_changed_called_);
290 on_can_draw_state_changed_called_ = false;
291
292 // Toggle the device viewport size to make sure it toggles can_draw.
293 host_impl_->SetViewportSize(gfx::Size());
294 if (always_draw) {
295 EXPECT_TRUE(host_impl_->CanDraw());
296 } else {
297 EXPECT_FALSE(host_impl_->CanDraw());
298 }
299 EXPECT_TRUE(on_can_draw_state_changed_called_);
300 on_can_draw_state_changed_called_ = false;
301
302 host_impl_->SetViewportSize(gfx::Size(100, 100));
303 EXPECT_TRUE(host_impl_->CanDraw());
304 EXPECT_TRUE(on_can_draw_state_changed_called_);
305 on_can_draw_state_changed_called_ = false;
306
307 // Toggle contents textures purged without causing any evictions,
308 // and make sure that it does not change can_draw.
309 set_reduce_memory_result(false);
310 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:07311 host_impl_->memory_allocation_limit_bytes() - 1));
312 host_impl_->SetDiscardBackBufferWhenNotVisible(true);
[email protected]6133cc232013-07-30 18:47:07313 EXPECT_TRUE(host_impl_->CanDraw());
314 EXPECT_FALSE(on_can_draw_state_changed_called_);
315 on_can_draw_state_changed_called_ = false;
316
317 // Toggle contents textures purged to make sure it toggles can_draw.
318 set_reduce_memory_result(true);
319 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:07320 host_impl_->memory_allocation_limit_bytes() - 1));
321 host_impl_->SetDiscardBackBufferWhenNotVisible(true);
[email protected]6133cc232013-07-30 18:47:07322 if (always_draw) {
323 EXPECT_TRUE(host_impl_->CanDraw());
324 } else {
325 EXPECT_FALSE(host_impl_->CanDraw());
326 }
327 EXPECT_TRUE(on_can_draw_state_changed_called_);
328 on_can_draw_state_changed_called_ = false;
329
330 host_impl_->active_tree()->ResetContentsTexturesPurged();
331 EXPECT_TRUE(host_impl_->CanDraw());
332 EXPECT_TRUE(on_can_draw_state_changed_called_);
333 on_can_draw_state_changed_called_ = false;
334 }
335
[email protected]aa043632013-03-25 03:39:42336 protected:
337 virtual scoped_ptr<OutputSurface> CreateOutputSurface() {
338 return CreateFakeOutputSurface();
339 }
340
341 void DrawOneFrame() {
342 LayerTreeHostImpl::FrameData frame_data;
[email protected]e0341352013-04-06 05:01:20343 host_impl_->PrepareToDraw(&frame_data, gfx::Rect());
[email protected]aa043632013-03-25 03:39:42344 host_impl_->DidDrawAllLayers(frame_data);
345 }
346
347 FakeProxy proxy_;
348 DebugScopedSetImplThread always_impl_thread_;
349 DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
350
351 scoped_ptr<LayerTreeHostImpl> host_impl_;
352 FakeRenderingStatsInstrumentation stats_instrumentation_;
353 bool on_can_draw_state_changed_called_;
[email protected]4f48f6e2013-08-27 06:33:38354 bool did_notify_ready_to_activate_;
[email protected]aa043632013-03-25 03:39:42355 bool did_request_commit_;
356 bool did_request_redraw_;
357 bool did_upload_visible_tile_;
[email protected]d9ca99e2013-08-28 21:49:48358 bool did_lose_output_surface_;
[email protected]aa043632013-03-25 03:39:42359 bool reduce_memory_result_;
[email protected]21c9dee72013-06-15 01:20:05360 base::TimeDelta requested_scrollbar_animation_delay_;
[email protected]fd32d122013-06-29 13:11:04361 size_t current_limit_bytes_;
362 int current_priority_cutoff_value_;
[email protected]aa043632013-03-25 03:39:42363};
364
[email protected]6133cc232013-07-30 18:47:07365TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
366 bool always_draw = false;
367 CheckNotifyCalledIfCanDrawChanged(always_draw);
368}
369
370TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) {
371 LayerTreeSettings settings;
372 settings.impl_side_painting = true;
373 host_impl_ = LayerTreeHostImpl::Create(
374 settings, this, &proxy_, &stats_instrumentation_);
[email protected]0634cdd42013-08-16 00:46:09375
376 scoped_ptr<FakeOutputSurface> output_surface(
377 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
378
[email protected]6133cc232013-07-30 18:47:07379 host_impl_->InitializeRenderer(
[email protected]0634cdd42013-08-16 00:46:09380 output_surface.PassAs<OutputSurface>());
[email protected]6133cc232013-07-30 18:47:07381 host_impl_->SetViewportSize(gfx::Size(10, 10));
382
383 bool always_draw = true;
384 CheckNotifyCalledIfCanDrawChanged(always_draw);
385}
386
[email protected]aa043632013-03-25 03:39:42387TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) {
388 ASSERT_FALSE(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:14389
[email protected]aa043632013-03-25 03:39:42390 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
391 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
[email protected]94f206c12012-08-25 00:09:14392}
393
[email protected]aa043632013-03-25 03:39:42394TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
395 {
396 scoped_ptr<LayerImpl> root =
397 LayerImpl::Create(host_impl_->active_tree(), 1);
398 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2));
399 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3));
400 root->children()[1]->AddChild(
401 LayerImpl::Create(host_impl_->active_tree(), 4));
402 root->children()[1]->AddChild(
403 LayerImpl::Create(host_impl_->active_tree(), 5));
404 root->children()[1]->children()[0]->AddChild(
405 LayerImpl::Create(host_impl_->active_tree(), 6));
406 host_impl_->active_tree()->SetRootLayer(root.Pass());
407 }
408 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:14409
[email protected]aa043632013-03-25 03:39:42410 ExpectClearedScrollDeltasRecursive(root);
[email protected]0ede3bb2012-12-09 09:14:39411
[email protected]aa043632013-03-25 03:39:42412 scoped_ptr<ScrollAndScaleSet> scroll_info;
413
414 scroll_info = host_impl_->ProcessScrollDeltas();
415 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
416 ExpectClearedScrollDeltasRecursive(root);
417
418 scroll_info = host_impl_->ProcessScrollDeltas();
419 ASSERT_EQ(scroll_info->scrolls.size(), 0u);
420 ExpectClearedScrollDeltasRecursive(root);
[email protected]94f206c12012-08-25 00:09:14421}
422
[email protected]aa043632013-03-25 03:39:42423TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
424 gfx::Vector2d scroll_offset(20, 30);
425 gfx::Vector2d scroll_delta(11, -15);
426 {
427 scoped_ptr<LayerImpl> root =
428 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]d30700f12013-07-31 08:21:01429 root->SetMaxScrollOffset(gfx::Vector2d(100, 100));
[email protected]aa043632013-03-25 03:39:42430 root->SetScrollOffset(scroll_offset);
431 root->SetScrollable(true);
[email protected]aa043632013-03-25 03:39:42432 root->ScrollBy(scroll_delta);
433 host_impl_->active_tree()->SetRootLayer(root.Pass());
434 }
435 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:14436
[email protected]aa043632013-03-25 03:39:42437 scoped_ptr<ScrollAndScaleSet> scroll_info;
[email protected]94f206c12012-08-25 00:09:14438
[email protected]aa043632013-03-25 03:39:42439 scroll_info = host_impl_->ProcessScrollDeltas();
440 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
441 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta);
442 ExpectContains(*scroll_info, root->id(), scroll_delta);
[email protected]94f206c12012-08-25 00:09:14443
[email protected]aa043632013-03-25 03:39:42444 gfx::Vector2d scroll_delta2(-5, 27);
445 root->ScrollBy(scroll_delta2);
446 scroll_info = host_impl_->ProcessScrollDeltas();
447 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
448 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
449 ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2);
450
451 root->ScrollBy(gfx::Vector2d());
452 scroll_info = host_impl_->ProcessScrollDeltas();
453 EXPECT_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
[email protected]94f206c12012-08-25 00:09:14454}
455
[email protected]aa043632013-03-25 03:39:42456TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
457 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40458 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42459 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:14460
[email protected]5ff3c9782013-04-29 17:35:12461 EXPECT_EQ(InputHandler::ScrollStarted,
462 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42463 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
464 host_impl_->ScrollEnd();
465 EXPECT_TRUE(did_request_redraw_);
466 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:14467}
468
[email protected]aa043632013-03-25 03:39:42469TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
470 // We should not crash when trying to scroll an empty layer tree.
[email protected]5ff3c9782013-04-29 17:35:12471 EXPECT_EQ(InputHandler::ScrollIgnored,
472 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:14473}
474
[email protected]aa043632013-03-25 03:39:42475TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
476 LayerTreeSettings settings;
477 host_impl_ = LayerTreeHostImpl::Create(settings,
478 this,
479 &proxy_,
480 &stats_instrumentation_);
[email protected]0634cdd42013-08-16 00:46:09481 scoped_ptr<TestWebGraphicsContext3D> context_owned =
482 TestWebGraphicsContext3D::Create();
483 context_owned->set_times_make_current_succeeds(0);
484
485 scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d(
486 context_owned.Pass()));
[email protected]94f206c12012-08-25 00:09:14487
[email protected]aa043632013-03-25 03:39:42488 // Initialization will fail here.
[email protected]0634cdd42013-08-16 00:46:09489 host_impl_->InitializeRenderer(output_surface.PassAs<OutputSurface>());
[email protected]18ce59702013-04-09 04:58:40490 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]a90aa702012-11-07 04:48:24491
[email protected]aa043632013-03-25 03:39:42492 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:14493
[email protected]aa043632013-03-25 03:39:42494 // We should not crash when trying to scroll after the renderer initialization
495 // fails.
[email protected]5ff3c9782013-04-29 17:35:12496 EXPECT_EQ(InputHandler::ScrollIgnored,
497 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:14498}
499
[email protected]aa043632013-03-25 03:39:42500TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
[email protected]35a99a12013-05-09 23:52:29501 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40502 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42503 InitializeRendererAndDrawFrame();
[email protected]a9710962012-11-14 20:11:02504
[email protected]aa043632013-03-25 03:39:42505 // We should not crash if the tree is replaced while we are scrolling.
[email protected]5ff3c9782013-04-29 17:35:12506 EXPECT_EQ(InputHandler::ScrollStarted,
507 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42508 host_impl_->active_tree()->DetachLayerTree();
509
[email protected]35a99a12013-05-09 23:52:29510 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42511
512 // We should still be scrolling, because the scrolled layer also exists in the
513 // new tree.
514 gfx::Vector2d scroll_delta(0, 10);
515 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
516 host_impl_->ScrollEnd();
517 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]35a99a12013-05-09 23:52:29518 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta);
[email protected]aa043632013-03-25 03:39:42519}
520
521TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndScroll) {
522 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40523 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42524 InitializeRendererAndDrawFrame();
525
526 // We should be able to scroll even if the root layer loses its render surface
527 // after the most recent render.
528 host_impl_->active_tree()->root_layer()->ClearRenderSurface();
529 host_impl_->active_tree()->set_needs_update_draw_properties();
530
[email protected]5ff3c9782013-04-29 17:35:12531 EXPECT_EQ(InputHandler::ScrollStarted,
532 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42533}
534
535TEST_F(LayerTreeHostImplTest, WheelEventHandlers) {
536 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40537 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42538 InitializeRendererAndDrawFrame();
539 LayerImpl* root = host_impl_->active_tree()->root_layer();
540
541 root->SetHaveWheelEventHandlers(true);
542
543 // With registered event handlers, wheel scrolls have to go to the main
544 // thread.
[email protected]5ff3c9782013-04-29 17:35:12545 EXPECT_EQ(InputHandler::ScrollOnMainThread,
546 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42547
548 // But gesture scrolls can still be handled.
[email protected]5ff3c9782013-04-29 17:35:12549 EXPECT_EQ(InputHandler::ScrollStarted,
550 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42551}
552
[email protected]7c45d8152013-04-23 18:27:21553TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) {
554 SetupScrollAndContentsLayers(gfx::Size(100, 100));
555 host_impl_->SetViewportSize(gfx::Size(50, 50));
556 InitializeRendererAndDrawFrame();
557
558 // Ignore the fling since no layer is being scrolled
[email protected]5ff3c9782013-04-29 17:35:12559 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21560 host_impl_->FlingScrollBegin());
561
562 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12563 EXPECT_EQ(InputHandler::ScrollStarted,
564 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]7c45d8152013-04-23 18:27:21565
566 // Now the fling should go ahead since we've started scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12567 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]7c45d8152013-04-23 18:27:21568 host_impl_->FlingScrollBegin());
569}
570
571TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) {
572 SetupScrollAndContentsLayers(gfx::Size(100, 100));
573 host_impl_->SetViewportSize(gfx::Size(50, 50));
574 InitializeRendererAndDrawFrame();
575
576 // Ignore the fling since no layer is being scrolled
[email protected]5ff3c9782013-04-29 17:35:12577 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21578 host_impl_->FlingScrollBegin());
579
580 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12581 EXPECT_EQ(InputHandler::ScrollStarted,
582 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]7c45d8152013-04-23 18:27:21583
584 // Now the fling should go ahead since we've started scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12585 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]7c45d8152013-04-23 18:27:21586 host_impl_->FlingScrollBegin());
587}
588
589TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) {
590 SetupScrollAndContentsLayers(gfx::Size(100, 100));
591 host_impl_->SetViewportSize(gfx::Size(50, 50));
592 InitializeRendererAndDrawFrame();
593 LayerImpl* root = host_impl_->active_tree()->root_layer();
594
595 root->SetShouldScrollOnMainThread(true);
596
597 // Start scrolling a layer
[email protected]5ff3c9782013-04-29 17:35:12598 EXPECT_EQ(InputHandler::ScrollOnMainThread,
599 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]7c45d8152013-04-23 18:27:21600
601 // The fling should be ignored since there's no layer being scrolled impl-side
[email protected]5ff3c9782013-04-29 17:35:12602 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]7c45d8152013-04-23 18:27:21603 host_impl_->FlingScrollBegin());
604}
605
[email protected]aa043632013-03-25 03:39:42606TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
607 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40608 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42609 InitializeRendererAndDrawFrame();
610 LayerImpl* root = host_impl_->active_tree()->root_layer();
611
612 root->SetShouldScrollOnMainThread(true);
613
[email protected]5ff3c9782013-04-29 17:35:12614 EXPECT_EQ(InputHandler::ScrollOnMainThread,
615 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
616 EXPECT_EQ(InputHandler::ScrollOnMainThread,
617 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42618}
619
620TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
621 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40622 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42623
624 LayerImpl* root = host_impl_->active_tree()->root_layer();
625 root->SetContentsScale(2.f, 2.f);
626 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
627
628 InitializeRendererAndDrawFrame();
629
630 // All scroll types inside the non-fast scrollable region should fail.
[email protected]5ff3c9782013-04-29 17:35:12631 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42632 host_impl_->ScrollBegin(gfx::Point(25, 25),
[email protected]5ff3c9782013-04-29 17:35:12633 InputHandler::Wheel));
634 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42635 host_impl_->ScrollBegin(gfx::Point(25, 25),
[email protected]5ff3c9782013-04-29 17:35:12636 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42637
638 // All scroll types outside this region should succeed.
[email protected]5ff3c9782013-04-29 17:35:12639 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42640 host_impl_->ScrollBegin(gfx::Point(75, 75),
[email protected]5ff3c9782013-04-29 17:35:12641 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42642 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
643 host_impl_->ScrollEnd();
[email protected]5ff3c9782013-04-29 17:35:12644 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42645 host_impl_->ScrollBegin(gfx::Point(75, 75),
[email protected]5ff3c9782013-04-29 17:35:12646 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42647 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
648 host_impl_->ScrollEnd();
649}
650
651TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
652 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40653 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42654
655 LayerImpl* root = host_impl_->active_tree()->root_layer();
656 root->SetContentsScale(2.f, 2.f);
657 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
658 root->SetPosition(gfx::PointF(-25.f, 0.f));
659
660 InitializeRendererAndDrawFrame();
661
662 // This point would fall into the non-fast scrollable region except that we've
663 // moved the layer down by 25 pixels.
[email protected]5ff3c9782013-04-29 17:35:12664 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42665 host_impl_->ScrollBegin(gfx::Point(40, 10),
[email protected]5ff3c9782013-04-29 17:35:12666 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42667 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
668 host_impl_->ScrollEnd();
669
670 // This point is still inside the non-fast region.
[email protected]5ff3c9782013-04-29 17:35:12671 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:42672 host_impl_->ScrollBegin(gfx::Point(10, 10),
[email protected]5ff3c9782013-04-29 17:35:12673 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42674}
675
676TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
677 SetupScrollAndContentsLayers(gfx::Size(200, 200));
[email protected]18ce59702013-04-09 04:58:40678 host_impl_->SetViewportSize(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:42679
680 InitializeRendererAndDrawFrame();
681
[email protected]5ff3c9782013-04-29 17:35:12682 EXPECT_EQ(InputHandler::ScrollStarted,
683 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:42684
685 // Trying to scroll to the left/top will not succeed.
686 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
687 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
688 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
689
690 // Scrolling to the right/bottom will succeed.
691 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
692 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
693 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
694
695 // Scrolling to left/top will now succeed.
696 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
697 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
698 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
699
700 // Scrolling diagonally against an edge will succeed.
701 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
702 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
703 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
704
705 // Trying to scroll more than the available space will also succeed.
706 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
707}
708
709TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) {
710 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
[email protected]18ce59702013-04-09 04:58:40711 host_impl_->SetViewportSize(gfx::Size(100, 1000));
[email protected]aa043632013-03-25 03:39:42712
713 InitializeRendererAndDrawFrame();
714
[email protected]5ff3c9782013-04-29 17:35:12715 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42716 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:12717 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42718
719 // Trying to scroll without a vertical scrollbar will fail.
720 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49721 gfx::Point(), SCROLL_FORWARD));
[email protected]aa043632013-03-25 03:39:42722 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49723 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:42724
[email protected]3a83478b2013-08-22 20:55:17725 scoped_ptr<cc::PaintedScrollbarLayerImpl> vertical_scrollbar(
726 cc::PaintedScrollbarLayerImpl::Create(
[email protected]aa043632013-03-25 03:39:42727 host_impl_->active_tree(),
728 20,
[email protected]c28df4c12013-05-22 17:36:49729 VERTICAL));
[email protected]aa043632013-03-25 03:39:42730 vertical_scrollbar->SetBounds(gfx::Size(15, 1000));
731 host_impl_->RootScrollLayer()->SetVerticalScrollbarLayer(
732 vertical_scrollbar.get());
733
734 // Trying to scroll with a vertical scrollbar will succeed.
735 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49736 gfx::Point(), SCROLL_FORWARD));
[email protected]1960a712013-04-30 17:06:47737 EXPECT_FLOAT_EQ(875.f, host_impl_->RootScrollLayer()->ScrollDelta().y());
[email protected]aa043632013-03-25 03:39:42738 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
[email protected]c28df4c12013-05-22 17:36:49739 gfx::Point(), SCROLL_BACKWARD));
[email protected]aa043632013-03-25 03:39:42740}
741
742TEST_F(LayerTreeHostImplTest,
743 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) {
744 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40745 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42746 InitializeRendererAndDrawFrame();
747
748 // We should be able to hit test for touch event handlers even if the root
749 // layer loses its render surface after the most recent render.
750 host_impl_->active_tree()->root_layer()->ClearRenderSurface();
751 host_impl_->active_tree()->set_needs_update_draw_properties();
752
753 EXPECT_EQ(host_impl_->HaveTouchEventHandlersAt(gfx::Point()), false);
754}
755
756TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
[email protected]35a99a12013-05-09 23:52:29757 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40758 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42759 InitializeRendererAndDrawFrame();
760
[email protected]35a99a12013-05-09 23:52:29761 EXPECT_EQ(scroll_layer, host_impl_->RootScrollLayer());
[email protected]aa043632013-03-25 03:39:42762
763 float min_page_scale = 1.f, max_page_scale = 4.f;
[email protected]aa043632013-03-25 03:39:42764
765 // The impl-based pinch zoom should adjust the max scroll position.
766 {
767 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
768 min_page_scale,
769 max_page_scale);
770 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]aa043632013-03-25 03:39:42771 scroll_layer->SetScrollDelta(gfx::Vector2d());
772
773 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57774 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42775 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
776 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57777 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42778 EXPECT_TRUE(did_request_redraw_);
779 EXPECT_TRUE(did_request_commit_);
780
781 scoped_ptr<ScrollAndScaleSet> scroll_info =
782 host_impl_->ProcessScrollDeltas();
783 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
784
[email protected]35a99a12013-05-09 23:52:29785 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(),
786 scroll_layer->max_scroll_offset().ToString());
[email protected]aa043632013-03-25 03:39:42787 }
788
789 // Scrolling after a pinch gesture should always be in local space. The
790 // scroll deltas do not have the page scale factor applied.
791 {
792 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
793 min_page_scale,
794 max_page_scale);
795 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]aa043632013-03-25 03:39:42796 scroll_layer->SetScrollDelta(gfx::Vector2d());
797
798 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57799 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42800 host_impl_->PinchGestureBegin();
801 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
802 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57803 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42804
805 gfx::Vector2d scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:12806 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:42807 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:12808 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:42809 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
810 host_impl_->ScrollEnd();
[email protected]a9710962012-11-14 20:11:02811
[email protected]aa043632013-03-25 03:39:42812 scoped_ptr<ScrollAndScaleSet> scroll_info =
813 host_impl_->ProcessScrollDeltas();
814 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:29815 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:42816 scroll_delta);
817 }
[email protected]a9710962012-11-14 20:11:02818}
819
[email protected]aa043632013-03-25 03:39:42820TEST_F(LayerTreeHostImplTest, PinchGesture) {
821 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40822 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42823 InitializeRendererAndDrawFrame();
[email protected]be782f52013-03-23 21:36:14824
[email protected]aa043632013-03-25 03:39:42825 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
826 DCHECK(scroll_layer);
[email protected]be782f52013-03-23 21:36:14827
[email protected]aa043632013-03-25 03:39:42828 float min_page_scale = 1.f;
829 float max_page_scale = 4.f;
[email protected]be782f52013-03-23 21:36:14830
[email protected]aa043632013-03-25 03:39:42831 // Basic pinch zoom in gesture
832 {
833 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
834 min_page_scale,
835 max_page_scale);
[email protected]aa043632013-03-25 03:39:42836 scroll_layer->SetScrollDelta(gfx::Vector2d());
[email protected]be782f52013-03-23 21:36:14837
[email protected]aa043632013-03-25 03:39:42838 float page_scale_delta = 2.f;
[email protected]9ec24df2013-08-09 23:32:57839 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42840 host_impl_->PinchGestureBegin();
841 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
842 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57843 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42844 EXPECT_TRUE(did_request_redraw_);
845 EXPECT_TRUE(did_request_commit_);
[email protected]be782f52013-03-23 21:36:14846
[email protected]aa043632013-03-25 03:39:42847 scoped_ptr<ScrollAndScaleSet> scroll_info =
848 host_impl_->ProcessScrollDeltas();
849 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
850 }
851
852 // Zoom-in clamping
853 {
854 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
855 min_page_scale,
856 max_page_scale);
[email protected]aa043632013-03-25 03:39:42857 scroll_layer->SetScrollDelta(gfx::Vector2d());
858 float page_scale_delta = 10.f;
859
[email protected]9ec24df2013-08-09 23:32:57860 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42861 host_impl_->PinchGestureBegin();
862 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
863 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57864 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42865
866 scoped_ptr<ScrollAndScaleSet> scroll_info =
867 host_impl_->ProcessScrollDeltas();
868 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale);
869 }
870
871 // Zoom-out clamping
872 {
873 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
874 min_page_scale,
875 max_page_scale);
[email protected]aa043632013-03-25 03:39:42876 scroll_layer->SetScrollDelta(gfx::Vector2d());
877 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
878
879 float page_scale_delta = 0.1f;
[email protected]9ec24df2013-08-09 23:32:57880 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42881 host_impl_->PinchGestureBegin();
882 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
883 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57884 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42885
886 scoped_ptr<ScrollAndScaleSet> scroll_info =
887 host_impl_->ProcessScrollDeltas();
888 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
889
890 EXPECT_TRUE(scroll_info->scrolls.empty());
891 }
892
893 // Two-finger panning should not happen based on pinch events only
894 {
895 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
896 min_page_scale,
897 max_page_scale);
[email protected]aa043632013-03-25 03:39:42898 scroll_layer->SetScrollDelta(gfx::Vector2d());
899 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20));
900
901 float page_scale_delta = 1.f;
[email protected]9ec24df2013-08-09 23:32:57902 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42903 host_impl_->PinchGestureBegin();
904 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
905 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
906 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:57907 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:42908
909 scoped_ptr<ScrollAndScaleSet> scroll_info =
910 host_impl_->ProcessScrollDeltas();
911 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
912 EXPECT_TRUE(scroll_info->scrolls.empty());
913 }
914
915 // Two-finger panning should work with interleaved scroll events
916 {
917 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
918 min_page_scale,
919 max_page_scale);
[email protected]aa043632013-03-25 03:39:42920 scroll_layer->SetScrollDelta(gfx::Vector2d());
921 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20));
922
923 float page_scale_delta = 1.f;
[email protected]9ec24df2013-08-09 23:32:57924 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:42925 host_impl_->PinchGestureBegin();
926 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
927 host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
928 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
929 host_impl_->PinchGestureEnd();
930 host_impl_->ScrollEnd();
931
932 scoped_ptr<ScrollAndScaleSet> scroll_info =
933 host_impl_->ProcessScrollDeltas();
934 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
935 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10));
936 }
[email protected]9ec24df2013-08-09 23:32:57937
938 // Two-finger panning should work when starting fully zoomed out.
939 {
940 host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f,
941 0.5f,
942 4.f);
943 scroll_layer->SetScrollDelta(gfx::Vector2d());
944 scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0));
945 host_impl_->active_tree()->UpdateMaxScrollOffset();
946
947 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture);
948 host_impl_->PinchGestureBegin();
949 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
950 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
951 host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
952 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
953 host_impl_->PinchGestureEnd();
954 host_impl_->ScrollEnd();
955
956 scoped_ptr<ScrollAndScaleSet> scroll_info =
957 host_impl_->ProcessScrollDeltas();
958 EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
959 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20));
960 }
[email protected]be782f52013-03-23 21:36:14961}
962
[email protected]aa043632013-03-25 03:39:42963TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
964 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:40965 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:42966 InitializeRendererAndDrawFrame();
[email protected]df8f44f2013-01-08 08:00:31967
[email protected]aa043632013-03-25 03:39:42968 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
969 DCHECK(scroll_layer);
[email protected]df8f44f2013-01-08 08:00:31970
[email protected]aa043632013-03-25 03:39:42971 float min_page_scale = 0.5f;
972 float max_page_scale = 4.f;
973 base::TimeTicks start_time = base::TimeTicks() +
974 base::TimeDelta::FromSeconds(1);
975 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
976 base::TimeTicks halfway_through_animation = start_time + duration / 2;
977 base::TimeTicks end_time = start_time + duration;
[email protected]aa043632013-03-25 03:39:42978
979 // Non-anchor zoom-in
980 {
981 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
982 min_page_scale,
983 max_page_scale);
[email protected]aa043632013-03-25 03:39:42984 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
985
986 host_impl_->StartPageScaleAnimation(gfx::Vector2d(),
987 false,
988 2.f,
989 start_time,
990 duration);
991 host_impl_->Animate(halfway_through_animation, base::Time());
992 EXPECT_TRUE(did_request_redraw_);
993 host_impl_->Animate(end_time, base::Time());
994 EXPECT_TRUE(did_request_commit_);
995
996 scoped_ptr<ScrollAndScaleSet> scroll_info =
997 host_impl_->ProcessScrollDeltas();
998 EXPECT_EQ(scroll_info->page_scale_delta, 2);
999 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1000 }
1001
1002 // Anchor zoom-out
1003 {
1004 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1005 min_page_scale,
1006 max_page_scale);
[email protected]aa043632013-03-25 03:39:421007 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
1008
1009 host_impl_->StartPageScaleAnimation(gfx::Vector2d(25, 25),
1010 true,
1011 min_page_scale,
1012 start_time, duration);
1013 host_impl_->Animate(end_time, base::Time());
1014 EXPECT_TRUE(did_request_redraw_);
1015 EXPECT_TRUE(did_request_commit_);
1016
1017 scoped_ptr<ScrollAndScaleSet> scroll_info =
1018 host_impl_->ProcessScrollDeltas();
1019 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
1020 // Pushed to (0,0) via clamping against contents layer size.
1021 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1022 }
[email protected]df8f44f2013-01-08 08:00:311023}
1024
[email protected]aa043632013-03-25 03:39:421025TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
1026 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401027 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:421028 InitializeRendererAndDrawFrame();
[email protected]1c0c9bc2012-10-08 22:41:481029
[email protected]aa043632013-03-25 03:39:421030 LayerImpl* scroll_layer = host_impl_->RootScrollLayer();
1031 DCHECK(scroll_layer);
[email protected]1c0c9bc2012-10-08 22:41:481032
[email protected]aa043632013-03-25 03:39:421033 float min_page_scale = 0.5f;
1034 float max_page_scale = 4.f;
1035 base::TimeTicks start_time = base::TimeTicks() +
1036 base::TimeDelta::FromSeconds(1);
1037 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1038 base::TimeTicks halfway_through_animation = start_time + duration / 2;
1039 base::TimeTicks end_time = start_time + duration;
[email protected]1c0c9bc2012-10-08 22:41:481040
[email protected]aa043632013-03-25 03:39:421041 // Anchor zoom with unchanged page scale should not change scroll or scale.
1042 {
1043 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1044 min_page_scale,
1045 max_page_scale);
[email protected]aa043632013-03-25 03:39:421046 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
[email protected]c60279472013-01-30 12:10:511047
[email protected]aa043632013-03-25 03:39:421048 host_impl_->StartPageScaleAnimation(gfx::Vector2d(),
1049 true,
1050 1.f,
1051 start_time,
1052 duration);
1053 host_impl_->Animate(halfway_through_animation, base::Time());
1054 EXPECT_TRUE(did_request_redraw_);
1055 host_impl_->Animate(end_time, base::Time());
1056 EXPECT_TRUE(did_request_commit_);
[email protected]c60279472013-01-30 12:10:511057
[email protected]aa043632013-03-25 03:39:421058 scoped_ptr<ScrollAndScaleSet> scroll_info =
1059 host_impl_->ProcessScrollDeltas();
1060 EXPECT_EQ(scroll_info->page_scale_delta, 1);
1061 ExpectNone(*scroll_info, scroll_layer->id());
1062 }
[email protected]1c0c9bc2012-10-08 22:41:481063}
1064
[email protected]21c9dee72013-06-15 01:20:051065class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
1066 public:
1067 LayerTreeHostImplOverridePhysicalTime(
1068 const LayerTreeSettings& settings,
1069 LayerTreeHostImplClient* client,
1070 Proxy* proxy,
1071 RenderingStatsInstrumentation* rendering_stats_instrumentation)
1072 : LayerTreeHostImpl(settings,
1073 client,
1074 proxy,
1075 rendering_stats_instrumentation) {}
1076
1077
1078 virtual base::TimeTicks CurrentPhysicalTimeTicks() const OVERRIDE {
1079 return fake_current_physical_time_;
1080 }
1081
1082 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) {
1083 fake_current_physical_time_ = fake_now;
1084 }
1085
1086 private:
1087 base::TimeTicks fake_current_physical_time_;
1088};
1089
1090TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
1091 LayerTreeSettings settings;
[email protected]fea161872013-08-27 22:34:591092 settings.scrollbar_animator = LayerTreeSettings::LinearFade;
[email protected]21c9dee72013-06-15 01:20:051093 settings.scrollbar_linear_fade_delay_ms = 20;
1094 settings.scrollbar_linear_fade_length_ms = 20;
1095
[email protected]4f0f43a2013-07-31 17:44:441096 gfx::Size viewport_size(10, 10);
1097 gfx::Size content_size(100, 100);
1098
[email protected]21c9dee72013-06-15 01:20:051099 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =
1100 new LayerTreeHostImplOverridePhysicalTime(
1101 settings, this, &proxy_, &stats_instrumentation_);
1102 host_impl_ = make_scoped_ptr<LayerTreeHostImpl>(host_impl_override_time);
1103 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]4f0f43a2013-07-31 17:44:441104 host_impl_->SetViewportSize(viewport_size);
[email protected]21c9dee72013-06-15 01:20:051105
[email protected]21c9dee72013-06-15 01:20:051106 scoped_ptr<LayerImpl> root =
1107 LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]4f0f43a2013-07-31 17:44:441108 root->SetBounds(viewport_size);
[email protected]21c9dee72013-06-15 01:20:051109
1110 scoped_ptr<LayerImpl> scroll =
1111 LayerImpl::Create(host_impl_->active_tree(), 2);
1112 scroll->SetScrollable(true);
1113 scroll->SetScrollOffset(gfx::Vector2d());
1114 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
1115 content_size.height()));
1116 scroll->SetBounds(content_size);
1117 scroll->SetContentBounds(content_size);
1118
1119 scoped_ptr<LayerImpl> contents =
1120 LayerImpl::Create(host_impl_->active_tree(), 3);
1121 contents->SetDrawsContent(true);
1122 contents->SetBounds(content_size);
1123 contents->SetContentBounds(content_size);
1124
[email protected]3a83478b2013-08-22 20:55:171125 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
1126 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 4, VERTICAL);
[email protected]21c9dee72013-06-15 01:20:051127 scroll->SetVerticalScrollbarLayer(scrollbar.get());
1128
1129 scroll->AddChild(contents.Pass());
1130 root->AddChild(scroll.Pass());
1131 root->AddChild(scrollbar.PassAs<LayerImpl>());
1132
1133 host_impl_->active_tree()->SetRootLayer(root.Pass());
1134 host_impl_->active_tree()->DidBecomeActive();
1135 InitializeRendererAndDrawFrame();
1136
1137 base::TimeTicks fake_now = base::TimeTicks::Now();
1138 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1139
1140 // If no scroll happened recently, StartScrollbarAnimation should have no
1141 // effect.
1142 host_impl_->StartScrollbarAnimation();
1143 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1144 EXPECT_FALSE(did_request_redraw_);
1145
1146 // After a scroll, a fade animation should be scheduled about 20ms from now.
1147 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1148 host_impl_->ScrollEnd();
1149 host_impl_->StartScrollbarAnimation();
1150 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1151 requested_scrollbar_animation_delay_);
1152 EXPECT_FALSE(did_request_redraw_);
1153 requested_scrollbar_animation_delay_ = base::TimeDelta();
1154
1155 // After the fade begins, we should start getting redraws instead of a
1156 // scheduled animation.
1157 fake_now += base::TimeDelta::FromMilliseconds(25);
1158 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1159 host_impl_->StartScrollbarAnimation();
1160 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1161 EXPECT_TRUE(did_request_redraw_);
1162 did_request_redraw_ = false;
1163
1164 // If no scroll happened recently, StartScrollbarAnimation should have no
1165 // effect.
1166 fake_now += base::TimeDelta::FromMilliseconds(25);
1167 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1168 host_impl_->StartScrollbarAnimation();
1169 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1170 EXPECT_FALSE(did_request_redraw_);
1171
1172 // Setting the scroll offset outside a scroll should also cause the scrollbar
1173 // to appear and to schedule a fade.
1174 host_impl_->RootScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
1175 host_impl_->StartScrollbarAnimation();
1176 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1177 requested_scrollbar_animation_delay_);
1178 EXPECT_FALSE(did_request_redraw_);
1179 requested_scrollbar_animation_delay_ = base::TimeDelta();
1180
1181 // None of the above should have called CurrentFrameTimeTicks, so if we call
1182 // it now we should get the current time.
1183 fake_now += base::TimeDelta::FromMilliseconds(10);
1184 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
1185 EXPECT_EQ(fake_now, host_impl_->CurrentFrameTimeTicks());
1186}
1187
[email protected]aa043632013-03-25 03:39:421188TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
1189 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]18ce59702013-04-09 04:58:401190 host_impl_->SetViewportSize(gfx::Size(50, 50));
[email protected]aa043632013-03-25 03:39:421191 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
1192 InitializeRendererAndDrawFrame();
1193 {
1194 CompositorFrameMetadata metadata =
1195 host_impl_->MakeCompositorFrameMetadata();
1196 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
1197 EXPECT_EQ(1.f, metadata.page_scale_factor);
1198 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.viewport_size);
1199 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1200 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1201 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1202 }
[email protected]94f206c12012-08-25 00:09:141203
[email protected]aa043632013-03-25 03:39:421204 // Scrolling should update metadata immediately.
[email protected]5ff3c9782013-04-29 17:35:121205 EXPECT_EQ(InputHandler::ScrollStarted,
1206 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421207 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1208 {
1209 CompositorFrameMetadata metadata =
1210 host_impl_->MakeCompositorFrameMetadata();
1211 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1212 }
1213 host_impl_->ScrollEnd();
1214 {
1215 CompositorFrameMetadata metadata =
1216 host_impl_->MakeCompositorFrameMetadata();
1217 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1218 }
[email protected]94f206c12012-08-25 00:09:141219
[email protected]aa043632013-03-25 03:39:421220 // Page scale should update metadata correctly (shrinking only the viewport).
[email protected]9ec24df2013-08-09 23:32:571221 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:421222 host_impl_->PinchGestureBegin();
1223 host_impl_->PinchGestureUpdate(2.f, gfx::Point());
1224 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:571225 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:421226 {
1227 CompositorFrameMetadata metadata =
1228 host_impl_->MakeCompositorFrameMetadata();
1229 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1230 EXPECT_EQ(2.f, metadata.page_scale_factor);
1231 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.viewport_size);
1232 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1233 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1234 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1235 }
[email protected]94f206c12012-08-25 00:09:141236
[email protected]aa043632013-03-25 03:39:421237 // Likewise if set from the main thread.
1238 host_impl_->ProcessScrollDeltas();
1239 host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f);
1240 host_impl_->active_tree()->SetPageScaleDelta(1.f);
1241 {
1242 CompositorFrameMetadata metadata =
1243 host_impl_->MakeCompositorFrameMetadata();
1244 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1245 EXPECT_EQ(4.f, metadata.page_scale_factor);
1246 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.viewport_size);
1247 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1248 EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1249 EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1250 }
[email protected]f2b5a5be2013-01-08 00:34:361251}
1252
[email protected]96baf3e2012-10-22 23:09:551253class DidDrawCheckLayer : public TiledLayerImpl {
[email protected]aa043632013-03-25 03:39:421254 public:
1255 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
1256 return scoped_ptr<LayerImpl>(new DidDrawCheckLayer(tree_impl, id));
1257 }
[email protected]94f206c12012-08-25 00:09:141258
[email protected]ffbb2212013-06-02 23:47:591259 virtual bool WillDraw(DrawMode draw_mode, ResourceProvider* provider)
1260 OVERRIDE {
1261 will_draw_called_ = true;
1262 if (will_draw_returns_false_)
1263 return false;
1264 return TiledLayerImpl::WillDraw(draw_mode, provider);
1265 }
1266
1267 virtual void AppendQuads(QuadSink* quad_sink,
1268 AppendQuadsData* append_quads_data) OVERRIDE {
1269 append_quads_called_ = true;
1270 TiledLayerImpl::AppendQuads(quad_sink, append_quads_data);
1271 }
1272
[email protected]bf691c22013-03-26 21:15:061273 virtual void DidDraw(ResourceProvider* provider) OVERRIDE {
[email protected]aa043632013-03-25 03:39:421274 did_draw_called_ = true;
[email protected]ffbb2212013-06-02 23:47:591275 TiledLayerImpl::DidDraw(provider);
[email protected]aa043632013-03-25 03:39:421276 }
[email protected]94f206c12012-08-25 00:09:141277
[email protected]aa043632013-03-25 03:39:421278 bool will_draw_called() const { return will_draw_called_; }
[email protected]ffbb2212013-06-02 23:47:591279 bool append_quads_called() const { return append_quads_called_; }
1280 bool did_draw_called() const { return did_draw_called_; }
1281
1282 void set_will_draw_returns_false() { will_draw_returns_false_ = true; }
[email protected]94f206c12012-08-25 00:09:141283
[email protected]aa043632013-03-25 03:39:421284 void ClearDidDrawCheck() {
[email protected]aa043632013-03-25 03:39:421285 will_draw_called_ = false;
[email protected]ffbb2212013-06-02 23:47:591286 append_quads_called_ = false;
1287 did_draw_called_ = false;
[email protected]aa043632013-03-25 03:39:421288 }
[email protected]94f206c12012-08-25 00:09:141289
[email protected]aa043632013-03-25 03:39:421290 protected:
1291 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id)
1292 : TiledLayerImpl(tree_impl, id),
[email protected]ffbb2212013-06-02 23:47:591293 will_draw_returns_false_(false),
1294 will_draw_called_(false),
1295 append_quads_called_(false),
1296 did_draw_called_(false) {
[email protected]aa043632013-03-25 03:39:421297 SetAnchorPoint(gfx::PointF());
1298 SetBounds(gfx::Size(10, 10));
1299 SetContentBounds(gfx::Size(10, 10));
1300 SetDrawsContent(true);
1301 set_skips_draw(false);
1302 draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
[email protected]94f206c12012-08-25 00:09:141303
[email protected]aa043632013-03-25 03:39:421304 scoped_ptr<LayerTilingData> tiler =
1305 LayerTilingData::Create(gfx::Size(100, 100),
1306 LayerTilingData::HAS_BORDER_TEXELS);
1307 tiler->SetBounds(content_bounds());
1308 SetTilingData(*tiler.get());
1309 }
[email protected]94f206c12012-08-25 00:09:141310
[email protected]aa043632013-03-25 03:39:421311 private:
[email protected]ffbb2212013-06-02 23:47:591312 bool will_draw_returns_false_;
[email protected]aa043632013-03-25 03:39:421313 bool will_draw_called_;
[email protected]ffbb2212013-06-02 23:47:591314 bool append_quads_called_;
1315 bool did_draw_called_;
[email protected]94f206c12012-08-25 00:09:141316};
1317
[email protected]ffbb2212013-06-02 23:47:591318TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
1319 // The root layer is always drawn, so run this test on a child layer that
1320 // will be masked out by the root layer's bounds.
1321 host_impl_->active_tree()->SetRootLayer(
1322 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1323 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1324 host_impl_->active_tree()->root_layer());
1325
1326 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1327 DidDrawCheckLayer* layer =
1328 static_cast<DidDrawCheckLayer*>(root->children()[0]);
1329
1330 {
1331 LayerTreeHostImpl::FrameData frame;
1332 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
1333 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1334 host_impl_->DidDrawAllLayers(frame);
1335
1336 EXPECT_TRUE(layer->will_draw_called());
1337 EXPECT_TRUE(layer->append_quads_called());
1338 EXPECT_TRUE(layer->did_draw_called());
1339 }
1340
1341 {
1342 LayerTreeHostImpl::FrameData frame;
1343
1344 layer->set_will_draw_returns_false();
1345 layer->ClearDidDrawCheck();
1346
1347 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
1348 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1349 host_impl_->DidDrawAllLayers(frame);
1350
1351 EXPECT_TRUE(layer->will_draw_called());
1352 EXPECT_FALSE(layer->append_quads_called());
1353 EXPECT_FALSE(layer->did_draw_called());
1354 }
1355}
1356
[email protected]aa043632013-03-25 03:39:421357TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
1358 // The root layer is always drawn, so run this test on a child layer that
1359 // will be masked out by the root layer's bounds.
1360 host_impl_->active_tree()->SetRootLayer(
1361 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1362 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1363 host_impl_->active_tree()->root_layer());
1364 root->SetMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:141365
[email protected]aa043632013-03-25 03:39:421366 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1367 DidDrawCheckLayer* layer =
1368 static_cast<DidDrawCheckLayer*>(root->children()[0]);
1369 // Ensure visible_content_rect for layer is empty.
1370 layer->SetPosition(gfx::PointF(100.f, 100.f));
1371 layer->SetBounds(gfx::Size(10, 10));
1372 layer->SetContentBounds(gfx::Size(10, 10));
[email protected]94f206c12012-08-25 00:09:141373
[email protected]aa043632013-03-25 03:39:421374 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141375
[email protected]aa043632013-03-25 03:39:421376 EXPECT_FALSE(layer->will_draw_called());
1377 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141378
[email protected]e0341352013-04-06 05:01:201379 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421380 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1381 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141382
[email protected]aa043632013-03-25 03:39:421383 EXPECT_FALSE(layer->will_draw_called());
1384 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141385
[email protected]aa043632013-03-25 03:39:421386 EXPECT_TRUE(layer->visible_content_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:141387
[email protected]aa043632013-03-25 03:39:421388 // Ensure visible_content_rect for layer is not empty
1389 layer->SetPosition(gfx::PointF());
[email protected]94f206c12012-08-25 00:09:141390
[email protected]aa043632013-03-25 03:39:421391 EXPECT_FALSE(layer->will_draw_called());
1392 EXPECT_FALSE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141393
[email protected]e0341352013-04-06 05:01:201394 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421395 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1396 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141397
[email protected]aa043632013-03-25 03:39:421398 EXPECT_TRUE(layer->will_draw_called());
1399 EXPECT_TRUE(layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141400
[email protected]aa043632013-03-25 03:39:421401 EXPECT_FALSE(layer->visible_content_rect().IsEmpty());
[email protected]94f206c12012-08-25 00:09:141402}
1403
[email protected]aa043632013-03-25 03:39:421404TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
1405 gfx::Size big_size(1000, 1000);
[email protected]18ce59702013-04-09 04:58:401406 host_impl_->SetViewportSize(big_size);
[email protected]94f206c12012-08-25 00:09:141407
[email protected]aa043632013-03-25 03:39:421408 host_impl_->active_tree()->SetRootLayer(
1409 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1410 DidDrawCheckLayer* root =
1411 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:141412
[email protected]aa043632013-03-25 03:39:421413 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1414 DidDrawCheckLayer* occluded_layer =
1415 static_cast<DidDrawCheckLayer*>(root->children()[0]);
[email protected]94f206c12012-08-25 00:09:141416
[email protected]aa043632013-03-25 03:39:421417 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1418 DidDrawCheckLayer* top_layer =
1419 static_cast<DidDrawCheckLayer*>(root->children()[1]);
1420 // This layer covers the occluded_layer above. Make this layer large so it can
1421 // occlude.
1422 top_layer->SetBounds(big_size);
1423 top_layer->SetContentBounds(big_size);
1424 top_layer->SetContentsOpaque(true);
[email protected]94f206c12012-08-25 00:09:141425
[email protected]aa043632013-03-25 03:39:421426 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141427
[email protected]aa043632013-03-25 03:39:421428 EXPECT_FALSE(occluded_layer->will_draw_called());
1429 EXPECT_FALSE(occluded_layer->did_draw_called());
1430 EXPECT_FALSE(top_layer->will_draw_called());
1431 EXPECT_FALSE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141432
[email protected]e0341352013-04-06 05:01:201433 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421434 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1435 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141436
[email protected]aa043632013-03-25 03:39:421437 EXPECT_FALSE(occluded_layer->will_draw_called());
1438 EXPECT_FALSE(occluded_layer->did_draw_called());
1439 EXPECT_TRUE(top_layer->will_draw_called());
1440 EXPECT_TRUE(top_layer->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141441}
1442
[email protected]aa043632013-03-25 03:39:421443TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
1444 host_impl_->active_tree()->SetRootLayer(
1445 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1446 DidDrawCheckLayer* root =
1447 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
[email protected]94f206c12012-08-25 00:09:141448
[email protected]aa043632013-03-25 03:39:421449 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1450 DidDrawCheckLayer* layer1 =
1451 static_cast<DidDrawCheckLayer*>(root->children()[0]);
[email protected]94f206c12012-08-25 00:09:141452
[email protected]aa043632013-03-25 03:39:421453 layer1->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1454 DidDrawCheckLayer* layer2 =
1455 static_cast<DidDrawCheckLayer*>(layer1->children()[0]);
[email protected]94f206c12012-08-25 00:09:141456
[email protected]aa043632013-03-25 03:39:421457 layer1->SetOpacity(0.3f);
1458 layer1->SetPreserves3d(false);
[email protected]94f206c12012-08-25 00:09:141459
[email protected]aa043632013-03-25 03:39:421460 EXPECT_FALSE(root->did_draw_called());
1461 EXPECT_FALSE(layer1->did_draw_called());
1462 EXPECT_FALSE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141463
[email protected]aa043632013-03-25 03:39:421464 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:201465 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421466 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1467 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141468
[email protected]aa043632013-03-25 03:39:421469 EXPECT_TRUE(root->did_draw_called());
1470 EXPECT_TRUE(layer1->did_draw_called());
1471 EXPECT_TRUE(layer2->did_draw_called());
[email protected]94f206c12012-08-25 00:09:141472
[email protected]aa043632013-03-25 03:39:421473 EXPECT_NE(root->render_surface(), layer1->render_surface());
1474 EXPECT_TRUE(!!layer1->render_surface());
[email protected]94f206c12012-08-25 00:09:141475}
1476
1477class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
[email protected]aa043632013-03-25 03:39:421478 public:
1479 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
1480 int id,
1481 bool tile_missing,
1482 bool skips_draw,
1483 bool animating,
1484 ResourceProvider* resource_provider) {
1485 return scoped_ptr<LayerImpl>(new MissingTextureAnimatingLayer(
1486 tree_impl,
1487 id,
1488 tile_missing,
1489 skips_draw,
1490 animating,
1491 resource_provider));
1492 }
[email protected]94f206c12012-08-25 00:09:141493
[email protected]aa043632013-03-25 03:39:421494 private:
1495 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl,
1496 int id,
1497 bool tile_missing,
1498 bool skips_draw,
1499 bool animating,
1500 ResourceProvider* resource_provider)
1501 : DidDrawCheckLayer(tree_impl, id) {
1502 scoped_ptr<LayerTilingData> tiling_data =
1503 LayerTilingData::Create(gfx::Size(10, 10),
1504 LayerTilingData::NO_BORDER_TEXELS);
1505 tiling_data->SetBounds(bounds());
1506 SetTilingData(*tiling_data.get());
1507 set_skips_draw(skips_draw);
1508 if (!tile_missing) {
1509 ResourceProvider::ResourceId resource =
[email protected]cdccc7d42013-05-03 17:15:071510 resource_provider->CreateResource(gfx::Size(1, 1),
[email protected]aa043632013-03-25 03:39:421511 GL_RGBA,
1512 ResourceProvider::TextureUsageAny);
1513 resource_provider->AllocateForTesting(resource);
1514 PushTileProperties(0, 0, resource, gfx::Rect(), false);
[email protected]94f206c12012-08-25 00:09:141515 }
[email protected]aa043632013-03-25 03:39:421516 if (animating)
1517 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1518 }
[email protected]94f206c12012-08-25 00:09:141519};
1520
[email protected]aa043632013-03-25 03:39:421521TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
1522 // When the texture is not missing, we draw as usual.
1523 host_impl_->active_tree()->SetRootLayer(
1524 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1525 DidDrawCheckLayer* root =
1526 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1527 root->AddChild(
1528 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1529 2,
1530 false,
1531 false,
1532 true,
1533 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141534
[email protected]aa043632013-03-25 03:39:421535 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:141536
[email protected]e0341352013-04-06 05:01:201537 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421538 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1539 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141540
[email protected]aa043632013-03-25 03:39:421541 // When a texture is missing and we're not animating, we draw as usual with
1542 // checkerboarding.
1543 host_impl_->active_tree()->SetRootLayer(
1544 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1545 root =
1546 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1547 root->AddChild(
1548 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1549 4,
1550 true,
1551 false,
1552 false,
1553 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141554
[email protected]e0341352013-04-06 05:01:201555 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421556 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1557 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141558
[email protected]aa043632013-03-25 03:39:421559 // When a texture is missing and we're animating, we don't want to draw
1560 // anything.
1561 host_impl_->active_tree()->SetRootLayer(
1562 DidDrawCheckLayer::Create(host_impl_->active_tree(), 5));
1563 root =
1564 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1565 root->AddChild(
1566 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1567 6,
1568 true,
1569 false,
1570 true,
1571 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141572
[email protected]e0341352013-04-06 05:01:201573 EXPECT_FALSE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421574 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1575 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141576
[email protected]aa043632013-03-25 03:39:421577 // When the layer skips draw and we're animating, we still draw the frame.
1578 host_impl_->active_tree()->SetRootLayer(
1579 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7));
1580 root =
1581 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1582 root->AddChild(
1583 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
1584 8,
1585 false,
1586 true,
1587 true,
1588 host_impl_->resource_provider()));
[email protected]94f206c12012-08-25 00:09:141589
[email protected]e0341352013-04-06 05:01:201590 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421591 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1592 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141593}
1594
[email protected]aa043632013-03-25 03:39:421595TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
1596 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1597 root->SetScrollable(false);
1598 host_impl_->active_tree()->SetRootLayer(root.Pass());
1599 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141600
[email protected]aa043632013-03-25 03:39:421601 // Scroll event is ignored because layer is not scrollable.
[email protected]5ff3c9782013-04-29 17:35:121602 EXPECT_EQ(InputHandler::ScrollIgnored,
1603 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421604 EXPECT_FALSE(did_request_redraw_);
1605 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141606}
1607
[email protected]aa043632013-03-25 03:39:421608TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) {
1609 LayerTreeSettings settings;
1610 settings.calculate_top_controls_position = true;
1611 settings.top_controls_height = 50;
[email protected]c8415bf92013-02-17 18:57:271612
[email protected]aa043632013-03-25 03:39:421613 host_impl_ = LayerTreeHostImpl::Create(settings,
1614 this,
1615 &proxy_,
1616 &stats_instrumentation_);
1617 host_impl_->InitializeRenderer(CreateOutputSurface());
[email protected]18ce59702013-04-09 04:58:401618 host_impl_->SetViewportSize(gfx::Size(10, 10));
[email protected]c8415bf92013-02-17 18:57:271619
[email protected]aa043632013-03-25 03:39:421620 gfx::Size layer_size(5, 5);
1621 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1622 root->SetScrollable(true);
1623 root->SetMaxScrollOffset(gfx::Vector2d(layer_size.width(),
1624 layer_size.height()));
1625 root->SetBounds(layer_size);
1626 root->SetContentBounds(layer_size);
1627 root->SetPosition(gfx::PointF());
1628 root->SetAnchorPoint(gfx::PointF());
[email protected]e0341352013-04-06 05:01:201629 root->SetDrawsContent(false);
[email protected]aa043632013-03-25 03:39:421630 host_impl_->active_tree()->SetRootLayer(root.Pass());
1631 host_impl_->active_tree()->FindRootScrollLayer();
1632 InitializeRendererAndDrawFrame();
[email protected]c8415bf92013-02-17 18:57:271633
[email protected]5ff3c9782013-04-29 17:35:121634 EXPECT_EQ(InputHandler::ScrollIgnored,
1635 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]c8415bf92013-02-17 18:57:271636
[email protected]aa043632013-03-25 03:39:421637 host_impl_->top_controls_manager()->ScrollBegin();
1638 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
1639 host_impl_->top_controls_manager()->ScrollEnd();
1640 EXPECT_EQ(host_impl_->top_controls_manager()->content_top_offset(), 0.f);
[email protected]c8415bf92013-02-17 18:57:271641
[email protected]5ff3c9782013-04-29 17:35:121642 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421643 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:121644 InputHandler::Gesture));
[email protected]c8415bf92013-02-17 18:57:271645}
1646
[email protected]aa043632013-03-25 03:39:421647TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
1648 // Test the configuration where a non-composited root layer is embedded in a
1649 // scrollable outer layer.
1650 gfx::Size surface_size(10, 10);
[email protected]94f206c12012-08-25 00:09:141651
[email protected]aa043632013-03-25 03:39:421652 scoped_ptr<LayerImpl> content_layer =
1653 LayerImpl::Create(host_impl_->active_tree(), 1);
1654 content_layer->SetDrawsContent(true);
1655 content_layer->SetPosition(gfx::PointF());
1656 content_layer->SetAnchorPoint(gfx::PointF());
1657 content_layer->SetBounds(surface_size);
1658 content_layer->SetContentBounds(gfx::Size(surface_size.width() * 2,
1659 surface_size.height() * 2));
1660 content_layer->SetContentsScale(2.f, 2.f);
[email protected]94f206c12012-08-25 00:09:141661
[email protected]aa043632013-03-25 03:39:421662 scoped_ptr<LayerImpl> scroll_layer =
1663 LayerImpl::Create(host_impl_->active_tree(), 2);
1664 scroll_layer->SetScrollable(true);
1665 scroll_layer->SetMaxScrollOffset(gfx::Vector2d(surface_size.width(),
1666 surface_size.height()));
1667 scroll_layer->SetBounds(surface_size);
1668 scroll_layer->SetContentBounds(surface_size);
1669 scroll_layer->SetPosition(gfx::PointF());
1670 scroll_layer->SetAnchorPoint(gfx::PointF());
1671 scroll_layer->AddChild(content_layer.Pass());
[email protected]94f206c12012-08-25 00:09:141672
[email protected]aa043632013-03-25 03:39:421673 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass());
[email protected]18ce59702013-04-09 04:58:401674 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421675 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141676
[email protected]5ff3c9782013-04-29 17:35:121677 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421678 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121679 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421680 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1681 host_impl_->ScrollEnd();
1682 EXPECT_TRUE(did_request_redraw_);
1683 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141684}
1685
[email protected]aa043632013-03-25 03:39:421686TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
1687 gfx::Size surface_size(10, 10);
1688 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1689 root->SetBounds(surface_size);
1690 root->SetContentBounds(surface_size);
1691 root->AddChild(CreateScrollableLayer(2, surface_size));
1692 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:401693 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421694 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141695
[email protected]5ff3c9782013-04-29 17:35:121696 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421697 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121698 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421699 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1700 host_impl_->ScrollEnd();
1701 EXPECT_TRUE(did_request_redraw_);
1702 EXPECT_TRUE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141703}
1704
[email protected]aa043632013-03-25 03:39:421705TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
1706 gfx::Size surface_size(10, 10);
1707 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1708 root->AddChild(CreateScrollableLayer(2, surface_size));
1709 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:401710 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421711 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141712
[email protected]aa043632013-03-25 03:39:421713 // Scroll event is ignored because the input coordinate is outside the layer
1714 // boundaries.
[email protected]5ff3c9782013-04-29 17:35:121715 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]aa043632013-03-25 03:39:421716 host_impl_->ScrollBegin(gfx::Point(15, 5),
[email protected]5ff3c9782013-04-29 17:35:121717 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421718 EXPECT_FALSE(did_request_redraw_);
1719 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141720}
1721
[email protected]aa043632013-03-25 03:39:421722TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
1723 gfx::Size surface_size(10, 10);
1724 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1725 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
[email protected]18ce59702013-04-09 04:58:401726 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:141727
[email protected]aa043632013-03-25 03:39:421728 gfx::Transform matrix;
1729 matrix.RotateAboutXAxis(180.0);
1730 child->SetTransform(matrix);
1731 child->SetDoubleSided(false);
[email protected]94f206c12012-08-25 00:09:141732
[email protected]aa043632013-03-25 03:39:421733 root->AddChild(child.Pass());
1734 host_impl_->active_tree()->SetRootLayer(root.Pass());
1735 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141736
[email protected]aa043632013-03-25 03:39:421737 // Scroll event is ignored because the scrollable layer is not facing the
1738 // viewer and there is nothing scrollable behind it.
[email protected]5ff3c9782013-04-29 17:35:121739 EXPECT_EQ(InputHandler::ScrollIgnored,
[email protected]aa043632013-03-25 03:39:421740 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121741 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421742 EXPECT_FALSE(did_request_redraw_);
1743 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:141744}
1745
[email protected]aa043632013-03-25 03:39:421746TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
1747 gfx::Size surface_size(10, 10);
1748 scoped_ptr<LayerImpl> content_layer = CreateScrollableLayer(1, surface_size);
1749 content_layer->SetShouldScrollOnMainThread(true);
1750 content_layer->SetScrollable(false);
[email protected]94f206c12012-08-25 00:09:141751
[email protected]aa043632013-03-25 03:39:421752 scoped_ptr<LayerImpl> scroll_layer = CreateScrollableLayer(2, surface_size);
1753 scroll_layer->AddChild(content_layer.Pass());
[email protected]94f206c12012-08-25 00:09:141754
[email protected]aa043632013-03-25 03:39:421755 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass());
[email protected]18ce59702013-04-09 04:58:401756 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421757 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141758
[email protected]aa043632013-03-25 03:39:421759 // Scrolling fails because the content layer is asking to be scrolled on the
1760 // main thread.
[email protected]5ff3c9782013-04-29 17:35:121761 EXPECT_EQ(InputHandler::ScrollOnMainThread,
[email protected]aa043632013-03-25 03:39:421762 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121763 InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:141764}
1765
[email protected]aa043632013-03-25 03:39:421766TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
1767 gfx::Size surface_size(10, 10);
1768 float page_scale = 2.f;
[email protected]9781afa2013-07-17 23:15:321769 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1770 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
1771 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421772 host_impl_->active_tree()->SetRootLayer(root.Pass());
1773 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401774 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421775 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141776
[email protected]9781afa2013-07-17 23:15:321777 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1778
[email protected]aa043632013-03-25 03:39:421779 gfx::Vector2d scroll_delta(0, 10);
1780 gfx::Vector2d expected_scroll_delta = scroll_delta;
[email protected]9781afa2013-07-17 23:15:321781 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset();
[email protected]5ff3c9782013-04-29 17:35:121782 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421783 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121784 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421785 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1786 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141787
[email protected]aa043632013-03-25 03:39:421788 // Set new page scale from main thread.
1789 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
1790 page_scale,
1791 page_scale);
[email protected]94f206c12012-08-25 00:09:141792
[email protected]aa043632013-03-25 03:39:421793 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:321794 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:141795
[email protected]aa043632013-03-25 03:39:421796 // The scroll range should also have been updated.
[email protected]9781afa2013-07-17 23:15:321797 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset());
[email protected]94f206c12012-08-25 00:09:141798
[email protected]aa043632013-03-25 03:39:421799 // The page scale delta remains constant because the impl thread did not
1800 // scale.
[email protected]f2136262013-04-26 21:10:191801 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:141802}
1803
[email protected]aa043632013-03-25 03:39:421804TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
1805 gfx::Size surface_size(10, 10);
1806 float page_scale = 2.f;
[email protected]9781afa2013-07-17 23:15:321807 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1808 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
1809 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421810 host_impl_->active_tree()->SetRootLayer(root.Pass());
1811 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401812 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421813 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale);
1814 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141815
[email protected]9781afa2013-07-17 23:15:321816 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
1817
[email protected]aa043632013-03-25 03:39:421818 gfx::Vector2d scroll_delta(0, 10);
1819 gfx::Vector2d expected_scroll_delta = scroll_delta;
[email protected]9781afa2013-07-17 23:15:321820 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset();
[email protected]5ff3c9782013-04-29 17:35:121821 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421822 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121823 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421824 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1825 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141826
[email protected]aa043632013-03-25 03:39:421827 // Set new page scale on impl thread by pinching.
[email protected]9ec24df2013-08-09 23:32:571828 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:421829 host_impl_->PinchGestureBegin();
1830 host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
1831 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:571832 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:421833 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:141834
[email protected]aa043632013-03-25 03:39:421835 // The scroll delta is not scaled because the main thread did not scale.
1836 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:321837 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:141838
[email protected]aa043632013-03-25 03:39:421839 // The scroll range should also have been updated.
[email protected]9781afa2013-07-17 23:15:321840 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset());
[email protected]94f206c12012-08-25 00:09:141841
[email protected]aa043632013-03-25 03:39:421842 // The page scale delta should match the new scale on the impl side.
[email protected]f2136262013-04-26 21:10:191843 EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor());
[email protected]94f206c12012-08-25 00:09:141844}
1845
[email protected]aa043632013-03-25 03:39:421846TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
1847 gfx::Size surface_size(10, 10);
1848 float default_page_scale = 1.f;
1849 gfx::Transform default_page_scale_matrix;
[email protected]3209161d2013-03-29 19:17:341850 default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
[email protected]1c0c9bc2012-10-08 22:41:481851
[email protected]aa043632013-03-25 03:39:421852 float new_page_scale = 2.f;
1853 gfx::Transform new_page_scale_matrix;
1854 new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
[email protected]94f206c12012-08-25 00:09:141855
[email protected]aa043632013-03-25 03:39:421856 // Create a normal scrollable root layer and another scrollable child layer.
[email protected]35a99a12013-05-09 23:52:291857 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
[email protected]aa043632013-03-25 03:39:421858 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]35a99a12013-05-09 23:52:291859 LayerImpl* child = scroll->children()[0];
[email protected]94f206c12012-08-25 00:09:141860
[email protected]aa043632013-03-25 03:39:421861 scoped_ptr<LayerImpl> scrollable_child =
[email protected]35a99a12013-05-09 23:52:291862 CreateScrollableLayer(4, surface_size);
[email protected]aa043632013-03-25 03:39:421863 child->AddChild(scrollable_child.Pass());
1864 LayerImpl* grand_child = child->children()[0];
[email protected]94f206c12012-08-25 00:09:141865
[email protected]aa043632013-03-25 03:39:421866 // Set new page scale on impl thread by pinching.
[email protected]9ec24df2013-08-09 23:32:571867 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
[email protected]aa043632013-03-25 03:39:421868 host_impl_->PinchGestureBegin();
1869 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
1870 host_impl_->PinchGestureEnd();
[email protected]9ec24df2013-08-09 23:32:571871 host_impl_->ScrollEnd();
[email protected]aa043632013-03-25 03:39:421872 DrawOneFrame();
[email protected]94f206c12012-08-25 00:09:141873
[email protected]f2136262013-04-26 21:10:191874 EXPECT_EQ(1.f, root->contents_scale_x());
1875 EXPECT_EQ(1.f, root->contents_scale_y());
[email protected]35a99a12013-05-09 23:52:291876 EXPECT_EQ(1.f, scroll->contents_scale_x());
1877 EXPECT_EQ(1.f, scroll->contents_scale_y());
[email protected]f2136262013-04-26 21:10:191878 EXPECT_EQ(1.f, child->contents_scale_x());
1879 EXPECT_EQ(1.f, child->contents_scale_y());
1880 EXPECT_EQ(1.f, grand_child->contents_scale_x());
1881 EXPECT_EQ(1.f, grand_child->contents_scale_y());
[email protected]94f206c12012-08-25 00:09:141882
[email protected]aa043632013-03-25 03:39:421883 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
1884 // the page scale delta on the root layer is applied hierarchically.
1885 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:201886 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:421887 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
1888 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:141889
[email protected]35a99a12013-05-09 23:52:291890 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0));
1891 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(1, 1));
1892 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(0, 0));
1893 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(1, 1));
[email protected]aa043632013-03-25 03:39:421894 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(0, 0));
1895 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(1, 1));
1896 EXPECT_EQ(new_page_scale,
1897 grand_child->draw_transform().matrix().getDouble(0, 0));
1898 EXPECT_EQ(new_page_scale,
1899 grand_child->draw_transform().matrix().getDouble(1, 1));
[email protected]94f206c12012-08-25 00:09:141900}
1901
[email protected]aa043632013-03-25 03:39:421902TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
1903 gfx::Size surface_size(10, 10);
1904 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
[email protected]9781afa2013-07-17 23:15:321905 scoped_ptr<LayerImpl> root_scrolling =
1906 LayerImpl::Create(host_impl_->active_tree(), 2);
1907 root_scrolling->SetBounds(surface_size);
1908 root_scrolling->SetContentBounds(surface_size);
1909 root_scrolling->SetScrollable(true);
1910 root->AddChild(root_scrolling.Pass());
1911 int child_scroll_layer_id = 3;
1912 scoped_ptr<LayerImpl> child_scrolling =
1913 CreateScrollableLayer(child_scroll_layer_id, surface_size);
1914 LayerImpl* child = child_scrolling.get();
1915 root->AddChild(child_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:421916 host_impl_->active_tree()->SetRootLayer(root.Pass());
1917 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401918 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421919 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:141920
[email protected]aa043632013-03-25 03:39:421921 gfx::Vector2d scroll_delta(0, 10);
1922 gfx::Vector2d expected_scroll_delta(scroll_delta);
1923 gfx::Vector2d expected_max_scroll(child->max_scroll_offset());
[email protected]5ff3c9782013-04-29 17:35:121924 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:421925 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:121926 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421927 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1928 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141929
[email protected]aa043632013-03-25 03:39:421930 float page_scale = 2.f;
1931 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
1932 1.f,
1933 page_scale);
[email protected]94f206c12012-08-25 00:09:141934
[email protected]aa043632013-03-25 03:39:421935 DrawOneFrame();
[email protected]1c0c9bc2012-10-08 22:41:481936
[email protected]aa043632013-03-25 03:39:421937 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]9781afa2013-07-17 23:15:321938 ExpectContains(
1939 *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:141940
[email protected]aa043632013-03-25 03:39:421941 // The scroll range should not have changed.
1942 EXPECT_EQ(child->max_scroll_offset(), expected_max_scroll);
[email protected]94f206c12012-08-25 00:09:141943
[email protected]aa043632013-03-25 03:39:421944 // The page scale delta remains constant because the impl thread did not
1945 // scale.
[email protected]f2136262013-04-26 21:10:191946 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
[email protected]94f206c12012-08-25 00:09:141947}
1948
[email protected]aa043632013-03-25 03:39:421949TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
1950 // Scroll a child layer beyond its maximum scroll range and make sure the
1951 // parent layer is scrolled on the axis on which the child was unable to
1952 // scroll.
1953 gfx::Size surface_size(10, 10);
1954 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size);
[email protected]94f206c12012-08-25 00:09:141955
[email protected]aa043632013-03-25 03:39:421956 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size);
1957 grand_child->SetScrollOffset(gfx::Vector2d(0, 5));
[email protected]94f206c12012-08-25 00:09:141958
[email protected]aa043632013-03-25 03:39:421959 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
1960 child->SetScrollOffset(gfx::Vector2d(3, 0));
1961 child->AddChild(grand_child.Pass());
[email protected]94f206c12012-08-25 00:09:141962
[email protected]aa043632013-03-25 03:39:421963 root->AddChild(child.Pass());
1964 host_impl_->active_tree()->SetRootLayer(root.Pass());
1965 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:401966 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:421967 InitializeRendererAndDrawFrame();
1968 {
1969 gfx::Vector2d scroll_delta(-8, -7);
[email protected]5ff3c9782013-04-29 17:35:121970 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:471971 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:121972 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:421973 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
1974 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:141975
[email protected]aa043632013-03-25 03:39:421976 scoped_ptr<ScrollAndScaleSet> scroll_info =
1977 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:141978
[email protected]aa043632013-03-25 03:39:421979 // The grand child should have scrolled up to its limit.
1980 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
1981 LayerImpl* grand_child = child->children()[0];
1982 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5));
[email protected]94f206c12012-08-25 00:09:141983
[email protected]aa043632013-03-25 03:39:421984 // The child should have only scrolled on the other axis.
1985 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0));
1986 }
[email protected]94f206c12012-08-25 00:09:141987}
1988
[email protected]aa043632013-03-25 03:39:421989TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
1990 // Scroll a child layer beyond its maximum scroll range and make sure the
1991 // the scroll doesn't bubble up to the parent layer.
1992 gfx::Size surface_size(10, 10);
[email protected]9781afa2013-07-17 23:15:321993 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
1994 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size);
[email protected]7dfa6862013-01-31 01:29:091995
[email protected]9781afa2013-07-17 23:15:321996 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(4, surface_size);
[email protected]aa043632013-03-25 03:39:421997 grand_child->SetScrollOffset(gfx::Vector2d(0, 2));
[email protected]7dfa6862013-01-31 01:29:091998
[email protected]9781afa2013-07-17 23:15:321999 scoped_ptr<LayerImpl> child = CreateScrollableLayer(3, surface_size);
[email protected]aa043632013-03-25 03:39:422000 child->SetScrollOffset(gfx::Vector2d(0, 3));
2001 child->AddChild(grand_child.Pass());
[email protected]7dfa6862013-01-31 01:29:092002
[email protected]9781afa2013-07-17 23:15:322003 root_scrolling->AddChild(child.Pass());
2004 root->AddChild(root_scrolling.Pass());
[email protected]aa043632013-03-25 03:39:422005 host_impl_->active_tree()->SetRootLayer(root.Pass());
2006 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402007 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422008 InitializeRendererAndDrawFrame();
2009 {
2010 gfx::Vector2d scroll_delta(0, -10);
[email protected]5ff3c9782013-04-29 17:35:122011 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472012 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122013 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422014 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2015 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092016
[email protected]aa043632013-03-25 03:39:422017 scoped_ptr<ScrollAndScaleSet> scroll_info =
2018 host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092019
[email protected]aa043632013-03-25 03:39:422020 // The grand child should have scrolled up to its limit.
[email protected]9781afa2013-07-17 23:15:322021 LayerImpl* child =
2022 host_impl_->active_tree()->root_layer()->children()[0]->children()[0];
[email protected]aa043632013-03-25 03:39:422023 LayerImpl* grand_child = child->children()[0];
2024 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
[email protected]7dfa6862013-01-31 01:29:092025
[email protected]aa043632013-03-25 03:39:422026 // The child should not have scrolled.
2027 ExpectNone(*scroll_info.get(), child->id());
[email protected]7dfa6862013-01-31 01:29:092028
[email protected]aa043632013-03-25 03:39:422029 // The next time we scroll we should only scroll the parent.
2030 scroll_delta = gfx::Vector2d(0, -3);
[email protected]5ff3c9782013-04-29 17:35:122031 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422032 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122033 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422034 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2035 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2036 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
2037 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092038
[email protected]aa043632013-03-25 03:39:422039 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092040
[email protected]aa043632013-03-25 03:39:422041 // The child should have scrolled up to its limit.
2042 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
[email protected]7dfa6862013-01-31 01:29:092043
[email protected]aa043632013-03-25 03:39:422044 // The grand child should not have scrolled.
2045 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
[email protected]7dfa6862013-01-31 01:29:092046
[email protected]aa043632013-03-25 03:39:422047 // After scrolling the parent, another scroll on the opposite direction
2048 // should still scroll the child.
2049 scroll_delta = gfx::Vector2d(0, 7);
[email protected]5ff3c9782013-04-29 17:35:122050 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422051 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122052 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422053 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2054 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2055 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2056 host_impl_->ScrollEnd();
[email protected]7dfa6862013-01-31 01:29:092057
[email protected]aa043632013-03-25 03:39:422058 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]7dfa6862013-01-31 01:29:092059
[email protected]aa043632013-03-25 03:39:422060 // The grand child should have scrolled.
2061 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5));
[email protected]7dfa6862013-01-31 01:29:092062
[email protected]aa043632013-03-25 03:39:422063 // The child should not have scrolled.
2064 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
[email protected]f4937272013-02-07 05:54:502065
2066
[email protected]aa043632013-03-25 03:39:422067 // Scrolling should be adjusted from viewport space.
2068 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f);
2069 host_impl_->active_tree()->SetPageScaleDelta(1.f);
[email protected]f4937272013-02-07 05:54:502070
[email protected]aa043632013-03-25 03:39:422071 scroll_delta = gfx::Vector2d(0, -2);
[email protected]5ff3c9782013-04-29 17:35:122072 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422073 host_impl_->ScrollBegin(gfx::Point(1, 1),
[email protected]5ff3c9782013-04-29 17:35:122074 InputHandler::NonBubblingGesture));
[email protected]aa043632013-03-25 03:39:422075 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer());
2076 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2077 host_impl_->ScrollEnd();
[email protected]f4937272013-02-07 05:54:502078
[email protected]aa043632013-03-25 03:39:422079 scroll_info = host_impl_->ProcessScrollDeltas();
[email protected]f4937272013-02-07 05:54:502080
[email protected]aa043632013-03-25 03:39:422081 // Should have scrolled by half the amount in layer space (5 - 2/2)
2082 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4));
2083 }
[email protected]7dfa6862013-01-31 01:29:092084}
2085
[email protected]aa043632013-03-25 03:39:422086TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
2087 // When we try to scroll a non-scrollable child layer, the scroll delta
2088 // should be applied to one of its ancestors if possible.
2089 gfx::Size surface_size(10, 10);
2090 gfx::Size content_size(20, 20);
2091 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
2092 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
[email protected]94f206c12012-08-25 00:09:142093
[email protected]aa043632013-03-25 03:39:422094 child->SetScrollable(false);
2095 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:142096
[email protected]18ce59702013-04-09 04:58:402097 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422098 host_impl_->active_tree()->SetRootLayer(root.Pass());
2099 host_impl_->active_tree()->DidBecomeActive();
2100 InitializeRendererAndDrawFrame();
2101 {
2102 gfx::Vector2d scroll_delta(0, 4);
[email protected]5ff3c9782013-04-29 17:35:122103 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422104 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122105 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422106 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2107 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142108
[email protected]aa043632013-03-25 03:39:422109 scoped_ptr<ScrollAndScaleSet> scroll_info =
2110 host_impl_->ProcessScrollDeltas();
[email protected]94f206c12012-08-25 00:09:142111
[email protected]aa043632013-03-25 03:39:422112 // Only the root should have scrolled.
2113 ASSERT_EQ(scroll_info->scrolls.size(), 1u);
2114 ExpectContains(*scroll_info.get(),
2115 host_impl_->active_tree()->root_layer()->id(),
2116 scroll_delta);
2117 }
[email protected]94f206c12012-08-25 00:09:142118}
2119
[email protected]aa043632013-03-25 03:39:422120TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
2121 gfx::Size surface_size(10, 10);
2122 host_impl_->active_tree()->SetRootLayer(
2123 CreateScrollableLayer(1, surface_size));
2124 host_impl_->active_tree()->DidBecomeActive();
[email protected]18ce59702013-04-09 04:58:402125 host_impl_->SetViewportSize(surface_size);
[email protected]94f206c12012-08-25 00:09:142126
[email protected]aa043632013-03-25 03:39:422127 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2128 // synchronization.
2129 InitializeRendererAndDrawFrame();
2130 host_impl_->active_tree()->DetachLayerTree();
2131 host_impl_->active_tree()->SetRootLayer(
2132 CreateScrollableLayer(2, surface_size));
2133 host_impl_->active_tree()->DidBecomeActive();
[email protected]94f206c12012-08-25 00:09:142134
[email protected]aa043632013-03-25 03:39:422135 // Scrolling should still work even though we did not draw yet.
[email protected]5ff3c9782013-04-29 17:35:122136 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422137 host_impl_->ScrollBegin(gfx::Point(5, 5),
[email protected]5ff3c9782013-04-29 17:35:122138 InputHandler::Wheel));
[email protected]94f206c12012-08-25 00:09:142139}
2140
[email protected]aa043632013-03-25 03:39:422141TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:292142 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:142143
[email protected]aa043632013-03-25 03:39:422144 // Rotate the root layer 90 degrees counter-clockwise about its center.
2145 gfx::Transform rotate_transform;
2146 rotate_transform.Rotate(-90.0);
2147 host_impl_->active_tree()->root_layer()->SetTransform(rotate_transform);
[email protected]94f206c12012-08-25 00:09:142148
[email protected]aa043632013-03-25 03:39:422149 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402150 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422151 InitializeRendererAndDrawFrame();
[email protected]94f206c12012-08-25 00:09:142152
[email protected]aa043632013-03-25 03:39:422153 // Scroll to the right in screen coordinates with a gesture.
2154 gfx::Vector2d gesture_scroll_delta(10, 0);
[email protected]5ff3c9782013-04-29 17:35:122155 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422156 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122157 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422158 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2159 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142160
[email protected]aa043632013-03-25 03:39:422161 // The layer should have scrolled down in its local coordinates.
2162 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
2163 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292164 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422165 gfx::Vector2d(0, gesture_scroll_delta.x()));
[email protected]94f206c12012-08-25 00:09:142166
[email protected]aa043632013-03-25 03:39:422167 // Reset and scroll down with the wheel.
[email protected]35a99a12013-05-09 23:52:292168 scroll_layer->SetScrollDelta(gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:422169 gfx::Vector2d wheel_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122170 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422171 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122172 InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422173 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
2174 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142175
[email protected]aa043632013-03-25 03:39:422176 // The layer should have scrolled down in its local coordinates.
2177 scroll_info = host_impl_->ProcessScrollDeltas();
2178 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292179 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422180 wheel_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142181}
2182
[email protected]aa043632013-03-25 03:39:422183TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
[email protected]35a99a12013-05-09 23:52:292184 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
2185 int child_layer_id = 4;
[email protected]aa043632013-03-25 03:39:422186 float child_layer_angle = -20.f;
[email protected]94f206c12012-08-25 00:09:142187
[email protected]aa043632013-03-25 03:39:422188 // Create a child layer that is rotated to a non-axis-aligned angle.
2189 scoped_ptr<LayerImpl> child = CreateScrollableLayer(
2190 child_layer_id,
[email protected]35a99a12013-05-09 23:52:292191 scroll_layer->content_bounds());
[email protected]aa043632013-03-25 03:39:422192 gfx::Transform rotate_transform;
2193 rotate_transform.Translate(-50.0, -50.0);
2194 rotate_transform.Rotate(child_layer_angle);
2195 rotate_transform.Translate(50.0, 50.0);
2196 child->SetTransform(rotate_transform);
[email protected]94f206c12012-08-25 00:09:142197
[email protected]aa043632013-03-25 03:39:422198 // Only allow vertical scrolling.
2199 child->SetMaxScrollOffset(gfx::Vector2d(0, child->content_bounds().height()));
[email protected]35a99a12013-05-09 23:52:292200 scroll_layer->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:142201
[email protected]aa043632013-03-25 03:39:422202 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402203 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422204 InitializeRendererAndDrawFrame();
2205 {
[email protected]94f206c12012-08-25 00:09:142206 // Scroll down in screen coordinates with a gesture.
[email protected]aa043632013-03-25 03:39:422207 gfx::Vector2d gesture_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122208 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422209 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122210 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422211 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2212 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142213
[email protected]aa043632013-03-25 03:39:422214 // The child layer should have scrolled down in its local coordinates an
2215 // amount proportional to the angle between it and the input scroll delta.
2216 gfx::Vector2d expected_scroll_delta(
2217 0,
2218 gesture_scroll_delta.y() *
2219 std::cos(MathUtil::Deg2Rad(child_layer_angle)));
2220 scoped_ptr<ScrollAndScaleSet> scroll_info =
2221 host_impl_->ProcessScrollDeltas();
2222 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142223
[email protected]35a99a12013-05-09 23:52:292224 // The root scroll layer should not have scrolled, because the input delta
2225 // was close to the layer's axis of movement.
[email protected]aa043632013-03-25 03:39:422226 EXPECT_EQ(scroll_info->scrolls.size(), 1u);
2227 }
2228 {
2229 // Now reset and scroll the same amount horizontally.
[email protected]35a99a12013-05-09 23:52:292230 scroll_layer->children()[1]->SetScrollDelta(
[email protected]aa043632013-03-25 03:39:422231 gfx::Vector2dF());
2232 gfx::Vector2d gesture_scroll_delta(10, 0);
[email protected]5ff3c9782013-04-29 17:35:122233 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]aa043632013-03-25 03:39:422234 host_impl_->ScrollBegin(gfx::Point(),
[email protected]5ff3c9782013-04-29 17:35:122235 InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422236 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
2237 host_impl_->ScrollEnd();
[email protected]94f206c12012-08-25 00:09:142238
[email protected]aa043632013-03-25 03:39:422239 // The child layer should have scrolled down in its local coordinates an
2240 // amount proportional to the angle between it and the input scroll delta.
2241 gfx::Vector2d expected_scroll_delta(
2242 0,
2243 -gesture_scroll_delta.x() *
2244 std::sin(MathUtil::Deg2Rad(child_layer_angle)));
2245 scoped_ptr<ScrollAndScaleSet> scroll_info =
2246 host_impl_->ProcessScrollDeltas();
2247 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
2248
[email protected]35a99a12013-05-09 23:52:292249 // The root scroll layer should have scrolled more, since the input scroll
2250 // delta was mostly orthogonal to the child layer's vertical scroll axis.
[email protected]aa043632013-03-25 03:39:422251 gfx::Vector2d expected_root_scroll_delta(
2252 gesture_scroll_delta.x() *
2253 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2),
2254 0);
2255 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292256 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422257 expected_root_scroll_delta);
2258 }
2259}
2260
2261TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
[email protected]35a99a12013-05-09 23:52:292262 LayerImpl* scroll_layer =
2263 SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]aa043632013-03-25 03:39:422264
2265 // Scale the layer to twice its normal size.
2266 int scale = 2;
2267 gfx::Transform scale_transform;
2268 scale_transform.Scale(scale, scale);
[email protected]35a99a12013-05-09 23:52:292269 scroll_layer->SetTransform(scale_transform);
[email protected]aa043632013-03-25 03:39:422270
2271 gfx::Size surface_size(50, 50);
[email protected]18ce59702013-04-09 04:58:402272 host_impl_->SetViewportSize(surface_size);
[email protected]aa043632013-03-25 03:39:422273 InitializeRendererAndDrawFrame();
2274
2275 // Scroll down in screen coordinates with a gesture.
2276 gfx::Vector2d scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122277 EXPECT_EQ(InputHandler::ScrollStarted,
2278 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
[email protected]aa043632013-03-25 03:39:422279 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2280 host_impl_->ScrollEnd();
2281
2282 // The layer should have scrolled down in its local coordinates, but half the
2283 // amount.
2284 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
2285 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292286 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422287 gfx::Vector2d(0, scroll_delta.y() / scale));
2288
2289 // Reset and scroll down with the wheel.
[email protected]35a99a12013-05-09 23:52:292290 scroll_layer->SetScrollDelta(gfx::Vector2dF());
[email protected]aa043632013-03-25 03:39:422291 gfx::Vector2d wheel_scroll_delta(0, 10);
[email protected]5ff3c9782013-04-29 17:35:122292 EXPECT_EQ(InputHandler::ScrollStarted,
2293 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
[email protected]aa043632013-03-25 03:39:422294 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
2295 host_impl_->ScrollEnd();
2296
2297 // The scale should not have been applied to the scroll delta.
2298 scroll_info = host_impl_->ProcessScrollDeltas();
2299 ExpectContains(*scroll_info.get(),
[email protected]35a99a12013-05-09 23:52:292300 scroll_layer->id(),
[email protected]aa043632013-03-25 03:39:422301 wheel_scroll_delta);
[email protected]94f206c12012-08-25 00:09:142302}
2303
[email protected]0a0d1422013-05-02 09:14:522304class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
2305 public:
2306 TestScrollOffsetDelegate() {}
2307 virtual ~TestScrollOffsetDelegate() {}
2308
2309 virtual void SetTotalScrollOffset(gfx::Vector2dF new_value) OVERRIDE {
2310 last_set_scroll_offset_ = new_value;
2311 }
2312
2313 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
2314 return getter_return_value_;
2315 }
2316
2317 gfx::Vector2dF last_set_scroll_offset() {
2318 return last_set_scroll_offset_;
2319 }
2320
2321 void set_getter_return_value(gfx::Vector2dF value) {
2322 getter_return_value_ = value;
2323 }
2324
2325 private:
2326 gfx::Vector2dF last_set_scroll_offset_;
2327 gfx::Vector2dF getter_return_value_;
2328};
2329
2330TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
2331 TestScrollOffsetDelegate scroll_delegate;
[email protected]35a99a12013-05-09 23:52:292332 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
[email protected]0a0d1422013-05-02 09:14:522333
2334 // Setting the delegate results in the current scroll offset being set.
[email protected]35a99a12013-05-09 23:52:292335 gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
2336 scroll_layer->SetScrollOffset(gfx::Vector2d());
2337 scroll_layer->SetScrollDelta(initial_scroll_delta);
[email protected]0a0d1422013-05-02 09:14:522338 host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
[email protected]35a99a12013-05-09 23:52:292339 EXPECT_EQ(initial_scroll_delta.ToString(),
2340 scroll_delegate.last_set_scroll_offset().ToString());
[email protected]0a0d1422013-05-02 09:14:522341
2342 // Scrolling should be relative to the offset as returned by the delegate.
[email protected]35a99a12013-05-09 23:52:292343 gfx::Vector2dF scroll_delta(0.f, 10.f);
2344 gfx::Vector2dF current_offset(7.f, 8.f);
[email protected]0a0d1422013-05-02 09:14:522345
2346 scroll_delegate.set_getter_return_value(current_offset);
2347 EXPECT_EQ(InputHandler::ScrollStarted,
2348 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2349
2350 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2351 EXPECT_EQ(current_offset + scroll_delta,
2352 scroll_delegate.last_set_scroll_offset());
2353
[email protected]35a99a12013-05-09 23:52:292354 current_offset = gfx::Vector2dF(42.f, 41.f);
[email protected]0a0d1422013-05-02 09:14:522355 scroll_delegate.set_getter_return_value(current_offset);
2356 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2357 EXPECT_EQ(current_offset + scroll_delta,
2358 scroll_delegate.last_set_scroll_offset());
2359 host_impl_->ScrollEnd();
2360
2361 // Un-setting the delegate should propagate the delegate's current offset to
2362 // the root scrollable layer.
[email protected]35a99a12013-05-09 23:52:292363 current_offset = gfx::Vector2dF(13.f, 12.f);
[email protected]0a0d1422013-05-02 09:14:522364 scroll_delegate.set_getter_return_value(current_offset);
2365 host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
2366
[email protected]35a99a12013-05-09 23:52:292367 EXPECT_EQ(current_offset.ToString(),
2368 scroll_layer->TotalScrollOffset().ToString());
[email protected]0a0d1422013-05-02 09:14:522369}
2370
[email protected]a2b5ded2013-05-20 21:32:532371TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
2372 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2373 host_impl_->SetViewportSize(gfx::Size(50, 50));
2374 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
2375 InitializeRendererAndDrawFrame();
2376 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2377 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2378
2379 // In-bounds scrolling does not affect overscroll.
2380 EXPECT_EQ(InputHandler::ScrollStarted,
2381 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2382 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2383 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2384 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2385
2386 // Overscroll events are reflected immediately.
2387 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
2388 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
2389 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2390
[email protected]2bd503f2013-07-23 05:35:292391 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
[email protected]a2b5ded2013-05-20 21:32:532392 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
2393 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
2394 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
2395 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
[email protected]2bd503f2013-07-23 05:35:292396 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
2397 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
2398 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
2399 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll());
2400 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
2401 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll());
2402 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
2403 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
[email protected]a2b5ded2013-05-20 21:32:532404
2405 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
2406 // as no scroll occurs.
2407 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2408 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll());
2409 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2410 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll());
2411 // Overscroll resets on valid scroll.
2412 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2413 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
2414 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2415 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
2416 host_impl_->ScrollEnd();
2417
2418 EXPECT_EQ(InputHandler::ScrollStarted,
2419 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2420 // Fling velocity is reflected immediately.
2421 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0));
2422 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2423 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
2424 EXPECT_EQ(gfx::Vector2dF(0, -20), host_impl_->accumulated_root_overscroll());
2425 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2426}
2427
2428
2429TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
2430 // Scroll child layers beyond their maximum scroll range and make sure root
2431 // overscroll does not accumulate.
2432 gfx::Size surface_size(10, 10);
2433 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size);
2434
2435 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size);
2436 grand_child->SetScrollOffset(gfx::Vector2d(0, 2));
2437
2438 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size);
2439 child->SetScrollOffset(gfx::Vector2d(0, 3));
2440 child->AddChild(grand_child.Pass());
2441
2442 root->AddChild(child.Pass());
2443 host_impl_->active_tree()->SetRootLayer(root.Pass());
2444 host_impl_->active_tree()->DidBecomeActive();
2445 host_impl_->SetViewportSize(surface_size);
2446 InitializeRendererAndDrawFrame();
2447 {
2448 gfx::Vector2d scroll_delta(0, -10);
2449 EXPECT_EQ(InputHandler::ScrollStarted,
[email protected]4ec78f82013-07-11 18:45:472450 host_impl_->ScrollBegin(gfx::Point(),
[email protected]a2b5ded2013-05-20 21:32:532451 InputHandler::NonBubblingGesture));
2452 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2453 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2454 host_impl_->ScrollEnd();
2455
2456 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
2457 LayerImpl* grand_child = child->children()[0];
2458
2459 // The next time we scroll we should only scroll the parent, but overscroll
2460 // should still not reach the root layer.
2461 scroll_delta = gfx::Vector2d(0, -30);
2462 EXPECT_EQ(InputHandler::ScrollStarted,
2463 host_impl_->ScrollBegin(gfx::Point(5, 5),
2464 InputHandler::NonBubblingGesture));
2465 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2466 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2467 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2468 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
2469 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2470 host_impl_->ScrollEnd();
2471
2472 // After scrolling the parent, another scroll on the opposite direction
2473 // should scroll the child, resetting the fling velocity.
2474 scroll_delta = gfx::Vector2d(0, 70);
2475 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0));
2476 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity());
2477 EXPECT_EQ(InputHandler::ScrollStarted,
2478 host_impl_->ScrollBegin(gfx::Point(5, 5),
2479 InputHandler::NonBubblingGesture));
2480 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2481 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2482 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
2483 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2484 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity());
2485 host_impl_->ScrollEnd();
2486 }
2487}
2488
2489TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
2490 // When we try to scroll a non-scrollable child layer, the scroll delta
2491 // should be applied to one of its ancestors if possible. Overscroll should
2492 // be reflected only when it has bubbled up to the root scrolling layer.
2493 gfx::Size surface_size(10, 10);
2494 gfx::Size content_size(20, 20);
2495 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size);
2496 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size);
2497
2498 child->SetScrollable(false);
2499 root->AddChild(child.Pass());
2500
2501 host_impl_->SetViewportSize(surface_size);
2502 host_impl_->active_tree()->SetRootLayer(root.Pass());
2503 host_impl_->active_tree()->DidBecomeActive();
2504 InitializeRendererAndDrawFrame();
2505 {
2506 gfx::Vector2d scroll_delta(0, 8);
2507 EXPECT_EQ(InputHandler::ScrollStarted,
2508 host_impl_->ScrollBegin(gfx::Point(5, 5),
2509 InputHandler::Wheel));
2510 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2511 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
2512 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2513 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
2514 host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2515 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
2516 host_impl_->ScrollEnd();
2517 }
2518}
2519
2520
[email protected]c8756fbe2013-02-12 01:53:492521class BlendStateTrackerContext: public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:422522 public:
2523 BlendStateTrackerContext() : blend_(false) {}
[email protected]94f206c12012-08-25 00:09:142524
[email protected]aa043632013-03-25 03:39:422525 virtual void enable(WebKit::WGC3Denum cap) OVERRIDE {
2526 if (cap == GL_BLEND)
2527 blend_ = true;
2528 }
[email protected]94f206c12012-08-25 00:09:142529
[email protected]aa043632013-03-25 03:39:422530 virtual void disable(WebKit::WGC3Denum cap) OVERRIDE {
2531 if (cap == GL_BLEND)
2532 blend_ = false;
2533 }
[email protected]94f206c12012-08-25 00:09:142534
[email protected]aa043632013-03-25 03:39:422535 bool blend() const { return blend_; }
[email protected]94f206c12012-08-25 00:09:142536
[email protected]aa043632013-03-25 03:39:422537 private:
2538 bool blend_;
[email protected]94f206c12012-08-25 00:09:142539};
2540
[email protected]96baf3e2012-10-22 23:09:552541class BlendStateCheckLayer : public LayerImpl {
[email protected]aa043632013-03-25 03:39:422542 public:
2543 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
2544 int id,
2545 ResourceProvider* resource_provider) {
2546 return scoped_ptr<LayerImpl>(new BlendStateCheckLayer(tree_impl,
2547 id,
2548 resource_provider));
2549 }
[email protected]94f206c12012-08-25 00:09:142550
[email protected]aa043632013-03-25 03:39:422551 virtual void AppendQuads(QuadSink* quad_sink,
2552 AppendQuadsData* append_quads_data) OVERRIDE {
2553 quads_appended_ = true;
[email protected]94f206c12012-08-25 00:09:142554
[email protected]aa043632013-03-25 03:39:422555 gfx::Rect opaque_rect;
2556 if (contents_opaque())
2557 opaque_rect = quad_rect_;
2558 else
2559 opaque_rect = opaque_content_rect_;
[email protected]94f206c12012-08-25 00:09:142560
[email protected]aa043632013-03-25 03:39:422561 SharedQuadState* shared_quad_state =
2562 quad_sink->UseSharedQuadState(CreateSharedQuadState());
2563 scoped_ptr<TileDrawQuad> test_blending_draw_quad = TileDrawQuad::Create();
2564 test_blending_draw_quad->SetNew(shared_quad_state,
2565 quad_rect_,
2566 opaque_rect,
2567 resource_id_,
2568 gfx::RectF(0.f, 0.f, 1.f, 1.f),
2569 gfx::Size(1, 1),
2570 false);
2571 test_blending_draw_quad->visible_rect = quad_visible_rect_;
2572 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
2573 EXPECT_EQ(has_render_surface_, !!render_surface());
2574 quad_sink->Append(test_blending_draw_quad.PassAs<DrawQuad>(),
2575 append_quads_data);
2576 }
[email protected]94f206c12012-08-25 00:09:142577
[email protected]aa043632013-03-25 03:39:422578 void SetExpectation(bool blend, bool has_render_surface) {
2579 blend_ = blend;
2580 has_render_surface_ = has_render_surface;
2581 quads_appended_ = false;
2582 }
[email protected]94f206c12012-08-25 00:09:142583
[email protected]aa043632013-03-25 03:39:422584 bool quads_appended() const { return quads_appended_; }
[email protected]94f206c12012-08-25 00:09:142585
[email protected]aa043632013-03-25 03:39:422586 void SetQuadRect(gfx::Rect rect) { quad_rect_ = rect; }
2587 void SetQuadVisibleRect(gfx::Rect rect) { quad_visible_rect_ = rect; }
2588 void SetOpaqueContentRect(gfx::Rect rect) { opaque_content_rect_ = rect; }
[email protected]94f206c12012-08-25 00:09:142589
[email protected]aa043632013-03-25 03:39:422590 private:
2591 BlendStateCheckLayer(LayerTreeImpl* tree_impl,
2592 int id,
2593 ResourceProvider* resource_provider)
2594 : LayerImpl(tree_impl, id),
2595 blend_(false),
2596 has_render_surface_(false),
2597 quads_appended_(false),
2598 quad_rect_(5, 5, 5, 5),
2599 quad_visible_rect_(5, 5, 5, 5),
2600 resource_id_(resource_provider->CreateResource(
2601 gfx::Size(1, 1),
2602 GL_RGBA,
2603 ResourceProvider::TextureUsageAny)) {
2604 resource_provider->AllocateForTesting(resource_id_);
2605 SetAnchorPoint(gfx::PointF());
2606 SetBounds(gfx::Size(10, 10));
2607 SetContentBounds(gfx::Size(10, 10));
2608 SetDrawsContent(true);
2609 }
[email protected]94f206c12012-08-25 00:09:142610
[email protected]aa043632013-03-25 03:39:422611 bool blend_;
2612 bool has_render_surface_;
2613 bool quads_appended_;
2614 gfx::Rect quad_rect_;
2615 gfx::Rect opaque_content_rect_;
2616 gfx::Rect quad_visible_rect_;
2617 ResourceProvider::ResourceId resource_id_;
[email protected]94f206c12012-08-25 00:09:142618};
2619
[email protected]aa043632013-03-25 03:39:422620TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
2621 {
2622 scoped_ptr<LayerImpl> root =
2623 LayerImpl::Create(host_impl_->active_tree(), 1);
2624 root->SetAnchorPoint(gfx::PointF());
2625 root->SetBounds(gfx::Size(10, 10));
2626 root->SetContentBounds(root->bounds());
2627 root->SetDrawsContent(false);
2628 host_impl_->active_tree()->SetRootLayer(root.Pass());
2629 }
2630 LayerImpl* root = host_impl_->active_tree()->root_layer();
[email protected]94f206c12012-08-25 00:09:142631
[email protected]aa043632013-03-25 03:39:422632 root->AddChild(
2633 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2634 2,
2635 host_impl_->resource_provider()));
2636 BlendStateCheckLayer* layer1 =
2637 static_cast<BlendStateCheckLayer*>(root->children()[0]);
2638 layer1->SetPosition(gfx::PointF(2.f, 2.f));
[email protected]94f206c12012-08-25 00:09:142639
[email protected]aa043632013-03-25 03:39:422640 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:142641
[email protected]aa043632013-03-25 03:39:422642 // Opaque layer, drawn without blending.
2643 layer1->SetContentsOpaque(true);
2644 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202645 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2646 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422647 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2648 EXPECT_TRUE(layer1->quads_appended());
2649 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142650
[email protected]aa043632013-03-25 03:39:422651 // Layer with translucent content and painting, so drawn with blending.
2652 layer1->SetContentsOpaque(false);
2653 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202654 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2655 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422656 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2657 EXPECT_TRUE(layer1->quads_appended());
2658 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142659
[email protected]aa043632013-03-25 03:39:422660 // Layer with translucent opacity, drawn with blending.
2661 layer1->SetContentsOpaque(true);
2662 layer1->SetOpacity(0.5f);
2663 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202664 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2665 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422666 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2667 EXPECT_TRUE(layer1->quads_appended());
2668 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142669
[email protected]aa043632013-03-25 03:39:422670 // Layer with translucent opacity and painting, drawn with blending.
2671 layer1->SetContentsOpaque(true);
2672 layer1->SetOpacity(0.5f);
2673 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202674 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2675 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422676 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2677 EXPECT_TRUE(layer1->quads_appended());
2678 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142679
[email protected]aa043632013-03-25 03:39:422680 layer1->AddChild(
2681 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2682 3,
2683 host_impl_->resource_provider()));
2684 BlendStateCheckLayer* layer2 =
2685 static_cast<BlendStateCheckLayer*>(layer1->children()[0]);
2686 layer2->SetPosition(gfx::PointF(4.f, 4.f));
[email protected]94f206c12012-08-25 00:09:142687
[email protected]aa043632013-03-25 03:39:422688 // 2 opaque layers, drawn without blending.
2689 layer1->SetContentsOpaque(true);
2690 layer1->SetOpacity(1.f);
2691 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202692 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422693 layer2->SetContentsOpaque(true);
2694 layer2->SetOpacity(1.f);
2695 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202696 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2697 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422698 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2699 EXPECT_TRUE(layer1->quads_appended());
2700 EXPECT_TRUE(layer2->quads_appended());
2701 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142702
[email protected]aa043632013-03-25 03:39:422703 // Parent layer with translucent content, drawn with blending.
2704 // Child layer with opaque content, drawn without blending.
2705 layer1->SetContentsOpaque(false);
2706 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202707 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422708 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202709 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2710 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422711 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2712 EXPECT_TRUE(layer1->quads_appended());
2713 EXPECT_TRUE(layer2->quads_appended());
2714 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142715
[email protected]aa043632013-03-25 03:39:422716 // Parent layer with translucent content but opaque painting, drawn without
2717 // blending.
2718 // Child layer with opaque content, drawn without blending.
2719 layer1->SetContentsOpaque(true);
2720 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202721 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422722 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202723 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2724 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422725 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2726 EXPECT_TRUE(layer1->quads_appended());
2727 EXPECT_TRUE(layer2->quads_appended());
2728 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142729
[email protected]aa043632013-03-25 03:39:422730 // Parent layer with translucent opacity and opaque content. Since it has a
2731 // drawing child, it's drawn to a render surface which carries the opacity,
2732 // so it's itself drawn without blending.
2733 // Child layer with opaque content, drawn without blending (parent surface
2734 // carries the inherited opacity).
2735 layer1->SetContentsOpaque(true);
2736 layer1->SetOpacity(0.5f);
2737 layer1->SetExpectation(false, true);
[email protected]e0341352013-04-06 05:01:202738 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422739 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202740 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2741 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422742 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2743 EXPECT_TRUE(layer1->quads_appended());
2744 EXPECT_TRUE(layer2->quads_appended());
2745 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142746
[email protected]aa043632013-03-25 03:39:422747 // Draw again, but with child non-opaque, to make sure
2748 // layer1 not culled.
2749 layer1->SetContentsOpaque(true);
2750 layer1->SetOpacity(1.f);
2751 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202752 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422753 layer2->SetContentsOpaque(true);
2754 layer2->SetOpacity(0.5f);
2755 layer2->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202756 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2757 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422758 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2759 EXPECT_TRUE(layer1->quads_appended());
2760 EXPECT_TRUE(layer2->quads_appended());
2761 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142762
[email protected]aa043632013-03-25 03:39:422763 // A second way of making the child non-opaque.
2764 layer1->SetContentsOpaque(true);
2765 layer1->SetOpacity(1.f);
2766 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202767 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422768 layer2->SetContentsOpaque(false);
2769 layer2->SetOpacity(1.f);
2770 layer2->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202771 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2772 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422773 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2774 EXPECT_TRUE(layer1->quads_appended());
2775 EXPECT_TRUE(layer2->quads_appended());
2776 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142777
[email protected]aa043632013-03-25 03:39:422778 // And when the layer says its not opaque but is painted opaque, it is not
2779 // blended.
2780 layer1->SetContentsOpaque(true);
2781 layer1->SetOpacity(1.f);
2782 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202783 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
[email protected]aa043632013-03-25 03:39:422784 layer2->SetContentsOpaque(true);
2785 layer2->SetOpacity(1.f);
2786 layer2->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202787 layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
2788 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422789 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2790 EXPECT_TRUE(layer1->quads_appended());
2791 EXPECT_TRUE(layer2->quads_appended());
2792 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142793
[email protected]aa043632013-03-25 03:39:422794 // Layer with partially opaque contents, drawn with blending.
2795 layer1->SetContentsOpaque(false);
2796 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
2797 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
2798 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
2799 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202800 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2801 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422802 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2803 EXPECT_TRUE(layer1->quads_appended());
2804 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142805
[email protected]aa043632013-03-25 03:39:422806 // Layer with partially opaque contents partially culled, drawn with blending.
2807 layer1->SetContentsOpaque(false);
2808 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
2809 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
2810 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
2811 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202812 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2813 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422814 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2815 EXPECT_TRUE(layer1->quads_appended());
2816 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142817
[email protected]aa043632013-03-25 03:39:422818 // Layer with partially opaque contents culled, drawn with blending.
2819 layer1->SetContentsOpaque(false);
2820 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
2821 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
2822 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
2823 layer1->SetExpectation(true, false);
[email protected]e0341352013-04-06 05:01:202824 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2825 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422826 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2827 EXPECT_TRUE(layer1->quads_appended());
2828 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142829
[email protected]aa043632013-03-25 03:39:422830 // Layer with partially opaque contents and translucent contents culled, drawn
2831 // without blending.
2832 layer1->SetContentsOpaque(false);
2833 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
2834 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
2835 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
2836 layer1->SetExpectation(false, false);
[email protected]e0341352013-04-06 05:01:202837 layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
2838 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422839 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
2840 EXPECT_TRUE(layer1->quads_appended());
2841 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:142842}
2843
[email protected]6133cc232013-07-30 18:47:072844class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
2845 public:
[email protected]9f4f6a32013-09-04 21:35:122846 LayerTreeHostImplViewportCoveredTest() :
2847 gutter_quad_material_(DrawQuad::SOLID_COLOR),
2848 child_(NULL),
2849 did_activate_pending_tree_(false) {}
2850
[email protected]6133cc232013-07-30 18:47:072851 void CreateLayerTreeHostImpl(bool always_draw) {
2852 LayerTreeSettings settings;
2853 settings.minimum_occlusion_tracking_size = gfx::Size();
2854 settings.impl_side_painting = true;
2855 host_impl_ = LayerTreeHostImpl::Create(
2856 settings, this, &proxy_, &stats_instrumentation_);
[email protected]0634cdd42013-08-16 00:46:092857
2858 scoped_ptr<FakeOutputSurface> output_surface;
2859 if (always_draw)
2860 output_surface = FakeOutputSurface::CreateAlwaysDrawAndSwap3d().Pass();
2861 else
2862 output_surface = FakeOutputSurface::Create3d().Pass();
2863
2864 host_impl_->InitializeRenderer(output_surface.PassAs<OutputSurface>());
[email protected]6133cc232013-07-30 18:47:072865 viewport_size_ = gfx::Size(1000, 1000);
2866 }
[email protected]94f206c12012-08-25 00:09:142867
[email protected]6133cc232013-07-30 18:47:072868 void SetupActiveTreeLayers() {
2869 host_impl_->active_tree()->set_background_color(SK_ColorGRAY);
2870 host_impl_->active_tree()->SetRootLayer(
2871 LayerImpl::Create(host_impl_->active_tree(), 1));
2872 host_impl_->active_tree()->root_layer()->AddChild(
2873 BlendStateCheckLayer::Create(host_impl_->active_tree(),
2874 2,
2875 host_impl_->resource_provider()));
2876 child_ = static_cast<BlendStateCheckLayer*>(
2877 host_impl_->active_tree()->root_layer()->children()[0]);
2878 child_->SetExpectation(false, false);
2879 child_->SetContentsOpaque(true);
2880 }
[email protected]94f206c12012-08-25 00:09:142881
[email protected]6133cc232013-07-30 18:47:072882 // Expect no gutter rects.
2883 void TestLayerCoversFullViewport() {
2884 gfx::Rect layer_rect(viewport_size_);
2885 child_->SetPosition(layer_rect.origin());
2886 child_->SetBounds(layer_rect.size());
2887 child_->SetContentBounds(layer_rect.size());
2888 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
2889 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:142890
[email protected]aa043632013-03-25 03:39:422891 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:202892 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422893 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:142894
[email protected]9f4f6a32013-09-04 21:35:122895 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:422896 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:122897 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:142898
[email protected]9f4f6a32013-09-04 21:35:122899 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:422900 host_impl_->DidDrawAllLayers(frame);
2901 }
[email protected]94f206c12012-08-25 00:09:142902
[email protected]6133cc232013-07-30 18:47:072903 // Expect fullscreen gutter rect.
2904 void TestEmptyLayer() {
[email protected]aa043632013-03-25 03:39:422905 gfx::Rect layer_rect(0, 0, 0, 0);
[email protected]6133cc232013-07-30 18:47:072906 child_->SetPosition(layer_rect.origin());
2907 child_->SetBounds(layer_rect.size());
2908 child_->SetContentBounds(layer_rect.size());
2909 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
2910 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:142911
[email protected]aa043632013-03-25 03:39:422912 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:202913 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422914 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:142915
[email protected]9f4f6a32013-09-04 21:35:122916 EXPECT_EQ(1u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:422917 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:122918 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:142919
[email protected]9f4f6a32013-09-04 21:35:122920 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:422921 host_impl_->DidDrawAllLayers(frame);
2922 }
[email protected]94f206c12012-08-25 00:09:142923
[email protected]6133cc232013-07-30 18:47:072924 // Expect four surrounding gutter rects.
2925 void TestLayerInMiddleOfViewport() {
[email protected]aa043632013-03-25 03:39:422926 gfx::Rect layer_rect(500, 500, 200, 200);
[email protected]6133cc232013-07-30 18:47:072927 child_->SetPosition(layer_rect.origin());
2928 child_->SetBounds(layer_rect.size());
2929 child_->SetContentBounds(layer_rect.size());
2930 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
2931 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
[email protected]94f206c12012-08-25 00:09:142932
[email protected]aa043632013-03-25 03:39:422933 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:202934 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:422935 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:142936
[email protected]9f4f6a32013-09-04 21:35:122937 EXPECT_EQ(4u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]aa043632013-03-25 03:39:422938 EXPECT_EQ(5u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:122939 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]94f206c12012-08-25 00:09:142940
[email protected]9f4f6a32013-09-04 21:35:122941 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
[email protected]aa043632013-03-25 03:39:422942 host_impl_->DidDrawAllLayers(frame);
2943 }
[email protected]6133cc232013-07-30 18:47:072944
2945 // Expect no gutter rects.
2946 void TestLayerIsLargerThanViewport() {
2947 gfx::Rect layer_rect(viewport_size_.width() + 10,
2948 viewport_size_.height() + 10);
2949 child_->SetPosition(layer_rect.origin());
2950 child_->SetBounds(layer_rect.size());
2951 child_->SetContentBounds(layer_rect.size());
2952 child_->SetQuadRect(gfx::Rect(layer_rect.size()));
2953 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
2954
2955 LayerTreeHostImpl::FrameData frame;
2956 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
2957 ASSERT_EQ(1u, frame.render_passes.size());
2958
[email protected]9f4f6a32013-09-04 21:35:122959 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
[email protected]6133cc232013-07-30 18:47:072960 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
[email protected]9f4f6a32013-09-04 21:35:122961 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
[email protected]6133cc232013-07-30 18:47:072962
2963 host_impl_->DidDrawAllLayers(frame);
2964 }
2965
2966 virtual void DidActivatePendingTree() OVERRIDE {
2967 did_activate_pending_tree_ = true;
2968 }
2969
[email protected]9f4f6a32013-09-04 21:35:122970 void set_gutter_quad_material(DrawQuad::Material material) {
2971 gutter_quad_material_ = material;
2972 }
2973 void set_gutter_texture_size(gfx::Size gutter_texture_size) {
2974 gutter_texture_size_ = gutter_texture_size;
2975 }
2976
[email protected]6133cc232013-07-30 18:47:072977 protected:
[email protected]9f4f6a32013-09-04 21:35:122978 size_t CountGutterQuads(const QuadList& quad_list) {
2979 size_t num_gutter_quads = 0;
2980 for (size_t i = 0; i < quad_list.size(); ++i) {
2981 num_gutter_quads += (quad_list[i]->material ==
2982 gutter_quad_material_) ? 1 : 0;
2983 }
2984 return num_gutter_quads;
2985 }
2986
2987 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) {
2988 LayerTestCommon::VerifyQuadsExactlyCoverRect(
2989 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_)));
2990 }
2991
2992 // Make sure that the texture coordinates match their expectations.
2993 void ValidateTextureDrawQuads(const QuadList& quad_list) {
2994 for (size_t i = 0; i < quad_list.size(); ++i) {
2995 if (quad_list[i]->material != DrawQuad::TEXTURE_CONTENT)
2996 continue;
2997 const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(quad_list[i]);
2998 gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize(
2999 gutter_texture_size_, host_impl_->device_scale_factor());
3000 EXPECT_EQ(quad->uv_top_left.x(),
3001 quad->rect.x() / gutter_texture_size_pixels.width());
3002 EXPECT_EQ(quad->uv_top_left.y(),
3003 quad->rect.y() / gutter_texture_size_pixels.height());
3004 EXPECT_EQ(quad->uv_bottom_right.x(),
3005 quad->rect.right() / gutter_texture_size_pixels.width());
3006 EXPECT_EQ(quad->uv_bottom_right.y(),
3007 quad->rect.bottom() / gutter_texture_size_pixels.height());
3008 }
3009 }
3010
3011 gfx::Size DipSizeToPixelSize(gfx::Size size) {
3012 return gfx::ToRoundedSize(
3013 gfx::ScaleSize(size, host_impl_->device_scale_factor()));
3014 }
3015
3016 DrawQuad::Material gutter_quad_material_;
3017 gfx::Size gutter_texture_size_;
[email protected]6133cc232013-07-30 18:47:073018 gfx::Size viewport_size_;
3019 BlendStateCheckLayer* child_;
3020 bool did_activate_pending_tree_;
3021};
3022
3023TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) {
3024 bool always_draw = false;
3025 CreateLayerTreeHostImpl(always_draw);
3026
[email protected]9f4f6a32013-09-04 21:35:123027 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073028 SetupActiveTreeLayers();
3029 TestLayerCoversFullViewport();
3030 TestEmptyLayer();
3031 TestLayerInMiddleOfViewport();
3032 TestLayerIsLargerThanViewport();
[email protected]94f206c12012-08-25 00:09:143033}
3034
[email protected]9f4f6a32013-09-04 21:35:123035TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
3036 bool always_draw = false;
3037 CreateLayerTreeHostImpl(always_draw);
3038
3039 host_impl_->SetDeviceScaleFactor(2.f);
3040 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3041 SetupActiveTreeLayers();
3042 TestLayerCoversFullViewport();
3043 TestEmptyLayer();
3044 TestLayerInMiddleOfViewport();
3045 TestLayerIsLargerThanViewport();
3046}
3047
3048TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
3049 bool always_draw = false;
3050 CreateLayerTreeHostImpl(always_draw);
3051
3052 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3053 SetupActiveTreeLayers();
3054
3055 // Specify an overhang bitmap to use.
3056 scoped_refptr<UIResourceBitmap> ui_resource_bitmap(UIResourceBitmap::Create(
3057 new uint8_t[4], UIResourceBitmap::RGBA8, gfx::Size(1, 1)));
3058 UIResourceId ui_resource_id = 12345;
3059 host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
3060 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
3061 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT);
3062 set_gutter_texture_size(gfx::Size(32, 32));
3063
3064 TestLayerCoversFullViewport();
3065 TestEmptyLayer();
3066 TestLayerInMiddleOfViewport();
3067 TestLayerIsLargerThanViewport();
3068
3069 // Change the resource size.
3070 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16));
3071 set_gutter_texture_size(gfx::Size(128, 16));
3072
3073 TestLayerCoversFullViewport();
3074 TestEmptyLayer();
3075 TestLayerInMiddleOfViewport();
3076 TestLayerIsLargerThanViewport();
3077
3078 // Change the device scale factor
3079 host_impl_->SetDeviceScaleFactor(2.f);
3080 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
3081
3082 TestLayerCoversFullViewport();
3083 TestEmptyLayer();
3084 TestLayerInMiddleOfViewport();
3085 TestLayerIsLargerThanViewport();
3086}
3087
[email protected]6133cc232013-07-30 18:47:073088TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
3089 bool always_draw = true;
3090 CreateLayerTreeHostImpl(always_draw);
3091
3092 // Pending tree to force active_tree size invalid. Not used otherwise.
3093 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:123094 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073095 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
3096
3097 SetupActiveTreeLayers();
3098 TestEmptyLayer();
3099 TestLayerInMiddleOfViewport();
3100 TestLayerIsLargerThanViewport();
3101}
3102
3103TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) {
3104 bool always_draw = true;
3105 CreateLayerTreeHostImpl(always_draw);
3106
3107 // Set larger viewport and activate it to active tree.
3108 host_impl_->CreatePendingTree();
3109 gfx::Size larger_viewport(viewport_size_.width() + 100,
3110 viewport_size_.height() + 100);
[email protected]9f4f6a32013-09-04 21:35:123111 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport));
[email protected]6133cc232013-07-30 18:47:073112 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
[email protected]4f48f6e2013-08-27 06:33:383113 host_impl_->ActivatePendingTree();
[email protected]6133cc232013-07-30 18:47:073114 EXPECT_TRUE(did_activate_pending_tree_);
3115 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid());
3116
3117 // Shrink pending tree viewport without activating.
3118 host_impl_->CreatePendingTree();
[email protected]9f4f6a32013-09-04 21:35:123119 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
[email protected]6133cc232013-07-30 18:47:073120 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
3121
3122 SetupActiveTreeLayers();
3123 TestEmptyLayer();
3124 TestLayerInMiddleOfViewport();
3125 TestLayerIsLargerThanViewport();
3126}
[email protected]94f206c12012-08-25 00:09:143127
[email protected]c8756fbe2013-02-12 01:53:493128class ReshapeTrackerContext: public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423129 public:
[email protected]94c40e6292013-05-24 22:01:503130 ReshapeTrackerContext()
3131 : reshape_called_(false),
3132 last_reshape_width_(-1),
3133 last_reshape_height_(-1),
3134 last_reshape_scale_factor_(-1.f) {
3135 }
[email protected]94f206c12012-08-25 00:09:143136
[email protected]94c40e6292013-05-24 22:01:503137 virtual void reshapeWithScaleFactor(
3138 int width, int height, float scale_factor) OVERRIDE {
[email protected]aa043632013-03-25 03:39:423139 reshape_called_ = true;
[email protected]94c40e6292013-05-24 22:01:503140 last_reshape_width_ = width;
3141 last_reshape_height_ = height;
3142 last_reshape_scale_factor_ = scale_factor;
[email protected]aa043632013-03-25 03:39:423143 }
[email protected]94f206c12012-08-25 00:09:143144
[email protected]aa043632013-03-25 03:39:423145 bool reshape_called() const { return reshape_called_; }
[email protected]94c40e6292013-05-24 22:01:503146 void clear_reshape_called() { reshape_called_ = false; }
3147 int last_reshape_width() { return last_reshape_width_; }
3148 int last_reshape_height() { return last_reshape_height_; }
3149 int last_reshape_scale_factor() { return last_reshape_scale_factor_; }
[email protected]94f206c12012-08-25 00:09:143150
[email protected]aa043632013-03-25 03:39:423151 private:
3152 bool reshape_called_;
[email protected]94c40e6292013-05-24 22:01:503153 int last_reshape_width_;
3154 int last_reshape_height_;
3155 float last_reshape_scale_factor_;
[email protected]94f206c12012-08-25 00:09:143156};
3157
[email protected]96baf3e2012-10-22 23:09:553158class FakeDrawableLayerImpl: public LayerImpl {
[email protected]aa043632013-03-25 03:39:423159 public:
3160 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3161 return scoped_ptr<LayerImpl>(new FakeDrawableLayerImpl(tree_impl, id));
3162 }
3163 protected:
3164 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id)
3165 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:143166};
3167
3168// Only reshape when we know we are going to draw. Otherwise, the reshape
3169// can leave the window at the wrong size if we never draw and the proper
3170// viewport size is never set.
[email protected]aa043632013-03-25 03:39:423171TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
[email protected]0634cdd42013-08-16 00:46:093172 scoped_ptr<ReshapeTrackerContext> owned_reshape_tracker(
3173 new ReshapeTrackerContext);
3174 ReshapeTrackerContext* reshape_tracker = owned_reshape_tracker.get();
3175 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3176 owned_reshape_tracker.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423177 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]94f206c12012-08-25 00:09:143178
[email protected]aa043632013-03-25 03:39:423179 scoped_ptr<LayerImpl> root =
3180 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
3181 root->SetAnchorPoint(gfx::PointF());
3182 root->SetBounds(gfx::Size(10, 10));
[email protected]e0341352013-04-06 05:01:203183 root->SetContentBounds(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423184 root->SetDrawsContent(true);
3185 host_impl_->active_tree()->SetRootLayer(root.Pass());
3186 EXPECT_FALSE(reshape_tracker->reshape_called());
[email protected]94c40e6292013-05-24 22:01:503187 reshape_tracker->clear_reshape_called();
[email protected]94f206c12012-08-25 00:09:143188
[email protected]aa043632013-03-25 03:39:423189 LayerTreeHostImpl::FrameData frame;
[email protected]94c40e6292013-05-24 22:01:503190 host_impl_->SetViewportSize(gfx::Size(10, 10));
3191 host_impl_->SetDeviceScaleFactor(1.f);
[email protected]e0341352013-04-06 05:01:203192 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423193 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3194 EXPECT_TRUE(reshape_tracker->reshape_called());
[email protected]94c40e6292013-05-24 22:01:503195 EXPECT_EQ(reshape_tracker->last_reshape_width(), 10);
3196 EXPECT_EQ(reshape_tracker->last_reshape_height(), 10);
3197 EXPECT_EQ(reshape_tracker->last_reshape_scale_factor(), 1.f);
[email protected]aa043632013-03-25 03:39:423198 host_impl_->DidDrawAllLayers(frame);
[email protected]94c40e6292013-05-24 22:01:503199 reshape_tracker->clear_reshape_called();
3200
3201 host_impl_->SetViewportSize(gfx::Size(20, 30));
3202 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
3203 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3204 EXPECT_TRUE(reshape_tracker->reshape_called());
3205 EXPECT_EQ(reshape_tracker->last_reshape_width(), 20);
3206 EXPECT_EQ(reshape_tracker->last_reshape_height(), 30);
3207 EXPECT_EQ(reshape_tracker->last_reshape_scale_factor(), 1.f);
3208 host_impl_->DidDrawAllLayers(frame);
3209 reshape_tracker->clear_reshape_called();
3210
3211 host_impl_->SetDeviceScaleFactor(2.f);
3212 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
3213 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3214 EXPECT_TRUE(reshape_tracker->reshape_called());
3215 EXPECT_EQ(reshape_tracker->last_reshape_width(), 20);
3216 EXPECT_EQ(reshape_tracker->last_reshape_height(), 30);
3217 EXPECT_EQ(reshape_tracker->last_reshape_scale_factor(), 2.f);
3218 host_impl_->DidDrawAllLayers(frame);
3219 reshape_tracker->clear_reshape_called();
[email protected]94f206c12012-08-25 00:09:143220}
3221
[email protected]3191cc672013-06-12 21:16:553222class SwapTrackerContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423223 public:
[email protected]41de22822013-08-29 04:16:173224 SwapTrackerContext()
3225 : last_update_type_(NoUpdate) {
3226 test_capabilities_.post_sub_buffer = true;
3227 test_capabilities_.set_visibility = true;
3228 }
[email protected]3191cc672013-06-12 21:16:553229
3230 virtual void prepareTexture() OVERRIDE {
3231 update_rect_ = gfx::Rect(width_, height_);
3232 last_update_type_ = PrepareTexture;
3233 }
3234
[email protected]aa043632013-03-25 03:39:423235 virtual void postSubBufferCHROMIUM(int x, int y, int width, int height)
3236 OVERRIDE {
[email protected]3191cc672013-06-12 21:16:553237 update_rect_ = gfx::Rect(x, y, width, height);
3238 last_update_type_ = PostSubBuffer;
[email protected]aa043632013-03-25 03:39:423239 }
3240
[email protected]3191cc672013-06-12 21:16:553241 gfx::Rect update_rect() const { return update_rect_; }
3242
3243 enum UpdateType {
3244 NoUpdate = 0,
3245 PrepareTexture,
3246 PostSubBuffer
3247 };
3248
3249 UpdateType last_update_type() {
3250 return last_update_type_;
3251 }
[email protected]94f206c12012-08-25 00:09:143252
[email protected]aa043632013-03-25 03:39:423253 private:
[email protected]3191cc672013-06-12 21:16:553254 gfx::Rect update_rect_;
3255 UpdateType last_update_type_;
[email protected]94f206c12012-08-25 00:09:143256};
3257
3258// Make sure damage tracking propagates all the way to the graphics context,
[email protected]aa043632013-03-25 03:39:423259// where it should request to swap only the sub-buffer that is damaged.
3260TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
[email protected]0634cdd42013-08-16 00:46:093261 scoped_ptr<SwapTrackerContext> context(new SwapTrackerContext);
3262 SwapTrackerContext* swap_tracker = context.get();
3263
3264 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3265 context.PassAs<TestWebGraphicsContext3D>()));
[email protected]94f206c12012-08-25 00:09:143266
[email protected]aa043632013-03-25 03:39:423267 // This test creates its own LayerTreeHostImpl, so
3268 // that we can force partial swap enabled.
3269 LayerTreeSettings settings;
3270 settings.partial_swap_enabled = true;
3271 scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl =
3272 LayerTreeHostImpl::Create(settings,
3273 this,
3274 &proxy_,
3275 &stats_instrumentation_);
3276 layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403277 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
[email protected]94f206c12012-08-25 00:09:143278
[email protected]aa043632013-03-25 03:39:423279 scoped_ptr<LayerImpl> root =
3280 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
3281 scoped_ptr<LayerImpl> child =
3282 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
3283 child->SetPosition(gfx::PointF(12.f, 13.f));
3284 child->SetAnchorPoint(gfx::PointF());
3285 child->SetBounds(gfx::Size(14, 15));
3286 child->SetContentBounds(gfx::Size(14, 15));
3287 child->SetDrawsContent(true);
3288 root->SetAnchorPoint(gfx::PointF());
3289 root->SetBounds(gfx::Size(500, 500));
3290 root->SetContentBounds(gfx::Size(500, 500));
3291 root->SetDrawsContent(true);
3292 root->AddChild(child.Pass());
3293 layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143294
[email protected]aa043632013-03-25 03:39:423295 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143296
[email protected]aa043632013-03-25 03:39:423297 // First frame, the entire screen should get swapped.
[email protected]e0341352013-04-06 05:01:203298 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423299 layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3300 layer_tree_host_impl->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203301 layer_tree_host_impl->SwapBuffers(frame);
[email protected]3191cc672013-06-12 21:16:553302 gfx::Rect actual_swap_rect = swap_tracker->update_rect();
[email protected]aa043632013-03-25 03:39:423303 gfx::Rect expected_swap_rect = gfx::Rect(0, 0, 500, 500);
3304 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3305 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3306 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3307 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]3191cc672013-06-12 21:16:553308 EXPECT_EQ(swap_tracker->last_update_type(),
3309 SwapTrackerContext::PrepareTexture);
[email protected]aa043632013-03-25 03:39:423310 // Second frame, only the damaged area should get swapped. Damage should be
3311 // the union of old and new child rects.
3312 // expected damage rect: gfx::Rect(26, 28);
3313 // expected swap rect: vertically flipped, with origin at bottom left corner.
3314 layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
3315 gfx::PointF());
[email protected]e0341352013-04-06 05:01:203316 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423317 layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3318 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203319 layer_tree_host_impl->SwapBuffers(frame);
[email protected]3191cc672013-06-12 21:16:553320 actual_swap_rect = swap_tracker->update_rect();
[email protected]aa043632013-03-25 03:39:423321 expected_swap_rect = gfx::Rect(0, 500-28, 26, 28);
3322 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3323 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3324 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3325 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]3191cc672013-06-12 21:16:553326 EXPECT_EQ(swap_tracker->last_update_type(),
3327 SwapTrackerContext::PostSubBuffer);
[email protected]94f206c12012-08-25 00:09:143328
[email protected]aa043632013-03-25 03:39:423329 // Make sure that partial swap is constrained to the viewport dimensions
3330 // expected damage rect: gfx::Rect(500, 500);
3331 // expected swap rect: flipped damage rect, but also clamped to viewport
[email protected]18ce59702013-04-09 04:58:403332 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10));
[email protected]aa043632013-03-25 03:39:423333 // This will damage everything.
[email protected]35a99a12013-05-09 23:52:293334 layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor(
3335 SK_ColorBLACK);
[email protected]e0341352013-04-06 05:01:203336 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423337 layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3338 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203339 layer_tree_host_impl->SwapBuffers(frame);
[email protected]3191cc672013-06-12 21:16:553340 actual_swap_rect = swap_tracker->update_rect();
[email protected]aa043632013-03-25 03:39:423341 expected_swap_rect = gfx::Rect(10, 10);
3342 EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
3343 EXPECT_EQ(expected_swap_rect.y(), actual_swap_rect.y());
3344 EXPECT_EQ(expected_swap_rect.width(), actual_swap_rect.width());
3345 EXPECT_EQ(expected_swap_rect.height(), actual_swap_rect.height());
[email protected]3191cc672013-06-12 21:16:553346 EXPECT_EQ(swap_tracker->last_update_type(),
3347 SwapTrackerContext::PrepareTexture);
[email protected]94f206c12012-08-25 00:09:143348}
3349
[email protected]aa043632013-03-25 03:39:423350TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
3351 scoped_ptr<LayerImpl> root =
3352 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
3353 scoped_ptr<LayerImpl> child =
3354 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
3355 child->SetAnchorPoint(gfx::PointF());
3356 child->SetBounds(gfx::Size(10, 10));
3357 child->SetContentBounds(gfx::Size(10, 10));
3358 child->SetDrawsContent(true);
3359 root->SetAnchorPoint(gfx::PointF());
3360 root->SetBounds(gfx::Size(10, 10));
3361 root->SetContentBounds(gfx::Size(10, 10));
3362 root->SetDrawsContent(true);
[email protected]35a99a12013-05-09 23:52:293363 root->SetForceRenderSurface(true);
[email protected]aa043632013-03-25 03:39:423364 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:143365
[email protected]aa043632013-03-25 03:39:423366 host_impl_->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143367
[email protected]aa043632013-03-25 03:39:423368 LayerTreeHostImpl::FrameData frame;
[email protected]94f206c12012-08-25 00:09:143369
[email protected]e0341352013-04-06 05:01:203370 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423371 EXPECT_EQ(1u, frame.render_surface_layer_list->size());
3372 EXPECT_EQ(1u, frame.render_passes.size());
3373 host_impl_->DidDrawAllLayers(frame);
[email protected]94f206c12012-08-25 00:09:143374}
3375
[email protected]96baf3e2012-10-22 23:09:553376class FakeLayerWithQuads : public LayerImpl {
[email protected]aa043632013-03-25 03:39:423377 public:
3378 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
3379 return scoped_ptr<LayerImpl>(new FakeLayerWithQuads(tree_impl, id));
3380 }
[email protected]94f206c12012-08-25 00:09:143381
[email protected]aa043632013-03-25 03:39:423382 virtual void AppendQuads(QuadSink* quad_sink,
3383 AppendQuadsData* append_quads_data) OVERRIDE {
3384 SharedQuadState* shared_quad_state =
3385 quad_sink->UseSharedQuadState(CreateSharedQuadState());
[email protected]94f206c12012-08-25 00:09:143386
[email protected]aa043632013-03-25 03:39:423387 SkColor gray = SkColorSetRGB(100, 100, 100);
[email protected]2c7c6702013-03-26 03:14:053388 gfx::Rect quad_rect(content_bounds());
[email protected]aa043632013-03-25 03:39:423389 scoped_ptr<SolidColorDrawQuad> my_quad = SolidColorDrawQuad::Create();
[email protected]10a30b12013-05-02 16:42:113390 my_quad->SetNew(shared_quad_state, quad_rect, gray, false);
[email protected]aa043632013-03-25 03:39:423391 quad_sink->Append(my_quad.PassAs<DrawQuad>(), append_quads_data);
3392 }
[email protected]94f206c12012-08-25 00:09:143393
[email protected]aa043632013-03-25 03:39:423394 private:
3395 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id)
3396 : LayerImpl(tree_impl, id) {}
[email protected]94f206c12012-08-25 00:09:143397};
3398
[email protected]c8756fbe2013-02-12 01:53:493399class MockContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423400 public:
3401 MOCK_METHOD1(useProgram, void(WebKit::WebGLId program));
3402 MOCK_METHOD5(uniform4f, void(WebKit::WGC3Dint location,
3403 WebKit::WGC3Dfloat x,
3404 WebKit::WGC3Dfloat y,
3405 WebKit::WGC3Dfloat z,
3406 WebKit::WGC3Dfloat w));
3407 MOCK_METHOD4(uniformMatrix4fv, void(WebKit::WGC3Dint location,
3408 WebKit::WGC3Dsizei count,
3409 WebKit::WGC3Dboolean transpose,
3410 const WebKit::WGC3Dfloat* value));
3411 MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
3412 WebKit::WGC3Dsizei count,
3413 WebKit::WGC3Denum type,
3414 WebKit::WGC3Dintptr offset));
[email protected]aa043632013-03-25 03:39:423415 MOCK_METHOD0(getRequestableExtensionsCHROMIUM, WebKit::WebString());
3416 MOCK_METHOD1(enable, void(WebKit::WGC3Denum cap));
3417 MOCK_METHOD1(disable, void(WebKit::WGC3Denum cap));
3418 MOCK_METHOD4(scissor, void(WebKit::WGC3Dint x,
3419 WebKit::WGC3Dint y,
3420 WebKit::WGC3Dsizei width,
3421 WebKit::WGC3Dsizei height));
[email protected]94f206c12012-08-25 00:09:143422};
3423
3424class MockContextHarness {
[email protected]aa043632013-03-25 03:39:423425 private:
3426 MockContext* context_;
[email protected]bf691c22013-03-26 21:15:063427
[email protected]aa043632013-03-25 03:39:423428 public:
[email protected]bf691c22013-03-26 21:15:063429 explicit MockContextHarness(MockContext* context)
[email protected]aa043632013-03-25 03:39:423430 : context_(context) {
[email protected]41de22822013-08-29 04:16:173431 context_->set_have_post_sub_buffer(true);
3432
[email protected]aa043632013-03-25 03:39:423433 // Catch "uninteresting" calls
3434 EXPECT_CALL(*context_, useProgram(_))
3435 .Times(0);
[email protected]94f206c12012-08-25 00:09:143436
[email protected]aa043632013-03-25 03:39:423437 EXPECT_CALL(*context_, drawElements(_, _, _, _))
3438 .Times(0);
[email protected]94f206c12012-08-25 00:09:143439
[email protected]aa043632013-03-25 03:39:423440 // These are not asserted
3441 EXPECT_CALL(*context_, uniformMatrix4fv(_, _, _, _))
3442 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143443
[email protected]aa043632013-03-25 03:39:423444 EXPECT_CALL(*context_, uniform4f(_, _, _, _, _))
3445 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143446
[email protected]aa043632013-03-25 03:39:423447 // Any un-sanctioned calls to enable() are OK
3448 EXPECT_CALL(*context_, enable(_))
3449 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143450
[email protected]aa043632013-03-25 03:39:423451 // Any un-sanctioned calls to disable() are OK
3452 EXPECT_CALL(*context_, disable(_))
3453 .WillRepeatedly(Return());
3454 }
[email protected]94f206c12012-08-25 00:09:143455
[email protected]aa043632013-03-25 03:39:423456 void MustDrawSolidQuad() {
3457 EXPECT_CALL(*context_, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0))
3458 .WillOnce(Return())
3459 .RetiresOnSaturation();
[email protected]94f206c12012-08-25 00:09:143460
[email protected]aa043632013-03-25 03:39:423461 EXPECT_CALL(*context_, useProgram(_))
3462 .WillOnce(Return())
3463 .RetiresOnSaturation();
[email protected]aa043632013-03-25 03:39:423464 }
[email protected]94f206c12012-08-25 00:09:143465
[email protected]aa043632013-03-25 03:39:423466 void MustSetScissor(int x, int y, int width, int height) {
3467 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
3468 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143469
[email protected]aa043632013-03-25 03:39:423470 EXPECT_CALL(*context_, scissor(x, y, width, height))
3471 .Times(AtLeast(1))
3472 .WillRepeatedly(Return());
3473 }
[email protected]94f206c12012-08-25 00:09:143474
[email protected]aa043632013-03-25 03:39:423475 void MustSetNoScissor() {
3476 EXPECT_CALL(*context_, disable(GL_SCISSOR_TEST))
3477 .WillRepeatedly(Return());
[email protected]94f206c12012-08-25 00:09:143478
[email protected]aa043632013-03-25 03:39:423479 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
3480 .Times(0);
[email protected]94f206c12012-08-25 00:09:143481
[email protected]aa043632013-03-25 03:39:423482 EXPECT_CALL(*context_, scissor(_, _, _, _))
3483 .Times(0);
3484 }
[email protected]94f206c12012-08-25 00:09:143485};
3486
[email protected]aa043632013-03-25 03:39:423487TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
[email protected]0634cdd42013-08-16 00:46:093488 scoped_ptr<MockContext> mock_context_owned(new MockContext);
3489 MockContext* mock_context = mock_context_owned.get();
3490
3491 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3492 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423493 MockContextHarness harness(mock_context);
[email protected]94f206c12012-08-25 00:09:143494
[email protected]aa043632013-03-25 03:39:423495 // Run test case
3496 CreateLayerTreeHost(false, output_surface.Pass());
3497 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
[email protected]94f206c12012-08-25 00:09:143498
[email protected]aa043632013-03-25 03:39:423499 // Without partial swap, and no clipping, no scissor is set.
3500 harness.MustDrawSolidQuad();
3501 harness.MustSetNoScissor();
3502 {
3503 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203504 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423505 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3506 host_impl_->DidDrawAllLayers(frame);
3507 }
3508 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]dc462d782012-11-21 21:43:013509
[email protected]aa043632013-03-25 03:39:423510 // Without partial swap, but a layer does clip its subtree, one scissor is
3511 // set.
3512 host_impl_->active_tree()->root_layer()->SetMasksToBounds(true);
3513 harness.MustDrawSolidQuad();
3514 harness.MustSetScissor(0, 0, 10, 10);
3515 {
3516 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203517 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423518 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3519 host_impl_->DidDrawAllLayers(frame);
3520 }
3521 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143522}
3523
[email protected]aa043632013-03-25 03:39:423524TEST_F(LayerTreeHostImplTest, PartialSwap) {
[email protected]0634cdd42013-08-16 00:46:093525 scoped_ptr<MockContext> context_owned(new MockContext);
3526 MockContext* mock_context = context_owned.get();
3527 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3528 context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]aa043632013-03-25 03:39:423529 MockContextHarness harness(mock_context);
[email protected]94f206c12012-08-25 00:09:143530
[email protected]aa043632013-03-25 03:39:423531 CreateLayerTreeHost(true, output_surface.Pass());
3532 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
[email protected]94f206c12012-08-25 00:09:143533
[email protected]aa043632013-03-25 03:39:423534 // The first frame is not a partially-swapped one.
3535 harness.MustSetScissor(0, 0, 10, 10);
3536 harness.MustDrawSolidQuad();
3537 {
3538 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203539 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423540 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3541 host_impl_->DidDrawAllLayers(frame);
3542 }
3543 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143544
[email protected]aa043632013-03-25 03:39:423545 // Damage a portion of the frame.
3546 host_impl_->active_tree()->root_layer()->set_update_rect(
3547 gfx::Rect(0, 0, 2, 3));
[email protected]94f206c12012-08-25 00:09:143548
[email protected]aa043632013-03-25 03:39:423549 // The second frame will be partially-swapped (the y coordinates are flipped).
3550 harness.MustSetScissor(0, 7, 2, 3);
3551 harness.MustDrawSolidQuad();
3552 {
3553 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203554 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423555 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3556 host_impl_->DidDrawAllLayers(frame);
3557 }
3558 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143559}
3560
[email protected]c8756fbe2013-02-12 01:53:493561class PartialSwapContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423562 public:
[email protected]41de22822013-08-29 04:16:173563 PartialSwapContext() {
3564 test_capabilities_.post_sub_buffer = true;
[email protected]aa043632013-03-25 03:39:423565 }
[email protected]94f206c12012-08-25 00:09:143566
[email protected]aa043632013-03-25 03:39:423567 // Unlimited texture size.
3568 virtual void getIntegerv(WebKit::WGC3Denum pname, WebKit::WGC3Dint* value)
3569 OVERRIDE {
3570 if (pname == GL_MAX_TEXTURE_SIZE)
3571 *value = 8192;
[email protected]ac28ebc2013-07-31 15:57:553572 else if (pname == GL_ACTIVE_TEXTURE)
3573 *value = GL_TEXTURE0;
[email protected]aa043632013-03-25 03:39:423574 }
[email protected]94f206c12012-08-25 00:09:143575};
3576
[email protected]aa043632013-03-25 03:39:423577static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
3578 bool partial_swap,
3579 LayerTreeHostImplClient* client,
3580 Proxy* proxy,
3581 RenderingStatsInstrumentation* stats_instrumentation) {
[email protected]0634cdd42013-08-16 00:46:093582 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3583 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:143584
[email protected]aa043632013-03-25 03:39:423585 LayerTreeSettings settings;
3586 settings.partial_swap_enabled = partial_swap;
3587 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3588 LayerTreeHostImpl::Create(settings, client, proxy, stats_instrumentation);
3589 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403590 my_host_impl->SetViewportSize(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:143591
[email protected]aa043632013-03-25 03:39:423592 /*
3593 Layers are created as follows:
[email protected]94f206c12012-08-25 00:09:143594
[email protected]aa043632013-03-25 03:39:423595 +--------------------+
3596 | 1 |
3597 | +-----------+ |
3598 | | 2 | |
3599 | | +-------------------+
3600 | | | 3 |
3601 | | +-------------------+
3602 | | | |
3603 | +-----------+ |
3604 | |
3605 | |
3606 +--------------------+
[email protected]94f206c12012-08-25 00:09:143607
[email protected]aa043632013-03-25 03:39:423608 Layers 1, 2 have render surfaces
3609 */
3610 scoped_ptr<LayerImpl> root =
3611 LayerImpl::Create(my_host_impl->active_tree(), 1);
3612 scoped_ptr<LayerImpl> child =
3613 LayerImpl::Create(my_host_impl->active_tree(), 2);
3614 scoped_ptr<LayerImpl> grand_child =
3615 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3);
[email protected]94f206c12012-08-25 00:09:143616
[email protected]aa043632013-03-25 03:39:423617 gfx::Rect root_rect(0, 0, 100, 100);
3618 gfx::Rect child_rect(10, 10, 50, 50);
3619 gfx::Rect grand_child_rect(5, 5, 150, 150);
[email protected]94f206c12012-08-25 00:09:143620
[email protected]aa043632013-03-25 03:39:423621 root->CreateRenderSurface();
3622 root->SetAnchorPoint(gfx::PointF());
3623 root->SetPosition(root_rect.origin());
3624 root->SetBounds(root_rect.size());
3625 root->SetContentBounds(root->bounds());
3626 root->draw_properties().visible_content_rect = root_rect;
3627 root->SetDrawsContent(false);
3628 root->render_surface()->SetContentRect(gfx::Rect(root_rect.size()));
[email protected]94f206c12012-08-25 00:09:143629
[email protected]aa043632013-03-25 03:39:423630 child->SetAnchorPoint(gfx::PointF());
3631 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
3632 child->SetOpacity(0.5f);
3633 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
3634 child->SetContentBounds(child->bounds());
3635 child->draw_properties().visible_content_rect = child_rect;
3636 child->SetDrawsContent(false);
3637 child->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:143638
[email protected]aa043632013-03-25 03:39:423639 grand_child->SetAnchorPoint(gfx::PointF());
3640 grand_child->SetPosition(grand_child_rect.origin());
3641 grand_child->SetBounds(grand_child_rect.size());
3642 grand_child->SetContentBounds(grand_child->bounds());
3643 grand_child->draw_properties().visible_content_rect = grand_child_rect;
3644 grand_child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143645
[email protected]aa043632013-03-25 03:39:423646 child->AddChild(grand_child.Pass());
3647 root->AddChild(child.Pass());
[email protected]94f206c12012-08-25 00:09:143648
[email protected]aa043632013-03-25 03:39:423649 my_host_impl->active_tree()->SetRootLayer(root.Pass());
3650 return my_host_impl.Pass();
[email protected]94f206c12012-08-25 00:09:143651}
3652
[email protected]aa043632013-03-25 03:39:423653TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
3654 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3655 SetupLayersForOpacity(true, this, &proxy_, &stats_instrumentation_);
3656 {
3657 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203658 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143659
[email protected]aa043632013-03-25 03:39:423660 // Verify all quads have been computed
3661 ASSERT_EQ(2U, frame.render_passes.size());
3662 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
3663 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
3664 EXPECT_EQ(DrawQuad::SOLID_COLOR,
3665 frame.render_passes[0]->quad_list[0]->material);
3666 EXPECT_EQ(DrawQuad::RENDER_PASS,
3667 frame.render_passes[1]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:143668
[email protected]aa043632013-03-25 03:39:423669 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3670 my_host_impl->DidDrawAllLayers(frame);
3671 }
[email protected]94f206c12012-08-25 00:09:143672}
3673
[email protected]aa043632013-03-25 03:39:423674TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
3675 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3676 SetupLayersForOpacity(false, this, &proxy_, &stats_instrumentation_);
3677 {
3678 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203679 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143680
[email protected]aa043632013-03-25 03:39:423681 // Verify all quads have been computed
3682 ASSERT_EQ(2U, frame.render_passes.size());
3683 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
3684 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
3685 EXPECT_EQ(DrawQuad::SOLID_COLOR,
3686 frame.render_passes[0]->quad_list[0]->material);
3687 EXPECT_EQ(DrawQuad::RENDER_PASS,
3688 frame.render_passes[1]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:143689
[email protected]aa043632013-03-25 03:39:423690 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3691 my_host_impl->DidDrawAllLayers(frame);
3692 }
[email protected]94f206c12012-08-25 00:09:143693}
3694
[email protected]009dc072012-12-16 20:32:133695// Fake WebKit::WebGraphicsContext3D that tracks the number of textures in use.
[email protected]c8756fbe2013-02-12 01:53:493696class TrackingWebGraphicsContext3D : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423697 public:
3698 TrackingWebGraphicsContext3D()
3699 : TestWebGraphicsContext3D(),
[email protected]41de22822013-08-29 04:16:173700 num_textures_(0) {
3701 test_capabilities_.iosurface = true;
3702 test_capabilities_.texture_rectangle = true;
3703 }
[email protected]94f206c12012-08-25 00:09:143704
[email protected]aa043632013-03-25 03:39:423705 virtual WebKit::WebGLId createTexture() OVERRIDE {
3706 WebKit::WebGLId id = TestWebGraphicsContext3D::createTexture();
[email protected]94f206c12012-08-25 00:09:143707
[email protected]aa043632013-03-25 03:39:423708 textures_[id] = true;
3709 ++num_textures_;
3710 return id;
3711 }
3712
3713 virtual void deleteTexture(WebKit::WebGLId id) OVERRIDE {
3714 if (textures_.find(id) == textures_.end())
3715 return;
3716
3717 textures_[id] = false;
3718 --num_textures_;
3719 }
3720
[email protected]aa043632013-03-25 03:39:423721 unsigned num_textures() const { return num_textures_; }
[email protected]94f206c12012-08-25 00:09:143722
[email protected]aa043632013-03-25 03:39:423723 private:
3724 base::hash_map<WebKit::WebGLId, bool> textures_;
3725 unsigned num_textures_;
[email protected]94f206c12012-08-25 00:09:143726};
3727
[email protected]aa043632013-03-25 03:39:423728TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
3729 scoped_ptr<TestWebGraphicsContext3D> context =
3730 TestWebGraphicsContext3D::Create();
3731 TestWebGraphicsContext3D* context3d = context.get();
[email protected]0634cdd42013-08-16 00:46:093732 scoped_ptr<OutputSurface> output_surface(
3733 FakeOutputSurface::Create3d(context.Pass()));
[email protected]aa043632013-03-25 03:39:423734 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]d993b602013-01-04 02:08:123735
[email protected]aa043632013-03-25 03:39:423736 scoped_ptr<LayerImpl> root_layer =
3737 LayerImpl::Create(host_impl_->active_tree(), 1);
3738 root_layer->SetBounds(gfx::Size(10, 10));
3739 root_layer->SetAnchorPoint(gfx::PointF());
[email protected]94f206c12012-08-25 00:09:143740
[email protected]aa043632013-03-25 03:39:423741 scoped_refptr<VideoFrame> softwareFrame =
3742 media::VideoFrame::CreateColorFrame(
3743 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
3744 FakeVideoFrameProvider provider;
3745 provider.set_frame(softwareFrame);
3746 scoped_ptr<VideoLayerImpl> video_layer =
3747 VideoLayerImpl::Create(host_impl_->active_tree(), 4, &provider);
3748 video_layer->SetBounds(gfx::Size(10, 10));
3749 video_layer->SetAnchorPoint(gfx::PointF());
3750 video_layer->SetContentBounds(gfx::Size(10, 10));
3751 video_layer->SetDrawsContent(true);
3752 root_layer->AddChild(video_layer.PassAs<LayerImpl>());
[email protected]94f206c12012-08-25 00:09:143753
[email protected]aa043632013-03-25 03:39:423754 scoped_ptr<IOSurfaceLayerImpl> io_surface_layer =
3755 IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5);
3756 io_surface_layer->SetBounds(gfx::Size(10, 10));
3757 io_surface_layer->SetAnchorPoint(gfx::PointF());
3758 io_surface_layer->SetContentBounds(gfx::Size(10, 10));
3759 io_surface_layer->SetDrawsContent(true);
3760 io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10));
3761 root_layer->AddChild(io_surface_layer.PassAs<LayerImpl>());
[email protected]94f206c12012-08-25 00:09:143762
[email protected]aa043632013-03-25 03:39:423763 host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
[email protected]94f206c12012-08-25 00:09:143764
[email protected]aa043632013-03-25 03:39:423765 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]d993b602013-01-04 02:08:123766
[email protected]aa043632013-03-25 03:39:423767 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203768 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423769 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3770 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:203771 host_impl_->SwapBuffers(frame);
[email protected]94f206c12012-08-25 00:09:143772
[email protected]aa043632013-03-25 03:39:423773 EXPECT_GT(context3d->NumTextures(), 0u);
[email protected]94f206c12012-08-25 00:09:143774
[email protected]aa043632013-03-25 03:39:423775 // Kill the layer tree.
3776 host_impl_->active_tree()->SetRootLayer(
3777 LayerImpl::Create(host_impl_->active_tree(), 100));
3778 // There should be no textures left in use after.
3779 EXPECT_EQ(0u, context3d->NumTextures());
[email protected]94f206c12012-08-25 00:09:143780}
3781
[email protected]c8756fbe2013-02-12 01:53:493782class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
[email protected]aa043632013-03-25 03:39:423783 public:
3784 MOCK_METHOD1(useProgram, void(WebKit::WebGLId program));
3785 MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
3786 WebKit::WGC3Dsizei count,
3787 WebKit::WGC3Denum type,
3788 WebKit::WGC3Dintptr offset));
[email protected]94f206c12012-08-25 00:09:143789};
3790
[email protected]aa043632013-03-25 03:39:423791TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
[email protected]0634cdd42013-08-16 00:46:093792 scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned(
3793 new MockDrawQuadsToFillScreenContext);
3794 MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get();
3795
3796 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3797 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
[email protected]94f206c12012-08-25 00:09:143798
[email protected]aa043632013-03-25 03:39:423799 // Run test case
3800 CreateLayerTreeHost(false, output_surface.Pass());
3801 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
3802 host_impl_->active_tree()->set_background_color(SK_ColorWHITE);
[email protected]94f206c12012-08-25 00:09:143803
[email protected]aa043632013-03-25 03:39:423804 // Verify one quad is drawn when transparent background set is not set.
3805 host_impl_->active_tree()->set_has_transparent_background(false);
3806 EXPECT_CALL(*mock_context, useProgram(_))
3807 .Times(1);
3808 EXPECT_CALL(*mock_context, drawElements(_, _, _, _))
3809 .Times(1);
3810 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203811 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423812 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3813 host_impl_->DidDrawAllLayers(frame);
3814 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143815
[email protected]aa043632013-03-25 03:39:423816 // Verify no quads are drawn when transparent background is set.
3817 host_impl_->active_tree()->set_has_transparent_background(true);
[email protected]e0341352013-04-06 05:01:203818 host_impl_->SetFullRootLayerDamage();
3819 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:423820 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
3821 host_impl_->DidDrawAllLayers(frame);
3822 Mock::VerifyAndClearExpectations(&mock_context);
[email protected]94f206c12012-08-25 00:09:143823}
3824
[email protected]aa043632013-03-25 03:39:423825static void AddDrawingLayerTo(LayerImpl* parent,
3826 int id,
3827 gfx::Rect layer_rect,
3828 LayerImpl** result) {
3829 scoped_ptr<LayerImpl> layer =
3830 FakeLayerWithQuads::Create(parent->layer_tree_impl(), id);
3831 LayerImpl* layer_ptr = layer.get();
3832 layer_ptr->SetAnchorPoint(gfx::PointF());
3833 layer_ptr->SetPosition(gfx::PointF(layer_rect.origin()));
3834 layer_ptr->SetBounds(layer_rect.size());
3835 layer_ptr->SetContentBounds(layer_rect.size());
3836 layer_ptr->SetDrawsContent(true); // only children draw content
3837 layer_ptr->SetContentsOpaque(true);
3838 parent->AddChild(layer.Pass());
3839 if (result)
3840 *result = layer_ptr;
[email protected]94f206c12012-08-25 00:09:143841}
3842
[email protected]aa043632013-03-25 03:39:423843static void SetupLayersForTextureCaching(
3844 LayerTreeHostImpl* layer_tree_host_impl,
3845 LayerImpl*& root_ptr,
3846 LayerImpl*& intermediate_layer_ptr,
3847 LayerImpl*& surface_layer_ptr,
3848 LayerImpl*& child_ptr,
3849 gfx::Size root_size) {
[email protected]0634cdd42013-08-16 00:46:093850 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3851 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:143852
[email protected]aa043632013-03-25 03:39:423853 layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403854 layer_tree_host_impl->SetViewportSize(root_size);
[email protected]94f206c12012-08-25 00:09:143855
[email protected]aa043632013-03-25 03:39:423856 scoped_ptr<LayerImpl> root =
3857 LayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
3858 root_ptr = root.get();
[email protected]94f206c12012-08-25 00:09:143859
[email protected]aa043632013-03-25 03:39:423860 root->SetAnchorPoint(gfx::PointF());
3861 root->SetPosition(gfx::PointF());
3862 root->SetBounds(root_size);
3863 root->SetContentBounds(root_size);
3864 root->SetDrawsContent(true);
3865 layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143866
[email protected]aa043632013-03-25 03:39:423867 AddDrawingLayerTo(root_ptr,
3868 2,
3869 gfx::Rect(10, 10, root_size.width(), root_size.height()),
3870 &intermediate_layer_ptr);
3871 // Only children draw content.
3872 intermediate_layer_ptr->SetDrawsContent(false);
[email protected]94f206c12012-08-25 00:09:143873
[email protected]aa043632013-03-25 03:39:423874 // Surface layer is the layer that changes its opacity
3875 // It will contain other layers that draw content.
3876 AddDrawingLayerTo(intermediate_layer_ptr,
3877 3,
3878 gfx::Rect(10, 10, root_size.width(), root_size.height()),
3879 &surface_layer_ptr);
3880 // Only children draw content.
3881 surface_layer_ptr->SetDrawsContent(false);
3882 surface_layer_ptr->SetOpacity(0.5f);
3883 surface_layer_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:143884
[email protected]aa043632013-03-25 03:39:423885 // Child of the surface layer will produce some quads
3886 AddDrawingLayerTo(surface_layer_ptr,
3887 4,
3888 gfx::Rect(5,
3889 5,
3890 root_size.width() - 25,
3891 root_size.height() - 25),
3892 &child_ptr);
[email protected]94f206c12012-08-25 00:09:143893}
3894
[email protected]96baf3e2012-10-22 23:09:553895class GLRendererWithReleaseTextures : public GLRenderer {
[email protected]aa043632013-03-25 03:39:423896 public:
3897 using GLRenderer::ReleaseRenderPassTextures;
[email protected]94f206c12012-08-25 00:09:143898};
3899
[email protected]aa043632013-03-25 03:39:423900TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusion) {
3901 LayerTreeSettings settings;
3902 settings.minimum_occlusion_tracking_size = gfx::Size();
3903 settings.cache_render_pass_contents = true;
3904 scoped_ptr<LayerTreeHostImpl> my_host_impl =
3905 LayerTreeHostImpl::Create(settings,
3906 this,
3907 &proxy_,
3908 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:143909
[email protected]aa043632013-03-25 03:39:423910 // Layers are structure as follows:
3911 //
3912 // R +-- S1 +- L10 (owning)
3913 // | +- L11
3914 // | +- L12
3915 // |
3916 // +-- S2 +- L20 (owning)
3917 // +- L21
3918 //
3919 // Occlusion:
3920 // L12 occludes L11 (internal)
3921 // L20 occludes L10 (external)
3922 // L21 occludes L20 (internal)
[email protected]94f206c12012-08-25 00:09:143923
[email protected]aa043632013-03-25 03:39:423924 LayerImpl* root_ptr;
3925 LayerImpl* layer_s1_ptr;
3926 LayerImpl* layer_s2_ptr;
[email protected]94f206c12012-08-25 00:09:143927
[email protected]0634cdd42013-08-16 00:46:093928 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
3929 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:143930
[email protected]aa043632013-03-25 03:39:423931 gfx::Size root_size(1000, 1000);
[email protected]94f206c12012-08-25 00:09:143932
[email protected]aa043632013-03-25 03:39:423933 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:403934 my_host_impl->SetViewportSize(root_size);
[email protected]94f206c12012-08-25 00:09:143935
[email protected]aa043632013-03-25 03:39:423936 scoped_ptr<LayerImpl> root =
3937 LayerImpl::Create(my_host_impl->active_tree(), 1);
3938 root_ptr = root.get();
[email protected]94f206c12012-08-25 00:09:143939
[email protected]aa043632013-03-25 03:39:423940 root->SetAnchorPoint(gfx::PointF());
3941 root->SetPosition(gfx::PointF());
3942 root->SetBounds(root_size);
3943 root->SetContentBounds(root_size);
3944 root->SetDrawsContent(true);
3945 root->SetMasksToBounds(true);
3946 my_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:143947
[email protected]aa043632013-03-25 03:39:423948 AddDrawingLayerTo(root_ptr, 2, gfx::Rect(300, 300, 300, 300), &layer_s1_ptr);
3949 layer_s1_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:143950
[email protected]aa043632013-03-25 03:39:423951 AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(10, 10, 10, 10), 0); // L11
3952 AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(0, 0, 30, 30), 0); // L12
[email protected]94f206c12012-08-25 00:09:143953
[email protected]aa043632013-03-25 03:39:423954 AddDrawingLayerTo(root_ptr, 5, gfx::Rect(550, 250, 300, 400), &layer_s2_ptr);
3955 layer_s2_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:143956
[email protected]aa043632013-03-25 03:39:423957 AddDrawingLayerTo(layer_s2_ptr, 6, gfx::Rect(20, 20, 5, 5), 0); // L21
[email protected]94f206c12012-08-25 00:09:143958
[email protected]aa043632013-03-25 03:39:423959 // Initial draw - must receive all quads
3960 {
3961 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203962 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143963
[email protected]aa043632013-03-25 03:39:423964 // Must receive 3 render passes.
3965 // For Root, there are 2 quads; for S1, there are 2 quads (1 is occluded);
3966 // for S2, there is 2 quads.
3967 ASSERT_EQ(3U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143968
[email protected]aa043632013-03-25 03:39:423969 EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size());
3970 EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size());
3971 EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:143972
[email protected]aa043632013-03-25 03:39:423973 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3974 my_host_impl->DidDrawAllLayers(frame);
3975 }
[email protected]94f206c12012-08-25 00:09:143976
[email protected]aa043632013-03-25 03:39:423977 // "Unocclude" surface S1 and repeat draw.
3978 // Must remove S2's render pass since it's cached;
3979 // Must keep S1 quads because texture contained external occlusion.
3980 gfx::Transform transform = layer_s2_ptr->transform();
3981 transform.Translate(150.0, 150.0);
3982 layer_s2_ptr->SetTransform(transform);
3983 {
3984 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:203985 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:143986
[email protected]aa043632013-03-25 03:39:423987 // Must receive 2 render passes.
3988 // For Root, there are 2 quads
3989 // For S1, the number of quads depends on what got unoccluded, so not
3990 // asserted beyond being positive.
3991 // For S2, there is no render pass
3992 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:143993
[email protected]aa043632013-03-25 03:39:423994 EXPECT_GT(frame.render_passes[0]->quad_list.size(), 0U);
3995 EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:143996
[email protected]aa043632013-03-25 03:39:423997 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
3998 my_host_impl->DidDrawAllLayers(frame);
3999 }
[email protected]94f206c12012-08-25 00:09:144000
[email protected]aa043632013-03-25 03:39:424001 // "Re-occlude" surface S1 and repeat draw.
4002 // Must remove S1's render pass since it is now available in full.
4003 // S2 has no change so must also be removed.
4004 transform = layer_s2_ptr->transform();
4005 transform.Translate(-15.0, -15.0);
4006 layer_s2_ptr->SetTransform(transform);
4007 {
4008 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204009 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144010
[email protected]aa043632013-03-25 03:39:424011 // Must receive 1 render pass - for the root.
4012 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144013
[email protected]aa043632013-03-25 03:39:424014 EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144015
[email protected]aa043632013-03-25 03:39:424016 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4017 my_host_impl->DidDrawAllLayers(frame);
4018 }
[email protected]94f206c12012-08-25 00:09:144019}
4020
[email protected]aa043632013-03-25 03:39:424021TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionEarlyOut) {
4022 LayerTreeSettings settings;
4023 settings.minimum_occlusion_tracking_size = gfx::Size();
4024 settings.cache_render_pass_contents = true;
4025 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4026 LayerTreeHostImpl::Create(settings,
4027 this,
4028 &proxy_,
4029 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144030
[email protected]aa043632013-03-25 03:39:424031 // Layers are structure as follows:
4032 //
4033 // R +-- S1 +- L10 (owning, non drawing)
4034 // | +- L11 (corner, unoccluded)
4035 // | +- L12 (corner, unoccluded)
4036 // | +- L13 (corner, unoccluded)
4037 // | +- L14 (corner, entirely occluded)
4038 // |
4039 // +-- S2 +- L20 (owning, drawing)
4040 //
[email protected]94f206c12012-08-25 00:09:144041
[email protected]aa043632013-03-25 03:39:424042 LayerImpl* root_ptr;
4043 LayerImpl* layer_s1_ptr;
4044 LayerImpl* layer_s2_ptr;
[email protected]94f206c12012-08-25 00:09:144045
[email protected]0634cdd42013-08-16 00:46:094046 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
4047 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:144048
[email protected]aa043632013-03-25 03:39:424049 gfx::Size root_size(1000, 1000);
[email protected]94f206c12012-08-25 00:09:144050
[email protected]aa043632013-03-25 03:39:424051 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:404052 my_host_impl->SetViewportSize(root_size);
[email protected]94f206c12012-08-25 00:09:144053
[email protected]aa043632013-03-25 03:39:424054 scoped_ptr<LayerImpl> root =
4055 LayerImpl::Create(my_host_impl->active_tree(), 1);
4056 root_ptr = root.get();
[email protected]94f206c12012-08-25 00:09:144057
[email protected]aa043632013-03-25 03:39:424058 root->SetAnchorPoint(gfx::PointF());
4059 root->SetPosition(gfx::PointF());
4060 root->SetBounds(root_size);
4061 root->SetContentBounds(root_size);
4062 root->SetDrawsContent(true);
4063 root->SetMasksToBounds(true);
4064 my_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:144065
[email protected]aa043632013-03-25 03:39:424066 AddDrawingLayerTo(root_ptr, 2, gfx::Rect(0, 0, 800, 800), &layer_s1_ptr);
4067 layer_s1_ptr->SetForceRenderSurface(true);
4068 layer_s1_ptr->SetDrawsContent(false);
[email protected]94f206c12012-08-25 00:09:144069
[email protected]aa043632013-03-25 03:39:424070 AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(0, 0, 300, 300), 0); // L11
4071 AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(0, 500, 300, 300), 0); // L12
4072 AddDrawingLayerTo(layer_s1_ptr, 5, gfx::Rect(500, 0, 300, 300), 0); // L13
4073 AddDrawingLayerTo(layer_s1_ptr, 6, gfx::Rect(500, 500, 300, 300), 0); // L14
4074 AddDrawingLayerTo(layer_s1_ptr, 9, gfx::Rect(500, 500, 300, 300), 0); // L14
[email protected]94f206c12012-08-25 00:09:144075
[email protected]aa043632013-03-25 03:39:424076 AddDrawingLayerTo(root_ptr, 7, gfx::Rect(450, 450, 450, 450), &layer_s2_ptr);
4077 layer_s2_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:144078
[email protected]aa043632013-03-25 03:39:424079 // Initial draw - must receive all quads
4080 {
4081 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204082 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144083
[email protected]aa043632013-03-25 03:39:424084 // Must receive 3 render passes.
4085 // For Root, there are 2 quads; for S1, there are 3 quads; for S2, there is
4086 // 1 quad.
4087 ASSERT_EQ(3U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144088
[email protected]aa043632013-03-25 03:39:424089 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144090
[email protected]aa043632013-03-25 03:39:424091 // L14 is culled, so only 3 quads.
4092 EXPECT_EQ(3U, frame.render_passes[1]->quad_list.size());
4093 EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144094
[email protected]aa043632013-03-25 03:39:424095 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4096 my_host_impl->DidDrawAllLayers(frame);
4097 }
[email protected]94f206c12012-08-25 00:09:144098
[email protected]aa043632013-03-25 03:39:424099 // "Unocclude" surface S1 and repeat draw.
4100 // Must remove S2's render pass since it's cached;
4101 // Must keep S1 quads because texture contained external occlusion.
4102 gfx::Transform transform = layer_s2_ptr->transform();
4103 transform.Translate(100.0, 100.0);
4104 layer_s2_ptr->SetTransform(transform);
4105 {
4106 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204107 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144108
[email protected]aa043632013-03-25 03:39:424109 // Must receive 2 render passes.
4110 // For Root, there are 2 quads
4111 // For S1, the number of quads depends on what got unoccluded, so not
4112 // asserted beyond being positive.
4113 // For S2, there is no render pass
4114 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144115
[email protected]aa043632013-03-25 03:39:424116 EXPECT_GT(frame.render_passes[0]->quad_list.size(), 0U);
4117 EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144118
[email protected]aa043632013-03-25 03:39:424119 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4120 my_host_impl->DidDrawAllLayers(frame);
4121 }
[email protected]94f206c12012-08-25 00:09:144122
[email protected]aa043632013-03-25 03:39:424123 // "Re-occlude" surface S1 and repeat draw.
4124 // Must remove S1's render pass since it is now available in full.
4125 // S2 has no change so must also be removed.
4126 transform = layer_s2_ptr->transform();
4127 transform.Translate(-15.0, -15.0);
4128 layer_s2_ptr->SetTransform(transform);
4129 {
4130 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204131 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144132
[email protected]aa043632013-03-25 03:39:424133 // Must receive 1 render pass - for the root.
4134 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144135
[email protected]aa043632013-03-25 03:39:424136 EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144137
[email protected]aa043632013-03-25 03:39:424138 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4139 my_host_impl->DidDrawAllLayers(frame);
4140 }
[email protected]94f206c12012-08-25 00:09:144141}
4142
[email protected]aa043632013-03-25 03:39:424143TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalOverInternal) {
4144 LayerTreeSettings settings;
4145 settings.minimum_occlusion_tracking_size = gfx::Size();
4146 settings.cache_render_pass_contents = true;
4147 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4148 LayerTreeHostImpl::Create(settings,
4149 this,
4150 &proxy_,
4151 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144152
[email protected]aa043632013-03-25 03:39:424153 // Layers are structured as follows:
4154 //
4155 // R +-- S1 +- L10 (owning, drawing)
4156 // | +- L11 (corner, occluded by L12)
4157 // | +- L12 (opposite corner)
4158 // |
4159 // +-- S2 +- L20 (owning, drawing)
4160 //
[email protected]94f206c12012-08-25 00:09:144161
[email protected]aa043632013-03-25 03:39:424162 LayerImpl* root_ptr;
4163 LayerImpl* layer_s1_ptr;
4164 LayerImpl* layer_s2_ptr;
[email protected]94f206c12012-08-25 00:09:144165
[email protected]0634cdd42013-08-16 00:46:094166 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
4167 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:144168
[email protected]aa043632013-03-25 03:39:424169 gfx::Size root_size(1000, 1000);
[email protected]94f206c12012-08-25 00:09:144170
[email protected]aa043632013-03-25 03:39:424171 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:404172 my_host_impl->SetViewportSize(root_size);
[email protected]94f206c12012-08-25 00:09:144173
[email protected]aa043632013-03-25 03:39:424174 scoped_ptr<LayerImpl> root =
4175 LayerImpl::Create(my_host_impl->active_tree(), 1);
4176 root_ptr = root.get();
[email protected]94f206c12012-08-25 00:09:144177
[email protected]aa043632013-03-25 03:39:424178 root->SetAnchorPoint(gfx::PointF());
4179 root->SetPosition(gfx::PointF());
4180 root->SetBounds(root_size);
4181 root->SetContentBounds(root_size);
4182 root->SetDrawsContent(true);
4183 root->SetMasksToBounds(true);
4184 my_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:144185
[email protected]aa043632013-03-25 03:39:424186 AddDrawingLayerTo(root_ptr, 2, gfx::Rect(0, 0, 400, 400), &layer_s1_ptr);
4187 layer_s1_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:144188
[email protected]aa043632013-03-25 03:39:424189 AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(0, 0, 300, 300), 0); // L11
4190 AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(100, 0, 300, 300), 0); // L12
[email protected]94f206c12012-08-25 00:09:144191
[email protected]aa043632013-03-25 03:39:424192 AddDrawingLayerTo(root_ptr, 7, gfx::Rect(200, 0, 300, 300), &layer_s2_ptr);
4193 layer_s2_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:144194
[email protected]aa043632013-03-25 03:39:424195 // Initial draw - must receive all quads
4196 {
4197 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204198 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144199
[email protected]aa043632013-03-25 03:39:424200 // Must receive 3 render passes.
4201 // For Root, there are 2 quads; for S1, there are 3 quads; for S2, there is
4202 // 1 quad.
4203 ASSERT_EQ(3U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144204
[email protected]aa043632013-03-25 03:39:424205 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4206 EXPECT_EQ(3U, frame.render_passes[1]->quad_list.size());
4207 EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144208
[email protected]aa043632013-03-25 03:39:424209 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4210 my_host_impl->DidDrawAllLayers(frame);
4211 }
[email protected]94f206c12012-08-25 00:09:144212
[email protected]aa043632013-03-25 03:39:424213 // "Unocclude" surface S1 and repeat draw.
4214 // Must remove S2's render pass since it's cached;
4215 // Must keep S1 quads because texture contained external occlusion.
4216 gfx::Transform transform = layer_s2_ptr->transform();
4217 transform.Translate(300.0, 0.0);
4218 layer_s2_ptr->SetTransform(transform);
4219 {
4220 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204221 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144222
[email protected]aa043632013-03-25 03:39:424223 // Must receive 2 render passes.
4224 // For Root, there are 2 quads
4225 // For S1, the number of quads depends on what got unoccluded, so not
4226 // asserted beyond being positive.
4227 // For S2, there is no render pass
4228 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144229
[email protected]aa043632013-03-25 03:39:424230 EXPECT_GT(frame.render_passes[0]->quad_list.size(), 0U);
4231 EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144232
[email protected]aa043632013-03-25 03:39:424233 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4234 my_host_impl->DidDrawAllLayers(frame);
4235 }
[email protected]94f206c12012-08-25 00:09:144236}
4237
[email protected]aa043632013-03-25 03:39:424238TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalNotAligned) {
4239 LayerTreeSettings settings;
4240 settings.cache_render_pass_contents = true;
4241 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4242 LayerTreeHostImpl::Create(settings,
4243 this,
4244 &proxy_,
4245 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144246
[email protected]aa043632013-03-25 03:39:424247 // Layers are structured as follows:
4248 //
4249 // R +-- S1 +- L10 (rotated, drawing)
4250 // +- L11 (occupies half surface)
[email protected]94f206c12012-08-25 00:09:144251
[email protected]aa043632013-03-25 03:39:424252 LayerImpl* root_ptr;
4253 LayerImpl* layer_s1_ptr;
[email protected]94f206c12012-08-25 00:09:144254
[email protected]0634cdd42013-08-16 00:46:094255 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
4256 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:144257
[email protected]aa043632013-03-25 03:39:424258 gfx::Size root_size(1000, 1000);
[email protected]94f206c12012-08-25 00:09:144259
[email protected]aa043632013-03-25 03:39:424260 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:404261 my_host_impl->SetViewportSize(root_size);
[email protected]94f206c12012-08-25 00:09:144262
[email protected]aa043632013-03-25 03:39:424263 scoped_ptr<LayerImpl> root =
4264 LayerImpl::Create(my_host_impl->active_tree(), 1);
4265 root_ptr = root.get();
[email protected]94f206c12012-08-25 00:09:144266
[email protected]aa043632013-03-25 03:39:424267 root->SetAnchorPoint(gfx::PointF());
4268 root->SetPosition(gfx::PointF());
4269 root->SetBounds(root_size);
4270 root->SetContentBounds(root_size);
4271 root->SetDrawsContent(true);
4272 root->SetMasksToBounds(true);
4273 my_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:144274
[email protected]aa043632013-03-25 03:39:424275 AddDrawingLayerTo(root_ptr, 2, gfx::Rect(0, 0, 400, 400), &layer_s1_ptr);
4276 layer_s1_ptr->SetForceRenderSurface(true);
4277 gfx::Transform transform = layer_s1_ptr->transform();
4278 transform.Translate(200.0, 200.0);
4279 transform.Rotate(45.0);
4280 transform.Translate(-200.0, -200.0);
4281 layer_s1_ptr->SetTransform(transform);
[email protected]94f206c12012-08-25 00:09:144282
[email protected]aa043632013-03-25 03:39:424283 AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(200, 0, 200, 400), 0); // L11
[email protected]94f206c12012-08-25 00:09:144284
[email protected]aa043632013-03-25 03:39:424285 // Initial draw - must receive all quads
4286 {
4287 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204288 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144289
[email protected]aa043632013-03-25 03:39:424290 // Must receive 2 render passes.
4291 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144292
[email protected]aa043632013-03-25 03:39:424293 EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size());
4294 EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144295
[email protected]aa043632013-03-25 03:39:424296 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4297 my_host_impl->DidDrawAllLayers(frame);
4298 }
[email protected]94f206c12012-08-25 00:09:144299
[email protected]aa043632013-03-25 03:39:424300 // Change opacity and draw. Verify we used cached texture.
4301 layer_s1_ptr->SetOpacity(0.2f);
4302 {
4303 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204304 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144305
[email protected]aa043632013-03-25 03:39:424306 // One render pass must be gone due to cached texture.
4307 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144308
[email protected]aa043632013-03-25 03:39:424309 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144310
[email protected]aa043632013-03-25 03:39:424311 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4312 my_host_impl->DidDrawAllLayers(frame);
4313 }
[email protected]94f206c12012-08-25 00:09:144314}
4315
[email protected]aa043632013-03-25 03:39:424316TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionPartialSwap) {
4317 LayerTreeSettings settings;
4318 settings.minimum_occlusion_tracking_size = gfx::Size();
4319 settings.partial_swap_enabled = true;
4320 settings.cache_render_pass_contents = true;
4321 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4322 LayerTreeHostImpl::Create(settings,
4323 this,
4324 &proxy_,
4325 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144326
[email protected]aa043632013-03-25 03:39:424327 // Layers are structure as follows:
4328 //
4329 // R +-- S1 +- L10 (owning)
4330 // | +- L11
4331 // | +- L12
4332 // |
4333 // +-- S2 +- L20 (owning)
4334 // +- L21
4335 //
4336 // Occlusion:
4337 // L12 occludes L11 (internal)
4338 // L20 occludes L10 (external)
4339 // L21 occludes L20 (internal)
[email protected]94f206c12012-08-25 00:09:144340
[email protected]aa043632013-03-25 03:39:424341 LayerImpl* root_ptr;
4342 LayerImpl* layer_s1_ptr;
4343 LayerImpl* layer_s2_ptr;
[email protected]94f206c12012-08-25 00:09:144344
[email protected]0634cdd42013-08-16 00:46:094345 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
4346 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]94f206c12012-08-25 00:09:144347
[email protected]aa043632013-03-25 03:39:424348 gfx::Size root_size(1000, 1000);
[email protected]94f206c12012-08-25 00:09:144349
[email protected]aa043632013-03-25 03:39:424350 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]18ce59702013-04-09 04:58:404351 my_host_impl->SetViewportSize(root_size);
[email protected]94f206c12012-08-25 00:09:144352
[email protected]aa043632013-03-25 03:39:424353 scoped_ptr<LayerImpl> root =
4354 LayerImpl::Create(my_host_impl->active_tree(), 1);
4355 root_ptr = root.get();
[email protected]94f206c12012-08-25 00:09:144356
[email protected]aa043632013-03-25 03:39:424357 root->SetAnchorPoint(gfx::PointF());
4358 root->SetPosition(gfx::PointF());
4359 root->SetBounds(root_size);
4360 root->SetContentBounds(root_size);
4361 root->SetDrawsContent(true);
4362 root->SetMasksToBounds(true);
4363 my_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]94f206c12012-08-25 00:09:144364
[email protected]aa043632013-03-25 03:39:424365 AddDrawingLayerTo(root_ptr, 2, gfx::Rect(300, 300, 300, 300), &layer_s1_ptr);
4366 layer_s1_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:144367
[email protected]aa043632013-03-25 03:39:424368 AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(10, 10, 10, 10), 0); // L11
4369 AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(0, 0, 30, 30), 0); // L12
[email protected]94f206c12012-08-25 00:09:144370
[email protected]aa043632013-03-25 03:39:424371 AddDrawingLayerTo(root_ptr, 5, gfx::Rect(550, 250, 300, 400), &layer_s2_ptr);
4372 layer_s2_ptr->SetForceRenderSurface(true);
[email protected]94f206c12012-08-25 00:09:144373
[email protected]aa043632013-03-25 03:39:424374 AddDrawingLayerTo(layer_s2_ptr, 6, gfx::Rect(20, 20, 5, 5), 0); // L21
[email protected]94f206c12012-08-25 00:09:144375
[email protected]aa043632013-03-25 03:39:424376 // Initial draw - must receive all quads
4377 {
4378 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204379 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144380
[email protected]aa043632013-03-25 03:39:424381 // Must receive 3 render passes.
4382 // For Root, there are 2 quads; for S1, there are 2 quads (one is occluded);
4383 // for S2, there is 2 quads.
4384 ASSERT_EQ(3U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144385
[email protected]aa043632013-03-25 03:39:424386 EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size());
4387 EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size());
4388 EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144389
[email protected]aa043632013-03-25 03:39:424390 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4391 my_host_impl->DidDrawAllLayers(frame);
4392 }
[email protected]94f206c12012-08-25 00:09:144393
[email protected]aa043632013-03-25 03:39:424394 // "Unocclude" surface S1 and repeat draw.
4395 // Must remove S2's render pass since it's cached;
4396 // Must keep S1 quads because texture contained external occlusion.
4397 gfx::Transform transform = layer_s2_ptr->transform();
4398 transform.Translate(150.0, 150.0);
4399 layer_s2_ptr->SetTransform(transform);
4400 {
4401 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204402 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144403
[email protected]aa043632013-03-25 03:39:424404 // Must receive 2 render passes.
4405 // For Root, there are 2 quads.
4406 // For S1, there are 2 quads.
4407 // For S2, there is no render pass
4408 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144409
[email protected]aa043632013-03-25 03:39:424410 EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size());
4411 EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144412
[email protected]aa043632013-03-25 03:39:424413 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4414 my_host_impl->DidDrawAllLayers(frame);
4415 }
[email protected]94f206c12012-08-25 00:09:144416
[email protected]aa043632013-03-25 03:39:424417 // "Re-occlude" surface S1 and repeat draw.
4418 // Must remove S1's render pass since it is now available in full.
4419 // S2 has no change so must also be removed.
4420 transform = layer_s2_ptr->transform();
4421 transform.Translate(-15.0, -15.0);
4422 layer_s2_ptr->SetTransform(transform);
4423 {
4424 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204425 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144426
[email protected]aa043632013-03-25 03:39:424427 // Root render pass only.
4428 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144429
[email protected]aa043632013-03-25 03:39:424430 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4431 my_host_impl->DidDrawAllLayers(frame);
4432 }
[email protected]94f206c12012-08-25 00:09:144433}
4434
[email protected]aa043632013-03-25 03:39:424435TEST_F(LayerTreeHostImplTest, TextureCachingWithScissor) {
4436 LayerTreeSettings settings;
4437 settings.minimum_occlusion_tracking_size = gfx::Size();
4438 settings.cache_render_pass_contents = true;
4439 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4440 LayerTreeHostImpl::Create(settings,
4441 this,
4442 &proxy_,
4443 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144444
[email protected]aa043632013-03-25 03:39:424445 /*
4446 Layers are created as follows:
[email protected]94f206c12012-08-25 00:09:144447
[email protected]aa043632013-03-25 03:39:424448 +--------------------+
4449 | 1 |
4450 | +-----------+ |
4451 | | 2 | |
4452 | | +-------------------+
4453 | | | 3 |
4454 | | +-------------------+
4455 | | | |
4456 | +-----------+ |
4457 | |
4458 | |
4459 +--------------------+
[email protected]94f206c12012-08-25 00:09:144460
[email protected]aa043632013-03-25 03:39:424461 Layers 1, 2 have render surfaces
4462 */
4463 scoped_ptr<LayerImpl> root =
4464 LayerImpl::Create(my_host_impl->active_tree(), 1);
4465 scoped_ptr<TiledLayerImpl> child =
4466 TiledLayerImpl::Create(my_host_impl->active_tree(), 2);
4467 scoped_ptr<LayerImpl> grand_child =
4468 LayerImpl::Create(my_host_impl->active_tree(), 3);
[email protected]94f206c12012-08-25 00:09:144469
[email protected]aa043632013-03-25 03:39:424470 gfx::Rect root_rect(0, 0, 100, 100);
4471 gfx::Rect child_rect(10, 10, 50, 50);
4472 gfx::Rect grand_child_rect(5, 5, 150, 150);
[email protected]94f206c12012-08-25 00:09:144473
[email protected]0634cdd42013-08-16 00:46:094474 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
4475 scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext)));
[email protected]aa043632013-03-25 03:39:424476 my_host_impl->InitializeRenderer(output_surface.Pass());
[email protected]94f206c12012-08-25 00:09:144477
[email protected]aa043632013-03-25 03:39:424478 root->SetAnchorPoint(gfx::PointF());
4479 root->SetPosition(gfx::PointF(root_rect.x(), root_rect.y()));
4480 root->SetBounds(gfx::Size(root_rect.width(), root_rect.height()));
4481 root->SetContentBounds(root->bounds());
4482 root->SetDrawsContent(true);
4483 root->SetMasksToBounds(true);
[email protected]94f206c12012-08-25 00:09:144484
[email protected]aa043632013-03-25 03:39:424485 child->SetAnchorPoint(gfx::PointF());
4486 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
4487 child->SetOpacity(0.5f);
4488 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
4489 child->SetContentBounds(child->bounds());
4490 child->SetDrawsContent(true);
4491 child->set_skips_draw(false);
[email protected]94f206c12012-08-25 00:09:144492
[email protected]aa043632013-03-25 03:39:424493 // child layer has 10x10 tiles.
4494 scoped_ptr<LayerTilingData> tiler =
4495 LayerTilingData::Create(gfx::Size(10, 10),
4496 LayerTilingData::HAS_BORDER_TEXELS);
4497 tiler->SetBounds(child->content_bounds());
4498 child->SetTilingData(*tiler.get());
[email protected]94f206c12012-08-25 00:09:144499
[email protected]aa043632013-03-25 03:39:424500 grand_child->SetAnchorPoint(gfx::PointF());
4501 grand_child->SetPosition(grand_child_rect.origin());
4502 grand_child->SetBounds(grand_child_rect.size());
4503 grand_child->SetContentBounds(grand_child->bounds());
4504 grand_child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:144505
[email protected]aa043632013-03-25 03:39:424506 TiledLayerImpl* child_ptr = child.get();
4507 RenderPass::Id child_pass_id(child_ptr->id(), 0);
[email protected]94f206c12012-08-25 00:09:144508
[email protected]aa043632013-03-25 03:39:424509 child->AddChild(grand_child.Pass());
4510 root->AddChild(child.PassAs<LayerImpl>());
4511 my_host_impl->active_tree()->SetRootLayer(root.Pass());
[email protected]18ce59702013-04-09 04:58:404512 my_host_impl->SetViewportSize(root_rect.size());
[email protected]94f206c12012-08-25 00:09:144513
[email protected]aa043632013-03-25 03:39:424514 EXPECT_FALSE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId(
4515 child_pass_id));
4516 {
4517 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204518 host_impl_->SetFullRootLayerDamage();
4519 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:424520 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4521 my_host_impl->DidDrawAllLayers(frame);
4522 }
[email protected]94f206c12012-08-25 00:09:144523
[email protected]aa043632013-03-25 03:39:424524 // We should have cached textures for surface 2.
4525 EXPECT_TRUE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId(
4526 child_pass_id));
4527 {
4528 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204529 host_impl_->SetFullRootLayerDamage();
4530 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:424531 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4532 my_host_impl->DidDrawAllLayers(frame);
4533 }
[email protected]94f206c12012-08-25 00:09:144534
[email protected]aa043632013-03-25 03:39:424535 // We should still have cached textures for surface 2 after drawing with no
4536 // damage.
4537 EXPECT_TRUE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId(
4538 child_pass_id));
[email protected]94f206c12012-08-25 00:09:144539
[email protected]aa043632013-03-25 03:39:424540 // Damage a single tile of surface 2.
4541 child_ptr->set_update_rect(gfx::Rect(10, 10, 10, 10));
4542 {
4543 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204544 host_impl_->SetFullRootLayerDamage();
4545 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:424546 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4547 my_host_impl->DidDrawAllLayers(frame);
4548 }
[email protected]94f206c12012-08-25 00:09:144549
[email protected]aa043632013-03-25 03:39:424550 // We should have a cached texture for surface 2 again even though it was
4551 // damaged.
4552 EXPECT_TRUE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId(
4553 child_pass_id));
[email protected]94f206c12012-08-25 00:09:144554}
4555
[email protected]aa043632013-03-25 03:39:424556TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
4557 LayerTreeSettings settings;
4558 settings.minimum_occlusion_tracking_size = gfx::Size();
4559 settings.partial_swap_enabled = true;
4560 settings.cache_render_pass_contents = true;
4561 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4562 LayerTreeHostImpl::Create(settings,
4563 this,
4564 &proxy_,
4565 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144566
[email protected]aa043632013-03-25 03:39:424567 LayerImpl* root_ptr;
4568 LayerImpl* intermediate_layer_ptr;
4569 LayerImpl* surface_layer_ptr;
4570 LayerImpl* child_ptr;
[email protected]94f206c12012-08-25 00:09:144571
[email protected]aa043632013-03-25 03:39:424572 SetupLayersForTextureCaching(my_host_impl.get(),
4573 root_ptr,
4574 intermediate_layer_ptr,
4575 surface_layer_ptr,
4576 child_ptr,
4577 gfx::Size(100, 100));
4578 {
4579 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204580 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144581
[email protected]aa043632013-03-25 03:39:424582 // Must receive two render passes, each with one quad
4583 ASSERT_EQ(2U, frame.render_passes.size());
4584 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4585 EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144586
[email protected]aa043632013-03-25 03:39:424587 EXPECT_EQ(DrawQuad::RENDER_PASS,
4588 frame.render_passes[1]->quad_list[0]->material);
4589 const RenderPassDrawQuad* quad =
4590 RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]);
4591 RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id];
4592 ASSERT_TRUE(target_pass);
4593 EXPECT_FALSE(target_pass->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144594
[email protected]aa043632013-03-25 03:39:424595 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4596 my_host_impl->DidDrawAllLayers(frame);
4597 }
[email protected]94f206c12012-08-25 00:09:144598
[email protected]aa043632013-03-25 03:39:424599 // Draw without any change
4600 {
4601 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204602 my_host_impl->SetFullRootLayerDamage();
4603 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144604
[email protected]aa043632013-03-25 03:39:424605 // Must receive one render pass, as the other one should be culled
4606 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144607
[email protected]aa043632013-03-25 03:39:424608 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4609 EXPECT_EQ(DrawQuad::RENDER_PASS,
4610 frame.render_passes[0]->quad_list[0]->material);
4611 const RenderPassDrawQuad* quad =
4612 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4613 EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) ==
4614 frame.render_passes_by_id.end());
[email protected]94f206c12012-08-25 00:09:144615
[email protected]aa043632013-03-25 03:39:424616 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4617 my_host_impl->DidDrawAllLayers(frame);
4618 }
[email protected]94f206c12012-08-25 00:09:144619
[email protected]aa043632013-03-25 03:39:424620 // Change opacity and draw
4621 surface_layer_ptr->SetOpacity(0.6f);
4622 {
4623 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204624 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144625
[email protected]aa043632013-03-25 03:39:424626 // Must receive one render pass, as the other one should be culled
4627 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144628
[email protected]aa043632013-03-25 03:39:424629 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4630 EXPECT_EQ(DrawQuad::RENDER_PASS,
4631 frame.render_passes[0]->quad_list[0]->material);
4632 const RenderPassDrawQuad* quad =
4633 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4634 EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) ==
4635 frame.render_passes_by_id.end());
[email protected]94f206c12012-08-25 00:09:144636
[email protected]aa043632013-03-25 03:39:424637 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4638 my_host_impl->DidDrawAllLayers(frame);
4639 }
[email protected]94f206c12012-08-25 00:09:144640
[email protected]aa043632013-03-25 03:39:424641 // Change less benign property and draw - should have contents changed flag
4642 surface_layer_ptr->SetStackingOrderChanged(true);
4643 {
4644 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204645 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144646
[email protected]aa043632013-03-25 03:39:424647 // Must receive two render passes, each with one quad
4648 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144649
[email protected]aa043632013-03-25 03:39:424650 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4651 EXPECT_EQ(DrawQuad::SOLID_COLOR,
4652 frame.render_passes[0]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:144653
[email protected]aa043632013-03-25 03:39:424654 EXPECT_EQ(DrawQuad::RENDER_PASS,
4655 frame.render_passes[1]->quad_list[0]->material);
4656 const RenderPassDrawQuad* quad =
4657 RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]);
4658 RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id];
4659 ASSERT_TRUE(target_pass);
4660 EXPECT_FALSE(target_pass->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144661
[email protected]aa043632013-03-25 03:39:424662 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4663 my_host_impl->DidDrawAllLayers(frame);
4664 }
[email protected]94f206c12012-08-25 00:09:144665
[email protected]aa043632013-03-25 03:39:424666 // Change opacity again, and evict the cached surface texture.
4667 surface_layer_ptr->SetOpacity(0.5f);
4668 static_cast<GLRendererWithReleaseTextures*>(
4669 my_host_impl->renderer())->ReleaseRenderPassTextures();
[email protected]94f206c12012-08-25 00:09:144670
[email protected]aa043632013-03-25 03:39:424671 // Change opacity and draw
4672 surface_layer_ptr->SetOpacity(0.6f);
4673 {
4674 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204675 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144676
[email protected]aa043632013-03-25 03:39:424677 // Must receive two render passes
4678 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144679
[email protected]aa043632013-03-25 03:39:424680 // Even though not enough properties changed, the entire thing must be
4681 // redrawn as we don't have cached textures
4682 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4683 EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144684
[email protected]aa043632013-03-25 03:39:424685 EXPECT_EQ(DrawQuad::RENDER_PASS,
4686 frame.render_passes[1]->quad_list[0]->material);
4687 const RenderPassDrawQuad* quad =
4688 RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]);
4689 RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id];
4690 ASSERT_TRUE(target_pass);
4691 EXPECT_TRUE(target_pass->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144692
[email protected]aa043632013-03-25 03:39:424693 // Was our surface evicted?
4694 EXPECT_FALSE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId(
4695 target_pass->id));
[email protected]94f206c12012-08-25 00:09:144696
[email protected]aa043632013-03-25 03:39:424697 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4698 my_host_impl->DidDrawAllLayers(frame);
4699 }
[email protected]94f206c12012-08-25 00:09:144700
[email protected]aa043632013-03-25 03:39:424701 // Draw without any change, to make sure the state is clear
4702 {
4703 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204704 my_host_impl->SetFullRootLayerDamage();
4705 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144706
[email protected]aa043632013-03-25 03:39:424707 // Must receive one render pass, as the other one should be culled
4708 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144709
[email protected]aa043632013-03-25 03:39:424710 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4711 EXPECT_EQ(DrawQuad::RENDER_PASS,
4712 frame.render_passes[0]->quad_list[0]->material);
4713 const RenderPassDrawQuad* quad =
4714 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4715 EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) ==
4716 frame.render_passes_by_id.end());
[email protected]94f206c12012-08-25 00:09:144717
[email protected]aa043632013-03-25 03:39:424718 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4719 my_host_impl->DidDrawAllLayers(frame);
4720 }
[email protected]94f206c12012-08-25 00:09:144721
[email protected]aa043632013-03-25 03:39:424722 // Change location of the intermediate layer
4723 gfx::Transform transform = intermediate_layer_ptr->transform();
4724 transform.matrix().setDouble(0, 3, 1.0001);
4725 intermediate_layer_ptr->SetTransform(transform);
4726 {
4727 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204728 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144729
[email protected]aa043632013-03-25 03:39:424730 // Must receive one render pass, as the other one should be culled.
4731 ASSERT_EQ(1U, frame.render_passes.size());
4732 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144733
[email protected]aa043632013-03-25 03:39:424734 EXPECT_EQ(DrawQuad::RENDER_PASS,
4735 frame.render_passes[0]->quad_list[0]->material);
4736 const RenderPassDrawQuad* quad =
4737 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4738 EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) ==
4739 frame.render_passes_by_id.end());
[email protected]94f206c12012-08-25 00:09:144740
[email protected]aa043632013-03-25 03:39:424741 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4742 my_host_impl->DidDrawAllLayers(frame);
4743 }
[email protected]94f206c12012-08-25 00:09:144744}
4745
[email protected]aa043632013-03-25 03:39:424746TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
4747 LayerTreeSettings settings;
4748 settings.minimum_occlusion_tracking_size = gfx::Size();
4749 settings.cache_render_pass_contents = true;
4750 scoped_ptr<LayerTreeHostImpl> my_host_impl =
4751 LayerTreeHostImpl::Create(settings,
4752 this,
4753 &proxy_,
4754 &stats_instrumentation_);
[email protected]94f206c12012-08-25 00:09:144755
[email protected]aa043632013-03-25 03:39:424756 LayerImpl* root_ptr;
4757 LayerImpl* intermediate_layer_ptr;
4758 LayerImpl* surface_layer_ptr;
4759 LayerImpl* child_ptr;
[email protected]94f206c12012-08-25 00:09:144760
[email protected]aa043632013-03-25 03:39:424761 SetupLayersForTextureCaching(my_host_impl.get(),
4762 root_ptr,
4763 intermediate_layer_ptr,
4764 surface_layer_ptr,
4765 child_ptr,
4766 gfx::Size(100, 100));
4767 {
4768 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204769 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144770
[email protected]aa043632013-03-25 03:39:424771 // Must receive two render passes, each with one quad
4772 ASSERT_EQ(2U, frame.render_passes.size());
4773 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4774 EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144775
[email protected]aa043632013-03-25 03:39:424776 EXPECT_EQ(DrawQuad::RENDER_PASS,
4777 frame.render_passes[1]->quad_list[0]->material);
4778 const RenderPassDrawQuad* quad =
4779 RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]);
4780 RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id];
4781 EXPECT_FALSE(target_pass->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144782
[email protected]aa043632013-03-25 03:39:424783 EXPECT_FALSE(frame.render_passes[0]->damage_rect.IsEmpty());
4784 EXPECT_FALSE(frame.render_passes[1]->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144785
[email protected]aa043632013-03-25 03:39:424786 EXPECT_FALSE(
4787 frame.render_passes[0]->has_occlusion_from_outside_target_surface);
4788 EXPECT_FALSE(
4789 frame.render_passes[1]->has_occlusion_from_outside_target_surface);
[email protected]94f206c12012-08-25 00:09:144790
[email protected]aa043632013-03-25 03:39:424791 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4792 my_host_impl->DidDrawAllLayers(frame);
4793 }
[email protected]94f206c12012-08-25 00:09:144794
[email protected]aa043632013-03-25 03:39:424795 // Draw without any change
4796 {
4797 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204798 my_host_impl->SetFullRootLayerDamage();
4799 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144800
[email protected]aa043632013-03-25 03:39:424801 // Even though there was no change, we set the damage to entire viewport.
4802 // One of the passes should be culled as a result, since contents didn't
4803 // change and we have cached texture.
4804 ASSERT_EQ(1U, frame.render_passes.size());
4805 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144806
[email protected]aa043632013-03-25 03:39:424807 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4808 my_host_impl->DidDrawAllLayers(frame);
4809 }
[email protected]94f206c12012-08-25 00:09:144810
[email protected]aa043632013-03-25 03:39:424811 // Change opacity and draw
4812 surface_layer_ptr->SetOpacity(0.6f);
4813 {
4814 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204815 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144816
[email protected]aa043632013-03-25 03:39:424817 // Must receive one render pass, as the other one should be culled
4818 ASSERT_EQ(1U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144819
[email protected]aa043632013-03-25 03:39:424820 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4821 EXPECT_EQ(DrawQuad::RENDER_PASS,
4822 frame.render_passes[0]->quad_list[0]->material);
4823 const RenderPassDrawQuad* quad =
4824 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4825 EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) ==
4826 frame.render_passes_by_id.end());
[email protected]94f206c12012-08-25 00:09:144827
[email protected]aa043632013-03-25 03:39:424828 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4829 my_host_impl->DidDrawAllLayers(frame);
4830 }
[email protected]94f206c12012-08-25 00:09:144831
[email protected]aa043632013-03-25 03:39:424832 // Change less benign property and draw - should have contents changed flag
4833 surface_layer_ptr->SetStackingOrderChanged(true);
4834 {
4835 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204836 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144837
[email protected]aa043632013-03-25 03:39:424838 // Must receive two render passes, each with one quad
4839 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144840
[email protected]aa043632013-03-25 03:39:424841 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4842 EXPECT_EQ(DrawQuad::SOLID_COLOR,
4843 frame.render_passes[0]->quad_list[0]->material);
[email protected]94f206c12012-08-25 00:09:144844
[email protected]aa043632013-03-25 03:39:424845 EXPECT_EQ(DrawQuad::RENDER_PASS,
4846 frame.render_passes[1]->quad_list[0]->material);
4847 const RenderPassDrawQuad* quad =
4848 RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]);
4849 RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id];
4850 ASSERT_TRUE(target_pass);
4851 EXPECT_FALSE(target_pass->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144852
[email protected]aa043632013-03-25 03:39:424853 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4854 my_host_impl->DidDrawAllLayers(frame);
4855 }
[email protected]94f206c12012-08-25 00:09:144856
[email protected]aa043632013-03-25 03:39:424857 // Change opacity again, and evict the cached surface texture.
4858 surface_layer_ptr->SetOpacity(0.5f);
4859 static_cast<GLRendererWithReleaseTextures*>(
4860 my_host_impl->renderer())->ReleaseRenderPassTextures();
[email protected]94f206c12012-08-25 00:09:144861
[email protected]aa043632013-03-25 03:39:424862 // Change opacity and draw
4863 surface_layer_ptr->SetOpacity(0.6f);
4864 {
4865 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204866 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144867
[email protected]aa043632013-03-25 03:39:424868 // Must receive two render passes
4869 ASSERT_EQ(2U, frame.render_passes.size());
[email protected]94f206c12012-08-25 00:09:144870
[email protected]aa043632013-03-25 03:39:424871 // Even though not enough properties changed, the entire thing must be
4872 // redrawn as we don't have cached textures
4873 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
4874 EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144875
[email protected]aa043632013-03-25 03:39:424876 EXPECT_EQ(DrawQuad::RENDER_PASS,
4877 frame.render_passes[1]->quad_list[0]->material);
4878 const RenderPassDrawQuad* quad =
4879 RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]);
4880 RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id];
4881 ASSERT_TRUE(target_pass);
4882 EXPECT_TRUE(target_pass->damage_rect.IsEmpty());
[email protected]94f206c12012-08-25 00:09:144883
[email protected]aa043632013-03-25 03:39:424884 // Was our surface evicted?
4885 EXPECT_FALSE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId(
4886 target_pass->id));
[email protected]94f206c12012-08-25 00:09:144887
[email protected]aa043632013-03-25 03:39:424888 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4889 my_host_impl->DidDrawAllLayers(frame);
4890 }
[email protected]94f206c12012-08-25 00:09:144891
[email protected]aa043632013-03-25 03:39:424892 // Draw without any change, to make sure the state is clear
4893 {
4894 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204895 my_host_impl->SetFullRootLayerDamage();
4896 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144897
[email protected]aa043632013-03-25 03:39:424898 // Even though there was no change, we set the damage to entire viewport.
4899 // One of the passes should be culled as a result, since contents didn't
4900 // change and we have cached texture.
4901 ASSERT_EQ(1U, frame.render_passes.size());
4902 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144903
[email protected]aa043632013-03-25 03:39:424904 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4905 my_host_impl->DidDrawAllLayers(frame);
4906 }
[email protected]94f206c12012-08-25 00:09:144907
[email protected]aa043632013-03-25 03:39:424908 // Change location of the intermediate layer
4909 gfx::Transform transform = intermediate_layer_ptr->transform();
4910 transform.matrix().setDouble(0, 3, 1.0001);
4911 intermediate_layer_ptr->SetTransform(transform);
4912 {
4913 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:204914 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
[email protected]94f206c12012-08-25 00:09:144915
[email protected]aa043632013-03-25 03:39:424916 // Must receive one render pass, as the other one should be culled.
4917 ASSERT_EQ(1U, frame.render_passes.size());
4918 EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
[email protected]94f206c12012-08-25 00:09:144919
[email protected]aa043632013-03-25 03:39:424920 EXPECT_EQ(DrawQuad::RENDER_PASS,
4921 frame.render_passes[0]->quad_list[0]->material);
4922 const RenderPassDrawQuad* quad =
4923 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
4924 EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) ==
4925 frame.render_passes_by_id.end());
[email protected]94f206c12012-08-25 00:09:144926
[email protected]aa043632013-03-25 03:39:424927 my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
4928 my_host_impl->DidDrawAllLayers(frame);
4929 }
[email protected]94f206c12012-08-25 00:09:144930}
4931
[email protected]aa043632013-03-25 03:39:424932TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
4933 set_reduce_memory_result(false);
[email protected]b1969fa2012-10-17 20:16:294934
[email protected]d7626ffd2013-03-29 00:17:424935 // If changing the memory limit wouldn't result in changing what was
4936 // committed, then no commit should be requested.
[email protected]aa043632013-03-25 03:39:424937 set_reduce_memory_result(false);
[email protected]d7626ffd2013-03-29 00:17:424938 host_impl_->set_max_memory_needed_bytes(
4939 host_impl_->memory_allocation_limit_bytes() - 1);
[email protected]fd32d122013-06-29 13:11:044940 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:074941 host_impl_->memory_allocation_limit_bytes() - 1));
4942 host_impl_->SetDiscardBackBufferWhenNotVisible(true);
[email protected]d7626ffd2013-03-29 00:17:424943 EXPECT_FALSE(did_request_commit_);
4944 did_request_commit_ = false;
4945
4946 // If changing the memory limit would result in changing what was
4947 // committed, then a commit should be requested, even though nothing was
4948 // evicted.
4949 set_reduce_memory_result(false);
4950 host_impl_->set_max_memory_needed_bytes(
4951 host_impl_->memory_allocation_limit_bytes());
[email protected]fd32d122013-06-29 13:11:044952 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:074953 host_impl_->memory_allocation_limit_bytes() - 1));
4954 host_impl_->SetDiscardBackBufferWhenNotVisible(true);
[email protected]aa043632013-03-25 03:39:424955 EXPECT_TRUE(did_request_commit_);
4956 did_request_commit_ = false;
[email protected]b1969fa2012-10-17 20:16:294957
[email protected]aa043632013-03-25 03:39:424958 // Especially if changing the memory limit caused evictions, we need
4959 // to re-commit.
4960 set_reduce_memory_result(true);
[email protected]d7626ffd2013-03-29 00:17:424961 host_impl_->set_max_memory_needed_bytes(1);
[email protected]fd32d122013-06-29 13:11:044962 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:074963 host_impl_->memory_allocation_limit_bytes() - 1));
4964 host_impl_->SetDiscardBackBufferWhenNotVisible(true);
[email protected]aa043632013-03-25 03:39:424965 EXPECT_TRUE(did_request_commit_);
4966 did_request_commit_ = false;
[email protected]b1969fa2012-10-17 20:16:294967
[email protected]aa043632013-03-25 03:39:424968 // But if we set it to the same value that it was before, we shouldn't
4969 // re-commit.
[email protected]fd32d122013-06-29 13:11:044970 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
[email protected]3f2ff112013-08-03 02:41:074971 host_impl_->memory_allocation_limit_bytes()));
4972 host_impl_->SetDiscardBackBufferWhenNotVisible(true);
[email protected]aa043632013-03-25 03:39:424973 EXPECT_FALSE(did_request_commit_);
[email protected]94f206c12012-08-25 00:09:144974}
4975
[email protected]96baf3e2012-10-22 23:09:554976struct RenderPassRemovalTestData : public LayerTreeHostImpl::FrameData {
[email protected]03c43ec2013-08-30 02:41:324977 base::ScopedPtrHashMap<RenderPass::Id, TestRenderPass> render_pass_cache;
[email protected]aa043632013-03-25 03:39:424978 scoped_ptr<SharedQuadState> shared_quad_state;
[email protected]94f206c12012-08-25 00:09:144979};
4980
[email protected]96baf3e2012-10-22 23:09:554981class TestRenderer : public GLRenderer, public RendererClient {
[email protected]aa043632013-03-25 03:39:424982 public:
4983 static scoped_ptr<TestRenderer> Create(ResourceProvider* resource_provider,
4984 OutputSurface* output_surface,
4985 Proxy* proxy) {
4986 scoped_ptr<TestRenderer> renderer(new TestRenderer(resource_provider,
4987 output_surface,
4988 proxy));
4989 if (!renderer->Initialize())
4990 return scoped_ptr<TestRenderer>();
[email protected]94f206c12012-08-25 00:09:144991
[email protected]aa043632013-03-25 03:39:424992 return renderer.Pass();
4993 }
[email protected]94f206c12012-08-25 00:09:144994
[email protected]aa043632013-03-25 03:39:424995 void ClearCachedTextures() { textures_.clear(); }
4996 void SetHaveCachedResourcesForRenderPassId(RenderPass::Id id) {
4997 textures_.insert(id);
4998 }
[email protected]94f206c12012-08-25 00:09:144999
[email protected]aa043632013-03-25 03:39:425000 virtual bool HaveCachedResourcesForRenderPassId(RenderPass::Id id) const
5001 OVERRIDE {
5002 return textures_.count(id);
5003 }
[email protected]94f206c12012-08-25 00:09:145004
[email protected]aa043632013-03-25 03:39:425005 // RendererClient implementation.
[email protected]f224cc92013-06-06 23:23:325006 virtual gfx::Rect DeviceViewport() const OVERRIDE {
5007 return gfx::Rect(viewport_size_);
[email protected]aa043632013-03-25 03:39:425008 }
[email protected]54af03522013-09-05 00:43:285009 virtual gfx::Rect DeviceClip() const OVERRIDE {
5010 return DeviceViewport();
5011 }
[email protected]94c40e6292013-05-24 22:01:505012 virtual float DeviceScaleFactor() const OVERRIDE {
5013 return 1.f;
5014 }
[email protected]aa043632013-03-25 03:39:425015 virtual const LayerTreeSettings& Settings() const OVERRIDE {
5016 return settings_;
5017 }
[email protected]aa043632013-03-25 03:39:425018 virtual void SetFullRootLayerDamage() OVERRIDE {}
[email protected]aa043632013-03-25 03:39:425019 virtual bool HasImplThread() const OVERRIDE { return false; }
5020 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; }
5021 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const
5022 OVERRIDE { return CompositorFrameMetadata(); }
[email protected]73673592013-04-03 22:14:325023 virtual bool AllowPartialSwap() const OVERRIDE {
5024 return true;
5025 }
[email protected]c32a1962013-07-30 19:41:175026 virtual bool ExternalStencilTestEnabled() const OVERRIDE { return false; }
[email protected]94f206c12012-08-25 00:09:145027
[email protected]aa043632013-03-25 03:39:425028 protected:
5029 TestRenderer(ResourceProvider* resource_provider,
5030 OutputSurface* output_surface,
5031 Proxy* proxy)
[email protected]075d8aa2013-04-01 23:03:115032 : GLRenderer(this, output_surface, resource_provider, 0) {}
[email protected]94f206c12012-08-25 00:09:145033
[email protected]aa043632013-03-25 03:39:425034 private:
5035 LayerTreeSettings settings_;
5036 gfx::Size viewport_size_;
5037 base::hash_set<RenderPass::Id> textures_;
[email protected]94f206c12012-08-25 00:09:145038};
5039
[email protected]aa043632013-03-25 03:39:425040static void ConfigureRenderPassTestData(const char* test_script,
[email protected]d002dd02013-03-27 07:40:405041 RenderPassRemovalTestData* test_data,
[email protected]aa043632013-03-25 03:39:425042 TestRenderer* renderer) {
5043 renderer->ClearCachedTextures();
[email protected]94f206c12012-08-25 00:09:145044
[email protected]aa043632013-03-25 03:39:425045 // One shared state for all quads - we don't need the correct details
[email protected]d002dd02013-03-27 07:40:405046 test_data->shared_quad_state = SharedQuadState::Create();
5047 test_data->shared_quad_state->SetAll(gfx::Transform(),
5048 gfx::Size(),
5049 gfx::Rect(),
5050 gfx::Rect(),
5051 false,
5052 1.f);
[email protected]94f206c12012-08-25 00:09:145053
[email protected]aa043632013-03-25 03:39:425054 const char* current_char = test_script;
[email protected]94f206c12012-08-25 00:09:145055
[email protected]aa043632013-03-25 03:39:425056 // Pre-create root pass
5057 RenderPass::Id root_render_pass_id =
5058 RenderPass::Id(test_script[0], test_script[1]);
5059 scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
5060 pass->SetNew(root_render_pass_id, gfx::Rect(), gfx::Rect(), gfx::Transform());
[email protected]d002dd02013-03-27 07:40:405061 test_data->render_pass_cache.add(root_render_pass_id, pass.Pass());
[email protected]aa043632013-03-25 03:39:425062 while (*current_char) {
5063 int layer_id = *current_char;
5064 current_char++;
5065 ASSERT_TRUE(current_char);
5066 int index = *current_char;
5067 current_char++;
[email protected]0f077a52012-09-08 01:45:245068
[email protected]aa043632013-03-25 03:39:425069 RenderPass::Id render_pass_id = RenderPass::Id(layer_id, index);
[email protected]94f206c12012-08-25 00:09:145070
[email protected]aa043632013-03-25 03:39:425071 bool is_replica = false;
[email protected]d002dd02013-03-27 07:40:405072 if (!test_data->render_pass_cache.contains(render_pass_id))
[email protected]aa043632013-03-25 03:39:425073 is_replica = true;
[email protected]94f206c12012-08-25 00:09:145074
[email protected]aa043632013-03-25 03:39:425075 scoped_ptr<TestRenderPass> render_pass =
[email protected]d002dd02013-03-27 07:40:405076 test_data->render_pass_cache.take(render_pass_id);
[email protected]94f206c12012-08-25 00:09:145077
[email protected]aa043632013-03-25 03:39:425078 // Cycle through quad data and create all quads.
5079 while (*current_char && *current_char != '\n') {
5080 if (*current_char == 's') {
5081 // Solid color draw quad.
5082 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
[email protected]d002dd02013-03-27 07:40:405083 quad->SetNew(test_data->shared_quad_state.get(),
[email protected]aa043632013-03-25 03:39:425084 gfx::Rect(0, 0, 10, 10),
[email protected]10a30b12013-05-02 16:42:115085 SK_ColorWHITE,
5086 false);
[email protected]4c91aec2012-12-15 20:17:185087
[email protected]aa043632013-03-25 03:39:425088 render_pass->AppendQuad(quad.PassAs<DrawQuad>());
5089 current_char++;
5090 } else if ((*current_char >= 'A') && (*current_char <= 'Z')) {
5091 // RenderPass draw quad.
5092 int layer_id = *current_char;
5093 current_char++;
5094 ASSERT_TRUE(current_char);
5095 int index = *current_char;
5096 current_char++;
5097 RenderPass::Id new_render_pass_id = RenderPass::Id(layer_id, index);
5098 ASSERT_NE(root_render_pass_id, new_render_pass_id);
5099 bool has_texture = false;
5100 bool contents_changed = true;
[email protected]4c91aec2012-12-15 20:17:185101
[email protected]aa043632013-03-25 03:39:425102 if (*current_char == '[') {
5103 current_char++;
5104 while (*current_char && *current_char != ']') {
5105 switch (*current_char) {
5106 case 'c':
5107 contents_changed = false;
[email protected]94f206c12012-08-25 00:09:145108 break;
[email protected]aa043632013-03-25 03:39:425109 case 't':
5110 has_texture = true;
[email protected]94f206c12012-08-25 00:09:145111 break;
5112 }
[email protected]aa043632013-03-25 03:39:425113 current_char++;
5114 }
5115 if (*current_char == ']')
5116 current_char++;
[email protected]94f206c12012-08-25 00:09:145117 }
[email protected]aa043632013-03-25 03:39:425118
[email protected]d002dd02013-03-27 07:40:405119 if (test_data->render_pass_cache.find(new_render_pass_id) ==
5120 test_data->render_pass_cache.end()) {
[email protected]aa043632013-03-25 03:39:425121 if (has_texture)
5122 renderer->SetHaveCachedResourcesForRenderPassId(new_render_pass_id);
5123
5124 scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
5125 pass->SetNew(new_render_pass_id,
5126 gfx::Rect(),
5127 gfx::Rect(),
5128 gfx::Transform());
[email protected]d002dd02013-03-27 07:40:405129 test_data->render_pass_cache.add(new_render_pass_id, pass.Pass());
[email protected]aa043632013-03-25 03:39:425130 }
5131
5132 gfx::Rect quad_rect = gfx::Rect(0, 0, 1, 1);
5133 gfx::Rect contents_changed_rect =
5134 contents_changed ? quad_rect : gfx::Rect();
5135 scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
[email protected]d002dd02013-03-27 07:40:405136 quad->SetNew(test_data->shared_quad_state.get(),
[email protected]aa043632013-03-25 03:39:425137 quad_rect,
5138 new_render_pass_id,
5139 is_replica,
5140 1,
5141 contents_changed_rect,
5142 gfx::RectF(0.f, 0.f, 1.f, 1.f),
[email protected]ae6b1a72013-06-25 18:49:295143 FilterOperations(),
[email protected]aa043632013-03-25 03:39:425144 skia::RefPtr<SkImageFilter>(),
[email protected]ae6b1a72013-06-25 18:49:295145 FilterOperations());
[email protected]aa043632013-03-25 03:39:425146 render_pass->AppendQuad(quad.PassAs<DrawQuad>());
5147 }
[email protected]94f206c12012-08-25 00:09:145148 }
[email protected]d002dd02013-03-27 07:40:405149 test_data->render_passes_by_id[render_pass_id] = render_pass.get();
5150 test_data->render_passes.insert(test_data->render_passes.begin(),
5151 render_pass.PassAs<RenderPass>());
[email protected]aa043632013-03-25 03:39:425152 if (*current_char)
5153 current_char++;
5154 }
[email protected]94f206c12012-08-25 00:09:145155}
5156
[email protected]aa043632013-03-25 03:39:425157void DumpRenderPassTestData(const RenderPassRemovalTestData& test_data,
5158 char* buffer) {
5159 char* pos = buffer;
5160 for (RenderPassList::const_reverse_iterator it =
5161 test_data.render_passes.rbegin();
5162 it != test_data.render_passes.rend();
5163 ++it) {
5164 const RenderPass* current_pass = *it;
5165 *pos = current_pass->id.layer_id;
5166 pos++;
5167 *pos = current_pass->id.index;
5168 pos++;
5169
5170 QuadList::const_iterator quad_list_iterator =
5171 current_pass->quad_list.begin();
5172 while (quad_list_iterator != current_pass->quad_list.end()) {
5173 DrawQuad* current_quad = *quad_list_iterator;
5174 switch (current_quad->material) {
5175 case DrawQuad::SOLID_COLOR:
5176 *pos = 's';
5177 pos++;
5178 break;
5179 case DrawQuad::RENDER_PASS:
5180 *pos = RenderPassDrawQuad::MaterialCast(current_quad)->
5181 render_pass_id.layer_id;
5182 pos++;
5183 *pos = RenderPassDrawQuad::MaterialCast(current_quad)->
5184 render_pass_id.index;
5185 pos++;
5186 break;
5187 default:
5188 *pos = 'x';
5189 pos++;
5190 break;
5191 }
5192
5193 quad_list_iterator++;
5194 }
5195 *pos = '\n';
5196 pos++;
5197 }
5198 *pos = '\0';
5199}
5200
5201// Each RenderPassList is represented by a string which describes the
5202// configuration.
[email protected]94f206c12012-08-25 00:09:145203// The syntax of the string is as follows:
5204//
[email protected]aa043632013-03-25 03:39:425205// RsssssX[c]ssYsssZ[t]ssW[ct]
5206// Identifies the render pass------------------------^ ^^^ ^ ^ ^ ^ ^
5207// These are solid color quads--------------------------+ | | | | |
5208// Identifies RenderPassDrawQuad's RenderPass--------------+ | | | |
5209// This quad's contents didn't change------------------------+ | | |
5210// This quad's contents changed and it has no texture------------+ | |
5211// This quad has texture but its contents changed----------------------+ |
5212// This quad's contents didn't change and it has texture - will be removed---+
[email protected]94f206c12012-08-25 00:09:145213//
[email protected]aa043632013-03-25 03:39:425214// Expected results have exactly the same syntax, except they do not use square
5215// brackets, since we only check the structure, not attributes.
[email protected]94f206c12012-08-25 00:09:145216//
[email protected]aa043632013-03-25 03:39:425217// Test case configuration consists of initialization script and expected
5218// results, all in the same format.
[email protected]94f206c12012-08-25 00:09:145219struct TestCase {
[email protected]aa043632013-03-25 03:39:425220 const char* name;
5221 const char* init_script;
5222 const char* expected_result;
[email protected]94f206c12012-08-25 00:09:145223};
5224
[email protected]aa043632013-03-25 03:39:425225TestCase remove_render_passes_cases[] = {
5226 {
5227 "Single root pass",
5228 "R0ssss\n",
5229 "R0ssss\n"
[email protected]8591a642013-04-17 18:48:565230 }, {
[email protected]aa043632013-03-25 03:39:425231 "Single pass - no quads",
5232 "R0\n",
5233 "R0\n"
[email protected]8591a642013-04-17 18:48:565234 }, {
[email protected]aa043632013-03-25 03:39:425235 "Two passes, no removal",
5236 "R0ssssA0sss\n"
5237 "A0ssss\n",
5238 "R0ssssA0sss\n"
5239 "A0ssss\n"
[email protected]8591a642013-04-17 18:48:565240 }, {
[email protected]aa043632013-03-25 03:39:425241 "Two passes, remove last",
5242 "R0ssssA0[ct]sss\n"
5243 "A0ssss\n",
5244 "R0ssssA0sss\n"
[email protected]8591a642013-04-17 18:48:565245 }, {
[email protected]aa043632013-03-25 03:39:425246 "Have texture but contents changed - leave pass",
5247 "R0ssssA0[t]sss\n"
5248 "A0ssss\n",
5249 "R0ssssA0sss\n"
5250 "A0ssss\n"
[email protected]8591a642013-04-17 18:48:565251 }, {
[email protected]aa043632013-03-25 03:39:425252 "Contents didn't change but no texture - leave pass",
5253 "R0ssssA0[c]sss\n"
5254 "A0ssss\n",
5255 "R0ssssA0sss\n"
5256 "A0ssss\n"
[email protected]8591a642013-04-17 18:48:565257 }, {
[email protected]aa043632013-03-25 03:39:425258 "Replica: two quads reference the same pass; remove",
5259 "R0ssssA0[ct]A0[ct]sss\n"
5260 "A0ssss\n",
5261 "R0ssssA0A0sss\n"
[email protected]8591a642013-04-17 18:48:565262 }, {
[email protected]aa043632013-03-25 03:39:425263 "Replica: two quads reference the same pass; leave",
5264 "R0ssssA0[c]A0[c]sss\n"
5265 "A0ssss\n",
5266 "R0ssssA0A0sss\n"
5267 "A0ssss\n",
[email protected]8591a642013-04-17 18:48:565268 }, {
[email protected]aa043632013-03-25 03:39:425269 "Many passes, remove all",
5270 "R0ssssA0[ct]sss\n"
5271 "A0sssB0[ct]C0[ct]s\n"
5272 "B0sssD0[ct]ssE0[ct]F0[ct]\n"
5273 "E0ssssss\n"
5274 "C0G0[ct]\n"
5275 "D0sssssss\n"
5276 "F0sssssss\n"
5277 "G0sss\n",
[email protected]94f206c12012-08-25 00:09:145278
[email protected]aa043632013-03-25 03:39:425279 "R0ssssA0sss\n"
[email protected]8591a642013-04-17 18:48:565280 }, {
[email protected]aa043632013-03-25 03:39:425281 "Deep recursion, remove all",
[email protected]94f206c12012-08-25 00:09:145282
[email protected]aa043632013-03-25 03:39:425283 "R0sssssA0[ct]ssss\n"
5284 "A0ssssB0sss\n"
5285 "B0C0\n"
5286 "C0D0\n"
5287 "D0E0\n"
5288 "E0F0\n"
5289 "F0G0\n"
5290 "G0H0\n"
5291 "H0sssI0sss\n"
5292 "I0J0\n"
5293 "J0ssss\n",
[email protected]4c91aec2012-12-15 20:17:185294
[email protected]aa043632013-03-25 03:39:425295 "R0sssssA0ssss\n"
[email protected]8591a642013-04-17 18:48:565296 }, {
[email protected]aa043632013-03-25 03:39:425297 "Wide recursion, remove all",
5298 "R0A0[ct]B0[ct]C0[ct]D0[ct]E0[ct]F0[ct]G0[ct]H0[ct]I0[ct]J0[ct]\n"
5299 "A0s\n"
5300 "B0s\n"
5301 "C0ssss\n"
5302 "D0ssss\n"
5303 "E0s\n"
5304 "F0\n"
5305 "G0s\n"
5306 "H0s\n"
5307 "I0s\n"
5308 "J0ssss\n",
[email protected]4c91aec2012-12-15 20:17:185309
[email protected]aa043632013-03-25 03:39:425310 "R0A0B0C0D0E0F0G0H0I0J0\n"
[email protected]8591a642013-04-17 18:48:565311 }, {
[email protected]aa043632013-03-25 03:39:425312 "Remove passes regardless of cache state",
5313 "R0ssssA0[ct]sss\n"
5314 "A0sssB0C0s\n"
5315 "B0sssD0[c]ssE0[t]F0\n"
5316 "E0ssssss\n"
5317 "C0G0\n"
5318 "D0sssssss\n"
5319 "F0sssssss\n"
5320 "G0sss\n",
[email protected]94f206c12012-08-25 00:09:145321
[email protected]aa043632013-03-25 03:39:425322 "R0ssssA0sss\n"
[email protected]8591a642013-04-17 18:48:565323 }, {
[email protected]aa043632013-03-25 03:39:425324 "Leave some passes, remove others",
[email protected]94f206c12012-08-25 00:09:145325
[email protected]aa043632013-03-25 03:39:425326 "R0ssssA0[c]sss\n"
5327 "A0sssB0[t]C0[ct]s\n"
5328 "B0sssD0[c]ss\n"
5329 "C0G0\n"
5330 "D0sssssss\n"
5331 "G0sss\n",
[email protected]94f206c12012-08-25 00:09:145332
[email protected]aa043632013-03-25 03:39:425333 "R0ssssA0sss\n"
5334 "A0sssB0C0s\n"
5335 "B0sssD0ss\n"
5336 "D0sssssss\n"
[email protected]8591a642013-04-17 18:48:565337 }, {
[email protected]aa043632013-03-25 03:39:425338 0, 0, 0
5339 }
[email protected]ea9d8f22012-12-08 03:39:295340};
5341
[email protected]bf691c22013-03-26 21:15:065342static void VerifyRenderPassTestData(
5343 const TestCase& test_case,
5344 const RenderPassRemovalTestData& test_data) {
[email protected]aa043632013-03-25 03:39:425345 char actual_result[1024];
5346 DumpRenderPassTestData(test_data, actual_result);
5347 EXPECT_STREQ(test_case.expected_result, actual_result) << "In test case: " <<
5348 test_case.name;
5349}
[email protected]c2d0c5a2013-02-26 04:43:365350
[email protected]aa043632013-03-25 03:39:425351TEST_F(LayerTreeHostImplTest, TestRemoveRenderPasses) {
[email protected]0634cdd42013-08-16 00:46:095352 FakeOutputSurfaceClient output_surface_client;
[email protected]aa043632013-03-25 03:39:425353 scoped_ptr<OutputSurface> output_surface(CreateOutputSurface());
[email protected]0634cdd42013-08-16 00:46:095354 ASSERT_TRUE(output_surface->BindToClient(&output_surface_client));
5355 ASSERT_TRUE(output_surface->context_provider());
5356
[email protected]aa043632013-03-25 03:39:425357 scoped_ptr<ResourceProvider> resource_provider =
[email protected]075d8aa2013-04-01 23:03:115358 ResourceProvider::Create(output_surface.get(), 0);
[email protected]ea9d8f22012-12-08 03:39:295359
[email protected]aa043632013-03-25 03:39:425360 scoped_ptr<TestRenderer> renderer =
5361 TestRenderer::Create(resource_provider.get(),
5362 output_surface.get(),
5363 &proxy_);
5364
5365 int test_case_index = 0;
5366 while (remove_render_passes_cases[test_case_index].name) {
5367 RenderPassRemovalTestData test_data;
5368 ConfigureRenderPassTestData(
5369 remove_render_passes_cases[test_case_index].init_script,
[email protected]d002dd02013-03-27 07:40:405370 &test_data,
[email protected]aa043632013-03-25 03:39:425371 renderer.get());
5372 LayerTreeHostImpl::RemoveRenderPasses(
[email protected]bf691c22013-03-26 21:15:065373 LayerTreeHostImpl::CullRenderPassesWithCachedTextures(renderer.get()),
[email protected]aa043632013-03-25 03:39:425374 &test_data);
5375 VerifyRenderPassTestData(remove_render_passes_cases[test_case_index],
5376 test_data);
5377 test_case_index++;
5378 }
5379}
5380
5381class LayerTreeHostImplTestWithDelegatingRenderer
5382 : public LayerTreeHostImplTest {
5383 protected:
5384 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
5385 return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>();
5386 }
5387
5388 void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) {
[email protected]e0341352013-04-06 05:01:205389 bool expect_to_draw = !expected_damage.IsEmpty();
5390
[email protected]aa043632013-03-25 03:39:425391 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205392 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]aa043632013-03-25 03:39:425393
[email protected]e0341352013-04-06 05:01:205394 if (!expect_to_draw) {
5395 // With no damage, we don't draw, and no quads are created.
5396 ASSERT_EQ(0u, frame.render_passes.size());
5397 } else {
5398 ASSERT_EQ(1u, frame.render_passes.size());
[email protected]aa043632013-03-25 03:39:425399
[email protected]e0341352013-04-06 05:01:205400 // Verify the damage rect for the root render pass.
5401 const RenderPass* root_render_pass = frame.render_passes.back();
5402 EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect);
5403
5404 // Verify the root and child layers' quads are generated and not being
5405 // culled.
5406 ASSERT_EQ(2u, root_render_pass->quad_list.size());
5407
5408 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
5409 gfx::RectF expected_child_visible_rect(child->content_bounds());
5410 EXPECT_RECT_EQ(expected_child_visible_rect,
5411 root_render_pass->quad_list[0]->visible_rect);
5412
5413 LayerImpl* root = host_impl_->active_tree()->root_layer();
5414 gfx::RectF expected_root_visible_rect(root->content_bounds());
5415 EXPECT_RECT_EQ(expected_root_visible_rect,
5416 root_render_pass->quad_list[1]->visible_rect);
5417 }
[email protected]aa043632013-03-25 03:39:425418
5419 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5420 host_impl_->DidDrawAllLayers(frame);
[email protected]e0341352013-04-06 05:01:205421 EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame));
[email protected]aa043632013-03-25 03:39:425422 }
5423};
5424
5425TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
5426 scoped_ptr<SolidColorLayerImpl> root =
5427 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
5428 root->SetAnchorPoint(gfx::PointF());
5429 root->SetPosition(gfx::PointF());
5430 root->SetBounds(gfx::Size(10, 10));
5431 root->SetContentBounds(gfx::Size(10, 10));
5432 root->SetDrawsContent(true);
[email protected]e0341352013-04-06 05:01:205433
5434 // Child layer is in the bottom right corner.
5435 scoped_ptr<SolidColorLayerImpl> child =
5436 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
5437 child->SetAnchorPoint(gfx::PointF(0.f, 0.f));
5438 child->SetPosition(gfx::PointF(9.f, 9.f));
5439 child->SetBounds(gfx::Size(1, 1));
5440 child->SetContentBounds(gfx::Size(1, 1));
5441 child->SetDrawsContent(true);
5442 root->AddChild(child.PassAs<LayerImpl>());
5443
[email protected]aa043632013-03-25 03:39:425444 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>());
5445
5446 // Draw a frame. In the first frame, the entire viewport should be damaged.
[email protected]54af03522013-09-05 00:43:285447 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
[email protected]aa043632013-03-25 03:39:425448 DrawFrameAndTestDamage(full_frame_damage);
5449
[email protected]e0341352013-04-06 05:01:205450 // The second frame has damage that doesn't touch the child layer. Its quads
5451 // should still be generated.
5452 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
5453 host_impl_->active_tree()->root_layer()->set_update_rect(small_damage);
5454 DrawFrameAndTestDamage(small_damage);
5455
5456 // The third frame should have no damage, so no quads should be generated.
[email protected]aa043632013-03-25 03:39:425457 gfx::Rect no_damage;
5458 DrawFrameAndTestDamage(no_damage);
[email protected]ea9d8f22012-12-08 03:39:295459}
5460
[email protected]05dea302013-01-15 08:30:415461class FakeMaskLayerImpl : public LayerImpl {
[email protected]aa043632013-03-25 03:39:425462 public:
5463 static scoped_ptr<FakeMaskLayerImpl> Create(LayerTreeImpl* tree_impl,
5464 int id) {
5465 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id));
5466 }
[email protected]05dea302013-01-15 08:30:415467
[email protected]aa043632013-03-25 03:39:425468 virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE {
5469 return 0;
5470 }
[email protected]05dea302013-01-15 08:30:415471
[email protected]aa043632013-03-25 03:39:425472 private:
5473 FakeMaskLayerImpl(LayerTreeImpl* tree_impl, int id)
5474 : LayerImpl(tree_impl, id) {}
[email protected]05dea302013-01-15 08:30:415475};
5476
[email protected]aa043632013-03-25 03:39:425477TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
[email protected]35a99a12013-05-09 23:52:295478 LayerTreeSettings settings;
5479 settings.layer_transforms_should_scale_layer_contents = true;
5480 host_impl_ = LayerTreeHostImpl::Create(settings,
5481 this,
5482 &proxy_,
5483 &stats_instrumentation_);
5484 host_impl_->InitializeRenderer(CreateOutputSurface());
5485 host_impl_->SetViewportSize(gfx::Size(10, 10));
5486
[email protected]aa043632013-03-25 03:39:425487 // Root
5488 // |
5489 // +-- Scaling Layer (adds a 2x scale)
5490 // |
5491 // +-- Content Layer
5492 // +--Mask
5493 scoped_ptr<LayerImpl> scoped_root =
5494 LayerImpl::Create(host_impl_->active_tree(), 1);
5495 LayerImpl* root = scoped_root.get();
5496 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
[email protected]05dea302013-01-15 08:30:415497
[email protected]aa043632013-03-25 03:39:425498 scoped_ptr<LayerImpl> scoped_scaling_layer =
5499 LayerImpl::Create(host_impl_->active_tree(), 2);
5500 LayerImpl* scaling_layer = scoped_scaling_layer.get();
5501 root->AddChild(scoped_scaling_layer.Pass());
[email protected]05dea302013-01-15 08:30:415502
[email protected]aa043632013-03-25 03:39:425503 scoped_ptr<LayerImpl> scoped_content_layer =
5504 LayerImpl::Create(host_impl_->active_tree(), 3);
5505 LayerImpl* content_layer = scoped_content_layer.get();
5506 scaling_layer->AddChild(scoped_content_layer.Pass());
[email protected]05dea302013-01-15 08:30:415507
[email protected]aa043632013-03-25 03:39:425508 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5509 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
5510 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5511 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
[email protected]05dea302013-01-15 08:30:415512
[email protected]aa043632013-03-25 03:39:425513 gfx::Size root_size(100, 100);
5514 root->SetBounds(root_size);
5515 root->SetContentBounds(root_size);
5516 root->SetPosition(gfx::PointF());
5517 root->SetAnchorPoint(gfx::PointF());
[email protected]05dea302013-01-15 08:30:415518
[email protected]aa043632013-03-25 03:39:425519 gfx::Size scaling_layer_size(50, 50);
5520 scaling_layer->SetBounds(scaling_layer_size);
5521 scaling_layer->SetContentBounds(scaling_layer_size);
5522 scaling_layer->SetPosition(gfx::PointF());
5523 scaling_layer->SetAnchorPoint(gfx::PointF());
5524 gfx::Transform scale;
5525 scale.Scale(2.f, 2.f);
5526 scaling_layer->SetTransform(scale);
[email protected]05dea302013-01-15 08:30:415527
[email protected]aa043632013-03-25 03:39:425528 content_layer->SetBounds(scaling_layer_size);
5529 content_layer->SetContentBounds(scaling_layer_size);
5530 content_layer->SetPosition(gfx::PointF());
5531 content_layer->SetAnchorPoint(gfx::PointF());
5532 content_layer->SetDrawsContent(true);
[email protected]05dea302013-01-15 08:30:415533
[email protected]aa043632013-03-25 03:39:425534 mask_layer->SetBounds(scaling_layer_size);
5535 mask_layer->SetContentBounds(scaling_layer_size);
5536 mask_layer->SetPosition(gfx::PointF());
5537 mask_layer->SetAnchorPoint(gfx::PointF());
5538 mask_layer->SetDrawsContent(true);
[email protected]05dea302013-01-15 08:30:415539
5540
[email protected]aa043632013-03-25 03:39:425541 // Check that the tree scaling is correctly taken into account for the mask,
5542 // that should fully map onto the quad.
5543 float device_scale_factor = 1.f;
[email protected]18ce59702013-04-09 04:58:405544 host_impl_->SetViewportSize(root_size);
[email protected]a7dffcf2013-03-29 08:54:015545 host_impl_->SetDeviceScaleFactor(device_scale_factor);
5546 {
[email protected]aa043632013-03-25 03:39:425547 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205548 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:415549
[email protected]aa043632013-03-25 03:39:425550 ASSERT_EQ(1u, frame.render_passes.size());
5551 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5552 ASSERT_EQ(DrawQuad::RENDER_PASS,
5553 frame.render_passes[0]->quad_list[0]->material);
5554 const RenderPassDrawQuad* render_pass_quad =
5555 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5556 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5557 render_pass_quad->rect.ToString());
5558 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5559 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:415560
[email protected]aa043632013-03-25 03:39:425561 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5562 host_impl_->DidDrawAllLayers(frame);
5563 }
[email protected]05dea302013-01-15 08:30:415564
5565
[email protected]aa043632013-03-25 03:39:425566 // Applying a DSF should change the render surface size, but won't affect
5567 // which part of the mask is used.
5568 device_scale_factor = 2.f;
5569 gfx::Size device_viewport =
5570 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
[email protected]18ce59702013-04-09 04:58:405571 host_impl_->SetViewportSize(device_viewport);
[email protected]aa043632013-03-25 03:39:425572 host_impl_->SetDeviceScaleFactor(device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:015573 host_impl_->active_tree()->set_needs_update_draw_properties();
5574 {
[email protected]aa043632013-03-25 03:39:425575 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205576 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:415577
[email protected]aa043632013-03-25 03:39:425578 ASSERT_EQ(1u, frame.render_passes.size());
5579 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5580 ASSERT_EQ(DrawQuad::RENDER_PASS,
5581 frame.render_passes[0]->quad_list[0]->material);
5582 const RenderPassDrawQuad* render_pass_quad =
5583 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5584 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5585 render_pass_quad->rect.ToString());
5586 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5587 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:415588
[email protected]aa043632013-03-25 03:39:425589 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5590 host_impl_->DidDrawAllLayers(frame);
5591 }
[email protected]05dea302013-01-15 08:30:415592
5593
[email protected]aa043632013-03-25 03:39:425594 // Applying an equivalent content scale on the content layer and the mask
5595 // should still result in the same part of the mask being used.
5596 gfx::Size content_bounds =
5597 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size,
5598 device_scale_factor));
5599 content_layer->SetContentBounds(content_bounds);
5600 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5601 mask_layer->SetContentBounds(content_bounds);
5602 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:015603 host_impl_->active_tree()->set_needs_update_draw_properties();
5604 {
[email protected]aa043632013-03-25 03:39:425605 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205606 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]05dea302013-01-15 08:30:415607
[email protected]aa043632013-03-25 03:39:425608 ASSERT_EQ(1u, frame.render_passes.size());
5609 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5610 ASSERT_EQ(DrawQuad::RENDER_PASS,
5611 frame.render_passes[0]->quad_list[0]->material);
5612 const RenderPassDrawQuad* render_pass_quad =
5613 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5614 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5615 render_pass_quad->rect.ToString());
5616 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5617 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:555618
[email protected]aa043632013-03-25 03:39:425619 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5620 host_impl_->DidDrawAllLayers(frame);
5621 }
[email protected]8611f012013-01-17 03:44:555622}
5623
[email protected]aa043632013-03-25 03:39:425624TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
5625 // The mask layer has bounds 100x100 but is attached to a layer with bounds
5626 // 50x50.
[email protected]8611f012013-01-17 03:44:555627
[email protected]aa043632013-03-25 03:39:425628 scoped_ptr<LayerImpl> scoped_root =
5629 LayerImpl::Create(host_impl_->active_tree(), 1);
5630 LayerImpl* root = scoped_root.get();
5631 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
[email protected]8611f012013-01-17 03:44:555632
[email protected]aa043632013-03-25 03:39:425633 scoped_ptr<LayerImpl> scoped_content_layer =
5634 LayerImpl::Create(host_impl_->active_tree(), 3);
5635 LayerImpl* content_layer = scoped_content_layer.get();
5636 root->AddChild(scoped_content_layer.Pass());
[email protected]8611f012013-01-17 03:44:555637
[email protected]aa043632013-03-25 03:39:425638 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5639 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
5640 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5641 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
[email protected]8611f012013-01-17 03:44:555642
[email protected]aa043632013-03-25 03:39:425643 gfx::Size root_size(100, 100);
5644 root->SetBounds(root_size);
5645 root->SetContentBounds(root_size);
5646 root->SetPosition(gfx::PointF());
5647 root->SetAnchorPoint(gfx::PointF());
[email protected]8611f012013-01-17 03:44:555648
[email protected]aa043632013-03-25 03:39:425649 gfx::Size layer_size(50, 50);
5650 content_layer->SetBounds(layer_size);
5651 content_layer->SetContentBounds(layer_size);
5652 content_layer->SetPosition(gfx::PointF());
5653 content_layer->SetAnchorPoint(gfx::PointF());
5654 content_layer->SetDrawsContent(true);
[email protected]8611f012013-01-17 03:44:555655
[email protected]aa043632013-03-25 03:39:425656 gfx::Size mask_size(100, 100);
5657 mask_layer->SetBounds(mask_size);
5658 mask_layer->SetContentBounds(mask_size);
5659 mask_layer->SetPosition(gfx::PointF());
5660 mask_layer->SetAnchorPoint(gfx::PointF());
5661 mask_layer->SetDrawsContent(true);
[email protected]8611f012013-01-17 03:44:555662
[email protected]aa043632013-03-25 03:39:425663 // Check that the mask fills the surface.
5664 float device_scale_factor = 1.f;
[email protected]18ce59702013-04-09 04:58:405665 host_impl_->SetViewportSize(root_size);
[email protected]a7dffcf2013-03-29 08:54:015666 host_impl_->SetDeviceScaleFactor(device_scale_factor);
5667 {
[email protected]aa043632013-03-25 03:39:425668 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205669 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:555670
[email protected]aa043632013-03-25 03:39:425671 ASSERT_EQ(1u, frame.render_passes.size());
5672 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5673 ASSERT_EQ(DrawQuad::RENDER_PASS,
5674 frame.render_passes[0]->quad_list[0]->material);
5675 const RenderPassDrawQuad* render_pass_quad =
5676 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5677 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5678 render_pass_quad->rect.ToString());
5679 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5680 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:555681
[email protected]aa043632013-03-25 03:39:425682 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5683 host_impl_->DidDrawAllLayers(frame);
5684 }
[email protected]8611f012013-01-17 03:44:555685
[email protected]aa043632013-03-25 03:39:425686 // Applying a DSF should change the render surface size, but won't affect
5687 // which part of the mask is used.
5688 device_scale_factor = 2.f;
5689 gfx::Size device_viewport =
5690 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
[email protected]18ce59702013-04-09 04:58:405691 host_impl_->SetViewportSize(device_viewport);
[email protected]aa043632013-03-25 03:39:425692 host_impl_->SetDeviceScaleFactor(device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:015693 host_impl_->active_tree()->set_needs_update_draw_properties();
5694 {
[email protected]aa043632013-03-25 03:39:425695 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205696 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:555697
[email protected]aa043632013-03-25 03:39:425698 ASSERT_EQ(1u, frame.render_passes.size());
5699 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5700 ASSERT_EQ(DrawQuad::RENDER_PASS,
5701 frame.render_passes[0]->quad_list[0]->material);
5702 const RenderPassDrawQuad* render_pass_quad =
5703 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5704 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5705 render_pass_quad->rect.ToString());
5706 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5707 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:555708
[email protected]aa043632013-03-25 03:39:425709 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5710 host_impl_->DidDrawAllLayers(frame);
5711 }
[email protected]8611f012013-01-17 03:44:555712
[email protected]aa043632013-03-25 03:39:425713 // Applying an equivalent content scale on the content layer and the mask
5714 // should still result in the same part of the mask being used.
5715 gfx::Size layer_size_large =
5716 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
5717 content_layer->SetContentBounds(layer_size_large);
5718 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5719 gfx::Size mask_size_large =
5720 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
5721 mask_layer->SetContentBounds(mask_size_large);
5722 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
[email protected]a7dffcf2013-03-29 08:54:015723 host_impl_->active_tree()->set_needs_update_draw_properties();
5724 {
[email protected]aa043632013-03-25 03:39:425725 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205726 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:555727
[email protected]aa043632013-03-25 03:39:425728 ASSERT_EQ(1u, frame.render_passes.size());
5729 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5730 ASSERT_EQ(DrawQuad::RENDER_PASS,
5731 frame.render_passes[0]->quad_list[0]->material);
5732 const RenderPassDrawQuad* render_pass_quad =
5733 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5734 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5735 render_pass_quad->rect.ToString());
5736 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5737 render_pass_quad->mask_uv_rect.ToString());
[email protected]8611f012013-01-17 03:44:555738
[email protected]aa043632013-03-25 03:39:425739 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5740 host_impl_->DidDrawAllLayers(frame);
5741 }
[email protected]8611f012013-01-17 03:44:555742
[email protected]8591a642013-04-17 18:48:565743 // Applying a different contents scale to the mask layer means it will have
5744 // a larger texture, but it should use the same tex coords to cover the
5745 // layer it masks.
[email protected]aa043632013-03-25 03:39:425746 mask_layer->SetContentBounds(mask_size);
[email protected]8591a642013-04-17 18:48:565747 mask_layer->SetContentsScale(1.f, 1.f);
[email protected]a7dffcf2013-03-29 08:54:015748 host_impl_->active_tree()->set_needs_update_draw_properties();
5749 {
[email protected]aa043632013-03-25 03:39:425750 LayerTreeHostImpl::FrameData frame;
[email protected]e0341352013-04-06 05:01:205751 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
[email protected]8611f012013-01-17 03:44:555752
[email protected]aa043632013-03-25 03:39:425753 ASSERT_EQ(1u, frame.render_passes.size());
5754 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5755 ASSERT_EQ(DrawQuad::RENDER_PASS,
5756 frame.render_passes[0]->quad_list[0]->material);
5757 const RenderPassDrawQuad* render_pass_quad =
5758 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5759 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5760 render_pass_quad->rect.ToString());
5761 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5762 render_pass_quad->mask_uv_rect.ToString());
[email protected]05dea302013-01-15 08:30:415763
[email protected]aa043632013-03-25 03:39:425764 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5765 host_impl_->DidDrawAllLayers(frame);
5766 }
[email protected]05dea302013-01-15 08:30:415767}
5768
[email protected]8591a642013-04-17 18:48:565769TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
5770 // The replica's mask layer has bounds 100x100 but the replica is of a
5771 // layer with bounds 50x50.
5772
5773 scoped_ptr<LayerImpl> scoped_root =
5774 LayerImpl::Create(host_impl_->active_tree(), 1);
5775 LayerImpl* root = scoped_root.get();
5776 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
5777
5778 scoped_ptr<LayerImpl> scoped_content_layer =
5779 LayerImpl::Create(host_impl_->active_tree(), 3);
5780 LayerImpl* content_layer = scoped_content_layer.get();
5781 root->AddChild(scoped_content_layer.Pass());
5782
5783 scoped_ptr<LayerImpl> scoped_replica_layer =
5784 LayerImpl::Create(host_impl_->active_tree(), 2);
5785 LayerImpl* replica_layer = scoped_replica_layer.get();
5786 content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
5787
5788 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5789 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
5790 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5791 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
5792
5793 gfx::Size root_size(100, 100);
5794 root->SetBounds(root_size);
5795 root->SetContentBounds(root_size);
5796 root->SetPosition(gfx::PointF());
5797 root->SetAnchorPoint(gfx::PointF());
5798
5799 gfx::Size layer_size(50, 50);
5800 content_layer->SetBounds(layer_size);
5801 content_layer->SetContentBounds(layer_size);
5802 content_layer->SetPosition(gfx::PointF());
5803 content_layer->SetAnchorPoint(gfx::PointF());
5804 content_layer->SetDrawsContent(true);
5805
5806 gfx::Size mask_size(100, 100);
5807 mask_layer->SetBounds(mask_size);
5808 mask_layer->SetContentBounds(mask_size);
5809 mask_layer->SetPosition(gfx::PointF());
5810 mask_layer->SetAnchorPoint(gfx::PointF());
5811 mask_layer->SetDrawsContent(true);
5812
5813 // Check that the mask fills the surface.
5814 float device_scale_factor = 1.f;
5815 host_impl_->SetViewportSize(root_size);
5816 host_impl_->SetDeviceScaleFactor(device_scale_factor);
5817 {
5818 LayerTreeHostImpl::FrameData frame;
5819 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
5820
5821 ASSERT_EQ(1u, frame.render_passes.size());
5822 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5823 ASSERT_EQ(DrawQuad::RENDER_PASS,
5824 frame.render_passes[0]->quad_list[1]->material);
5825 const RenderPassDrawQuad* replica_quad =
5826 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
5827 EXPECT_TRUE(replica_quad->is_replica);
5828 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5829 replica_quad->rect.ToString());
5830 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5831 replica_quad->mask_uv_rect.ToString());
5832
5833 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5834 host_impl_->DidDrawAllLayers(frame);
5835 }
5836
5837 // Applying a DSF should change the render surface size, but won't affect
5838 // which part of the mask is used.
5839 device_scale_factor = 2.f;
5840 gfx::Size device_viewport =
5841 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
5842 host_impl_->SetViewportSize(device_viewport);
5843 host_impl_->SetDeviceScaleFactor(device_scale_factor);
5844 host_impl_->active_tree()->set_needs_update_draw_properties();
5845 {
5846 LayerTreeHostImpl::FrameData frame;
5847 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
5848
5849 ASSERT_EQ(1u, frame.render_passes.size());
5850 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5851 ASSERT_EQ(DrawQuad::RENDER_PASS,
5852 frame.render_passes[0]->quad_list[1]->material);
5853 const RenderPassDrawQuad* replica_quad =
5854 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
5855 EXPECT_TRUE(replica_quad->is_replica);
5856 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5857 replica_quad->rect.ToString());
5858 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5859 replica_quad->mask_uv_rect.ToString());
5860
5861 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5862 host_impl_->DidDrawAllLayers(frame);
5863 }
5864
5865 // Applying an equivalent content scale on the content layer and the mask
5866 // should still result in the same part of the mask being used.
5867 gfx::Size layer_size_large =
5868 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
5869 content_layer->SetContentBounds(layer_size_large);
5870 content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5871 gfx::Size mask_size_large =
5872 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
5873 mask_layer->SetContentBounds(mask_size_large);
5874 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5875 host_impl_->active_tree()->set_needs_update_draw_properties();
5876 {
5877 LayerTreeHostImpl::FrameData frame;
5878 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
5879
5880 ASSERT_EQ(1u, frame.render_passes.size());
5881 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5882 ASSERT_EQ(DrawQuad::RENDER_PASS,
5883 frame.render_passes[0]->quad_list[1]->material);
5884 const RenderPassDrawQuad* replica_quad =
5885 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
5886 EXPECT_TRUE(replica_quad->is_replica);
5887 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5888 replica_quad->rect.ToString());
5889 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5890 replica_quad->mask_uv_rect.ToString());
5891
5892 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5893 host_impl_->DidDrawAllLayers(frame);
5894 }
5895
5896 // Applying a different contents scale to the mask layer means it will have
5897 // a larger texture, but it should use the same tex coords to cover the
5898 // layer it masks.
5899 mask_layer->SetContentBounds(mask_size);
5900 mask_layer->SetContentsScale(1.f, 1.f);
5901 host_impl_->active_tree()->set_needs_update_draw_properties();
5902 {
5903 LayerTreeHostImpl::FrameData frame;
5904 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
5905
5906 ASSERT_EQ(1u, frame.render_passes.size());
5907 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5908 ASSERT_EQ(DrawQuad::RENDER_PASS,
5909 frame.render_passes[0]->quad_list[1]->material);
5910 const RenderPassDrawQuad* replica_quad =
5911 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
5912 EXPECT_TRUE(replica_quad->is_replica);
5913 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5914 replica_quad->rect.ToString());
5915 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5916 replica_quad->mask_uv_rect.ToString());
5917
5918 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
5919 host_impl_->DidDrawAllLayers(frame);
5920 }
5921}
5922
5923TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) {
5924 // The replica is of a layer with bounds 50x50, but it has a child that causes
5925 // the surface bounds to be larger.
5926
5927 scoped_ptr<LayerImpl> scoped_root =
5928 LayerImpl::Create(host_impl_->active_tree(), 1);
5929 LayerImpl* root = scoped_root.get();
5930 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
5931
5932 scoped_ptr<LayerImpl> scoped_content_layer =
5933 LayerImpl::Create(host_impl_->active_tree(), 2);
5934 LayerImpl* content_layer = scoped_content_layer.get();
5935 root->AddChild(scoped_content_layer.Pass());
5936
5937 scoped_ptr<LayerImpl> scoped_content_child_layer =
5938 LayerImpl::Create(host_impl_->active_tree(), 3);
5939 LayerImpl* content_child_layer = scoped_content_child_layer.get();
5940 content_layer->AddChild(scoped_content_child_layer.Pass());
5941
5942 scoped_ptr<LayerImpl> scoped_replica_layer =
5943 LayerImpl::Create(host_impl_->active_tree(), 4);
5944 LayerImpl* replica_layer = scoped_replica_layer.get();
5945 content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
5946
5947 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5948 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5);
5949 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5950 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
5951
5952 gfx::Size root_size(100, 100);
5953 root->SetBounds(root_size);
5954 root->SetContentBounds(root_size);
5955 root->SetPosition(gfx::PointF());
5956 root->SetAnchorPoint(gfx::PointF());
5957
5958 gfx::Size layer_size(50, 50);
5959 content_layer->SetBounds(layer_size);
5960 content_layer->SetContentBounds(layer_size);
5961 content_layer->SetPosition(gfx::PointF());
5962 content_layer->SetAnchorPoint(gfx::PointF());
5963 content_layer->SetDrawsContent(true);
5964
5965 gfx::Size child_size(50, 50);
5966 content_child_layer->SetBounds(child_size);
5967 content_child_layer->SetContentBounds(child_size);
5968 content_child_layer->SetPosition(gfx::Point(50, 0));
5969 content_child_layer->SetAnchorPoint(gfx::PointF());
5970 content_child_layer->SetDrawsContent(true);
5971
5972 gfx::Size mask_size(50, 50);
5973 mask_layer->SetBounds(mask_size);
5974 mask_layer->SetContentBounds(mask_size);
5975 mask_layer->SetPosition(gfx::PointF());
5976 mask_layer->SetAnchorPoint(gfx::PointF());
5977 mask_layer->SetDrawsContent(true);
5978
5979 float device_scale_factor = 1.f;
5980 host_impl_->SetViewportSize(root_size);
5981 host_impl_->SetDeviceScaleFactor(device_scale_factor);
5982 {
5983 LayerTreeHostImpl::FrameData frame;
5984 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
5985
5986 ASSERT_EQ(1u, frame.render_passes.size());
5987 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5988
5989 // The surface is 100x50.
5990 ASSERT_EQ(DrawQuad::RENDER_PASS,
5991 frame.render_passes[0]->quad_list[0]->material);
5992 const RenderPassDrawQuad* render_pass_quad =
5993 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
5994 EXPECT_FALSE(render_pass_quad->is_replica);
5995 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5996 render_pass_quad->rect.ToString());
5997
5998 // The mask covers the owning layer only.
5999 ASSERT_EQ(DrawQuad::RENDER_PASS,
6000 frame.render_passes[0]->quad_list[1]->material);
6001 const RenderPassDrawQuad* replica_quad =
6002 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
6003 EXPECT_TRUE(replica_quad->is_replica);
6004 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
6005 replica_quad->rect.ToString());
6006 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
6007 replica_quad->mask_uv_rect.ToString());
6008
6009 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
6010 host_impl_->DidDrawAllLayers(frame);
6011 }
6012
6013 // Move the child to (-50, 0) instead. Now the mask should be moved to still
6014 // cover the layer being replicated.
6015 content_child_layer->SetPosition(gfx::Point(-50, 0));
6016 {
6017 LayerTreeHostImpl::FrameData frame;
6018 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
6019
6020 ASSERT_EQ(1u, frame.render_passes.size());
6021 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
6022
6023 // The surface is 100x50 with its origin at (-50, 0).
6024 ASSERT_EQ(DrawQuad::RENDER_PASS,
6025 frame.render_passes[0]->quad_list[0]->material);
6026 const RenderPassDrawQuad* render_pass_quad =
6027 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
6028 EXPECT_FALSE(render_pass_quad->is_replica);
6029 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6030 render_pass_quad->rect.ToString());
6031
6032 // The mask covers the owning layer only.
6033 ASSERT_EQ(DrawQuad::RENDER_PASS,
6034 frame.render_passes[0]->quad_list[1]->material);
6035 const RenderPassDrawQuad* replica_quad =
6036 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]);
6037 EXPECT_TRUE(replica_quad->is_replica);
6038 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6039 replica_quad->rect.ToString());
6040 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
6041 replica_quad->mask_uv_rect.ToString());
6042
6043 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
6044 host_impl_->DidDrawAllLayers(frame);
6045 }
6046}
6047
6048TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) {
6049 // The masked layer has bounds 50x50, but it has a child that causes
6050 // the surface bounds to be larger. It also has a parent that clips the
6051 // masked layer and its surface.
6052
6053 scoped_ptr<LayerImpl> scoped_root =
6054 LayerImpl::Create(host_impl_->active_tree(), 1);
6055 LayerImpl* root = scoped_root.get();
6056 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
6057
6058 scoped_ptr<LayerImpl> scoped_clipping_layer =
6059 LayerImpl::Create(host_impl_->active_tree(), 2);
6060 LayerImpl* clipping_layer = scoped_clipping_layer.get();
6061 root->AddChild(scoped_clipping_layer.Pass());
6062
6063 scoped_ptr<LayerImpl> scoped_content_layer =
6064 LayerImpl::Create(host_impl_->active_tree(), 3);
6065 LayerImpl* content_layer = scoped_content_layer.get();
6066 clipping_layer->AddChild(scoped_content_layer.Pass());
6067
6068 scoped_ptr<LayerImpl> scoped_content_child_layer =
6069 LayerImpl::Create(host_impl_->active_tree(), 4);
6070 LayerImpl* content_child_layer = scoped_content_child_layer.get();
6071 content_layer->AddChild(scoped_content_child_layer.Pass());
6072
6073 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
6074 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6);
6075 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
6076 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>());
6077
6078 gfx::Size root_size(100, 100);
6079 root->SetBounds(root_size);
6080 root->SetContentBounds(root_size);
6081 root->SetPosition(gfx::PointF());
6082 root->SetAnchorPoint(gfx::PointF());
6083
6084 gfx::Rect clipping_rect(20, 10, 10, 20);
6085 clipping_layer->SetBounds(clipping_rect.size());
6086 clipping_layer->SetContentBounds(clipping_rect.size());
6087 clipping_layer->SetPosition(clipping_rect.origin());
6088 clipping_layer->SetAnchorPoint(gfx::PointF());
6089 clipping_layer->SetMasksToBounds(true);
6090
6091 gfx::Size layer_size(50, 50);
6092 content_layer->SetBounds(layer_size);
6093 content_layer->SetContentBounds(layer_size);
6094 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
6095 content_layer->SetAnchorPoint(gfx::PointF());
6096 content_layer->SetDrawsContent(true);
6097
6098 gfx::Size child_size(50, 50);
6099 content_child_layer->SetBounds(child_size);
6100 content_child_layer->SetContentBounds(child_size);
6101 content_child_layer->SetPosition(gfx::Point(50, 0));
6102 content_child_layer->SetAnchorPoint(gfx::PointF());
6103 content_child_layer->SetDrawsContent(true);
6104
6105 gfx::Size mask_size(100, 100);
6106 mask_layer->SetBounds(mask_size);
6107 mask_layer->SetContentBounds(mask_size);
6108 mask_layer->SetPosition(gfx::PointF());
6109 mask_layer->SetAnchorPoint(gfx::PointF());
6110 mask_layer->SetDrawsContent(true);
6111
6112 float device_scale_factor = 1.f;
6113 host_impl_->SetViewportSize(root_size);
6114 host_impl_->SetDeviceScaleFactor(device_scale_factor);
6115 {
6116 LayerTreeHostImpl::FrameData frame;
6117 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
6118
6119 ASSERT_EQ(1u, frame.render_passes.size());
6120 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
6121
6122 // The surface is clipped to 10x20.
6123 ASSERT_EQ(DrawQuad::RENDER_PASS,
6124 frame.render_passes[0]->quad_list[0]->material);
6125 const RenderPassDrawQuad* render_pass_quad =
6126 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]);
6127 EXPECT_FALSE(render_pass_quad->is_replica);
6128 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6129 render_pass_quad->rect.ToString());
6130
6131 // The masked layer is 50x50, but the surface size is 10x20. So the texture
6132 // coords in the mask are scaled by 10/50 and 20/50.
6133 // The surface is clipped to (20,10) so the mask texture coords are offset
6134 // by 20/50 and 10/50
6135 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f),
6136 1.f / 50.f).ToString(),
6137 render_pass_quad->mask_uv_rect.ToString());
6138
6139 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
6140 host_impl_->DidDrawAllLayers(frame);
6141 }
6142}
6143
[email protected]bb1e2822013-04-17 22:06:016144class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
6145 public:
6146 CompositorFrameMetadataTest()
6147 : swap_buffers_complete_(0) {}
6148
[email protected]bb1e2822013-04-17 22:06:016149 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {
6150 swap_buffers_complete_++;
6151 }
6152
6153 int swap_buffers_complete_;
6154};
6155
6156TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
6157 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
6158 {
6159 LayerTreeHostImpl::FrameData frame;
6160 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
6161 host_impl_->DrawLayers(&frame, base::TimeTicks());
6162 host_impl_->DidDrawAllLayers(frame);
6163 }
6164 CompositorFrameAck ack;
[email protected]36e5ff12013-06-11 12:19:296165 host_impl_->OnSwapBuffersComplete(&ack);
[email protected]bb1e2822013-04-17 22:06:016166 EXPECT_EQ(swap_buffers_complete_, 1);
6167}
6168
[email protected]fbe89f72013-05-21 07:24:246169class CountingSoftwareDevice : public SoftwareOutputDevice {
6170 public:
6171 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
6172
6173 virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE {
6174 ++frames_began_;
6175 return SoftwareOutputDevice::BeginPaint(damage_rect);
6176 }
6177 virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE {
6178 ++frames_ended_;
6179 SoftwareOutputDevice::EndPaint(frame_data);
6180 }
6181
6182 int frames_began_, frames_ended_;
6183};
6184
6185TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) {
[email protected]50644642013-06-20 13:58:556186 // No main thread evictions in resourceless software mode.
6187 set_reduce_memory_result(false);
[email protected]fbe89f72013-05-21 07:24:246188 SetupScrollAndContentsLayers(gfx::Size(100, 100));
6189 host_impl_->SetViewportSize(gfx::Size(50, 50));
6190 CountingSoftwareDevice* software_device = new CountingSoftwareDevice();
6191 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL(
6192 scoped_ptr<SoftwareOutputDevice>(software_device)).release();
[email protected]50644642013-06-20 13:58:556193 EXPECT_TRUE(host_impl_->InitializeRenderer(
6194 scoped_ptr<OutputSurface>(output_surface)));
[email protected]fbe89f72013-05-21 07:24:246195
6196 output_surface->set_forced_draw_to_software_device(true);
6197 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice());
6198
6199 EXPECT_EQ(0, software_device->frames_began_);
6200 EXPECT_EQ(0, software_device->frames_ended_);
6201
6202 DrawFrame();
6203
6204 EXPECT_EQ(1, software_device->frames_began_);
6205 EXPECT_EQ(1, software_device->frames_ended_);
[email protected]15cc9922013-05-24 07:31:476206
6207 // Call other API methods that are likely to hit NULL pointer in this mode.
6208 EXPECT_TRUE(host_impl_->AsValue());
6209 EXPECT_TRUE(host_impl_->ActivationStateAsValue());
[email protected]fbe89f72013-05-21 07:24:246210}
6211
[email protected]ffbb2212013-06-02 23:47:596212TEST_F(LayerTreeHostImplTest,
6213 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) {
[email protected]50644642013-06-20 13:58:556214 set_reduce_memory_result(false);
[email protected]ffbb2212013-06-02 23:47:596215 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL(
6216 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())).release();
6217 host_impl_->InitializeRenderer(
6218 scoped_ptr<OutputSurface>(output_surface));
6219
6220 output_surface->set_forced_draw_to_software_device(true);
6221 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice());
6222
6223 // SolidColorLayerImpl will be drawn.
6224 scoped_ptr<SolidColorLayerImpl> root_layer =
6225 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
6226
6227 // VideoLayerImpl will not be drawn.
6228 FakeVideoFrameProvider provider;
6229 scoped_ptr<VideoLayerImpl> video_layer =
6230 VideoLayerImpl::Create(host_impl_->active_tree(), 2, &provider);
6231 video_layer->SetBounds(gfx::Size(10, 10));
6232 video_layer->SetContentBounds(gfx::Size(10, 10));
6233 video_layer->SetDrawsContent(true);
6234 root_layer->AddChild(video_layer.PassAs<LayerImpl>());
6235 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>());
6236
6237 LayerTreeHostImpl::FrameData frame;
6238 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
6239 host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
6240 host_impl_->DidDrawAllLayers(frame);
6241
6242 EXPECT_EQ(1u, frame.will_draw_layers.size());
6243 EXPECT_EQ(host_impl_->active_tree()->root_layer(), frame.will_draw_layers[0]);
6244}
6245
[email protected]d9ca99e2013-08-28 21:49:486246class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest {
6247 protected:
6248 virtual void SetUp() OVERRIDE {
6249 LayerTreeHostImplTest::SetUp();
[email protected]2b154b22013-06-07 09:03:276250
[email protected]d9ca99e2013-08-28 21:49:486251 set_reduce_memory_result(false);
[email protected]2b154b22013-06-07 09:03:276252
[email protected]d9ca99e2013-08-28 21:49:486253 scoped_ptr<FakeOutputSurface> output_surface(
6254 FakeOutputSurface::CreateDeferredGL(
6255 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())));
6256 output_surface_ = output_surface.get();
6257
6258 EXPECT_TRUE(host_impl_->InitializeRenderer(
6259 output_surface.PassAs<OutputSurface>()));
6260
6261 scoped_ptr<SolidColorLayerImpl> root_layer =
6262 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
6263 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>());
6264
6265 onscreen_context_provider_ = TestContextProvider::Create();
6266 offscreen_context_provider_ = TestContextProvider::Create();
6267 }
6268
6269 FakeOutputSurface* output_surface_;
6270 scoped_refptr<TestContextProvider> onscreen_context_provider_;
6271 scoped_refptr<TestContextProvider> offscreen_context_provider_;
6272};
6273
6274
6275TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) {
[email protected]2b154b22013-06-07 09:03:276276 // Software draw.
6277 DrawFrame();
6278
[email protected]b5174d712013-08-28 08:10:436279 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6280 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6281
[email protected]2b154b22013-06-07 09:03:276282 // DeferredInitialize and hardware draw.
[email protected]d9ca99e2013-08-28 21:49:486283 EXPECT_TRUE(output_surface_->InitializeAndSetContext3d(
6284 onscreen_context_provider_, offscreen_context_provider_));
6285 EXPECT_EQ(onscreen_context_provider_,
[email protected]b5174d712013-08-28 08:10:436286 host_impl_->output_surface()->context_provider());
[email protected]d9ca99e2013-08-28 21:49:486287 EXPECT_EQ(offscreen_context_provider_,
[email protected]b5174d712013-08-28 08:10:436288 host_impl_->offscreen_context_provider());
[email protected]2b154b22013-06-07 09:03:276289
6290 // Defer intialized GL draw.
6291 DrawFrame();
[email protected]50af3c22013-07-13 03:50:206292
6293 // Revert back to software.
[email protected]d9ca99e2013-08-28 21:49:486294 output_surface_->ReleaseGL();
[email protected]b5174d712013-08-28 08:10:436295 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6296 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6297
6298 // Software draw again.
[email protected]50af3c22013-07-13 03:50:206299 DrawFrame();
[email protected]2b154b22013-06-07 09:03:276300}
6301
[email protected]d9ca99e2013-08-28 21:49:486302TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_0) {
6303 // Software draw.
6304 DrawFrame();
6305
6306 // Fail initialization of the onscreen context before the OutputSurface binds
6307 // it to the thread.
6308 onscreen_context_provider_->UnboundTestContext3d()
6309 ->set_times_make_current_succeeds(0);
6310
6311 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6312 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6313 EXPECT_FALSE(did_lose_output_surface_);
6314
6315 // DeferredInitialize fails.
6316 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
6317 onscreen_context_provider_, offscreen_context_provider_));
6318 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6319 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6320
6321 // Software draw again.
6322 DrawFrame();
6323}
6324
6325TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_1) {
6326 // Software draw.
6327 DrawFrame();
6328
6329 // Fail initialization of the onscreen context after the OutputSurface binds
6330 // it to the thread.
6331 onscreen_context_provider_->UnboundTestContext3d()
6332 ->set_times_make_current_succeeds(2);
6333
6334 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6335 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6336 EXPECT_FALSE(did_lose_output_surface_);
6337
6338 // DeferredInitialize fails.
6339 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
6340 onscreen_context_provider_, offscreen_context_provider_));
6341 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6342 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6343
6344 // We lose the output surface.
6345 EXPECT_TRUE(did_lose_output_surface_);
6346}
6347
6348TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_2) {
6349 // Software draw.
6350 DrawFrame();
6351
6352 // Fail initialization of the onscreen context after the OutputSurface binds
6353 // it to the thread and during renderer initialization.
6354 onscreen_context_provider_->UnboundTestContext3d()
6355 ->set_times_make_current_succeeds(1);
6356
6357 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6358 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6359 EXPECT_FALSE(did_lose_output_surface_);
6360
6361 // DeferredInitialize fails.
6362 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
6363 onscreen_context_provider_, offscreen_context_provider_));
6364 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6365 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6366
6367 // We lose the output surface.
6368 EXPECT_TRUE(did_lose_output_surface_);
6369}
6370
6371TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) {
6372 // Software draw.
6373 DrawFrame();
6374
6375 // Fail initialization of the offscreen context.
6376 offscreen_context_provider_->UnboundTestContext3d()
6377 ->set_times_make_current_succeeds(0);
6378
6379 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6380 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6381 EXPECT_FALSE(did_lose_output_surface_);
6382
6383 // DeferredInitialize fails.
6384 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
6385 onscreen_context_provider_, offscreen_context_provider_));
6386 EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6387 EXPECT_FALSE(host_impl_->offscreen_context_provider());
6388
6389 // We lose the output surface.
6390 EXPECT_TRUE(did_lose_output_surface_);
6391}
6392
[email protected]fd32d122013-06-29 13:11:046393// Checks that we have a non-0 default allocation if we pass a context that
6394// doesn't support memory management extensions.
6395TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
6396 LayerTreeSettings settings;
6397 host_impl_ = LayerTreeHostImpl::Create(settings,
6398 this,
6399 &proxy_,
6400 &stats_instrumentation_);
6401
[email protected]0634cdd42013-08-16 00:46:096402 scoped_ptr<OutputSurface> output_surface(
[email protected]41de22822013-08-29 04:16:176403 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
[email protected]0634cdd42013-08-16 00:46:096404 host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]fd32d122013-06-29 13:11:046405 EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes());
6406}
6407
6408TEST_F(LayerTreeHostImplTest, MemoryPolicy) {
6409 ManagedMemoryPolicy policy1(
6410 456, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
[email protected]3f2ff112013-08-03 02:41:076411 123, ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE, 1000);
[email protected]fd32d122013-06-29 13:11:046412 int visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
6413 policy1.priority_cutoff_when_visible);
6414 int not_visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
6415 policy1.priority_cutoff_when_not_visible);
6416
6417 host_impl_->SetVisible(true);
[email protected]3f2ff112013-08-03 02:41:076418 host_impl_->SetMemoryPolicy(policy1);
[email protected]fd32d122013-06-29 13:11:046419 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
6420 EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_);
6421
6422 host_impl_->SetVisible(false);
6423 EXPECT_EQ(policy1.bytes_limit_when_not_visible, current_limit_bytes_);
6424 EXPECT_EQ(not_visible_cutoff_value, current_priority_cutoff_value_);
6425
6426 host_impl_->SetVisible(true);
6427 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
6428 EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_);
[email protected]fd32d122013-06-29 13:11:046429}
6430
[email protected]c9280762013-08-01 06:28:576431TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
6432 scoped_ptr<TestWebGraphicsContext3D> context =
6433 TestWebGraphicsContext3D::Create();
6434 TestWebGraphicsContext3D* context3d = context.get();
[email protected]0634cdd42013-08-16 00:46:096435 scoped_ptr<OutputSurface> output_surface = CreateFakeOutputSurface();
[email protected]c9280762013-08-01 06:28:576436 host_impl_->InitializeRenderer(output_surface.Pass());
6437
6438 EXPECT_EQ(0u, context3d->NumTextures());
6439
6440 UIResourceId ui_resource_id = 1;
6441 scoped_refptr<UIResourceBitmap> bitmap = UIResourceBitmap::Create(
6442 new uint8_t[1], UIResourceBitmap::RGBA8, gfx::Size(1, 1));
6443 host_impl_->CreateUIResource(ui_resource_id, bitmap);
6444 EXPECT_EQ(1u, context3d->NumTextures());
6445 ResourceProvider::ResourceId id1 =
6446 host_impl_->ResourceIdForUIResource(ui_resource_id);
6447 EXPECT_NE(0u, id1);
6448
6449 // Multiple requests with the same id is allowed. The previous texture is
6450 // deleted.
6451 host_impl_->CreateUIResource(ui_resource_id, bitmap);
6452 EXPECT_EQ(1u, context3d->NumTextures());
6453 ResourceProvider::ResourceId id2 =
6454 host_impl_->ResourceIdForUIResource(ui_resource_id);
6455 EXPECT_NE(0u, id2);
6456 EXPECT_NE(id1, id2);
6457
6458 // Deleting invalid UIResourceId is allowed and does not change state.
6459 host_impl_->DeleteUIResource(-1);
6460 EXPECT_EQ(1u, context3d->NumTextures());
6461
6462 // Should return zero for invalid UIResourceId. Number of textures should
6463 // not change.
6464 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
6465 EXPECT_EQ(1u, context3d->NumTextures());
6466
6467 host_impl_->DeleteUIResource(ui_resource_id);
6468 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
6469 EXPECT_EQ(0u, context3d->NumTextures());
6470
6471 // Should not change state for multiple deletion on one UIResourceId
6472 host_impl_->DeleteUIResource(ui_resource_id);
6473 EXPECT_EQ(0u, context3d->NumTextures());
6474}
6475
[email protected]ba565742012-11-10 09:29:486476} // namespace
6477} // namespace cc