summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 22:37:28 +0000
committerccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 22:37:28 +0000
commit039fa8c89dba9061a69a43107ca4016b255a7d39 (patch)
tree5a228350d7dc3ff9a6510df95691d37f7918d3ec
parent3e83618c9c1254dc0a76929dcc98a44cb1ba809b (diff)
downloadchromium_src-039fa8c89dba9061a69a43107ca4016b255a7d39.zip
chromium_src-039fa8c89dba9061a69a43107ca4016b255a7d39.tar.gz
chromium_src-039fa8c89dba9061a69a43107ca4016b255a7d39.tar.bz2
Fix transition from hardware to software compositing.
When the the LayerTreeHost's output surface changes, the capabilities of the renderer change. In particular, support for BGRA textures goes away when transitioning from hardware compositing to software compositing. The preferred texture format is cached by tiled layer types and isn't updated when the renderer's capabilities change, resulting in BGRA textures being requested for the new renderer that doesn't support them. Add a callback to all layers on output surface creation so they can update any cached values that they have. Also fix a bug where LayerTreeHostImpl::resource_provider_ was assumed to exist when getting a callback from the GPU memory manager, when in it may have already been destroyed. BUG=304384 NOTRY=true Review URL: https://codereview.chromium.org/26323002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227824 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/content_layer.cc6
-rw-r--r--cc/layers/content_layer.h2
-rw-r--r--cc/layers/image_layer.cc6
-rw-r--r--cc/layers/image_layer.h1
-rw-r--r--cc/layers/layer.h1
-rw-r--r--cc/layers/tiled_layer.cc13
-rw-r--r--cc/layers/tiled_layer.h1
-rw-r--r--cc/test/fake_content_layer.cc6
-rw-r--r--cc/test/fake_content_layer.h6
-rw-r--r--cc/trees/layer_tree_host.cc10
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc69
11 files changed, 121 insertions, 0 deletions
diff --git a/cc/layers/content_layer.cc b/cc/layers/content_layer.cc
index 3d611ee..24cb8b3 100644
--- a/cc/layers/content_layer.cc
+++ b/cc/layers/content_layer.cc
@@ -165,4 +165,10 @@ skia::RefPtr<SkPicture> ContentLayer::GetPicture() const {
return picture;
}
+void ContentLayer::OnOutputSurfaceCreated() {
+ SetTextureFormat(
+ layer_tree_host()->GetRendererCapabilities().best_texture_format);
+ TiledLayer::OnOutputSurfaceCreated();
+}
+
} // namespace cc
diff --git a/cc/layers/content_layer.h b/cc/layers/content_layer.h
index a076c31..e7782ce 100644
--- a/cc/layers/content_layer.h
+++ b/cc/layers/content_layer.h
@@ -54,6 +54,8 @@ class CC_EXPORT ContentLayer : public TiledLayer {
virtual skia::RefPtr<SkPicture> GetPicture() const OVERRIDE;
+ virtual void OnOutputSurfaceCreated() OVERRIDE;
+
protected:
explicit ContentLayer(ContentLayerClient* client);
virtual ~ContentLayer();
diff --git a/cc/layers/image_layer.cc b/cc/layers/image_layer.cc
index bbf1aa8..2f90bfc 100644
--- a/cc/layers/image_layer.cc
+++ b/cc/layers/image_layer.cc
@@ -80,6 +80,12 @@ bool ImageLayer::DrawsContent() const {
return !bitmap_.isNull() && TiledLayer::DrawsContent();
}
+void ImageLayer::OnOutputSurfaceCreated() {
+ SetTextureFormat(
+ layer_tree_host()->GetRendererCapabilities().best_texture_format);
+ TiledLayer::OnOutputSurfaceCreated();
+}
+
float ImageLayer::ImageContentsScaleX() const {
if (bounds().IsEmpty() || bitmap_.width() == 0)
return 1;
diff --git a/cc/layers/image_layer.h b/cc/layers/image_layer.h
index ae8383a..6cd8275 100644
--- a/cc/layers/image_layer.h
+++ b/cc/layers/image_layer.h
@@ -31,6 +31,7 @@ class CC_EXPORT ImageLayer : public TiledLayer {
float* contents_scale_x,
float* contents_scale_y,
gfx::Size* content_bounds) OVERRIDE;
+ virtual void OnOutputSurfaceCreated() OVERRIDE;
void SetBitmap(const SkBitmap& image);
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 6e86d3e..1f8c8ac 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -327,6 +327,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
virtual bool NeedMoreUpdates();
virtual void SetIsMask(bool is_mask) {}
virtual void ReduceMemoryUsage() {}
+ virtual void OnOutputSurfaceCreated() {}
virtual std::string DebugName();
diff --git a/cc/layers/tiled_layer.cc b/cc/layers/tiled_layer.cc
index da42554..a650672 100644
--- a/cc/layers/tiled_layer.cc
+++ b/cc/layers/tiled_layer.cc
@@ -850,6 +850,19 @@ bool TiledLayer::Update(ResourceUpdateQueue* queue,
return updated;
}
+void TiledLayer::OnOutputSurfaceCreated() {
+ // Ensure that all textures are of the right format.
+ for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
+ iter != tiler_->tiles().end();
+ ++iter) {
+ UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
+ if (!tile)
+ continue;
+ PrioritizedResource* resource = tile->managed_resource();
+ resource->SetDimensions(resource->size(), texture_format_);
+ }
+}
+
bool TiledLayer::NeedsIdlePaint() {
// Don't trigger more paints if we failed (as we'll just fail again).
if (failed_update_ || visible_content_rect().IsEmpty() ||
diff --git a/cc/layers/tiled_layer.h b/cc/layers/tiled_layer.h
index 3870d69..a7bd9f7b 100644
--- a/cc/layers/tiled_layer.h
+++ b/cc/layers/tiled_layer.h
@@ -36,6 +36,7 @@ class CC_EXPORT TiledLayer : public ContentsScalingLayer {
virtual Region VisibleContentOpaqueRegion() const OVERRIDE;
virtual bool Update(ResourceUpdateQueue* queue,
const OcclusionTracker* occlusion) OVERRIDE;
+ virtual void OnOutputSurfaceCreated() OVERRIDE;
protected:
TiledLayer();
diff --git a/cc/test/fake_content_layer.cc b/cc/test/fake_content_layer.cc
index 077831fd..56a52cc 100644
--- a/cc/test/fake_content_layer.cc
+++ b/cc/test/fake_content_layer.cc
@@ -13,6 +13,7 @@ FakeContentLayer::FakeContentLayer(ContentLayerClient* client)
: ContentLayer(client),
update_count_(0),
push_properties_count_(0),
+ output_surface_created_count_(0),
always_update_resources_(false) {
SetAnchorPoint(gfx::PointF(0.f, 0.f));
SetBounds(gfx::Size(1, 1));
@@ -38,6 +39,11 @@ void FakeContentLayer::PushPropertiesTo(LayerImpl* layer) {
push_properties_count_++;
}
+void FakeContentLayer::OnOutputSurfaceCreated() {
+ ContentLayer::OnOutputSurfaceCreated();
+ output_surface_created_count_++;
+}
+
bool FakeContentLayer::HaveBackingAt(int i, int j) {
const PrioritizedResource* resource = ResourceAtForTesting(i, j);
return resource && resource->have_backing_texture();
diff --git a/cc/test/fake_content_layer.h b/cc/test/fake_content_layer.h
index 191a634..35344a7 100644
--- a/cc/test/fake_content_layer.h
+++ b/cc/test/fake_content_layer.h
@@ -35,6 +35,11 @@ class FakeContentLayer : public ContentLayer {
virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE;
+ virtual void OnOutputSurfaceCreated() OVERRIDE;
+ size_t output_surface_created_count() const {
+ return output_surface_created_count_;
+ }
+
bool HaveBackingAt(int i, int j);
private:
@@ -43,6 +48,7 @@ class FakeContentLayer : public ContentLayer {
size_t update_count_;
size_t push_properties_count_;
+ size_t output_surface_created_count_;
bool always_update_resources_;
};
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 0be4c31..2722c44 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -194,6 +194,10 @@ void LayerTreeHost::SetLayerTreeHostClientReady() {
proxy_->SetLayerTreeHostClientReady();
}
+static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) {
+ layer->OnOutputSurfaceCreated();
+}
+
LayerTreeHost::CreateResult
LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
TRACE_EVENT1("cc",
@@ -213,6 +217,12 @@ LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
}
+ if (root_layer()) {
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ root_layer(),
+ base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
+ }
+
client_->DidInitializeOutputSurface(true);
return CreateSucceeded;
}
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 0c0a8de..263c7a6 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -2245,5 +2245,74 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostEviction);
+class LayerTreeHostContextTestSurfaceCreateCallback
+ : public LayerTreeHostContextTest {
+ public:
+ LayerTreeHostContextTestSurfaceCreateCallback()
+ : LayerTreeHostContextTest(),
+ layer_(FakeContentLayer::Create(&client_)),
+ num_commits_(0) {}
+
+ virtual void SetupTree() OVERRIDE {
+ layer_->SetBounds(gfx::Size(10, 20));
+ layer_tree_host()->SetRootLayer(layer_);
+ LayerTreeHostContextTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void DidCommit() OVERRIDE {
+ switch (num_commits_) {
+ case 0:
+ EXPECT_EQ(1u, layer_->output_surface_created_count());
+ layer_tree_host()->SetNeedsCommit();
+ break;
+ case 1:
+ EXPECT_EQ(1u, layer_->output_surface_created_count());
+ layer_tree_host()->SetNeedsCommit();
+ break;
+ case 2:
+ EXPECT_EQ(1u, layer_->output_surface_created_count());
+ break;
+ case 3:
+ EXPECT_EQ(2u, layer_->output_surface_created_count());
+ layer_tree_host()->SetNeedsCommit();
+ break;
+ }
+ ++num_commits_;
+ }
+
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ LayerTreeHostContextTest::CommitCompleteOnThread(impl);
+ switch (num_commits_) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ LoseContext();
+ break;
+ case 3:
+ EndTest();
+ break;
+ }
+ }
+
+ virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE {
+ EXPECT_TRUE(succeeded);
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ protected:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> layer_;
+ int num_commits_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback);
+
} // namespace
} // namespace cc