Connect PPAPI IPC channels for non-SFI mode.
[chromium-blink-merge.git] / cc / layers / tiled_layer_unittest.cc
blob32042808018b8645216709b566242c90c87abeb3
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"
7 #include <limits>
8 #include <vector>
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"
30 namespace cc {
31 namespace {
33 class TestOcclusionTracker : public OcclusionTracker {
34 public:
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 {
49 public:
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(
63 FROM_HERE,
64 run_loop_.QuitClosure(),
65 base::TimeDelta::FromSeconds(5));
66 run_loop_.Run();
67 return output_surface_created_;
70 virtual CreateResult OnCreateAndInitializeOutputSurfaceAttempted(
71 bool success) OVERRIDE {
72 CreateResult result =
73 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(success);
74 output_surface_created_ = success;
75 run_loop_.Quit();
76 return result;
79 private:
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 {
95 public:
96 TiledLayerTest()
97 : proxy_(NULL),
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),
102 occlusion_(NULL) {
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_,
111 NULL,
112 settings_,
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_);
124 resource_provider_ =
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();
136 host_impl_.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_);
154 DCHECK(queue_);
155 scoped_ptr<ResourceUpdateController> update_controller =
156 ResourceUpdateController::Create(NULL,
157 proxy_->ImplThreadTaskRunner(),
158 queue_.Pass(),
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) {
178 if (occlusion_)
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) {
203 // Get textures
204 resource_manager_->ClearPriorities();
205 if (layer1.get())
206 layer1->SetTexturePriorities(priority_calculator_);
207 if (layer2.get())
208 layer2->SetTexturePriorities(priority_calculator_);
209 resource_manager_->PrioritizeTextures();
211 // Save paint properties
212 if (layer1.get())
213 layer1->SavePaintProperties();
214 if (layer2.get())
215 layer2->SavePaintProperties();
217 // Update content
218 if (layer1.get())
219 layer1->Update(queue_.get(), occlusion_);
220 if (layer2.get())
221 layer2->Update(queue_.get(), occlusion_);
223 bool needs_update = false;
224 if (layer1.get())
225 needs_update |= layer1->NeedsIdlePaint();
226 if (layer2.get())
227 needs_update |= layer2->NeedsIdlePaint();
229 // Update textures and push.
230 UpdateTextures();
231 if (layer1.get())
232 LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
233 if (layer2.get())
234 LayerPushPropertiesTo(layer2.get(), layer_impl2.get());
236 return needs_update;
239 public:
240 Proxy* proxy_;
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
279 // not painted.
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);
304 EXPECT_NEAR(
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(),
325 20000 + 2500,
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
330 // unoccluded.
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
442 // in the center.
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
451 // frame.
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
473 // now.
474 if (k <= 3) {
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
576 // paint.
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])
682 layer_width *= 2;
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);
710 UpdateTextures();
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));
721 } else {
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,
805 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,
810 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];
821 if (invalidate[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
853 // the LayerUpdater.
854 UpdateAndPush(layer, layer_impl);
855 EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
857 // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
858 // update.
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());
897 UpdateTextures();
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());
907 UpdateTextures();
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);
934 UpdateTextures();
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);
943 UpdateTextures();
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);
962 UpdateTextures();
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(
1013 memory_limit);
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);
1059 int size = 1 << 30;
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 {
1072 public:
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());
1098 UpdateTextures();
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());
1114 UpdateTextures();
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());
1130 UpdateTextures();
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());
1155 UpdateTextures();
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());
1171 UpdateTextures();
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);
1231 EXPECT_NEAR(
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(),
1247 330000 + 340000,
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);
1297 EXPECT_NEAR(
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(),
1317 210000 + 180000,
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
1324 // the same result.
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);
1369 EXPECT_NEAR(
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
1379 // now.
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);
1384 EXPECT_NEAR(
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);
1423 EXPECT_NEAR(
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
1504 // screen.
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
1546 // various ways.
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);
1572 EXPECT_NEAR(
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
1577 // opaque.
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);
1585 UpdateTextures();
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);
1603 UpdateTextures();
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);
1623 UpdateTextures();
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);
1643 UpdateTextures();
1644 opaque_contents = layer->VisibleContentOpaqueRegion();
1645 EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
1646 visible_bounds).ToString(),
1647 opaque_contents.ToString());
1649 EXPECT_NEAR(
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
1669 // various ways.
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);
1685 UpdateTextures();
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);
1691 EXPECT_NEAR(
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
1697 // uploaded.
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);
1705 UpdateTextures();
1706 opaque_contents = layer->VisibleContentOpaqueRegion();
1707 EXPECT_TRUE(opaque_contents.IsEmpty());
1709 // The middle tile was painted even though not invalidated.
1710 EXPECT_NEAR(
1711 occluded.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
1712 // The pixels uploaded will not include the non-invalidated tile in the
1713 // middle.
1714 EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1715 EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1716 30000 + 1 + 100,
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());
1768 UpdateTextures();
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(
1807 memory_limit);
1808 layer_tree_host_->UpdateLayers(queue_.get());
1810 UpdateTextures();
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(
1849 memory_limit);
1850 layer_tree_host_->UpdateLayers(queue_.get());
1852 UpdateTextures();
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 {
1887 public:
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(); }
1901 private:
1902 gfx::Rect painted_rect_;
1905 class UpdateTrackingTiledLayer : public FakeTiledLayer {
1906 public:
1907 explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
1908 : FakeTiledLayer(manager) {
1909 scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
1910 tracking_layer_painter_ = painter.get();
1911 layer_updater_ =
1912 BitmapContentLayerUpdater::Create(painter.PassAs<LayerPainter>(),
1913 &stats_instrumentation_,
1917 TrackingLayerPainter* tracking_layer_painter() const {
1918 return tracking_layer_painter_;
1921 private:
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());
1957 UpdateTextures();
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());
1992 UpdateTextures();
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());
2002 } // namespace
2003 } // namespace cc