diff options
author | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-09 22:37:28 +0000 |
---|---|---|
committer | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-09 22:37:28 +0000 |
commit | 039fa8c89dba9061a69a43107ca4016b255a7d39 (patch) | |
tree | 5a228350d7dc3ff9a6510df95691d37f7918d3ec | |
parent | 3e83618c9c1254dc0a76929dcc98a44cb1ba809b (diff) | |
download | chromium_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.cc | 6 | ||||
-rw-r--r-- | cc/layers/content_layer.h | 2 | ||||
-rw-r--r-- | cc/layers/image_layer.cc | 6 | ||||
-rw-r--r-- | cc/layers/image_layer.h | 1 | ||||
-rw-r--r-- | cc/layers/layer.h | 1 | ||||
-rw-r--r-- | cc/layers/tiled_layer.cc | 13 | ||||
-rw-r--r-- | cc/layers/tiled_layer.h | 1 | ||||
-rw-r--r-- | cc/test/fake_content_layer.cc | 6 | ||||
-rw-r--r-- | cc/test/fake_content_layer.h | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 10 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_context.cc | 69 |
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 |