diff options
Diffstat (limited to 'cc/trees')
-rw-r--r-- | cc/trees/layer_tree_host.cc | 25 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.h | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 184 |
3 files changed, 166 insertions, 45 deletions
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 65d5dd6..7df3186 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -109,6 +109,7 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, max_page_scale_factor_(1.f), trigger_idle_updates_(true), has_gpu_rasterization_trigger_(false), + content_is_suitable_for_gpu_rasterization_(true), background_color_(SK_ColorWHITE), has_transparent_background_(false), partial_texture_update_requests_(0), @@ -589,6 +590,10 @@ void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) { if (hud_layer_.get()) hud_layer_->RemoveFromParent(); + // Reset gpu rasterization flag. + // This flag is sticky until a new tree comes along. + content_is_suitable_for_gpu_rasterization_ = true; + SetNeedsFullTreeSync(); } @@ -608,6 +613,17 @@ void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) { proxy_->SetDebugState(debug_state); } +bool LayerTreeHost::UseGpuRasterization() const { + if (settings_.gpu_rasterization_forced) { + return true; + } else if (settings_.gpu_rasterization_enabled) { + return has_gpu_rasterization_trigger_ && + content_is_suitable_for_gpu_rasterization_; + } else { + return false; + } +} + void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) { if (device_viewport_size == device_viewport_size_) return; @@ -982,6 +998,15 @@ void LayerTreeHost::PaintLayerContents( DCHECK(!it->paint_properties().bounds.IsEmpty()); *did_paint_content |= it->Update(queue, &occlusion_tracker); *need_more_updates |= it->NeedMoreUpdates(); + // Note the '&&' with previous is-suitable state. + // This means that once the layer-tree becomes unsuitable for gpu + // rasterization due to some content, it will continue to be unsuitable + // even if that content is replaced by gpu-friendly content. + // This is to avoid switching back-and-forth between gpu and sw + // rasterization which may be both bad for performance and visually + // jarring. + content_is_suitable_for_gpu_rasterization_ &= + it->IsSuitableForGpuRasterization(); } occlusion_tracker.LeaveLayer(it); diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index b58ce39..380cc95 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -197,6 +197,7 @@ class CC_EXPORT LayerTreeHost { void set_has_gpu_rasterization_trigger(bool has_trigger) { has_gpu_rasterization_trigger_ = has_trigger; } + bool UseGpuRasterization() const; void SetViewportSize(const gfx::Size& device_viewport_size); void SetOverdrawBottomHeight(float overdraw_bottom_height); @@ -399,6 +400,7 @@ class CC_EXPORT LayerTreeHost { gfx::Transform impl_transform_; bool trigger_idle_updates_; bool has_gpu_rasterization_trigger_; + bool content_is_suitable_for_gpu_rasterization_; SkColor background_color_; bool has_transparent_background_; diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 1bf4213..ff8c08d 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -4970,55 +4970,135 @@ class LayerTreeHostTestHighResRequiredAfterEvictingUIResources MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources); +class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { + protected: + virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + settings->impl_side_painting = true; + + EXPECT_FALSE(settings->gpu_rasterization_enabled); + EXPECT_FALSE(settings->gpu_rasterization_forced); + } + + virtual void SetupTree() OVERRIDE { + LayerTreeHostTest::SetupTree(); + + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); + layer->SetBounds(gfx::Size(10, 10)); + layer->SetIsDrawable(true); + layer_tree_host()->root_layer()->AddChild(layer); + } + + virtual void BeginTest() OVERRIDE { + Layer* root = layer_tree_host()->root_layer(); + PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); + PicturePile* pile = layer->GetPicturePileForTesting(); + + // Verify default values. + EXPECT_TRUE(root->IsSuitableForGpuRasterization()); + EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); + EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); + + // Setting gpu rasterization trigger does not enable gpu rasterization. + layer_tree_host()->set_has_gpu_rasterization_trigger(true); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); + + PostSetNeedsCommitToMainThread(); + } + + virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + LayerImpl* root = host_impl->pending_tree()->root_layer(); + PictureLayerImpl* layer_impl = + static_cast<PictureLayerImpl*>(root->children()[0]); + + EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization()); + } + + virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + LayerImpl* root = host_impl->active_tree()->root_layer(); + PictureLayerImpl* layer_impl = + static_cast<PictureLayerImpl*>(root->children()[0]); + + EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization()); + EndTest(); + } + + virtual void AfterTest() OVERRIDE {} + + FakeContentLayerClient layer_client_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); + class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { protected: virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { settings->impl_side_painting = true; + + EXPECT_FALSE(settings->gpu_rasterization_enabled); settings->gpu_rasterization_enabled = true; } virtual void SetupTree() OVERRIDE { LayerTreeHostTest::SetupTree(); - scoped_refptr<PictureLayer> parent = PictureLayer::Create(&client_); - parent->SetBounds(gfx::Size(10, 10)); - layer_tree_host()->root_layer()->AddChild(parent); - - scoped_refptr<Layer> child = PictureLayer::Create(&client_); - child->SetBounds(gfx::Size(10, 10)); - parent->AddChild(child); + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); + layer->SetBounds(gfx::Size(10, 10)); + layer->SetIsDrawable(true); + layer_tree_host()->root_layer()->AddChild(layer); + } + virtual void BeginTest() OVERRIDE { + Layer* root = layer_tree_host()->root_layer(); + PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); + PicturePile* pile = layer->GetPicturePileForTesting(); + + // Verify default values. + EXPECT_TRUE(root->IsSuitableForGpuRasterization()); + EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); + EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); + + // Gpu rasterization trigger is relevant. layer_tree_host()->set_has_gpu_rasterization_trigger(true); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); + + // Content-based veto is relevant as well. + pile->SetUnsuitableForGpuRasterizationForTesting(); + EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); + // Veto will take effect when layers are updated. + // The results will be verified after commit is completed below. + // Since we are manually marking picture pile as unsuitable, + // make sure that the layer gets a chance to update. + layer->SetNeedsDisplay(); + PostSetNeedsCommitToMainThread(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { LayerImpl* root = host_impl->pending_tree()->root_layer(); - PictureLayerImpl* parent = + PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(root->children()[0]); - PictureLayerImpl* child = - static_cast<PictureLayerImpl*>(parent->children()[0]); - EXPECT_TRUE(parent->ShouldUseGpuRasterization()); - EXPECT_TRUE(child->ShouldUseGpuRasterization()); + EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization()); } virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { LayerImpl* root = host_impl->active_tree()->root_layer(); - PictureLayerImpl* parent = + PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(root->children()[0]); - PictureLayerImpl* child = - static_cast<PictureLayerImpl*>(parent->children()[0]); - EXPECT_TRUE(parent->ShouldUseGpuRasterization()); - EXPECT_TRUE(child->ShouldUseGpuRasterization()); + EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization()); EndTest(); } virtual void AfterTest() OVERRIDE {} - FakeContentLayerClient client_; + FakeContentLayerClient layer_client_; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); @@ -5027,55 +5107,69 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { protected: virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { settings->impl_side_painting = true; + + EXPECT_FALSE(settings->gpu_rasterization_forced); settings->gpu_rasterization_forced = true; } virtual void SetupTree() OVERRIDE { LayerTreeHostTest::SetupTree(); - scoped_refptr<PictureLayer> parent = PictureLayer::Create(&client_); - parent->SetBounds(gfx::Size(10, 10)); - layer_tree_host()->root_layer()->AddChild(parent); - - scoped_refptr<Layer> child = PictureLayer::Create(&client_); - child->SetBounds(gfx::Size(10, 10)); - parent->AddChild(child); - - layer_tree_host()->set_has_gpu_rasterization_trigger(false); + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); + layer->SetBounds(gfx::Size(10, 10)); + layer->SetIsDrawable(true); + layer_tree_host()->root_layer()->AddChild(layer); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + virtual void BeginTest() OVERRIDE { + Layer* root = layer_tree_host()->root_layer(); + PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); + PicturePile* pile = layer->GetPicturePileForTesting(); + + // Verify default values. + EXPECT_TRUE(root->IsSuitableForGpuRasterization()); + EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); + EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + + // With gpu rasterization forced, gpu rasterization trigger is irrelevant. + EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); + layer_tree_host()->set_has_gpu_rasterization_trigger(true); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); + + // Content-based veto is irrelevant as well. + pile->SetUnsuitableForGpuRasterizationForTesting(); + EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); + // Veto will take effect when layers are updated. + // The results will be verified after commit is completed below. + // Since we are manually marking picture pile as unsuitable, + // make sure that the layer gets a chance to update. + layer->SetNeedsDisplay(); + PostSetNeedsCommitToMainThread(); + } virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { LayerImpl* root = host_impl->pending_tree()->root_layer(); - PictureLayerImpl* parent = + PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(root->children()[0]); - PictureLayerImpl* child = - static_cast<PictureLayerImpl*>(parent->children()[0]); - // All layers should use GPU rasterization, regardless of whether a GPU - // rasterization trigger has been set. - EXPECT_TRUE(parent->ShouldUseGpuRasterization()); - EXPECT_TRUE(child->ShouldUseGpuRasterization()); + EXPECT_TRUE(layer_impl->ShouldUseGpuRasterization()); } virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { LayerImpl* root = host_impl->active_tree()->root_layer(); - PictureLayerImpl* parent = + PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(root->children()[0]); - PictureLayerImpl* child = - static_cast<PictureLayerImpl*>(parent->children()[0]); - // All layers should use GPU rasterization, regardless of whether a GPU - // rasterization trigger has been set. - EXPECT_TRUE(parent->ShouldUseGpuRasterization()); - EXPECT_TRUE(child->ShouldUseGpuRasterization()); + EXPECT_TRUE(layer_impl->ShouldUseGpuRasterization()); EndTest(); } virtual void AfterTest() OVERRIDE {} - FakeContentLayerClient client_; + FakeContentLayerClient layer_client_; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced); |