| // Copyright 2016 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/test/test_layer_tree_host_base.h" |
| |
| #include "base/memory/ptr_util.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "cc/test/fake_layer_tree_frame_sink.h" |
| #include "cc/test/fake_raster_source.h" |
| #include "cc/trees/layer_tree_impl.h" |
| |
| namespace cc { |
| |
| TestLayerTreeHostBase::TestLayerTreeHostBase() |
| : task_runner_provider_(base::ThreadTaskRunnerHandle::Get()), |
| pending_layer_(nullptr), |
| active_layer_(nullptr), |
| old_pending_layer_(nullptr), |
| root_id_(6), |
| id_(7) {} |
| |
| TestLayerTreeHostBase::~TestLayerTreeHostBase() = default; |
| |
| void TestLayerTreeHostBase::SetUp() { |
| layer_tree_frame_sink_ = CreateLayerTreeFrameSink(); |
| task_graph_runner_ = CreateTaskGraphRunner(); |
| host_impl_ = CreateHostImpl(CreateSettings(), &task_runner_provider_, |
| task_graph_runner_.get()); |
| InitializeFrameSink(); |
| SetInitialTreePriority(); |
| } |
| |
| LayerTreeSettings TestLayerTreeHostBase::CreateSettings() { |
| LayerTreeSettings settings; |
| return settings; |
| } |
| |
| std::unique_ptr<LayerTreeFrameSink> |
| TestLayerTreeHostBase::CreateLayerTreeFrameSink() { |
| return FakeLayerTreeFrameSink::Create3d(); |
| } |
| |
| std::unique_ptr<FakeLayerTreeHostImpl> TestLayerTreeHostBase::CreateHostImpl( |
| const LayerTreeSettings& settings, |
| TaskRunnerProvider* task_runner_provider, |
| TaskGraphRunner* task_graph_runner) { |
| return std::make_unique<FakeLayerTreeHostImpl>(settings, task_runner_provider, |
| task_graph_runner); |
| } |
| |
| std::unique_ptr<TaskGraphRunner> |
| TestLayerTreeHostBase::CreateTaskGraphRunner() { |
| return base::WrapUnique(new TestTaskGraphRunner); |
| } |
| |
| void TestLayerTreeHostBase::InitializeFrameSink() { |
| host_impl_->SetVisible(true); |
| host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); |
| } |
| |
| void TestLayerTreeHostBase::ResetLayerTreeFrameSink( |
| std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) { |
| host_impl()->DidLoseLayerTreeFrameSink(); |
| host_impl()->SetVisible(true); |
| host_impl()->InitializeFrameSink(layer_tree_frame_sink.get()); |
| layer_tree_frame_sink_ = std::move(layer_tree_frame_sink); |
| } |
| |
| std::unique_ptr<FakeLayerTreeHostImpl> TestLayerTreeHostBase::TakeHostImpl() { |
| return std::move(host_impl_); |
| } |
| |
| void TestLayerTreeHostBase::SetupDefaultTrees(const gfx::Size& layer_bounds) { |
| scoped_refptr<FakeRasterSource> pending_raster_source = |
| FakeRasterSource::CreateFilled(layer_bounds); |
| scoped_refptr<FakeRasterSource> active_raster_source = |
| FakeRasterSource::CreateFilled(layer_bounds); |
| |
| SetupTrees(std::move(pending_raster_source), std::move(active_raster_source)); |
| } |
| |
| void TestLayerTreeHostBase::SetupTrees( |
| scoped_refptr<RasterSource> pending_raster_source, |
| scoped_refptr<RasterSource> active_raster_source) { |
| SetupPendingTree(std::move(active_raster_source)); |
| ActivateTree(); |
| SetupPendingTree(std::move(pending_raster_source)); |
| } |
| |
| void TestLayerTreeHostBase::SetupPendingTree( |
| scoped_refptr<RasterSource> raster_source) { |
| SetupPendingTree(std::move(raster_source), gfx::Size(), Region()); |
| } |
| |
| void TestLayerTreeHostBase::SetupPendingTree( |
| scoped_refptr<RasterSource> raster_source, |
| const gfx::Size& tile_size, |
| const Region& invalidation, |
| Layer::LayerMaskType mask_type) { |
| host_impl()->CreatePendingTree(); |
| host_impl()->pending_tree()->PushPageScaleFromMainThread(1.f, 0.00001f, |
| 100000.f); |
| LayerTreeImpl* pending_tree = host_impl()->pending_tree(); |
| pending_tree->SetDeviceViewportSize( |
| host_impl()->active_tree()->GetDeviceViewport().size()); |
| pending_tree->SetDeviceScaleFactor( |
| host_impl()->active_tree()->device_scale_factor()); |
| |
| // Steal from the recycled tree if possible. |
| LayerImpl* pending_root = pending_tree->root_layer_for_testing(); |
| std::unique_ptr<FakePictureLayerImpl> pending_layer; |
| DCHECK(!pending_root || pending_root->id() == root_id_); |
| if (!pending_root) { |
| std::unique_ptr<LayerImpl> new_pending_root = |
| LayerImpl::Create(pending_tree, root_id_); |
| switch (mask_type) { |
| case Layer::LayerMaskType::NOT_MASK: |
| pending_layer = FakePictureLayerImpl::Create(pending_tree, id_); |
| break; |
| case Layer::LayerMaskType::SINGLE_TEXTURE_MASK: |
| pending_layer = |
| FakePictureLayerImpl::CreateSingleTextureMask(pending_tree, id_); |
| break; |
| case Layer::LayerMaskType::MULTI_TEXTURE_MASK: |
| pending_layer = FakePictureLayerImpl::CreateMask(pending_tree, id_); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| if (!tile_size.IsEmpty()) |
| pending_layer->set_fixed_tile_size(tile_size); |
| pending_layer->SetDrawsContent(true); |
| pending_layer->SetScrollable(gfx::Size(1, 1)); |
| pending_root = new_pending_root.get(); |
| pending_tree->SetRootLayerForTesting(std::move(new_pending_root)); |
| } else { |
| pending_layer.reset(static_cast<FakePictureLayerImpl*>( |
| pending_root->test_properties() |
| ->RemoveChild(pending_root->test_properties()->children[0]) |
| .release())); |
| if (!tile_size.IsEmpty()) |
| pending_layer->set_fixed_tile_size(tile_size); |
| } |
| pending_root->test_properties()->force_render_surface = true; |
| // The bounds() just mirror the raster source size. |
| pending_layer->SetBounds(raster_source->GetSize()); |
| pending_layer->SetRasterSourceOnPending(raster_source, invalidation); |
| |
| pending_root->test_properties()->AddChild(std::move(pending_layer)); |
| LayerTreeImpl::ViewportLayerIds viewport_ids; |
| viewport_ids.page_scale = pending_tree->root_layer_for_testing()->id(); |
| pending_tree->SetViewportLayersFromIds(viewport_ids); |
| |
| pending_layer_ = static_cast<FakePictureLayerImpl*>( |
| host_impl()->pending_tree()->LayerById(id_)); |
| |
| // Add tilings/tiles for the layer. |
| RebuildPropertyTreesOnPendingTree(); |
| host_impl()->pending_tree()->UpdateDrawProperties(); |
| } |
| |
| void TestLayerTreeHostBase::ActivateTree() { |
| RebuildPropertyTreesOnPendingTree(); |
| host_impl()->ActivateSyncTree(); |
| CHECK(!host_impl()->pending_tree()); |
| CHECK(host_impl()->recycle_tree()); |
| old_pending_layer_ = pending_layer_; |
| pending_layer_ = nullptr; |
| active_layer_ = static_cast<FakePictureLayerImpl*>( |
| host_impl()->active_tree()->LayerById(id_)); |
| |
| host_impl()->active_tree()->UpdateDrawProperties(); |
| } |
| |
| void TestLayerTreeHostBase::PerformImplSideInvalidation() { |
| DCHECK(host_impl()->active_tree()); |
| DCHECK(!host_impl()->pending_tree()); |
| DCHECK(host_impl()->recycle_tree()); |
| |
| host_impl()->CreatePendingTree(); |
| host_impl()->sync_tree()->InvalidateRegionForImages( |
| host_impl()->tile_manager()->TakeImagesToInvalidateOnSyncTree()); |
| pending_layer_ = old_pending_layer_; |
| old_pending_layer_ = nullptr; |
| } |
| |
| void TestLayerTreeHostBase::RebuildPropertyTreesOnPendingTree() { |
| host_impl()->pending_tree()->property_trees()->needs_rebuild = true; |
| host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); |
| } |
| |
| void TestLayerTreeHostBase::SetInitialTreePriority() { |
| GlobalStateThatImpactsTilePriority state; |
| |
| state.soft_memory_limit_in_bytes = 100 * 1000 * 1000; |
| state.num_resources_limit = 10000; |
| state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2; |
| state.memory_limit_policy = ALLOW_ANYTHING; |
| state.tree_priority = SAME_PRIORITY_FOR_BOTH_TREES; |
| |
| host_impl_->resource_pool()->SetResourceUsageLimits( |
| state.soft_memory_limit_in_bytes, state.num_resources_limit); |
| host_impl_->tile_manager()->SetGlobalStateForTesting(state); |
| } |
| |
| } // namespace cc |