diff options
author | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-05 23:53:08 +0000 |
---|---|---|
committer | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-05 23:53:08 +0000 |
commit | a6c1b23057d3ac6b6fa95cf539cee43d9161ae18 (patch) | |
tree | b0dc74e4f51d0c30dab3d5af8221385fc70725b6 | |
parent | b58f32d76d2431c3e2372a85bb337caa55dc6183 (diff) | |
download | chromium_src-a6c1b23057d3ac6b6fa95cf539cee43d9161ae18.zip chromium_src-a6c1b23057d3ac6b6fa95cf539cee43d9161ae18.tar.gz chromium_src-a6c1b23057d3ac6b6fa95cf539cee43d9161ae18.tar.bz2 |
cc: Make gpu rasterization flag per page instead of per layer.
BUG=367198
Review URL: https://codereview.chromium.org/265823003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268320 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/layers/layer.cc | 4 | ||||
-rw-r--r-- | cc/layers/layer.h | 1 | ||||
-rw-r--r-- | cc/layers/picture_layer.cc | 17 | ||||
-rw-r--r-- | cc/layers/picture_layer.h | 3 | ||||
-rw-r--r-- | cc/layers/picture_layer_unittest.cc | 81 | ||||
-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 |
8 files changed, 183 insertions, 134 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index befedf7..60360d3 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -1043,6 +1043,10 @@ bool Layer::NeedMoreUpdates() { return false; } +bool Layer::IsSuitableForGpuRasterization() const { + return true; +} + scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() { if (client_) return client_->TakeDebugInfo(); diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 5e4a401..7e7d2861 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -363,6 +363,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, virtual void SetIsMask(bool is_mask) {} virtual void ReduceMemoryUsage() {} virtual void OnOutputSurfaceCreated() {} + virtual bool IsSuitableForGpuRasterization() const; virtual scoped_refptr<base::debug::ConvertableToTraceFormat> TakeDebugInfo(); diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index ca30346..700d285 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc @@ -53,7 +53,7 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { } layer_impl->SetIsMask(is_mask_); - layer_impl->SetUseGpuRasterization(ShouldUseGpuRasterization()); + layer_impl->SetUseGpuRasterization(layer_tree_host()->UseGpuRasterization()); // Unlike other properties, invalidation must always be set on layer_impl. // See PictureLayerImpl::PushPropertiesTo for more details. @@ -142,17 +142,6 @@ void PictureLayer::SetIsMask(bool is_mask) { is_mask_ = is_mask; } -bool PictureLayer::ShouldUseGpuRasterization() const { - if (layer_tree_host()->settings().gpu_rasterization_forced) { - return true; - } else if (layer_tree_host()->settings().gpu_rasterization_enabled) { - return layer_tree_host()->has_gpu_rasterization_trigger() && - pile_->is_suitable_for_gpu_rasterization(); - } else { - return false; - } -} - bool PictureLayer::SupportsLCDText() const { return true; } @@ -178,6 +167,10 @@ skia::RefPtr<SkPicture> PictureLayer::GetPicture() const { return picture; } +bool PictureLayer::IsSuitableForGpuRasterization() const { + return pile_->is_suitable_for_gpu_rasterization(); +} + void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) { benchmark->RunOnLayer(this); } diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index 184eea7..dd1bbfe 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h @@ -35,13 +35,12 @@ class CC_EXPORT PictureLayer : public Layer { virtual void SetIsMask(bool is_mask) OVERRIDE; virtual bool SupportsLCDText() const OVERRIDE; virtual skia::RefPtr<SkPicture> GetPicture() const OVERRIDE; + virtual bool IsSuitableForGpuRasterization() const OVERRIDE; virtual void RunMicroBenchmark(MicroBenchmark* benchmark) OVERRIDE; ContentLayerClient* client() { return client_; } - bool ShouldUseGpuRasterization() const; - PicturePile* GetPicturePileForTesting() const { return pile_.get(); } protected: diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index dfc24a0..3edb9c8 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc @@ -69,88 +69,19 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { } } -TEST(PictureLayerTest, ForcedCpuRaster) { +TEST(PictureLayerTest, SuitableForGpuRasterization) { MockContentLayerClient client; scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); - - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); - host->SetRootLayer(layer); - - // The default value is false. - EXPECT_FALSE(layer->ShouldUseGpuRasterization()); - - // Gpu rasterization cannot be enabled even with raster hint. - host->set_has_gpu_rasterization_trigger(true); - EXPECT_FALSE(layer->ShouldUseGpuRasterization()); -} - -TEST(PictureLayerTest, ForceGpuRaster) { - MockContentLayerClient client; - scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); - - LayerTreeSettings settings; - settings.gpu_rasterization_forced = true; - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(settings); - host->SetRootLayer(layer); - - // The default value is true. - EXPECT_TRUE(layer->ShouldUseGpuRasterization()); - - // Gpu rasterization cannot be disabled even with raster hint. - host->set_has_gpu_rasterization_trigger(false); - EXPECT_TRUE(layer->ShouldUseGpuRasterization()); - - // Gpu rasterization cannot be disabled even with skia veto. PicturePile* pile = layer->GetPicturePileForTesting(); - EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); - pile->SetUnsuitableForGpuRasterizationForTesting(); - EXPECT_TRUE(layer->ShouldUseGpuRasterization()); -} - -TEST(PictureLayerTest, EnableGpuRaster) { - MockContentLayerClient client; - scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); - - LayerTreeSettings settings; - settings.gpu_rasterization_enabled = true; - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(settings); - host->SetRootLayer(layer); - - // The default value is false. - EXPECT_FALSE(layer->ShouldUseGpuRasterization()); - - // Gpu rasterization can be enabled. - host->set_has_gpu_rasterization_trigger(true); - EXPECT_TRUE(layer->ShouldUseGpuRasterization()); - - // Gpu rasterization can be disabled. - host->set_has_gpu_rasterization_trigger(false); - EXPECT_FALSE(layer->ShouldUseGpuRasterization()); - - // Gpu rasterization can be enabled again. - host->set_has_gpu_rasterization_trigger(true); - EXPECT_TRUE(layer->ShouldUseGpuRasterization()); -} -TEST(PictureLayerTest, VetoGpuRaster) { - MockContentLayerClient client; - scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); - - LayerTreeSettings settings; - settings.gpu_rasterization_enabled = true; - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(settings); - host->SetRootLayer(layer); - - EXPECT_FALSE(layer->ShouldUseGpuRasterization()); - - host->set_has_gpu_rasterization_trigger(true); - EXPECT_TRUE(layer->ShouldUseGpuRasterization()); + // Layer is suitable for gpu rasterization by default. + EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); // Veto gpu rasterization. - PicturePile* pile = layer->GetPicturePileForTesting(); - EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization()); pile->SetUnsuitableForGpuRasterizationForTesting(); - EXPECT_FALSE(layer->ShouldUseGpuRasterization()); + EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization()); + EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); } } // namespace 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); |