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 "cc/debug/overdraw_metrics.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/fake_rendering_stats_instrumentation.h"
22 #include "cc/test/geometry_test_utils.h"
23 #include "cc/test/tiled_layer_test_common.h"
24 #include "cc/trees/single_thread_proxy.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/rect_conversions.h"
27 #include "ui/gfx/transform.h"
32 class TestOcclusionTracker
: public OcclusionTracker
{
34 TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000), true) {
35 stack_
.push_back(StackObject());
38 void SetRenderTarget(Layer
* render_target
) {
39 stack_
.back().target
= render_target
;
42 void SetOcclusion(const Region
& occlusion
) {
43 stack_
.back().occlusion_from_inside_target
= occlusion
;
47 class TiledLayerTest
: public testing::Test
{
51 output_surface_(FakeOutputSurface::Create3d()),
52 queue_(make_scoped_ptr(new ResourceUpdateQueue
)),
53 impl_thread_("ImplThread"),
54 fake_layer_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D
),
56 settings_
.max_partial_texture_updates
= std::numeric_limits
<size_t>::max();
57 settings_
.layer_transforms_should_scale_layer_contents
= true;
60 virtual void SetUp() {
62 layer_tree_host_
= LayerTreeHost::CreateThreaded(
63 &fake_layer_tree_host_client_
,
66 impl_thread_
.message_loop_proxy());
67 proxy_
= layer_tree_host_
->proxy();
68 resource_manager_
= PrioritizedResourceManager::Create(proxy_
);
69 layer_tree_host_
->SetLayerTreeHostClientReady();
70 layer_tree_host_
->InitializeOutputSurfaceIfNeeded();
71 layer_tree_host_
->SetRootLayer(Layer::Create());
73 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
75 DebugScopedSetImplThreadAndMainThreadBlocked
76 impl_thread_and_main_thread_blocked(proxy_
);
78 ResourceProvider::Create(output_surface_
.get(), NULL
, 0, false, 1);
79 host_impl_
= make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_
));
82 virtual ~TiledLayerTest() {
83 ResourceManagerClearAllMemory(resource_manager_
.get(),
84 resource_provider_
.get());
86 DebugScopedSetImplThreadAndMainThreadBlocked
87 impl_thread_and_main_thread_blocked(proxy_
);
88 resource_provider_
.reset();
92 void ResourceManagerClearAllMemory(
93 PrioritizedResourceManager
* resource_manager
,
94 ResourceProvider
* resource_provider
) {
96 DebugScopedSetImplThreadAndMainThreadBlocked
97 impl_thread_and_main_thread_blocked(proxy_
);
98 resource_manager
->ClearAllMemory(resource_provider
);
99 resource_manager
->ReduceMemory(resource_provider
);
101 resource_manager
->UnlinkAndClearEvictedBackings();
104 void UpdateTextures() {
105 DebugScopedSetImplThreadAndMainThreadBlocked
106 impl_thread_and_main_thread_blocked(proxy_
);
108 scoped_ptr
<ResourceUpdateController
> update_controller
=
109 ResourceUpdateController::Create(NULL
,
110 proxy_
->ImplThreadTaskRunner(),
112 resource_provider_
.get());
113 update_controller
->Finalize();
114 queue_
= make_scoped_ptr(new ResourceUpdateQueue
);
117 void LayerPushPropertiesTo(FakeTiledLayer
* layer
,
118 FakeTiledLayerImpl
* layer_impl
) {
119 DebugScopedSetImplThreadAndMainThreadBlocked
120 impl_thread_and_main_thread_blocked(proxy_
);
121 layer
->PushPropertiesTo(layer_impl
);
122 layer
->ResetNumDependentsNeedPushProperties();
125 void LayerUpdate(FakeTiledLayer
* layer
, TestOcclusionTracker
* occluded
) {
126 DebugScopedSetMainThread
main_thread(proxy_
);
127 layer
->Update(queue_
.get(), occluded
);
130 void CalcDrawProps(RenderSurfaceLayerList
* render_surface_layer_list
) {
132 occlusion_
->SetRenderTarget(layer_tree_host_
->root_layer());
134 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
135 layer_tree_host_
->root_layer(),
136 layer_tree_host_
->device_viewport_size(),
137 render_surface_layer_list
);
138 inputs
.device_scale_factor
= layer_tree_host_
->device_scale_factor();
139 inputs
.max_texture_size
=
140 layer_tree_host_
->GetRendererCapabilities().max_texture_size
;
141 inputs
.can_adjust_raster_scales
= true;
142 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
145 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
146 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
) {
147 scoped_refptr
<FakeTiledLayer
> layer2
;
148 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
;
149 return UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
152 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
153 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
,
154 const scoped_refptr
<FakeTiledLayer
>& layer2
,
155 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl2
) {
157 resource_manager_
->ClearPriorities();
159 layer1
->SetTexturePriorities(priority_calculator_
);
161 layer2
->SetTexturePriorities(priority_calculator_
);
162 resource_manager_
->PrioritizeTextures();
164 // Save paint properties
166 layer1
->SavePaintProperties();
168 layer2
->SavePaintProperties();
172 layer1
->Update(queue_
.get(), occlusion_
);
174 layer2
->Update(queue_
.get(), occlusion_
);
176 bool needs_update
= false;
178 needs_update
|= layer1
->NeedsIdlePaint();
180 needs_update
|= layer2
->NeedsIdlePaint();
182 // Update textures and push.
185 LayerPushPropertiesTo(layer1
.get(), layer_impl1
.get());
187 LayerPushPropertiesTo(layer2
.get(), layer_impl2
.get());
194 LayerTreeSettings settings_
;
195 FakeOutputSurfaceClient output_surface_client_
;
196 scoped_ptr
<OutputSurface
> output_surface_
;
197 scoped_ptr
<ResourceProvider
> resource_provider_
;
198 scoped_ptr
<ResourceUpdateQueue
> queue_
;
199 PriorityCalculator priority_calculator_
;
200 base::Thread impl_thread_
;
201 FakeLayerTreeHostClient fake_layer_tree_host_client_
;
202 scoped_ptr
<LayerTreeHost
> layer_tree_host_
;
203 scoped_ptr
<FakeLayerTreeHostImpl
> host_impl_
;
204 scoped_ptr
<PrioritizedResourceManager
> resource_manager_
;
205 TestOcclusionTracker
* occlusion_
;
208 TEST_F(TiledLayerTest
, PushDirtyTiles
) {
209 scoped_refptr
<FakeTiledLayer
> layer
=
210 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
211 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
212 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
213 RenderSurfaceLayerList render_surface_layer_list
;
215 layer_tree_host_
->root_layer()->AddChild(layer
);
217 // The tile size is 100x100, so this invalidates and then paints two tiles.
218 layer
->SetBounds(gfx::Size(100, 200));
219 CalcDrawProps(&render_surface_layer_list
);
220 UpdateAndPush(layer
, layer_impl
);
222 // We should have both tiles on the impl side.
223 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
224 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
226 // Invalidates both tiles, but then only update one of them.
227 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
228 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
229 UpdateAndPush(layer
, layer_impl
);
231 // We should only have the first tile since the other tile was invalidated but
233 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
234 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
237 TEST_F(TiledLayerTest
, PushOccludedDirtyTiles
) {
238 scoped_refptr
<FakeTiledLayer
> layer
=
239 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
240 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
241 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
242 TestOcclusionTracker occluded
;
243 occlusion_
= &occluded
;
244 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
246 layer_tree_host_
->root_layer()->AddChild(layer
);
249 RenderSurfaceLayerList render_surface_layer_list
;
251 // The tile size is 100x100, so this invalidates and then paints two tiles.
252 layer
->SetBounds(gfx::Size(100, 200));
253 CalcDrawProps(&render_surface_layer_list
);
254 UpdateAndPush(layer
, layer_impl
);
256 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
258 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
259 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
261 // We should have both tiles on the impl side.
262 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
263 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
267 RenderSurfaceLayerList render_surface_layer_list
;
269 // Invalidates part of the top tile...
270 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
271 // ....but the area is occluded.
272 occluded
.SetOcclusion(gfx::Rect(0, 0, 50, 50));
273 CalcDrawProps(&render_surface_layer_list
);
274 UpdateAndPush(layer
, layer_impl
);
276 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
277 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
280 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
282 // We should still have both tiles, as part of the top tile is still
284 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
285 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
289 TEST_F(TiledLayerTest
, PushDeletedTiles
) {
290 scoped_refptr
<FakeTiledLayer
> layer
=
291 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
292 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
293 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
294 RenderSurfaceLayerList render_surface_layer_list
;
296 layer_tree_host_
->root_layer()->AddChild(layer
);
298 // The tile size is 100x100, so this invalidates and then paints two tiles.
299 layer
->SetBounds(gfx::Size(100, 200));
300 CalcDrawProps(&render_surface_layer_list
);
301 UpdateAndPush(layer
, layer_impl
);
303 // We should have both tiles on the impl side.
304 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
305 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
307 resource_manager_
->ClearPriorities();
308 ResourceManagerClearAllMemory(resource_manager_
.get(),
309 resource_provider_
.get());
310 resource_manager_
->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
312 // This should drop the tiles on the impl thread.
313 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
315 // We should now have no textures on the impl thread.
316 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
317 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
319 // This should recreate and update one of the deleted textures.
320 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
321 UpdateAndPush(layer
, layer_impl
);
323 // We should have one tiles on the impl side.
324 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
325 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
328 TEST_F(TiledLayerTest
, PushIdlePaintTiles
) {
329 scoped_refptr
<FakeTiledLayer
> layer
=
330 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
331 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
332 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
333 RenderSurfaceLayerList render_surface_layer_list
;
335 layer_tree_host_
->root_layer()->AddChild(layer
);
337 // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
338 // center. This paints 1 visible of the 25 invalid tiles.
339 layer
->SetBounds(gfx::Size(500, 500));
340 CalcDrawProps(&render_surface_layer_list
);
341 layer
->draw_properties().visible_content_rect
= gfx::Rect(200, 200, 100, 100);
342 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
343 // We should need idle-painting for surrounding tiles.
344 EXPECT_TRUE(needs_update
);
346 // We should have one tile on the impl side.
347 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(2, 2));
349 // For the next four updates, we should detect we still need idle painting.
350 for (int i
= 0; i
< 4; i
++) {
351 needs_update
= UpdateAndPush(layer
, layer_impl
);
352 EXPECT_TRUE(needs_update
);
355 // We should always finish painting eventually.
356 for (int i
= 0; i
< 20; i
++)
357 needs_update
= UpdateAndPush(layer
, layer_impl
);
359 // We should have pre-painted all of the surrounding tiles.
360 for (int i
= 0; i
< 5; i
++) {
361 for (int j
= 0; j
< 5; j
++)
362 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
365 EXPECT_FALSE(needs_update
);
368 TEST_F(TiledLayerTest
, PredictivePainting
) {
369 scoped_refptr
<FakeTiledLayer
> layer
=
370 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
371 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
372 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
374 layer_tree_host_
->root_layer()->AddChild(layer
);
376 // Prepainting should occur in the scroll direction first, and the
377 // visible rect should be extruded only along the dominant axis.
378 gfx::Vector2d directions
[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
379 gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
380 gfx::Vector2d(10, 20),
381 gfx::Vector2d(-20, 10) };
382 // We should push all tiles that touch the extruded visible rect.
383 gfx::Rect pushed_visible_tiles
[6] = {
384 gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
385 gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
387 // The first pre-paint should also paint first in the scroll
388 // direction so we should find one additional tile in the scroll direction.
389 gfx::Rect pushed_prepaint_tiles
[6] = {
390 gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
391 gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
393 for (int k
= 0; k
< 6; k
++) {
394 // The tile size is 100x100. Setup 5x5 tiles with one visible tile
396 gfx::Size bounds
= gfx::Size(500, 500);
397 gfx::Rect visible_rect
= gfx::Rect(200, 200, 100, 100);
398 gfx::Rect previous_visible_rect
=
399 gfx::Rect(visible_rect
.origin() + directions
[k
], visible_rect
.size());
400 gfx::Rect next_visible_rect
=
401 gfx::Rect(visible_rect
.origin() - directions
[k
], visible_rect
.size());
403 // Setup. Use the previous_visible_rect to setup the prediction for next
405 layer
->SetBounds(bounds
);
407 RenderSurfaceLayerList render_surface_layer_list
;
408 CalcDrawProps(&render_surface_layer_list
);
409 layer
->draw_properties().visible_content_rect
= previous_visible_rect
;
410 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
412 // Invalidate and move the visible_rect in the scroll direction.
413 // Check that the correct tiles have been painted in the visible pass.
414 layer
->SetNeedsDisplay();
415 layer
->draw_properties().visible_content_rect
= visible_rect
;
416 needs_update
= UpdateAndPush(layer
, layer_impl
);
417 for (int i
= 0; i
< 5; i
++) {
418 for (int j
= 0; j
< 5; j
++)
419 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
420 pushed_visible_tiles
[k
].Contains(i
, j
));
423 // Move the transform in the same direction without invalidating.
424 // Check that non-visible pre-painting occured in the correct direction.
425 // Ignore diagonal scrolls here (k > 3) as these have new visible content
428 layer
->draw_properties().visible_content_rect
= next_visible_rect
;
429 needs_update
= UpdateAndPush(layer
, layer_impl
);
430 for (int i
= 0; i
< 5; i
++) {
431 for (int j
= 0; j
< 5; j
++)
432 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
433 pushed_prepaint_tiles
[k
].Contains(i
, j
));
437 // We should always finish painting eventually.
438 for (int i
= 0; i
< 20; i
++)
439 needs_update
= UpdateAndPush(layer
, layer_impl
);
440 EXPECT_FALSE(needs_update
);
444 TEST_F(TiledLayerTest
, PushTilesAfterIdlePaintFailed
) {
445 // Start with 2mb of memory, but the test is going to try to use just more
446 // than 1mb, so we reduce to 1mb later.
447 resource_manager_
->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
448 scoped_refptr
<FakeTiledLayer
> layer1
=
449 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
450 scoped_ptr
<FakeTiledLayerImpl
> layer_impl1
=
451 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
452 scoped_refptr
<FakeTiledLayer
> layer2
=
453 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
454 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
=
455 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
456 RenderSurfaceLayerList render_surface_layer_list
;
458 layer_tree_host_
->root_layer()->AddChild(layer1
);
459 layer_tree_host_
->root_layer()->AddChild(layer2
);
461 // For this test we have two layers. layer1 exhausts most texture memory,
462 // leaving room for 2 more tiles from layer2, but not all three tiles. First
463 // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
464 // we will fail on the third tile of layer2, and this should not leave the
465 // second tile in a bad state.
467 // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
468 // for 2 tiles only in the other layer.
469 gfx::Rect
layer1_rect(0, 0, 100, 2400);
471 // This requires 4*30000 bytes of memory.
472 gfx::Rect
layer2_rect(0, 0, 100, 300);
474 // Paint a single tile in layer2 so that it will idle paint.
475 layer1
->SetBounds(layer1_rect
.size());
476 layer2
->SetBounds(layer2_rect
.size());
477 CalcDrawProps(&render_surface_layer_list
);
478 layer1
->draw_properties().visible_content_rect
= layer1_rect
;
479 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
480 bool needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
481 // We should need idle-painting for both remaining tiles in layer2.
482 EXPECT_TRUE(needs_update
);
484 // Reduce our memory limits to 1mb.
485 resource_manager_
->SetMaxMemoryLimitBytes(1024 * 1024);
487 // Now idle paint layer2. We are going to run out of memory though!
488 // Oh well, commit the frame and push.
489 for (int i
= 0; i
< 4; i
++) {
490 needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
493 // Sanity check, we should have textures for the big layer.
494 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 0));
495 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 23));
497 // We should only have the first two tiles from layer2 since
498 // it failed to idle update the last tile.
499 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
500 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
501 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
502 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
504 EXPECT_FALSE(needs_update
);
505 EXPECT_FALSE(layer_impl2
->HasResourceIdForTileAt(0, 2));
508 TEST_F(TiledLayerTest
, PushIdlePaintedOccludedTiles
) {
509 scoped_refptr
<FakeTiledLayer
> layer
=
510 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
511 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
512 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
513 RenderSurfaceLayerList render_surface_layer_list
;
514 TestOcclusionTracker occluded
;
515 occlusion_
= &occluded
;
517 layer_tree_host_
->root_layer()->AddChild(layer
);
519 // The tile size is 100x100, so this invalidates one occluded tile, culls it
520 // during paint, but prepaints it.
521 occluded
.SetOcclusion(gfx::Rect(0, 0, 100, 100));
523 layer
->SetBounds(gfx::Size(100, 100));
524 CalcDrawProps(&render_surface_layer_list
);
525 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
526 UpdateAndPush(layer
, layer_impl
);
528 // We should have the prepainted tile on the impl side, but culled it during
530 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
531 EXPECT_EQ(1, occluded
.overdraw_metrics()->tiles_culled_for_upload());
534 TEST_F(TiledLayerTest
, PushTilesMarkedDirtyDuringPaint
) {
535 scoped_refptr
<FakeTiledLayer
> layer
=
536 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
537 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
538 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
539 RenderSurfaceLayerList render_surface_layer_list
;
541 layer_tree_host_
->root_layer()->AddChild(layer
);
543 // The tile size is 100x100, so this invalidates and then paints two tiles.
544 // However, during the paint, we invalidate one of the tiles. This should
545 // not prevent the tile from being pushed.
546 layer
->fake_layer_updater()->SetRectToInvalidate(
547 gfx::Rect(0, 50, 100, 50), layer
.get());
548 layer
->SetBounds(gfx::Size(100, 200));
549 CalcDrawProps(&render_surface_layer_list
);
550 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
551 UpdateAndPush(layer
, layer_impl
);
553 // We should have both tiles on the impl side.
554 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
555 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
558 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer
) {
559 scoped_refptr
<FakeTiledLayer
> layer1
=
560 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
561 scoped_refptr
<FakeTiledLayer
> layer2
=
562 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
563 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
564 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
565 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
566 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
567 RenderSurfaceLayerList render_surface_layer_list
;
569 layer_tree_host_
->root_layer()->AddChild(layer1
);
570 layer_tree_host_
->root_layer()->AddChild(layer2
);
572 // Invalidate a tile on layer1, during update of layer 2.
573 layer2
->fake_layer_updater()->SetRectToInvalidate(
574 gfx::Rect(0, 50, 100, 50), layer1
.get());
575 layer1
->SetBounds(gfx::Size(100, 200));
576 layer2
->SetBounds(gfx::Size(100, 200));
577 CalcDrawProps(&render_surface_layer_list
);
578 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
579 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
580 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
582 // We should have both tiles on the impl side for all layers.
583 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
584 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
585 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
586 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
589 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
) {
590 scoped_refptr
<FakeTiledLayer
> layer1
=
591 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
592 scoped_refptr
<FakeTiledLayer
> layer2
=
593 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
594 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
595 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
596 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
597 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
598 RenderSurfaceLayerList render_surface_layer_list
;
600 layer_tree_host_
->root_layer()->AddChild(layer1
);
601 layer_tree_host_
->root_layer()->AddChild(layer2
);
603 layer1
->fake_layer_updater()->SetRectToInvalidate(
604 gfx::Rect(0, 50, 100, 50), layer2
.get());
605 layer1
->SetBounds(gfx::Size(100, 200));
606 layer2
->SetBounds(gfx::Size(100, 200));
607 CalcDrawProps(&render_surface_layer_list
);
608 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
609 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
610 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
612 // We should have both tiles on the impl side for all layers.
613 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
614 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
615 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
616 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
619 TEST_F(TiledLayerTest
, PaintSmallAnimatedLayersImmediately
) {
620 // Create a LayerTreeHost that has the right viewportsize,
621 // so the layer is considered small enough.
622 bool run_out_of_memory
[2] = { false, true };
623 for (int i
= 0; i
< 2; i
++) {
624 // Create a layer with 5x5 tiles, with 4x4 size viewport.
625 int viewport_width
= 4 * FakeTiledLayer::tile_size().width();
626 int viewport_height
= 4 * FakeTiledLayer::tile_size().width();
627 int layer_width
= 5 * FakeTiledLayer::tile_size().width();
628 int layer_height
= 5 * FakeTiledLayer::tile_size().height();
629 int memory_for_layer
= layer_width
* layer_height
* 4;
630 layer_tree_host_
->SetViewportSize(
631 gfx::Size(viewport_width
, viewport_height
));
633 // Use 10x5 tiles to run out of memory.
634 if (run_out_of_memory
[i
])
637 resource_manager_
->SetMaxMemoryLimitBytes(memory_for_layer
);
639 scoped_refptr
<FakeTiledLayer
> layer
=
640 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
641 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
642 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
643 RenderSurfaceLayerList render_surface_layer_list
;
645 layer_tree_host_
->root_layer()->AddChild(layer
);
647 // Full size layer with half being visible.
648 layer
->SetBounds(gfx::Size(layer_width
, layer_height
));
649 gfx::Rect
visible_rect(0, 0, layer_width
/ 2, layer_height
);
650 CalcDrawProps(&render_surface_layer_list
);
652 // Pretend the layer is animating.
653 layer
->draw_properties().target_space_transform_is_animating
= true;
654 layer
->draw_properties().visible_content_rect
= visible_rect
;
655 layer
->SetLayerTreeHost(layer_tree_host_
.get());
657 // The layer should paint its entire contents on the first paint
658 // if it is close to the viewport size and has the available memory.
659 layer
->SetTexturePriorities(priority_calculator_
);
660 resource_manager_
->PrioritizeTextures();
661 layer
->SavePaintProperties();
662 layer
->Update(queue_
.get(), NULL
);
664 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
666 // We should have all the tiles for the small animated layer.
667 // We should still have the visible tiles when we didn't
668 // have enough memory for all the tiles.
669 if (!run_out_of_memory
[i
]) {
670 for (int i
= 0; i
< 5; ++i
) {
671 for (int j
= 0; j
< 5; ++j
)
672 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
675 for (int i
= 0; i
< 10; ++i
) {
676 for (int j
= 0; j
< 5; ++j
)
677 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
), i
< 5);
681 layer
->RemoveFromParent();
685 TEST_F(TiledLayerTest
, IdlePaintOutOfMemory
) {
686 scoped_refptr
<FakeTiledLayer
> layer
=
687 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
688 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
689 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
690 RenderSurfaceLayerList render_surface_layer_list
;
692 layer_tree_host_
->root_layer()->AddChild(layer
);
694 // We have enough memory for only the visible rect, so we will run out of
695 // memory in first idle paint.
696 int memory_limit
= 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
697 resource_manager_
->SetMaxMemoryLimitBytes(memory_limit
);
699 // The tile size is 100x100, so this invalidates and then paints two tiles.
700 bool needs_update
= false;
701 layer
->SetBounds(gfx::Size(300, 300));
702 CalcDrawProps(&render_surface_layer_list
);
703 layer
->draw_properties().visible_content_rect
= gfx::Rect(100, 100, 100, 100);
704 for (int i
= 0; i
< 2; i
++)
705 needs_update
= UpdateAndPush(layer
, layer_impl
);
707 // Idle-painting should see no more priority tiles for painting.
708 EXPECT_FALSE(needs_update
);
710 // We should have one tile on the impl side.
711 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
714 TEST_F(TiledLayerTest
, IdlePaintZeroSizedLayer
) {
715 scoped_refptr
<FakeTiledLayer
> layer
=
716 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
717 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
718 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
720 layer_tree_host_
->root_layer()->AddChild(layer
);
722 bool animating
[2] = { false, true };
723 for (int i
= 0; i
< 2; i
++) {
724 // Pretend the layer is animating.
725 layer
->draw_properties().target_space_transform_is_animating
= animating
[i
];
727 // The layer's bounds are empty.
728 // Empty layers don't paint or idle-paint.
729 layer
->SetBounds(gfx::Size());
731 RenderSurfaceLayerList render_surface_layer_list
;
732 CalcDrawProps(&render_surface_layer_list
);
733 layer
->draw_properties().visible_content_rect
= gfx::Rect();
734 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
736 // Empty layers don't have tiles.
737 EXPECT_EQ(0u, layer
->NumPaintedTiles());
739 // Empty layers don't need prepaint.
740 EXPECT_FALSE(needs_update
);
742 // Empty layers don't have tiles.
743 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
747 TEST_F(TiledLayerTest
, IdlePaintNonVisibleLayers
) {
748 scoped_refptr
<FakeTiledLayer
> layer
=
749 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
750 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
751 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
753 // Alternate between not visible and visible.
754 gfx::Rect
v(0, 0, 100, 100);
755 gfx::Rect
nv(0, 0, 0, 0);
756 gfx::Rect visible_rect
[10] = { nv
, nv
, v
, v
, nv
, nv
, v
, v
, nv
, nv
};
757 bool invalidate
[10] = { true, true, true, true, true, true, true, true, false,
760 // We should not have any tiles except for when the layer was visible
761 // or after the layer was visible and we didn't invalidate.
762 bool have_tile
[10] = { false, false, true, true, false, false, true, true,
765 layer_tree_host_
->root_layer()->AddChild(layer
);
767 for (int i
= 0; i
< 10; i
++) {
768 layer
->SetBounds(gfx::Size(100, 100));
770 RenderSurfaceLayerList render_surface_layer_list
;
771 CalcDrawProps(&render_surface_layer_list
);
772 layer
->draw_properties().visible_content_rect
= visible_rect
[i
];
775 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
776 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
778 // We should never signal idle paint, as we painted the entire layer
779 // or the layer was not visible.
780 EXPECT_FALSE(needs_update
);
781 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(0, 0), have_tile
[i
]);
785 TEST_F(TiledLayerTest
, InvalidateFromPrepare
) {
786 scoped_refptr
<FakeTiledLayer
> layer
=
787 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
788 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
789 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
790 RenderSurfaceLayerList render_surface_layer_list
;
792 layer_tree_host_
->root_layer()->AddChild(layer
);
794 // The tile size is 100x100, so this invalidates and then paints two tiles.
795 layer
->SetBounds(gfx::Size(100, 200));
796 CalcDrawProps(&render_surface_layer_list
);
797 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
798 UpdateAndPush(layer
, layer_impl
);
800 // We should have both tiles on the impl side.
801 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
802 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
804 layer
->fake_layer_updater()->ClearPrepareCount();
805 // Invoke update again. As the layer is valid update shouldn't be invoked on
807 UpdateAndPush(layer
, layer_impl
);
808 EXPECT_EQ(0, layer
->fake_layer_updater()->prepare_count());
810 // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
812 layer
->fake_layer_updater()->SetRectToInvalidate(
813 gfx::Rect(25, 25, 50, 50), layer
.get());
814 layer
->fake_layer_updater()->ClearPrepareCount();
815 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
816 UpdateAndPush(layer
, layer_impl
);
817 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
818 layer
->fake_layer_updater()->ClearPrepareCount();
820 // The layer should still be invalid as update invoked invalidate.
821 UpdateAndPush(layer
, layer_impl
); // visible
822 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
825 TEST_F(TiledLayerTest
, VerifyUpdateRectWhenContentBoundsAreScaled
) {
826 // The update rect (that indicates what was actually painted) should be in
827 // layer space, not the content space.
828 scoped_refptr
<FakeTiledLayerWithScaledBounds
> layer
= make_scoped_refptr(
829 new FakeTiledLayerWithScaledBounds(resource_manager_
.get()));
831 layer_tree_host_
->root_layer()->AddChild(layer
);
833 gfx::Rect
layer_bounds(0, 0, 300, 200);
834 gfx::Rect
content_bounds(0, 0, 200, 250);
836 layer
->SetBounds(layer_bounds
.size());
837 layer
->SetContentBounds(content_bounds
.size());
838 layer
->draw_properties().visible_content_rect
= content_bounds
;
840 // On first update, the update_rect includes all tiles, even beyond the
841 // boundaries of the layer.
842 // However, it should still be in layer space, not content space.
843 layer
->InvalidateContentRect(content_bounds
);
845 layer
->SetTexturePriorities(priority_calculator_
);
846 resource_manager_
->PrioritizeTextures();
847 layer
->SavePaintProperties();
848 layer
->Update(queue_
.get(), NULL
);
849 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 300, 300 * 0.8), layer
->update_rect());
852 // After the tiles are updated once, another invalidate only needs to update
853 // the bounds of the layer.
854 layer
->SetTexturePriorities(priority_calculator_
);
855 resource_manager_
->PrioritizeTextures();
856 layer
->InvalidateContentRect(content_bounds
);
857 layer
->SavePaintProperties();
858 layer
->Update(queue_
.get(), NULL
);
859 EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds
), layer
->update_rect());
862 // Partial re-paint should also be represented by the update rect in layer
863 // space, not content space.
864 gfx::Rect
partial_damage(30, 100, 10, 10);
865 layer
->InvalidateContentRect(partial_damage
);
866 layer
->SetTexturePriorities(priority_calculator_
);
867 resource_manager_
->PrioritizeTextures();
868 layer
->SavePaintProperties();
869 layer
->Update(queue_
.get(), NULL
);
870 EXPECT_FLOAT_RECT_EQ(gfx::RectF(45, 80, 15, 8), layer
->update_rect());
873 TEST_F(TiledLayerTest
, VerifyInvalidationWhenContentsScaleChanges
) {
874 scoped_refptr
<FakeTiledLayer
> layer
=
875 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
876 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
877 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
878 RenderSurfaceLayerList render_surface_layer_list
;
880 layer_tree_host_
->root_layer()->AddChild(layer
);
882 // Create a layer with one tile.
883 layer
->SetBounds(gfx::Size(100, 100));
884 CalcDrawProps(&render_surface_layer_list
);
885 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
886 layer
->Update(queue_
.get(), NULL
);
888 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
889 layer
->last_needs_display_rect());
891 // Push the tiles to the impl side and check that there is exactly one.
892 layer
->SetTexturePriorities(priority_calculator_
);
893 resource_manager_
->PrioritizeTextures();
894 layer
->SavePaintProperties();
895 layer
->Update(queue_
.get(), NULL
);
897 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
898 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
899 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
900 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
901 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
903 layer
->SetNeedsDisplayRect(gfx::Rect());
904 EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer
->last_needs_display_rect());
906 // Change the contents scale.
907 layer
->UpdateContentsScale(2.f
);
908 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 200, 200);
910 // The impl side should get 2x2 tiles now.
911 layer
->SetTexturePriorities(priority_calculator_
);
912 resource_manager_
->PrioritizeTextures();
913 layer
->SavePaintProperties();
914 layer
->Update(queue_
.get(), NULL
);
916 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
917 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
918 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
919 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 0));
920 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
922 // Verify that changing the contents scale caused invalidation, and
923 // that the layer-space rectangle requiring painting is not scaled.
924 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
925 layer
->last_needs_display_rect());
927 // Invalidate the entire layer again, but do not paint. All tiles should be
928 // gone now from the impl side.
929 layer
->SetNeedsDisplay();
930 layer
->SetTexturePriorities(priority_calculator_
);
931 resource_manager_
->PrioritizeTextures();
933 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
934 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
935 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
936 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
937 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
940 TEST_F(TiledLayerTest
, SkipsDrawGetsReset
) {
941 // Create two 300 x 300 tiled layers.
942 gfx::Size
content_bounds(300, 300);
943 gfx::Rect
content_rect(content_bounds
);
945 // We have enough memory for only one of the two layers.
946 int memory_limit
= 4 * 300 * 300; // 4 bytes per pixel.
948 scoped_refptr
<FakeTiledLayer
> root_layer
= make_scoped_refptr(
949 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
950 scoped_refptr
<FakeTiledLayer
> child_layer
= make_scoped_refptr(
951 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
952 root_layer
->AddChild(child_layer
);
954 root_layer
->SetBounds(content_bounds
);
955 root_layer
->draw_properties().visible_content_rect
= content_rect
;
956 root_layer
->SetPosition(gfx::PointF(0, 0));
957 child_layer
->SetBounds(content_bounds
);
958 child_layer
->draw_properties().visible_content_rect
= content_rect
;
959 child_layer
->SetPosition(gfx::PointF(0, 0));
960 root_layer
->InvalidateContentRect(content_rect
);
961 child_layer
->InvalidateContentRect(content_rect
);
963 layer_tree_host_
->SetRootLayer(root_layer
);
964 layer_tree_host_
->SetViewportSize(gfx::Size(300, 300));
965 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
968 layer_tree_host_
->UpdateLayers(queue_
.get());
970 // We'll skip the root layer.
971 EXPECT_TRUE(root_layer
->SkipsDraw());
972 EXPECT_FALSE(child_layer
->SkipsDraw());
974 layer_tree_host_
->CommitComplete();
976 // Remove the child layer.
977 root_layer
->RemoveAllChildren();
979 layer_tree_host_
->UpdateLayers(queue_
.get());
980 EXPECT_FALSE(root_layer
->SkipsDraw());
982 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
983 resource_provider_
.get());
984 layer_tree_host_
->SetRootLayer(NULL
);
987 TEST_F(TiledLayerTest
, ResizeToSmaller
) {
988 scoped_refptr
<FakeTiledLayer
> layer
=
989 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
991 layer_tree_host_
->root_layer()->AddChild(layer
);
993 layer
->SetBounds(gfx::Size(700, 700));
994 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
995 layer
->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
997 layer
->SetTexturePriorities(priority_calculator_
);
998 resource_manager_
->PrioritizeTextures();
999 layer
->SavePaintProperties();
1000 layer
->Update(queue_
.get(), NULL
);
1002 layer
->SetBounds(gfx::Size(200, 200));
1003 layer
->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
1006 TEST_F(TiledLayerTest
, HugeLayerUpdateCrash
) {
1007 scoped_refptr
<FakeTiledLayer
> layer
=
1008 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1010 layer_tree_host_
->root_layer()->AddChild(layer
);
1013 layer
->SetBounds(gfx::Size(size
, size
));
1014 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1015 layer
->InvalidateContentRect(gfx::Rect(0, 0, size
, size
));
1017 // Ensure no crash for bounds where size * size would overflow an int.
1018 layer
->SetTexturePriorities(priority_calculator_
);
1019 resource_manager_
->PrioritizeTextures();
1020 layer
->SavePaintProperties();
1021 layer
->Update(queue_
.get(), NULL
);
1024 class TiledLayerPartialUpdateTest
: public TiledLayerTest
{
1026 TiledLayerPartialUpdateTest() { settings_
.max_partial_texture_updates
= 4; }
1029 TEST_F(TiledLayerPartialUpdateTest
, PartialUpdates
) {
1030 // Create one 300 x 200 tiled layer with 3 x 2 tiles.
1031 gfx::Size
content_bounds(300, 200);
1032 gfx::Rect
content_rect(content_bounds
);
1034 scoped_refptr
<FakeTiledLayer
> layer
= make_scoped_refptr(
1035 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1036 layer
->SetBounds(content_bounds
);
1037 layer
->SetPosition(gfx::PointF(0, 0));
1038 layer
->draw_properties().visible_content_rect
= content_rect
;
1039 layer
->InvalidateContentRect(content_rect
);
1041 layer_tree_host_
->SetRootLayer(layer
);
1042 layer_tree_host_
->SetViewportSize(gfx::Size(300, 200));
1044 // Full update of all 6 tiles.
1045 layer_tree_host_
->UpdateLayers(queue_
.get());
1047 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1048 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1049 EXPECT_EQ(6u, queue_
->FullUploadSize());
1050 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1052 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1053 EXPECT_FALSE(queue_
->HasMoreUpdates());
1054 layer
->fake_layer_updater()->ClearUpdateCount();
1055 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1057 layer_tree_host_
->CommitComplete();
1059 // Full update of 3 tiles and partial update of 3 tiles.
1060 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
1061 layer_tree_host_
->UpdateLayers(queue_
.get());
1063 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1064 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1065 EXPECT_EQ(3u, queue_
->FullUploadSize());
1066 EXPECT_EQ(3u, queue_
->PartialUploadSize());
1068 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1069 EXPECT_FALSE(queue_
->HasMoreUpdates());
1070 layer
->fake_layer_updater()->ClearUpdateCount();
1071 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1073 layer_tree_host_
->CommitComplete();
1075 // Partial update of 6 tiles.
1076 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1078 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1079 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1080 layer_tree_host_
->UpdateLayers(queue_
.get());
1081 EXPECT_EQ(2u, queue_
->FullUploadSize());
1082 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1084 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1085 EXPECT_FALSE(queue_
->HasMoreUpdates());
1086 layer
->fake_layer_updater()->ClearUpdateCount();
1087 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1089 layer_tree_host_
->CommitComplete();
1091 // Checkerboard all tiles.
1092 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
1094 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1095 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1096 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1098 layer_tree_host_
->CommitComplete();
1100 // Partial update of 6 checkerboard tiles.
1101 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1103 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1104 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1105 layer_tree_host_
->UpdateLayers(queue_
.get());
1106 EXPECT_EQ(6u, queue_
->FullUploadSize());
1107 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1109 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1110 EXPECT_FALSE(queue_
->HasMoreUpdates());
1111 layer
->fake_layer_updater()->ClearUpdateCount();
1112 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1114 layer_tree_host_
->CommitComplete();
1116 // Partial update of 4 tiles.
1117 layer
->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
1119 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1120 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1121 layer_tree_host_
->UpdateLayers(queue_
.get());
1122 EXPECT_EQ(0u, queue_
->FullUploadSize());
1123 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1125 EXPECT_EQ(4, layer
->fake_layer_updater()->update_count());
1126 EXPECT_FALSE(queue_
->HasMoreUpdates());
1127 layer
->fake_layer_updater()->ClearUpdateCount();
1128 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1130 layer_tree_host_
->CommitComplete();
1132 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1133 resource_provider_
.get());
1134 layer_tree_host_
->SetRootLayer(NULL
);
1137 TEST_F(TiledLayerTest
, TilesPaintedWithoutOcclusion
) {
1138 scoped_refptr
<FakeTiledLayer
> layer
=
1139 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1140 RenderSurfaceLayerList render_surface_layer_list
;
1142 layer_tree_host_
->root_layer()->AddChild(layer
);
1144 // The tile size is 100x100, so this invalidates and then paints two tiles.
1145 layer
->SetBounds(gfx::Size(100, 200));
1146 CalcDrawProps(&render_surface_layer_list
);
1148 layer
->SetTexturePriorities(priority_calculator_
);
1149 resource_manager_
->PrioritizeTextures();
1150 layer
->SavePaintProperties();
1151 layer
->Update(queue_
.get(), NULL
);
1152 EXPECT_EQ(2, layer
->fake_layer_updater()->update_count());
1155 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusion
) {
1156 scoped_refptr
<FakeTiledLayer
> layer
=
1157 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1158 RenderSurfaceLayerList render_surface_layer_list
;
1159 TestOcclusionTracker occluded
;
1160 occlusion_
= &occluded
;
1162 layer_tree_host_
->root_layer()->AddChild(layer
);
1164 // The tile size is 100x100.
1166 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1167 layer
->SetBounds(gfx::Size(600, 600));
1168 CalcDrawProps(&render_surface_layer_list
);
1170 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 100));
1171 layer
->draw_properties().drawable_content_rect
=
1172 gfx::Rect(layer
->content_bounds());
1173 layer
->draw_properties().visible_content_rect
=
1174 gfx::Rect(layer
->content_bounds());
1175 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1177 layer
->SetTexturePriorities(priority_calculator_
);
1178 resource_manager_
->PrioritizeTextures();
1179 layer
->SavePaintProperties();
1180 layer
->Update(queue_
.get(), &occluded
);
1181 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1183 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1185 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1186 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1188 layer
->fake_layer_updater()->ClearUpdateCount();
1189 layer
->SetTexturePriorities(priority_calculator_
);
1190 resource_manager_
->PrioritizeTextures();
1192 occluded
.SetOcclusion(gfx::Rect(250, 200, 300, 100));
1193 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1194 layer
->SavePaintProperties();
1195 layer
->Update(queue_
.get(), &occluded
);
1196 EXPECT_EQ(36 - 2, layer
->fake_layer_updater()->update_count());
1198 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1199 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1202 EXPECT_EQ(3 + 2, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1204 layer
->fake_layer_updater()->ClearUpdateCount();
1205 layer
->SetTexturePriorities(priority_calculator_
);
1206 resource_manager_
->PrioritizeTextures();
1208 occluded
.SetOcclusion(gfx::Rect(250, 250, 300, 100));
1209 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1210 layer
->SavePaintProperties();
1211 layer
->Update(queue_
.get(), &occluded
);
1212 EXPECT_EQ(36, layer
->fake_layer_updater()->update_count());
1214 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1215 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1216 330000 + 340000 + 360000,
1218 EXPECT_EQ(3 + 2, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1221 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndVisiblityConstraints
) {
1222 scoped_refptr
<FakeTiledLayer
> layer
=
1223 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1224 RenderSurfaceLayerList render_surface_layer_list
;
1225 TestOcclusionTracker occluded
;
1226 occlusion_
= &occluded
;
1228 layer_tree_host_
->root_layer()->AddChild(layer
);
1230 // The tile size is 100x100.
1232 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1233 layer
->SetBounds(gfx::Size(600, 600));
1234 CalcDrawProps(&render_surface_layer_list
);
1236 // The partially occluded tiles (by the 150 occlusion height) are visible
1237 // beyond the occlusion, so not culled.
1238 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 150));
1239 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 360);
1240 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 360);
1241 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1243 layer
->SetTexturePriorities(priority_calculator_
);
1244 resource_manager_
->PrioritizeTextures();
1245 layer
->SavePaintProperties();
1246 layer
->Update(queue_
.get(), &occluded
);
1247 EXPECT_EQ(24 - 3, layer
->fake_layer_updater()->update_count());
1249 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1251 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 210000, 1);
1252 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1254 layer
->fake_layer_updater()->ClearUpdateCount();
1256 // Now the visible region stops at the edge of the occlusion so the partly
1257 // visible tiles become fully occluded.
1258 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 150));
1259 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 350);
1260 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 350);
1261 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1262 layer
->SetTexturePriorities(priority_calculator_
);
1263 resource_manager_
->PrioritizeTextures();
1264 layer
->SavePaintProperties();
1265 layer
->Update(queue_
.get(), &occluded
);
1266 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1268 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1269 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1272 EXPECT_EQ(3 + 6, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1274 layer
->fake_layer_updater()->ClearUpdateCount();
1276 // Now the visible region is even smaller than the occlusion, it should have
1278 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 150));
1279 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 340);
1280 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 340);
1281 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1282 layer
->SetTexturePriorities(priority_calculator_
);
1283 resource_manager_
->PrioritizeTextures();
1284 layer
->SavePaintProperties();
1285 layer
->Update(queue_
.get(), &occluded
);
1286 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1288 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1289 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1290 210000 + 180000 + 180000,
1292 EXPECT_EQ(3 + 6 + 6, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1295 TEST_F(TiledLayerTest
, TilesNotPaintedWithoutInvalidation
) {
1296 scoped_refptr
<FakeTiledLayer
> layer
=
1297 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1298 RenderSurfaceLayerList render_surface_layer_list
;
1299 TestOcclusionTracker occluded
;
1300 occlusion_
= &occluded
;
1302 layer_tree_host_
->root_layer()->AddChild(layer
);
1304 // The tile size is 100x100.
1306 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1307 layer
->SetBounds(gfx::Size(600, 600));
1308 CalcDrawProps(&render_surface_layer_list
);
1310 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 100));
1311 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 600);
1312 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 600);
1313 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1314 layer
->SetTexturePriorities(priority_calculator_
);
1315 resource_manager_
->PrioritizeTextures();
1316 layer
->SavePaintProperties();
1317 layer
->Update(queue_
.get(), &occluded
);
1318 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1319 { UpdateTextures(); }
1321 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1323 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1324 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1326 layer
->fake_layer_updater()->ClearUpdateCount();
1327 layer
->SetTexturePriorities(priority_calculator_
);
1328 resource_manager_
->PrioritizeTextures();
1329 layer
->SavePaintProperties();
1331 // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
1333 layer
->Update(queue_
.get(), &occluded
);
1334 EXPECT_EQ(3, layer
->fake_layer_updater()->update_count());
1336 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1338 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1339 EXPECT_EQ(6, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1342 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndTransforms
) {
1343 scoped_refptr
<FakeTiledLayer
> layer
=
1344 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1345 RenderSurfaceLayerList render_surface_layer_list
;
1346 TestOcclusionTracker occluded
;
1347 occlusion_
= &occluded
;
1349 layer_tree_host_
->root_layer()->AddChild(layer
);
1351 // The tile size is 100x100.
1353 // This makes sure the painting works when the occluded region (in screen
1354 // space) is transformed differently than the layer.
1355 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1356 layer
->SetBounds(gfx::Size(600, 600));
1357 CalcDrawProps(&render_surface_layer_list
);
1358 gfx::Transform screen_transform
;
1359 screen_transform
.Scale(0.5, 0.5);
1360 layer
->draw_properties().screen_space_transform
= screen_transform
;
1361 layer
->draw_properties().target_space_transform
= screen_transform
;
1363 occluded
.SetOcclusion(gfx::Rect(100, 100, 150, 50));
1364 layer
->draw_properties().drawable_content_rect
=
1365 gfx::Rect(layer
->content_bounds());
1366 layer
->draw_properties().visible_content_rect
=
1367 gfx::Rect(layer
->content_bounds());
1368 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1369 layer
->SetTexturePriorities(priority_calculator_
);
1370 resource_manager_
->PrioritizeTextures();
1371 layer
->SavePaintProperties();
1372 layer
->Update(queue_
.get(), &occluded
);
1373 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1375 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1377 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1378 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1381 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndScaling
) {
1382 scoped_refptr
<FakeTiledLayer
> layer
=
1383 new FakeTiledLayer(resource_manager_
.get());
1384 RenderSurfaceLayerList render_surface_layer_list
;
1385 TestOcclusionTracker occluded
;
1386 occlusion_
= &occluded
;
1388 scoped_refptr
<FakeTiledLayer
> scale_layer
=
1389 new FakeTiledLayer(resource_manager_
.get());
1390 gfx::Transform scale_transform
;
1391 scale_transform
.Scale(2.0, 2.0);
1392 scale_layer
->SetTransform(scale_transform
);
1394 layer_tree_host_
->root_layer()->AddChild(scale_layer
);
1396 // The tile size is 100x100.
1398 // This makes sure the painting works when the content space is scaled to
1399 // a different layer space.
1400 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1401 layer
->SetAnchorPoint(gfx::PointF());
1402 layer
->SetBounds(gfx::Size(300, 300));
1403 scale_layer
->AddChild(layer
);
1404 CalcDrawProps(&render_surface_layer_list
);
1405 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_x());
1406 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_y());
1407 EXPECT_EQ(gfx::Size(600, 600).ToString(),
1408 layer
->content_bounds().ToString());
1410 // No tiles are covered by the 300x50 occlusion.
1411 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 50));
1412 layer
->draw_properties().drawable_content_rect
=
1413 gfx::Rect(layer
->bounds());
1414 layer
->draw_properties().visible_content_rect
=
1415 gfx::Rect(layer
->content_bounds());
1416 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1417 layer
->SetTexturePriorities(priority_calculator_
);
1418 resource_manager_
->PrioritizeTextures();
1419 layer
->SavePaintProperties();
1420 layer
->Update(queue_
.get(), &occluded
);
1421 int visible_tiles1
= 6 * 6;
1422 EXPECT_EQ(visible_tiles1
, layer
->fake_layer_updater()->update_count());
1424 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1425 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1426 visible_tiles1
* 100 * 100,
1428 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1430 layer
->fake_layer_updater()->ClearUpdateCount();
1432 // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1433 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 100));
1434 layer
->draw_properties().drawable_content_rect
=
1435 gfx::Rect(layer
->bounds());
1436 layer
->draw_properties().visible_content_rect
=
1437 gfx::Rect(layer
->content_bounds());
1438 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1439 layer
->SetTexturePriorities(priority_calculator_
);
1440 resource_manager_
->PrioritizeTextures();
1441 layer
->SavePaintProperties();
1442 layer
->Update(queue_
.get(), &occluded
);
1443 int visible_tiles2
= 6 * 6 - 3;
1444 EXPECT_EQ(visible_tiles2
, layer
->fake_layer_updater()->update_count());
1446 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1447 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1448 visible_tiles2
* 100 * 100 +
1449 visible_tiles1
* 100 * 100,
1451 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1453 layer
->fake_layer_updater()->ClearUpdateCount();
1455 // This makes sure content scaling and transforms work together.
1456 // When the tiles are scaled down by half, they are 50x50 each in the
1458 gfx::Transform screen_transform
;
1459 screen_transform
.Scale(0.5, 0.5);
1460 layer
->draw_properties().screen_space_transform
= screen_transform
;
1461 layer
->draw_properties().target_space_transform
= screen_transform
;
1463 // An occlusion of 150x100 will cover 3*2 = 6 tiles.
1464 occluded
.SetOcclusion(gfx::Rect(100, 100, 150, 100));
1466 gfx::Rect
layer_bounds_rect(layer
->bounds());
1467 layer
->draw_properties().drawable_content_rect
=
1468 gfx::ScaleToEnclosingRect(layer_bounds_rect
, 0.5f
);
1469 layer
->draw_properties().visible_content_rect
=
1470 gfx::Rect(layer
->content_bounds());
1471 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1472 layer
->SetTexturePriorities(priority_calculator_
);
1473 resource_manager_
->PrioritizeTextures();
1474 layer
->SavePaintProperties();
1475 layer
->Update(queue_
.get(), &occluded
);
1476 int visible_tiles3
= 6 * 6 - 6;
1477 EXPECT_EQ(visible_tiles3
, layer
->fake_layer_updater()->update_count());
1479 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1480 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1481 visible_tiles3
* 100 * 100 +
1482 visible_tiles2
* 100 * 100 +
1483 visible_tiles1
* 100 * 100,
1485 EXPECT_EQ(6 + 3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1488 TEST_F(TiledLayerTest
, VisibleContentOpaqueRegion
) {
1489 scoped_refptr
<FakeTiledLayer
> layer
=
1490 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1491 RenderSurfaceLayerList render_surface_layer_list
;
1492 TestOcclusionTracker occluded
;
1493 occlusion_
= &occluded
;
1494 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1496 layer_tree_host_
->root_layer()->AddChild(layer
);
1498 // The tile size is 100x100, so this invalidates and then paints two tiles in
1501 gfx::Rect opaque_paint_rect
;
1502 Region opaque_contents
;
1504 gfx::Rect content_bounds
= gfx::Rect(0, 0, 100, 200);
1505 gfx::Rect visible_bounds
= gfx::Rect(0, 0, 100, 150);
1507 layer
->SetBounds(content_bounds
.size());
1508 CalcDrawProps(&render_surface_layer_list
);
1509 layer
->draw_properties().drawable_content_rect
= visible_bounds
;
1510 layer
->draw_properties().visible_content_rect
= visible_bounds
;
1512 // If the layer doesn't paint opaque content, then the
1513 // VisibleContentOpaqueRegion should be empty.
1514 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1515 layer
->InvalidateContentRect(content_bounds
);
1516 layer
->SetTexturePriorities(priority_calculator_
);
1517 resource_manager_
->PrioritizeTextures();
1518 layer
->SavePaintProperties();
1519 layer
->Update(queue_
.get(), &occluded
);
1520 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1521 EXPECT_TRUE(opaque_contents
.IsEmpty());
1523 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000, 1);
1524 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1526 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
1527 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1529 // VisibleContentOpaqueRegion should match the visible part of what is painted
1531 opaque_paint_rect
= gfx::Rect(10, 10, 90, 190);
1532 layer
->fake_layer_updater()->SetOpaquePaintRect(opaque_paint_rect
);
1533 layer
->InvalidateContentRect(content_bounds
);
1534 layer
->SetTexturePriorities(priority_calculator_
);
1535 resource_manager_
->PrioritizeTextures();
1536 layer
->SavePaintProperties();
1537 layer
->Update(queue_
.get(), &occluded
);
1539 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1540 EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect
, visible_bounds
).ToString(),
1541 opaque_contents
.ToString());
1543 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
1544 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1545 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1546 20000 + 20000 - 17100,
1548 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1550 // If we paint again without invalidating, the same stuff should be opaque.
1551 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1552 layer
->SetTexturePriorities(priority_calculator_
);
1553 resource_manager_
->PrioritizeTextures();
1554 layer
->SavePaintProperties();
1555 layer
->Update(queue_
.get(), &occluded
);
1557 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1558 EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect
, visible_bounds
).ToString(),
1559 opaque_contents
.ToString());
1561 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
1562 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1563 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1564 20000 + 20000 - 17100,
1566 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1568 // If we repaint a non-opaque part of the tile, then it shouldn't lose its
1569 // opaque-ness. And other tiles should not be affected.
1570 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1571 layer
->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
1572 layer
->SetTexturePriorities(priority_calculator_
);
1573 resource_manager_
->PrioritizeTextures();
1574 layer
->SavePaintProperties();
1575 layer
->Update(queue_
.get(), &occluded
);
1577 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1578 EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect
, visible_bounds
).ToString(),
1579 opaque_contents
.ToString());
1581 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1, 1);
1582 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1583 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1584 20000 + 20000 - 17100 + 1,
1586 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1588 // If we repaint an opaque part of the tile, then it should lose its
1589 // opaque-ness. But other tiles should still not be affected.
1590 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1591 layer
->InvalidateContentRect(gfx::Rect(10, 10, 1, 1));
1592 layer
->SetTexturePriorities(priority_calculator_
);
1593 resource_manager_
->PrioritizeTextures();
1594 layer
->SavePaintProperties();
1595 layer
->Update(queue_
.get(), &occluded
);
1597 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1598 EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
1599 visible_bounds
).ToString(),
1600 opaque_contents
.ToString());
1603 occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1 + 1, 1);
1604 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1605 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1606 20000 + 20000 - 17100 + 1 + 1,
1608 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1611 TEST_F(TiledLayerTest
, PixelsPaintedMetrics
) {
1612 scoped_refptr
<FakeTiledLayer
> layer
=
1613 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1614 RenderSurfaceLayerList render_surface_layer_list
;
1615 TestOcclusionTracker occluded
;
1616 occlusion_
= &occluded
;
1617 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1619 layer_tree_host_
->root_layer()->AddChild(layer
);
1621 // The tile size is 100x100, so this invalidates and then paints two tiles in
1624 gfx::Rect opaque_paint_rect
;
1625 Region opaque_contents
;
1627 gfx::Rect content_bounds
= gfx::Rect(0, 0, 100, 300);
1628 layer
->SetBounds(content_bounds
.size());
1629 CalcDrawProps(&render_surface_layer_list
);
1631 // Invalidates and paints the whole layer.
1632 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1633 layer
->InvalidateContentRect(content_bounds
);
1634 layer
->SetTexturePriorities(priority_calculator_
);
1635 resource_manager_
->PrioritizeTextures();
1636 layer
->SavePaintProperties();
1637 layer
->Update(queue_
.get(), &occluded
);
1639 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1640 EXPECT_TRUE(opaque_contents
.IsEmpty());
1642 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 30000, 1);
1643 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1645 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 30000, 1);
1646 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1648 // Invalidates an area on the top and bottom tile, which will cause us to
1649 // paint the tile in the middle, even though it is not dirty and will not be
1651 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1652 layer
->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
1653 layer
->InvalidateContentRect(gfx::Rect(50, 200, 10, 10));
1654 layer
->SetTexturePriorities(priority_calculator_
);
1655 resource_manager_
->PrioritizeTextures();
1656 layer
->SavePaintProperties();
1657 layer
->Update(queue_
.get(), &occluded
);
1659 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1660 EXPECT_TRUE(opaque_contents
.IsEmpty());
1662 // The middle tile was painted even though not invalidated.
1664 occluded
.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
1665 // The pixels uploaded will not include the non-invalidated tile in the
1667 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1668 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1671 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1674 TEST_F(TiledLayerTest
, DontAllocateContentsWhenTargetSurfaceCantBeAllocated
) {
1675 // Tile size is 100x100.
1676 gfx::Rect
root_rect(0, 0, 300, 200);
1677 gfx::Rect
child_rect(0, 0, 300, 100);
1678 gfx::Rect
child2_rect(0, 100, 300, 100);
1680 scoped_refptr
<FakeTiledLayer
> root
= make_scoped_refptr(
1681 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1682 scoped_refptr
<Layer
> surface
= Layer::Create();
1683 scoped_refptr
<FakeTiledLayer
> child
= make_scoped_refptr(
1684 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1685 scoped_refptr
<FakeTiledLayer
> child2
= make_scoped_refptr(
1686 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1688 root
->SetBounds(root_rect
.size());
1689 root
->SetAnchorPoint(gfx::PointF());
1690 root
->draw_properties().drawable_content_rect
= root_rect
;
1691 root
->draw_properties().visible_content_rect
= root_rect
;
1692 root
->AddChild(surface
);
1694 surface
->SetForceRenderSurface(true);
1695 surface
->SetAnchorPoint(gfx::PointF());
1696 surface
->SetOpacity(0.5);
1697 surface
->AddChild(child
);
1698 surface
->AddChild(child2
);
1700 child
->SetBounds(child_rect
.size());
1701 child
->SetAnchorPoint(gfx::PointF());
1702 child
->SetPosition(child_rect
.origin());
1703 child
->draw_properties().visible_content_rect
= child_rect
;
1704 child
->draw_properties().drawable_content_rect
= root_rect
;
1706 child2
->SetBounds(child2_rect
.size());
1707 child2
->SetAnchorPoint(gfx::PointF());
1708 child2
->SetPosition(child2_rect
.origin());
1709 child2
->draw_properties().visible_content_rect
= child2_rect
;
1710 child2
->draw_properties().drawable_content_rect
= root_rect
;
1712 layer_tree_host_
->SetRootLayer(root
);
1713 layer_tree_host_
->SetViewportSize(root_rect
.size());
1715 // With a huge memory limit, all layers should update and push their textures.
1716 root
->InvalidateContentRect(root_rect
);
1717 child
->InvalidateContentRect(child_rect
);
1718 child2
->InvalidateContentRect(child2_rect
);
1719 layer_tree_host_
->UpdateLayers(queue_
.get());
1722 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1723 EXPECT_EQ(3, child
->fake_layer_updater()->update_count());
1724 EXPECT_EQ(3, child2
->fake_layer_updater()->update_count());
1725 EXPECT_FALSE(queue_
->HasMoreUpdates());
1727 root
->fake_layer_updater()->ClearUpdateCount();
1728 child
->fake_layer_updater()->ClearUpdateCount();
1729 child2
->fake_layer_updater()->ClearUpdateCount();
1731 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1732 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1733 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1734 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1735 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1736 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1737 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1738 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1739 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1741 for (unsigned i
= 0; i
< 3; ++i
) {
1742 for (unsigned j
= 0; j
< 2; ++j
)
1743 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1744 EXPECT_TRUE(child_impl
->HasResourceIdForTileAt(i
, 0));
1745 EXPECT_TRUE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1748 layer_tree_host_
->CommitComplete();
1750 // With a memory limit that includes only the root layer (3x2 tiles) and half
1751 // the surface that the child layers draw into, the child layers will not be
1752 // allocated. If the surface isn't accounted for, then one of the children
1753 // would fit within the memory limit.
1754 root
->InvalidateContentRect(root_rect
);
1755 child
->InvalidateContentRect(child_rect
);
1756 child2
->InvalidateContentRect(child2_rect
);
1758 size_t memory_limit
= (3 * 2 + 3 * 1) * (100 * 100) * 4;
1759 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1761 layer_tree_host_
->UpdateLayers(queue_
.get());
1764 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1765 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1766 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1767 EXPECT_FALSE(queue_
->HasMoreUpdates());
1769 root
->fake_layer_updater()->ClearUpdateCount();
1770 child
->fake_layer_updater()->ClearUpdateCount();
1771 child2
->fake_layer_updater()->ClearUpdateCount();
1773 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1774 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1775 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1776 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1777 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1778 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1779 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1780 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1781 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1783 for (unsigned i
= 0; i
< 3; ++i
) {
1784 for (unsigned j
= 0; j
< 2; ++j
)
1785 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1786 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1787 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1790 layer_tree_host_
->CommitComplete();
1792 // With a memory limit that includes only half the root layer, no contents
1793 // will be allocated. If render surface memory wasn't accounted for, there is
1794 // enough space for one of the children layers, but they draw into a surface
1795 // that can't be allocated.
1796 root
->InvalidateContentRect(root_rect
);
1797 child
->InvalidateContentRect(child_rect
);
1798 child2
->InvalidateContentRect(child2_rect
);
1800 memory_limit
= (3 * 1) * (100 * 100) * 4;
1801 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1803 layer_tree_host_
->UpdateLayers(queue_
.get());
1806 EXPECT_EQ(0, root
->fake_layer_updater()->update_count());
1807 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1808 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1809 EXPECT_FALSE(queue_
->HasMoreUpdates());
1811 root
->fake_layer_updater()->ClearUpdateCount();
1812 child
->fake_layer_updater()->ClearUpdateCount();
1813 child2
->fake_layer_updater()->ClearUpdateCount();
1815 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1816 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1817 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1818 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1819 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1820 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1821 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1822 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1823 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1825 for (unsigned i
= 0; i
< 3; ++i
) {
1826 for (unsigned j
= 0; j
< 2; ++j
)
1827 EXPECT_FALSE(root_impl
->HasResourceIdForTileAt(i
, j
));
1828 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1829 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1832 layer_tree_host_
->CommitComplete();
1834 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1835 resource_provider_
.get());
1836 layer_tree_host_
->SetRootLayer(NULL
);
1839 class TrackingLayerPainter
: public LayerPainter
{
1841 static scoped_ptr
<TrackingLayerPainter
> Create() {
1842 return make_scoped_ptr(new TrackingLayerPainter());
1845 virtual void Paint(SkCanvas
* canvas
,
1846 const gfx::Rect
& content_rect
,
1847 gfx::RectF
* opaque
) OVERRIDE
{
1848 painted_rect_
= content_rect
;
1851 gfx::Rect
PaintedRect() const { return painted_rect_
; }
1852 void ResetPaintedRect() { painted_rect_
= gfx::Rect(); }
1855 gfx::Rect painted_rect_
;
1858 class UpdateTrackingTiledLayer
: public FakeTiledLayer
{
1860 explicit UpdateTrackingTiledLayer(PrioritizedResourceManager
* manager
)
1861 : FakeTiledLayer(manager
) {
1862 scoped_ptr
<TrackingLayerPainter
> painter(TrackingLayerPainter::Create());
1863 tracking_layer_painter_
= painter
.get();
1865 BitmapContentLayerUpdater::Create(painter
.PassAs
<LayerPainter
>(),
1866 &stats_instrumentation_
,
1870 TrackingLayerPainter
* tracking_layer_painter() const {
1871 return tracking_layer_painter_
;
1875 virtual LayerUpdater
* Updater() const OVERRIDE
{
1876 return layer_updater_
.get();
1878 virtual ~UpdateTrackingTiledLayer() {}
1880 TrackingLayerPainter
* tracking_layer_painter_
;
1881 scoped_refptr
<BitmapContentLayerUpdater
> layer_updater_
;
1882 FakeRenderingStatsInstrumentation stats_instrumentation_
;
1885 TEST_F(TiledLayerTest
, NonIntegerContentsScaleIsNotDistortedDuringPaint
) {
1886 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1887 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1889 layer_tree_host_
->root_layer()->AddChild(layer
);
1891 gfx::Rect
layer_rect(0, 0, 30, 31);
1892 layer
->SetPosition(layer_rect
.origin());
1893 layer
->SetBounds(layer_rect
.size());
1894 layer
->UpdateContentsScale(1.5f
);
1896 gfx::Rect
content_rect(0, 0, 45, 47);
1897 EXPECT_EQ(content_rect
.size(), layer
->content_bounds());
1898 layer
->draw_properties().visible_content_rect
= content_rect
;
1899 layer
->draw_properties().drawable_content_rect
= content_rect
;
1901 layer
->SetTexturePriorities(priority_calculator_
);
1902 resource_manager_
->PrioritizeTextures();
1903 layer
->SavePaintProperties();
1905 // Update the whole tile.
1906 layer
->Update(queue_
.get(), NULL
);
1907 layer
->tracking_layer_painter()->ResetPaintedRect();
1909 EXPECT_RECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1912 // Invalidate the entire layer in content space. When painting, the rect given
1913 // to webkit should match the layer's bounds.
1914 layer
->InvalidateContentRect(content_rect
);
1915 layer
->Update(queue_
.get(), NULL
);
1917 EXPECT_RECT_EQ(layer_rect
, layer
->tracking_layer_painter()->PaintedRect());
1920 TEST_F(TiledLayerTest
,
1921 NonIntegerContentsScaleIsNotDistortedDuringInvalidation
) {
1922 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1923 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1925 layer_tree_host_
->root_layer()->AddChild(layer
);
1927 gfx::Rect
layer_rect(0, 0, 30, 31);
1928 layer
->SetPosition(layer_rect
.origin());
1929 layer
->SetBounds(layer_rect
.size());
1930 layer
->UpdateContentsScale(1.3f
);
1932 gfx::Rect
content_rect(layer
->content_bounds());
1933 layer
->draw_properties().visible_content_rect
= content_rect
;
1934 layer
->draw_properties().drawable_content_rect
= content_rect
;
1936 layer
->SetTexturePriorities(priority_calculator_
);
1937 resource_manager_
->PrioritizeTextures();
1938 layer
->SavePaintProperties();
1940 // Update the whole tile.
1941 layer
->Update(queue_
.get(), NULL
);
1942 layer
->tracking_layer_painter()->ResetPaintedRect();
1944 EXPECT_RECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1947 // Invalidate the entire layer in layer space. When painting, the rect given
1948 // to webkit should match the layer's bounds.
1949 layer
->SetNeedsDisplayRect(layer_rect
);
1950 layer
->Update(queue_
.get(), NULL
);
1952 EXPECT_RECT_EQ(layer_rect
, layer
->tracking_layer_painter()->PaintedRect());