// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "cc/layers/picture_layer_impl.h" #include "base/threading/thread_task_runner_handle.h" #include "base/timer/lap_timer.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_raster_source.h" #include "cc/test/test_task_graph_runner.h" #include "cc/tiles/tiling_set_raster_queue_all.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h" namespace cc { namespace { static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; void AddTiling(float scale, FakePictureLayerImpl* layer, std::vector* all_tiles) { PictureLayerTiling* tiling = layer->AddTiling(gfx::AxisTransform2d(scale, gfx::Vector2dF())); tiling->set_resolution(HIGH_RESOLUTION); tiling->CreateAllTilesForTesting(); std::vector tiling_tiles = tiling->AllTilesForTesting(); std::copy( tiling_tiles.begin(), tiling_tiles.end(), std::back_inserter(*all_tiles)); } class PictureLayerImplPerfTest : public testing::Test { public: PictureLayerImplPerfTest() : task_runner_provider_(base::ThreadTaskRunnerHandle::Get()), layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()), host_impl_(LayerTreeSettings(), &task_runner_provider_, &task_graph_runner_), timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} PictureLayerImplPerfTest(const PictureLayerImplPerfTest&) = delete; PictureLayerImplPerfTest& operator=(const PictureLayerImplPerfTest&) = delete; void SetUp() override { host_impl_.SetVisible(true); host_impl_.InitializeFrameSink(layer_tree_frame_sink_.get()); } void SetupPendingTree(const gfx::Size& layer_bounds) { scoped_refptr raster_source = FakeRasterSource::CreateFilled(layer_bounds); host_impl_.CreatePendingTree(); LayerTreeImpl* pending_tree = host_impl_.pending_tree(); pending_tree->DetachLayers(); std::unique_ptr pending_layer = FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 7, raster_source); pending_layer->SetDrawsContent(true); pending_layer->test_properties()->force_render_surface = true; pending_tree->SetRootLayerForTesting(std::move(pending_layer)); pending_tree->BuildLayerListAndPropertyTreesForTesting(); pending_layer_ = static_cast( host_impl_.pending_tree()->LayerById(7)); } void RunRasterQueueConstructAndIterateTest(const std::string& test_name, int num_tiles, const gfx::Rect& viewport_rect) { host_impl_.active_tree()->SetDeviceViewportRect(viewport_rect); host_impl_.pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { int count = num_tiles; std::unique_ptr queue( new TilingSetRasterQueueAll( pending_layer_->picture_layer_tiling_set(), false, true)); while (count--) { ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count; ASSERT_TRUE(queue->Top().tile()) << "count: " << count; queue->Pop(); } timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); perf_test::PrintResult("tiling_set_raster_queue_construct_and_iterate", "", test_name, timer_.LapsPerSecond(), "runs/s", true); } void RunRasterQueueConstructTest(const std::string& test_name, const gfx::Rect& viewport) { host_impl_.active_tree()->SetDeviceViewportRect(viewport); host_impl_.pending_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( pending_layer_->element_id(), gfx::ScrollOffset(viewport.x(), viewport.y())); host_impl_.pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { std::unique_ptr queue( new TilingSetRasterQueueAll( pending_layer_->picture_layer_tiling_set(), false, true)); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); perf_test::PrintResult("tiling_set_raster_queue_construct", "", test_name, timer_.LapsPerSecond(), "runs/s", true); } void RunEvictionQueueConstructAndIterateTest(const std::string& test_name, int num_tiles, const gfx::Rect& viewport_rect) { host_impl_.active_tree()->SetDeviceViewportRect(viewport_rect); host_impl_.pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { int count = num_tiles; std::unique_ptr queue(new TilingSetEvictionQueue( pending_layer_->picture_layer_tiling_set(), pending_layer_->contributes_to_drawn_render_surface())); while (count--) { ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count; ASSERT_TRUE(queue->Top().tile()) << "count: " << count; queue->Pop(); } timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); perf_test::PrintResult("tiling_set_eviction_queue_construct_and_iterate", "", test_name, timer_.LapsPerSecond(), "runs/s", true); } void RunEvictionQueueConstructTest(const std::string& test_name, const gfx::Rect& viewport) { host_impl_.active_tree()->SetDeviceViewportRect(viewport); host_impl_.pending_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( pending_layer_->element_id(), gfx::ScrollOffset(viewport.x(), viewport.y())); host_impl_.pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { std::unique_ptr queue(new TilingSetEvictionQueue( pending_layer_->picture_layer_tiling_set(), pending_layer_->contributes_to_drawn_render_surface())); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); perf_test::PrintResult("tiling_set_eviction_queue_construct", "", test_name, timer_.LapsPerSecond(), "runs/s", true); } protected: TestTaskGraphRunner task_graph_runner_; FakeImplTaskRunnerProvider task_runner_provider_; std::unique_ptr layer_tree_frame_sink_; FakeLayerTreeHostImpl host_impl_; FakePictureLayerImpl* pending_layer_; base::LapTimer timer_; }; TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) { SetupPendingTree(gfx::Size(10000, 10000)); float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; pending_layer_->AddTiling( gfx::AxisTransform2d(low_res_factor, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(0.3f, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(0.7f, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(1.0f, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(2.0f, gfx::Vector2dF())); RunRasterQueueConstructAndIterateTest("32_100x100", 32, gfx::Rect(100, 100)); RunRasterQueueConstructAndIterateTest("32_500x500", 32, gfx::Rect(500, 500)); RunRasterQueueConstructAndIterateTest("64_100x100", 64, gfx::Rect(100, 100)); RunRasterQueueConstructAndIterateTest("64_500x500", 64, gfx::Rect(500, 500)); } TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstruct) { SetupPendingTree(gfx::Size(10000, 10000)); float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; pending_layer_->AddTiling( gfx::AxisTransform2d(low_res_factor, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(0.3f, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(0.7f, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(1.0f, gfx::Vector2dF())); pending_layer_->AddTiling(gfx::AxisTransform2d(2.0f, gfx::Vector2dF())); RunRasterQueueConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100)); RunRasterQueueConstructTest("5000_0_100x100", gfx::Rect(5000, 0, 100, 100)); RunRasterQueueConstructTest("9999_0_100x100", gfx::Rect(9999, 0, 100, 100)); } TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) { SetupPendingTree(gfx::Size(10000, 10000)); float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; std::vector all_tiles; AddTiling(low_res_factor, pending_layer_, &all_tiles); AddTiling(0.3f, pending_layer_, &all_tiles); AddTiling(0.7f, pending_layer_, &all_tiles); AddTiling(1.0f, pending_layer_, &all_tiles); AddTiling(2.0f, pending_layer_, &all_tiles); ASSERT_TRUE(host_impl_.tile_manager() != nullptr); host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); RunEvictionQueueConstructAndIterateTest("32_100x100", 32, gfx::Rect(100, 100)); RunEvictionQueueConstructAndIterateTest("32_500x500", 32, gfx::Rect(500, 500)); RunEvictionQueueConstructAndIterateTest("64_100x100", 64, gfx::Rect(100, 100)); RunEvictionQueueConstructAndIterateTest("64_500x500", 64, gfx::Rect(500, 500)); } TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstruct) { SetupPendingTree(gfx::Size(10000, 10000)); float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; std::vector all_tiles; AddTiling(low_res_factor, pending_layer_, &all_tiles); AddTiling(0.3f, pending_layer_, &all_tiles); AddTiling(0.7f, pending_layer_, &all_tiles); AddTiling(1.0f, pending_layer_, &all_tiles); AddTiling(2.0f, pending_layer_, &all_tiles); ASSERT_TRUE(host_impl_.tile_manager() != nullptr); host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); RunEvictionQueueConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100)); RunEvictionQueueConstructTest("5000_0_100x100", gfx::Rect(5000, 0, 100, 100)); RunEvictionQueueConstructTest("9999_0_100x100", gfx::Rect(9999, 0, 100, 100)); } } // namespace } // namespace cc