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/location.h"
11 #include "base/run_loop.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "cc/resources/bitmap_content_layer_updater.h"
15 #include "cc/resources/layer_painter.h"
16 #include "cc/resources/prioritized_resource_manager.h"
17 #include "cc/resources/resource_update_controller.h"
18 #include "cc/test/animation_test_common.h"
19 #include "cc/test/fake_layer_tree_host_client.h"
20 #include "cc/test/fake_layer_tree_host_impl.h"
21 #include "cc/test/fake_output_surface.h"
22 #include "cc/test/fake_output_surface_client.h"
23 #include "cc/test/fake_proxy.h"
24 #include "cc/test/geometry_test_utils.h"
25 #include "cc/test/test_shared_bitmap_manager.h"
26 #include "cc/test/tiled_layer_test_common.h"
27 #include "cc/trees/occlusion_tracker.h"
28 #include "cc/trees/single_thread_proxy.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "ui/gfx/geometry/rect_conversions.h"
31 #include "ui/gfx/transform.h"
36 class TestOcclusionTracker
: public OcclusionTracker
<Layer
> {
38 TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000)) {
39 stack_
.push_back(StackObject());
42 void SetRenderTarget(Layer
* render_target
) {
43 stack_
.back().target
= render_target
;
46 void SetOcclusion(const SimpleEnclosedRegion
& occlusion
) {
47 stack_
.back().occlusion_from_inside_target
= occlusion
;
51 class SynchronousOutputSurfaceClient
: public FakeLayerTreeHostClient
{
53 SynchronousOutputSurfaceClient()
54 : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D
) {}
56 bool EnsureOutputSurfaceCreated() {
57 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
58 FROM_HERE
, run_loop_
.QuitClosure(), base::TimeDelta::FromSeconds(5));
60 return output_surface_created_
;
63 void DidInitializeOutputSurface() override
{
64 FakeLayerTreeHostClient::DidInitializeOutputSurface();
65 output_surface_created_
= true;
69 void DidFailToInitializeOutputSurface() override
{
70 FakeLayerTreeHostClient::DidFailToInitializeOutputSurface();
71 output_surface_created_
= false;
76 bool output_surface_created_
;
77 base::RunLoop run_loop_
;
80 class TiledLayerTest
: public testing::Test
{
84 output_surface_(FakeOutputSurface::Create3d()),
85 queue_(make_scoped_ptr(new ResourceUpdateQueue
)),
86 impl_thread_("ImplThread"),
88 settings_
.max_partial_texture_updates
= std::numeric_limits
<size_t>::max();
89 settings_
.layer_transforms_should_scale_layer_contents
= true;
90 settings_
.verify_property_trees
= true;
91 settings_
.impl_side_painting
= false;
94 void SetUp() override
{
96 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
97 layer_tree_host_
= LayerTreeHost::CreateThreaded(
98 &synchonous_output_surface_client_
, shared_bitmap_manager_
.get(),
99 nullptr, nullptr, settings_
, base::ThreadTaskRunnerHandle::Get(),
100 impl_thread_
.task_runner(), nullptr);
101 synchonous_output_surface_client_
.SetLayerTreeHost(layer_tree_host_
.get());
102 proxy_
= layer_tree_host_
->proxy();
103 resource_manager_
= PrioritizedResourceManager::Create(proxy_
);
104 layer_tree_host_
->SetLayerTreeHostClientReady();
105 CHECK(synchonous_output_surface_client_
.EnsureOutputSurfaceCreated());
107 layer_tree_host_
->SetRootLayer(Layer::Create());
109 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
111 DebugScopedSetImplThreadAndMainThreadBlocked
112 impl_thread_and_main_thread_blocked(proxy_
);
113 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
114 shared_bitmap_manager_
.get(),
120 host_impl_
= make_scoped_ptr(new FakeLayerTreeHostImpl(
121 proxy_
, shared_bitmap_manager_
.get(), nullptr));
124 ~TiledLayerTest() override
{
125 ResourceManagerClearAllMemory(resource_manager_
.get(),
126 resource_provider_
.get());
128 DebugScopedSetImplThreadAndMainThreadBlocked
129 impl_thread_and_main_thread_blocked(proxy_
);
130 resource_provider_
= nullptr;
131 host_impl_
= nullptr;
134 void ResourceManagerClearAllMemory(
135 PrioritizedResourceManager
* resource_manager
,
136 ResourceProvider
* resource_provider
) {
138 DebugScopedSetImplThreadAndMainThreadBlocked
139 impl_thread_and_main_thread_blocked(proxy_
);
140 resource_manager
->ClearAllMemory(resource_provider
);
141 resource_manager
->ReduceMemory(resource_provider
);
143 resource_manager
->UnlinkAndClearEvictedBackings();
146 void UpdateTextures() {
147 DebugScopedSetImplThreadAndMainThreadBlocked
148 impl_thread_and_main_thread_blocked(proxy_
);
150 scoped_ptr
<ResourceUpdateController
> update_controller
=
151 ResourceUpdateController::Create(nullptr,
152 proxy_
->ImplThreadTaskRunner(),
154 resource_provider_
.get());
155 update_controller
->Finalize();
156 queue_
= make_scoped_ptr(new ResourceUpdateQueue
);
159 void LayerPushPropertiesTo(FakeTiledLayer
* layer
,
160 FakeTiledLayerImpl
* layer_impl
) {
161 DebugScopedSetImplThreadAndMainThreadBlocked
162 impl_thread_and_main_thread_blocked(proxy_
);
163 layer
->PushPropertiesTo(layer_impl
);
164 layer
->ResetNumDependentsNeedPushProperties();
167 void LayerUpdate(FakeTiledLayer
* layer
, TestOcclusionTracker
* occluded
) {
168 DebugScopedSetMainThread
main_thread(proxy_
);
169 layer
->Update(queue_
.get(), occluded
);
172 void CalcDrawProps(RenderSurfaceLayerList
* render_surface_layer_list
) {
174 occlusion_
->SetRenderTarget(layer_tree_host_
->root_layer());
176 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
177 layer_tree_host_
->root_layer(),
178 layer_tree_host_
->device_viewport_size(),
179 render_surface_layer_list
);
180 inputs
.device_scale_factor
= layer_tree_host_
->device_scale_factor();
181 inputs
.max_texture_size
=
182 layer_tree_host_
->GetRendererCapabilities().max_texture_size
;
183 inputs
.can_adjust_raster_scales
= true;
184 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
187 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
188 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
) {
189 scoped_refptr
<FakeTiledLayer
> layer2
;
190 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
;
191 return UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
194 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
195 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
,
196 const scoped_refptr
<FakeTiledLayer
>& layer2
,
197 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl2
) {
199 resource_manager_
->ClearPriorities();
201 layer1
->SetTexturePriorities(priority_calculator_
);
203 layer2
->SetTexturePriorities(priority_calculator_
);
204 resource_manager_
->PrioritizeTextures();
206 // Save paint properties
208 layer1
->SavePaintProperties();
210 layer2
->SavePaintProperties();
214 layer1
->Update(queue_
.get(), occlusion_
);
216 layer2
->Update(queue_
.get(), occlusion_
);
218 bool needs_update
= false;
220 needs_update
|= layer1
->NeedsIdlePaint();
222 needs_update
|= layer2
->NeedsIdlePaint();
224 // Update textures and push.
227 LayerPushPropertiesTo(layer1
.get(), layer_impl1
.get());
229 LayerPushPropertiesTo(layer2
.get(), layer_impl2
.get());
236 LayerTreeSettings settings_
;
237 FakeOutputSurfaceClient output_surface_client_
;
238 scoped_ptr
<OutputSurface
> output_surface_
;
239 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
240 scoped_ptr
<ResourceProvider
> resource_provider_
;
241 scoped_ptr
<ResourceUpdateQueue
> queue_
;
242 PriorityCalculator priority_calculator_
;
243 base::Thread impl_thread_
;
244 SynchronousOutputSurfaceClient synchonous_output_surface_client_
;
245 scoped_ptr
<LayerTreeHost
> layer_tree_host_
;
246 scoped_ptr
<FakeLayerTreeHostImpl
> host_impl_
;
247 scoped_ptr
<PrioritizedResourceManager
> resource_manager_
;
248 TestOcclusionTracker
* occlusion_
;
251 TEST_F(TiledLayerTest
, PushDirtyTiles
) {
252 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
254 scoped_refptr
<FakeTiledLayer
> layer
=
255 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
256 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
257 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
258 RenderSurfaceLayerList render_surface_layer_list
;
260 layer_tree_host_
->root_layer()->AddChild(layer
);
262 // The tile size is 100x100, so this invalidates and then paints two tiles.
263 layer
->SetBounds(gfx::Size(100, 200));
264 CalcDrawProps(&render_surface_layer_list
);
265 UpdateAndPush(layer
, layer_impl
);
267 // We should have both tiles on the impl side.
268 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
269 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
271 // Invalidates both tiles, but then only update one of them.
272 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
273 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
274 UpdateAndPush(layer
, layer_impl
);
276 // We should only have the first tile since the other tile was invalidated but
278 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
279 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
282 TEST_F(TiledLayerTest
, Scale
) {
283 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
285 layer_tree_host_
->SetDeviceScaleFactor(1.5);
287 scoped_refptr
<FakeTiledLayer
> layer
=
288 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
289 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
290 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
291 RenderSurfaceLayerList render_surface_layer_list
;
293 layer_tree_host_
->root_layer()->AddChild(layer
);
295 layer
->SetBounds(gfx::Size(100, 200));
296 CalcDrawProps(&render_surface_layer_list
);
298 // Change the width so that it doesn't divide cleanly by the scale.
299 layer
->SetBounds(gfx::Size(101, 200));
300 UpdateAndPush(layer
, layer_impl
);
302 EXPECT_EQ(1.5, layer
->fake_layer_updater()->last_contents_width_scale());
305 TEST_F(TiledLayerTest
, PushOccludedDirtyTiles
) {
306 scoped_refptr
<FakeTiledLayer
> layer
=
307 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
308 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
309 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
310 TestOcclusionTracker occluded
;
311 occlusion_
= &occluded
;
312 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
314 layer_tree_host_
->root_layer()->AddChild(layer
);
317 RenderSurfaceLayerList render_surface_layer_list
;
319 // The tile size is 100x100, so this invalidates and then paints two tiles.
320 layer
->SetBounds(gfx::Size(100, 200));
321 CalcDrawProps(&render_surface_layer_list
);
322 UpdateAndPush(layer
, layer_impl
);
324 // We should have both tiles on the impl side.
325 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
326 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
330 RenderSurfaceLayerList render_surface_layer_list
;
332 // Invalidates part of the top tile...
333 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
334 // ....but the area is occluded.
335 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 50, 50)));
336 CalcDrawProps(&render_surface_layer_list
);
337 UpdateAndPush(layer
, layer_impl
);
339 // We should still have both tiles, as part of the top tile is still
341 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
342 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
346 TEST_F(TiledLayerTest
, PushDeletedTiles
) {
347 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
349 scoped_refptr
<FakeTiledLayer
> layer
=
350 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
351 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
352 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
353 RenderSurfaceLayerList render_surface_layer_list
;
355 layer_tree_host_
->root_layer()->AddChild(layer
);
357 // The tile size is 100x100, so this invalidates and then paints two tiles.
358 layer
->SetBounds(gfx::Size(100, 200));
359 CalcDrawProps(&render_surface_layer_list
);
360 UpdateAndPush(layer
, layer_impl
);
362 // We should have both tiles on the impl side.
363 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
364 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
366 resource_manager_
->ClearPriorities();
367 ResourceManagerClearAllMemory(resource_manager_
.get(),
368 resource_provider_
.get());
369 resource_manager_
->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
371 // This should drop the tiles on the impl thread.
372 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
374 // We should now have no textures on the impl thread.
375 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
376 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
378 // This should recreate and update one of the deleted textures.
379 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
380 UpdateAndPush(layer
, layer_impl
);
382 // We should have one tiles on the impl side.
383 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
384 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
387 TEST_F(TiledLayerTest
, PushIdlePaintTiles
) {
388 scoped_refptr
<FakeTiledLayer
> layer
=
389 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
390 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
391 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
392 RenderSurfaceLayerList render_surface_layer_list
;
394 layer_tree_host_
->root_layer()->AddChild(layer
);
396 // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
397 // center. This paints 1 visible of the 25 invalid tiles.
398 layer
->SetBounds(gfx::Size(500, 500));
399 CalcDrawProps(&render_surface_layer_list
);
400 layer
->draw_properties().visible_content_rect
= gfx::Rect(200, 200, 100, 100);
401 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
402 // We should need idle-painting for surrounding tiles.
403 EXPECT_TRUE(needs_update
);
405 // We should have one tile on the impl side.
406 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(2, 2));
408 // For the next four updates, we should detect we still need idle painting.
409 for (int i
= 0; i
< 4; i
++) {
410 needs_update
= UpdateAndPush(layer
, layer_impl
);
411 EXPECT_TRUE(needs_update
);
414 // We should always finish painting eventually.
415 for (int i
= 0; i
< 20; i
++)
416 needs_update
= UpdateAndPush(layer
, layer_impl
);
418 // We should have pre-painted all of the surrounding tiles.
419 for (int i
= 0; i
< 5; i
++) {
420 for (int j
= 0; j
< 5; j
++)
421 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
424 EXPECT_FALSE(needs_update
);
427 TEST_F(TiledLayerTest
, PredictivePainting
) {
428 scoped_refptr
<FakeTiledLayer
> layer
=
429 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
430 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
431 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
433 layer_tree_host_
->root_layer()->AddChild(layer
);
435 // Prepainting should occur in the scroll direction first, and the
436 // visible rect should be extruded only along the dominant axis.
437 gfx::Vector2d directions
[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
438 gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
439 gfx::Vector2d(10, 20),
440 gfx::Vector2d(-20, 10) };
441 // We should push all tiles that touch the extruded visible rect.
442 gfx::Rect pushed_visible_tiles
[6] = {
443 gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
444 gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
446 // The first pre-paint should also paint first in the scroll
447 // direction so we should find one additional tile in the scroll direction.
448 gfx::Rect pushed_prepaint_tiles
[6] = {
449 gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
450 gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
452 for (int k
= 0; k
< 6; k
++) {
453 // The tile size is 100x100. Setup 5x5 tiles with one visible tile
455 gfx::Size bounds
= gfx::Size(500, 500);
456 gfx::Rect visible_rect
= gfx::Rect(200, 200, 100, 100);
457 gfx::Rect previous_visible_rect
=
458 gfx::Rect(visible_rect
.origin() + directions
[k
], visible_rect
.size());
459 gfx::Rect next_visible_rect
=
460 gfx::Rect(visible_rect
.origin() - directions
[k
], visible_rect
.size());
462 // Setup. Use the previous_visible_rect to setup the prediction for next
464 layer
->SetBounds(bounds
);
466 RenderSurfaceLayerList render_surface_layer_list
;
467 CalcDrawProps(&render_surface_layer_list
);
468 layer
->draw_properties().visible_content_rect
= previous_visible_rect
;
469 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
471 // Invalidate and move the visible_rect in the scroll direction.
472 // Check that the correct tiles have been painted in the visible pass.
473 layer
->SetNeedsDisplay();
474 layer
->draw_properties().visible_content_rect
= visible_rect
;
475 needs_update
= UpdateAndPush(layer
, layer_impl
);
476 for (int i
= 0; i
< 5; i
++) {
477 for (int j
= 0; j
< 5; j
++)
478 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
479 pushed_visible_tiles
[k
].Contains(i
, j
));
482 // Move the transform in the same direction without invalidating.
483 // Check that non-visible pre-painting occured in the correct direction.
484 // Ignore diagonal scrolls here (k > 3) as these have new visible content
487 layer
->draw_properties().visible_content_rect
= next_visible_rect
;
488 needs_update
= UpdateAndPush(layer
, layer_impl
);
489 for (int i
= 0; i
< 5; i
++) {
490 for (int j
= 0; j
< 5; j
++)
491 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
492 pushed_prepaint_tiles
[k
].Contains(i
, j
));
496 // We should always finish painting eventually.
497 for (int i
= 0; i
< 20; i
++)
498 needs_update
= UpdateAndPush(layer
, layer_impl
);
499 EXPECT_FALSE(needs_update
);
503 TEST_F(TiledLayerTest
, PushTilesAfterIdlePaintFailed
) {
504 // Start with 2mb of memory, but the test is going to try to use just more
505 // than 1mb, so we reduce to 1mb later.
506 resource_manager_
->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
507 scoped_refptr
<FakeTiledLayer
> layer1
=
508 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
509 scoped_ptr
<FakeTiledLayerImpl
> layer_impl1
=
510 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
511 scoped_refptr
<FakeTiledLayer
> layer2
=
512 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
513 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
=
514 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
515 RenderSurfaceLayerList render_surface_layer_list
;
517 layer_tree_host_
->root_layer()->AddChild(layer1
);
518 layer_tree_host_
->root_layer()->AddChild(layer2
);
520 // For this test we have two layers. layer1 exhausts most texture memory,
521 // leaving room for 2 more tiles from layer2, but not all three tiles. First
522 // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
523 // we will fail on the third tile of layer2, and this should not leave the
524 // second tile in a bad state.
526 // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
527 // for 2 tiles only in the other layer.
528 gfx::Rect
layer1_rect(0, 0, 100, 2400);
530 // This requires 4*30000 bytes of memory.
531 gfx::Rect
layer2_rect(0, 0, 100, 300);
533 // Paint a single tile in layer2 so that it will idle paint.
534 layer1
->SetBounds(layer1_rect
.size());
535 layer2
->SetBounds(layer2_rect
.size());
536 CalcDrawProps(&render_surface_layer_list
);
537 layer1
->draw_properties().visible_content_rect
= layer1_rect
;
538 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
539 bool needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
540 // We should need idle-painting for both remaining tiles in layer2.
541 EXPECT_TRUE(needs_update
);
543 // Reduce our memory limits to 1mb.
544 resource_manager_
->SetMaxMemoryLimitBytes(1024 * 1024);
546 // Now idle paint layer2. We are going to run out of memory though!
547 // Oh well, commit the frame and push.
548 for (int i
= 0; i
< 4; i
++) {
549 needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
552 // Sanity check, we should have textures for the big layer.
553 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 0));
554 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 23));
556 // We should only have the first two tiles from layer2 since
557 // it failed to idle update the last tile.
558 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
559 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
560 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
561 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
563 EXPECT_FALSE(needs_update
);
564 EXPECT_FALSE(layer_impl2
->HasResourceIdForTileAt(0, 2));
567 TEST_F(TiledLayerTest
, PushIdlePaintedOccludedTiles
) {
568 scoped_refptr
<FakeTiledLayer
> layer
=
569 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
570 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
571 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
572 RenderSurfaceLayerList render_surface_layer_list
;
573 TestOcclusionTracker occluded
;
574 occlusion_
= &occluded
;
576 layer_tree_host_
->root_layer()->AddChild(layer
);
578 // The tile size is 100x100, so this invalidates one occluded tile, culls it
579 // during paint, but prepaints it.
580 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 100, 100)));
582 layer
->SetBounds(gfx::Size(100, 100));
583 CalcDrawProps(&render_surface_layer_list
);
584 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
585 UpdateAndPush(layer
, layer_impl
);
587 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
590 TEST_F(TiledLayerTest
, PushTilesMarkedDirtyDuringPaint
) {
591 scoped_refptr
<FakeTiledLayer
> layer
=
592 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
593 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
594 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
595 RenderSurfaceLayerList render_surface_layer_list
;
597 layer_tree_host_
->root_layer()->AddChild(layer
);
599 // The tile size is 100x100, so this invalidates and then paints two tiles.
600 // However, during the paint, we invalidate one of the tiles. This should
601 // not prevent the tile from being pushed.
602 layer
->fake_layer_updater()->SetRectToInvalidate(
603 gfx::Rect(0, 50, 100, 50), layer
.get());
604 layer
->SetBounds(gfx::Size(100, 200));
605 CalcDrawProps(&render_surface_layer_list
);
606 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
607 UpdateAndPush(layer
, layer_impl
);
609 // We should have both tiles on the impl side.
610 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
611 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
614 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer
) {
615 scoped_refptr
<FakeTiledLayer
> layer1
=
616 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
617 scoped_refptr
<FakeTiledLayer
> layer2
=
618 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
619 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
620 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
621 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
622 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
623 RenderSurfaceLayerList render_surface_layer_list
;
625 layer_tree_host_
->root_layer()->AddChild(layer1
);
626 layer_tree_host_
->root_layer()->AddChild(layer2
);
628 // Invalidate a tile on layer1, during update of layer 2.
629 layer2
->fake_layer_updater()->SetRectToInvalidate(
630 gfx::Rect(0, 50, 100, 50), layer1
.get());
631 layer1
->SetBounds(gfx::Size(100, 200));
632 layer2
->SetBounds(gfx::Size(100, 200));
633 CalcDrawProps(&render_surface_layer_list
);
634 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
635 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
636 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
638 // We should have both tiles on the impl side for all layers.
639 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
640 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
641 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
642 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
645 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
) {
646 scoped_refptr
<FakeTiledLayer
> layer1
=
647 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
648 scoped_refptr
<FakeTiledLayer
> layer2
=
649 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
650 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
651 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
652 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
653 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
654 RenderSurfaceLayerList render_surface_layer_list
;
656 layer_tree_host_
->root_layer()->AddChild(layer1
);
657 layer_tree_host_
->root_layer()->AddChild(layer2
);
659 layer1
->fake_layer_updater()->SetRectToInvalidate(
660 gfx::Rect(0, 50, 100, 50), layer2
.get());
661 layer1
->SetBounds(gfx::Size(100, 200));
662 layer2
->SetBounds(gfx::Size(100, 200));
663 CalcDrawProps(&render_surface_layer_list
);
664 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
665 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
666 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
668 // We should have both tiles on the impl side for all layers.
669 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
670 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
671 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
672 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
675 TEST_F(TiledLayerTest
, PaintSmallAnimatedLayersImmediately
) {
676 // Create a LayerTreeHost that has the right viewportsize,
677 // so the layer is considered small enough.
678 bool run_out_of_memory
[2] = { false, true };
679 for (int i
= 0; i
< 2; i
++) {
680 // Create a layer with 5x5 tiles, with 4x4 size viewport.
681 int viewport_width
= 4 * FakeTiledLayer::tile_size().width();
682 int viewport_height
= 4 * FakeTiledLayer::tile_size().width();
683 int layer_width
= 5 * FakeTiledLayer::tile_size().width();
684 int layer_height
= 5 * FakeTiledLayer::tile_size().height();
685 int memory_for_layer
= layer_width
* layer_height
* 4;
686 layer_tree_host_
->SetViewportSize(
687 gfx::Size(viewport_width
, viewport_height
));
689 // Use 10x5 tiles to run out of memory.
690 if (run_out_of_memory
[i
])
693 resource_manager_
->SetMaxMemoryLimitBytes(memory_for_layer
);
695 scoped_refptr
<FakeTiledLayer
> layer
=
696 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
697 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
698 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
699 RenderSurfaceLayerList render_surface_layer_list
;
701 layer_tree_host_
->root_layer()->AddChild(layer
);
703 // Full size layer with half being visible.
704 layer
->SetBounds(gfx::Size(layer_width
, layer_height
));
705 gfx::Rect
visible_rect(0, 0, layer_width
/ 2, layer_height
);
706 CalcDrawProps(&render_surface_layer_list
);
708 // Pretend the layer is animating.
709 layer
->draw_properties().target_space_transform_is_animating
= true;
710 layer
->draw_properties().visible_content_rect
= visible_rect
;
711 layer
->SetLayerTreeHost(layer_tree_host_
.get());
713 // The layer should paint its entire contents on the first paint
714 // if it is close to the viewport size and has the available memory.
715 layer
->SetTexturePriorities(priority_calculator_
);
716 resource_manager_
->PrioritizeTextures();
717 layer
->SavePaintProperties();
718 layer
->Update(queue_
.get(), nullptr);
720 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
722 // We should have all the tiles for the small animated layer.
723 // We should still have the visible tiles when we didn't
724 // have enough memory for all the tiles.
725 if (!run_out_of_memory
[i
]) {
726 for (int i
= 0; i
< 5; ++i
) {
727 for (int j
= 0; j
< 5; ++j
)
728 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
731 for (int i
= 0; i
< 10; ++i
) {
732 for (int j
= 0; j
< 5; ++j
)
733 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
), i
< 5);
737 layer
->RemoveFromParent();
741 TEST_F(TiledLayerTest
, IdlePaintOutOfMemory
) {
742 scoped_refptr
<FakeTiledLayer
> layer
=
743 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
744 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
745 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
746 RenderSurfaceLayerList render_surface_layer_list
;
748 layer_tree_host_
->root_layer()->AddChild(layer
);
750 // We have enough memory for only the visible rect, so we will run out of
751 // memory in first idle paint.
752 int memory_limit
= 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
753 resource_manager_
->SetMaxMemoryLimitBytes(memory_limit
);
755 // The tile size is 100x100, so this invalidates and then paints two tiles.
756 bool needs_update
= false;
757 layer
->SetBounds(gfx::Size(300, 300));
758 CalcDrawProps(&render_surface_layer_list
);
759 layer
->draw_properties().visible_content_rect
= gfx::Rect(100, 100, 100, 100);
760 for (int i
= 0; i
< 2; i
++)
761 needs_update
= UpdateAndPush(layer
, layer_impl
);
763 // Idle-painting should see no more priority tiles for painting.
764 EXPECT_FALSE(needs_update
);
766 // We should have one tile on the impl side.
767 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
770 TEST_F(TiledLayerTest
, IdlePaintZeroSizedLayer
) {
771 scoped_refptr
<FakeTiledLayer
> layer
=
772 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
773 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
774 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
776 layer_tree_host_
->root_layer()->AddChild(layer
);
778 bool animating
[2] = { false, true };
779 for (int i
= 0; i
< 2; i
++) {
780 // Pretend the layer is animating.
781 layer
->draw_properties().target_space_transform_is_animating
= animating
[i
];
783 // The layer's bounds are empty.
784 // Empty layers don't paint or idle-paint.
785 layer
->SetBounds(gfx::Size());
787 RenderSurfaceLayerList render_surface_layer_list
;
788 CalcDrawProps(&render_surface_layer_list
);
789 layer
->draw_properties().visible_content_rect
= gfx::Rect();
790 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
792 // Empty layers don't have tiles.
793 EXPECT_EQ(0u, layer
->NumPaintedTiles());
795 // Empty layers don't need prepaint.
796 EXPECT_FALSE(needs_update
);
798 // Empty layers don't have tiles.
799 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
803 TEST_F(TiledLayerTest
, IdlePaintNonVisibleLayers
) {
804 scoped_refptr
<FakeTiledLayer
> layer
=
805 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
806 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
807 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
809 // Alternate between not visible and visible.
810 gfx::Rect
v(0, 0, 100, 100);
811 gfx::Rect
nv(0, 0, 0, 0);
812 gfx::Rect visible_rect
[10] = { nv
, nv
, v
, v
, nv
, nv
, v
, v
, nv
, nv
};
813 bool invalidate
[10] = { true, true, true, true, true, true, true, true, false,
816 // We should not have any tiles except for when the layer was visible
817 // or after the layer was visible and we didn't invalidate.
818 bool have_tile
[10] = { false, false, true, true, false, false, true, true,
821 layer_tree_host_
->root_layer()->AddChild(layer
);
823 for (int i
= 0; i
< 10; i
++) {
824 layer
->SetBounds(gfx::Size(100, 100));
826 RenderSurfaceLayerList render_surface_layer_list
;
827 CalcDrawProps(&render_surface_layer_list
);
828 layer
->draw_properties().visible_content_rect
= visible_rect
[i
];
831 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
832 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
834 // We should never signal idle paint, as we painted the entire layer
835 // or the layer was not visible.
836 EXPECT_FALSE(needs_update
);
837 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(0, 0), have_tile
[i
]);
841 TEST_F(TiledLayerTest
, InvalidateFromPrepare
) {
842 scoped_refptr
<FakeTiledLayer
> layer
=
843 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
844 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
845 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
846 RenderSurfaceLayerList render_surface_layer_list
;
848 layer_tree_host_
->root_layer()->AddChild(layer
);
850 // The tile size is 100x100, so this invalidates and then paints two tiles.
851 layer
->SetBounds(gfx::Size(100, 200));
852 CalcDrawProps(&render_surface_layer_list
);
853 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
854 UpdateAndPush(layer
, layer_impl
);
856 // We should have both tiles on the impl side.
857 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
858 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
860 layer
->fake_layer_updater()->ClearPrepareCount();
861 // Invoke update again. As the layer is valid update shouldn't be invoked on
863 UpdateAndPush(layer
, layer_impl
);
864 EXPECT_EQ(0, layer
->fake_layer_updater()->prepare_count());
866 // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
868 layer
->fake_layer_updater()->SetRectToInvalidate(
869 gfx::Rect(25, 25, 50, 50), layer
.get());
870 layer
->fake_layer_updater()->ClearPrepareCount();
871 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
872 UpdateAndPush(layer
, layer_impl
);
873 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
874 layer
->fake_layer_updater()->ClearPrepareCount();
876 // The layer should still be invalid as update invoked invalidate.
877 UpdateAndPush(layer
, layer_impl
); // visible
878 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
881 TEST_F(TiledLayerTest
, VerifyUpdateRectWhenContentBoundsAreScaled
) {
882 // The update rect (that indicates what was actually painted) should be in
883 // layer space, not the content space.
884 scoped_refptr
<FakeTiledLayerWithScaledBounds
> layer
= make_scoped_refptr(
885 new FakeTiledLayerWithScaledBounds(resource_manager_
.get()));
887 layer_tree_host_
->root_layer()->AddChild(layer
);
889 gfx::Rect
layer_bounds(0, 0, 300, 200);
890 gfx::Rect
content_bounds(0, 0, 150, 250);
892 layer
->SetBounds(layer_bounds
.size());
893 layer
->SetContentBounds(content_bounds
.size());
894 layer
->draw_properties().visible_content_rect
= content_bounds
;
895 layer
->draw_properties().contents_scale_x
= .5f
;
896 layer
->draw_properties().contents_scale_y
= 1.25f
;
898 // On first update, the update_rect includes all tiles, even beyond the
899 // boundaries of the layer.
900 // However, it should still be in layer space, not content space.
901 layer
->InvalidateContentRect(content_bounds
);
903 layer
->SetTexturePriorities(priority_calculator_
);
904 resource_manager_
->PrioritizeTextures();
905 layer
->SavePaintProperties();
906 layer
->Update(queue_
.get(), nullptr);
908 // Update rect is 200x300 (tile size of 100x100). Scaled this gives 400x240.
909 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 400, 240), layer
->update_rect());
912 // After the tiles are updated once, another invalidate only needs to update
913 // the bounds of the layer.
914 layer
->SetTexturePriorities(priority_calculator_
);
915 resource_manager_
->PrioritizeTextures();
916 layer
->InvalidateContentRect(content_bounds
);
917 layer
->SavePaintProperties();
918 layer
->Update(queue_
.get(), nullptr);
919 EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds
), layer
->update_rect());
922 // Partial re-paint should also be represented by the update rect in layer
923 // space, not content space.
924 gfx::Rect
partial_damage(30, 100, 10, 10);
925 layer
->InvalidateContentRect(partial_damage
);
926 layer
->SetTexturePriorities(priority_calculator_
);
927 resource_manager_
->PrioritizeTextures();
928 layer
->SavePaintProperties();
929 layer
->Update(queue_
.get(), nullptr);
930 EXPECT_FLOAT_RECT_EQ(gfx::RectF(60, 80, 20, 8), layer
->update_rect());
933 TEST_F(TiledLayerTest
, VerifyInvalidationWhenContentsScaleChanges
) {
934 scoped_refptr
<FakeTiledLayer
> layer
=
935 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
936 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
937 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
938 RenderSurfaceLayerList render_surface_layer_list
;
940 layer_tree_host_
->root_layer()->AddChild(layer
);
942 // Create a layer with one tile.
943 layer
->SetBounds(gfx::Size(100, 100));
944 CalcDrawProps(&render_surface_layer_list
);
945 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
946 layer
->Update(queue_
.get(), nullptr);
948 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
949 layer
->last_needs_display_rect());
951 // Push the tiles to the impl side and check that there is exactly one.
952 layer
->SetTexturePriorities(priority_calculator_
);
953 resource_manager_
->PrioritizeTextures();
954 layer
->SavePaintProperties();
955 layer
->Update(queue_
.get(), nullptr);
957 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
958 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
959 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
960 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
961 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
963 layer
->SetNeedsDisplayRect(gfx::Rect());
964 EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer
->last_needs_display_rect());
966 // Change the contents scale.
967 layer
->UpdateContentsScale(2.f
);
968 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 200, 200);
970 // The impl side should get 2x2 tiles now.
971 layer
->SetTexturePriorities(priority_calculator_
);
972 resource_manager_
->PrioritizeTextures();
973 layer
->SavePaintProperties();
974 layer
->Update(queue_
.get(), nullptr);
976 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
977 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
978 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
979 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 0));
980 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
982 // Verify that changing the contents scale caused invalidation, and
983 // that the layer-space rectangle requiring painting is not scaled.
984 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
985 layer
->last_needs_display_rect());
987 // Invalidate the entire layer again, but do not paint. All tiles should be
988 // gone now from the impl side.
989 layer
->SetNeedsDisplay();
990 layer
->SetTexturePriorities(priority_calculator_
);
991 resource_manager_
->PrioritizeTextures();
993 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
994 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
995 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
996 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
997 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
1000 TEST_F(TiledLayerTest
, SkipsDrawGetsReset
) {
1001 // Create two 300 x 300 tiled layers.
1002 gfx::Size
content_bounds(300, 300);
1003 gfx::Rect
content_rect(content_bounds
);
1005 // We have enough memory for only one of the two layers.
1006 int memory_limit
= 4 * 300 * 300; // 4 bytes per pixel.
1008 scoped_refptr
<FakeTiledLayer
> root_layer
= make_scoped_refptr(
1009 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1010 scoped_refptr
<FakeTiledLayer
> child_layer
= make_scoped_refptr(
1011 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1012 root_layer
->AddChild(child_layer
);
1014 root_layer
->SetBounds(content_bounds
);
1015 root_layer
->draw_properties().visible_content_rect
= content_rect
;
1016 root_layer
->SetPosition(gfx::PointF(0, 0));
1017 child_layer
->SetBounds(content_bounds
);
1018 child_layer
->draw_properties().visible_content_rect
= content_rect
;
1019 child_layer
->SetPosition(gfx::PointF(0, 0));
1020 root_layer
->InvalidateContentRect(content_rect
);
1021 child_layer
->InvalidateContentRect(content_rect
);
1023 layer_tree_host_
->SetRootLayer(root_layer
);
1024 layer_tree_host_
->SetViewportSize(gfx::Size(300, 300));
1025 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1028 layer_tree_host_
->UpdateLayers(queue_
.get());
1030 // We'll skip the root layer.
1031 EXPECT_TRUE(root_layer
->SkipsDraw());
1032 EXPECT_FALSE(child_layer
->SkipsDraw());
1034 layer_tree_host_
->CommitComplete();
1036 // Remove the child layer.
1037 root_layer
->RemoveAllChildren();
1039 layer_tree_host_
->UpdateLayers(queue_
.get());
1040 EXPECT_FALSE(root_layer
->SkipsDraw());
1042 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1043 resource_provider_
.get());
1044 layer_tree_host_
->SetRootLayer(nullptr);
1047 TEST_F(TiledLayerTest
, ResizeToSmaller
) {
1048 scoped_refptr
<FakeTiledLayer
> layer
=
1049 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1051 layer_tree_host_
->root_layer()->AddChild(layer
);
1053 layer
->SetBounds(gfx::Size(700, 700));
1054 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1055 layer
->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
1057 layer
->SetTexturePriorities(priority_calculator_
);
1058 resource_manager_
->PrioritizeTextures();
1059 layer
->SavePaintProperties();
1060 layer
->Update(queue_
.get(), nullptr);
1062 layer
->SetBounds(gfx::Size(200, 200));
1063 layer
->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
1066 TEST_F(TiledLayerTest
, HugeLayerUpdateCrash
) {
1067 scoped_refptr
<FakeTiledLayer
> layer
=
1068 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1070 layer_tree_host_
->root_layer()->AddChild(layer
);
1073 layer
->SetBounds(gfx::Size(size
, size
));
1074 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1075 layer
->InvalidateContentRect(gfx::Rect(0, 0, size
, size
));
1077 // Ensure no crash for bounds where size * size would overflow an int.
1078 layer
->SetTexturePriorities(priority_calculator_
);
1079 resource_manager_
->PrioritizeTextures();
1080 layer
->SavePaintProperties();
1081 layer
->Update(queue_
.get(), nullptr);
1084 class TiledLayerPartialUpdateTest
: public TiledLayerTest
{
1086 TiledLayerPartialUpdateTest() { settings_
.max_partial_texture_updates
= 4; }
1089 TEST_F(TiledLayerPartialUpdateTest
, PartialUpdates
) {
1090 // Create one 300 x 200 tiled layer with 3 x 2 tiles.
1091 gfx::Size
content_bounds(300, 200);
1092 gfx::Rect
content_rect(content_bounds
);
1094 scoped_refptr
<FakeTiledLayer
> layer
= make_scoped_refptr(
1095 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1096 layer
->SetBounds(content_bounds
);
1097 layer
->SetPosition(gfx::PointF(0, 0));
1098 layer
->draw_properties().visible_content_rect
= content_rect
;
1099 layer
->InvalidateContentRect(content_rect
);
1101 layer_tree_host_
->SetRootLayer(layer
);
1102 layer_tree_host_
->SetViewportSize(gfx::Size(300, 200));
1104 // Full update of all 6 tiles.
1105 layer_tree_host_
->UpdateLayers(queue_
.get());
1107 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1108 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1109 EXPECT_EQ(6u, queue_
->FullUploadSize());
1110 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1112 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1113 EXPECT_FALSE(queue_
->HasMoreUpdates());
1114 layer
->fake_layer_updater()->ClearUpdateCount();
1115 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1117 layer_tree_host_
->CommitComplete();
1119 // Full update of 3 tiles and partial update of 3 tiles.
1120 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
1121 layer_tree_host_
->UpdateLayers(queue_
.get());
1123 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1124 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1125 EXPECT_EQ(3u, queue_
->FullUploadSize());
1126 EXPECT_EQ(3u, queue_
->PartialUploadSize());
1128 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1129 EXPECT_FALSE(queue_
->HasMoreUpdates());
1130 layer
->fake_layer_updater()->ClearUpdateCount();
1131 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1133 layer_tree_host_
->CommitComplete();
1135 // Partial update of 6 tiles.
1136 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1138 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1139 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1140 layer_tree_host_
->UpdateLayers(queue_
.get());
1141 EXPECT_EQ(2u, queue_
->FullUploadSize());
1142 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1144 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1145 EXPECT_FALSE(queue_
->HasMoreUpdates());
1146 layer
->fake_layer_updater()->ClearUpdateCount();
1147 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1149 layer_tree_host_
->CommitComplete();
1151 // Checkerboard all tiles.
1152 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
1154 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1155 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1156 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1158 layer_tree_host_
->CommitComplete();
1160 // Partial update of 6 checkerboard tiles.
1161 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1163 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1164 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1165 layer_tree_host_
->UpdateLayers(queue_
.get());
1166 EXPECT_EQ(6u, queue_
->FullUploadSize());
1167 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1169 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1170 EXPECT_FALSE(queue_
->HasMoreUpdates());
1171 layer
->fake_layer_updater()->ClearUpdateCount();
1172 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1174 layer_tree_host_
->CommitComplete();
1176 // Partial update of 4 tiles.
1177 layer
->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
1179 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1180 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1181 layer_tree_host_
->UpdateLayers(queue_
.get());
1182 EXPECT_EQ(0u, queue_
->FullUploadSize());
1183 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1185 EXPECT_EQ(4, layer
->fake_layer_updater()->update_count());
1186 EXPECT_FALSE(queue_
->HasMoreUpdates());
1187 layer
->fake_layer_updater()->ClearUpdateCount();
1188 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1190 layer_tree_host_
->CommitComplete();
1192 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1193 resource_provider_
.get());
1194 layer_tree_host_
->SetRootLayer(nullptr);
1197 TEST_F(TiledLayerTest
, TilesPaintedWithoutOcclusion
) {
1198 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1200 scoped_refptr
<FakeTiledLayer
> layer
=
1201 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1202 RenderSurfaceLayerList render_surface_layer_list
;
1204 layer_tree_host_
->root_layer()->AddChild(layer
);
1206 // The tile size is 100x100, so this invalidates and then paints two tiles.
1207 layer
->SetBounds(gfx::Size(100, 200));
1208 CalcDrawProps(&render_surface_layer_list
);
1210 layer
->SetTexturePriorities(priority_calculator_
);
1211 resource_manager_
->PrioritizeTextures();
1212 layer
->SavePaintProperties();
1213 layer
->Update(queue_
.get(), nullptr);
1214 EXPECT_EQ(2, layer
->fake_layer_updater()->update_count());
1217 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusion
) {
1218 scoped_refptr
<FakeTiledLayer
> layer
=
1219 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1220 RenderSurfaceLayerList render_surface_layer_list
;
1221 TestOcclusionTracker occluded
;
1222 occlusion_
= &occluded
;
1224 layer_tree_host_
->root_layer()->AddChild(layer
);
1226 // The tile size is 100x100.
1228 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1229 layer
->SetBounds(gfx::Size(600, 600));
1230 CalcDrawProps(&render_surface_layer_list
);
1232 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1233 layer
->draw_properties().drawable_content_rect
=
1234 gfx::Rect(layer
->content_bounds());
1235 layer
->draw_properties().visible_content_rect
=
1236 gfx::Rect(layer
->content_bounds());
1237 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1239 layer
->SetTexturePriorities(priority_calculator_
);
1240 resource_manager_
->PrioritizeTextures();
1241 layer
->SavePaintProperties();
1242 layer
->Update(queue_
.get(), &occluded
);
1243 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1245 layer
->fake_layer_updater()->ClearUpdateCount();
1246 layer
->SetTexturePriorities(priority_calculator_
);
1247 resource_manager_
->PrioritizeTextures();
1249 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 200, 300, 100)));
1250 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1251 layer
->SavePaintProperties();
1252 layer
->Update(queue_
.get(), &occluded
);
1253 EXPECT_EQ(36 - 2, layer
->fake_layer_updater()->update_count());
1255 layer
->fake_layer_updater()->ClearUpdateCount();
1256 layer
->SetTexturePriorities(priority_calculator_
);
1257 resource_manager_
->PrioritizeTextures();
1259 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 250, 300, 100)));
1260 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1261 layer
->SavePaintProperties();
1262 layer
->Update(queue_
.get(), &occluded
);
1263 EXPECT_EQ(36, layer
->fake_layer_updater()->update_count());
1266 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndVisiblityConstraints
) {
1267 scoped_refptr
<FakeTiledLayer
> layer
=
1268 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1269 RenderSurfaceLayerList render_surface_layer_list
;
1270 TestOcclusionTracker occluded
;
1271 occlusion_
= &occluded
;
1273 layer_tree_host_
->root_layer()->AddChild(layer
);
1275 // The tile size is 100x100.
1277 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1278 layer
->SetBounds(gfx::Size(600, 600));
1279 CalcDrawProps(&render_surface_layer_list
);
1281 // The partially occluded tiles (by the 150 occlusion height) are visible
1282 // beyond the occlusion, so not culled.
1283 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1284 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 360);
1285 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 360);
1286 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1288 layer
->SetTexturePriorities(priority_calculator_
);
1289 resource_manager_
->PrioritizeTextures();
1290 layer
->SavePaintProperties();
1291 layer
->Update(queue_
.get(), &occluded
);
1292 EXPECT_EQ(24 - 3, layer
->fake_layer_updater()->update_count());
1294 layer
->fake_layer_updater()->ClearUpdateCount();
1296 // Now the visible region stops at the edge of the occlusion so the partly
1297 // visible tiles become fully occluded.
1298 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1299 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 350);
1300 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 350);
1301 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1302 layer
->SetTexturePriorities(priority_calculator_
);
1303 resource_manager_
->PrioritizeTextures();
1304 layer
->SavePaintProperties();
1305 layer
->Update(queue_
.get(), &occluded
);
1306 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1308 layer
->fake_layer_updater()->ClearUpdateCount();
1310 // Now the visible region is even smaller than the occlusion, it should have
1312 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
1313 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 340);
1314 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 340);
1315 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1316 layer
->SetTexturePriorities(priority_calculator_
);
1317 resource_manager_
->PrioritizeTextures();
1318 layer
->SavePaintProperties();
1319 layer
->Update(queue_
.get(), &occluded
);
1320 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1323 TEST_F(TiledLayerTest
, TilesNotPaintedWithoutInvalidation
) {
1324 scoped_refptr
<FakeTiledLayer
> layer
=
1325 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1326 RenderSurfaceLayerList render_surface_layer_list
;
1327 TestOcclusionTracker occluded
;
1328 occlusion_
= &occluded
;
1330 layer_tree_host_
->root_layer()->AddChild(layer
);
1332 // The tile size is 100x100.
1334 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1335 layer
->SetBounds(gfx::Size(600, 600));
1336 CalcDrawProps(&render_surface_layer_list
);
1338 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1339 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 600);
1340 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 600);
1341 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1342 layer
->SetTexturePriorities(priority_calculator_
);
1343 resource_manager_
->PrioritizeTextures();
1344 layer
->SavePaintProperties();
1345 layer
->Update(queue_
.get(), &occluded
);
1346 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1349 layer
->fake_layer_updater()->ClearUpdateCount();
1350 layer
->SetTexturePriorities(priority_calculator_
);
1351 resource_manager_
->PrioritizeTextures();
1352 layer
->SavePaintProperties();
1354 // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
1356 layer
->Update(queue_
.get(), &occluded
);
1357 EXPECT_EQ(3, layer
->fake_layer_updater()->update_count());
1360 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndTransforms
) {
1361 scoped_refptr
<FakeTiledLayer
> layer
=
1362 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1363 RenderSurfaceLayerList render_surface_layer_list
;
1364 TestOcclusionTracker occluded
;
1365 occlusion_
= &occluded
;
1367 layer_tree_host_
->root_layer()->AddChild(layer
);
1369 // The tile size is 100x100.
1371 // This makes sure the painting works when the occluded region (in screen
1372 // space) is transformed differently than the layer.
1373 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1374 layer
->SetBounds(gfx::Size(600, 600));
1375 CalcDrawProps(&render_surface_layer_list
);
1376 gfx::Transform screen_transform
;
1377 screen_transform
.Scale(0.5, 0.5);
1378 layer
->draw_properties().screen_space_transform
= screen_transform
;
1379 layer
->draw_properties().target_space_transform
= screen_transform
;
1381 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 50)));
1382 layer
->draw_properties().drawable_content_rect
=
1383 gfx::Rect(layer
->content_bounds());
1384 layer
->draw_properties().visible_content_rect
=
1385 gfx::Rect(layer
->content_bounds());
1386 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1387 layer
->SetTexturePriorities(priority_calculator_
);
1388 resource_manager_
->PrioritizeTextures();
1389 layer
->SavePaintProperties();
1390 layer
->Update(queue_
.get(), &occluded
);
1391 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1394 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndScaling
) {
1395 scoped_refptr
<FakeTiledLayer
> layer
=
1396 new FakeTiledLayer(resource_manager_
.get());
1397 RenderSurfaceLayerList render_surface_layer_list
;
1398 TestOcclusionTracker occluded
;
1399 occlusion_
= &occluded
;
1401 scoped_refptr
<FakeTiledLayer
> scale_layer
=
1402 new FakeTiledLayer(resource_manager_
.get());
1403 gfx::Transform scale_transform
;
1404 scale_transform
.Scale(2.0, 2.0);
1405 scale_layer
->SetTransform(scale_transform
);
1407 layer_tree_host_
->root_layer()->AddChild(scale_layer
);
1409 // The tile size is 100x100.
1411 // This makes sure the painting works when the content space is scaled to
1412 // a different layer space.
1413 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1414 layer
->SetBounds(gfx::Size(300, 300));
1415 scale_layer
->AddChild(layer
);
1416 CalcDrawProps(&render_surface_layer_list
);
1417 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_x());
1418 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_y());
1419 EXPECT_EQ(gfx::Size(600, 600).ToString(),
1420 layer
->content_bounds().ToString());
1422 // No tiles are covered by the 300x50 occlusion.
1423 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 50)));
1424 layer
->draw_properties().drawable_content_rect
=
1425 gfx::Rect(layer
->bounds());
1426 layer
->draw_properties().visible_content_rect
=
1427 gfx::Rect(layer
->content_bounds());
1428 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1429 layer
->SetTexturePriorities(priority_calculator_
);
1430 resource_manager_
->PrioritizeTextures();
1431 layer
->SavePaintProperties();
1432 layer
->Update(queue_
.get(), &occluded
);
1433 int visible_tiles1
= 6 * 6;
1434 EXPECT_EQ(visible_tiles1
, layer
->fake_layer_updater()->update_count());
1436 layer
->fake_layer_updater()->ClearUpdateCount();
1438 // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1439 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
1440 layer
->draw_properties().drawable_content_rect
=
1441 gfx::Rect(layer
->bounds());
1442 layer
->draw_properties().visible_content_rect
=
1443 gfx::Rect(layer
->content_bounds());
1444 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1445 layer
->SetTexturePriorities(priority_calculator_
);
1446 resource_manager_
->PrioritizeTextures();
1447 layer
->SavePaintProperties();
1448 layer
->Update(queue_
.get(), &occluded
);
1449 int visible_tiles2
= 6 * 6 - 3;
1450 EXPECT_EQ(visible_tiles2
, layer
->fake_layer_updater()->update_count());
1452 layer
->fake_layer_updater()->ClearUpdateCount();
1454 // This makes sure content scaling and transforms work together.
1455 // When the tiles are scaled down by half, they are 50x50 each in the
1457 gfx::Transform screen_transform
;
1458 screen_transform
.Scale(0.5, 0.5);
1459 layer
->draw_properties().screen_space_transform
= screen_transform
;
1460 layer
->draw_properties().target_space_transform
= screen_transform
;
1462 // An occlusion of 150x100 will cover 3*2 = 6 tiles.
1463 occluded
.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 100)));
1465 gfx::Rect
layer_bounds_rect(layer
->bounds());
1466 layer
->draw_properties().drawable_content_rect
=
1467 gfx::ScaleToEnclosingRect(layer_bounds_rect
, 0.5f
);
1468 layer
->draw_properties().visible_content_rect
=
1469 gfx::Rect(layer
->content_bounds());
1470 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1471 layer
->SetTexturePriorities(priority_calculator_
);
1472 resource_manager_
->PrioritizeTextures();
1473 layer
->SavePaintProperties();
1474 layer
->Update(queue_
.get(), &occluded
);
1475 int visible_tiles3
= 6 * 6 - 6;
1476 EXPECT_EQ(visible_tiles3
, layer
->fake_layer_updater()->update_count());
1479 TEST_F(TiledLayerTest
, DontAllocateContentsWhenTargetSurfaceCantBeAllocated
) {
1480 // Tile size is 100x100.
1481 gfx::Rect
root_rect(0, 0, 300, 200);
1482 gfx::Rect
child_rect(0, 0, 300, 100);
1483 gfx::Rect
child2_rect(0, 100, 300, 100);
1485 scoped_refptr
<FakeTiledLayer
> root
= make_scoped_refptr(
1486 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1487 scoped_refptr
<Layer
> surface
= Layer::Create();
1488 scoped_refptr
<FakeTiledLayer
> child
= make_scoped_refptr(
1489 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1490 scoped_refptr
<FakeTiledLayer
> child2
= make_scoped_refptr(
1491 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1493 root
->SetBounds(root_rect
.size());
1494 root
->draw_properties().drawable_content_rect
= root_rect
;
1495 root
->draw_properties().visible_content_rect
= root_rect
;
1496 root
->AddChild(surface
);
1498 surface
->SetForceRenderSurface(true);
1499 surface
->SetOpacity(0.5);
1500 surface
->AddChild(child
);
1501 surface
->AddChild(child2
);
1503 child
->SetBounds(child_rect
.size());
1504 child
->SetPosition(child_rect
.origin());
1505 child
->draw_properties().visible_content_rect
= child_rect
;
1506 child
->draw_properties().drawable_content_rect
= root_rect
;
1508 child2
->SetBounds(child2_rect
.size());
1509 child2
->SetPosition(child2_rect
.origin());
1510 child2
->draw_properties().visible_content_rect
= child2_rect
;
1511 child2
->draw_properties().drawable_content_rect
= root_rect
;
1513 layer_tree_host_
->SetRootLayer(root
);
1514 layer_tree_host_
->SetViewportSize(root_rect
.size());
1516 // With a huge memory limit, all layers should update and push their textures.
1517 root
->InvalidateContentRect(root_rect
);
1518 child
->InvalidateContentRect(child_rect
);
1519 child2
->InvalidateContentRect(child2_rect
);
1520 layer_tree_host_
->UpdateLayers(queue_
.get());
1523 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1524 EXPECT_EQ(3, child
->fake_layer_updater()->update_count());
1525 EXPECT_EQ(3, child2
->fake_layer_updater()->update_count());
1526 EXPECT_FALSE(queue_
->HasMoreUpdates());
1528 root
->fake_layer_updater()->ClearUpdateCount();
1529 child
->fake_layer_updater()->ClearUpdateCount();
1530 child2
->fake_layer_updater()->ClearUpdateCount();
1532 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1533 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1534 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1535 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1536 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1537 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1538 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1539 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1540 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1542 for (unsigned i
= 0; i
< 3; ++i
) {
1543 for (unsigned j
= 0; j
< 2; ++j
)
1544 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1545 EXPECT_TRUE(child_impl
->HasResourceIdForTileAt(i
, 0));
1546 EXPECT_TRUE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1549 layer_tree_host_
->CommitComplete();
1551 // With a memory limit that includes only the root layer (3x2 tiles) and half
1552 // the surface that the child layers draw into, the child layers will not be
1553 // allocated. If the surface isn't accounted for, then one of the children
1554 // would fit within the memory limit.
1555 root
->InvalidateContentRect(root_rect
);
1556 child
->InvalidateContentRect(child_rect
);
1557 child2
->InvalidateContentRect(child2_rect
);
1559 size_t memory_limit
= (3 * 2 + 3 * 1) * (100 * 100) * 4;
1560 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1562 layer_tree_host_
->UpdateLayers(queue_
.get());
1565 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1566 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1567 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1568 EXPECT_FALSE(queue_
->HasMoreUpdates());
1570 root
->fake_layer_updater()->ClearUpdateCount();
1571 child
->fake_layer_updater()->ClearUpdateCount();
1572 child2
->fake_layer_updater()->ClearUpdateCount();
1574 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1575 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1576 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1577 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1578 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1579 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1580 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1581 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1582 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1584 for (unsigned i
= 0; i
< 3; ++i
) {
1585 for (unsigned j
= 0; j
< 2; ++j
)
1586 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1587 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1588 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1591 layer_tree_host_
->CommitComplete();
1593 // With a memory limit that includes only half the root layer, no contents
1594 // will be allocated. If render surface memory wasn't accounted for, there is
1595 // enough space for one of the children layers, but they draw into a surface
1596 // that can't be allocated.
1597 root
->InvalidateContentRect(root_rect
);
1598 child
->InvalidateContentRect(child_rect
);
1599 child2
->InvalidateContentRect(child2_rect
);
1601 memory_limit
= (3 * 1) * (100 * 100) * 4;
1602 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1604 layer_tree_host_
->UpdateLayers(queue_
.get());
1607 EXPECT_EQ(0, root
->fake_layer_updater()->update_count());
1608 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1609 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1610 EXPECT_FALSE(queue_
->HasMoreUpdates());
1612 root
->fake_layer_updater()->ClearUpdateCount();
1613 child
->fake_layer_updater()->ClearUpdateCount();
1614 child2
->fake_layer_updater()->ClearUpdateCount();
1616 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1617 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1618 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1619 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1620 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1621 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1622 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1623 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1624 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1626 for (unsigned i
= 0; i
< 3; ++i
) {
1627 for (unsigned j
= 0; j
< 2; ++j
)
1628 EXPECT_FALSE(root_impl
->HasResourceIdForTileAt(i
, j
));
1629 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1630 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1633 layer_tree_host_
->CommitComplete();
1635 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1636 resource_provider_
.get());
1637 layer_tree_host_
->SetRootLayer(nullptr);
1640 class TrackingLayerPainter
: public LayerPainter
{
1642 static scoped_ptr
<TrackingLayerPainter
> Create() {
1643 return make_scoped_ptr(new TrackingLayerPainter());
1646 void Paint(SkCanvas
* canvas
, const gfx::Rect
& content_rect
) override
{
1647 painted_rect_
= content_rect
;
1650 gfx::Rect
PaintedRect() const { return painted_rect_
; }
1651 void ResetPaintedRect() { painted_rect_
= gfx::Rect(); }
1654 gfx::Rect painted_rect_
;
1657 class UpdateTrackingTiledLayer
: public FakeTiledLayer
{
1659 explicit UpdateTrackingTiledLayer(PrioritizedResourceManager
* manager
)
1660 : FakeTiledLayer(manager
) {
1661 scoped_ptr
<TrackingLayerPainter
> painter(TrackingLayerPainter::Create());
1662 tracking_layer_painter_
= painter
.get();
1663 layer_updater_
= BitmapContentLayerUpdater::Create(painter
.Pass(), 0);
1666 TrackingLayerPainter
* tracking_layer_painter() const {
1667 return tracking_layer_painter_
;
1671 LayerUpdater
* Updater() const override
{ return layer_updater_
.get(); }
1672 ~UpdateTrackingTiledLayer() override
{}
1674 TrackingLayerPainter
* tracking_layer_painter_
;
1675 scoped_refptr
<BitmapContentLayerUpdater
> layer_updater_
;
1678 TEST_F(TiledLayerTest
, NonIntegerContentsScaleIsNotDistortedDuringPaint
) {
1679 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1680 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1682 layer_tree_host_
->root_layer()->AddChild(layer
);
1684 gfx::Rect
layer_rect(0, 0, 30, 31);
1685 layer
->SetPosition(layer_rect
.origin());
1686 layer
->SetBounds(layer_rect
.size());
1687 layer
->UpdateContentsScale(1.5f
);
1689 gfx::Rect
content_rect(0, 0, 45, 47);
1690 EXPECT_EQ(content_rect
.size(), layer
->content_bounds());
1691 layer
->draw_properties().visible_content_rect
= content_rect
;
1692 layer
->draw_properties().drawable_content_rect
= content_rect
;
1694 layer
->SetTexturePriorities(priority_calculator_
);
1695 resource_manager_
->PrioritizeTextures();
1696 layer
->SavePaintProperties();
1698 // Update the whole tile.
1699 layer
->Update(queue_
.get(), nullptr);
1700 layer
->tracking_layer_painter()->ResetPaintedRect();
1702 EXPECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1705 // Invalidate the entire layer in content space. When painting, the rect given
1706 // to webkit should match the layer's bounds.
1707 layer
->InvalidateContentRect(content_rect
);
1708 layer
->Update(queue_
.get(), nullptr);
1710 // Rounding leads to an extra pixel.
1711 gfx::Rect
expanded_layer_rect(layer_rect
);
1712 expanded_layer_rect
.set_height(32);
1713 EXPECT_EQ(expanded_layer_rect
,
1714 layer
->tracking_layer_painter()->PaintedRect());
1717 TEST_F(TiledLayerTest
,
1718 NonIntegerContentsScaleIsNotDistortedDuringInvalidation
) {
1719 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1720 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1722 layer_tree_host_
->root_layer()->AddChild(layer
);
1724 gfx::Rect
layer_rect(0, 0, 30, 31);
1725 layer
->SetPosition(layer_rect
.origin());
1726 layer
->SetBounds(layer_rect
.size());
1727 layer
->UpdateContentsScale(1.3f
);
1729 gfx::Rect
content_rect(layer
->content_bounds());
1730 layer
->draw_properties().visible_content_rect
= content_rect
;
1731 layer
->draw_properties().drawable_content_rect
= content_rect
;
1733 layer
->SetTexturePriorities(priority_calculator_
);
1734 resource_manager_
->PrioritizeTextures();
1735 layer
->SavePaintProperties();
1737 // Update the whole tile.
1738 layer
->Update(queue_
.get(), nullptr);
1739 layer
->tracking_layer_painter()->ResetPaintedRect();
1741 EXPECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1744 // Invalidate the entire layer in layer space. When painting, the rect given
1745 // to webkit should match the layer's bounds.
1746 layer
->SetNeedsDisplayRect(layer_rect
);
1747 layer
->Update(queue_
.get(), nullptr);
1749 // Rounding leads to an extra pixel.
1750 gfx::Rect
expanded_layer_rect(layer_rect
);
1751 expanded_layer_rect
.set_height(32);
1752 EXPECT_EQ(expanded_layer_rect
,
1753 layer
->tracking_layer_painter()->PaintedRect());