Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: cc/tiles/tile_manager_unittest.cc

Issue 2726343004: cc: Optimize decode scheduling for checker-images. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/tiles/tile_manager.cc ('k') | cc/tiles/tiling_set_raster_queue_all.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 11 matching lines...) Expand all
22 #include "cc/test/fake_compositor_frame_sink.h" 22 #include "cc/test/fake_compositor_frame_sink.h"
23 #include "cc/test/fake_compositor_frame_sink_client.h" 23 #include "cc/test/fake_compositor_frame_sink_client.h"
24 #include "cc/test/fake_impl_task_runner_provider.h" 24 #include "cc/test/fake_impl_task_runner_provider.h"
25 #include "cc/test/fake_layer_tree_host_impl.h" 25 #include "cc/test/fake_layer_tree_host_impl.h"
26 #include "cc/test/fake_picture_layer_impl.h" 26 #include "cc/test/fake_picture_layer_impl.h"
27 #include "cc/test/fake_picture_layer_tiling_client.h" 27 #include "cc/test/fake_picture_layer_tiling_client.h"
28 #include "cc/test/fake_raster_source.h" 28 #include "cc/test/fake_raster_source.h"
29 #include "cc/test/fake_recording_source.h" 29 #include "cc/test/fake_recording_source.h"
30 #include "cc/test/fake_tile_manager.h" 30 #include "cc/test/fake_tile_manager.h"
31 #include "cc/test/fake_tile_task_manager.h" 31 #include "cc/test/fake_tile_task_manager.h"
32 #include "cc/test/skia_common.h"
32 #include "cc/test/test_layer_tree_host_base.h" 33 #include "cc/test/test_layer_tree_host_base.h"
33 #include "cc/test/test_task_graph_runner.h" 34 #include "cc/test/test_task_graph_runner.h"
34 #include "cc/test/test_tile_priorities.h" 35 #include "cc/test/test_tile_priorities.h"
35 #include "cc/tiles/eviction_tile_priority_queue.h" 36 #include "cc/tiles/eviction_tile_priority_queue.h"
36 #include "cc/tiles/raster_tile_priority_queue.h" 37 #include "cc/tiles/raster_tile_priority_queue.h"
37 #include "cc/tiles/tile.h" 38 #include "cc/tiles/tile.h"
38 #include "cc/tiles/tile_priority.h" 39 #include "cc/tiles/tile_priority.h"
39 #include "cc/tiles/tiling_set_raster_queue_all.h" 40 #include "cc/tiles/tiling_set_raster_queue_all.h"
40 #include "cc/trees/layer_tree_impl.h" 41 #include "cc/trees/layer_tree_impl.h"
41 #include "testing/gmock/include/gmock/gmock.h" 42 #include "testing/gmock/include/gmock/gmock.h"
(...skipping 2278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 SkImageInfo::MakeN32Premul(size.width(), size.height())) {} 2321 SkImageInfo::MakeN32Premul(size.width(), size.height())) {}
2321 2322
2322 protected: 2323 protected:
2323 MOCK_METHOD5(onGetPixels, 2324 MOCK_METHOD5(onGetPixels,
2324 bool(const SkImageInfo&, void*, size_t, SkPMColor[], int*)); 2325 bool(const SkImageInfo&, void*, size_t, SkPMColor[], int*));
2325 }; 2326 };
2326 2327
2327 void TearDown() override { 2328 void TearDown() override {
2328 // Allow all tasks on the image worker to run now. Any scheduled decodes 2329 // Allow all tasks on the image worker to run now. Any scheduled decodes
2329 // will be aborted. 2330 // will be aborted.
2330 image_worker_task_runner()->set_run_tasks_synchronously(true); 2331 task_runner_->set_run_tasks_synchronously(true);
2331 } 2332 }
2332 2333
2333 LayerTreeSettings CreateSettings() override { 2334 LayerTreeSettings CreateSettings() override {
2334 LayerTreeSettings settings; 2335 LayerTreeSettings settings;
2335 settings.enable_checker_imaging = true; 2336 settings.enable_checker_imaging = true;
2336 settings.renderer_settings.buffer_to_texture_target_map = 2337 settings.renderer_settings.buffer_to_texture_target_map =
2337 DefaultBufferToTextureTargetMapForTesting(); 2338 DefaultBufferToTextureTargetMapForTesting();
2338 return settings; 2339 return settings;
2339 } 2340 }
2340 2341
2341 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl( 2342 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl(
2342 const LayerTreeSettings& settings, 2343 const LayerTreeSettings& settings,
2343 TaskRunnerProvider* task_runner_provider, 2344 TaskRunnerProvider* task_runner_provider,
2344 TaskGraphRunner* task_graph_runner) override { 2345 TaskGraphRunner* task_graph_runner) override {
2345 task_runner_ = make_scoped_refptr(new SynchronousSimpleTaskRunner); 2346 task_runner_ = make_scoped_refptr(new SynchronousSimpleTaskRunner);
2346 return base::MakeUnique<FakeLayerTreeHostImpl>( 2347 return base::MakeUnique<FakeLayerTreeHostImpl>(
2347 settings, task_runner_provider, task_graph_runner, task_runner_); 2348 settings, task_runner_provider, task_graph_runner, task_runner_);
2348 } 2349 }
2349 2350
2350 std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override { 2351 std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override {
2351 return base::MakeUnique<SynchronousTaskGraphRunner>(); 2352 return base::MakeUnique<SynchronousTaskGraphRunner>();
2352 } 2353 }
2353 2354
2354 SynchronousSimpleTaskRunner* image_worker_task_runner() const { 2355 void FlushDecodeTasks() {
2355 return task_runner_.get(); 2356 while (task_runner_->HasPendingTask()) {
2357 task_runner_->RunUntilIdle();
2358 base::RunLoop().RunUntilIdle();
2359 }
2356 } 2360 }
2357 2361
2358 private: 2362 private:
2359 scoped_refptr<SynchronousSimpleTaskRunner> task_runner_; 2363 scoped_refptr<SynchronousSimpleTaskRunner> task_runner_;
2360 }; 2364 };
2361 2365
2362 TEST_F(CheckerImagingTileManagerTest, 2366 TEST_F(CheckerImagingTileManagerTest,
2363 NoImageDecodeDependencyForCheckeredTiles) { 2367 NoImageDecodeDependencyForCheckeredTiles) {
2364 const gfx::Size layer_bounds(512, 512); 2368 const gfx::Size layer_bounds(512, 512);
2365 SetupDefaultTrees(layer_bounds); 2369 SetupDefaultTrees(layer_bounds);
2366 2370
2367 std::unique_ptr<FakeRecordingSource> recording_source = 2371 std::unique_ptr<FakeRecordingSource> recording_source =
2368 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); 2372 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2373 recording_source->set_fill_with_nonsolid_color(true);
2369 recording_source->SetGenerateDiscardableImagesMetadata(true); 2374 recording_source->SetGenerateDiscardableImagesMetadata(true);
2370 2375
2371 sk_sp<SkImage> image = SkImage::MakeFromGenerator( 2376 sk_sp<SkImage> image = SkImage::MakeFromGenerator(
2372 base::MakeUnique<testing::StrictMock<MockImageGenerator>>( 2377 base::MakeUnique<testing::StrictMock<MockImageGenerator>>(
2373 gfx::Size(512, 512))); 2378 gfx::Size(512, 512)));
2374 recording_source->add_draw_image(image, gfx::Point(0, 0)); 2379 recording_source->add_draw_image(image, gfx::Point(0, 0));
2375 2380
2376 recording_source->Rerecord(); 2381 recording_source->Rerecord();
2377 scoped_refptr<RasterSource> raster_source = 2382 scoped_refptr<RasterSource> raster_source =
2378 RasterSource::CreateFromRecordingSource(recording_source.get(), false); 2383 RasterSource::CreateFromRecordingSource(recording_source.get(), false);
(...skipping 16 matching lines...) Expand all
2395 // PrepareTiles and synchronously run all tasks added to the TaskGraph. Since 2400 // PrepareTiles and synchronously run all tasks added to the TaskGraph. Since
2396 // we are using a strict mock for the SkImageGenerator, if the decode runs as 2401 // we are using a strict mock for the SkImageGenerator, if the decode runs as
2397 // a part of raster tasks, the test should fail. 2402 // a part of raster tasks, the test should fail.
2398 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); 2403 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2399 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); 2404 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2400 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle(); 2405 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
2401 base::RunLoop().RunUntilIdle(); 2406 base::RunLoop().RunUntilIdle();
2402 EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); 2407 EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2403 } 2408 }
2404 2409
2410 TEST_F(CheckerImagingTileManagerTest, BuildsImageDecodeQueueAsExpected) {
2411 const gfx::Size layer_bounds(900, 900);
2412
2413 std::unique_ptr<FakeRecordingSource> recording_source =
2414 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2415 recording_source->set_fill_with_nonsolid_color(true);
2416 recording_source->SetGenerateDiscardableImagesMetadata(true);
2417
2418 int dimension = 450;
2419 sk_sp<SkImage> image1 =
2420 CreateDiscardableImage(gfx::Size(dimension, dimension));
2421 sk_sp<SkImage> image2 =
2422 CreateDiscardableImage(gfx::Size(dimension, dimension));
2423 sk_sp<SkImage> image3 =
2424 CreateDiscardableImage(gfx::Size(dimension, dimension));
2425 recording_source->add_draw_image(image1, gfx::Point(0, 0));
2426 recording_source->add_draw_image(image2, gfx::Point(600, 0));
2427 recording_source->add_draw_image(image3, gfx::Point(0, 600));
2428
2429 recording_source->Rerecord();
2430 scoped_refptr<RasterSource> raster_source =
2431 RasterSource::CreateFromRecordingSource(recording_source.get(), false);
2432
2433 gfx::Size tile_size(500, 500);
2434 Region invalidation((gfx::Rect(layer_bounds)));
2435 SetupPendingTree(raster_source, tile_size, invalidation);
2436
2437 PictureLayerTilingSet* tiling_set =
2438 pending_layer()->picture_layer_tiling_set();
2439 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
2440 pending_tiling->set_resolution(HIGH_RESOLUTION);
2441 pending_tiling->CreateAllTilesForTesting();
2442 pending_tiling->SetTilePriorityRectsForTesting(
2443 gfx::Rect(layer_bounds), // Visible rect.
2444 gfx::Rect(layer_bounds), // Skewport rect.
2445 gfx::Rect(layer_bounds), // Soon rect.
2446 gfx::Rect(layer_bounds)); // Eventually rect.
2447
2448 // PrepareTiles and make sure we account correctly for tiles that have been
2449 // scheduled with checkered images.
2450 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2451 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2452
2453 for (int i = 0; i < 2; i++) {
2454 for (int j = 0; j < 2; j++) {
2455 const Tile* tile = pending_tiling->TileAt(i, j);
2456 EXPECT_TRUE(tile->HasRasterTask());
2457 if (i == 1 && j == 1)
2458 EXPECT_FALSE(tile->raster_task_scheduled_with_checker_images());
2459 else
2460 EXPECT_TRUE(tile->raster_task_scheduled_with_checker_images());
2461 }
2462 }
2463 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 3);
2464
2465 // Now raster all the tiles and make sure these tiles are still accounted for
2466 // with checkered images.
2467 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
2468 base::RunLoop().RunUntilIdle();
2469 EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2470 for (int i = 0; i < 2; i++) {
2471 for (int j = 0; j < 2; j++) {
2472 const Tile* tile = pending_tiling->TileAt(i, j);
2473 EXPECT_FALSE(tile->HasRasterTask());
2474 EXPECT_FALSE(tile->raster_task_scheduled_with_checker_images());
2475 EXPECT_TRUE(tile->draw_info().has_resource());
2476 if (i == 1 && j == 1)
2477 EXPECT_FALSE(tile->draw_info().is_checker_imaged());
2478 else
2479 EXPECT_TRUE(tile->draw_info().is_checker_imaged());
2480 }
2481 }
2482 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 3);
2483
2484 // Activate the pending tree.
2485 ActivateTree();
2486
2487 // Set empty tile priority rects so an empty image decode queue is used.
2488 gfx::Rect empty_rect;
2489 PictureLayerTiling* active_tiling =
2490 active_layer()->picture_layer_tiling_set()->tiling_at(0);
2491 active_tiling->SetTilePriorityRectsForTesting(
2492 gfx::Rect(empty_rect), // Visible rect.
2493 gfx::Rect(empty_rect), // Skewport rect.
2494 gfx::Rect(empty_rect), // Soon rect.
2495 gfx::Rect(empty_rect)); // Eventually rect.
2496 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2497
2498 // Run the decode tasks. Since the first decode is always scheduled, the
2499 // completion for it should be triggered.
2500 FlushDecodeTasks();
2501
2502 // Create a new pending tree to invalidate tiles for decoded images and verify
2503 // that only tiles for |image1| are invalidated.
2504 EXPECT_TRUE(host_impl()->client()->did_request_impl_side_invalidation());
2505 PerformImplSideInvalidation();
2506 for (int i = 0; i < 2; i++) {
2507 for (int j = 0; j < 2; j++) {
2508 const Tile* tile = pending_tiling->TileAt(i, j);
2509 if (i == 0 && j == 0)
2510 EXPECT_TRUE(tile);
2511 else
2512 EXPECT_FALSE(tile);
2513 }
2514 }
2515 host_impl()->client()->reset_did_request_impl_side_invalidation();
2516
2517 // Activating the tree replaces the checker-imaged tile.
2518 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 3);
2519 ActivateTree();
2520 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 2);
2521
2522 // Set the tile priority rects such that only the tile with the second image
2523 // is scheduled for decodes, since it is checker-imaged.
2524 gfx::Rect rect_to_raster(600, 0, 300, 900);
2525 active_tiling->SetTilePriorityRectsForTesting(
2526 gfx::Rect(rect_to_raster), // Visible rect.
2527 gfx::Rect(rect_to_raster), // Skewport rect.
2528 gfx::Rect(rect_to_raster), // Soon rect.
2529 gfx::Rect(rect_to_raster)); // Eventually rect.
2530 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2531
2532 // Run decode tasks to trigger completion of any pending decodes.
2533 FlushDecodeTasks();
2534
2535 // Create a new pending tree to invalidate tiles for decoded images and verify
2536 // that only tiles for |image2| are invalidated.
2537 EXPECT_TRUE(host_impl()->client()->did_request_impl_side_invalidation());
2538 PerformImplSideInvalidation();
2539 for (int i = 0; i < 2; i++) {
2540 for (int j = 0; j < 2; j++) {
2541 const Tile* tile = pending_tiling->TileAt(i, j);
2542 if (i == 1 && j == 0)
2543 EXPECT_TRUE(tile);
2544 else
2545 EXPECT_FALSE(tile);
2546 }
2547 }
2548 host_impl()->client()->reset_did_request_impl_side_invalidation();
2549
2550 // Activating the tree replaces the checker-imaged tile.
2551 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 2);
2552 ActivateTree();
2553 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 1);
2554
2555 // Set the tile priority rects to cover the complete tiling and change the
2556 // visibility. While |image3| has not yet been decoded, since we are
2557 // invisible no decodes should have been scheduled.
2558 active_tiling->SetTilePriorityRectsForTesting(
2559 gfx::Rect(layer_bounds), // Visible rect.
2560 gfx::Rect(layer_bounds), // Skewport rect.
2561 gfx::Rect(layer_bounds), // Soon rect.
2562 gfx::Rect(layer_bounds)); // Eventually rect.
2563 host_impl()->SetVisible(false);
2564 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2565 FlushDecodeTasks();
2566 EXPECT_FALSE(host_impl()->client()->did_request_impl_side_invalidation());
2567 }
2568
2569 class CheckerImagingTileManagerMemoryTest
2570 : public CheckerImagingTileManagerTest {
2571 public:
2572 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl(
2573 const LayerTreeSettings& settings,
2574 TaskRunnerProvider* task_runner_provider,
2575 TaskGraphRunner* task_graph_runner) override {
2576 LayerTreeSettings new_settings = settings;
2577 new_settings.gpu_memory_policy.num_resources_limit = 4;
2578 return CheckerImagingTileManagerTest::CreateHostImpl(
2579 new_settings, task_runner_provider, task_graph_runner);
2580 }
2581 };
2582
2583 TEST_F(CheckerImagingTileManagerMemoryTest, AddsAllNowTilesToImageDecodeQueue) {
2584 const gfx::Size layer_bounds(900, 1400);
2585
2586 std::unique_ptr<FakeRecordingSource> recording_source =
2587 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2588 recording_source->set_fill_with_nonsolid_color(true);
2589 recording_source->SetGenerateDiscardableImagesMetadata(true);
2590
2591 int dimension = 450;
2592 sk_sp<SkImage> image1 =
2593 CreateDiscardableImage(gfx::Size(dimension, dimension));
2594 sk_sp<SkImage> image2 =
2595 CreateDiscardableImage(gfx::Size(dimension, dimension));
2596 recording_source->add_draw_image(image1, gfx::Point(0, 515));
2597 recording_source->add_draw_image(image2, gfx::Point(515, 515));
2598
2599 recording_source->Rerecord();
2600 scoped_refptr<RasterSource> raster_source =
2601 RasterSource::CreateFromRecordingSource(recording_source.get(), false);
2602
2603 gfx::Size tile_size(500, 500);
2604 Region invalidation((gfx::Rect(layer_bounds)));
2605 SetupPendingTree(raster_source, tile_size, invalidation);
2606
2607 PictureLayerTilingSet* tiling_set =
2608 pending_layer()->picture_layer_tiling_set();
2609 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
2610 pending_tiling->set_resolution(HIGH_RESOLUTION);
2611 pending_tiling->CreateAllTilesForTesting();
2612
2613 // Use a rect that only rasterizes the bottom 2 rows of tiles.
2614 gfx::Rect rect_to_raster(0, 500, 900, 900);
2615 pending_tiling->SetTilePriorityRectsForTesting(
2616 rect_to_raster, // Visible rect.
2617 rect_to_raster, // Skewport rect.
2618 rect_to_raster, // Soon rect.
2619 rect_to_raster); // Eventually rect.
2620
2621 // PrepareTiles, rasterize all scheduled tiles and activate while no images
2622 // have been decoded.
2623 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2624 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
2625 base::RunLoop().RunUntilIdle();
2626 ActivateTree();
2627
2628 // Expand the visible rect to include the complete tiling. The tile iteration
2629 // will not go beyond the first tile since there are no resources with a lower
2630 // priority that can be evicted. But we should still see image decodes
2631 // scheduled for all visible tiles.
2632 gfx::Rect complete_tiling_rect(layer_bounds);
2633 PictureLayerTiling* active_tiling =
2634 active_layer()->picture_layer_tiling_set()->tiling_at(0);
2635 active_tiling->SetTilePriorityRectsForTesting(
2636 complete_tiling_rect, // Visible rect.
2637 complete_tiling_rect, // Skewport rect.
2638 complete_tiling_rect, // Soon rect.
2639 complete_tiling_rect); // Eventually rect.
2640 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2641
2642 // Flush all decode tasks. The tiles with checkered images should be
2643 // invalidated.
2644 FlushDecodeTasks();
2645 EXPECT_TRUE(host_impl()->client()->did_request_impl_side_invalidation());
2646 PerformImplSideInvalidation();
2647 for (int i = 0; i < 2; i++) {
2648 for (int j = 0; j < 3; j++) {
2649 const Tile* tile = pending_tiling->TileAt(i, j);
2650 if (j == 1)
2651 EXPECT_TRUE(tile);
2652 else
2653 EXPECT_FALSE(tile);
2654 }
2655 }
2656 host_impl()->client()->reset_did_request_impl_side_invalidation();
2657 }
2658
2405 } // namespace 2659 } // namespace
2406 } // namespace cc 2660 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/tile_manager.cc ('k') | cc/tiles/tiling_set_raster_queue_all.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698