summaryrefslogtreecommitdiffstats
path: root/cc/trees
diff options
context:
space:
mode:
Diffstat (limited to 'cc/trees')
-rw-r--r--cc/trees/layer_tree_host.cc25
-rw-r--r--cc/trees/layer_tree_host.h2
-rw-r--r--cc/trees/layer_tree_host_unittest.cc184
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);