1 // 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.
5 #include "cc/layers/tiled_layer.h"
10 #include "base/run_loop.h"
11 #include "cc/resources/bitmap_content_layer_updater.h"
12 #include "cc/resources/layer_painter.h"
13 #include "cc/resources/prioritized_resource_manager.h"
14 #include "cc/resources/resource_update_controller.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_layer_tree_host_client.h"
17 #include "cc/test/fake_layer_tree_host_impl.h"
18 #include "cc/test/fake_output_surface.h"
19 #include "cc/test/fake_output_surface_client.h"
20 #include "cc/test/fake_proxy.h"
21 #include "cc/test/geometry_test_utils.h"
22 #include "cc/test/test_shared_bitmap_manager.h"
23 #include "cc/test/tiled_layer_test_common.h"
24 #include "cc/trees/occlusion_tracker.h"
25 #include "cc/trees/single_thread_proxy.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/gfx/geometry/rect_conversions.h"
28 #include "ui/gfx/transform.h"
33 class TestOcclusionTracker
: public OcclusionTracker
<Layer
> {
35 TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000)) {
36 stack_
.push_back(StackObject());
39 void SetRenderTarget(Layer
* render_target
) {
40 stack_
.back().target
= render_target
;
43 void SetOcclusion(const SimpleEnclosedRegion
& occlusion
) {
44 stack_
.back().occlusion_from_inside_target
= occlusion
;
48 class SynchronousOutputSurfaceClient
: public FakeLayerTreeHostClient
{
50 SynchronousOutputSurfaceClient()
51 : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
) {}
53 bool EnsureOutputSurfaceCreated() {
54 base::MessageLoop::current()->PostDelayedTask(
56 run_loop_
.QuitClosure(),
57 base::TimeDelta::FromSeconds(5));
59 return output_surface_created_
;
62 void DidInitializeOutputSurface() override
{
63 FakeLayerTreeHostClient::DidInitializeOutputSurface();
64 output_surface_created_
= true;
68 void DidFailToInitializeOutputSurface() override
{
69 FakeLayerTreeHostClient::DidFailToInitializeOutputSurface();
70 output_surface_created_
= false;
75 bool output_surface_created_
;
76 base::RunLoop run_loop_
;
79 class TiledLayerTest
: public testing::Test
{
83 output_surface_(FakeOutputSurface::Create3d()),
84 queue_(make_scoped_ptr(new ResourceUpdateQueue
)),
85 impl_thread_("ImplThread"),
87 settings_
.max_partial_texture_updates
= std::numeric_limits
<size_t>::max();
88 settings_
.layer_transforms_should_scale_layer_contents
= true;
89 settings_
.verify_property_trees
= true;
92 void SetUp() override
{
94 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
95 layer_tree_host_
= LayerTreeHost::CreateThreaded(
96 &synchonous_output_surface_client_
, shared_bitmap_manager_
.get(),
97 nullptr, settings_
, base::MessageLoopProxy::current(),
98 impl_thread_
.message_loop_proxy(), nullptr);
99 synchonous_output_surface_client_
.SetLayerTreeHost(layer_tree_host_
.get());
100 proxy_
= layer_tree_host_
->proxy();
101 resource_manager_
= PrioritizedResourceManager::Create(proxy_
);
102 layer_tree_host_
->SetLayerTreeHostClientReady();
103 CHECK(synchonous_output_surface_client_
.EnsureOutputSurfaceCreated());
105 layer_tree_host_
->SetRootLayer(Layer::Create());
107 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
109 DebugScopedSetImplThreadAndMainThreadBlocked
110 impl_thread_and_main_thread_blocked(proxy_
);
111 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
112 shared_bitmap_manager_
.get(),
118 host_impl_
= make_scoped_ptr(
119 new FakeLayerTreeHostImpl(proxy_
, shared_bitmap_manager_
.get()));
122 ~TiledLayerTest() override
{
123 ResourceManagerClearAllMemory(resource_manager_
.get(),
124 resource_provider_
.get());
126 DebugScopedSetImplThreadAndMainThreadBlocked
127 impl_thread_and_main_thread_blocked(proxy_
);
128 resource_provider_
= nullptr;
129 host_impl_
= nullptr;
132 void ResourceManagerClearAllMemory(
133 PrioritizedResourceManager
* resource_manager
,
134 ResourceProvider
* resource_provider
) {
136 DebugScopedSetImplThreadAndMainThreadBlocked
137 impl_thread_and_main_thread_blocked(proxy_
);
138 resource_manager
->ClearAllMemory(resource_provider
);
139 resource_manager
->ReduceMemory(resource_provider
);
141 resource_manager
->UnlinkAndClearEvictedBackings();
144 void UpdateTextures() {
145 DebugScopedSetImplThreadAndMainThreadBlocked
146 impl_thread_and_main_thread_blocked(proxy_
);
148 scoped_ptr
<ResourceUpdateController
> update_controller
=
149 ResourceUpdateController::Create(nullptr,
150 proxy_
->ImplThreadTaskRunner(),
152 resource_provider_
.get());
153 update_controller
->Finalize();
154 queue_
= make_scoped_ptr(new ResourceUpdateQueue
);
157 void LayerPushPropertiesTo(FakeTiledLayer
* layer
,
158 FakeTiledLayerImpl
* layer_impl
) {
159 DebugScopedSetImplThreadAndMainThreadBlocked
160 impl_thread_and_main_thread_blocked(proxy_
);
161 layer
->PushPropertiesTo(layer_impl
);
162 layer
->ResetNumDependentsNeedPushProperties();
165 void LayerUpdate(FakeTiledLayer
* layer
, TestOcclusionTracker
* occluded
) {
166 DebugScopedSetMainThread
main_thread(proxy_
);
167 layer
->Update(queue_
.get(), occluded
);
170 void CalcDrawProps(RenderSurfaceLayerList
* render_surface_layer_list
) {
172 occlusion_
->SetRenderTarget(layer_tree_host_
->root_layer());
174 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
175 layer_tree_host_
->root_layer(),
176 layer_tree_host_
->device_viewport_size(),
177 render_surface_layer_list
);
178 inputs
.device_scale_factor
= layer_tree_host_
->device_scale_factor();
179 inputs
.max_texture_size
=
180 layer_tree_host_
->GetRendererCapabilities().max_texture_size
;
181 inputs
.can_adjust_raster_scales
= true;
182 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
185 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
186 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
) {
187 scoped_refptr
<FakeTiledLayer
> layer2
;
188 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
;
189 return UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
192 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
193 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
,
194 const scoped_refptr
<FakeTiledLayer
>& layer2
,
195 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl2
) {
197 resource_manager_
->ClearPriorities();
199 layer1
->SetTexturePriorities(priority_calculator_
);
201 layer2
->SetTexturePriorities(priority_calculator_
);
202 resource_manager_
->PrioritizeTextures();
204 // Save paint properties
206 layer1
->SavePaintProperties();
208 layer2
->SavePaintProperties();
212 layer1
->Update(queue_
.get(), occlusion_
);
214 layer2
->Update(queue_
.get(), occlusion_
);
216 bool needs_update
= false;
218 needs_update
|= layer1
->NeedsIdlePaint();
220 needs_update
|= layer2
->NeedsIdlePaint();
222 // Update textures and push.
225 LayerPushPropertiesTo(layer1
.get(), layer_impl1
.get());
227 LayerPushPropertiesTo(layer2
.get(), layer_impl2
.get());
234 LayerTreeSettings settings_
;
235 FakeOutputSurfaceClient output_surface_client_
;
236 scoped_ptr
<OutputSurface
> output_surface_
;
237 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
238 scoped_ptr
<ResourceProvider
> resource_provider_
;
239 scoped_ptr
<ResourceUpdateQueue
> queue_
;
240 PriorityCalculator priority_calculator_
;
241 base::Thread impl_thread_
;
242 SynchronousOutputSurfaceClient synchonous_output_surface_client_
;
243 scoped_ptr
<LayerTreeHost
> layer_tree_host_
;
244 scoped_ptr
<FakeLayerTreeHostImpl
> host_impl_
;
245 scoped_ptr
<PrioritizedResourceManager
> resource_manager_
;
246 TestOcclusionTracker
* occlusion_
;
249 TEST_F(TiledLayerTest
, PushDirtyTiles
) {
250 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
252 scoped_refptr
<FakeTiledLayer
> layer
=
253 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
254 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
255 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
256 RenderSurfaceLayerList render_surface_layer_list
;
258 layer_tree_host_
->root_layer()->AddChild(layer
);
260 // The tile size is 100x100, so this invalidates and then paints two tiles.
261 layer
->SetBounds(gfx::Size(100, 200));
262 CalcDrawProps(&render_surface_layer_list
);
263 UpdateAndPush(layer
, layer_impl
);
265 // We should have both tiles on the impl side.
266 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
267 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
269 // Invalidates both tiles, but then only update one of them.
270 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
271 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
272 UpdateAndPush(layer
, layer_impl
);
274 // We should only have the first tile since the other tile was invalidated but
276 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
277 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
280 TEST_F(TiledLayerTest
, Scale
) {
281 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
283 layer_tree_host_
->SetDeviceScaleFactor(1.5);
285 scoped_refptr
<FakeTiledLayer
> layer
=
286 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
287 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
288 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
289 RenderSurfaceLayerList render_surface_layer_list
;
291 layer_tree_host_
->root_layer()->AddChild(layer
);
293 layer
->SetBounds(gfx::Size(100, 200));
294 CalcDrawProps(&render_surface_layer_list
);
296 // Change the width so that it doesn't divide cleanly by the scale.
297 layer
->SetBounds(gfx::Size(101, 200));
298 UpdateAndPush(layer
, layer_impl
);
300 EXPECT_EQ(1.5, layer
->fake_layer_updater()->last_contents_width_scale());
303 TEST_F(TiledLayerTest
, PushOccludedDirtyTiles
) {
304 scoped_refptr
<FakeTiledLayer
> layer
=
305 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
306 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
307 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
308 TestOcclusionTracker occluded
;
309 occlusion_
= &occluded
;
310 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
312 layer_tree_host_
->root_layer()->AddChild(layer
);
315 RenderSurfaceLayerList render_surface_layer_list
;
317 // The tile size is 100x100, so this invalidates and then paints two tiles.
318 layer
->SetBounds(gfx::Size(100, 200));
319 CalcDrawProps(&render_surface_layer_list
);
320 UpdateAndPush(layer
, layer_impl
);
322 // We should have both tiles on the impl side.
323 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
324 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
328 RenderSurfaceLayerList render_surface_layer_list
;
330 // Invalidates part of the top tile...
331 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
332 // ....but the area is occluded.
333 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 50, 50)));
334 CalcDrawProps(&render_surface_layer_list
);
335 UpdateAndPush(layer
, layer_impl
);
337 // We should still have both tiles, as part of the top tile is still
339 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
340 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
344 TEST_F(TiledLayerTest
, PushDeletedTiles
) {
345 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
347 scoped_refptr
<FakeTiledLayer
> layer
=
348 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
349 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
350 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
351 RenderSurfaceLayerList render_surface_layer_list
;
353 layer_tree_host_
->root_layer()->AddChild(layer
);
355 // The tile size is 100x100, so this invalidates and then paints two tiles.
356 layer
->SetBounds(gfx::Size(100, 200));
357 CalcDrawProps(&render_surface_layer_list
);
358 UpdateAndPush(layer
, layer_impl
);
360 // We should have both tiles on the impl side.
361 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
362 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
364 resource_manager_
->ClearPriorities();
365 ResourceManagerClearAllMemory(resource_manager_
.get(),
366 resource_provider_
.get());
367 resource_manager_
->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
369 // This should drop the tiles on the impl thread.
370 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
372 // We should now have no textures on the impl thread.
373 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
374 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
376 // This should recreate and update one of the deleted textures.
377 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
378 UpdateAndPush(layer
, layer_impl
);
380 // We should have one tiles on the impl side.
381 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
382 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
385 TEST_F(TiledLayerTest
, PushIdlePaintTiles
) {
386 scoped_refptr
<FakeTiledLayer
> layer
=
387 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
388 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
389 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
390 RenderSurfaceLayerList render_surface_layer_list
;
392 layer_tree_host_
->root_layer()->AddChild(layer
);
394 // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
395 // center. This paints 1 visible of the 25 invalid tiles.
396 layer
->SetBounds(gfx::Size(500, 500));
397 CalcDrawProps(&render_surface_layer_list
);
398 layer
->draw_properties().visible_content_rect
= gfx::Rect(200, 200, 100, 100);
399 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
400 // We should need idle-painting for surrounding tiles.
401 EXPECT_TRUE(needs_update
);
403 // We should have one tile on the impl side.
404 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(2, 2));
406 // For the next four updates, we should detect we still need idle painting.
407 for (int i
= 0; i
< 4; i
++) {
408 needs_update
= UpdateAndPush(layer
, layer_impl
);
409 EXPECT_TRUE(needs_update
);
412 // We should always finish painting eventually.
413 for (int i
= 0; i
< 20; i
++)
414 needs_update
= UpdateAndPush(layer
, layer_impl
);
416 // We should have pre-painted all of the surrounding tiles.
417 for (int i
= 0; i
< 5; i
++) {
418 for (int j
= 0; j
< 5; j
++)
419 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
422 EXPECT_FALSE(needs_update
);
425 TEST_F(TiledLayerTest
, PredictivePainting
) {
426 scoped_refptr
<FakeTiledLayer
> layer
=
427 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
428 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
429 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
431 layer_tree_host_
->root_layer()->AddChild(layer
);
433 // Prepainting should occur in the scroll direction first, and the
434 // visible rect should be extruded only along the dominant axis.
435 gfx::Vector2d directions
[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
436 gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
437 gfx::Vector2d(10, 20),
438 gfx::Vector2d(-20, 10) };
439 // We should push all tiles that touch the extruded visible rect.
440 gfx::Rect pushed_visible_tiles
[6] = {
441 gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
442 gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
444 // The first pre-paint should also paint first in the scroll
445 // direction so we should find one additional tile in the scroll direction.
446 gfx::Rect pushed_prepaint_tiles
[6] = {
447 gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
448 gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
450 for (int k
= 0; k
< 6; k
++) {
451 // The tile size is 100x100. Setup 5x5 tiles with one visible tile
453 gfx::Size bounds
= gfx::Size(500, 500);
454 gfx::Rect visible_rect
= gfx::Rect(200, 200, 100, 100);
455 gfx::Rect previous_visible_rect
=
456 gfx::Rect(visible_rect
.origin() + directions
[k
], visible_rect
.size());
457 gfx::Rect next_visible_rect
=
458 gfx::Rect(visible_rect
.origin() - directions
[k
], visible_rect
.size());
460 // Setup. Use the previous_visible_rect to setup the prediction for next
462 layer
->SetBounds(bounds
);
464 RenderSurfaceLayerList render_surface_layer_list
;
465 CalcDrawProps(&render_surface_layer_list
);
466 layer
->draw_properties().visible_content_rect
= previous_visible_rect
;
467 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
469 // Invalidate and move the visible_rect in the scroll direction.
470 // Check that the correct tiles have been painted in the visible pass.
471 layer
->SetNeedsDisplay();
472 layer
->draw_properties().visible_content_rect
= visible_rect
;
473 needs_update
= UpdateAndPush(layer
, layer_impl
);
474 for (int i
= 0; i
< 5; i
++) {
475 for (int j
= 0; j
< 5; j
++)
476 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
477 pushed_visible_tiles
[k
].Contains(i
, j
));
480 // Move the transform in the same direction without invalidating.
481 // Check that non-visible pre-painting occured in the correct direction.
482 // Ignore diagonal scrolls here (k > 3) as these have new visible content
485 layer
->draw_properties().visible_content_rect
= next_visible_rect
;
486 needs_update
= UpdateAndPush(layer
, layer_impl
);
487 for (int i
= 0; i
< 5; i
++) {
488 for (int j
= 0; j
< 5; j
++)
489 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
490 pushed_prepaint_tiles
[k
].Contains(i
, j
));
494 // We should always finish painting eventually.
495 for (int i
= 0; i
< 20; i
++)
496 needs_update
= UpdateAndPush(layer
, layer_impl
);
497 EXPECT_FALSE(needs_update
);
501 TEST_F(TiledLayerTest
, PushTilesAfterIdlePaintFailed
) {
502 // Start with 2mb of memory, but the test is going to try to use just more
503 // than 1mb, so we reduce to 1mb later.
504 resource_manager_
->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
505 scoped_refptr
<FakeTiledLayer
> layer1
=
506 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
507 scoped_ptr
<FakeTiledLayerImpl
> layer_impl1
=
508 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
509 scoped_refptr
<FakeTiledLayer
> layer2
=
510 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
511 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
=
512 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
513 RenderSurfaceLayerList render_surface_layer_list
;
515 layer_tree_host_
->root_layer()->AddChild(layer1
);
516 layer_tree_host_
->root_layer()->AddChild(layer2
);
518 // For this test we have two layers. layer1 exhausts most texture memory,
519 // leaving room for 2 more tiles from layer2, but not all three tiles. First
520 // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
521 // we will fail on the third tile of layer2, and this should not leave the
522 // second tile in a bad state.
524 // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
525 // for 2 tiles only in the other layer.
526 gfx::Rect
layer1_rect(0, 0, 100, 2400);
528 // This requires 4*30000 bytes of memory.
529 gfx::Rect
layer2_rect(0, 0, 100, 300);
531 // Paint a single tile in layer2 so that it will idle paint.
532 layer1
->SetBounds(layer1_rect
.size());
533 layer2
->SetBounds(layer2_rect
.size());
534 CalcDrawProps(&render_surface_layer_list
);
535 layer1
->draw_properties().visible_content_rect
= layer1_rect
;
536 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
537 bool needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
538 // We should need idle-painting for both remaining tiles in layer2.
539 EXPECT_TRUE(needs_update
);
541 // Reduce our memory limits to 1mb.
542 resource_manager_
->SetMaxMemoryLimitBytes(1024 * 1024);
544 // Now idle paint layer2. We are going to run out of memory though!
545 // Oh well, commit the frame and push.
546 for (int i
= 0; i
< 4; i
++) {
547 needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
550 // Sanity check, we should have textures for the big layer.
551 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 0));
552 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 23));
554 // We should only have the first two tiles from layer2 since
555 // it failed to idle update the last tile.
556 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
557 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
558 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
559 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
561 EXPECT_FALSE(needs_update
);
562 EXPECT_FALSE(layer_impl2
->HasResourceIdForTileAt(0, 2));
565 TEST_F(TiledLayerTest
, PushIdlePaintedOccludedTiles
) {
566 scoped_refptr
<FakeTiledLayer
> layer
=
567 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
568 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
569 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
570 RenderSurfaceLayerList render_surface_layer_list
;
571 TestOcclusionTracker occluded
;
572 occlusion_
= &occluded
;
574 layer_tree_host_
->root_layer()->AddChild(layer
);
576 // The tile size is 100x100, so this invalidates one occluded tile, culls it
577 // during paint, but prepaints it.
578 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 100, 100)));
580 layer
->SetBounds(gfx::Size(100, 100));
581 CalcDrawProps(&render_surface_layer_list
);
582 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
583 UpdateAndPush(layer
, layer_impl
);
585 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
588 TEST_F(TiledLayerTest
, PushTilesMarkedDirtyDuringPaint
) {
589 scoped_refptr
<FakeTiledLayer
> layer
=
590 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
591 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
592 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
593 RenderSurfaceLayerList render_surface_layer_list
;
595 layer_tree_host_
->root_layer()->AddChild(layer
);
597 // The tile size is 100x100, so this invalidates and then paints two tiles.
598 // However, during the paint, we invalidate one of the tiles. This should
599 // not prevent the tile from being pushed.
600 layer
->fake_layer_updater()->SetRectToInvalidate(
601 gfx::Rect(0, 50, 100, 50), layer
.get());
602 layer
->SetBounds(gfx::Size(100, 200));
603 CalcDrawProps(&render_surface_layer_list
);
604 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
605 UpdateAndPush(layer
, layer_impl
);
607 // We should have both tiles on the impl side.
608 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
609 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
612 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer
) {
613 scoped_refptr
<FakeTiledLayer
> layer1
=
614 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
615 scoped_refptr
<FakeTiledLayer
> layer2
=
616 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
617 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
618 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
619 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
620 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
621 RenderSurfaceLayerList render_surface_layer_list
;
623 layer_tree_host_
->root_layer()->AddChild(layer1
);
624 layer_tree_host_
->root_layer()->AddChild(layer2
);
626 // Invalidate a tile on layer1, during update of layer 2.
627 layer2
->fake_layer_updater()->SetRectToInvalidate(
628 gfx::Rect(0, 50, 100, 50), layer1
.get());
629 layer1
->SetBounds(gfx::Size(100, 200));
630 layer2
->SetBounds(gfx::Size(100, 200));
631 CalcDrawProps(&render_surface_layer_list
);
632 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
633 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
634 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
636 // We should have both tiles on the impl side for all layers.
637 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
638 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
639 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
640 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
643 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
) {
644 scoped_refptr
<FakeTiledLayer
> layer1
=
645 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
646 scoped_refptr
<FakeTiledLayer
> layer2
=
647 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
648 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
649 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
650 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
651 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
652 RenderSurfaceLayerList render_surface_layer_list
;
654 layer_tree_host_
->root_layer()->AddChild(layer1
);
655 layer_tree_host_
->root_layer()->AddChild(layer2
);
657 layer1
->fake_layer_updater()->SetRectToInvalidate(
658 gfx::Rect(0, 50, 100, 50), layer2
.get());
659 layer1
->SetBounds(gfx::Size(100, 200));
660 layer2
->SetBounds(gfx::Size(100, 200));
661 CalcDrawProps(&render_surface_layer_list
);
662 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
663 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
664 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
666 // We should have both tiles on the impl side for all layers.
667 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
668 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
669 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
670 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
673 TEST_F(TiledLayerTest
, PaintSmallAnimatedLayersImmediately
) {
674 // Create a LayerTreeHost that has the right viewportsize,
675 // so the layer is considered small enough.
676 bool run_out_of_memory
[2] = { false, true };
677 for (int i
= 0; i
< 2; i
++) {
678 // Create a layer with 5x5 tiles, with 4x4 size viewport.
679 int viewport_width
= 4 * FakeTiledLayer::tile_size().width();
680 int viewport_height
= 4 * FakeTiledLayer::tile_size().width();
681 int layer_width
= 5 * FakeTiledLayer::tile_size().width();
682 int layer_height
= 5 * FakeTiledLayer::tile_size().height();
683 int memory_for_layer
= layer_width
* layer_height
* 4;
684 layer_tree_host_
->SetViewportSize(
685 gfx::Size(viewport_width
, viewport_height
));
687 // Use 10x5 tiles to run out of memory.
688 if (run_out_of_memory
[i
])
691 resource_manager_
->SetMaxMemoryLimitBytes(memory_for_layer
);
693 scoped_refptr
<FakeTiledLayer
> layer
=
694 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
695 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
696 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
697 RenderSurfaceLayerList render_surface_layer_list
;
699 layer_tree_host_
->root_layer()->AddChild(layer
);
701 // Full size layer with half being visible.
702 layer
->SetBounds(gfx::Size(layer_width
, layer_height
));
703 gfx::Rect
visible_rect(0, 0, layer_width
/ 2, layer_height
);
704 CalcDrawProps(&render_surface_layer_list
);
706 // Pretend the layer is animating.
707 layer
->draw_properties().target_space_transform_is_animating
= true;
708 layer
->draw_properties().visible_content_rect
= visible_rect
;
709 layer
->SetLayerTreeHost(layer_tree_host_
.get());
711 // The layer should paint its entire contents on the first paint
712 // if it is close to the viewport size and has the available memory.
713 layer
->SetTexturePriorities(priority_calculator_
);
714 resource_manager_
->PrioritizeTextures();
715 layer
->SavePaintProperties();
716 layer
->Update(queue_
.get(), nullptr);
718 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
720 // We should have all the tiles for the small animated layer.
721 // We should still have the visible tiles when we didn't
722 // have enough memory for all the tiles.
723 if (!run_out_of_memory
[i
]) {
724 for (int i
= 0; i
< 5; ++i
) {
725 for (int j
= 0; j
< 5; ++j
)
726 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
729 for (int i
= 0; i
< 10; ++i
) {
730 for (int j
= 0; j
< 5; ++j
)
731 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
), i
< 5);
735 layer
->RemoveFromParent();
739 TEST_F(TiledLayerTest
, IdlePaintOutOfMemory
) {
740 scoped_refptr
<FakeTiledLayer
> layer
=
741 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
742 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
743 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
744 RenderSurfaceLayerList render_surface_layer_list
;
746 layer_tree_host_
->root_layer()->AddChild(layer
);
748 // We have enough memory for only the visible rect, so we will run out of
749 // memory in first idle paint.
750 int memory_limit
= 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
751 resource_manager_
->SetMaxMemoryLimitBytes(memory_limit
);
753 // The tile size is 100x100, so this invalidates and then paints two tiles.
754 bool needs_update
= false;
755 layer
->SetBounds(gfx::Size(300, 300));
756 CalcDrawProps(&render_surface_layer_list
);
757 layer
->draw_properties().visible_content_rect
= gfx::Rect(100, 100, 100, 100);
758 for (int i
= 0; i
< 2; i
++)
759 needs_update
= UpdateAndPush(layer
, layer_impl
);
761 // Idle-painting should see no more priority tiles for painting.
762 EXPECT_FALSE(needs_update
);
764 // We should have one tile on the impl side.
765 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
768 TEST_F(TiledLayerTest
, IdlePaintZeroSizedLayer
) {
769 scoped_refptr
<FakeTiledLayer
> layer
=
770 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
771 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
772 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
774 layer_tree_host_
->root_layer()->AddChild(layer
);
776 bool animating
[2] = { false, true };
777 for (int i
= 0; i
< 2; i
++) {
778 // Pretend the layer is animating.
779 layer
->draw_properties().target_space_transform_is_animating
= animating
[i
];
781 // The layer's bounds are empty.
782 // Empty layers don't paint or idle-paint.
783 layer
->SetBounds(gfx::Size());
785 RenderSurfaceLayerList render_surface_layer_list
;
786 CalcDrawProps(&render_surface_layer_list
);
787 layer
->draw_properties().visible_content_rect
= gfx::Rect();
788 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
790 // Empty layers don't have tiles.
791 EXPECT_EQ(0u, layer
->NumPaintedTiles());
793 // Empty layers don't need prepaint.
794 EXPECT_FALSE(needs_update
);
796 // Empty layers don't have tiles.
797 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
801 TEST_F(TiledLayerTest
, IdlePaintNonVisibleLayers
) {
802 scoped_refptr
<FakeTiledLayer
> layer
=
803 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
804 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
805 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
807 // Alternate between not visible and visible.
808 gfx::Rect
v(0, 0, 100, 100);
809 gfx::Rect
nv(0, 0, 0, 0);
810 gfx::Rect visible_rect
[10] = { nv
, nv
, v
, v
, nv
, nv
, v
, v
, nv
, nv
};
811 bool invalidate
[10] = { true, true, true, true, true, true, true, true, false,
814 // We should not have any tiles except for when the layer was visible
815 // or after the layer was visible and we didn't invalidate.
816 bool have_tile
[10] = { false, false, true, true, false, false, true, true,
819 layer_tree_host_
->root_layer()->AddChild(layer
);
821 for (int i
= 0; i
< 10; i
++) {
822 layer
->SetBounds(gfx::Size(100, 100));
824 RenderSurfaceLayerList render_surface_layer_list
;
825 CalcDrawProps(&render_surface_layer_list
);
826 layer
->draw_properties().visible_content_rect
= visible_rect
[i
];
829 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
830 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
832 // We should never signal idle paint, as we painted the entire layer
833 // or the layer was not visible.
834 EXPECT_FALSE(needs_update
);
835 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(0, 0), have_tile
[i
]);
839 TEST_F(TiledLayerTest
, InvalidateFromPrepare
) {
840 scoped_refptr
<FakeTiledLayer
> layer
=
841 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
842 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
843 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
844 RenderSurfaceLayerList render_surface_layer_list
;
846 layer_tree_host_
->root_layer()->AddChild(layer
);
848 // The tile size is 100x100, so this invalidates and then paints two tiles.
849 layer
->SetBounds(gfx::Size(100, 200));
850 CalcDrawProps(&render_surface_layer_list
);
851 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
852 UpdateAndPush(layer
, layer_impl
);
854 // We should have both tiles on the impl side.
855 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
856 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
858 layer
->fake_layer_updater()->ClearPrepareCount();
859 // Invoke update again. As the layer is valid update shouldn't be invoked on
861 UpdateAndPush(layer
, layer_impl
);
862 EXPECT_EQ(0, layer
->fake_layer_updater()->prepare_count());
864 // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
866 layer
->fake_layer_updater()->SetRectToInvalidate(
867 gfx::Rect(25, 25, 50, 50), layer
.get());
868 layer
->fake_layer_updater()->ClearPrepareCount();
869 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
870 UpdateAndPush(layer
, layer_impl
);
871 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
872 layer
->fake_layer_updater()->ClearPrepareCount();
874 // The layer should still be invalid as update invoked invalidate.
875 UpdateAndPush(layer
, layer_impl
); // visible
876 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
879 TEST_F(TiledLayerTest
, VerifyUpdateRectWhenContentBoundsAreScaled
) {
880 // The update rect (that indicates what was actually painted) should be in
881 // layer space, not the content space.
882 scoped_refptr
<FakeTiledLayerWithScaledBounds
> layer
= make_scoped_refptr(
883 new FakeTiledLayerWithScaledBounds(resource_manager_
.get()));
885 layer_tree_host_
->root_layer()->AddChild(layer
);
887 gfx::Rect
layer_bounds(0, 0, 300, 200);
888 gfx::Rect
content_bounds(0, 0, 150, 250);
890 layer
->SetBounds(layer_bounds
.size());
891 layer
->SetContentBounds(content_bounds
.size());
892 layer
->draw_properties().visible_content_rect
= content_bounds
;
893 layer
->draw_properties().contents_scale_x
= .5f
;
894 layer
->draw_properties().contents_scale_y
= 1.25f
;
896 // On first update, the update_rect includes all tiles, even beyond the
897 // boundaries of the layer.
898 // However, it should still be in layer space, not content space.
899 layer
->InvalidateContentRect(content_bounds
);
901 layer
->SetTexturePriorities(priority_calculator_
);
902 resource_manager_
->PrioritizeTextures();
903 layer
->SavePaintProperties();
904 layer
->Update(queue_
.get(), nullptr);
906 // Update rect is 200x300 (tile size of 100x100). Scaled this gives 400x240.
907 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 400, 240), layer
->update_rect());
910 // After the tiles are updated once, another invalidate only needs to update
911 // the bounds of the layer.
912 layer
->SetTexturePriorities(priority_calculator_
);
913 resource_manager_
->PrioritizeTextures();
914 layer
->InvalidateContentRect(content_bounds
);
915 layer
->SavePaintProperties();
916 layer
->Update(queue_
.get(), nullptr);
917 EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds
), layer
->update_rect());
920 // Partial re-paint should also be represented by the update rect in layer
921 // space, not content space.
922 gfx::Rect
partial_damage(30, 100, 10, 10);
923 layer
->InvalidateContentRect(partial_damage
);
924 layer
->SetTexturePriorities(priority_calculator_
);
925 resource_manager_
->PrioritizeTextures();
926 layer
->SavePaintProperties();
927 layer
->Update(queue_
.get(), nullptr);
928 EXPECT_FLOAT_RECT_EQ(gfx::RectF(60, 80, 20, 8), layer
->update_rect());
931 TEST_F(TiledLayerTest
, VerifyInvalidationWhenContentsScaleChanges
) {
932 scoped_refptr
<FakeTiledLayer
> layer
=
933 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
934 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
935 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
936 RenderSurfaceLayerList render_surface_layer_list
;
938 layer_tree_host_
->root_layer()->AddChild(layer
);
940 // Create a layer with one tile.
941 layer
->SetBounds(gfx::Size(100, 100));
942 CalcDrawProps(&render_surface_layer_list
);
943 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
944 layer
->Update(queue_
.get(), nullptr);
946 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
947 layer
->last_needs_display_rect());
949 // Push the tiles to the impl side and check that there is exactly one.
950 layer
->SetTexturePriorities(priority_calculator_
);
951 resource_manager_
->PrioritizeTextures();
952 layer
->SavePaintProperties();
953 layer
->Update(queue_
.get(), nullptr);
955 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
956 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
957 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
958 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
959 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
961 layer
->SetNeedsDisplayRect(gfx::Rect());
962 EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer
->last_needs_display_rect());
964 // Change the contents scale.
965 layer
->UpdateContentsScale(2.f
);
966 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 200, 200);
968 // The impl side should get 2x2 tiles now.
969 layer
->SetTexturePriorities(priority_calculator_
);
970 resource_manager_
->PrioritizeTextures();
971 layer
->SavePaintProperties();
972 layer
->Update(queue_
.get(), nullptr);
974 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
975 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
976 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
977 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 0));
978 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
980 // Verify that changing the contents scale caused invalidation, and
981 // that the layer-space rectangle requiring painting is not scaled.
982 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
983 layer
->last_needs_display_rect());
985 // Invalidate the entire layer again, but do not paint. All tiles should be
986 // gone now from the impl side.
987 layer
->SetNeedsDisplay();
988 layer
->SetTexturePriorities(priority_calculator_
);
989 resource_manager_
->PrioritizeTextures();
991 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
992 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
993 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
994 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
995 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
998 TEST_F(TiledLayerTest
, SkipsDrawGetsReset
) {
999 // Create two 300 x 300 tiled layers.
1000 gfx::Size
content_bounds(300, 300);
1001 gfx::Rect
content_rect(content_bounds
);
1003 // We have enough memory for only one of the two layers.
1004 int memory_limit
= 4 * 300 * 300; // 4 bytes per pixel.
1006 scoped_refptr
<FakeTiledLayer
> root_layer
= make_scoped_refptr(
1007 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1008 scoped_refptr
<FakeTiledLayer
> child_layer
= make_scoped_refptr(
1009 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1010 root_layer
->AddChild(child_layer
);
1012 root_layer
->SetBounds(content_bounds
);
1013 root_layer
->draw_properties().visible_content_rect
= content_rect
;
1014 root_layer
->SetPosition(gfx::PointF(0, 0));
1015 child_layer
->SetBounds(content_bounds
);
1016 child_layer
->draw_properties().visible_content_rect
= content_rect
;
1017 child_layer
->SetPosition(gfx::PointF(0, 0));
1018 root_layer
->InvalidateContentRect(content_rect
);
1019 child_layer
->InvalidateContentRect(content_rect
);
1021 layer_tree_host_
->SetRootLayer(root_layer
);
1022 layer_tree_host_
->SetViewportSize(gfx::Size(300, 300));
1023 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1026 layer_tree_host_
->UpdateLayers(queue_
.get());
1028 // We'll skip the root layer.
1029 EXPECT_TRUE(root_layer
->SkipsDraw());
1030 EXPECT_FALSE(child_layer
->SkipsDraw());
1032 layer_tree_host_
->CommitComplete();
1034 // Remove the child layer.
1035 root_layer
->RemoveAllChildren();
1037 layer_tree_host_
->UpdateLayers(queue_
.get());
1038 EXPECT_FALSE(root_layer
->SkipsDraw());
1040 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1041 resource_provider_
.get());
1042 layer_tree_host_
->SetRootLayer(nullptr);
1045 TEST_F(TiledLayerTest
, ResizeToSmaller
) {
1046 scoped_refptr
<FakeTiledLayer
> layer
=
1047 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1049 layer_tree_host_
->root_layer()->AddChild(layer
);
1051 layer
->SetBounds(gfx::Size(700, 700));
1052 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1053 layer
->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
1055 layer
->SetTexturePriorities(priority_calculator_
);
1056 resource_manager_
->PrioritizeTextures();
1057 layer
->SavePaintProperties();
1058 layer
->Update(queue_
.get(), nullptr);
1060 layer
->SetBounds(gfx::Size(200, 200));
1061 layer
->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
1064 TEST_F(TiledLayerTest
, HugeLayerUpdateCrash
) {
1065 scoped_refptr
<FakeTiledLayer
> layer
=
1066 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1068 layer_tree_host_
->root_layer()->AddChild(layer
);
1071 layer
->SetBounds(gfx::Size(size
, size
));
1072 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1073 layer
->InvalidateContentRect(gfx::Rect(0, 0, size
, size
));
1075 // Ensure no crash for bounds where size * size would overflow an int.
1076 layer
->SetTexturePriorities(priority_calculator_
);
1077 resource_manager_
->PrioritizeTextures();
1078 layer
->SavePaintProperties();
1079 layer
->Update(queue_
.get(), nullptr);
1082 class TiledLayerPartialUpdateTest
: public TiledLayerTest
{
1084 TiledLayerPartialUpdateTest() { settings_
.max_partial_texture_updates
= 4; }
1087 TEST_F(TiledLayerPartialUpdateTest
, PartialUpdates
) {
1088 // Create one 300 x 200 tiled layer with 3 x 2 tiles.
1089 gfx::Size
content_bounds(300, 200);
1090 gfx::Rect
content_rect(content_bounds
);
1092 scoped_refptr
<FakeTiledLayer
> layer
= make_scoped_refptr(
1093 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1094 layer
->SetBounds(content_bounds
);
1095 layer
->SetPosition(gfx::PointF(0, 0));
1096 layer
->draw_properties().visible_content_rect
= content_rect
;
1097 layer
->InvalidateContentRect(content_rect
);
1099 layer_tree_host_
->SetRootLayer(layer
);
1100 layer_tree_host_
->SetViewportSize(gfx::Size(300, 200));
1102 // Full update of all 6 tiles.
1103 layer_tree_host_
->UpdateLayers(queue_
.get());
1105 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1106 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1107 EXPECT_EQ(6u, queue_
->FullUploadSize());
1108 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1110 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1111 EXPECT_FALSE(queue_
->HasMoreUpdates());
1112 layer
->fake_layer_updater()->ClearUpdateCount();
1113 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1115 layer_tree_host_
->CommitComplete();
1117 // Full update of 3 tiles and partial update of 3 tiles.
1118 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
1119 layer_tree_host_
->UpdateLayers(queue_
.get());
1121 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1122 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1123 EXPECT_EQ(3u, queue_
->FullUploadSize());
1124 EXPECT_EQ(3u, queue_
->PartialUploadSize());
1126 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1127 EXPECT_FALSE(queue_
->HasMoreUpdates());
1128 layer
->fake_layer_updater()->ClearUpdateCount();
1129 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1131 layer_tree_host_
->CommitComplete();
1133 // Partial update of 6 tiles.
1134 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1136 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1137 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1138 layer_tree_host_
->UpdateLayers(queue_
.get());
1139 EXPECT_EQ(2u, queue_
->FullUploadSize());
1140 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1142 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1143 EXPECT_FALSE(queue_
->HasMoreUpdates());
1144 layer
->fake_layer_updater()->ClearUpdateCount();
1145 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1147 layer_tree_host_
->CommitComplete();
1149 // Checkerboard all tiles.
1150 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
1152 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1153 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1154 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1156 layer_tree_host_
->CommitComplete();
1158 // Partial update of 6 checkerboard tiles.
1159 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1161 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1162 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1163 layer_tree_host_
->UpdateLayers(queue_
.get());
1164 EXPECT_EQ(6u, queue_
->FullUploadSize());
1165 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1167 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1168 EXPECT_FALSE(queue_
->HasMoreUpdates());
1169 layer
->fake_layer_updater()->ClearUpdateCount();
1170 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1172 layer_tree_host_
->CommitComplete();
1174 // Partial update of 4 tiles.
1175 layer
->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
1177 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1178 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1179 layer_tree_host_
->UpdateLayers(queue_
.get());
1180 EXPECT_EQ(0u, queue_
->FullUploadSize());
1181 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1183 EXPECT_EQ(4, layer
->fake_layer_updater()->update_count());
1184 EXPECT_FALSE(queue_
->HasMoreUpdates());
1185 layer
->fake_layer_updater()->ClearUpdateCount();
1186 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1188 layer_tree_host_
->CommitComplete();
1190 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1191 resource_provider_
.get());
1192 layer_tree_host_
->SetRootLayer(nullptr);
1195 TEST_F(TiledLayerTest
, TilesPaintedWithoutOcclusion
) {
1196 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1198 scoped_refptr
<FakeTiledLayer
> layer
=
1199 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1200 RenderSurfaceLayerList render_surface_layer_list
;
1202 layer_tree_host_
->root_layer()->AddChild(layer
);
1204 // The tile size is 100x100, so this invalidates and then paints two tiles.
1205 layer
->SetBounds(gfx::Size(100, 200));
1206 CalcDrawProps(&render_surface_layer_list
);
1208 layer
->SetTexturePriorities(priority_calculator_
);
1209 resource_manager_
->PrioritizeTextures();
1210 layer
->SavePaintProperties();
1211 layer
->Update(queue_
.get(), nullptr);
1212 EXPECT_EQ(2, layer
->fake_layer_updater()->update_count());
1215 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusion
) {
1216 scoped_refptr
<FakeTiledLayer
> layer
=
1217 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1218 RenderSurfaceLayerList render_surface_layer_list
;
1219 TestOcclusionTracker occluded
;
1220 occlusion_
= &occluded
;
1222 layer_tree_host_
->root_layer()->AddChild(layer
);
1224 // The tile size is 100x100.
1226 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1227 layer
->SetBounds(gfx::Size(600, 600));
1228 CalcDrawProps(&render_surface_layer_list
);
1230 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1231 layer
->draw_properties().drawable_content_rect
=
1232 gfx::Rect(layer
->content_bounds());
1233 layer
->draw_properties().visible_content_rect
=
1234 gfx::Rect(layer
->content_bounds());
1235 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1237 layer
->SetTexturePriorities(priority_calculator_
);
1238 resource_manager_
->PrioritizeTextures();
1239 layer
->SavePaintProperties();
1240 layer
->Update(queue_
.get(), &occluded
);
1241 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1243 layer
->fake_layer_updater()->ClearUpdateCount();
1244 layer
->SetTexturePriorities(priority_calculator_
);
1245 resource_manager_
->PrioritizeTextures();
1247 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 200, 300, 100)));
1248 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1249 layer
->SavePaintProperties();
1250 layer
->Update(queue_
.get(), &occluded
);
1251 EXPECT_EQ(36 - 2, layer
->fake_layer_updater()->update_count());
1253 layer
->fake_layer_updater()->ClearUpdateCount();
1254 layer
->SetTexturePriorities(priority_calculator_
);
1255 resource_manager_
->PrioritizeTextures();
1257 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 250, 300, 100)));
1258 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1259 layer
->SavePaintProperties();
1260 layer
->Update(queue_
.get(), &occluded
);
1261 EXPECT_EQ(36, layer
->fake_layer_updater()->update_count());
1264 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndVisiblityConstraints
) {
1265 scoped_refptr
<FakeTiledLayer
> layer
=
1266 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1267 RenderSurfaceLayerList render_surface_layer_list
;
1268 TestOcclusionTracker occluded
;
1269 occlusion_
= &occluded
;
1271 layer_tree_host_
->root_layer()->AddChild(layer
);
1273 // The tile size is 100x100.
1275 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1276 layer
->SetBounds(gfx::Size(600, 600));
1277 CalcDrawProps(&render_surface_layer_list
);
1279 // The partially occluded tiles (by the 150 occlusion height) are visible
1280 // beyond the occlusion, so not culled.
1281 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1282 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 360);
1283 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 360);
1284 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1286 layer
->SetTexturePriorities(priority_calculator_
);
1287 resource_manager_
->PrioritizeTextures();
1288 layer
->SavePaintProperties();
1289 layer
->Update(queue_
.get(), &occluded
);
1290 EXPECT_EQ(24 - 3, layer
->fake_layer_updater()->update_count());
1292 layer
->fake_layer_updater()->ClearUpdateCount();
1294 // Now the visible region stops at the edge of the occlusion so the partly
1295 // visible tiles become fully occluded.
1296 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1297 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 350);
1298 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 350);
1299 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1300 layer
->SetTexturePriorities(priority_calculator_
);
1301 resource_manager_
->PrioritizeTextures();
1302 layer
->SavePaintProperties();
1303 layer
->Update(queue_
.get(), &occluded
);
1304 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1306 layer
->fake_layer_updater()->ClearUpdateCount();
1308 // Now the visible region is even smaller than the occlusion, it should have
1310 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1311 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 340);
1312 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 340);
1313 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1314 layer
->SetTexturePriorities(priority_calculator_
);
1315 resource_manager_
->PrioritizeTextures();
1316 layer
->SavePaintProperties();
1317 layer
->Update(queue_
.get(), &occluded
);
1318 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1321 TEST_F(TiledLayerTest
, TilesNotPaintedWithoutInvalidation
) {
1322 scoped_refptr
<FakeTiledLayer
> layer
=
1323 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1324 RenderSurfaceLayerList render_surface_layer_list
;
1325 TestOcclusionTracker occluded
;
1326 occlusion_
= &occluded
;
1328 layer_tree_host_
->root_layer()->AddChild(layer
);
1330 // The tile size is 100x100.
1332 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1333 layer
->SetBounds(gfx::Size(600, 600));
1334 CalcDrawProps(&render_surface_layer_list
);
1336 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1337 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 600);
1338 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 600);
1339 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1340 layer
->SetTexturePriorities(priority_calculator_
);
1341 resource_manager_
->PrioritizeTextures();
1342 layer
->SavePaintProperties();
1343 layer
->Update(queue_
.get(), &occluded
);
1344 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1347 layer
->fake_layer_updater()->ClearUpdateCount();
1348 layer
->SetTexturePriorities(priority_calculator_
);
1349 resource_manager_
->PrioritizeTextures();
1350 layer
->SavePaintProperties();
1352 // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
1354 layer
->Update(queue_
.get(), &occluded
);
1355 EXPECT_EQ(3, layer
->fake_layer_updater()->update_count());
1358 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndTransforms
) {
1359 scoped_refptr
<FakeTiledLayer
> layer
=
1360 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1361 RenderSurfaceLayerList render_surface_layer_list
;
1362 TestOcclusionTracker occluded
;
1363 occlusion_
= &occluded
;
1365 layer_tree_host_
->root_layer()->AddChild(layer
);
1367 // The tile size is 100x100.
1369 // This makes sure the painting works when the occluded region (in screen
1370 // space) is transformed differently than the layer.
1371 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1372 layer
->SetBounds(gfx::Size(600, 600));
1373 CalcDrawProps(&render_surface_layer_list
);
1374 gfx::Transform screen_transform
;
1375 screen_transform
.Scale(0.5, 0.5);
1376 layer
->draw_properties().screen_space_transform
= screen_transform
;
1377 layer
->draw_properties().target_space_transform
= screen_transform
;
1379 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 50)));
1380 layer
->draw_properties().drawable_content_rect
=
1381 gfx::Rect(layer
->content_bounds());
1382 layer
->draw_properties().visible_content_rect
=
1383 gfx::Rect(layer
->content_bounds());
1384 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1385 layer
->SetTexturePriorities(priority_calculator_
);
1386 resource_manager_
->PrioritizeTextures();
1387 layer
->SavePaintProperties();
1388 layer
->Update(queue_
.get(), &occluded
);
1389 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1392 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndScaling
) {
1393 scoped_refptr
<FakeTiledLayer
> layer
=
1394 new FakeTiledLayer(resource_manager_
.get());
1395 RenderSurfaceLayerList render_surface_layer_list
;
1396 TestOcclusionTracker occluded
;
1397 occlusion_
= &occluded
;
1399 scoped_refptr
<FakeTiledLayer
> scale_layer
=
1400 new FakeTiledLayer(resource_manager_
.get());
1401 gfx::Transform scale_transform
;
1402 scale_transform
.Scale(2.0, 2.0);
1403 scale_layer
->SetTransform(scale_transform
);
1405 layer_tree_host_
->root_layer()->AddChild(scale_layer
);
1407 // The tile size is 100x100.
1409 // This makes sure the painting works when the content space is scaled to
1410 // a different layer space.
1411 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1412 layer
->SetBounds(gfx::Size(300, 300));
1413 scale_layer
->AddChild(layer
);
1414 CalcDrawProps(&render_surface_layer_list
);
1415 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_x());
1416 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_y());
1417 EXPECT_EQ(gfx::Size(600, 600).ToString(),
1418 layer
->content_bounds().ToString());
1420 // No tiles are covered by the 300x50 occlusion.
1421 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 50)));
1422 layer
->draw_properties().drawable_content_rect
=
1423 gfx::Rect(layer
->bounds());
1424 layer
->draw_properties().visible_content_rect
=
1425 gfx::Rect(layer
->content_bounds());
1426 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1427 layer
->SetTexturePriorities(priority_calculator_
);
1428 resource_manager_
->PrioritizeTextures();
1429 layer
->SavePaintProperties();
1430 layer
->Update(queue_
.get(), &occluded
);
1431 int visible_tiles1
= 6 * 6;
1432 EXPECT_EQ(visible_tiles1
, layer
->fake_layer_updater()->update_count());
1434 layer
->fake_layer_updater()->ClearUpdateCount();
1436 // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1437 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1438 layer
->draw_properties().drawable_content_rect
=
1439 gfx::Rect(layer
->bounds());
1440 layer
->draw_properties().visible_content_rect
=
1441 gfx::Rect(layer
->content_bounds());
1442 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1443 layer
->SetTexturePriorities(priority_calculator_
);
1444 resource_manager_
->PrioritizeTextures();
1445 layer
->SavePaintProperties();
1446 layer
->Update(queue_
.get(), &occluded
);
1447 int visible_tiles2
= 6 * 6 - 3;
1448 EXPECT_EQ(visible_tiles2
, layer
->fake_layer_updater()->update_count());
1450 layer
->fake_layer_updater()->ClearUpdateCount();
1452 // This makes sure content scaling and transforms work together.
1453 // When the tiles are scaled down by half, they are 50x50 each in the
1455 gfx::Transform screen_transform
;
1456 screen_transform
.Scale(0.5, 0.5);
1457 layer
->draw_properties().screen_space_transform
= screen_transform
;
1458 layer
->draw_properties().target_space_transform
= screen_transform
;
1460 // An occlusion of 150x100 will cover 3*2 = 6 tiles.
1461 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 100)));
1463 gfx::Rect
layer_bounds_rect(layer
->bounds());
1464 layer
->draw_properties().drawable_content_rect
=
1465 gfx::ScaleToEnclosingRect(layer_bounds_rect
, 0.5f
);
1466 layer
->draw_properties().visible_content_rect
=
1467 gfx::Rect(layer
->content_bounds());
1468 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1469 layer
->SetTexturePriorities(priority_calculator_
);
1470 resource_manager_
->PrioritizeTextures();
1471 layer
->SavePaintProperties();
1472 layer
->Update(queue_
.get(), &occluded
);
1473 int visible_tiles3
= 6 * 6 - 6;
1474 EXPECT_EQ(visible_tiles3
, layer
->fake_layer_updater()->update_count());
1477 TEST_F(TiledLayerTest
, DontAllocateContentsWhenTargetSurfaceCantBeAllocated
) {
1478 // Tile size is 100x100.
1479 gfx::Rect
root_rect(0, 0, 300, 200);
1480 gfx::Rect
child_rect(0, 0, 300, 100);
1481 gfx::Rect
child2_rect(0, 100, 300, 100);
1483 scoped_refptr
<FakeTiledLayer
> root
= make_scoped_refptr(
1484 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1485 scoped_refptr
<Layer
> surface
= Layer::Create();
1486 scoped_refptr
<FakeTiledLayer
> child
= make_scoped_refptr(
1487 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1488 scoped_refptr
<FakeTiledLayer
> child2
= make_scoped_refptr(
1489 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1491 root
->SetBounds(root_rect
.size());
1492 root
->draw_properties().drawable_content_rect
= root_rect
;
1493 root
->draw_properties().visible_content_rect
= root_rect
;
1494 root
->AddChild(surface
);
1496 surface
->SetForceRenderSurface(true);
1497 surface
->SetOpacity(0.5);
1498 surface
->AddChild(child
);
1499 surface
->AddChild(child2
);
1501 child
->SetBounds(child_rect
.size());
1502 child
->SetPosition(child_rect
.origin());
1503 child
->draw_properties().visible_content_rect
= child_rect
;
1504 child
->draw_properties().drawable_content_rect
= root_rect
;
1506 child2
->SetBounds(child2_rect
.size());
1507 child2
->SetPosition(child2_rect
.origin());
1508 child2
->draw_properties().visible_content_rect
= child2_rect
;
1509 child2
->draw_properties().drawable_content_rect
= root_rect
;
1511 layer_tree_host_
->SetRootLayer(root
);
1512 layer_tree_host_
->SetViewportSize(root_rect
.size());
1514 // With a huge memory limit, all layers should update and push their textures.
1515 root
->InvalidateContentRect(root_rect
);
1516 child
->InvalidateContentRect(child_rect
);
1517 child2
->InvalidateContentRect(child2_rect
);
1518 layer_tree_host_
->UpdateLayers(queue_
.get());
1521 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1522 EXPECT_EQ(3, child
->fake_layer_updater()->update_count());
1523 EXPECT_EQ(3, child2
->fake_layer_updater()->update_count());
1524 EXPECT_FALSE(queue_
->HasMoreUpdates());
1526 root
->fake_layer_updater()->ClearUpdateCount();
1527 child
->fake_layer_updater()->ClearUpdateCount();
1528 child2
->fake_layer_updater()->ClearUpdateCount();
1530 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1531 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1532 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1533 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1534 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1535 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1536 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1537 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1538 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1540 for (unsigned i
= 0; i
< 3; ++i
) {
1541 for (unsigned j
= 0; j
< 2; ++j
)
1542 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1543 EXPECT_TRUE(child_impl
->HasResourceIdForTileAt(i
, 0));
1544 EXPECT_TRUE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1547 layer_tree_host_
->CommitComplete();
1549 // With a memory limit that includes only the root layer (3x2 tiles) and half
1550 // the surface that the child layers draw into, the child layers will not be
1551 // allocated. If the surface isn't accounted for, then one of the children
1552 // would fit within the memory limit.
1553 root
->InvalidateContentRect(root_rect
);
1554 child
->InvalidateContentRect(child_rect
);
1555 child2
->InvalidateContentRect(child2_rect
);
1557 size_t memory_limit
= (3 * 2 + 3 * 1) * (100 * 100) * 4;
1558 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1560 layer_tree_host_
->UpdateLayers(queue_
.get());
1563 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1564 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1565 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1566 EXPECT_FALSE(queue_
->HasMoreUpdates());
1568 root
->fake_layer_updater()->ClearUpdateCount();
1569 child
->fake_layer_updater()->ClearUpdateCount();
1570 child2
->fake_layer_updater()->ClearUpdateCount();
1572 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1573 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1574 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1575 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1576 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1577 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1578 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1579 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1580 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1582 for (unsigned i
= 0; i
< 3; ++i
) {
1583 for (unsigned j
= 0; j
< 2; ++j
)
1584 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1585 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1586 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1589 layer_tree_host_
->CommitComplete();
1591 // With a memory limit that includes only half the root layer, no contents
1592 // will be allocated. If render surface memory wasn't accounted for, there is
1593 // enough space for one of the children layers, but they draw into a surface
1594 // that can't be allocated.
1595 root
->InvalidateContentRect(root_rect
);
1596 child
->InvalidateContentRect(child_rect
);
1597 child2
->InvalidateContentRect(child2_rect
);
1599 memory_limit
= (3 * 1) * (100 * 100) * 4;
1600 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1602 layer_tree_host_
->UpdateLayers(queue_
.get());
1605 EXPECT_EQ(0, root
->fake_layer_updater()->update_count());
1606 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1607 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1608 EXPECT_FALSE(queue_
->HasMoreUpdates());
1610 root
->fake_layer_updater()->ClearUpdateCount();
1611 child
->fake_layer_updater()->ClearUpdateCount();
1612 child2
->fake_layer_updater()->ClearUpdateCount();
1614 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1615 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1616 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1617 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1618 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1619 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1620 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1621 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1622 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1624 for (unsigned i
= 0; i
< 3; ++i
) {
1625 for (unsigned j
= 0; j
< 2; ++j
)
1626 EXPECT_FALSE(root_impl
->HasResourceIdForTileAt(i
, j
));
1627 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1628 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1631 layer_tree_host_
->CommitComplete();
1633 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1634 resource_provider_
.get());
1635 layer_tree_host_
->SetRootLayer(nullptr);
1638 class TrackingLayerPainter
: public LayerPainter
{
1640 static scoped_ptr
<TrackingLayerPainter
> Create() {
1641 return make_scoped_ptr(new TrackingLayerPainter());
1644 void Paint(SkCanvas
* canvas
, const gfx::Rect
& content_rect
) override
{
1645 painted_rect_
= content_rect
;
1648 gfx::Rect
PaintedRect() const { return painted_rect_
; }
1649 void ResetPaintedRect() { painted_rect_
= gfx::Rect(); }
1652 gfx::Rect painted_rect_
;
1655 class UpdateTrackingTiledLayer
: public FakeTiledLayer
{
1657 explicit UpdateTrackingTiledLayer(PrioritizedResourceManager
* manager
)
1658 : FakeTiledLayer(manager
) {
1659 scoped_ptr
<TrackingLayerPainter
> painter(TrackingLayerPainter::Create());
1660 tracking_layer_painter_
= painter
.get();
1661 layer_updater_
= BitmapContentLayerUpdater::Create(painter
.Pass(), 0);
1664 TrackingLayerPainter
* tracking_layer_painter() const {
1665 return tracking_layer_painter_
;
1669 LayerUpdater
* Updater() const override
{ return layer_updater_
.get(); }
1670 ~UpdateTrackingTiledLayer() override
{}
1672 TrackingLayerPainter
* tracking_layer_painter_
;
1673 scoped_refptr
<BitmapContentLayerUpdater
> layer_updater_
;
1676 TEST_F(TiledLayerTest
, NonIntegerContentsScaleIsNotDistortedDuringPaint
) {
1677 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1678 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1680 layer_tree_host_
->root_layer()->AddChild(layer
);
1682 gfx::Rect
layer_rect(0, 0, 30, 31);
1683 layer
->SetPosition(layer_rect
.origin());
1684 layer
->SetBounds(layer_rect
.size());
1685 layer
->UpdateContentsScale(1.5f
);
1687 gfx::Rect
content_rect(0, 0, 45, 47);
1688 EXPECT_EQ(content_rect
.size(), layer
->content_bounds());
1689 layer
->draw_properties().visible_content_rect
= content_rect
;
1690 layer
->draw_properties().drawable_content_rect
= content_rect
;
1692 layer
->SetTexturePriorities(priority_calculator_
);
1693 resource_manager_
->PrioritizeTextures();
1694 layer
->SavePaintProperties();
1696 // Update the whole tile.
1697 layer
->Update(queue_
.get(), nullptr);
1698 layer
->tracking_layer_painter()->ResetPaintedRect();
1700 EXPECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1703 // Invalidate the entire layer in content space. When painting, the rect given
1704 // to webkit should match the layer's bounds.
1705 layer
->InvalidateContentRect(content_rect
);
1706 layer
->Update(queue_
.get(), nullptr);
1708 // Rounding leads to an extra pixel.
1709 gfx::Rect
expanded_layer_rect(layer_rect
);
1710 expanded_layer_rect
.set_height(32);
1711 EXPECT_EQ(expanded_layer_rect
,
1712 layer
->tracking_layer_painter()->PaintedRect());
1715 TEST_F(TiledLayerTest
,
1716 NonIntegerContentsScaleIsNotDistortedDuringInvalidation
) {
1717 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1718 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1720 layer_tree_host_
->root_layer()->AddChild(layer
);
1722 gfx::Rect
layer_rect(0, 0, 30, 31);
1723 layer
->SetPosition(layer_rect
.origin());
1724 layer
->SetBounds(layer_rect
.size());
1725 layer
->UpdateContentsScale(1.3f
);
1727 gfx::Rect
content_rect(layer
->content_bounds());
1728 layer
->draw_properties().visible_content_rect
= content_rect
;
1729 layer
->draw_properties().drawable_content_rect
= content_rect
;
1731 layer
->SetTexturePriorities(priority_calculator_
);
1732 resource_manager_
->PrioritizeTextures();
1733 layer
->SavePaintProperties();
1735 // Update the whole tile.
1736 layer
->Update(queue_
.get(), nullptr);
1737 layer
->tracking_layer_painter()->ResetPaintedRect();
1739 EXPECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1742 // Invalidate the entire layer in layer space. When painting, the rect given
1743 // to webkit should match the layer's bounds.
1744 layer
->SetNeedsDisplayRect(layer_rect
);
1745 layer
->Update(queue_
.get(), nullptr);
1747 // Rounding leads to an extra pixel.
1748 gfx::Rect
expanded_layer_rect(layer_rect
);
1749 expanded_layer_rect
.set_height(32);
1750 EXPECT_EQ(expanded_layer_rect
,
1751 layer
->tracking_layer_painter()->PaintedRect());