1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/layers/tiled_layer.h"
10 #include "base/run_loop.h"
11 #include "cc/debug/overdraw_metrics.h"
12 #include "cc/resources/bitmap_content_layer_updater.h"
13 #include "cc/resources/layer_painter.h"
14 #include "cc/resources/prioritized_resource_manager.h"
15 #include "cc/resources/resource_update_controller.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_layer_tree_host_client.h"
18 #include "cc/test/fake_layer_tree_host_impl.h"
19 #include "cc/test/fake_output_surface.h"
20 #include "cc/test/fake_output_surface_client.h"
21 #include "cc/test/fake_proxy.h"
22 #include "cc/test/fake_rendering_stats_instrumentation.h"
23 #include "cc/test/geometry_test_utils.h"
24 #include "cc/test/tiled_layer_test_common.h"
25 #include "cc/trees/single_thread_proxy.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/gfx/rect_conversions.h"
28 #include "ui/gfx/transform.h"
33 class TestOcclusionTracker
: public OcclusionTracker
{
35 TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000), true) {
36 stack_
.push_back(StackObject());
39 void SetRenderTarget(Layer
* render_target
) {
40 stack_
.back().target
= render_target
;
43 void SetOcclusion(const Region
& occlusion
) {
44 stack_
.back().occlusion_from_inside_target
= occlusion
;
48 class SynchronousOutputSurfaceLayerTreeHost
: public LayerTreeHost
{
50 static scoped_ptr
<SynchronousOutputSurfaceLayerTreeHost
> Create(
51 LayerTreeHostClient
* client
,
52 SharedBitmapManager
* manager
,
53 const LayerTreeSettings
& settings
,
54 scoped_refptr
<base::SingleThreadTaskRunner
> impl_task_runner
) {
55 return make_scoped_ptr(new SynchronousOutputSurfaceLayerTreeHost(
56 client
, manager
, settings
, impl_task_runner
));
59 virtual ~SynchronousOutputSurfaceLayerTreeHost() {}
61 bool EnsureOutputSurfaceCreated() {
62 base::MessageLoop::current()->PostDelayedTask(
64 run_loop_
.QuitClosure(),
65 base::TimeDelta::FromSeconds(5));
67 return output_surface_created_
;
70 virtual CreateResult
OnCreateAndInitializeOutputSurfaceAttempted(
71 bool success
) OVERRIDE
{
73 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(success
);
74 output_surface_created_
= success
;
80 SynchronousOutputSurfaceLayerTreeHost(
81 LayerTreeHostClient
* client
,
82 SharedBitmapManager
* manager
,
83 const LayerTreeSettings
& settings
,
84 scoped_refptr
<base::SingleThreadTaskRunner
> impl_task_runner
)
85 : LayerTreeHost(client
, manager
, settings
),
86 output_surface_created_(false) {
87 LayerTreeHost::InitializeThreaded(impl_task_runner
);
90 bool output_surface_created_
;
91 base::RunLoop run_loop_
;
94 class TiledLayerTest
: public testing::Test
{
98 output_surface_(FakeOutputSurface::Create3d()),
99 queue_(make_scoped_ptr(new ResourceUpdateQueue
)),
100 impl_thread_("ImplThread"),
101 fake_layer_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D
),
103 settings_
.max_partial_texture_updates
= std::numeric_limits
<size_t>::max();
104 settings_
.layer_transforms_should_scale_layer_contents
= true;
107 virtual void SetUp() {
108 impl_thread_
.Start();
109 layer_tree_host_
= SynchronousOutputSurfaceLayerTreeHost::Create(
110 &fake_layer_tree_host_client_
,
113 impl_thread_
.message_loop_proxy());
114 proxy_
= layer_tree_host_
->proxy();
115 resource_manager_
= PrioritizedResourceManager::Create(proxy_
);
116 layer_tree_host_
->SetLayerTreeHostClientReady();
117 CHECK(layer_tree_host_
->EnsureOutputSurfaceCreated());
118 layer_tree_host_
->SetRootLayer(Layer::Create());
120 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
122 DebugScopedSetImplThreadAndMainThreadBlocked
123 impl_thread_and_main_thread_blocked(proxy_
);
125 ResourceProvider::Create(output_surface_
.get(), NULL
, 0, false, 1);
126 host_impl_
= make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_
));
129 virtual ~TiledLayerTest() {
130 ResourceManagerClearAllMemory(resource_manager_
.get(),
131 resource_provider_
.get());
133 DebugScopedSetImplThreadAndMainThreadBlocked
134 impl_thread_and_main_thread_blocked(proxy_
);
135 resource_provider_
.reset();
139 void ResourceManagerClearAllMemory(
140 PrioritizedResourceManager
* resource_manager
,
141 ResourceProvider
* resource_provider
) {
143 DebugScopedSetImplThreadAndMainThreadBlocked
144 impl_thread_and_main_thread_blocked(proxy_
);
145 resource_manager
->ClearAllMemory(resource_provider
);
146 resource_manager
->ReduceMemory(resource_provider
);
148 resource_manager
->UnlinkAndClearEvictedBackings();
151 void UpdateTextures() {
152 DebugScopedSetImplThreadAndMainThreadBlocked
153 impl_thread_and_main_thread_blocked(proxy_
);
155 scoped_ptr
<ResourceUpdateController
> update_controller
=
156 ResourceUpdateController::Create(NULL
,
157 proxy_
->ImplThreadTaskRunner(),
159 resource_provider_
.get());
160 update_controller
->Finalize();
161 queue_
= make_scoped_ptr(new ResourceUpdateQueue
);
164 void LayerPushPropertiesTo(FakeTiledLayer
* layer
,
165 FakeTiledLayerImpl
* layer_impl
) {
166 DebugScopedSetImplThreadAndMainThreadBlocked
167 impl_thread_and_main_thread_blocked(proxy_
);
168 layer
->PushPropertiesTo(layer_impl
);
169 layer
->ResetNumDependentsNeedPushProperties();
172 void LayerUpdate(FakeTiledLayer
* layer
, TestOcclusionTracker
* occluded
) {
173 DebugScopedSetMainThread
main_thread(proxy_
);
174 layer
->Update(queue_
.get(), occluded
);
177 void CalcDrawProps(RenderSurfaceLayerList
* render_surface_layer_list
) {
179 occlusion_
->SetRenderTarget(layer_tree_host_
->root_layer());
181 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
182 layer_tree_host_
->root_layer(),
183 layer_tree_host_
->device_viewport_size(),
184 render_surface_layer_list
);
185 inputs
.device_scale_factor
= layer_tree_host_
->device_scale_factor();
186 inputs
.max_texture_size
=
187 layer_tree_host_
->GetRendererCapabilities().max_texture_size
;
188 inputs
.can_adjust_raster_scales
= true;
189 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
192 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
193 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
) {
194 scoped_refptr
<FakeTiledLayer
> layer2
;
195 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
;
196 return UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
199 bool UpdateAndPush(const scoped_refptr
<FakeTiledLayer
>& layer1
,
200 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl1
,
201 const scoped_refptr
<FakeTiledLayer
>& layer2
,
202 const scoped_ptr
<FakeTiledLayerImpl
>& layer_impl2
) {
204 resource_manager_
->ClearPriorities();
206 layer1
->SetTexturePriorities(priority_calculator_
);
208 layer2
->SetTexturePriorities(priority_calculator_
);
209 resource_manager_
->PrioritizeTextures();
211 // Save paint properties
213 layer1
->SavePaintProperties();
215 layer2
->SavePaintProperties();
219 layer1
->Update(queue_
.get(), occlusion_
);
221 layer2
->Update(queue_
.get(), occlusion_
);
223 bool needs_update
= false;
225 needs_update
|= layer1
->NeedsIdlePaint();
227 needs_update
|= layer2
->NeedsIdlePaint();
229 // Update textures and push.
232 LayerPushPropertiesTo(layer1
.get(), layer_impl1
.get());
234 LayerPushPropertiesTo(layer2
.get(), layer_impl2
.get());
241 LayerTreeSettings settings_
;
242 FakeOutputSurfaceClient output_surface_client_
;
243 scoped_ptr
<OutputSurface
> output_surface_
;
244 scoped_ptr
<ResourceProvider
> resource_provider_
;
245 scoped_ptr
<ResourceUpdateQueue
> queue_
;
246 PriorityCalculator priority_calculator_
;
247 base::Thread impl_thread_
;
248 FakeLayerTreeHostClient fake_layer_tree_host_client_
;
249 scoped_ptr
<SynchronousOutputSurfaceLayerTreeHost
> layer_tree_host_
;
250 scoped_ptr
<FakeLayerTreeHostImpl
> host_impl_
;
251 scoped_ptr
<PrioritizedResourceManager
> resource_manager_
;
252 TestOcclusionTracker
* occlusion_
;
255 TEST_F(TiledLayerTest
, PushDirtyTiles
) {
256 scoped_refptr
<FakeTiledLayer
> layer
=
257 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
258 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
259 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
260 RenderSurfaceLayerList render_surface_layer_list
;
262 layer_tree_host_
->root_layer()->AddChild(layer
);
264 // The tile size is 100x100, so this invalidates and then paints two tiles.
265 layer
->SetBounds(gfx::Size(100, 200));
266 CalcDrawProps(&render_surface_layer_list
);
267 UpdateAndPush(layer
, layer_impl
);
269 // We should have both tiles on the impl side.
270 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
271 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
273 // Invalidates both tiles, but then only update one of them.
274 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
275 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
276 UpdateAndPush(layer
, layer_impl
);
278 // We should only have the first tile since the other tile was invalidated but
280 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
281 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
284 TEST_F(TiledLayerTest
, PushOccludedDirtyTiles
) {
285 scoped_refptr
<FakeTiledLayer
> layer
=
286 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
287 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
288 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
289 TestOcclusionTracker occluded
;
290 occlusion_
= &occluded
;
291 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
293 layer_tree_host_
->root_layer()->AddChild(layer
);
296 RenderSurfaceLayerList render_surface_layer_list
;
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 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
305 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
306 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
308 // We should have both tiles on the impl side.
309 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
310 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
314 RenderSurfaceLayerList render_surface_layer_list
;
316 // Invalidates part of the top tile...
317 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
318 // ....but the area is occluded.
319 occluded
.SetOcclusion(gfx::Rect(0, 0, 50, 50));
320 CalcDrawProps(&render_surface_layer_list
);
321 UpdateAndPush(layer
, layer_impl
);
323 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
324 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
327 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
329 // We should still have both tiles, as part of the top tile is still
331 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
332 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
336 TEST_F(TiledLayerTest
, PushDeletedTiles
) {
337 scoped_refptr
<FakeTiledLayer
> layer
=
338 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
339 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
340 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
341 RenderSurfaceLayerList render_surface_layer_list
;
343 layer_tree_host_
->root_layer()->AddChild(layer
);
345 // The tile size is 100x100, so this invalidates and then paints two tiles.
346 layer
->SetBounds(gfx::Size(100, 200));
347 CalcDrawProps(&render_surface_layer_list
);
348 UpdateAndPush(layer
, layer_impl
);
350 // We should have both tiles on the impl side.
351 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
352 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
354 resource_manager_
->ClearPriorities();
355 ResourceManagerClearAllMemory(resource_manager_
.get(),
356 resource_provider_
.get());
357 resource_manager_
->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
359 // This should drop the tiles on the impl thread.
360 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
362 // We should now have no textures on the impl thread.
363 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
364 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
366 // This should recreate and update one of the deleted textures.
367 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
368 UpdateAndPush(layer
, layer_impl
);
370 // We should have one tiles on the impl side.
371 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
372 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
375 TEST_F(TiledLayerTest
, PushIdlePaintTiles
) {
376 scoped_refptr
<FakeTiledLayer
> layer
=
377 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
378 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
379 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
380 RenderSurfaceLayerList render_surface_layer_list
;
382 layer_tree_host_
->root_layer()->AddChild(layer
);
384 // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
385 // center. This paints 1 visible of the 25 invalid tiles.
386 layer
->SetBounds(gfx::Size(500, 500));
387 CalcDrawProps(&render_surface_layer_list
);
388 layer
->draw_properties().visible_content_rect
= gfx::Rect(200, 200, 100, 100);
389 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
390 // We should need idle-painting for surrounding tiles.
391 EXPECT_TRUE(needs_update
);
393 // We should have one tile on the impl side.
394 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(2, 2));
396 // For the next four updates, we should detect we still need idle painting.
397 for (int i
= 0; i
< 4; i
++) {
398 needs_update
= UpdateAndPush(layer
, layer_impl
);
399 EXPECT_TRUE(needs_update
);
402 // We should always finish painting eventually.
403 for (int i
= 0; i
< 20; i
++)
404 needs_update
= UpdateAndPush(layer
, layer_impl
);
406 // We should have pre-painted all of the surrounding tiles.
407 for (int i
= 0; i
< 5; i
++) {
408 for (int j
= 0; j
< 5; j
++)
409 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
412 EXPECT_FALSE(needs_update
);
415 TEST_F(TiledLayerTest
, PredictivePainting
) {
416 scoped_refptr
<FakeTiledLayer
> layer
=
417 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
418 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
419 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
421 layer_tree_host_
->root_layer()->AddChild(layer
);
423 // Prepainting should occur in the scroll direction first, and the
424 // visible rect should be extruded only along the dominant axis.
425 gfx::Vector2d directions
[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
426 gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
427 gfx::Vector2d(10, 20),
428 gfx::Vector2d(-20, 10) };
429 // We should push all tiles that touch the extruded visible rect.
430 gfx::Rect pushed_visible_tiles
[6] = {
431 gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
432 gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
434 // The first pre-paint should also paint first in the scroll
435 // direction so we should find one additional tile in the scroll direction.
436 gfx::Rect pushed_prepaint_tiles
[6] = {
437 gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
438 gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
440 for (int k
= 0; k
< 6; k
++) {
441 // The tile size is 100x100. Setup 5x5 tiles with one visible tile
443 gfx::Size bounds
= gfx::Size(500, 500);
444 gfx::Rect visible_rect
= gfx::Rect(200, 200, 100, 100);
445 gfx::Rect previous_visible_rect
=
446 gfx::Rect(visible_rect
.origin() + directions
[k
], visible_rect
.size());
447 gfx::Rect next_visible_rect
=
448 gfx::Rect(visible_rect
.origin() - directions
[k
], visible_rect
.size());
450 // Setup. Use the previous_visible_rect to setup the prediction for next
452 layer
->SetBounds(bounds
);
454 RenderSurfaceLayerList render_surface_layer_list
;
455 CalcDrawProps(&render_surface_layer_list
);
456 layer
->draw_properties().visible_content_rect
= previous_visible_rect
;
457 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
459 // Invalidate and move the visible_rect in the scroll direction.
460 // Check that the correct tiles have been painted in the visible pass.
461 layer
->SetNeedsDisplay();
462 layer
->draw_properties().visible_content_rect
= visible_rect
;
463 needs_update
= UpdateAndPush(layer
, layer_impl
);
464 for (int i
= 0; i
< 5; i
++) {
465 for (int j
= 0; j
< 5; j
++)
466 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
467 pushed_visible_tiles
[k
].Contains(i
, j
));
470 // Move the transform in the same direction without invalidating.
471 // Check that non-visible pre-painting occured in the correct direction.
472 // Ignore diagonal scrolls here (k > 3) as these have new visible content
475 layer
->draw_properties().visible_content_rect
= next_visible_rect
;
476 needs_update
= UpdateAndPush(layer
, layer_impl
);
477 for (int i
= 0; i
< 5; i
++) {
478 for (int j
= 0; j
< 5; j
++)
479 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
),
480 pushed_prepaint_tiles
[k
].Contains(i
, j
));
484 // We should always finish painting eventually.
485 for (int i
= 0; i
< 20; i
++)
486 needs_update
= UpdateAndPush(layer
, layer_impl
);
487 EXPECT_FALSE(needs_update
);
491 TEST_F(TiledLayerTest
, PushTilesAfterIdlePaintFailed
) {
492 // Start with 2mb of memory, but the test is going to try to use just more
493 // than 1mb, so we reduce to 1mb later.
494 resource_manager_
->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
495 scoped_refptr
<FakeTiledLayer
> layer1
=
496 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
497 scoped_ptr
<FakeTiledLayerImpl
> layer_impl1
=
498 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
499 scoped_refptr
<FakeTiledLayer
> layer2
=
500 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
501 scoped_ptr
<FakeTiledLayerImpl
> layer_impl2
=
502 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
503 RenderSurfaceLayerList render_surface_layer_list
;
505 layer_tree_host_
->root_layer()->AddChild(layer1
);
506 layer_tree_host_
->root_layer()->AddChild(layer2
);
508 // For this test we have two layers. layer1 exhausts most texture memory,
509 // leaving room for 2 more tiles from layer2, but not all three tiles. First
510 // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
511 // we will fail on the third tile of layer2, and this should not leave the
512 // second tile in a bad state.
514 // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
515 // for 2 tiles only in the other layer.
516 gfx::Rect
layer1_rect(0, 0, 100, 2400);
518 // This requires 4*30000 bytes of memory.
519 gfx::Rect
layer2_rect(0, 0, 100, 300);
521 // Paint a single tile in layer2 so that it will idle paint.
522 layer1
->SetBounds(layer1_rect
.size());
523 layer2
->SetBounds(layer2_rect
.size());
524 CalcDrawProps(&render_surface_layer_list
);
525 layer1
->draw_properties().visible_content_rect
= layer1_rect
;
526 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
527 bool needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
528 // We should need idle-painting for both remaining tiles in layer2.
529 EXPECT_TRUE(needs_update
);
531 // Reduce our memory limits to 1mb.
532 resource_manager_
->SetMaxMemoryLimitBytes(1024 * 1024);
534 // Now idle paint layer2. We are going to run out of memory though!
535 // Oh well, commit the frame and push.
536 for (int i
= 0; i
< 4; i
++) {
537 needs_update
= UpdateAndPush(layer1
, layer_impl1
, layer2
, layer_impl2
);
540 // Sanity check, we should have textures for the big layer.
541 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 0));
542 EXPECT_TRUE(layer_impl1
->HasResourceIdForTileAt(0, 23));
544 // We should only have the first two tiles from layer2 since
545 // it failed to idle update the last tile.
546 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
547 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 0));
548 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
549 EXPECT_TRUE(layer_impl2
->HasResourceIdForTileAt(0, 1));
551 EXPECT_FALSE(needs_update
);
552 EXPECT_FALSE(layer_impl2
->HasResourceIdForTileAt(0, 2));
555 TEST_F(TiledLayerTest
, PushIdlePaintedOccludedTiles
) {
556 scoped_refptr
<FakeTiledLayer
> layer
=
557 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
558 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
559 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
560 RenderSurfaceLayerList render_surface_layer_list
;
561 TestOcclusionTracker occluded
;
562 occlusion_
= &occluded
;
564 layer_tree_host_
->root_layer()->AddChild(layer
);
566 // The tile size is 100x100, so this invalidates one occluded tile, culls it
567 // during paint, but prepaints it.
568 occluded
.SetOcclusion(gfx::Rect(0, 0, 100, 100));
570 layer
->SetBounds(gfx::Size(100, 100));
571 CalcDrawProps(&render_surface_layer_list
);
572 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
573 UpdateAndPush(layer
, layer_impl
);
575 // We should have the prepainted tile on the impl side, but culled it during
577 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
578 EXPECT_EQ(1, occluded
.overdraw_metrics()->tiles_culled_for_upload());
581 TEST_F(TiledLayerTest
, PushTilesMarkedDirtyDuringPaint
) {
582 scoped_refptr
<FakeTiledLayer
> layer
=
583 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
584 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
585 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
586 RenderSurfaceLayerList render_surface_layer_list
;
588 layer_tree_host_
->root_layer()->AddChild(layer
);
590 // The tile size is 100x100, so this invalidates and then paints two tiles.
591 // However, during the paint, we invalidate one of the tiles. This should
592 // not prevent the tile from being pushed.
593 layer
->fake_layer_updater()->SetRectToInvalidate(
594 gfx::Rect(0, 50, 100, 50), layer
.get());
595 layer
->SetBounds(gfx::Size(100, 200));
596 CalcDrawProps(&render_surface_layer_list
);
597 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
598 UpdateAndPush(layer
, layer_impl
);
600 // We should have both tiles on the impl side.
601 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
602 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
605 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer
) {
606 scoped_refptr
<FakeTiledLayer
> layer1
=
607 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
608 scoped_refptr
<FakeTiledLayer
> layer2
=
609 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
610 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
611 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
612 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
613 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
614 RenderSurfaceLayerList render_surface_layer_list
;
616 layer_tree_host_
->root_layer()->AddChild(layer1
);
617 layer_tree_host_
->root_layer()->AddChild(layer2
);
619 // Invalidate a tile on layer1, during update of layer 2.
620 layer2
->fake_layer_updater()->SetRectToInvalidate(
621 gfx::Rect(0, 50, 100, 50), layer1
.get());
622 layer1
->SetBounds(gfx::Size(100, 200));
623 layer2
->SetBounds(gfx::Size(100, 200));
624 CalcDrawProps(&render_surface_layer_list
);
625 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
626 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
627 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
629 // We should have both tiles on the impl side for all layers.
630 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
631 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
632 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
633 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
636 TEST_F(TiledLayerTest
, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
) {
637 scoped_refptr
<FakeTiledLayer
> layer1
=
638 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
639 scoped_refptr
<FakeTiledLayer
> layer2
=
640 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
641 scoped_ptr
<FakeTiledLayerImpl
> layer1_impl
=
642 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
643 scoped_ptr
<FakeTiledLayerImpl
> layer2_impl
=
644 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 2));
645 RenderSurfaceLayerList render_surface_layer_list
;
647 layer_tree_host_
->root_layer()->AddChild(layer1
);
648 layer_tree_host_
->root_layer()->AddChild(layer2
);
650 layer1
->fake_layer_updater()->SetRectToInvalidate(
651 gfx::Rect(0, 50, 100, 50), layer2
.get());
652 layer1
->SetBounds(gfx::Size(100, 200));
653 layer2
->SetBounds(gfx::Size(100, 200));
654 CalcDrawProps(&render_surface_layer_list
);
655 layer1
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
656 layer2
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
657 UpdateAndPush(layer1
, layer1_impl
, layer2
, layer2_impl
);
659 // We should have both tiles on the impl side for all layers.
660 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 0));
661 EXPECT_TRUE(layer1_impl
->HasResourceIdForTileAt(0, 1));
662 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 0));
663 EXPECT_TRUE(layer2_impl
->HasResourceIdForTileAt(0, 1));
666 TEST_F(TiledLayerTest
, PaintSmallAnimatedLayersImmediately
) {
667 // Create a LayerTreeHost that has the right viewportsize,
668 // so the layer is considered small enough.
669 bool run_out_of_memory
[2] = { false, true };
670 for (int i
= 0; i
< 2; i
++) {
671 // Create a layer with 5x5 tiles, with 4x4 size viewport.
672 int viewport_width
= 4 * FakeTiledLayer::tile_size().width();
673 int viewport_height
= 4 * FakeTiledLayer::tile_size().width();
674 int layer_width
= 5 * FakeTiledLayer::tile_size().width();
675 int layer_height
= 5 * FakeTiledLayer::tile_size().height();
676 int memory_for_layer
= layer_width
* layer_height
* 4;
677 layer_tree_host_
->SetViewportSize(
678 gfx::Size(viewport_width
, viewport_height
));
680 // Use 10x5 tiles to run out of memory.
681 if (run_out_of_memory
[i
])
684 resource_manager_
->SetMaxMemoryLimitBytes(memory_for_layer
);
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 // Full size layer with half being visible.
695 layer
->SetBounds(gfx::Size(layer_width
, layer_height
));
696 gfx::Rect
visible_rect(0, 0, layer_width
/ 2, layer_height
);
697 CalcDrawProps(&render_surface_layer_list
);
699 // Pretend the layer is animating.
700 layer
->draw_properties().target_space_transform_is_animating
= true;
701 layer
->draw_properties().visible_content_rect
= visible_rect
;
702 layer
->SetLayerTreeHost(layer_tree_host_
.get());
704 // The layer should paint its entire contents on the first paint
705 // if it is close to the viewport size and has the available memory.
706 layer
->SetTexturePriorities(priority_calculator_
);
707 resource_manager_
->PrioritizeTextures();
708 layer
->SavePaintProperties();
709 layer
->Update(queue_
.get(), NULL
);
711 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
713 // We should have all the tiles for the small animated layer.
714 // We should still have the visible tiles when we didn't
715 // have enough memory for all the tiles.
716 if (!run_out_of_memory
[i
]) {
717 for (int i
= 0; i
< 5; ++i
) {
718 for (int j
= 0; j
< 5; ++j
)
719 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(i
, j
));
722 for (int i
= 0; i
< 10; ++i
) {
723 for (int j
= 0; j
< 5; ++j
)
724 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(i
, j
), i
< 5);
728 layer
->RemoveFromParent();
732 TEST_F(TiledLayerTest
, IdlePaintOutOfMemory
) {
733 scoped_refptr
<FakeTiledLayer
> layer
=
734 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
735 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
736 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
737 RenderSurfaceLayerList render_surface_layer_list
;
739 layer_tree_host_
->root_layer()->AddChild(layer
);
741 // We have enough memory for only the visible rect, so we will run out of
742 // memory in first idle paint.
743 int memory_limit
= 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
744 resource_manager_
->SetMaxMemoryLimitBytes(memory_limit
);
746 // The tile size is 100x100, so this invalidates and then paints two tiles.
747 bool needs_update
= false;
748 layer
->SetBounds(gfx::Size(300, 300));
749 CalcDrawProps(&render_surface_layer_list
);
750 layer
->draw_properties().visible_content_rect
= gfx::Rect(100, 100, 100, 100);
751 for (int i
= 0; i
< 2; i
++)
752 needs_update
= UpdateAndPush(layer
, layer_impl
);
754 // Idle-painting should see no more priority tiles for painting.
755 EXPECT_FALSE(needs_update
);
757 // We should have one tile on the impl side.
758 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
761 TEST_F(TiledLayerTest
, IdlePaintZeroSizedLayer
) {
762 scoped_refptr
<FakeTiledLayer
> layer
=
763 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
764 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
765 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
767 layer_tree_host_
->root_layer()->AddChild(layer
);
769 bool animating
[2] = { false, true };
770 for (int i
= 0; i
< 2; i
++) {
771 // Pretend the layer is animating.
772 layer
->draw_properties().target_space_transform_is_animating
= animating
[i
];
774 // The layer's bounds are empty.
775 // Empty layers don't paint or idle-paint.
776 layer
->SetBounds(gfx::Size());
778 RenderSurfaceLayerList render_surface_layer_list
;
779 CalcDrawProps(&render_surface_layer_list
);
780 layer
->draw_properties().visible_content_rect
= gfx::Rect();
781 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
783 // Empty layers don't have tiles.
784 EXPECT_EQ(0u, layer
->NumPaintedTiles());
786 // Empty layers don't need prepaint.
787 EXPECT_FALSE(needs_update
);
789 // Empty layers don't have tiles.
790 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
794 TEST_F(TiledLayerTest
, IdlePaintNonVisibleLayers
) {
795 scoped_refptr
<FakeTiledLayer
> layer
=
796 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
797 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
798 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
800 // Alternate between not visible and visible.
801 gfx::Rect
v(0, 0, 100, 100);
802 gfx::Rect
nv(0, 0, 0, 0);
803 gfx::Rect visible_rect
[10] = { nv
, nv
, v
, v
, nv
, nv
, v
, v
, nv
, nv
};
804 bool invalidate
[10] = { true, true, true, true, true, true, true, true, false,
807 // We should not have any tiles except for when the layer was visible
808 // or after the layer was visible and we didn't invalidate.
809 bool have_tile
[10] = { false, false, true, true, false, false, true, true,
812 layer_tree_host_
->root_layer()->AddChild(layer
);
814 for (int i
= 0; i
< 10; i
++) {
815 layer
->SetBounds(gfx::Size(100, 100));
817 RenderSurfaceLayerList render_surface_layer_list
;
818 CalcDrawProps(&render_surface_layer_list
);
819 layer
->draw_properties().visible_content_rect
= visible_rect
[i
];
822 layer
->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
823 bool needs_update
= UpdateAndPush(layer
, layer_impl
);
825 // We should never signal idle paint, as we painted the entire layer
826 // or the layer was not visible.
827 EXPECT_FALSE(needs_update
);
828 EXPECT_EQ(layer_impl
->HasResourceIdForTileAt(0, 0), have_tile
[i
]);
832 TEST_F(TiledLayerTest
, InvalidateFromPrepare
) {
833 scoped_refptr
<FakeTiledLayer
> layer
=
834 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
835 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
836 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
837 RenderSurfaceLayerList render_surface_layer_list
;
839 layer_tree_host_
->root_layer()->AddChild(layer
);
841 // The tile size is 100x100, so this invalidates and then paints two tiles.
842 layer
->SetBounds(gfx::Size(100, 200));
843 CalcDrawProps(&render_surface_layer_list
);
844 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 200);
845 UpdateAndPush(layer
, layer_impl
);
847 // We should have both tiles on the impl side.
848 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
849 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
851 layer
->fake_layer_updater()->ClearPrepareCount();
852 // Invoke update again. As the layer is valid update shouldn't be invoked on
854 UpdateAndPush(layer
, layer_impl
);
855 EXPECT_EQ(0, layer
->fake_layer_updater()->prepare_count());
857 // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
859 layer
->fake_layer_updater()->SetRectToInvalidate(
860 gfx::Rect(25, 25, 50, 50), layer
.get());
861 layer
->fake_layer_updater()->ClearPrepareCount();
862 layer
->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
863 UpdateAndPush(layer
, layer_impl
);
864 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
865 layer
->fake_layer_updater()->ClearPrepareCount();
867 // The layer should still be invalid as update invoked invalidate.
868 UpdateAndPush(layer
, layer_impl
); // visible
869 EXPECT_EQ(1, layer
->fake_layer_updater()->prepare_count());
872 TEST_F(TiledLayerTest
, VerifyUpdateRectWhenContentBoundsAreScaled
) {
873 // The update rect (that indicates what was actually painted) should be in
874 // layer space, not the content space.
875 scoped_refptr
<FakeTiledLayerWithScaledBounds
> layer
= make_scoped_refptr(
876 new FakeTiledLayerWithScaledBounds(resource_manager_
.get()));
878 layer_tree_host_
->root_layer()->AddChild(layer
);
880 gfx::Rect
layer_bounds(0, 0, 300, 200);
881 gfx::Rect
content_bounds(0, 0, 200, 250);
883 layer
->SetBounds(layer_bounds
.size());
884 layer
->SetContentBounds(content_bounds
.size());
885 layer
->draw_properties().visible_content_rect
= content_bounds
;
887 // On first update, the update_rect includes all tiles, even beyond the
888 // boundaries of the layer.
889 // However, it should still be in layer space, not content space.
890 layer
->InvalidateContentRect(content_bounds
);
892 layer
->SetTexturePriorities(priority_calculator_
);
893 resource_manager_
->PrioritizeTextures();
894 layer
->SavePaintProperties();
895 layer
->Update(queue_
.get(), NULL
);
896 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 300, 300 * 0.8), layer
->update_rect());
899 // After the tiles are updated once, another invalidate only needs to update
900 // the bounds of the layer.
901 layer
->SetTexturePriorities(priority_calculator_
);
902 resource_manager_
->PrioritizeTextures();
903 layer
->InvalidateContentRect(content_bounds
);
904 layer
->SavePaintProperties();
905 layer
->Update(queue_
.get(), NULL
);
906 EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds
), layer
->update_rect());
909 // Partial re-paint should also be represented by the update rect in layer
910 // space, not content space.
911 gfx::Rect
partial_damage(30, 100, 10, 10);
912 layer
->InvalidateContentRect(partial_damage
);
913 layer
->SetTexturePriorities(priority_calculator_
);
914 resource_manager_
->PrioritizeTextures();
915 layer
->SavePaintProperties();
916 layer
->Update(queue_
.get(), NULL
);
917 EXPECT_FLOAT_RECT_EQ(gfx::RectF(45, 80, 15, 8), layer
->update_rect());
920 TEST_F(TiledLayerTest
, VerifyInvalidationWhenContentsScaleChanges
) {
921 scoped_refptr
<FakeTiledLayer
> layer
=
922 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
923 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
924 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
925 RenderSurfaceLayerList render_surface_layer_list
;
927 layer_tree_host_
->root_layer()->AddChild(layer
);
929 // Create a layer with one tile.
930 layer
->SetBounds(gfx::Size(100, 100));
931 CalcDrawProps(&render_surface_layer_list
);
932 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 100, 100);
933 layer
->Update(queue_
.get(), NULL
);
935 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
936 layer
->last_needs_display_rect());
938 // Push the tiles to the impl side and check that there is exactly one.
939 layer
->SetTexturePriorities(priority_calculator_
);
940 resource_manager_
->PrioritizeTextures();
941 layer
->SavePaintProperties();
942 layer
->Update(queue_
.get(), NULL
);
944 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
945 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
946 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
947 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
948 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
950 layer
->SetNeedsDisplayRect(gfx::Rect());
951 EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer
->last_needs_display_rect());
953 // Change the contents scale.
954 layer
->UpdateContentsScale(2.f
);
955 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 200, 200);
957 // The impl side should get 2x2 tiles now.
958 layer
->SetTexturePriorities(priority_calculator_
);
959 resource_manager_
->PrioritizeTextures();
960 layer
->SavePaintProperties();
961 layer
->Update(queue_
.get(), NULL
);
963 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
964 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 0));
965 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(0, 1));
966 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 0));
967 EXPECT_TRUE(layer_impl
->HasResourceIdForTileAt(1, 1));
969 // Verify that changing the contents scale caused invalidation, and
970 // that the layer-space rectangle requiring painting is not scaled.
971 EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
972 layer
->last_needs_display_rect());
974 // Invalidate the entire layer again, but do not paint. All tiles should be
975 // gone now from the impl side.
976 layer
->SetNeedsDisplay();
977 layer
->SetTexturePriorities(priority_calculator_
);
978 resource_manager_
->PrioritizeTextures();
980 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
981 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 0));
982 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(0, 1));
983 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 0));
984 EXPECT_FALSE(layer_impl
->HasResourceIdForTileAt(1, 1));
987 TEST_F(TiledLayerTest
, SkipsDrawGetsReset
) {
988 // Create two 300 x 300 tiled layers.
989 gfx::Size
content_bounds(300, 300);
990 gfx::Rect
content_rect(content_bounds
);
992 // We have enough memory for only one of the two layers.
993 int memory_limit
= 4 * 300 * 300; // 4 bytes per pixel.
995 scoped_refptr
<FakeTiledLayer
> root_layer
= make_scoped_refptr(
996 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
997 scoped_refptr
<FakeTiledLayer
> child_layer
= make_scoped_refptr(
998 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
999 root_layer
->AddChild(child_layer
);
1001 root_layer
->SetBounds(content_bounds
);
1002 root_layer
->draw_properties().visible_content_rect
= content_rect
;
1003 root_layer
->SetPosition(gfx::PointF(0, 0));
1004 child_layer
->SetBounds(content_bounds
);
1005 child_layer
->draw_properties().visible_content_rect
= content_rect
;
1006 child_layer
->SetPosition(gfx::PointF(0, 0));
1007 root_layer
->InvalidateContentRect(content_rect
);
1008 child_layer
->InvalidateContentRect(content_rect
);
1010 layer_tree_host_
->SetRootLayer(root_layer
);
1011 layer_tree_host_
->SetViewportSize(gfx::Size(300, 300));
1012 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1015 layer_tree_host_
->UpdateLayers(queue_
.get());
1017 // We'll skip the root layer.
1018 EXPECT_TRUE(root_layer
->SkipsDraw());
1019 EXPECT_FALSE(child_layer
->SkipsDraw());
1021 layer_tree_host_
->CommitComplete();
1023 // Remove the child layer.
1024 root_layer
->RemoveAllChildren();
1026 layer_tree_host_
->UpdateLayers(queue_
.get());
1027 EXPECT_FALSE(root_layer
->SkipsDraw());
1029 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1030 resource_provider_
.get());
1031 layer_tree_host_
->SetRootLayer(NULL
);
1034 TEST_F(TiledLayerTest
, ResizeToSmaller
) {
1035 scoped_refptr
<FakeTiledLayer
> layer
=
1036 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1038 layer_tree_host_
->root_layer()->AddChild(layer
);
1040 layer
->SetBounds(gfx::Size(700, 700));
1041 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1042 layer
->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
1044 layer
->SetTexturePriorities(priority_calculator_
);
1045 resource_manager_
->PrioritizeTextures();
1046 layer
->SavePaintProperties();
1047 layer
->Update(queue_
.get(), NULL
);
1049 layer
->SetBounds(gfx::Size(200, 200));
1050 layer
->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
1053 TEST_F(TiledLayerTest
, HugeLayerUpdateCrash
) {
1054 scoped_refptr
<FakeTiledLayer
> layer
=
1055 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1057 layer_tree_host_
->root_layer()->AddChild(layer
);
1060 layer
->SetBounds(gfx::Size(size
, size
));
1061 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 700, 700);
1062 layer
->InvalidateContentRect(gfx::Rect(0, 0, size
, size
));
1064 // Ensure no crash for bounds where size * size would overflow an int.
1065 layer
->SetTexturePriorities(priority_calculator_
);
1066 resource_manager_
->PrioritizeTextures();
1067 layer
->SavePaintProperties();
1068 layer
->Update(queue_
.get(), NULL
);
1071 class TiledLayerPartialUpdateTest
: public TiledLayerTest
{
1073 TiledLayerPartialUpdateTest() { settings_
.max_partial_texture_updates
= 4; }
1076 TEST_F(TiledLayerPartialUpdateTest
, PartialUpdates
) {
1077 // Create one 300 x 200 tiled layer with 3 x 2 tiles.
1078 gfx::Size
content_bounds(300, 200);
1079 gfx::Rect
content_rect(content_bounds
);
1081 scoped_refptr
<FakeTiledLayer
> layer
= make_scoped_refptr(
1082 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1083 layer
->SetBounds(content_bounds
);
1084 layer
->SetPosition(gfx::PointF(0, 0));
1085 layer
->draw_properties().visible_content_rect
= content_rect
;
1086 layer
->InvalidateContentRect(content_rect
);
1088 layer_tree_host_
->SetRootLayer(layer
);
1089 layer_tree_host_
->SetViewportSize(gfx::Size(300, 200));
1091 // Full update of all 6 tiles.
1092 layer_tree_host_
->UpdateLayers(queue_
.get());
1094 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1095 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1096 EXPECT_EQ(6u, queue_
->FullUploadSize());
1097 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1099 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1100 EXPECT_FALSE(queue_
->HasMoreUpdates());
1101 layer
->fake_layer_updater()->ClearUpdateCount();
1102 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1104 layer_tree_host_
->CommitComplete();
1106 // Full update of 3 tiles and partial update of 3 tiles.
1107 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
1108 layer_tree_host_
->UpdateLayers(queue_
.get());
1110 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1111 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1112 EXPECT_EQ(3u, queue_
->FullUploadSize());
1113 EXPECT_EQ(3u, queue_
->PartialUploadSize());
1115 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1116 EXPECT_FALSE(queue_
->HasMoreUpdates());
1117 layer
->fake_layer_updater()->ClearUpdateCount();
1118 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1120 layer_tree_host_
->CommitComplete();
1122 // Partial update of 6 tiles.
1123 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1125 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1126 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1127 layer_tree_host_
->UpdateLayers(queue_
.get());
1128 EXPECT_EQ(2u, queue_
->FullUploadSize());
1129 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1131 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1132 EXPECT_FALSE(queue_
->HasMoreUpdates());
1133 layer
->fake_layer_updater()->ClearUpdateCount();
1134 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1136 layer_tree_host_
->CommitComplete();
1138 // Checkerboard all tiles.
1139 layer
->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
1141 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1142 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1143 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1145 layer_tree_host_
->CommitComplete();
1147 // Partial update of 6 checkerboard tiles.
1148 layer
->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
1150 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1151 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1152 layer_tree_host_
->UpdateLayers(queue_
.get());
1153 EXPECT_EQ(6u, queue_
->FullUploadSize());
1154 EXPECT_EQ(0u, queue_
->PartialUploadSize());
1156 EXPECT_EQ(6, layer
->fake_layer_updater()->update_count());
1157 EXPECT_FALSE(queue_
->HasMoreUpdates());
1158 layer
->fake_layer_updater()->ClearUpdateCount();
1159 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1161 layer_tree_host_
->CommitComplete();
1163 // Partial update of 4 tiles.
1164 layer
->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
1166 scoped_ptr
<FakeTiledLayerImpl
> layer_impl
=
1167 make_scoped_ptr(new FakeTiledLayerImpl(host_impl_
->active_tree(), 1));
1168 layer_tree_host_
->UpdateLayers(queue_
.get());
1169 EXPECT_EQ(0u, queue_
->FullUploadSize());
1170 EXPECT_EQ(4u, queue_
->PartialUploadSize());
1172 EXPECT_EQ(4, layer
->fake_layer_updater()->update_count());
1173 EXPECT_FALSE(queue_
->HasMoreUpdates());
1174 layer
->fake_layer_updater()->ClearUpdateCount();
1175 LayerPushPropertiesTo(layer
.get(), layer_impl
.get());
1177 layer_tree_host_
->CommitComplete();
1179 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1180 resource_provider_
.get());
1181 layer_tree_host_
->SetRootLayer(NULL
);
1184 TEST_F(TiledLayerTest
, TilesPaintedWithoutOcclusion
) {
1185 scoped_refptr
<FakeTiledLayer
> layer
=
1186 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1187 RenderSurfaceLayerList render_surface_layer_list
;
1189 layer_tree_host_
->root_layer()->AddChild(layer
);
1191 // The tile size is 100x100, so this invalidates and then paints two tiles.
1192 layer
->SetBounds(gfx::Size(100, 200));
1193 CalcDrawProps(&render_surface_layer_list
);
1195 layer
->SetTexturePriorities(priority_calculator_
);
1196 resource_manager_
->PrioritizeTextures();
1197 layer
->SavePaintProperties();
1198 layer
->Update(queue_
.get(), NULL
);
1199 EXPECT_EQ(2, layer
->fake_layer_updater()->update_count());
1202 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusion
) {
1203 scoped_refptr
<FakeTiledLayer
> layer
=
1204 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1205 RenderSurfaceLayerList render_surface_layer_list
;
1206 TestOcclusionTracker occluded
;
1207 occlusion_
= &occluded
;
1209 layer_tree_host_
->root_layer()->AddChild(layer
);
1211 // The tile size is 100x100.
1213 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1214 layer
->SetBounds(gfx::Size(600, 600));
1215 CalcDrawProps(&render_surface_layer_list
);
1217 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 100));
1218 layer
->draw_properties().drawable_content_rect
=
1219 gfx::Rect(layer
->content_bounds());
1220 layer
->draw_properties().visible_content_rect
=
1221 gfx::Rect(layer
->content_bounds());
1222 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1224 layer
->SetTexturePriorities(priority_calculator_
);
1225 resource_manager_
->PrioritizeTextures();
1226 layer
->SavePaintProperties();
1227 layer
->Update(queue_
.get(), &occluded
);
1228 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1230 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1232 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1233 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1235 layer
->fake_layer_updater()->ClearUpdateCount();
1236 layer
->SetTexturePriorities(priority_calculator_
);
1237 resource_manager_
->PrioritizeTextures();
1239 occluded
.SetOcclusion(gfx::Rect(250, 200, 300, 100));
1240 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1241 layer
->SavePaintProperties();
1242 layer
->Update(queue_
.get(), &occluded
);
1243 EXPECT_EQ(36 - 2, layer
->fake_layer_updater()->update_count());
1245 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1246 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1249 EXPECT_EQ(3 + 2, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1251 layer
->fake_layer_updater()->ClearUpdateCount();
1252 layer
->SetTexturePriorities(priority_calculator_
);
1253 resource_manager_
->PrioritizeTextures();
1255 occluded
.SetOcclusion(gfx::Rect(250, 250, 300, 100));
1256 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1257 layer
->SavePaintProperties();
1258 layer
->Update(queue_
.get(), &occluded
);
1259 EXPECT_EQ(36, layer
->fake_layer_updater()->update_count());
1261 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1262 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1263 330000 + 340000 + 360000,
1265 EXPECT_EQ(3 + 2, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1268 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndVisiblityConstraints
) {
1269 scoped_refptr
<FakeTiledLayer
> layer
=
1270 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1271 RenderSurfaceLayerList render_surface_layer_list
;
1272 TestOcclusionTracker occluded
;
1273 occlusion_
= &occluded
;
1275 layer_tree_host_
->root_layer()->AddChild(layer
);
1277 // The tile size is 100x100.
1279 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1280 layer
->SetBounds(gfx::Size(600, 600));
1281 CalcDrawProps(&render_surface_layer_list
);
1283 // The partially occluded tiles (by the 150 occlusion height) are visible
1284 // beyond the occlusion, so not culled.
1285 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 150));
1286 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 360);
1287 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 360);
1288 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1290 layer
->SetTexturePriorities(priority_calculator_
);
1291 resource_manager_
->PrioritizeTextures();
1292 layer
->SavePaintProperties();
1293 layer
->Update(queue_
.get(), &occluded
);
1294 EXPECT_EQ(24 - 3, layer
->fake_layer_updater()->update_count());
1296 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1298 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 210000, 1);
1299 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1301 layer
->fake_layer_updater()->ClearUpdateCount();
1303 // Now the visible region stops at the edge of the occlusion so the partly
1304 // visible tiles become fully occluded.
1305 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 150));
1306 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 350);
1307 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 350);
1308 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1309 layer
->SetTexturePriorities(priority_calculator_
);
1310 resource_manager_
->PrioritizeTextures();
1311 layer
->SavePaintProperties();
1312 layer
->Update(queue_
.get(), &occluded
);
1313 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1315 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1316 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1319 EXPECT_EQ(3 + 6, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1321 layer
->fake_layer_updater()->ClearUpdateCount();
1323 // Now the visible region is even smaller than the occlusion, it should have
1325 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 150));
1326 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 340);
1327 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 340);
1328 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1329 layer
->SetTexturePriorities(priority_calculator_
);
1330 resource_manager_
->PrioritizeTextures();
1331 layer
->SavePaintProperties();
1332 layer
->Update(queue_
.get(), &occluded
);
1333 EXPECT_EQ(24 - 6, layer
->fake_layer_updater()->update_count());
1335 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1336 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1337 210000 + 180000 + 180000,
1339 EXPECT_EQ(3 + 6 + 6, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1342 TEST_F(TiledLayerTest
, TilesNotPaintedWithoutInvalidation
) {
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 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1354 layer
->SetBounds(gfx::Size(600, 600));
1355 CalcDrawProps(&render_surface_layer_list
);
1357 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 100));
1358 layer
->draw_properties().drawable_content_rect
= gfx::Rect(0, 0, 600, 600);
1359 layer
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 600, 600);
1360 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1361 layer
->SetTexturePriorities(priority_calculator_
);
1362 resource_manager_
->PrioritizeTextures();
1363 layer
->SavePaintProperties();
1364 layer
->Update(queue_
.get(), &occluded
);
1365 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1366 { UpdateTextures(); }
1368 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1370 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1371 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1373 layer
->fake_layer_updater()->ClearUpdateCount();
1374 layer
->SetTexturePriorities(priority_calculator_
);
1375 resource_manager_
->PrioritizeTextures();
1376 layer
->SavePaintProperties();
1378 // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
1380 layer
->Update(queue_
.get(), &occluded
);
1381 EXPECT_EQ(3, layer
->fake_layer_updater()->update_count());
1383 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1385 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1386 EXPECT_EQ(6, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1389 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndTransforms
) {
1390 scoped_refptr
<FakeTiledLayer
> layer
=
1391 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1392 RenderSurfaceLayerList render_surface_layer_list
;
1393 TestOcclusionTracker occluded
;
1394 occlusion_
= &occluded
;
1396 layer_tree_host_
->root_layer()->AddChild(layer
);
1398 // The tile size is 100x100.
1400 // This makes sure the painting works when the occluded region (in screen
1401 // space) is transformed differently than the layer.
1402 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1403 layer
->SetBounds(gfx::Size(600, 600));
1404 CalcDrawProps(&render_surface_layer_list
);
1405 gfx::Transform screen_transform
;
1406 screen_transform
.Scale(0.5, 0.5);
1407 layer
->draw_properties().screen_space_transform
= screen_transform
;
1408 layer
->draw_properties().target_space_transform
= screen_transform
;
1410 occluded
.SetOcclusion(gfx::Rect(100, 100, 150, 50));
1411 layer
->draw_properties().drawable_content_rect
=
1412 gfx::Rect(layer
->content_bounds());
1413 layer
->draw_properties().visible_content_rect
=
1414 gfx::Rect(layer
->content_bounds());
1415 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1416 layer
->SetTexturePriorities(priority_calculator_
);
1417 resource_manager_
->PrioritizeTextures();
1418 layer
->SavePaintProperties();
1419 layer
->Update(queue_
.get(), &occluded
);
1420 EXPECT_EQ(36 - 3, layer
->fake_layer_updater()->update_count());
1422 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1424 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
1425 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1428 TEST_F(TiledLayerTest
, TilesPaintedWithOcclusionAndScaling
) {
1429 scoped_refptr
<FakeTiledLayer
> layer
=
1430 new FakeTiledLayer(resource_manager_
.get());
1431 RenderSurfaceLayerList render_surface_layer_list
;
1432 TestOcclusionTracker occluded
;
1433 occlusion_
= &occluded
;
1435 scoped_refptr
<FakeTiledLayer
> scale_layer
=
1436 new FakeTiledLayer(resource_manager_
.get());
1437 gfx::Transform scale_transform
;
1438 scale_transform
.Scale(2.0, 2.0);
1439 scale_layer
->SetTransform(scale_transform
);
1441 layer_tree_host_
->root_layer()->AddChild(scale_layer
);
1443 // The tile size is 100x100.
1445 // This makes sure the painting works when the content space is scaled to
1446 // a different layer space.
1447 layer_tree_host_
->SetViewportSize(gfx::Size(600, 600));
1448 layer
->SetAnchorPoint(gfx::PointF());
1449 layer
->SetBounds(gfx::Size(300, 300));
1450 scale_layer
->AddChild(layer
);
1451 CalcDrawProps(&render_surface_layer_list
);
1452 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_x());
1453 EXPECT_FLOAT_EQ(2.f
, layer
->contents_scale_y());
1454 EXPECT_EQ(gfx::Size(600, 600).ToString(),
1455 layer
->content_bounds().ToString());
1457 // No tiles are covered by the 300x50 occlusion.
1458 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 50));
1459 layer
->draw_properties().drawable_content_rect
=
1460 gfx::Rect(layer
->bounds());
1461 layer
->draw_properties().visible_content_rect
=
1462 gfx::Rect(layer
->content_bounds());
1463 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1464 layer
->SetTexturePriorities(priority_calculator_
);
1465 resource_manager_
->PrioritizeTextures();
1466 layer
->SavePaintProperties();
1467 layer
->Update(queue_
.get(), &occluded
);
1468 int visible_tiles1
= 6 * 6;
1469 EXPECT_EQ(visible_tiles1
, layer
->fake_layer_updater()->update_count());
1471 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1472 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1473 visible_tiles1
* 100 * 100,
1475 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1477 layer
->fake_layer_updater()->ClearUpdateCount();
1479 // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1480 occluded
.SetOcclusion(gfx::Rect(200, 200, 300, 100));
1481 layer
->draw_properties().drawable_content_rect
=
1482 gfx::Rect(layer
->bounds());
1483 layer
->draw_properties().visible_content_rect
=
1484 gfx::Rect(layer
->content_bounds());
1485 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1486 layer
->SetTexturePriorities(priority_calculator_
);
1487 resource_manager_
->PrioritizeTextures();
1488 layer
->SavePaintProperties();
1489 layer
->Update(queue_
.get(), &occluded
);
1490 int visible_tiles2
= 6 * 6 - 3;
1491 EXPECT_EQ(visible_tiles2
, layer
->fake_layer_updater()->update_count());
1493 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1494 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1495 visible_tiles2
* 100 * 100 +
1496 visible_tiles1
* 100 * 100,
1498 EXPECT_EQ(3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1500 layer
->fake_layer_updater()->ClearUpdateCount();
1502 // This makes sure content scaling and transforms work together.
1503 // When the tiles are scaled down by half, they are 50x50 each in the
1505 gfx::Transform screen_transform
;
1506 screen_transform
.Scale(0.5, 0.5);
1507 layer
->draw_properties().screen_space_transform
= screen_transform
;
1508 layer
->draw_properties().target_space_transform
= screen_transform
;
1510 // An occlusion of 150x100 will cover 3*2 = 6 tiles.
1511 occluded
.SetOcclusion(gfx::Rect(100, 100, 150, 100));
1513 gfx::Rect
layer_bounds_rect(layer
->bounds());
1514 layer
->draw_properties().drawable_content_rect
=
1515 gfx::ScaleToEnclosingRect(layer_bounds_rect
, 0.5f
);
1516 layer
->draw_properties().visible_content_rect
=
1517 gfx::Rect(layer
->content_bounds());
1518 layer
->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1519 layer
->SetTexturePriorities(priority_calculator_
);
1520 resource_manager_
->PrioritizeTextures();
1521 layer
->SavePaintProperties();
1522 layer
->Update(queue_
.get(), &occluded
);
1523 int visible_tiles3
= 6 * 6 - 6;
1524 EXPECT_EQ(visible_tiles3
, layer
->fake_layer_updater()->update_count());
1526 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1527 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1528 visible_tiles3
* 100 * 100 +
1529 visible_tiles2
* 100 * 100 +
1530 visible_tiles1
* 100 * 100,
1532 EXPECT_EQ(6 + 3, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1535 TEST_F(TiledLayerTest
, VisibleContentOpaqueRegion
) {
1536 scoped_refptr
<FakeTiledLayer
> layer
=
1537 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1538 RenderSurfaceLayerList render_surface_layer_list
;
1539 TestOcclusionTracker occluded
;
1540 occlusion_
= &occluded
;
1541 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1543 layer_tree_host_
->root_layer()->AddChild(layer
);
1545 // The tile size is 100x100, so this invalidates and then paints two tiles in
1548 gfx::Rect opaque_paint_rect
;
1549 Region opaque_contents
;
1551 gfx::Rect content_bounds
= gfx::Rect(0, 0, 100, 200);
1552 gfx::Rect visible_bounds
= gfx::Rect(0, 0, 100, 150);
1554 layer
->SetBounds(content_bounds
.size());
1555 CalcDrawProps(&render_surface_layer_list
);
1556 layer
->draw_properties().drawable_content_rect
= visible_bounds
;
1557 layer
->draw_properties().visible_content_rect
= visible_bounds
;
1559 // If the layer doesn't paint opaque content, then the
1560 // VisibleContentOpaqueRegion should be empty.
1561 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1562 layer
->InvalidateContentRect(content_bounds
);
1563 layer
->SetTexturePriorities(priority_calculator_
);
1564 resource_manager_
->PrioritizeTextures();
1565 layer
->SavePaintProperties();
1566 layer
->Update(queue_
.get(), &occluded
);
1567 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1568 EXPECT_TRUE(opaque_contents
.IsEmpty());
1570 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000, 1);
1571 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1573 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
1574 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1576 // VisibleContentOpaqueRegion should match the visible part of what is painted
1578 opaque_paint_rect
= gfx::Rect(10, 10, 90, 190);
1579 layer
->fake_layer_updater()->SetOpaquePaintRect(opaque_paint_rect
);
1580 layer
->InvalidateContentRect(content_bounds
);
1581 layer
->SetTexturePriorities(priority_calculator_
);
1582 resource_manager_
->PrioritizeTextures();
1583 layer
->SavePaintProperties();
1584 layer
->Update(queue_
.get(), &occluded
);
1586 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1587 EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect
, visible_bounds
).ToString(),
1588 opaque_contents
.ToString());
1590 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
1591 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1592 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1593 20000 + 20000 - 17100,
1595 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1597 // If we paint again without invalidating, the same stuff should be opaque.
1598 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1599 layer
->SetTexturePriorities(priority_calculator_
);
1600 resource_manager_
->PrioritizeTextures();
1601 layer
->SavePaintProperties();
1602 layer
->Update(queue_
.get(), &occluded
);
1604 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1605 EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect
, visible_bounds
).ToString(),
1606 opaque_contents
.ToString());
1608 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
1609 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1610 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1611 20000 + 20000 - 17100,
1613 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1615 // If we repaint a non-opaque part of the tile, then it shouldn't lose its
1616 // opaque-ness. And other tiles should not be affected.
1617 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1618 layer
->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
1619 layer
->SetTexturePriorities(priority_calculator_
);
1620 resource_manager_
->PrioritizeTextures();
1621 layer
->SavePaintProperties();
1622 layer
->Update(queue_
.get(), &occluded
);
1624 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1625 EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect
, visible_bounds
).ToString(),
1626 opaque_contents
.ToString());
1628 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1, 1);
1629 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1630 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1631 20000 + 20000 - 17100 + 1,
1633 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1635 // If we repaint an opaque part of the tile, then it should lose its
1636 // opaque-ness. But other tiles should still not be affected.
1637 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1638 layer
->InvalidateContentRect(gfx::Rect(10, 10, 1, 1));
1639 layer
->SetTexturePriorities(priority_calculator_
);
1640 resource_manager_
->PrioritizeTextures();
1641 layer
->SavePaintProperties();
1642 layer
->Update(queue_
.get(), &occluded
);
1644 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1645 EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
1646 visible_bounds
).ToString(),
1647 opaque_contents
.ToString());
1650 occluded
.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1 + 1, 1);
1651 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
1652 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1653 20000 + 20000 - 17100 + 1 + 1,
1655 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1658 TEST_F(TiledLayerTest
, PixelsPaintedMetrics
) {
1659 scoped_refptr
<FakeTiledLayer
> layer
=
1660 make_scoped_refptr(new FakeTiledLayer(resource_manager_
.get()));
1661 RenderSurfaceLayerList render_surface_layer_list
;
1662 TestOcclusionTracker occluded
;
1663 occlusion_
= &occluded
;
1664 layer_tree_host_
->SetViewportSize(gfx::Size(1000, 1000));
1666 layer_tree_host_
->root_layer()->AddChild(layer
);
1668 // The tile size is 100x100, so this invalidates and then paints two tiles in
1671 gfx::Rect opaque_paint_rect
;
1672 Region opaque_contents
;
1674 gfx::Rect content_bounds
= gfx::Rect(0, 0, 100, 300);
1675 layer
->SetBounds(content_bounds
.size());
1676 CalcDrawProps(&render_surface_layer_list
);
1678 // Invalidates and paints the whole layer.
1679 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1680 layer
->InvalidateContentRect(content_bounds
);
1681 layer
->SetTexturePriorities(priority_calculator_
);
1682 resource_manager_
->PrioritizeTextures();
1683 layer
->SavePaintProperties();
1684 layer
->Update(queue_
.get(), &occluded
);
1686 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1687 EXPECT_TRUE(opaque_contents
.IsEmpty());
1689 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_painted(), 30000, 1);
1690 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1692 occluded
.overdraw_metrics()->pixels_uploaded_translucent(), 30000, 1);
1693 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1695 // Invalidates an area on the top and bottom tile, which will cause us to
1696 // paint the tile in the middle, even though it is not dirty and will not be
1698 layer
->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
1699 layer
->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
1700 layer
->InvalidateContentRect(gfx::Rect(50, 200, 10, 10));
1701 layer
->SetTexturePriorities(priority_calculator_
);
1702 resource_manager_
->PrioritizeTextures();
1703 layer
->SavePaintProperties();
1704 layer
->Update(queue_
.get(), &occluded
);
1706 opaque_contents
= layer
->VisibleContentOpaqueRegion();
1707 EXPECT_TRUE(opaque_contents
.IsEmpty());
1709 // The middle tile was painted even though not invalidated.
1711 occluded
.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
1712 // The pixels uploaded will not include the non-invalidated tile in the
1714 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1715 EXPECT_NEAR(occluded
.overdraw_metrics()->pixels_uploaded_translucent(),
1718 EXPECT_EQ(0, occluded
.overdraw_metrics()->tiles_culled_for_upload());
1721 TEST_F(TiledLayerTest
, DontAllocateContentsWhenTargetSurfaceCantBeAllocated
) {
1722 // Tile size is 100x100.
1723 gfx::Rect
root_rect(0, 0, 300, 200);
1724 gfx::Rect
child_rect(0, 0, 300, 100);
1725 gfx::Rect
child2_rect(0, 100, 300, 100);
1727 scoped_refptr
<FakeTiledLayer
> root
= make_scoped_refptr(
1728 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1729 scoped_refptr
<Layer
> surface
= Layer::Create();
1730 scoped_refptr
<FakeTiledLayer
> child
= make_scoped_refptr(
1731 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1732 scoped_refptr
<FakeTiledLayer
> child2
= make_scoped_refptr(
1733 new FakeTiledLayer(layer_tree_host_
->contents_texture_manager()));
1735 root
->SetBounds(root_rect
.size());
1736 root
->SetAnchorPoint(gfx::PointF());
1737 root
->draw_properties().drawable_content_rect
= root_rect
;
1738 root
->draw_properties().visible_content_rect
= root_rect
;
1739 root
->AddChild(surface
);
1741 surface
->SetForceRenderSurface(true);
1742 surface
->SetAnchorPoint(gfx::PointF());
1743 surface
->SetOpacity(0.5);
1744 surface
->AddChild(child
);
1745 surface
->AddChild(child2
);
1747 child
->SetBounds(child_rect
.size());
1748 child
->SetAnchorPoint(gfx::PointF());
1749 child
->SetPosition(child_rect
.origin());
1750 child
->draw_properties().visible_content_rect
= child_rect
;
1751 child
->draw_properties().drawable_content_rect
= root_rect
;
1753 child2
->SetBounds(child2_rect
.size());
1754 child2
->SetAnchorPoint(gfx::PointF());
1755 child2
->SetPosition(child2_rect
.origin());
1756 child2
->draw_properties().visible_content_rect
= child2_rect
;
1757 child2
->draw_properties().drawable_content_rect
= root_rect
;
1759 layer_tree_host_
->SetRootLayer(root
);
1760 layer_tree_host_
->SetViewportSize(root_rect
.size());
1762 // With a huge memory limit, all layers should update and push their textures.
1763 root
->InvalidateContentRect(root_rect
);
1764 child
->InvalidateContentRect(child_rect
);
1765 child2
->InvalidateContentRect(child2_rect
);
1766 layer_tree_host_
->UpdateLayers(queue_
.get());
1769 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1770 EXPECT_EQ(3, child
->fake_layer_updater()->update_count());
1771 EXPECT_EQ(3, child2
->fake_layer_updater()->update_count());
1772 EXPECT_FALSE(queue_
->HasMoreUpdates());
1774 root
->fake_layer_updater()->ClearUpdateCount();
1775 child
->fake_layer_updater()->ClearUpdateCount();
1776 child2
->fake_layer_updater()->ClearUpdateCount();
1778 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1779 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1780 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1781 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1782 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1783 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1784 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1785 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1786 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1788 for (unsigned i
= 0; i
< 3; ++i
) {
1789 for (unsigned j
= 0; j
< 2; ++j
)
1790 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1791 EXPECT_TRUE(child_impl
->HasResourceIdForTileAt(i
, 0));
1792 EXPECT_TRUE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1795 layer_tree_host_
->CommitComplete();
1797 // With a memory limit that includes only the root layer (3x2 tiles) and half
1798 // the surface that the child layers draw into, the child layers will not be
1799 // allocated. If the surface isn't accounted for, then one of the children
1800 // would fit within the memory limit.
1801 root
->InvalidateContentRect(root_rect
);
1802 child
->InvalidateContentRect(child_rect
);
1803 child2
->InvalidateContentRect(child2_rect
);
1805 size_t memory_limit
= (3 * 2 + 3 * 1) * (100 * 100) * 4;
1806 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1808 layer_tree_host_
->UpdateLayers(queue_
.get());
1811 EXPECT_EQ(6, root
->fake_layer_updater()->update_count());
1812 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1813 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1814 EXPECT_FALSE(queue_
->HasMoreUpdates());
1816 root
->fake_layer_updater()->ClearUpdateCount();
1817 child
->fake_layer_updater()->ClearUpdateCount();
1818 child2
->fake_layer_updater()->ClearUpdateCount();
1820 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1821 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1822 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1823 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1824 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1825 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1826 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1827 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1828 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1830 for (unsigned i
= 0; i
< 3; ++i
) {
1831 for (unsigned j
= 0; j
< 2; ++j
)
1832 EXPECT_TRUE(root_impl
->HasResourceIdForTileAt(i
, j
));
1833 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1834 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1837 layer_tree_host_
->CommitComplete();
1839 // With a memory limit that includes only half the root layer, no contents
1840 // will be allocated. If render surface memory wasn't accounted for, there is
1841 // enough space for one of the children layers, but they draw into a surface
1842 // that can't be allocated.
1843 root
->InvalidateContentRect(root_rect
);
1844 child
->InvalidateContentRect(child_rect
);
1845 child2
->InvalidateContentRect(child2_rect
);
1847 memory_limit
= (3 * 1) * (100 * 100) * 4;
1848 layer_tree_host_
->contents_texture_manager()->SetMaxMemoryLimitBytes(
1850 layer_tree_host_
->UpdateLayers(queue_
.get());
1853 EXPECT_EQ(0, root
->fake_layer_updater()->update_count());
1854 EXPECT_EQ(0, child
->fake_layer_updater()->update_count());
1855 EXPECT_EQ(0, child2
->fake_layer_updater()->update_count());
1856 EXPECT_FALSE(queue_
->HasMoreUpdates());
1858 root
->fake_layer_updater()->ClearUpdateCount();
1859 child
->fake_layer_updater()->ClearUpdateCount();
1860 child2
->fake_layer_updater()->ClearUpdateCount();
1862 scoped_ptr
<FakeTiledLayerImpl
> root_impl
= make_scoped_ptr(
1863 new FakeTiledLayerImpl(host_impl_
->active_tree(), root
->id()));
1864 scoped_ptr
<FakeTiledLayerImpl
> child_impl
= make_scoped_ptr(
1865 new FakeTiledLayerImpl(host_impl_
->active_tree(), child
->id()));
1866 scoped_ptr
<FakeTiledLayerImpl
> child2_impl
= make_scoped_ptr(
1867 new FakeTiledLayerImpl(host_impl_
->active_tree(), child2
->id()));
1868 LayerPushPropertiesTo(child2
.get(), child2_impl
.get());
1869 LayerPushPropertiesTo(child
.get(), child_impl
.get());
1870 LayerPushPropertiesTo(root
.get(), root_impl
.get());
1872 for (unsigned i
= 0; i
< 3; ++i
) {
1873 for (unsigned j
= 0; j
< 2; ++j
)
1874 EXPECT_FALSE(root_impl
->HasResourceIdForTileAt(i
, j
));
1875 EXPECT_FALSE(child_impl
->HasResourceIdForTileAt(i
, 0));
1876 EXPECT_FALSE(child2_impl
->HasResourceIdForTileAt(i
, 0));
1879 layer_tree_host_
->CommitComplete();
1881 ResourceManagerClearAllMemory(layer_tree_host_
->contents_texture_manager(),
1882 resource_provider_
.get());
1883 layer_tree_host_
->SetRootLayer(NULL
);
1886 class TrackingLayerPainter
: public LayerPainter
{
1888 static scoped_ptr
<TrackingLayerPainter
> Create() {
1889 return make_scoped_ptr(new TrackingLayerPainter());
1892 virtual void Paint(SkCanvas
* canvas
,
1893 const gfx::Rect
& content_rect
,
1894 gfx::RectF
* opaque
) OVERRIDE
{
1895 painted_rect_
= content_rect
;
1898 gfx::Rect
PaintedRect() const { return painted_rect_
; }
1899 void ResetPaintedRect() { painted_rect_
= gfx::Rect(); }
1902 gfx::Rect painted_rect_
;
1905 class UpdateTrackingTiledLayer
: public FakeTiledLayer
{
1907 explicit UpdateTrackingTiledLayer(PrioritizedResourceManager
* manager
)
1908 : FakeTiledLayer(manager
) {
1909 scoped_ptr
<TrackingLayerPainter
> painter(TrackingLayerPainter::Create());
1910 tracking_layer_painter_
= painter
.get();
1912 BitmapContentLayerUpdater::Create(painter
.PassAs
<LayerPainter
>(),
1913 &stats_instrumentation_
,
1917 TrackingLayerPainter
* tracking_layer_painter() const {
1918 return tracking_layer_painter_
;
1922 virtual LayerUpdater
* Updater() const OVERRIDE
{
1923 return layer_updater_
.get();
1925 virtual ~UpdateTrackingTiledLayer() {}
1927 TrackingLayerPainter
* tracking_layer_painter_
;
1928 scoped_refptr
<BitmapContentLayerUpdater
> layer_updater_
;
1929 FakeRenderingStatsInstrumentation stats_instrumentation_
;
1932 TEST_F(TiledLayerTest
, NonIntegerContentsScaleIsNotDistortedDuringPaint
) {
1933 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1934 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1936 layer_tree_host_
->root_layer()->AddChild(layer
);
1938 gfx::Rect
layer_rect(0, 0, 30, 31);
1939 layer
->SetPosition(layer_rect
.origin());
1940 layer
->SetBounds(layer_rect
.size());
1941 layer
->UpdateContentsScale(1.5f
);
1943 gfx::Rect
content_rect(0, 0, 45, 47);
1944 EXPECT_EQ(content_rect
.size(), layer
->content_bounds());
1945 layer
->draw_properties().visible_content_rect
= content_rect
;
1946 layer
->draw_properties().drawable_content_rect
= content_rect
;
1948 layer
->SetTexturePriorities(priority_calculator_
);
1949 resource_manager_
->PrioritizeTextures();
1950 layer
->SavePaintProperties();
1952 // Update the whole tile.
1953 layer
->Update(queue_
.get(), NULL
);
1954 layer
->tracking_layer_painter()->ResetPaintedRect();
1956 EXPECT_RECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1959 // Invalidate the entire layer in content space. When painting, the rect given
1960 // to webkit should match the layer's bounds.
1961 layer
->InvalidateContentRect(content_rect
);
1962 layer
->Update(queue_
.get(), NULL
);
1964 EXPECT_RECT_EQ(layer_rect
, layer
->tracking_layer_painter()->PaintedRect());
1967 TEST_F(TiledLayerTest
,
1968 NonIntegerContentsScaleIsNotDistortedDuringInvalidation
) {
1969 scoped_refptr
<UpdateTrackingTiledLayer
> layer
=
1970 make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_
.get()));
1972 layer_tree_host_
->root_layer()->AddChild(layer
);
1974 gfx::Rect
layer_rect(0, 0, 30, 31);
1975 layer
->SetPosition(layer_rect
.origin());
1976 layer
->SetBounds(layer_rect
.size());
1977 layer
->UpdateContentsScale(1.3f
);
1979 gfx::Rect
content_rect(layer
->content_bounds());
1980 layer
->draw_properties().visible_content_rect
= content_rect
;
1981 layer
->draw_properties().drawable_content_rect
= content_rect
;
1983 layer
->SetTexturePriorities(priority_calculator_
);
1984 resource_manager_
->PrioritizeTextures();
1985 layer
->SavePaintProperties();
1987 // Update the whole tile.
1988 layer
->Update(queue_
.get(), NULL
);
1989 layer
->tracking_layer_painter()->ResetPaintedRect();
1991 EXPECT_RECT_EQ(gfx::Rect(), layer
->tracking_layer_painter()->PaintedRect());
1994 // Invalidate the entire layer in layer space. When painting, the rect given
1995 // to webkit should match the layer's bounds.
1996 layer
->SetNeedsDisplayRect(layer_rect
);
1997 layer
->Update(queue_
.get(), NULL
);
1999 EXPECT_RECT_EQ(layer_rect
, layer
->tracking_layer_painter()->PaintedRect());