summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreveman <reveman@chromium.org>2015-09-23 17:19:43 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-24 00:34:48 +0000
commitd180dfc3198c1e58a8c10f7349f3d949e22c5f3d (patch)
tree3f1b2d58647d991dd3ab1d3ba13da4f7d8205979
parentf86718093f9c88d956207b527cf5bed4a872a24f (diff)
downloadchromium_src-d180dfc3198c1e58a8c10f7349f3d949e22c5f3d.zip
chromium_src-d180dfc3198c1e58a8c10f7349f3d949e22c5f3d.tar.gz
chromium_src-d180dfc3198c1e58a8c10f7349f3d949e22c5f3d.tar.bz2
Re-land: cc: Implement shared worker contexts.
This moves the responsibility to call BindToCurrentThread/SetupLock out of cc::OutputSurface and to the maintainer of the (possibly) shared context. OutputSurface now needs to be destroyed on the same thread they were created. OutputSurface::DetachFromClient() can be used to destroy any resources that need to be destroyed on the thread that the OutputSurface has been bound to. BUG=523411,525811 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1336733002 Cr-Commit-Position: refs/heads/master@{#350409}
-rw-r--r--cc/layers/delegated_renderer_layer_impl_unittest.cc6
-rw-r--r--cc/layers/heads_up_display_layer_impl_unittest.cc3
-rw-r--r--cc/layers/layer_impl_unittest.cc9
-rw-r--r--cc/layers/nine_patch_layer_impl_unittest.cc3
-rw-r--r--cc/layers/picture_image_layer_impl_unittest.cc4
-rw-r--r--cc/layers/picture_layer_impl_perftest.cc4
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc23
-rw-r--r--cc/layers/texture_layer_unittest.cc4
-rw-r--r--cc/layers/ui_resource_layer_impl_unittest.cc9
-rw-r--r--cc/output/context_provider.h14
-rw-r--r--cc/output/output_surface.cc31
-rw-r--r--cc/output/output_surface.h10
-rw-r--r--cc/raster/tile_task_worker_pool_unittest.cc5
-rw-r--r--cc/test/fake_output_surface.h18
-rw-r--r--cc/test/fake_proxy.cc4
-rw-r--r--cc/test/fake_proxy.h4
-rw-r--r--cc/test/layer_test_common.cc4
-rw-r--r--cc/test/layer_test_common.h1
-rw-r--r--cc/test/layer_tree_test.cc4
-rw-r--r--cc/test/test_context_provider.cc15
-rw-r--r--cc/test/test_context_provider.h3
-rw-r--r--cc/tiles/tile_manager_perftest.cc4
-rw-r--r--cc/tiles/tile_manager_unittest.cc16
-rw-r--r--cc/trees/layer_tree_host.cc15
-rw-r--r--cc/trees/layer_tree_host.h7
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc3
-rw-r--r--cc/trees/layer_tree_host_impl.cc43
-rw-r--r--cc/trees/layer_tree_host_impl.h9
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc54
-rw-r--r--cc/trees/layer_tree_host_unittest.cc18
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc1
-rw-r--r--cc/trees/layer_tree_impl_unittest.cc8
-rw-r--r--cc/trees/occlusion_tracker_perftest.cc6
-rw-r--r--cc/trees/proxy.h4
-rw-r--r--cc/trees/single_thread_proxy.cc7
-rw-r--r--cc/trees/single_thread_proxy.h4
-rw-r--r--cc/trees/thread_proxy.cc25
-rw-r--r--cc/trees/thread_proxy.h11
-rw-r--r--content/browser/android/in_process/synchronous_compositor_factory_impl.cc68
-rw-r--r--content/browser/android/in_process/synchronous_compositor_factory_impl.h6
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc14
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.h1
-rw-r--r--content/browser/compositor/gpu_process_transport_factory.cc12
-rw-r--r--content/child/child_thread_impl.cc8
-rw-r--r--content/renderer/gpu/compositor_output_surface.cc30
-rw-r--r--content/renderer/gpu/compositor_output_surface.h1
-rw-r--r--content/renderer/gpu/mailbox_output_surface.cc5
-rw-r--r--content/renderer/gpu/mailbox_output_surface.h1
-rw-r--r--content/renderer/render_thread_impl.cc26
-rw-r--r--content/renderer/render_thread_impl.h4
-rw-r--r--content/renderer/render_widget.cc7
-rw-r--r--ui/compositor/test/in_process_context_factory.cc32
-rw-r--r--ui/compositor/test/in_process_context_factory.h4
-rw-r--r--ui/compositor/test/in_process_context_provider.h18
54 files changed, 451 insertions, 199 deletions
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc
index 69857dc..8410221 100644
--- a/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -32,13 +32,14 @@ class DelegatedRendererLayerImplTest : public testing::Test {
public:
DelegatedRendererLayerImplTest()
: proxy_(),
- always_impl_thread_and_main_thread_blocked_(&proxy_) {
+ always_impl_thread_and_main_thread_blocked_(&proxy_),
+ output_surface_(FakeOutputSurface::Create3d()) {
LayerTreeSettings settings;
settings.minimum_occlusion_tracking_size = gfx::Size();
host_impl_.reset(new FakeLayerTreeHostImpl(
settings, &proxy_, &shared_bitmap_manager_, &task_graph_runner_));
- host_impl_->InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl_->InitializeRenderer(output_surface_.get());
host_impl_->SetViewportSize(gfx::Size(10, 10));
}
@@ -48,6 +49,7 @@ class DelegatedRendererLayerImplTest : public testing::Test {
always_impl_thread_and_main_thread_blocked_;
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<LayerTreeHostImpl> host_impl_;
};
diff --git a/cc/layers/heads_up_display_layer_impl_unittest.cc b/cc/layers/heads_up_display_layer_impl_unittest.cc
index ad22155..ef37783 100644
--- a/cc/layers/heads_up_display_layer_impl_unittest.cc
+++ b/cc/layers/heads_up_display_layer_impl_unittest.cc
@@ -34,10 +34,11 @@ TEST(HeadsUpDisplayLayerImplTest, ResourcelessSoftwareDrawAfterResourceLoss) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
host_impl.CreatePendingTree();
- host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl.InitializeRenderer(output_surface.get());
scoped_ptr<HeadsUpDisplayLayerImpl> layer =
HeadsUpDisplayLayerImpl::Create(host_impl.pending_tree(), 1);
layer->SetBounds(gfx::Size(100, 100));
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc
index 0676597..7404e4e 100644
--- a/cc/layers/layer_impl_unittest.cc
+++ b/cc/layers/layer_impl_unittest.cc
@@ -89,9 +89,10 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
+ EXPECT_TRUE(host_impl.InitializeRenderer(output_surface.get()));
scoped_ptr<LayerImpl> root_clip =
LayerImpl::Create(host_impl.active_tree(), 1);
scoped_ptr<LayerImpl> root_ptr =
@@ -247,9 +248,10 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
+ EXPECT_TRUE(host_impl.InitializeRenderer(output_surface.get()));
host_impl.active_tree()->SetRootLayer(
LayerImpl::Create(host_impl.active_tree(), 1));
LayerImpl* root = host_impl.active_tree()->root_layer();
@@ -361,9 +363,10 @@ TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
+ EXPECT_TRUE(host_impl.InitializeRenderer(output_surface.get()));
scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
diff --git a/cc/layers/nine_patch_layer_impl_unittest.cc b/cc/layers/nine_patch_layer_impl_unittest.cc
index ac77d12..3405bc5 100644
--- a/cc/layers/nine_patch_layer_impl_unittest.cc
+++ b/cc/layers/nine_patch_layer_impl_unittest.cc
@@ -46,9 +46,10 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size,
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl.InitializeRenderer(output_surface.get());
scoped_ptr<NinePatchLayerImpl> layer =
NinePatchLayerImpl::Create(host_impl.active_tree(), 1);
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc
index 2a9dda7..01ad1f3 100644
--- a/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -43,12 +43,13 @@ class PictureImageLayerImplTest : public testing::Test {
public:
PictureImageLayerImplTest()
: proxy_(base::ThreadTaskRunnerHandle::Get()),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(PictureLayerImplImageTestSettings(),
&proxy_,
&shared_bitmap_manager_,
&task_graph_runner_) {
host_impl_.CreatePendingTree();
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl_.InitializeRenderer(output_surface_.get());
}
scoped_ptr<TestablePictureImageLayerImpl> CreateLayer(int id,
@@ -93,6 +94,7 @@ class PictureImageLayerImplTest : public testing::Test {
FakeImplProxy proxy_;
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
FakeLayerTreeHostImpl host_impl_;
};
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc
index 9e7d82b..85d8c26 100644
--- a/cc/layers/picture_layer_impl_perftest.cc
+++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -41,6 +41,7 @@ class PictureLayerImplPerfTest : public testing::Test {
public:
PictureLayerImplPerfTest()
: proxy_(base::ThreadTaskRunnerHandle::Get()),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(LayerTreeSettings(),
&proxy_,
&shared_bitmap_manager_,
@@ -50,7 +51,7 @@ class PictureLayerImplPerfTest : public testing::Test {
kTimeCheckInterval) {}
void SetUp() override {
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl_.InitializeRenderer(output_surface_.get());
}
void SetupActiveTree(const gfx::Size& layer_bounds,
@@ -164,6 +165,7 @@ class PictureLayerImplPerfTest : public testing::Test {
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
FakeImplProxy proxy_;
+ scoped_ptr<OutputSurface> output_surface_;
FakeLayerTreeHostImpl host_impl_;
FakePictureLayerImpl* active_layer_;
LapTimer timer_;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 1628c0c5..970742b 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -93,6 +93,7 @@ class PictureLayerImplTest : public testing::Test {
public:
PictureLayerImplTest()
: proxy_(base::ThreadTaskRunnerHandle::Get()),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(LowResTilingsSettings(),
&proxy_,
&shared_bitmap_manager_,
@@ -107,6 +108,7 @@ class PictureLayerImplTest : public testing::Test {
explicit PictureLayerImplTest(const LayerTreeSettings& settings)
: proxy_(base::ThreadTaskRunnerHandle::Get()),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(settings,
&proxy_,
&shared_bitmap_manager_,
@@ -121,7 +123,7 @@ class PictureLayerImplTest : public testing::Test {
void SetUp() override { InitializeRenderer(); }
virtual void InitializeRenderer() {
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl_.InitializeRenderer(output_surface_.get());
}
void SetupDefaultTrees(const gfx::Size& layer_bounds) {
@@ -359,6 +361,7 @@ class PictureLayerImplTest : public testing::Test {
FakeImplProxy proxy_;
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
FakeLayerTreeHostImpl host_impl_;
int root_id_;
int id_;
@@ -1627,8 +1630,10 @@ TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) {
TestWebGraphicsContext3D::Create();
context->set_max_texture_size(140);
host_impl_.DidLoseOutputSurface();
- host_impl_.InitializeRenderer(
- FakeOutputSurface::Create3d(context.Pass()).Pass());
+ scoped_ptr<OutputSurface> new_output_surface =
+ FakeOutputSurface::Create3d(context.Pass());
+ host_impl_.InitializeRenderer(new_output_surface.get());
+ output_surface_ = new_output_surface.Pass();
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, 0.f,
false);
@@ -1672,8 +1677,10 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
TestWebGraphicsContext3D::Create();
context->set_max_texture_size(140);
host_impl_.DidLoseOutputSurface();
- host_impl_.InitializeRenderer(
- FakeOutputSurface::Create3d(context.Pass()).Pass());
+ scoped_ptr<OutputSurface> new_output_surface =
+ FakeOutputSurface::Create3d(context.Pass());
+ host_impl_.InitializeRenderer(new_output_surface.get());
+ output_surface_ = new_output_surface.Pass();
SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f,
false);
@@ -3925,10 +3932,12 @@ TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) {
class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest {
public:
- PictureLayerImplTestWithDelegatingRenderer() : PictureLayerImplTest() {}
+ PictureLayerImplTestWithDelegatingRenderer() : PictureLayerImplTest() {
+ output_surface_ = FakeOutputSurface::CreateDelegating3d();
+ }
void InitializeRenderer() override {
- host_impl_.InitializeRenderer(FakeOutputSurface::CreateDelegating3d());
+ host_impl_.InitializeRenderer(output_surface_.get());
}
};
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 22962a7..8c138c3 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -189,6 +189,7 @@ class TextureLayerTest : public testing::Test {
TextureLayerTest()
: fake_client_(
FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
test_data_(&shared_bitmap_manager_) {}
@@ -214,6 +215,7 @@ class TextureLayerTest : public testing::Test {
FakeLayerTreeHostClient fake_client_;
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
FakeLayerTreeHostImpl host_impl_;
CommonMailboxObjects test_data_;
LayerSettings layer_settings_;
@@ -833,7 +835,7 @@ class TextureLayerImplWithMailboxTest : public TextureLayerTest {
TextureLayerTest::SetUp();
layer_tree_host_ =
MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
- EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
+ EXPECT_TRUE(host_impl_.InitializeRenderer(output_surface_.get()));
}
bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
diff --git a/cc/layers/ui_resource_layer_impl_unittest.cc b/cc/layers/ui_resource_layer_impl_unittest.cc
index e31d68a..826c53f 100644
--- a/cc/layers/ui_resource_layer_impl_unittest.cc
+++ b/cc/layers/ui_resource_layer_impl_unittest.cc
@@ -60,9 +60,10 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl.InitializeRenderer(output_surface.get());
// Make sure we're appending quads when there are valid values.
gfx::Size bitmap_size(100, 100);
@@ -106,9 +107,10 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl.InitializeRenderer(output_surface.get());
gfx::Size bitmap_size(100, 100);
gfx::Size layer_size(100, 100);;
@@ -136,9 +138,10 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
- host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl.InitializeRenderer(output_surface.get());
gfx::Size bitmap_size(100, 100);
gfx::Size layer_size(100, 100);
diff --git a/cc/output/context_provider.h b/cc/output/context_provider.h
index c024e02..47eff20 100644
--- a/cc/output/context_provider.h
+++ b/cc/output/context_provider.h
@@ -32,11 +32,11 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
explicit ScopedContextLock(ContextProvider* context_provider)
: context_provider_(context_provider),
context_lock_(*context_provider_->GetLock()) {
- // Allow current thread to bind to |context_provider|.
+ // Allow current thread to use |context_provider_|.
context_provider_->DetachFromThread();
}
~ScopedContextLock() {
- // Allow a different thread to bind to |context_provider|.
+ // Allow usage by thread for which |context_provider_| is bound to.
context_provider_->DetachFromThread();
}
@@ -51,7 +51,9 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
// Bind the 3d context to the current thread. This should be called before
// accessing the contexts. Calling it more than once should have no effect.
// Once this function has been called, the class should only be accessed
- // from the same thread.
+ // from the same thread unless the function has some explicitly specified
+ // rules for access on a different thread. See SetupLockOnMainThread(), which
+ // can be used to provide access from multiple threads.
virtual bool BindToCurrentThread() = 0;
virtual void DetachFromThread() {}
@@ -70,11 +72,13 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
// See skia GrContext::resetContext for details.
virtual void InvalidateGrContext(uint32_t state) = 0;
- // Sets up a lock so this context can be used from multiple threads.
+ // Sets up a lock so this context can be used from multiple threads. After
+ // calling this, all functions without explicit thread usage constraints can
+ // be used on any thread while the lock returned by GetLock() is acquired.
virtual void SetupLock() = 0;
// Returns the lock that should be held if using this context from multiple
- // threads.
+ // threads. This can be called on any thread.
virtual base::Lock* GetLock() = 0;
// Returns the capabilities of the currently bound 3d context.
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index 5014fc0..d0300fe 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -120,6 +120,7 @@ OutputSurface::OutputSurface(
device_scale_factor_(-1),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this) {
+ client_thread_checker_.DetachFromThread();
}
OutputSurface::OutputSurface(
@@ -194,12 +195,8 @@ OutputSurface::~OutputSurface() {
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
- if (context_provider_.get()) {
- context_provider_->SetLostContextCallback(
- ContextProvider::LostContextCallback());
- context_provider_->SetMemoryPolicyChangedCallback(
- ContextProvider::MemoryPolicyChangedCallback());
- }
+ if (client_)
+ DetachFromClient();
}
bool OutputSurface::HasExternalStencilTest() const {
@@ -207,7 +204,9 @@ bool OutputSurface::HasExternalStencilTest() const {
}
bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
+ DCHECK(client_thread_checker_.CalledOnValidThread());
DCHECK(client);
+ DCHECK(!client_);
client_ = client;
bool success = true;
@@ -221,12 +220,6 @@ bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
}
}
- if (success && worker_context_provider_.get()) {
- success = worker_context_provider_->BindToCurrentThread();
- if (success)
- worker_context_provider_->SetupLock();
- }
-
if (!success)
client_ = NULL;
@@ -244,6 +237,20 @@ bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
return success;
}
+void OutputSurface::DetachFromClient() {
+ DCHECK(client_thread_checker_.CalledOnValidThread());
+ DCHECK(client_);
+ if (context_provider_.get()) {
+ context_provider_->SetLostContextCallback(
+ ContextProvider::LostContextCallback());
+ context_provider_->SetMemoryPolicyChangedCallback(
+ ContextProvider::MemoryPolicyChangedCallback());
+ }
+ context_provider_ = nullptr;
+ client_ = nullptr;
+ weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
void OutputSurface::EnsureBackbuffer() {
if (software_device_)
software_device_->EnsureBackbuffer();
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index f2cace6..0b7c194 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
#include "cc/base/cc_export.h"
#include "cc/output/context_provider.h"
#include "cc/output/overlay_candidate_validator.h"
@@ -112,10 +113,14 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider {
// Called by the compositor on the compositor thread. This is a place where
// thread-specific data for the output surface can be initialized, since from
- // this point on the output surface will only be used on the compositor
- // thread.
+ // this point to when DetachFromClient() is called the output surface will
+ // only be used on the compositor thread.
virtual bool BindToClient(OutputSurfaceClient* client);
+ // Called by the compositor on the compositor thread. This is a place where
+ // thread-specific data for the output surface can be uninitialized.
+ virtual void DetachFromClient();
+
virtual void EnsureBackbuffer();
virtual void DiscardBackbuffer();
@@ -180,6 +185,7 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider {
scoped_ptr<SoftwareOutputDevice> software_device_;
gfx::Size surface_size_;
float device_scale_factor_;
+ base::ThreadChecker client_thread_checker_;
void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval);
diff --git a/cc/raster/tile_task_worker_pool_unittest.cc b/cc/raster/tile_task_worker_pool_unittest.cc
index d8e0d19..8ecdb6c 100644
--- a/cc/raster/tile_task_worker_pool_unittest.cc
+++ b/cc/raster/tile_task_worker_pool_unittest.cc
@@ -130,9 +130,10 @@ class TileTaskWorkerPoolTest
TileTaskWorkerPoolTest()
: context_provider_(TestContextProvider::Create()),
- worker_context_provider_(TestContextProvider::Create()),
+ worker_context_provider_(TestContextProvider::CreateWorker()),
all_tile_tasks_finished_(
- base::ThreadTaskRunnerHandle::Get().get(),
+ base::ThreadTaskRunnerHandle::Get()
+ .get(),
base::Bind(&TileTaskWorkerPoolTest::AllTileTasksFinished,
base::Unretained(this))),
timeout_seconds_(5),
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
index 066f027..d2af2e3 100644
--- a/cc/test/fake_output_surface.h
+++ b/cc/test/fake_output_surface.h
@@ -23,14 +23,15 @@ class FakeOutputSurface : public OutputSurface {
~FakeOutputSurface() override;
static scoped_ptr<FakeOutputSurface> Create3d() {
- return make_scoped_ptr(new FakeOutputSurface(
- TestContextProvider::Create(), TestContextProvider::Create(), false));
+ return make_scoped_ptr(
+ new FakeOutputSurface(TestContextProvider::Create(),
+ TestContextProvider::CreateWorker(), false));
}
static scoped_ptr<FakeOutputSurface> Create3d(
scoped_refptr<ContextProvider> context_provider) {
return make_scoped_ptr(new FakeOutputSurface(
- context_provider, TestContextProvider::Create(), false));
+ context_provider, TestContextProvider::CreateWorker(), false));
}
static scoped_ptr<FakeOutputSurface> Create3d(
@@ -44,7 +45,7 @@ class FakeOutputSurface : public OutputSurface {
scoped_ptr<TestWebGraphicsContext3D> context) {
return make_scoped_ptr(
new FakeOutputSurface(TestContextProvider::Create(context.Pass()),
- TestContextProvider::Create(), false));
+ TestContextProvider::CreateWorker(), false));
}
static scoped_ptr<FakeOutputSurface> CreateSoftware(
@@ -54,21 +55,22 @@ class FakeOutputSurface : public OutputSurface {
}
static scoped_ptr<FakeOutputSurface> CreateDelegating3d() {
- return make_scoped_ptr(new FakeOutputSurface(
- TestContextProvider::Create(), TestContextProvider::Create(), true));
+ return make_scoped_ptr(
+ new FakeOutputSurface(TestContextProvider::Create(),
+ TestContextProvider::CreateWorker(), true));
}
static scoped_ptr<FakeOutputSurface> CreateDelegating3d(
scoped_refptr<TestContextProvider> context_provider) {
return make_scoped_ptr(new FakeOutputSurface(
- context_provider, TestContextProvider::Create(), true));
+ context_provider, TestContextProvider::CreateWorker(), true));
}
static scoped_ptr<FakeOutputSurface> CreateDelegating3d(
scoped_ptr<TestWebGraphicsContext3D> context) {
return make_scoped_ptr(
new FakeOutputSurface(TestContextProvider::Create(context.Pass()),
- TestContextProvider::Create(), true));
+ TestContextProvider::CreateWorker(), true));
}
static scoped_ptr<FakeOutputSurface> CreateDelegatingSoftware(
diff --git a/cc/test/fake_proxy.cc b/cc/test/fake_proxy.cc
index 87bea06..cc254eb 100644
--- a/cc/test/fake_proxy.cc
+++ b/cc/test/fake_proxy.cc
@@ -24,9 +24,7 @@ RendererCapabilities& FakeProxy::GetRendererCapabilities() {
return capabilities_;
}
-scoped_ptr<OutputSurface> FakeProxy::ReleaseOutputSurface() {
- return nullptr;
-}
+void FakeProxy::ReleaseOutputSurface() {}
bool FakeProxy::BeginMainFrameRequested() const { return false; }
diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h
index 0226431..d11d072 100644
--- a/cc/test/fake_proxy.h
+++ b/cc/test/fake_proxy.h
@@ -24,8 +24,8 @@ class FakeProxy : public Proxy {
void FinishAllRendering() override {}
bool IsStarted() const override;
bool CommitToActiveTree() const override;
- void SetOutputSurface(scoped_ptr<OutputSurface>) override {}
- scoped_ptr<OutputSurface> ReleaseOutputSurface() override;
+ void SetOutputSurface(OutputSurface* output_surface) override {}
+ void ReleaseOutputSurface() override;
void SetLayerTreeHostClientReady() override {}
void SetVisible(bool visible) override {}
void SetThrottleFrameProduction(bool throttle) override {}
diff --git a/cc/test/layer_test_common.cc b/cc/test/layer_test_common.cc
index 7cb97cd..8ed49a2 100644
--- a/cc/test/layer_test_common.cc
+++ b/cc/test/layer_test_common.cc
@@ -116,13 +116,13 @@ LayerTestCommon::LayerImplTest::LayerImplTest()
LayerTestCommon::LayerImplTest::LayerImplTest(const LayerTreeSettings& settings)
: client_(FakeLayerTreeHostClient::DIRECT_3D),
+ output_surface_(FakeOutputSurface::Create3d()),
host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_, settings)),
root_layer_impl_(LayerImpl::Create(host_->host_impl()->active_tree(), 1)),
render_pass_(RenderPass::Create()),
layer_impl_id_(2) {
root_layer_impl_->SetHasRenderSurface(true);
- scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d();
- host_->host_impl()->InitializeRenderer(FakeOutputSurface::Create3d());
+ host_->host_impl()->InitializeRenderer(output_surface_.get());
}
LayerTestCommon::LayerImplTest::~LayerImplTest() {}
diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h
index a915b59..f801461 100644
--- a/cc/test/layer_test_common.h
+++ b/cc/test/layer_test_common.h
@@ -139,6 +139,7 @@ class LayerTestCommon {
private:
FakeLayerTreeHostClient client_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<FakeLayerTreeHost> host_;
scoped_ptr<LayerImpl> root_layer_impl_;
scoped_ptr<RenderPass> render_pass_;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index c87c36b..e2d19b0 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -404,8 +404,8 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
test_hooks_->DidActivateTreeOnThread(this);
}
- bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface) override {
- bool success = LayerTreeHostImpl::InitializeRenderer(output_surface.Pass());
+ bool InitializeRenderer(OutputSurface* output_surface) override {
+ bool success = LayerTreeHostImpl::InitializeRenderer(output_surface);
test_hooks_->InitializedRendererOnThread(this, success);
return success;
}
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc
index ca7714d..5e43ee3 100644
--- a/cc/test/test_context_provider.cc
+++ b/cc/test/test_context_provider.cc
@@ -19,7 +19,20 @@ namespace cc {
// static
scoped_refptr<TestContextProvider> TestContextProvider::Create() {
- return Create(TestWebGraphicsContext3D::Create().Pass());
+ return Create(TestWebGraphicsContext3D::Create());
+}
+
+// static
+scoped_refptr<TestContextProvider> TestContextProvider::CreateWorker() {
+ scoped_refptr<TestContextProvider> worker_context_provider =
+ Create(TestWebGraphicsContext3D::Create());
+ if (!worker_context_provider)
+ return nullptr;
+ // Worker contexts are bound to the thread they are created on.
+ if (!worker_context_provider->BindToCurrentThread())
+ return nullptr;
+ worker_context_provider->SetupLock();
+ return worker_context_provider;
}
// static
diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h
index 82b3e61..3ff9092 100644
--- a/cc/test/test_context_provider.h
+++ b/cc/test/test_context_provider.h
@@ -25,6 +25,9 @@ class TestContextProvider : public ContextProvider {
CreateCallback;
static scoped_refptr<TestContextProvider> Create();
+ // Creates a worker context provider that can be used on any thread. This is
+ // equivalent to: Create(); BindToCurrentThread(); SetupLock().
+ static scoped_refptr<TestContextProvider> CreateWorker();
static scoped_refptr<TestContextProvider> Create(
scoped_ptr<TestWebGraphicsContext3D> context);
diff --git a/cc/tiles/tile_manager_perftest.cc b/cc/tiles/tile_manager_perftest.cc
index 1542233..0ba9c8e 100644
--- a/cc/tiles/tile_manager_perftest.cc
+++ b/cc/tiles/tile_manager_perftest.cc
@@ -89,6 +89,7 @@ class TileManagerPerfTest : public testing::Test {
max_tiles_(10000),
id_(7),
proxy_(base::ThreadTaskRunnerHandle::Get()),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(LayerTreeSettings(),
&proxy_,
&shared_bitmap_manager_,
@@ -119,7 +120,7 @@ class TileManagerPerfTest : public testing::Test {
}
virtual void InitializeRenderer() {
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d().Pass());
+ host_impl_.InitializeRenderer(output_surface_.get());
tile_manager()->SetTileTaskRunnerForTesting(
g_fake_tile_task_runner.Pointer());
}
@@ -412,6 +413,7 @@ class TileManagerPerfTest : public testing::Test {
int max_tiles_;
int id_;
FakeImplProxy proxy_;
+ scoped_ptr<OutputSurface> output_surface_;
FakeLayerTreeHostImpl host_impl_;
FakePictureLayerImpl* pending_root_layer_;
FakePictureLayerImpl* active_root_layer_;
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index e1fd51e..44bc756 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -46,6 +46,7 @@ class TileManagerTilePriorityQueueTest : public testing::Test {
ready_to_activate_(false),
id_(7),
proxy_(base::ThreadTaskRunnerHandle::Get()),
+ output_surface_(FakeOutputSurface::Create3d()),
host_impl_(LowResTilingsSettings(),
&proxy_,
&shared_bitmap_manager_,
@@ -74,7 +75,7 @@ class TileManagerTilePriorityQueueTest : public testing::Test {
}
virtual void InitializeRenderer() {
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl_.InitializeRenderer(output_surface_.get());
}
void SetupDefaultTrees(const gfx::Size& layer_bounds) {
@@ -156,6 +157,7 @@ class TileManagerTilePriorityQueueTest : public testing::Test {
bool ready_to_activate_;
int id_;
FakeImplProxy proxy_;
+ scoped_ptr<OutputSurface> output_surface_;
FakeLayerTreeHostImpl host_impl_;
FakePictureLayerImpl* pending_layer_;
FakePictureLayerImpl* active_layer_;
@@ -1423,7 +1425,11 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) {
class TileManagerTest : public testing::Test {
public:
TileManagerTest()
- : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {}
+ : output_surface_(FakeOutputSurface::CreateSoftware(
+ make_scoped_ptr(new SoftwareOutputDevice))),
+ host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {
+ host_impl_.InitializeRenderer(output_surface_.get());
+ }
protected:
// MockLayerTreeHostImpl allows us to intercept tile manager callbacks.
@@ -1432,10 +1438,7 @@ class TileManagerTest : public testing::Test {
MockLayerTreeHostImpl(Proxy* proxy,
SharedBitmapManager* manager,
TaskGraphRunner* task_graph_runner)
- : FakeLayerTreeHostImpl(proxy, manager, task_graph_runner) {
- InitializeRenderer(FakeOutputSurface::CreateSoftware(
- make_scoped_ptr(new SoftwareOutputDevice)));
- }
+ : FakeLayerTreeHostImpl(proxy, manager, task_graph_runner) {}
MOCK_METHOD0(NotifyAllTileTasksCompleted, void());
};
@@ -1443,6 +1446,7 @@ class TileManagerTest : public testing::Test {
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
FakeImplProxy proxy_;
+ scoped_ptr<OutputSurface> output_surface_;
MockLayerTreeHostImpl host_impl_;
};
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index d5bbe66..cece54d 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -385,7 +385,9 @@ void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) {
DCHECK(output_surface_lost_);
DCHECK(surface);
- proxy_->SetOutputSurface(surface.Pass());
+ DCHECK(!new_output_surface_);
+ new_output_surface_ = surface.Pass();
+ proxy_->SetOutputSurface(new_output_surface_.get());
}
scoped_ptr<OutputSurface> LayerTreeHost::ReleaseOutputSurface() {
@@ -393,7 +395,8 @@ scoped_ptr<OutputSurface> LayerTreeHost::ReleaseOutputSurface() {
DCHECK(!output_surface_lost_);
DidLoseOutputSurface();
- return proxy_->ReleaseOutputSurface();
+ proxy_->ReleaseOutputSurface();
+ return current_output_surface_.Pass();
}
void LayerTreeHost::RequestNewOutputSurface() {
@@ -401,12 +404,20 @@ void LayerTreeHost::RequestNewOutputSurface() {
}
void LayerTreeHost::DidInitializeOutputSurface() {
+ DCHECK(new_output_surface_);
output_surface_lost_ = false;
+ current_output_surface_ = new_output_surface_.Pass();
client_->DidInitializeOutputSurface();
}
void LayerTreeHost::DidFailToInitializeOutputSurface() {
DCHECK(output_surface_lost_);
+ DCHECK(new_output_surface_);
+ // Note: It is safe to drop all output surface references here as
+ // LayerTreeHostImpl will not keep a pointer to either the old or
+ // new output surface after failing to initialize the new one.
+ current_output_surface_ = nullptr;
+ new_output_surface_ = nullptr;
client_->DidFailToInitializeOutputSurface();
}
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 6ddef26..5c92f97 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -427,6 +427,13 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
int meta_information_sequence_number_;
scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation_;
+ // |current_output_surface_| can't be updated until we've successfully
+ // initialized a new output surface. |new_output_surface_| contains the
+ // new output surface that is currently being initialized. If initialization
+ // is successful then |new_output_surface_| replaces
+ // |current_output_surface_|.
+ scoped_ptr<OutputSurface> new_output_surface_;
+ scoped_ptr<OutputSurface> current_output_surface_;
bool output_surface_lost_;
scoped_refptr<Layer> root_layer_;
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 23e38e1..f0ca935 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -2695,6 +2695,7 @@ TEST_F(LayerTreeHostCommonTest,
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
&task_graph_runner);
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
@@ -2734,7 +2735,7 @@ TEST_F(LayerTreeHostCommonTest,
root->AddChild(child.Pass());
root->AddChild(occluding_child.Pass());
host_impl.active_tree()->SetRootLayer(root.Pass());
- host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl.InitializeRenderer(output_surface.get());
bool update_lcd_text = false;
host_impl.active_tree()->UpdateDrawProperties(update_lcd_text);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 36e7bdd..de1e213b 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -172,6 +172,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
: client_(client),
proxy_(proxy),
current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
+ output_surface_(nullptr),
content_is_suitable_for_gpu_rasterization_(true),
has_gpu_rasterization_trigger_(false),
use_gpu_rasterization_(false),
@@ -284,6 +285,13 @@ LayerTreeHostImpl::~LayerTreeHostImpl() {
}
CleanUpTileManager();
+ renderer_ = nullptr;
+ resource_provider_ = nullptr;
+
+ if (output_surface_) {
+ output_surface_->DetachFromClient();
+ output_surface_ = nullptr;
+ }
}
void LayerTreeHostImpl::BeginMainFrameAborted(CommitEarlyOutReason reason) {
@@ -1565,7 +1573,7 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) {
scoped_ptr<SoftwareRenderer> temp_software_renderer =
SoftwareRenderer::Create(this, &settings_.renderer_settings,
- output_surface_.get(), NULL);
+ output_surface_, NULL);
temp_software_renderer->DrawFrame(&frame->render_passes,
device_scale_factor_,
DeviceViewport(),
@@ -1627,7 +1635,7 @@ bool LayerTreeHostImpl::CanUseGpuRasterization() {
ContextProvider* context_provider =
output_surface_->worker_context_provider();
- base::AutoLock context_lock(*context_provider->GetLock());
+ ContextProvider::ScopedContextLock scoped_context(context_provider);
if (!context_provider->GrContext())
return false;
@@ -2010,18 +2018,18 @@ void LayerTreeHostImpl::CreateAndSetRenderer() {
DCHECK(resource_provider_);
if (output_surface_->capabilities().delegated_rendering) {
- renderer_ = DelegatingRenderer::Create(this, &settings_.renderer_settings,
- output_surface_.get(),
- resource_provider_.get());
+ renderer_ =
+ DelegatingRenderer::Create(this, &settings_.renderer_settings,
+ output_surface_, resource_provider_.get());
} else if (output_surface_->context_provider()) {
renderer_ = GLRenderer::Create(
- this, &settings_.renderer_settings, output_surface_.get(),
+ this, &settings_.renderer_settings, output_surface_,
resource_provider_.get(), texture_mailbox_deleter_.get(),
settings_.renderer_settings.highp_threshold_min);
} else if (output_surface_->software_device()) {
- renderer_ = SoftwareRenderer::Create(this, &settings_.renderer_settings,
- output_surface_.get(),
- resource_provider_.get());
+ renderer_ =
+ SoftwareRenderer::Create(this, &settings_.renderer_settings,
+ output_surface_, resource_provider_.get());
}
DCHECK(renderer_);
@@ -2150,7 +2158,7 @@ void LayerTreeHostImpl::CleanUpTileManager() {
single_thread_synchronous_task_graph_runner_ = nullptr;
}
-scoped_ptr<OutputSurface> LayerTreeHostImpl::ReleaseOutputSurface() {
+void LayerTreeHostImpl::ReleaseOutputSurface() {
TRACE_EVENT0("cc", "LayerTreeHostImpl::ReleaseOutputSurface");
// Since we will create a new resource provider, we cannot continue to use
@@ -2163,11 +2171,16 @@ scoped_ptr<OutputSurface> LayerTreeHostImpl::ReleaseOutputSurface() {
CleanUpTileManager();
resource_provider_ = nullptr;
- return output_surface_.Pass();
+ // Detach from the old output surface and reset |output_surface_| pointer
+ // as this surface is going to be destroyed independent of if binding the
+ // new output surface succeeds or not.
+ if (output_surface_) {
+ output_surface_->DetachFromClient();
+ output_surface_ = nullptr;
+ }
}
-bool LayerTreeHostImpl::InitializeRenderer(
- scoped_ptr<OutputSurface> output_surface) {
+bool LayerTreeHostImpl::InitializeRenderer(OutputSurface* output_surface) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeRenderer");
ReleaseOutputSurface();
@@ -2178,9 +2191,9 @@ bool LayerTreeHostImpl::InitializeRenderer(
return false;
}
- output_surface_ = output_surface.Pass();
+ output_surface_ = output_surface;
resource_provider_ = ResourceProvider::Create(
- output_surface_.get(), shared_bitmap_manager_, gpu_memory_buffer_manager_,
+ output_surface_, shared_bitmap_manager_, gpu_memory_buffer_manager_,
proxy_->blocking_main_thread_task_runner(),
settings_.renderer_settings.highp_threshold_min,
settings_.renderer_settings.use_rgba_4444_textures,
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index f3d4a67..7e8a85b 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -360,14 +360,15 @@ class CC_EXPORT LayerTreeHostImpl
// Implementation.
int id() const { return id_; }
bool CanDraw() const;
- OutputSurface* output_surface() const { return output_surface_.get(); }
- scoped_ptr<OutputSurface> ReleaseOutputSurface();
+ OutputSurface* output_surface() const { return output_surface_; }
+ void ReleaseOutputSurface();
+
std::string LayerTreeAsJson() const;
void FinishAllRendering();
int RequestedMSAASampleCount() const;
- virtual bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface);
+ virtual bool InitializeRenderer(OutputSurface* output_surface);
TileManager* tile_manager() { return tile_manager_.get(); }
void SetHasGpuRasterizationTrigger(bool flag) {
@@ -696,7 +697,7 @@ class CC_EXPORT LayerTreeHostImpl
// request queue.
std::set<UIResourceId> evicted_ui_resources_;
- scoped_ptr<OutputSurface> output_surface_;
+ OutputSurface* output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
bool content_is_suitable_for_gpu_rasterization_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 9921731..2f55c72 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -168,7 +168,8 @@ class LayerTreeHostImplTest : public testing::Test,
settings, this, &proxy_, &stats_instrumentation_,
&shared_bitmap_manager_, &gpu_memory_buffer_manager_,
&task_graph_runner_, 0);
- bool init = host_impl_->InitializeRenderer(output_surface.Pass());
+ output_surface_ = output_surface.Pass();
+ bool init = host_impl_->InitializeRenderer(output_surface_.get());
host_impl_->SetViewportSize(gfx::Size(10, 10));
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
// Set the BeginFrameArgs so that methods which use it are able to.
@@ -420,6 +421,7 @@ class LayerTreeHostImplTest : public testing::Test,
TestSharedBitmapManager shared_bitmap_manager_;
TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<LayerTreeHostImpl> host_impl_;
FakeRenderingStatsInstrumentation stats_instrumentation_;
bool on_can_draw_state_changed_called_;
@@ -2117,7 +2119,8 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
settings, this, &proxy_, &shared_bitmap_manager_,
&task_graph_runner_, &stats_instrumentation_);
host_impl_ = make_scoped_ptr(host_impl_override_time);
- host_impl_->InitializeRenderer(CreateOutputSurface());
+ output_surface_ = CreateOutputSurface();
+ host_impl_->InitializeRenderer(output_surface_.get());
SetupScrollAndContentsLayers(content_size);
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
@@ -5669,7 +5672,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
LayerTreeHostImpl::Create(
settings, this, &proxy_, &stats_instrumentation_,
&shared_bitmap_manager_, NULL, &task_graph_runner_, 0);
- layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
+ layer_tree_host_impl->InitializeRenderer(output_surface.get());
layer_tree_host_impl->WillBeginImplFrame(
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
@@ -5946,19 +5949,14 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
Proxy* proxy,
SharedBitmapManager* manager,
TaskGraphRunner* task_graph_runner,
- RenderingStatsInstrumentation* stats_instrumentation) {
- scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
- scoped_ptr<OutputSurface> output_surface(
- FakeOutputSurface::Create3d(provider));
- provider->BindToCurrentThread();
- provider->TestContext3d()->set_have_post_sub_buffer(true);
-
+ RenderingStatsInstrumentation* stats_instrumentation,
+ OutputSurface* output_surface) {
LayerTreeSettings settings;
settings.renderer_settings.partial_swap_enabled = partial_swap;
scoped_ptr<LayerTreeHostImpl> my_host_impl =
LayerTreeHostImpl::Create(settings, client, proxy, stats_instrumentation,
manager, nullptr, task_graph_runner, 0);
- my_host_impl->InitializeRenderer(output_surface.Pass());
+ my_host_impl->InitializeRenderer(output_surface);
my_host_impl->WillBeginImplFrame(
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
my_host_impl->SetViewportSize(gfx::Size(100, 100));
@@ -6021,9 +6019,14 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
- scoped_ptr<LayerTreeHostImpl> my_host_impl =
- SetupLayersForOpacity(true, this, &proxy_, &shared_bitmap_manager,
- &task_graph_runner, &stats_instrumentation_);
+ scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
+ provider->BindToCurrentThread();
+ provider->TestContext3d()->set_have_post_sub_buffer(true);
+ scoped_ptr<OutputSurface> output_surface(
+ FakeOutputSurface::Create3d(provider));
+ scoped_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity(
+ true, this, &proxy_, &shared_bitmap_manager, &task_graph_runner,
+ &stats_instrumentation_, output_surface.get());
{
LayerTreeHostImpl::FrameData frame;
EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
@@ -6045,9 +6048,14 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
TestSharedBitmapManager shared_bitmap_manager;
TestTaskGraphRunner task_graph_runner;
- scoped_ptr<LayerTreeHostImpl> my_host_impl =
- SetupLayersForOpacity(false, this, &proxy_, &shared_bitmap_manager,
- &task_graph_runner, &stats_instrumentation_);
+ scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
+ provider->BindToCurrentThread();
+ provider->TestContext3d()->set_have_post_sub_buffer(true);
+ scoped_ptr<OutputSurface> output_surface(
+ FakeOutputSurface::Create3d(provider));
+ scoped_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity(
+ false, this, &proxy_, &shared_bitmap_manager, &task_graph_runner,
+ &stats_instrumentation_, output_surface.get());
{
LayerTreeHostImpl::FrameData frame;
EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
@@ -6466,9 +6474,9 @@ TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
settings, this, &proxy_, &stats_instrumentation_, &shared_bitmap_manager_,
&gpu_memory_buffer_manager_, &task_graph_runner_, 0);
- scoped_ptr<OutputSurface> output_surface(
- FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
- host_impl_->InitializeRenderer(output_surface.Pass());
+ output_surface_ =
+ FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create());
+ host_impl_->InitializeRenderer(output_surface_.get());
EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes());
}
@@ -6529,7 +6537,8 @@ class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest {
new FakeLayerTreeHostImpl(LayerTreeSettings(), &proxy_,
&shared_bitmap_manager_, &task_graph_runner_);
host_impl_.reset(fake_host_impl_);
- host_impl_->InitializeRenderer(CreateOutputSurface());
+ output_surface_ = CreateOutputSurface();
+ host_impl_->InitializeRenderer(output_surface_.get());
host_impl_->SetViewportSize(gfx::Size(10, 10));
}
@@ -8522,7 +8531,8 @@ class MockReclaimResourcesOutputSurface : public FakeOutputSurface {
public:
static scoped_ptr<MockReclaimResourcesOutputSurface> Create3d() {
return make_scoped_ptr(new MockReclaimResourcesOutputSurface(
- TestContextProvider::Create(), TestContextProvider::Create(), false));
+ TestContextProvider::Create(), TestContextProvider::CreateWorker(),
+ false));
}
MOCK_METHOD0(ForceReclaimResources, void());
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 1481b99..0afcd9f 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -465,7 +465,7 @@ class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest {
explicit MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface(
bool delegated_rendering)
: FakeOutputSurface(TestContextProvider::Create(),
- TestContextProvider::Create(),
+ TestContextProvider::CreateWorker(),
delegated_rendering) {}
MOCK_METHOD1(SetWorkerContextShouldAggressivelyFreeResources,
void(bool is_visible));
@@ -6258,5 +6258,21 @@ class LayerTreeHostScrollingAndScalingUpdatesLayers : public LayerTreeHostTest {
MULTI_THREAD_TEST_F(LayerTreeHostScrollingAndScalingUpdatesLayers);
+class LayerTreeHostTestDestroyWhileInitializingOutputSurface
+ : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override {
+ // By ending the test immediately we start initialization of an output
+ // surface but destroy the LTH before it completes. This test verifies
+ // that this works correctly and the output surface is destroyed on
+ // the correct thread.
+ EndTest();
+ }
+
+ void AfterTest() override {}
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTestDestroyWhileInitializingOutputSurface);
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 3a41b55..34a70b9 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -416,7 +416,6 @@ class LayerTreeHostClientTakeAwayOutputSurface
scoped_ptr<OutputSurface> surface =
layer_tree_host()->ReleaseOutputSurface();
CHECK(surface);
- surface->context_provider()->DetachFromThread();
MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&LayerTreeHostClientTakeAwayOutputSurface::MakeVisible,
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc
index 34d26d5..e00e7c8 100644
--- a/cc/trees/layer_tree_impl_unittest.cc
+++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -22,12 +22,12 @@ namespace {
class LayerTreeImplTest : public LayerTreeHostCommonTest {
public:
- LayerTreeImplTest() {
+ LayerTreeImplTest() : output_surface_(FakeOutputSurface::Create3d()) {
LayerTreeSettings settings;
settings.layer_transforms_should_scale_layer_contents = true;
host_impl_.reset(new FakeLayerTreeHostImpl(
settings, &proxy_, &shared_bitmap_manager_, &task_graph_runner_));
- EXPECT_TRUE(host_impl_->InitializeRenderer(FakeOutputSurface::Create3d()));
+ EXPECT_TRUE(host_impl_->InitializeRenderer(output_surface_.get()));
}
FakeLayerTreeHostImpl& host_impl() { return *host_impl_; }
@@ -42,6 +42,7 @@ class LayerTreeImplTest : public LayerTreeHostCommonTest {
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
FakeImplProxy proxy_;
+ scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
};
@@ -97,10 +98,11 @@ TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) {
FakeImplProxy proxy;
LayerTreeSettings settings;
settings.verify_property_trees = true;
+ scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d();
scoped_ptr<FakeLayerTreeHostImpl> host_impl;
host_impl.reset(new FakeLayerTreeHostImpl(
settings, &proxy, &shared_bitmap_manager, &task_graph_runner));
- EXPECT_TRUE(host_impl->InitializeRenderer(FakeOutputSurface::Create3d()));
+ EXPECT_TRUE(host_impl->InitializeRenderer(output_surface.get()));
scoped_ptr<LayerImpl> root =
LayerImpl::Create(host_impl->active_tree(), 12345);
diff --git a/cc/trees/occlusion_tracker_perftest.cc b/cc/trees/occlusion_tracker_perftest.cc
index 209399d..01b63de 100644
--- a/cc/trees/occlusion_tracker_perftest.cc
+++ b/cc/trees/occlusion_tracker_perftest.cc
@@ -35,13 +35,14 @@ class OcclusionTrackerPerfTest : public testing::Test {
base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
kTimeCheckInterval),
proxy_(base::ThreadTaskRunnerHandle::Get(), nullptr),
- impl_(&proxy_) {}
+ impl_(&proxy_),
+ output_surface_(FakeOutputSurface::Create3d()) {}
void CreateHost() {
LayerTreeSettings settings;
host_impl_ = LayerTreeHostImpl::Create(settings, &client_, &proxy_, &stats_,
&shared_bitmap_manager_, nullptr,
&task_graph_runner_, 1);
- host_impl_->InitializeRenderer(FakeOutputSurface::Create3d());
+ host_impl_->InitializeRenderer(output_surface_.get());
scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1);
root_layer->SetHasRenderSurface(true);
@@ -71,6 +72,7 @@ class OcclusionTrackerPerfTest : public testing::Test {
FakeRenderingStatsInstrumentation stats_;
TestSharedBitmapManager shared_bitmap_manager_;
TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<LayerTreeHostImpl> host_impl_;
};
diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h
index 05dfe69..b40bb2f 100644
--- a/cc/trees/proxy.h
+++ b/cc/trees/proxy.h
@@ -60,9 +60,9 @@ class CC_EXPORT Proxy {
// Will call LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted
// with the result of this function.
- virtual void SetOutputSurface(scoped_ptr<OutputSurface> output_surface) = 0;
+ virtual void SetOutputSurface(OutputSurface* output_surface) = 0;
- virtual scoped_ptr<OutputSurface> ReleaseOutputSurface() = 0;
+ virtual void ReleaseOutputSurface() = 0;
// Indicates that the compositing surface associated with our context is
// ready to use.
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index 8ab3bc2..cefc074 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -149,7 +149,7 @@ void SingleThreadProxy::RequestNewOutputSurface() {
layer_tree_host_->RequestNewOutputSurface();
}
-scoped_ptr<OutputSurface> SingleThreadProxy::ReleaseOutputSurface() {
+void SingleThreadProxy::ReleaseOutputSurface() {
// |layer_tree_host_| should already be aware of this.
DCHECK(layer_tree_host_->output_surface_lost());
@@ -158,8 +158,7 @@ scoped_ptr<OutputSurface> SingleThreadProxy::ReleaseOutputSurface() {
return layer_tree_host_impl_->ReleaseOutputSurface();
}
-void SingleThreadProxy::SetOutputSurface(
- scoped_ptr<OutputSurface> output_surface) {
+void SingleThreadProxy::SetOutputSurface(OutputSurface* output_surface) {
DCHECK(Proxy::IsMainThread());
DCHECK(layer_tree_host_->output_surface_lost());
DCHECK(output_surface_creation_requested_);
@@ -169,7 +168,7 @@ void SingleThreadProxy::SetOutputSurface(
{
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
DebugScopedSetImplThread impl(this);
- success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
+ success = layer_tree_host_impl_->InitializeRenderer(output_surface);
}
if (success) {
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 4829d22..3caf139 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -38,8 +38,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void FinishAllRendering() override;
bool IsStarted() const override;
bool CommitToActiveTree() const override;
- void SetOutputSurface(scoped_ptr<OutputSurface>) override;
- scoped_ptr<OutputSurface> ReleaseOutputSurface() override;
+ void SetOutputSurface(OutputSurface* output_surface) override;
+ void ReleaseOutputSurface() override;
void SetLayerTreeHostClientReady() override;
void SetVisible(bool visible) override;
void SetThrottleFrameProduction(bool throttle) override;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index df9d560..585cbf5 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -210,26 +210,22 @@ void ThreadProxy::RequestNewOutputSurface() {
layer_tree_host()->RequestNewOutputSurface();
}
-void ThreadProxy::SetOutputSurface(scoped_ptr<OutputSurface> output_surface) {
+void ThreadProxy::SetOutputSurface(OutputSurface* output_surface) {
Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
- impl_thread_weak_ptr_, base::Passed(&output_surface)));
+ FROM_HERE, base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
+ impl_thread_weak_ptr_, output_surface));
}
-scoped_ptr<OutputSurface> ThreadProxy::ReleaseOutputSurface() {
+void ThreadProxy::ReleaseOutputSurface() {
DCHECK(IsMainThread());
DCHECK(layer_tree_host()->output_surface_lost());
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
CompletionEvent completion;
- scoped_ptr<OutputSurface> output_surface;
Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::ReleaseOutputSurfaceOnImplThread,
- impl_thread_weak_ptr_, &completion, &output_surface));
+ FROM_HERE, base::Bind(&ThreadProxy::ReleaseOutputSurfaceOnImplThread,
+ impl_thread_weak_ptr_, &completion));
completion.Wait();
- return output_surface;
}
void ThreadProxy::DidInitializeOutputSurface(
@@ -1041,12 +1037,12 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
}
void ThreadProxy::InitializeOutputSurfaceOnImplThread(
- scoped_ptr<OutputSurface> output_surface) {
+ OutputSurface* output_surface) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
DCHECK(IsImplThread());
LayerTreeHostImpl* host_impl = impl().layer_tree_host_impl.get();
- bool success = host_impl->InitializeRenderer(output_surface.Pass());
+ bool success = host_impl->InitializeRenderer(output_surface);
RendererCapabilities capabilities;
if (success) {
capabilities =
@@ -1065,14 +1061,13 @@ void ThreadProxy::InitializeOutputSurfaceOnImplThread(
}
void ThreadProxy::ReleaseOutputSurfaceOnImplThread(
- CompletionEvent* completion,
- scoped_ptr<OutputSurface>* output_surface) {
+ CompletionEvent* completion) {
DCHECK(IsImplThread());
// Unlike DidLoseOutputSurfaceOnImplThread, we don't need to call
// LayerTreeHost::DidLoseOutputSurface since it already knows.
impl().scheduler->DidLoseOutputSurface();
- *output_surface = impl().layer_tree_host_impl->ReleaseOutputSurface();
+ impl().layer_tree_host_impl->ReleaseOutputSurface();
completion->Signal();
}
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 9cbfc9a..9abca17 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -155,7 +155,7 @@ class CC_EXPORT ThreadProxy : public Proxy,
void FinishAllRendering() override;
bool IsStarted() const override;
bool CommitToActiveTree() const override;
- void SetOutputSurface(scoped_ptr<OutputSurface>) override;
+ void SetOutputSurface(OutputSurface* output_surface) override;
void SetLayerTreeHostClientReady() override;
void SetVisible(bool visible) override;
void SetThrottleFrameProduction(bool throttle) override;
@@ -176,7 +176,7 @@ class CC_EXPORT ThreadProxy : public Proxy,
bool MainFrameWillHappenForTesting() override;
void SetChildrenNeedBeginFrames(bool children_need_begin_frames) override;
void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) override;
- scoped_ptr<OutputSurface> ReleaseOutputSurface() override;
+ void ReleaseOutputSurface() override;
// LayerTreeHostImplClient implementation
void UpdateRendererCapabilitiesOnImplThread() override;
@@ -272,11 +272,8 @@ class CC_EXPORT ThreadProxy : public Proxy,
CompletionEvent* completion,
bool* has_initialized_output_surface);
void DeleteContentsTexturesOnImplThread(CompletionEvent* completion);
- void InitializeOutputSurfaceOnImplThread(
- scoped_ptr<OutputSurface> output_surface);
- void ReleaseOutputSurfaceOnImplThread(
- CompletionEvent* completion,
- scoped_ptr<OutputSurface>* output_surface);
+ void InitializeOutputSurfaceOnImplThread(OutputSurface* output_surface);
+ void ReleaseOutputSurfaceOnImplThread(CompletionEvent* completion);
void FinishGLOnImplThread(CompletionEvent* completion);
void LayerTreeHostClosedOnImplThread(CompletionEvent* completion);
DrawResult DrawSwapInternal(bool forced_draw);
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
index b90edd6..5d62030 100644
--- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
@@ -24,6 +24,7 @@
#include "content/renderer/render_thread_impl.h"
#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h"
#include "gpu/command_buffer/client/gl_in_process_context.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "ui/gl/android/surface_texture.h"
#include "ui/gl/gl_surface.h"
@@ -170,8 +171,7 @@ SynchronousCompositorFactoryImpl::CreateOutputSurface(
scoped_refptr<cc::ContextProvider> onscreen_context =
CreateContextProviderForCompositor(surface_id, RENDER_COMPOSITOR_CONTEXT);
scoped_refptr<cc::ContextProvider> worker_context =
- CreateContextProviderForCompositor(0, RENDER_WORKER_CONTEXT);
-
+ GetSharedWorkerContextProvider();
return make_scoped_ptr(new SynchronousCompositorOutputSurface(
onscreen_context, worker_context, routing_id, frame_swap_message_queue));
}
@@ -211,6 +211,9 @@ SynchronousCompositorFactoryImpl::CreateContextProviderForCompositor(
// This is half of what RenderWidget uses because synchronous compositor
// pipeline is only one frame deep. But twice of half for low end here
// because 16bit texture is not supported.
+ // TODO(reveman): This limit is based on the usage required by async
+ // uploads. Determine what a good limit is now that async uploads are
+ // no longer used.
unsigned int mapped_memory_reclaim_limit =
(base::SysInfo::IsLowEndDevice() ? 2 : 6) * 1024 * 1024;
blink::WebGraphicsContext3D::Attributes attributes = GetDefaultAttribs();
@@ -232,6 +235,67 @@ SynchronousCompositorFactoryImpl::CreateContextProviderForCompositor(
"Child-Compositor");
}
+scoped_refptr<cc::ContextProvider>
+SynchronousCompositorFactoryImpl::GetSharedWorkerContextProvider() {
+ // TODO(reveman): This limit is based on the usage required by async
+ // uploads. Determine what a good limit is now that async uploads are
+ // no longer used.
+ unsigned int mapped_memory_reclaim_limit =
+ (base::SysInfo::IsLowEndDevice() ? 2 : 6) * 1024 * 1024;
+
+ if (use_ipc_command_buffer_) {
+ bool shared_worker_context_lost = false;
+ if (shared_worker_context_) {
+ // Note: If context is lost, we delete reference after releasing the lock.
+ base::AutoLock lock(*shared_worker_context_->GetLock());
+ if (shared_worker_context_->ContextGL()->GetGraphicsResetStatusKHR() !=
+ GL_NO_ERROR) {
+ shared_worker_context_lost = true;
+ }
+ }
+ if (!shared_worker_context_ || shared_worker_context_lost) {
+ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits mem_limits;
+ mem_limits.mapped_memory_reclaim_limit = mapped_memory_reclaim_limit;
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context =
+ CreateContext3D(0, GetDefaultAttribs(), mem_limits);
+ shared_worker_context_ =
+ make_scoped_refptr(new SynchronousCompositorContextProvider(
+ context.Pass(), RENDER_WORKER_CONTEXT));
+ if (!shared_worker_context_->BindToCurrentThread())
+ shared_worker_context_ = nullptr;
+ if (shared_worker_context_)
+ shared_worker_context_->SetupLock();
+ }
+
+ return shared_worker_context_;
+ }
+
+ bool in_process_shared_worker_context_lost = false;
+ if (in_process_shared_worker_context_) {
+ // Note: If context is lost, we delete reference after releasing the lock.
+ base::AutoLock lock(*in_process_shared_worker_context_->GetLock());
+ if (in_process_shared_worker_context_->ContextGL()
+ ->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
+ in_process_shared_worker_context_lost = true;
+ }
+ }
+ if (!in_process_shared_worker_context_ ||
+ in_process_shared_worker_context_lost) {
+ gpu::GLInProcessContextSharedMemoryLimits mem_limits;
+ mem_limits.mapped_memory_reclaim_limit = mapped_memory_reclaim_limit;
+ ContextHolder holder = CreateContextHolder(
+ GetDefaultAttribs(), GpuThreadService(), mem_limits, true);
+ in_process_shared_worker_context_ = ContextProviderInProcess::Create(
+ holder.command_buffer.Pass(), "Child-Worker");
+ if (!in_process_shared_worker_context_->BindToCurrentThread())
+ in_process_shared_worker_context_ = nullptr;
+ if (in_process_shared_worker_context_)
+ in_process_shared_worker_context_->SetupLock();
+ }
+
+ return in_process_shared_worker_context_;
+}
+
scoped_refptr<StreamTextureFactory>
SynchronousCompositorFactoryImpl::CreateStreamTextureFactory(int frame_id) {
scoped_refptr<StreamTextureFactorySynchronousImpl> factory(
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
index 84ceb03..90d6105 100644
--- a/content/browser/android/in_process/synchronous_compositor_factory_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
@@ -28,6 +28,7 @@ class WebGraphicsContext3DInProcessCommandBufferImpl;
namespace content {
class InProcessChildThreadParams;
+class SynchronousCompositorContextProvider;
class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
public:
@@ -74,6 +75,7 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
scoped_refptr<cc::ContextProvider> CreateContextProviderForCompositor(
int surface_id,
CommandBufferContextType type);
+ scoped_refptr<cc::ContextProvider> GetSharedWorkerContextProvider();
bool CanCreateMainThreadContext();
scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
TryCreateStreamTextureFactory();
@@ -88,6 +90,10 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
class VideoContextProvider;
scoped_refptr<VideoContextProvider> video_context_provider_;
+ scoped_refptr<SynchronousCompositorContextProvider> shared_worker_context_;
+ scoped_refptr<cc_blink::ContextProviderWebContext>
+ in_process_shared_worker_context_;
+
bool use_ipc_command_buffer_;
// |num_hardware_compositor_lock_| is updated on UI thread only but can be
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
index 85c7bcb..f03f992 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -83,11 +83,6 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
}
SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {
- DCHECK(CalledOnValidThread());
- if (registered_) {
- SynchronousCompositorRegistry::GetInstance()->UnregisterOutputSurface(
- routing_id_, this);
- }
}
bool SynchronousCompositorOutputSurface::BindToClient(
@@ -105,6 +100,15 @@ bool SynchronousCompositorOutputSurface::BindToClient(
return true;
}
+void SynchronousCompositorOutputSurface::DetachFromClient() {
+ DCHECK(CalledOnValidThread());
+ if (registered_) {
+ SynchronousCompositorRegistry::GetInstance()->UnregisterOutputSurface(
+ routing_id_, this);
+ }
+ cc::OutputSurface::DetachFromClient();
+}
+
void SynchronousCompositorOutputSurface::SetCompositor(
SynchronousCompositorImpl* compositor) {
DCHECK(CalledOnValidThread());
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h
index 4146952..b1baa64 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -58,6 +58,7 @@ class SynchronousCompositorOutputSurface
// OutputSurface.
bool BindToClient(cc::OutputSurfaceClient* surface_client) override;
+ void DetachFromClient() override;
void Reshape(const gfx::Size& size, float scale_factor) override;
void SwapBuffers(cc::CompositorFrame* frame) override;
void Invalidate() override;
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index a5b1433..1af8acd 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -244,11 +244,14 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
scoped_refptr<ContextProviderCommandBuffer> context_provider;
if (create_gpu_output_surface) {
// Try to reuse existing worker context provider.
+ bool shared_worker_context_provider_lost = false;
if (shared_worker_context_provider_) {
+ // Note: If context is lost, we delete reference after releasing the lock.
base::AutoLock lock(*shared_worker_context_provider_->GetLock());
if (shared_worker_context_provider_->ContextGL()
- ->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
- shared_worker_context_provider_ = nullptr;
+ ->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
+ shared_worker_context_provider_lost = true;
+ }
}
scoped_refptr<GpuChannelHost> gpu_channel_host =
BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
@@ -259,7 +262,8 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
BROWSER_COMPOSITOR_ONSCREEN_CONTEXT);
if (context_provider && !context_provider->BindToCurrentThread())
context_provider = nullptr;
- if (!shared_worker_context_provider_) {
+ if (!shared_worker_context_provider_ ||
+ shared_worker_context_provider_lost) {
shared_worker_context_provider_ = ContextProviderCommandBuffer::Create(
GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host,
0),
@@ -267,6 +271,8 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
if (shared_worker_context_provider_ &&
!shared_worker_context_provider_->BindToCurrentThread())
shared_worker_context_provider_ = nullptr;
+ if (shared_worker_context_provider_)
+ shared_worker_context_provider_->SetupLock();
}
}
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index bfb1f3a..47e2aef 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -590,7 +590,7 @@ scoped_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory(
shared_buf.reset(new base::SharedMemory);
if (!shared_buf->CreateAnonymous(buf_size)) {
NOTREACHED();
- return NULL;
+ return nullptr;
}
#else
// On POSIX, we need to ask the browser to create the shared memory for us,
@@ -602,11 +602,11 @@ scoped_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory(
shared_buf.reset(new base::SharedMemory(shared_mem_handle, false));
} else {
NOTREACHED() << "Browser failed to allocate shared memory";
- return NULL;
+ return nullptr;
}
} else {
- NOTREACHED() << "Browser allocation request message failed";
- return NULL;
+ // Send is allowed to fail during shutdown. Return null in this case.
+ return nullptr;
}
#endif
return shared_buf;
diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc
index c3298d0..3f96ef3 100644
--- a/content/renderer/gpu/compositor_output_surface.cc
+++ b/content/renderer/gpu/compositor_output_surface.cc
@@ -50,28 +50,15 @@ CompositorOutputSurface::CompositorOutputSurface(
weak_ptrs_(this) {
DCHECK(output_surface_filter_.get());
DCHECK(frame_swap_message_queue_.get());
- DetachFromThread();
capabilities_.max_frames_pending = 1;
message_sender_ = RenderThreadImpl::current()->sync_message_filter();
DCHECK(message_sender_.get());
}
-CompositorOutputSurface::~CompositorOutputSurface() {
- DCHECK(CalledOnValidThread());
- if (!HasClient())
- return;
- UpdateSmoothnessTakesPriority(false);
- if (output_surface_proxy_.get())
- output_surface_proxy_->ClearOutputSurface();
- output_surface_filter_->RemoveHandlerOnCompositorThread(
- routing_id_,
- output_surface_filter_handler_);
-}
+CompositorOutputSurface::~CompositorOutputSurface() {}
bool CompositorOutputSurface::BindToClient(
cc::OutputSurfaceClient* client) {
- DCHECK(CalledOnValidThread());
-
if (!cc::OutputSurface::BindToClient(client))
return false;
@@ -94,6 +81,17 @@ bool CompositorOutputSurface::BindToClient(
return true;
}
+void CompositorOutputSurface::DetachFromClient() {
+ if (!HasClient())
+ return;
+ UpdateSmoothnessTakesPriority(false);
+ if (output_surface_proxy_.get())
+ output_surface_proxy_->ClearOutputSurface();
+ output_surface_filter_->RemoveHandlerOnCompositorThread(
+ routing_id_, output_surface_filter_handler_);
+ cc::OutputSurface::DetachFromClient();
+}
+
void CompositorOutputSurface::ShortcutSwapAck(
uint32 output_surface_id,
scoped_ptr<cc::GLFrameData> gl_frame_data) {
@@ -156,7 +154,7 @@ void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
}
void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) {
- DCHECK(CalledOnValidThread());
+ DCHECK(client_thread_checker_.CalledOnValidThread());
if (!HasClient())
return;
IPC_BEGIN_MESSAGE_MAP(CompositorOutputSurface, message)
@@ -170,7 +168,7 @@ void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) {
void CompositorOutputSurface::OnUpdateVSyncParametersFromBrowser(
base::TimeTicks timebase,
base::TimeDelta interval) {
- DCHECK(CalledOnValidThread());
+ DCHECK(client_thread_checker_.CalledOnValidThread());
CommitVSyncParameters(timebase, interval);
}
diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h
index fa91b75..909bf5f 100644
--- a/content/renderer/gpu/compositor_output_surface.h
+++ b/content/renderer/gpu/compositor_output_surface.h
@@ -51,6 +51,7 @@ class CompositorOutputSurface
// cc::OutputSurface implementation.
bool BindToClient(cc::OutputSurfaceClient* client) override;
+ void DetachFromClient() override;
void SwapBuffers(cc::CompositorFrame* frame) override;
// TODO(epenner): This seems out of place here and would be a better fit
diff --git a/content/renderer/gpu/mailbox_output_surface.cc b/content/renderer/gpu/mailbox_output_surface.cc
index b7c3045..fe6bd6a 100644
--- a/content/renderer/gpu/mailbox_output_surface.cc
+++ b/content/renderer/gpu/mailbox_output_surface.cc
@@ -43,7 +43,9 @@ MailboxOutputSurface::MailboxOutputSurface(
capabilities_.uses_default_gl_framebuffer = false;
}
-MailboxOutputSurface::~MailboxOutputSurface() {
+MailboxOutputSurface::~MailboxOutputSurface() {}
+
+void MailboxOutputSurface::DetachFromClient() {
DiscardBackbuffer();
while (!pending_textures_.empty()) {
if (pending_textures_.front().texture_id) {
@@ -52,6 +54,7 @@ MailboxOutputSurface::~MailboxOutputSurface() {
}
pending_textures_.pop_front();
}
+ cc::OutputSurface::DetachFromClient();
}
void MailboxOutputSurface::EnsureBackbuffer() {
diff --git a/content/renderer/gpu/mailbox_output_surface.h b/content/renderer/gpu/mailbox_output_surface.h
index f907fb8..fc789c4 100644
--- a/content/renderer/gpu/mailbox_output_surface.h
+++ b/content/renderer/gpu/mailbox_output_surface.h
@@ -37,6 +37,7 @@ class MailboxOutputSurface : public CompositorOutputSurface {
~MailboxOutputSurface() override;
// cc::OutputSurface implementation.
+ void DetachFromClient() override;
void EnsureBackbuffer() override;
void DiscardBackbuffer() override;
void Reshape(const gfx::Size& size, float scale_factor) override;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 0cdb8c3..71a8781 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -846,6 +846,7 @@ void RenderThreadImpl::Shutdown() {
main_thread_compositor_task_runner_ = NULL;
// Context providers must be released prior to destroying the GPU channel.
+ shared_worker_context_provider_ = nullptr;
gpu_va_context_provider_ = nullptr;
shared_main_thread_contexts_ = nullptr;
@@ -1893,6 +1894,31 @@ base::TaskRunner* RenderThreadImpl::GetWorkerTaskRunner() {
return raster_worker_pool_.get();
}
+scoped_refptr<ContextProviderCommandBuffer>
+RenderThreadImpl::SharedWorkerContextProvider() {
+ DCHECK(IsMainThread());
+ // Try to reuse existing shared worker context provider.
+ bool shared_worker_context_provider_lost = false;
+ if (shared_worker_context_provider_) {
+ // Note: If context is lost, delete reference after releasing the lock.
+ base::AutoLock lock(*shared_worker_context_provider_->GetLock());
+ if (shared_worker_context_provider_->ContextGL()
+ ->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
+ shared_worker_context_provider_lost = true;
+ }
+ }
+ if (!shared_worker_context_provider_ || shared_worker_context_provider_lost) {
+ shared_worker_context_provider_ = ContextProviderCommandBuffer::Create(
+ CreateOffscreenContext3d(), RENDER_WORKER_CONTEXT);
+ if (shared_worker_context_provider_ &&
+ !shared_worker_context_provider_->BindToCurrentThread())
+ shared_worker_context_provider_ = nullptr;
+ if (shared_worker_context_provider_)
+ shared_worker_context_provider_->SetupLock();
+ }
+ return shared_worker_context_provider_;
+}
+
void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) {
blink_platform_impl_->sampleGamepads(*data);
}
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index 3b99b4e..c3f9ab6 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -325,6 +325,9 @@ class CONTENT_EXPORT RenderThreadImpl
// A TaskRunner instance that runs tasks on the raster worker pool.
base::TaskRunner* GetWorkerTaskRunner();
+ // Returns a shared worker context provider that can be used on any thread.
+ scoped_refptr<ContextProviderCommandBuffer> SharedWorkerContextProvider();
+
// Causes the idle handler to skip sending idle notifications
// on the two next scheduled calls, so idle notifications are
// not sent for at least one notification delay.
@@ -591,6 +594,7 @@ class CONTENT_EXPORT RenderThreadImpl
base::ObserverList<RenderProcessObserver> observers_;
+ scoped_refptr<ContextProviderCommandBuffer> shared_worker_context_provider_;
scoped_refptr<ContextProviderCommandBuffer> gpu_va_context_provider_;
scoped_ptr<AudioRendererMixerManager> audio_renderer_mixer_manager_;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index ec6203b..7fa1172 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1018,10 +1018,9 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) {
// Cause the compositor to wait and try again.
return nullptr;
}
-
- worker_context_provider = ContextProviderCommandBuffer::Create(
- CreateGraphicsContext3D(false), RENDER_WORKER_CONTEXT);
- if (!worker_context_provider.get()) {
+ worker_context_provider =
+ RenderThreadImpl::current()->SharedWorkerContextProvider();
+ if (!worker_context_provider) {
// Cause the compositor to wait and try again.
return nullptr;
}
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index 942947d..1d96e01 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -112,19 +112,37 @@ void InProcessContextFactory::CreateOutputSurface(
InProcessContextProvider::Create(attribs, &gpu_memory_buffer_manager_,
&image_factory_,
compositor->widget(), "UICompositor");
- scoped_refptr<InProcessContextProvider> worker_context_provider =
- InProcessContextProvider::CreateOffscreen(&gpu_memory_buffer_manager_,
- &image_factory_);
+
+ // Try to reuse existing shared worker context provider.
+ bool shared_worker_context_provider_lost = false;
+ if (shared_worker_context_provider_) {
+ // Note: If context is lost, delete reference after releasing the lock.
+ base::AutoLock lock(*shared_worker_context_provider_->GetLock());
+ if (shared_worker_context_provider_->ContextGL()
+ ->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
+ shared_worker_context_provider_lost = true;
+ }
+ }
+ if (!shared_worker_context_provider_ || shared_worker_context_provider_lost) {
+ shared_worker_context_provider_ = InProcessContextProvider::CreateOffscreen(
+ &gpu_memory_buffer_manager_, &image_factory_);
+ if (shared_worker_context_provider_ &&
+ !shared_worker_context_provider_->BindToCurrentThread())
+ shared_worker_context_provider_ = nullptr;
+ if (shared_worker_context_provider_)
+ shared_worker_context_provider_->SetupLock();
+ }
scoped_ptr<cc::OutputSurface> real_output_surface;
if (use_test_surface_) {
bool flipped_output_surface = false;
real_output_surface = make_scoped_ptr(new cc::PixelTestOutputSurface(
- context_provider, worker_context_provider, flipped_output_surface));
+ context_provider, shared_worker_context_provider_,
+ flipped_output_surface));
} else {
- real_output_surface = make_scoped_ptr(
- new DirectOutputSurface(context_provider, worker_context_provider));
+ real_output_surface = make_scoped_ptr(new DirectOutputSurface(
+ context_provider, shared_worker_context_provider_));
}
if (surface_manager_) {
@@ -136,7 +154,7 @@ void InProcessContextFactory::CreateOutputSurface(
scoped_ptr<cc::SurfaceDisplayOutputSurface> surface_output_surface(
new cc::SurfaceDisplayOutputSurface(
surface_manager_, compositor->surface_id_allocator(),
- context_provider, worker_context_provider));
+ context_provider, shared_worker_context_provider_));
display_client->set_surface_output_surface(surface_output_surface.get());
surface_output_surface->set_display_client(display_client.get());
diff --git a/ui/compositor/test/in_process_context_factory.h b/ui/compositor/test/in_process_context_factory.h
index 4387adc..3c4e176 100644
--- a/ui/compositor/test/in_process_context_factory.h
+++ b/ui/compositor/test/in_process_context_factory.h
@@ -21,6 +21,7 @@ class SurfaceManager;
}
namespace ui {
+class InProcessContextProvider;
class InProcessContextFactory : public ContextFactory {
public:
@@ -56,7 +57,8 @@ class InProcessContextFactory : public ContextFactory {
const gfx::Size& size) override;
private:
- scoped_refptr<cc::ContextProvider> shared_main_thread_contexts_;
+ scoped_refptr<InProcessContextProvider> shared_main_thread_contexts_;
+ scoped_refptr<InProcessContextProvider> shared_worker_context_provider_;
cc::TestSharedBitmapManager shared_bitmap_manager_;
cc::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
cc::TestImageFactory image_factory_;
diff --git a/ui/compositor/test/in_process_context_provider.h b/ui/compositor/test/in_process_context_provider.h
index 0f5f35f..628eaec 100644
--- a/ui/compositor/test/in_process_context_provider.h
+++ b/ui/compositor/test/in_process_context_provider.h
@@ -38,15 +38,6 @@ class InProcessContextProvider : public cc::ContextProvider {
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
gpu::ImageFactory* image_factory);
- private:
- InProcessContextProvider(
- const gpu::gles2::ContextCreationAttribHelper& attribs,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- gpu::ImageFactory* image_factory,
- gfx::AcceleratedWidget window,
- const std::string& debug_name);
- ~InProcessContextProvider() override;
-
// cc::ContextProvider:
bool BindToCurrentThread() override;
void DetachFromThread() override;
@@ -66,6 +57,15 @@ class InProcessContextProvider : public cc::ContextProvider {
const MemoryPolicyChangedCallback& memory_policy_changed_callback)
override;
+ private:
+ InProcessContextProvider(
+ const gpu::gles2::ContextCreationAttribHelper& attribs,
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+ gpu::ImageFactory* image_factory,
+ gfx::AcceleratedWidget window,
+ const std::string& debug_name);
+ ~InProcessContextProvider() override;
+
void OnLostContext();
base::ThreadChecker main_thread_checker_;