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;
90 settings_
.impl_side_painting
= false;
93 void SetUp() override
{
95 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
96 layer_tree_host_
= LayerTreeHost::CreateThreaded(
97 &synchonous_output_surface_client_
, shared_bitmap_manager_
.get(),
98 nullptr, nullptr, settings_
, base::MessageLoopProxy::current(),
99 impl_thread_
.message_loop_proxy(), nullptr);
100 synchonous_output_surface_client_
.SetLayerTreeHost(layer_tree_host_
.get());
101 proxy_
= layer_tree_host_
->proxy();
102 resource_manager_
= PrioritizedResourceManager::Create(proxy_
);
103 layer_tree_host_
->SetLayerTreeHostClientReady();
104 CHECK(synchonous_output_surface_client_
.EnsureOutputSurfaceCreated());
106 layer_tree_host_
->SetRootLayer(Layer::Create());
108 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
110 DebugScopedSetImplThreadAndMainThreadBlocked
111 impl_thread_and_main_thread_blocked(proxy_
);
112 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
113 shared_bitmap_manager_
.get(),
119 host_impl_
= make_scoped_ptr(new FakeLayerTreeHostImpl(
120 proxy_
, shared_bitmap_manager_
.get(), nullptr));
123 ~TiledLayerTest() override
{
124 ResourceManagerClearAllMemory(resource_manager_
.get(),
125 resource_provider_
.get());
127 DebugScopedSetImplThreadAndMainThreadBlocked
128 impl_thread_and_main_thread_blocked(proxy_
);
129 resource_provider_
= nullptr;
130 host_impl_
= nullptr;
133 void ResourceManagerClearAllMemory(
134 PrioritizedResourceManager
* resource_manager
,
135 ResourceProvider
* resource_provider
) {
137 DebugScopedSetImplThreadAndMainThreadBlocked
138 impl_thread_and_main_thread_blocked(proxy_
);
139 resource_manager
->ClearAllMemory(resource_provider
);
140 resource_manager
->ReduceMemory(resource_provider
);
142 resource_manager
->UnlinkAndClearEvictedBackings();
145 void UpdateTextures() {
146 DebugScopedSetImplThreadAndMainThreadBlocked
147 impl_thread_and_main_thread_blocked(proxy_
);
149 scoped_ptr
<ResourceUpdateController
> update_controller
=
150 ResourceUpdateController::Create(nullptr,
151 proxy_
->ImplThreadTaskRunner(),
153 resource_provider_
.get());
154 update_controller
->Finalize();
155 queue_
= make_scoped_ptr(new ResourceUpdateQueue
);
158 void LayerPushPropertiesTo(FakeTiledLayer
* layer
,
159 FakeTiledLayerImpl
* layer_impl
) {
160 DebugScopedSetImplThreadAndMainThreadBlocked
161 impl_thread_and_main_thread_blocked(proxy_
);
162 layer
->PushPropertiesTo(layer_impl
);
163 layer
->ResetNumDependentsNeedPushProperties();
166 void LayerUpdate(FakeTiledLayer
* layer
, TestOcclusionTracker
* occluded
) {
167 DebugScopedSetMainThread
main_thread(proxy_
);
168 layer
->Update(queue_
.get(), occluded
);
171 void CalcDrawProps(RenderSurfaceLayerList
* render_surface_layer_list
) {
173 occlusion_
->SetRenderTarget(layer_tree_host_
->root_layer());
175 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
176 layer_tree_host_
->root_layer(),
177 layer_tree_host_
->device_viewport_size(),
178 render_surface_layer_list
);
179 inputs
.device_scale_factor
= layer_tree_host_
->device_scale_factor();
180 inputs
.max_texture_size
=
181 layer_tree_host_
->GetRendererCapabilities().max_texture_size
;
182 inputs
.can_adjust_raster_scales
= true;
183 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
186 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
187 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
) {
188 scoped_refptr
<FakeTiledLayer
> layer2
;
189 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
;
190 return UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
193 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
194 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
,
195 const scoped_refptr
<FakeTiledLayer
>& layer2
,
196 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl2
) {
198 resource_manager_
->ClearPriorities();
200 layer1
->SetTexturePriorities(priority_calculator_
);
202 layer2
->SetTexturePriorities(priority_calculator_
);
203 resource_manager_
->PrioritizeTextures();
205 // Save paint properties
207 layer1
->SavePaintProperties();
209 layer2
->SavePaintProperties();
213 layer1
->Update(queue_
.get(), occlusion_
);
215 layer2
->Update(queue_
.get(), occlusion_
);
217 bool needs_update
= false;
219 needs_update
|= layer1
->NeedsIdlePaint();
221 needs_update
|= layer2
->NeedsIdlePaint();
223 // Update textures and push.
226 LayerPushPropertiesTo(layer1
.get(), layer_impl1
.get());
228 LayerPushPropertiesTo(layer2
.get(), layer_impl2
.get());
235 LayerTreeSettings settings_
;
236 FakeOutputSurfaceClient output_surface_client_
;
237 scoped_ptr
<OutputSurface
> output_surface_
;
238 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
239 scoped_ptr
<ResourceProvider
> resource_provider_
;
240 scoped_ptr
<ResourceUpdateQueue
> queue_
;
241 PriorityCalculator priority_calculator_
;
242 base::Thread impl_thread_
;
243 SynchronousOutputSurfaceClient synchonous_output_surface_client_
;
244 scoped_ptr
<LayerTreeHost
> layer_tree_host_
;
245 scoped_ptr
<FakeLayerTreeHostImpl
> host_impl_
;
246 scoped_ptr
<PrioritizedResourceManager
> resource_manager_
;
247 TestOcclusionTracker
* occlusion_
;
250 TEST_F(TiledLayerTest
, PushDirtyTiles
) {
251 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
253 scoped_refptr
<FakeTiledLayer
> layer
=
254 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
255 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
256 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
257 RenderSurfaceLayerList render_surface_layer_list
;
259 layer_tree_host_
->root_layer()->AddChild(layer
);
261 // The tile size is 100x100, so this invalidates and then paints two tiles.
262 layer
->SetBounds(gfx::Size(100, 200));
263 CalcDrawProps(&render_surface_layer_list
);
264 UpdateAndPush(layer
, layer_impl
);
266 // We should have both tiles on the impl side.
267 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
268 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
270 // Invalidates both tiles, but then only update one of them.
271 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
272 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
273 UpdateAndPush(layer
, layer_impl
);
275 // We should only have the first tile since the other tile was invalidated but
277 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
278 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
281 TEST_F(TiledLayerTest
, Scale
) {
282 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
284 layer_tree_host_
->SetDeviceScaleFactor(1.5);
286 scoped_refptr
<FakeTiledLayer
> layer
=
287 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
288 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
289 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
290 RenderSurfaceLayerList render_surface_layer_list
;
292 layer_tree_host_
->root_layer()->AddChild(layer
);
294 layer
->SetBounds(gfx::Size(100, 200));
295 CalcDrawProps(&render_surface_layer_list
);
297 // Change the width so that it doesn't divide cleanly by the scale.
298 layer
->SetBounds(gfx::Size(101, 200));
299 UpdateAndPush(layer
, layer_impl
);
301 EXPECT_EQ(1.5, layer
->fake_layer_updater()->last_contents_width_scale());
304 TEST_F(TiledLayerTest
, PushOccludedDirtyTiles
) {
305 scoped_refptr
<FakeTiledLayer
> layer
=
306 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
307 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
308 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
309 TestOcclusionTracker occluded
;
310 occlusion_
= &occluded
;
311 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
313 layer_tree_host_
->root_layer()->AddChild(layer
);
316 RenderSurfaceLayerList render_surface_layer_list
;
318 // The tile size is 100x100, so this invalidates and then paints two tiles.
319 layer
->SetBounds(gfx::Size(100, 200));
320 CalcDrawProps(&render_surface_layer_list
);
321 UpdateAndPush(layer
, layer_impl
);
323 // We should have both tiles on the impl side.
324 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
325 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
329 RenderSurfaceLayerList render_surface_layer_list
;
331 // Invalidates part of the top tile...
332 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
333 // ....but the area is occluded.
334 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 50, 50)));
335 CalcDrawProps(&render_surface_layer_list
);
336 UpdateAndPush(layer
, layer_impl
);
338 // We should still have both tiles, as part of the top tile is still
340 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
341 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
345 TEST_F(TiledLayerTest
, PushDeletedTiles
) {
346 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
348 scoped_refptr
<FakeTiledLayer
> layer
=
349 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
350 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
351 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
352 RenderSurfaceLayerList render_surface_layer_list
;
354 layer_tree_host_
->root_layer()->AddChild(layer
);
356 // The tile size is 100x100, so this invalidates and then paints two tiles.
357 layer
->SetBounds(gfx::Size(100, 200));
358 CalcDrawProps(&render_surface_layer_list
);
359 UpdateAndPush(layer
, layer_impl
);
361 // We should have both tiles on the impl side.
362 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
363 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
365 resource_manager_
->ClearPriorities();
366 ResourceManagerClearAllMemory(resource_manager_
.get(),
367 resource_provider_
.get());
368 resource_manager_
->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
370 // This should drop the tiles on the impl thread.
371 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
373 // We should now have no textures on the impl thread.
374 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
375 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
377 // This should recreate and update one of the deleted textures.
378 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
379 UpdateAndPush(layer
, layer_impl
);
381 // We should have one tiles on the impl side.
382 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
383 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
386 TEST_F(TiledLayerTest
, PushIdlePaintTiles
) {
387 scoped_refptr
<FakeTiledLayer
> layer
=
388 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
389 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
390 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
391 RenderSurfaceLayerList render_surface_layer_list
;
393 layer_tree_host_
->root_layer()->AddChild(layer
);
395 // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
396 // center. This paints 1 visible of the 25 invalid tiles.
397 layer
->SetBounds(gfx::Size(500, 500));
398 CalcDrawProps(&render_surface_layer_list
);
399 layer
->draw_properties().visible_content_rect
= gfx::Rect(200, 200, 100, 100);
400 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
401 // We should need idle-painting for surrounding tiles.
402 EXPECT_TRUE(needs_update
);
404 // We should have one tile on the impl side.
405 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(2, 2));
407 // For the next four updates, we should detect we still need idle painting.
408 for (int i
= 0; i
< 4; i
++) {
409 needs_update
= UpdateAndPush(layer
, layer_impl
);
410 EXPECT_TRUE(needs_update
);
413 // We should always finish painting eventually.
414 for (int i
= 0; i
< 20; i
++)
415 needs_update
= UpdateAndPush(layer
, layer_impl
);
417 // We should have pre-painted all of the surrounding tiles.
418 for (int i
= 0; i
< 5; i
++) {
419 for (int j
= 0; j
< 5; j
++)
420 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
423 EXPECT_FALSE(needs_update
);
426 TEST_F(TiledLayerTest
, PredictivePainting
) {
427 scoped_refptr
<FakeTiledLayer
> layer
=
428 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
429 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
430 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
432 layer_tree_host_
->root_layer()->AddChild(layer
);
434 // Prepainting should occur in the scroll direction first, and the
435 // visible rect should be extruded only along the dominant axis.
436 gfx::Vector2d directions
[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
437 gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
438 gfx::Vector2d(10, 20),
439 gfx::Vector2d(-20, 10) };
440 // We should push all tiles that touch the extruded visible rect.
441 gfx::Rect pushed_visible_tiles
[6] = {
442 gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
443 gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
445 // The first pre-paint should also paint first in the scroll
446 // direction so we should find one additional tile in the scroll direction.
447 gfx::Rect pushed_prepaint_tiles
[6] = {
448 gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
449 gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
451 for (int k
= 0; k
< 6; k
++) {
452 // The tile size is 100x100. Setup 5x5 tiles with one visible tile
454 gfx::Size bounds
= gfx::Size(500, 500);
455 gfx::Rect visible_rect
= gfx::Rect(200, 200, 100, 100);
456 gfx::Rect previous_visible_rect
=
457 gfx::Rect(visible_rect
.origin() + directions
[k
], visible_rect
.size());
458 gfx::Rect next_visible_rect
=
459 gfx::Rect(visible_rect
.origin() - directions
[k
], visible_rect
.size());
461 // Setup. Use the previous_visible_rect to setup the prediction for next
463 layer
->SetBounds(bounds
);
465 RenderSurfaceLayerList render_surface_layer_list
;
466 CalcDrawProps(&render_surface_layer_list
);
467 layer
->draw_properties().visible_content_rect
= previous_visible_rect
;
468 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
470 // Invalidate and move the visible_rect in the scroll direction.
471 // Check that the correct tiles have been painted in the visible pass.
472 layer
->SetNeedsDisplay();
473 layer
->draw_properties().visible_content_rect
= visible_rect
;
474 needs_update
= UpdateAndPush(layer
, layer_impl
);
475 for (int i
= 0; i
< 5; i
++) {
476 for (int j
= 0; j
< 5; j
++)
477 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
478 pushed_visible_tiles
[k
].Contains(i
, j
));
481 // Move the transform in the same direction without invalidating.
482 // Check that non-visible pre-painting occured in the correct direction.
483 // Ignore diagonal scrolls here (k > 3) as these have new visible content
486 layer
->draw_properties().visible_content_rect
= next_visible_rect
;
487 needs_update
= UpdateAndPush(layer
, layer_impl
);
488 for (int i
= 0; i
< 5; i
++) {
489 for (int j
= 0; j
< 5; j
++)
490 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
491 pushed_prepaint_tiles
[k
].Contains(i
, j
));
495 // We should always finish painting eventually.
496 for (int i
= 0; i
< 20; i
++)
497 needs_update
= UpdateAndPush(layer
, layer_impl
);
498 EXPECT_FALSE(needs_update
);
502 TEST_F(TiledLayerTest
, PushTilesAfterIdlePaintFailed
) {
503 // Start with 2mb of memory, but the test is going to try to use just more
504 // than 1mb, so we reduce to 1mb later.
505 resource_manager_
->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
506 scoped_refptr
<FakeTiledLayer
> layer1
=
507 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
508 scoped_ptr
<FakeTiledLayerImpl
> layer_impl1
=
509 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
510 scoped_refptr
<FakeTiledLayer
> layer2
=
511 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
512 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
=
513 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
514 RenderSurfaceLayerList render_surface_layer_list
;
516 layer_tree_host_
->root_layer()->AddChild(layer1
);
517 layer_tree_host_
->root_layer()->AddChild(layer2
);
519 // For this test we have two layers. layer1 exhausts most texture memory,
520 // leaving room for 2 more tiles from layer2, but not all three tiles. First
521 // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
522 // we will fail on the third tile of layer2, and this should not leave the
523 // second tile in a bad state.
525 // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
526 // for 2 tiles only in the other layer.
527 gfx::Rect
layer1_rect(0, 0, 100, 2400);
529 // This requires 4*30000 bytes of memory.
530 gfx::Rect
layer2_rect(0, 0, 100, 300);
532 // Paint a single tile in layer2 so that it will idle paint.
533 layer1
->SetBounds(layer1_rect
.size());
534 layer2
->SetBounds(layer2_rect
.size());
535 CalcDrawProps(&render_surface_layer_list
);
536 layer1
->draw_properties().visible_content_rect
= layer1_rect
;
537 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
538 bool needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
539 // We should need idle-painting for both remaining tiles in layer2.
540 EXPECT_TRUE(needs_update
);
542 // Reduce our memory limits to 1mb.
543 resource_manager_
->SetMaxMemoryLimitBytes(1024 * 1024);
545 // Now idle paint layer2. We are going to run out of memory though!
546 // Oh well, commit the frame and push.
547 for (int i
= 0; i
< 4; i
++) {
548 needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
551 // Sanity check, we should have textures for the big layer.
552 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 0));
553 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 23));
555 // We should only have the first two tiles from layer2 since
556 // it failed to idle update the last tile.
557 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
558 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
559 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
560 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
562 EXPECT_FALSE(needs_update
);
563 EXPECT_FALSE(layer_impl2
->HasResourceIdForTileAt(0, 2));
566 TEST_F(TiledLayerTest
, PushIdlePaintedOccludedTiles
) {
567 scoped_refptr
<FakeTiledLayer
> layer
=
568 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
569 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
570 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
571 RenderSurfaceLayerList render_surface_layer_list
;
572 TestOcclusionTracker occluded
;
573 occlusion_
= &occluded
;
575 layer_tree_host_
->root_layer()->AddChild(layer
);
577 // The tile size is 100x100, so this invalidates one occluded tile, culls it
578 // during paint, but prepaints it.
579 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 100, 100)));
581 layer
->SetBounds(gfx::Size(100, 100));
582 CalcDrawProps(&render_surface_layer_list
);
583 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
584 UpdateAndPush(layer
, layer_impl
);
586 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
589 TEST_F(TiledLayerTest
, PushTilesMarkedDirtyDuringPaint
) {
590 scoped_refptr
<FakeTiledLayer
> layer
=
591 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
592 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
593 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
594 RenderSurfaceLayerList render_surface_layer_list
;
596 layer_tree_host_
->root_layer()->AddChild(layer
);
598 // The tile size is 100x100, so this invalidates and then paints two tiles.
599 // However, during the paint, we invalidate one of the tiles. This should
600 // not prevent the tile from being pushed.
601 layer
->fake_layer_updater()->SetRectToInvalidate(
602 gfx::Rect(0, 50, 100, 50), layer
.get());
603 layer
->SetBounds(gfx::Size(100, 200));
604 CalcDrawProps(&render_surface_layer_list
);
605 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
606 UpdateAndPush(layer
, layer_impl
);
608 // We should have both tiles on the impl side.
609 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
610 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
613 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer
) {
614 scoped_refptr
<FakeTiledLayer
> layer1
=
615 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
616 scoped_refptr
<FakeTiledLayer
> layer2
=
617 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
618 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
619 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
620 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
621 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
622 RenderSurfaceLayerList render_surface_layer_list
;
624 layer_tree_host_
->root_layer()->AddChild(layer1
);
625 layer_tree_host_
->root_layer()->AddChild(layer2
);
627 // Invalidate a tile on layer1, during update of layer 2.
628 layer2
->fake_layer_updater()->SetRectToInvalidate(
629 gfx::Rect(0, 50, 100, 50), layer1
.get());
630 layer1
->SetBounds(gfx::Size(100, 200));
631 layer2
->SetBounds(gfx::Size(100, 200));
632 CalcDrawProps(&render_surface_layer_list
);
633 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
634 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
635 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
637 // We should have both tiles on the impl side for all layers.
638 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
639 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
640 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
641 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
644 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
) {
645 scoped_refptr
<FakeTiledLayer
> layer1
=
646 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
647 scoped_refptr
<FakeTiledLayer
> layer2
=
648 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
649 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
650 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
651 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
652 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
653 RenderSurfaceLayerList render_surface_layer_list
;
655 layer_tree_host_
->root_layer()->AddChild(layer1
);
656 layer_tree_host_
->root_layer()->AddChild(layer2
);
658 layer1
->fake_layer_updater()->SetRectToInvalidate(
659 gfx::Rect(0, 50, 100, 50), layer2
.get());
660 layer1
->SetBounds(gfx::Size(100, 200));
661 layer2
->SetBounds(gfx::Size(100, 200));
662 CalcDrawProps(&render_surface_layer_list
);
663 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
664 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
665 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
667 // We should have both tiles on the impl side for all layers.
668 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
669 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
670 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
671 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
674 TEST_F(TiledLayerTest
, PaintSmallAnimatedLayersImmediately
) {
675 // Create a LayerTreeHost that has the right viewportsize,
676 // so the layer is considered small enough.
677 bool run_out_of_memory
[2] = { false, true };
678 for (int i
= 0; i
< 2; i
++) {
679 // Create a layer with 5x5 tiles, with 4x4 size viewport.
680 int viewport_width
= 4 * FakeTiledLayer::tile_size().width();
681 int viewport_height
= 4 * FakeTiledLayer::tile_size().width();
682 int layer_width
= 5 * FakeTiledLayer::tile_size().width();
683 int layer_height
= 5 * FakeTiledLayer::tile_size().height();
684 int memory_for_layer
= layer_width
* layer_height
* 4;
685 layer_tree_host_
->SetViewportSize(
686 gfx::Size(viewport_width
, viewport_height
));
688 // Use 10x5 tiles to run out of memory.
689 if (run_out_of_memory
[i
])
692 resource_manager_
->SetMaxMemoryLimitBytes(memory_for_layer
);
694 scoped_refptr
<FakeTiledLayer
> layer
=
695 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
696 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
697 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
698 RenderSurfaceLayerList render_surface_layer_list
;
700 layer_tree_host_
->root_layer()->AddChild(layer
);
702 // Full size layer with half being visible.
703 layer
->SetBounds(gfx::Size(layer_width
, layer_height
));
704 gfx::Rect
visible_rect(0, 0, layer_width
/ 2, layer_height
);
705 CalcDrawProps(&render_surface_layer_list
);
707 // Pretend the layer is animating.
708 layer
->draw_properties().target_space_transform_is_animating
= true;
709 layer
->draw_properties().visible_content_rect
= visible_rect
;
710 layer
->SetLayerTreeHost(layer_tree_host_
.get());
712 // The layer should paint its entire contents on the first paint
713 // if it is close to the viewport size and has the available memory.
714 layer
->SetTexturePriorities(priority_calculator_
);
715 resource_manager_
->PrioritizeTextures();
716 layer
->SavePaintProperties();
717 layer
->Update(queue_
.get(), nullptr);
719 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
721 // We should have all the tiles for the small animated layer.
722 // We should still have the visible tiles when we didn't
723 // have enough memory for all the tiles.
724 if (!run_out_of_memory
[i
]) {
725 for (int i
= 0; i
< 5; ++i
) {
726 for (int j
= 0; j
< 5; ++j
)
727 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
730 for (int i
= 0; i
< 10; ++i
) {
731 for (int j
= 0; j
< 5; ++j
)
732 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
), i
< 5);
736 layer
->RemoveFromParent();
740 TEST_F(TiledLayerTest
, IdlePaintOutOfMemory
) {
741 scoped_refptr
<FakeTiledLayer
> layer
=
742 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
743 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
744 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
745 RenderSurfaceLayerList render_surface_layer_list
;
747 layer_tree_host_
->root_layer()->AddChild(layer
);
749 // We have enough memory for only the visible rect, so we will run out of
750 // memory in first idle paint.
751 int memory_limit
= 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
752 resource_manager_
->SetMaxMemoryLimitBytes(memory_limit
);
754 // The tile size is 100x100, so this invalidates and then paints two tiles.
755 bool needs_update
= false;
756 layer
->SetBounds(gfx::Size(300, 300));
757 CalcDrawProps(&render_surface_layer_list
);
758 layer
->draw_properties().visible_content_rect
= gfx::Rect(100, 100, 100, 100);
759 for (int i
= 0; i
< 2; i
++)
760 needs_update
= UpdateAndPush(layer
, layer_impl
);
762 // Idle-painting should see no more priority tiles for painting.
763 EXPECT_FALSE(needs_update
);
765 // We should have one tile on the impl side.
766 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
769 TEST_F(TiledLayerTest
, IdlePaintZeroSizedLayer
) {
770 scoped_refptr
<FakeTiledLayer
> layer
=
771 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
772 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
773 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
775 layer_tree_host_
->root_layer()->AddChild(layer
);
777 bool animating
[2] = { false, true };
778 for (int i
= 0; i
< 2; i
++) {
779 // Pretend the layer is animating.
780 layer
->draw_properties().target_space_transform_is_animating
= animating
[i
];
782 // The layer's bounds are empty.
783 // Empty layers don't paint or idle-paint.
784 layer
->SetBounds(gfx::Size());
786 RenderSurfaceLayerList render_surface_layer_list
;
787 CalcDrawProps(&render_surface_layer_list
);
788 layer
->draw_properties().visible_content_rect
= gfx::Rect();
789 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
791 // Empty layers don't have tiles.
792 EXPECT_EQ(0u, layer
->NumPaintedTiles());
794 // Empty layers don't need prepaint.
795 EXPECT_FALSE(needs_update
);
797 // Empty layers don't have tiles.
798 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
802 TEST_F(TiledLayerTest
, IdlePaintNonVisibleLayers
) {
803 scoped_refptr
<FakeTiledLayer
> layer
=
804 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
805 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
806 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
808 // Alternate between not visible and visible.
809 gfx::Rect
v(0, 0, 100, 100);
810 gfx::Rect
nv(0, 0, 0, 0);
811 gfx::Rect visible_rect
[10] = { nv
, nv
, v
, v
, nv
, nv
, v
, v
, nv
, nv
};
812 bool invalidate
[10] = { true, true, true, true, true, true, true, true, false,
815 // We should not have any tiles except for when the layer was visible
816 // or after the layer was visible and we didn't invalidate.
817 bool have_tile
[10] = { false, false, true, true, false, false, true, true,
820 layer_tree_host_
->root_layer()->AddChild(layer
);
822 for (int i
= 0; i
< 10; i
++) {
823 layer
->SetBounds(gfx::Size(100, 100));
825 RenderSurfaceLayerList render_surface_layer_list
;
826 CalcDrawProps(&render_surface_layer_list
);
827 layer
->draw_properties().visible_content_rect
= visible_rect
[i
];
830 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
831 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
833 // We should never signal idle paint, as we painted the entire layer
834 // or the layer was not visible.
835 EXPECT_FALSE(needs_update
);
836 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(0, 0), have_tile
[i
]);
840 TEST_F(TiledLayerTest
, InvalidateFromPrepare
) {
841 scoped_refptr
<FakeTiledLayer
> layer
=
842 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
843 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
844 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
845 RenderSurfaceLayerList render_surface_layer_list
;
847 layer_tree_host_
->root_layer()->AddChild(layer
);
849 // The tile size is 100x100, so this invalidates and then paints two tiles.
850 layer
->SetBounds(gfx::Size(100, 200));
851 CalcDrawProps(&render_surface_layer_list
);
852 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
853 UpdateAndPush(layer
, layer_impl
);
855 // We should have both tiles on the impl side.
856 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
857 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
859 layer
->fake_layer_updater()->ClearPrepareCount();
860 // Invoke update again. As the layer is valid update shouldn't be invoked on
862 UpdateAndPush(layer
, layer_impl
);
863 EXPECT_EQ(0, layer
->fake_layer_updater()->prepare_count());
865 // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
867 layer
->fake_layer_updater()->SetRectToInvalidate(
868 gfx::Rect(25, 25, 50, 50), layer
.get());
869 layer
->fake_layer_updater()->ClearPrepareCount();
870 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
871 UpdateAndPush(layer
, layer_impl
);
872 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
873 layer
->fake_layer_updater()->ClearPrepareCount();
875 // The layer should still be invalid as update invoked invalidate.
876 UpdateAndPush(layer
, layer_impl
); // visible
877 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
880 TEST_F(TiledLayerTest
, VerifyUpdateRectWhenContentBoundsAreScaled
) {
881 // The update rect (that indicates what was actually painted) should be in
882 // layer space, not the content space.
883 scoped_refptr
<FakeTiledLayerWithScaledBounds
> layer
= make_scoped_refptr(
884 new FakeTiledLayerWithScaledBounds(resource_manager_
.get()));
886 layer_tree_host_
->root_layer()->AddChild(layer
);
888 gfx::Rect
layer_bounds(0, 0, 300, 200);
889 gfx::Rect
content_bounds(0, 0, 150, 250);
891 layer
->SetBounds(layer_bounds
.size());
892 layer
->SetContentBounds(content_bounds
.size());
893 layer
->draw_properties().visible_content_rect
= content_bounds
;
894 layer
->draw_properties().contents_scale_x
= .5f
;
895 layer
->draw_properties().contents_scale_y
= 1.25f
;
897 // On first update, the update_rect includes all tiles, even beyond the
898 // boundaries of the layer.
899 // However, it should still be in layer space, not content space.
900 layer
->InvalidateContentRect(content_bounds
);
902 layer
->SetTexturePriorities(priority_calculator_
);
903 resource_manager_
->PrioritizeTextures();
904 layer
->SavePaintProperties();
905 layer
->Update(queue_
.get(), nullptr);
907 // Update rect is 200x300 (tile size of 100x100). Scaled this gives 400x240.
908 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 400, 240), layer
->update_rect());
911 // After the tiles are updated once, another invalidate only needs to update
912 // the bounds of the layer.
913 layer
->SetTexturePriorities(priority_calculator_
);
914 resource_manager_
->PrioritizeTextures();
915 layer
->InvalidateContentRect(content_bounds
);
916 layer
->SavePaintProperties();
917 layer
->Update(queue_
.get(), nullptr);
918 EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds
), layer
->update_rect());
921 // Partial re-paint should also be represented by the update rect in layer
922 // space, not content space.
923 gfx::Rect
partial_damage(30, 100, 10, 10);
924 layer
->InvalidateContentRect(partial_damage
);
925 layer
->SetTexturePriorities(priority_calculator_
);
926 resource_manager_
->PrioritizeTextures();
927 layer
->SavePaintProperties();
928 layer
->Update(queue_
.get(), nullptr);
929 EXPECT_FLOAT_RECT_EQ(gfx::RectF(60, 80, 20, 8), layer
->update_rect());
932 TEST_F(TiledLayerTest
, VerifyInvalidationWhenContentsScaleChanges
) {
933 scoped_refptr
<FakeTiledLayer
> layer
=
934 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
935 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
936 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
937 RenderSurfaceLayerList render_surface_layer_list
;
939 layer_tree_host_
->root_layer()->AddChild(layer
);
941 // Create a layer with one tile.
942 layer
->SetBounds(gfx::Size(100, 100));
943 CalcDrawProps(&render_surface_layer_list
);
944 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
945 layer
->Update(queue_
.get(), nullptr);
947 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
948 layer
->last_needs_display_rect());
950 // Push the tiles to the impl side and check that there is exactly one.
951 layer
->SetTexturePriorities(priority_calculator_
);
952 resource_manager_
->PrioritizeTextures();
953 layer
->SavePaintProperties();
954 layer
->Update(queue_
.get(), nullptr);
956 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
957 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
958 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
959 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
960 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
962 layer
->SetNeedsDisplayRect(gfx::Rect());
963 EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer
->last_needs_display_rect());
965 // Change the contents scale.
966 layer
->UpdateContentsScale(2.f
);
967 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 200, 200);
969 // The impl side should get 2x2 tiles now.
970 layer
->SetTexturePriorities(priority_calculator_
);
971 resource_manager_
->PrioritizeTextures();
972 layer
->SavePaintProperties();
973 layer
->Update(queue_
.get(), nullptr);
975 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
976 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
977 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
978 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 0));
979 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
981 // Verify that changing the contents scale caused invalidation, and
982 // that the layer-space rectangle requiring painting is not scaled.
983 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
984 layer
->last_needs_display_rect());
986 // Invalidate the entire layer again, but do not paint. All tiles should be
987 // gone now from the impl side.
988 layer
->SetNeedsDisplay();
989 layer
->SetTexturePriorities(priority_calculator_
);
990 resource_manager_
->PrioritizeTextures();
992 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
993 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
994 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
995 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
996 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
999 TEST_F(TiledLayerTest
, SkipsDrawGetsReset
) {
1000 // Create two 300 x 300 tiled layers.
1001 gfx::Size
content_bounds(300, 300);
1002 gfx::Rect
content_rect(content_bounds
);
1004 // We have enough memory for only one of the two layers.
1005 int memory_limit
= 4 * 300 * 300; // 4 bytes per pixel.
1007 scoped_refptr
<FakeTiledLayer
> root_layer
= make_scoped_refptr(
1008 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1009 scoped_refptr
<FakeTiledLayer
> child_layer
= make_scoped_refptr(
1010 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1011 root_layer
->AddChild(child_layer
);
1013 root_layer
->SetBounds(content_bounds
);
1014 root_layer
->draw_properties().visible_content_rect
= content_rect
;
1015 root_layer
->SetPosition(gfx::PointF(0, 0));
1016 child_layer
->SetBounds(content_bounds
);
1017 child_layer
->draw_properties().visible_content_rect
= content_rect
;
1018 child_layer
->SetPosition(gfx::PointF(0, 0));
1019 root_layer
->InvalidateContentRect(content_rect
);
1020 child_layer
->InvalidateContentRect(content_rect
);
1022 layer_tree_host_
->SetRootLayer(root_layer
);
1023 layer_tree_host_
->SetViewportSize(gfx::Size(300, 300));
1024 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1027 layer_tree_host_
->UpdateLayers(queue_
.get());
1029 // We'll skip the root layer.
1030 EXPECT_TRUE(root_layer
->SkipsDraw());
1031 EXPECT_FALSE(child_layer
->SkipsDraw());
1033 layer_tree_host_
->CommitComplete();
1035 // Remove the child layer.
1036 root_layer
->RemoveAllChildren();
1038 layer_tree_host_
->UpdateLayers(queue_
.get());
1039 EXPECT_FALSE(root_layer
->SkipsDraw());
1041 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1042 resource_provider_
.get());
1043 layer_tree_host_
->SetRootLayer(nullptr);
1046 TEST_F(TiledLayerTest
, ResizeToSmaller
) {
1047 scoped_refptr
<FakeTiledLayer
> layer
=
1048 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1050 layer_tree_host_
->root_layer()->AddChild(layer
);
1052 layer
->SetBounds(gfx::Size(700, 700));
1053 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1054 layer
->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
1056 layer
->SetTexturePriorities(priority_calculator_
);
1057 resource_manager_
->PrioritizeTextures();
1058 layer
->SavePaintProperties();
1059 layer
->Update(queue_
.get(), nullptr);
1061 layer
->SetBounds(gfx::Size(200, 200));
1062 layer
->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
1065 TEST_F(TiledLayerTest
, HugeLayerUpdateCrash
) {
1066 scoped_refptr
<FakeTiledLayer
> layer
=
1067 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1069 layer_tree_host_
->root_layer()->AddChild(layer
);
1072 layer
->SetBounds(gfx::Size(size
, size
));
1073 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1074 layer
->InvalidateContentRect(gfx::Rect(0, 0, size
, size
));
1076 // Ensure no crash for bounds where size * size would overflow an int.
1077 layer
->SetTexturePriorities(priority_calculator_
);
1078 resource_manager_
->PrioritizeTextures();
1079 layer
->SavePaintProperties();
1080 layer
->Update(queue_
.get(), nullptr);
1083 class TiledLayerPartialUpdateTest
: public TiledLayerTest
{
1085 TiledLayerPartialUpdateTest() { settings_
.max_partial_texture_updates
= 4; }
1088 TEST_F(TiledLayerPartialUpdateTest
, PartialUpdates
) {
1089 // Create one 300 x 200 tiled layer with 3 x 2 tiles.
1090 gfx::Size
content_bounds(300, 200);
1091 gfx::Rect
content_rect(content_bounds
);
1093 scoped_refptr
<FakeTiledLayer
> layer
= make_scoped_refptr(
1094 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1095 layer
->SetBounds(content_bounds
);
1096 layer
->SetPosition(gfx::PointF(0, 0));
1097 layer
->draw_properties().visible_content_rect
= content_rect
;
1098 layer
->InvalidateContentRect(content_rect
);
1100 layer_tree_host_
->SetRootLayer(layer
);
1101 layer_tree_host_
->SetViewportSize(gfx::Size(300, 200));
1103 // Full update of all 6 tiles.
1104 layer_tree_host_
->UpdateLayers(queue_
.get());
1106 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1107 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1108 EXPECT_EQ(6u, queue_
->FullUploadSize());
1109 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1111 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1112 EXPECT_FALSE(queue_
->HasMoreUpdates());
1113 layer
->fake_layer_updater()->ClearUpdateCount();
1114 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1116 layer_tree_host_
->CommitComplete();
1118 // Full update of 3 tiles and partial update of 3 tiles.
1119 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
1120 layer_tree_host_
->UpdateLayers(queue_
.get());
1122 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1123 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1124 EXPECT_EQ(3u, queue_
->FullUploadSize());
1125 EXPECT_EQ(3u, queue_
->PartialUploadSize());
1127 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1128 EXPECT_FALSE(queue_
->HasMoreUpdates());
1129 layer
->fake_layer_updater()->ClearUpdateCount();
1130 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1132 layer_tree_host_
->CommitComplete();
1134 // Partial update of 6 tiles.
1135 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1137 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1138 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1139 layer_tree_host_
->UpdateLayers(queue_
.get());
1140 EXPECT_EQ(2u, queue_
->FullUploadSize());
1141 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1143 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1144 EXPECT_FALSE(queue_
->HasMoreUpdates());
1145 layer
->fake_layer_updater()->ClearUpdateCount();
1146 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1148 layer_tree_host_
->CommitComplete();
1150 // Checkerboard all tiles.
1151 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
1153 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1154 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1155 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1157 layer_tree_host_
->CommitComplete();
1159 // Partial update of 6 checkerboard tiles.
1160 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1162 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1163 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1164 layer_tree_host_
->UpdateLayers(queue_
.get());
1165 EXPECT_EQ(6u, queue_
->FullUploadSize());
1166 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1168 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1169 EXPECT_FALSE(queue_
->HasMoreUpdates());
1170 layer
->fake_layer_updater()->ClearUpdateCount();
1171 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1173 layer_tree_host_
->CommitComplete();
1175 // Partial update of 4 tiles.
1176 layer
->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
1178 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1179 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1180 layer_tree_host_
->UpdateLayers(queue_
.get());
1181 EXPECT_EQ(0u, queue_
->FullUploadSize());
1182 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1184 EXPECT_EQ(4, layer
->fake_layer_updater()->update_count());
1185 EXPECT_FALSE(queue_
->HasMoreUpdates());
1186 layer
->fake_layer_updater()->ClearUpdateCount();
1187 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1189 layer_tree_host_
->CommitComplete();
1191 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1192 resource_provider_
.get());
1193 layer_tree_host_
->SetRootLayer(nullptr);
1196 TEST_F(TiledLayerTest
, TilesPaintedWithoutOcclusion
) {
1197 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1199 scoped_refptr
<FakeTiledLayer
> layer
=
1200 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1201 RenderSurfaceLayerList render_surface_layer_list
;
1203 layer_tree_host_
->root_layer()->AddChild(layer
);
1205 // The tile size is 100x100, so this invalidates and then paints two tiles.
1206 layer
->SetBounds(gfx::Size(100, 200));
1207 CalcDrawProps(&render_surface_layer_list
);
1209 layer
->SetTexturePriorities(priority_calculator_
);
1210 resource_manager_
->PrioritizeTextures();
1211 layer
->SavePaintProperties();
1212 layer
->Update(queue_
.get(), nullptr);
1213 EXPECT_EQ(2, layer
->fake_layer_updater()->update_count());
1216 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusion
) {
1217 scoped_refptr
<FakeTiledLayer
> layer
=
1218 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1219 RenderSurfaceLayerList render_surface_layer_list
;
1220 TestOcclusionTracker occluded
;
1221 occlusion_
= &occluded
;
1223 layer_tree_host_
->root_layer()->AddChild(layer
);
1225 // The tile size is 100x100.
1227 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1228 layer
->SetBounds(gfx::Size(600, 600));
1229 CalcDrawProps(&render_surface_layer_list
);
1231 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1232 layer
->draw_properties().drawable_content_rect
=
1233 gfx::Rect(layer
->content_bounds());
1234 layer
->draw_properties().visible_content_rect
=
1235 gfx::Rect(layer
->content_bounds());
1236 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1238 layer
->SetTexturePriorities(priority_calculator_
);
1239 resource_manager_
->PrioritizeTextures();
1240 layer
->SavePaintProperties();
1241 layer
->Update(queue_
.get(), &occluded
);
1242 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1244 layer
->fake_layer_updater()->ClearUpdateCount();
1245 layer
->SetTexturePriorities(priority_calculator_
);
1246 resource_manager_
->PrioritizeTextures();
1248 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 200, 300, 100)));
1249 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1250 layer
->SavePaintProperties();
1251 layer
->Update(queue_
.get(), &occluded
);
1252 EXPECT_EQ(36 - 2, layer
->fake_layer_updater()->update_count());
1254 layer
->fake_layer_updater()->ClearUpdateCount();
1255 layer
->SetTexturePriorities(priority_calculator_
);
1256 resource_manager_
->PrioritizeTextures();
1258 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 250, 300, 100)));
1259 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1260 layer
->SavePaintProperties();
1261 layer
->Update(queue_
.get(), &occluded
);
1262 EXPECT_EQ(36, layer
->fake_layer_updater()->update_count());
1265 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndVisiblityConstraints
) {
1266 scoped_refptr
<FakeTiledLayer
> layer
=
1267 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1268 RenderSurfaceLayerList render_surface_layer_list
;
1269 TestOcclusionTracker occluded
;
1270 occlusion_
= &occluded
;
1272 layer_tree_host_
->root_layer()->AddChild(layer
);
1274 // The tile size is 100x100.
1276 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1277 layer
->SetBounds(gfx::Size(600, 600));
1278 CalcDrawProps(&render_surface_layer_list
);
1280 // The partially occluded tiles (by the 150 occlusion height) are visible
1281 // beyond the occlusion, so not culled.
1282 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1283 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 360);
1284 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 360);
1285 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1287 layer
->SetTexturePriorities(priority_calculator_
);
1288 resource_manager_
->PrioritizeTextures();
1289 layer
->SavePaintProperties();
1290 layer
->Update(queue_
.get(), &occluded
);
1291 EXPECT_EQ(24 - 3, layer
->fake_layer_updater()->update_count());
1293 layer
->fake_layer_updater()->ClearUpdateCount();
1295 // Now the visible region stops at the edge of the occlusion so the partly
1296 // visible tiles become fully occluded.
1297 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1298 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 350);
1299 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 350);
1300 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1301 layer
->SetTexturePriorities(priority_calculator_
);
1302 resource_manager_
->PrioritizeTextures();
1303 layer
->SavePaintProperties();
1304 layer
->Update(queue_
.get(), &occluded
);
1305 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1307 layer
->fake_layer_updater()->ClearUpdateCount();
1309 // Now the visible region is even smaller than the occlusion, it should have
1311 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1312 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 340);
1313 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 340);
1314 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1315 layer
->SetTexturePriorities(priority_calculator_
);
1316 resource_manager_
->PrioritizeTextures();
1317 layer
->SavePaintProperties();
1318 layer
->Update(queue_
.get(), &occluded
);
1319 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1322 TEST_F(TiledLayerTest
, TilesNotPaintedWithoutInvalidation
) {
1323 scoped_refptr
<FakeTiledLayer
> layer
=
1324 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1325 RenderSurfaceLayerList render_surface_layer_list
;
1326 TestOcclusionTracker occluded
;
1327 occlusion_
= &occluded
;
1329 layer_tree_host_
->root_layer()->AddChild(layer
);
1331 // The tile size is 100x100.
1333 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1334 layer
->SetBounds(gfx::Size(600, 600));
1335 CalcDrawProps(&render_surface_layer_list
);
1337 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1338 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 600);
1339 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 600);
1340 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1341 layer
->SetTexturePriorities(priority_calculator_
);
1342 resource_manager_
->PrioritizeTextures();
1343 layer
->SavePaintProperties();
1344 layer
->Update(queue_
.get(), &occluded
);
1345 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1348 layer
->fake_layer_updater()->ClearUpdateCount();
1349 layer
->SetTexturePriorities(priority_calculator_
);
1350 resource_manager_
->PrioritizeTextures();
1351 layer
->SavePaintProperties();
1353 // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
1355 layer
->Update(queue_
.get(), &occluded
);
1356 EXPECT_EQ(3, layer
->fake_layer_updater()->update_count());
1359 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndTransforms
) {
1360 scoped_refptr
<FakeTiledLayer
> layer
=
1361 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1362 RenderSurfaceLayerList render_surface_layer_list
;
1363 TestOcclusionTracker occluded
;
1364 occlusion_
= &occluded
;
1366 layer_tree_host_
->root_layer()->AddChild(layer
);
1368 // The tile size is 100x100.
1370 // This makes sure the painting works when the occluded region (in screen
1371 // space) is transformed differently than the layer.
1372 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1373 layer
->SetBounds(gfx::Size(600, 600));
1374 CalcDrawProps(&render_surface_layer_list
);
1375 gfx::Transform screen_transform
;
1376 screen_transform
.Scale(0.5, 0.5);
1377 layer
->draw_properties().screen_space_transform
= screen_transform
;
1378 layer
->draw_properties().target_space_transform
= screen_transform
;
1380 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 50)));
1381 layer
->draw_properties().drawable_content_rect
=
1382 gfx::Rect(layer
->content_bounds());
1383 layer
->draw_properties().visible_content_rect
=
1384 gfx::Rect(layer
->content_bounds());
1385 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1386 layer
->SetTexturePriorities(priority_calculator_
);
1387 resource_manager_
->PrioritizeTextures();
1388 layer
->SavePaintProperties();
1389 layer
->Update(queue_
.get(), &occluded
);
1390 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1393 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndScaling
) {
1394 scoped_refptr
<FakeTiledLayer
> layer
=
1395 new FakeTiledLayer(resource_manager_
.get());
1396 RenderSurfaceLayerList render_surface_layer_list
;
1397 TestOcclusionTracker occluded
;
1398 occlusion_
= &occluded
;
1400 scoped_refptr
<FakeTiledLayer
> scale_layer
=
1401 new FakeTiledLayer(resource_manager_
.get());
1402 gfx::Transform scale_transform
;
1403 scale_transform
.Scale(2.0, 2.0);
1404 scale_layer
->SetTransform(scale_transform
);
1406 layer_tree_host_
->root_layer()->AddChild(scale_layer
);
1408 // The tile size is 100x100.
1410 // This makes sure the painting works when the content space is scaled to
1411 // a different layer space.
1412 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1413 layer
->SetBounds(gfx::Size(300, 300));
1414 scale_layer
->AddChild(layer
);
1415 CalcDrawProps(&render_surface_layer_list
);
1416 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_x());
1417 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_y());
1418 EXPECT_EQ(gfx::Size(600, 600).ToString(),
1419 layer
->content_bounds().ToString());
1421 // No tiles are covered by the 300x50 occlusion.
1422 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 50)));
1423 layer
->draw_properties().drawable_content_rect
=
1424 gfx::Rect(layer
->bounds());
1425 layer
->draw_properties().visible_content_rect
=
1426 gfx::Rect(layer
->content_bounds());
1427 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1428 layer
->SetTexturePriorities(priority_calculator_
);
1429 resource_manager_
->PrioritizeTextures();
1430 layer
->SavePaintProperties();
1431 layer
->Update(queue_
.get(), &occluded
);
1432 int visible_tiles1
= 6 * 6;
1433 EXPECT_EQ(visible_tiles1
, layer
->fake_layer_updater()->update_count());
1435 layer
->fake_layer_updater()->ClearUpdateCount();
1437 // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1438 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1439 layer
->draw_properties().drawable_content_rect
=
1440 gfx::Rect(layer
->bounds());
1441 layer
->draw_properties().visible_content_rect
=
1442 gfx::Rect(layer
->content_bounds());
1443 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1444 layer
->SetTexturePriorities(priority_calculator_
);
1445 resource_manager_
->PrioritizeTextures();
1446 layer
->SavePaintProperties();
1447 layer
->Update(queue_
.get(), &occluded
);
1448 int visible_tiles2
= 6 * 6 - 3;
1449 EXPECT_EQ(visible_tiles2
, layer
->fake_layer_updater()->update_count());
1451 layer
->fake_layer_updater()->ClearUpdateCount();
1453 // This makes sure content scaling and transforms work together.
1454 // When the tiles are scaled down by half, they are 50x50 each in the
1456 gfx::Transform screen_transform
;
1457 screen_transform
.Scale(0.5, 0.5);
1458 layer
->draw_properties().screen_space_transform
= screen_transform
;
1459 layer
->draw_properties().target_space_transform
= screen_transform
;
1461 // An occlusion of 150x100 will cover 3*2 = 6 tiles.
1462 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 100)));
1464 gfx::Rect
layer_bounds_rect(layer
->bounds());
1465 layer
->draw_properties().drawable_content_rect
=
1466 gfx::ScaleToEnclosingRect(layer_bounds_rect
, 0.5f
);
1467 layer
->draw_properties().visible_content_rect
=
1468 gfx::Rect(layer
->content_bounds());
1469 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1470 layer
->SetTexturePriorities(priority_calculator_
);
1471 resource_manager_
->PrioritizeTextures();
1472 layer
->SavePaintProperties();
1473 layer
->Update(queue_
.get(), &occluded
);
1474 int visible_tiles3
= 6 * 6 - 6;
1475 EXPECT_EQ(visible_tiles3
, layer
->fake_layer_updater()->update_count());
1478 TEST_F(TiledLayerTest
, DontAllocateContentsWhenTargetSurfaceCantBeAllocated
) {
1479 // Tile size is 100x100.
1480 gfx::Rect
root_rect(0, 0, 300, 200);
1481 gfx::Rect
child_rect(0, 0, 300, 100);
1482 gfx::Rect
child2_rect(0, 100, 300, 100);
1484 scoped_refptr
<FakeTiledLayer
> root
= make_scoped_refptr(
1485 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1486 scoped_refptr
<Layer
> surface
= Layer::Create();
1487 scoped_refptr
<FakeTiledLayer
> child
= make_scoped_refptr(
1488 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1489 scoped_refptr
<FakeTiledLayer
> child2
= make_scoped_refptr(
1490 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1492 root
->SetBounds(root_rect
.size());
1493 root
->draw_properties().drawable_content_rect
= root_rect
;
1494 root
->draw_properties().visible_content_rect
= root_rect
;
1495 root
->AddChild(surface
);
1497 surface
->SetForceRenderSurface(true);
1498 surface
->SetOpacity(0.5);
1499 surface
->AddChild(child
);
1500 surface
->AddChild(child2
);
1502 child
->SetBounds(child_rect
.size());
1503 child
->SetPosition(child_rect
.origin());
1504 child
->draw_properties().visible_content_rect
= child_rect
;
1505 child
->draw_properties().drawable_content_rect
= root_rect
;
1507 child2
->SetBounds(child2_rect
.size());
1508 child2
->SetPosition(child2_rect
.origin());
1509 child2
->draw_properties().visible_content_rect
= child2_rect
;
1510 child2
->draw_properties().drawable_content_rect
= root_rect
;
1512 layer_tree_host_
->SetRootLayer(root
);
1513 layer_tree_host_
->SetViewportSize(root_rect
.size());
1515 // With a huge memory limit, all layers should update and push their textures.
1516 root
->InvalidateContentRect(root_rect
);
1517 child
->InvalidateContentRect(child_rect
);
1518 child2
->InvalidateContentRect(child2_rect
);
1519 layer_tree_host_
->UpdateLayers(queue_
.get());
1522 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1523 EXPECT_EQ(3, child
->fake_layer_updater()->update_count());
1524 EXPECT_EQ(3, child2
->fake_layer_updater()->update_count());
1525 EXPECT_FALSE(queue_
->HasMoreUpdates());
1527 root
->fake_layer_updater()->ClearUpdateCount();
1528 child
->fake_layer_updater()->ClearUpdateCount();
1529 child2
->fake_layer_updater()->ClearUpdateCount();
1531 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1532 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1533 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1534 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1535 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1536 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1537 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1538 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1539 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1541 for (unsigned i
= 0; i
< 3; ++i
) {
1542 for (unsigned j
= 0; j
< 2; ++j
)
1543 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1544 EXPECT_TRUE(child_impl
->HasResourceIdForTileAt(i
, 0));
1545 EXPECT_TRUE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1548 layer_tree_host_
->CommitComplete();
1550 // With a memory limit that includes only the root layer (3x2 tiles) and half
1551 // the surface that the child layers draw into, the child layers will not be
1552 // allocated. If the surface isn't accounted for, then one of the children
1553 // would fit within the memory limit.
1554 root
->InvalidateContentRect(root_rect
);
1555 child
->InvalidateContentRect(child_rect
);
1556 child2
->InvalidateContentRect(child2_rect
);
1558 size_t memory_limit
= (3 * 2 + 3 * 1) * (100 * 100) * 4;
1559 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1561 layer_tree_host_
->UpdateLayers(queue_
.get());
1564 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1565 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1566 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1567 EXPECT_FALSE(queue_
->HasMoreUpdates());
1569 root
->fake_layer_updater()->ClearUpdateCount();
1570 child
->fake_layer_updater()->ClearUpdateCount();
1571 child2
->fake_layer_updater()->ClearUpdateCount();
1573 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1574 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1575 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1576 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1577 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1578 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1579 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1580 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1581 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1583 for (unsigned i
= 0; i
< 3; ++i
) {
1584 for (unsigned j
= 0; j
< 2; ++j
)
1585 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1586 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1587 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1590 layer_tree_host_
->CommitComplete();
1592 // With a memory limit that includes only half the root layer, no contents
1593 // will be allocated. If render surface memory wasn't accounted for, there is
1594 // enough space for one of the children layers, but they draw into a surface
1595 // that can't be allocated.
1596 root
->InvalidateContentRect(root_rect
);
1597 child
->InvalidateContentRect(child_rect
);
1598 child2
->InvalidateContentRect(child2_rect
);
1600 memory_limit
= (3 * 1) * (100 * 100) * 4;
1601 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1603 layer_tree_host_
->UpdateLayers(queue_
.get());
1606 EXPECT_EQ(0, root
->fake_layer_updater()->update_count());
1607 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1608 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1609 EXPECT_FALSE(queue_
->HasMoreUpdates());
1611 root
->fake_layer_updater()->ClearUpdateCount();
1612 child
->fake_layer_updater()->ClearUpdateCount();
1613 child2
->fake_layer_updater()->ClearUpdateCount();
1615 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1616 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1617 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1618 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1619 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1620 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1621 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1622 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1623 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1625 for (unsigned i
= 0; i
< 3; ++i
) {
1626 for (unsigned j
= 0; j
< 2; ++j
)
1627 EXPECT_FALSE(root_impl
->HasResourceIdForTileAt(i
, j
));
1628 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1629 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1632 layer_tree_host_
->CommitComplete();
1634 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1635 resource_provider_
.get());
1636 layer_tree_host_
->SetRootLayer(nullptr);
1639 class TrackingLayerPainter
: public LayerPainter
{
1641 static scoped_ptr
<TrackingLayerPainter
> Create() {
1642 return make_scoped_ptr(new TrackingLayerPainter());
1645 void Paint(SkCanvas
* canvas
, const gfx::Rect
& content_rect
) override
{
1646 painted_rect_
= content_rect
;
1649 gfx::Rect
PaintedRect() const { return painted_rect_
; }
1650 void ResetPaintedRect() { painted_rect_
= gfx::Rect(); }
1653 gfx::Rect painted_rect_
;
1656 class UpdateTrackingTiledLayer
: public FakeTiledLayer
{
1658 explicit UpdateTrackingTiledLayer(PrioritizedResourceManager
* manager
)
1659 : FakeTiledLayer(manager
) {
1660 scoped_ptr
<TrackingLayerPainter
> painter(TrackingLayerPainter::Create());
1661 tracking_layer_painter_
= painter
.get();
1662 layer_updater_
= BitmapContentLayerUpdater::Create(painter
.Pass(), 0);
1665 TrackingLayerPainter
* tracking_layer_painter() const {
1666 return tracking_layer_painter_
;
1670 LayerUpdater
* Updater() const override
{ return layer_updater_
.get(); }
1671 ~UpdateTrackingTiledLayer() override
{}
1673 TrackingLayerPainter
* tracking_layer_painter_
;
1674 scoped_refptr
<BitmapContentLayerUpdater
> layer_updater_
;
1677 TEST_F(TiledLayerTest
, NonIntegerContentsScaleIsNotDistortedDuringPaint
) {
1678 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1679 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1681 layer_tree_host_
->root_layer()->AddChild(layer
);
1683 gfx::Rect
layer_rect(0, 0, 30, 31);
1684 layer
->SetPosition(layer_rect
.origin());
1685 layer
->SetBounds(layer_rect
.size());
1686 layer
->UpdateContentsScale(1.5f
);
1688 gfx::Rect
content_rect(0, 0, 45, 47);
1689 EXPECT_EQ(content_rect
.size(), layer
->content_bounds());
1690 layer
->draw_properties().visible_content_rect
= content_rect
;
1691 layer
->draw_properties().drawable_content_rect
= content_rect
;
1693 layer
->SetTexturePriorities(priority_calculator_
);
1694 resource_manager_
->PrioritizeTextures();
1695 layer
->SavePaintProperties();
1697 // Update the whole tile.
1698 layer
->Update(queue_
.get(), nullptr);
1699 layer
->tracking_layer_painter()->ResetPaintedRect();
1701 EXPECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1704 // Invalidate the entire layer in content space. When painting, the rect given
1705 // to webkit should match the layer's bounds.
1706 layer
->InvalidateContentRect(content_rect
);
1707 layer
->Update(queue_
.get(), nullptr);
1709 // Rounding leads to an extra pixel.
1710 gfx::Rect
expanded_layer_rect(layer_rect
);
1711 expanded_layer_rect
.set_height(32);
1712 EXPECT_EQ(expanded_layer_rect
,
1713 layer
->tracking_layer_painter()->PaintedRect());
1716 TEST_F(TiledLayerTest
,
1717 NonIntegerContentsScaleIsNotDistortedDuringInvalidation
) {
1718 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1719 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1721 layer_tree_host_
->root_layer()->AddChild(layer
);
1723 gfx::Rect
layer_rect(0, 0, 30, 31);
1724 layer
->SetPosition(layer_rect
.origin());
1725 layer
->SetBounds(layer_rect
.size());
1726 layer
->UpdateContentsScale(1.3f
);
1728 gfx::Rect
content_rect(layer
->content_bounds());
1729 layer
->draw_properties().visible_content_rect
= content_rect
;
1730 layer
->draw_properties().drawable_content_rect
= content_rect
;
1732 layer
->SetTexturePriorities(priority_calculator_
);
1733 resource_manager_
->PrioritizeTextures();
1734 layer
->SavePaintProperties();
1736 // Update the whole tile.
1737 layer
->Update(queue_
.get(), nullptr);
1738 layer
->tracking_layer_painter()->ResetPaintedRect();
1740 EXPECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1743 // Invalidate the entire layer in layer space. When painting, the rect given
1744 // to webkit should match the layer's bounds.
1745 layer
->SetNeedsDisplayRect(layer_rect
);
1746 layer
->Update(queue_
.get(), nullptr);
1748 // Rounding leads to an extra pixel.
1749 gfx::Rect
expanded_layer_rect(layer_rect
);
1750 expanded_layer_rect
.set_height(32);
1751 EXPECT_EQ(expanded_layer_rect
,
1752 layer
->tracking_layer_painter()->PaintedRect());