diff options
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/context_group.cc | 28 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group.h | 16 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group_unittest.cc | 44 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc | 3 |
5 files changed, 66 insertions, 35 deletions
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index d04d1d8..ec22342 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -17,8 +17,7 @@ namespace gpu { namespace gles2 { ContextGroup::ContextGroup(bool bind_generates_resource) - : initialized_(false), - have_context_(true), + : num_contexts_(0), bind_generates_resource_(bind_generates_resource), max_vertex_attribs_(0u), max_texture_units_(0u), @@ -36,7 +35,7 @@ ContextGroup::ContextGroup(bool bind_generates_resource) } ContextGroup::~ContextGroup() { - Destroy(); + CHECK(num_contexts_ == 0); } static void GetIntegerv(GLenum pname, uint32* var) { @@ -47,7 +46,8 @@ static void GetIntegerv(GLenum pname, uint32* var) { bool ContextGroup::Initialize(const DisallowedFeatures& disallowed_features, const char* allowed_features) { - if (initialized_) { + if (num_contexts_ > 0) { + ++num_contexts_; return true; } @@ -115,38 +115,42 @@ bool ContextGroup::Initialize(const DisallowedFeatures& disallowed_features, return false; } - initialized_ = true; + ++num_contexts_; return true; } -void ContextGroup::Destroy() { +void ContextGroup::Destroy(bool have_context) { + DCHECK(num_contexts_ > 0); + if (--num_contexts_ > 0) + return; + if (buffer_manager_ != NULL) { - buffer_manager_->Destroy(have_context_); + buffer_manager_->Destroy(have_context); buffer_manager_.reset(); } if (framebuffer_manager_ != NULL) { - framebuffer_manager_->Destroy(have_context_); + framebuffer_manager_->Destroy(have_context); framebuffer_manager_.reset(); } if (renderbuffer_manager_ != NULL) { - renderbuffer_manager_->Destroy(have_context_); + renderbuffer_manager_->Destroy(have_context); renderbuffer_manager_.reset(); } if (texture_manager_ != NULL) { - texture_manager_->Destroy(have_context_); + texture_manager_->Destroy(have_context); texture_manager_.reset(); } if (program_manager_ != NULL) { - program_manager_->Destroy(have_context_); + program_manager_->Destroy(have_context); program_manager_.reset(); } if (shader_manager_ != NULL) { - shader_manager_->Destroy(have_context_); + shader_manager_->Destroy(have_context); shader_manager_.reset(); } } diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 1700423..48fac44 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -39,14 +39,14 @@ class ContextGroup : public base::RefCounted<ContextGroup> { explicit ContextGroup(bool bind_generates_resource); ~ContextGroup(); - // This should only be called by GLES2Decoder. + // This should only be called by GLES2Decoder. This must be paired with a + // call to destroy if it succeeds. bool Initialize(const DisallowedFeatures& disallowed_features, const char* allowed_features); - // Sets the ContextGroup has having a lost context. - void set_have_context(bool have_context) { - have_context_ = have_context; - } + // Destroys all the resources when called for the last context in the group. + // It should only be called by GLES2Decoder. + void Destroy(bool have_context); bool bind_generates_resource() { return bind_generates_resource_; @@ -111,12 +111,8 @@ class ContextGroup : public base::RefCounted<ContextGroup> { IdAllocatorInterface* GetIdAllocator(unsigned namespace_id); private: - // Destroys all the resources. - void Destroy(); - // Whether or not this context is initialized. - bool initialized_; - bool have_context_; + int num_contexts_; bool bind_generates_resource_; uint32 max_vertex_attribs_; diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc index bf8809e..bb60af9 100644 --- a/gpu/command_buffer/service/context_group_unittest.cc +++ b/gpu/command_buffer/service/context_group_unittest.cc @@ -40,10 +40,6 @@ class ContextGroupTest : public testing::Test { } virtual void TearDown() { - // we must release the ContextGroup before we clear out the GL interface. - // since its destructor uses GL. - group_->set_have_context(false); - group_ = NULL; ::gfx::GLInterface::SetGLInterface(NULL); gl_.reset(); } @@ -93,6 +89,46 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) { EXPECT_TRUE(group_->texture_manager() != NULL); EXPECT_TRUE(group_->program_manager() != NULL); EXPECT_TRUE(group_->shader_manager() != NULL); + + group_->Destroy(false); + EXPECT_TRUE(group_->buffer_manager() == NULL); + EXPECT_TRUE(group_->framebuffer_manager() == NULL); + EXPECT_TRUE(group_->renderbuffer_manager() == NULL); + EXPECT_TRUE(group_->texture_manager() == NULL); + EXPECT_TRUE(group_->program_manager() == NULL); + EXPECT_TRUE(group_->shader_manager() == NULL); +} + +TEST_F(ContextGroupTest, MultipleContexts) { + TestHelper::SetupContextGroupInitExpectations(gl_.get(), + DisallowedFeatures(), ""); + group_->Initialize(DisallowedFeatures(), ""); + group_->Initialize(DisallowedFeatures(), ""); + + EXPECT_TRUE(group_->buffer_manager() != NULL); + EXPECT_TRUE(group_->framebuffer_manager() != NULL); + EXPECT_TRUE(group_->renderbuffer_manager() != NULL); + EXPECT_TRUE(group_->texture_manager() != NULL); + EXPECT_TRUE(group_->program_manager() != NULL); + EXPECT_TRUE(group_->shader_manager() != NULL); + + group_->Destroy(false); + + EXPECT_TRUE(group_->buffer_manager() != NULL); + EXPECT_TRUE(group_->framebuffer_manager() != NULL); + EXPECT_TRUE(group_->renderbuffer_manager() != NULL); + EXPECT_TRUE(group_->texture_manager() != NULL); + EXPECT_TRUE(group_->program_manager() != NULL); + EXPECT_TRUE(group_->shader_manager() != NULL); + + group_->Destroy(false); + + EXPECT_TRUE(group_->buffer_manager() == NULL); + EXPECT_TRUE(group_->framebuffer_manager() == NULL); + EXPECT_TRUE(group_->renderbuffer_manager() == NULL); + EXPECT_TRUE(group_->texture_manager() == NULL); + EXPECT_TRUE(group_->program_manager() == NULL); + EXPECT_TRUE(group_->shader_manager() == NULL); } } // namespace gles2 diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 35ae5b9..c3402d9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2360,9 +2360,6 @@ bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, void GLES2DecoderImpl::Destroy() { bool have_context = context_.get() && MakeCurrent(); - if (group_.get()) - group_->set_have_context(have_context); - SetParent(NULL, 0); if (have_context) { @@ -2396,10 +2393,6 @@ void GLES2DecoderImpl::Destroy() { offscreen_resolved_frame_buffer_->Destroy(); if (offscreen_resolved_color_texture_.get()) offscreen_resolved_color_texture_->Destroy(); - - // must release the ContextGroup before destroying the context as its - // destructor uses GL. - group_ = NULL; } else { if (offscreen_target_frame_buffer_.get()) offscreen_target_frame_buffer_->Invalidate(); @@ -2421,6 +2414,9 @@ void GLES2DecoderImpl::Destroy() { offscreen_resolved_color_texture_->Invalidate(); } + group_->Destroy(have_context); + group_ = NULL; + if (context_.get()) { context_->ReleaseCurrent(NULL); context_ = NULL; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 7dace75..1a72012 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -221,8 +221,7 @@ void GLES2DecoderTestBase::TearDown() { .RetiresOnSaturation(); decoder_->Destroy(); decoder_.reset(); - group_->set_have_context(false); - group_ = NULL; + group_->Destroy(false); engine_.reset(); ::gfx::GLInterface::SetGLInterface(NULL); gl_.reset(); |