diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 03:58:07 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 03:58:07 +0000 |
commit | 4f9958143b76ecb130820cc5e4edbd820640676e (patch) | |
tree | 09bf3f5c10f261f3f6aac2fb6de038c750d67619 | |
parent | 508b89a64ab700aa09f21fc666a5588b47360eab (diff) | |
download | chromium_src-4f9958143b76ecb130820cc5e4edbd820640676e.zip chromium_src-4f9958143b76ecb130820cc5e4edbd820640676e.tar.gz chromium_src-4f9958143b76ecb130820cc5e4edbd820640676e.tar.bz2 |
Fix stream textures + mailboxes
DestroyStreamTexture was called from DeleteTextures, which is awkward because it doesn't mean the texture is actually deleted.
Instead, rationalize StreamTexture ownership, by making it associated with the TextureRef (i.e. client id) that created it. When the TextureRef is destroyed and the stream texture wasn't explicitly destroyed yet, it gets destroyed implicitly at this point.
The StreamTextureManager still maps StreamTextures by service id, so that multiple TextureRef in the same ContextGroup (in practice, in the same channel actually) will still allow updates on bind.
This also makes explicit the fact that the StreamTextureManager is shared per ContxtGroup, since we rely on that for Update.
BUG=254494
Review URL: https://chromiumcodereview.appspot.com/18430002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209605 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.cc | 9 | ||||
-rw-r--r-- | gpu/command_buffer/client/gl_in_process_context.cc | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group.h | 7 | ||||
-rw-r--r-- | gpu/command_buffer/service/context_group_unittest.cc | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 36 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_mock.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 66 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc | 9 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 18 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 26 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_manager.cc | 1 | ||||
-rw-r--r-- | gpu/demos/framework/window.cc | 2 | ||||
-rw-r--r-- | gpu/gles2_conform_support/egl/display.cc | 2 |
16 files changed, 136 insertions, 59 deletions
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index abfa92f..321a2ca8 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -141,10 +141,15 @@ GpuCommandBufferStub::GpuCommandBufferStub( if (share_group) { context_group_ = share_group->context_group_; } else { + gpu::StreamTextureManager* stream_texture_manager = NULL; +#if defined(OS_ANDROID) + stream_texture_manager = channel_->stream_texture_manager(); +#endif context_group_ = new gpu::gles2::ContextGroup( mailbox_manager, image_manager, new GpuCommandBufferMemoryTracker(channel), + stream_texture_manager, true); } } @@ -536,10 +541,6 @@ void GpuCommandBufferStub::OnInitialize( base::Unretained(this))); } -#if defined(OS_ANDROID) - decoder_->SetStreamTextureManager(channel_->stream_texture_manager()); -#endif - if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass())) { DLOG(ERROR) << "Failed to map shared stae buffer."; OnInitializeFailed(reply_message); diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc index 7e17929..2f9f41e 100644 --- a/gpu/command_buffer/client/gl_in_process_context.cc +++ b/gpu/command_buffer/client/gl_in_process_context.cc @@ -376,7 +376,7 @@ bool GLInProcessContextImpl::Initialize( decoder_.reset(gles2::GLES2Decoder::Create( context_group ? context_group->decoder_->GetContextGroup() : new gles2::ContextGroup( - NULL, NULL, NULL, bind_generates_resource))); + NULL, NULL, NULL, NULL, bind_generates_resource))); gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(), decoder_.get(), diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 91214bd..bbacc71 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -32,10 +32,12 @@ ContextGroup::ContextGroup( MailboxManager* mailbox_manager, ImageManager* image_manager, MemoryTracker* memory_tracker, + StreamTextureManager* stream_texture_manager, bool bind_generates_resource) : mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager), image_manager_(image_manager ? image_manager : new ImageManager), memory_tracker_(memory_tracker), + stream_texture_manager_(stream_texture_manager), enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnforceGLMinimums)), bind_generates_resource_(bind_generates_resource), @@ -170,6 +172,7 @@ bool ContextGroup::Initialize( max_texture_size, max_cube_map_texture_size)); texture_manager_->set_framebuffer_manager(framebuffer_manager_.get()); + texture_manager_->set_stream_texture_manager(stream_texture_manager_); const GLint kMinTextureImageUnits = 8; const GLint kMinVertexTextureImageUnits = 0; @@ -305,6 +308,7 @@ void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { } memory_tracker_ = NULL; + stream_texture_manager_ = NULL; } IdAllocatorInterface* ContextGroup::GetIdAllocator(unsigned namespace_id) { diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index a8edaf0..13d031a 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -21,6 +21,7 @@ namespace gpu { class IdAllocatorInterface; +class StreamTextureManager; class TransferBufferManagerInterface; namespace gles2 { @@ -46,6 +47,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { MailboxManager* mailbox_manager, ImageManager* image_manager, MemoryTracker* memory_tracker, + StreamTextureManager* stream_texture_manager, bool bind_generates_resource); // This should only be called by GLES2Decoder. This must be paired with a @@ -71,6 +73,10 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { return memory_tracker_.get(); } + StreamTextureManager* stream_texture_manager() const { + return stream_texture_manager_; + } + bool bind_generates_resource() { return bind_generates_resource_; } @@ -179,6 +185,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { scoped_refptr<MailboxManager> mailbox_manager_; scoped_refptr<ImageManager> image_manager_; scoped_refptr<MemoryTracker> memory_tracker_; + StreamTextureManager* stream_texture_manager_; scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; bool enforce_gl_minimums_; diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc index 11df9e8..c80f619 100644 --- a/gpu/command_buffer/service/context_group_unittest.cc +++ b/gpu/command_buffer/service/context_group_unittest.cc @@ -39,7 +39,7 @@ class ContextGroupTest : public testing::Test { ::gfx::GLInterface::SetGLInterface(gl_.get()); decoder_.reset(new MockGLES2Decoder()); group_ = scoped_refptr<ContextGroup>( - new ContextGroup(NULL, NULL, NULL, true)); + new ContextGroup(NULL, NULL, NULL, NULL, true)); } virtual void TearDown() { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 852e297..6ed619c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -598,8 +598,6 @@ class GLES2DecoderImpl : public GLES2Decoder { virtual void SetWaitSyncPointCallback( const WaitSyncPointCallback& callback) OVERRIDE; - virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE; - virtual AsyncPixelTransferManager* GetAsyncPixelTransferManager() OVERRIDE; virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE; @@ -710,6 +708,10 @@ class GLES2DecoderImpl : public GLES2Decoder { return group_->memory_tracker(); } + StreamTextureManager* stream_texture_manager() const { + return group_->stream_texture_manager(); + } + bool EnsureGPUMemoryAvailable(size_t estimated_size) { MemoryTracker* tracker = memory_tracker(); if (tracker) { @@ -1657,7 +1659,6 @@ class GLES2DecoderImpl : public GLES2Decoder { ShaderCacheCallback shader_cache_callback_; - StreamTextureManager* stream_texture_manager_; scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_; // The format of the back buffer_ @@ -2136,7 +2137,6 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) offscreen_target_samples_(0), offscreen_target_buffer_preserved_(true), offscreen_saved_color_format_(0), - stream_texture_manager_(NULL), back_buffer_color_format_(0), back_buffer_has_depth_(false), back_buffer_has_stencil_(false), @@ -2760,11 +2760,8 @@ void GLES2DecoderImpl::DeleteTexturesHelper( ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); } } - GLuint service_id = texture->service_id(); - if (texture->IsStreamTexture() && stream_texture_manager_) { - stream_texture_manager_->DestroyStreamTexture(service_id); - } #if defined(OS_MACOSX) + GLuint service_id = texture->service_id(); if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) { ReleaseIOSurfaceForTexture(service_id); } @@ -3068,10 +3065,6 @@ void GLES2DecoderImpl::SetWaitSyncPointCallback( wait_sync_point_callback_ = callback; } -void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { - stream_texture_manager_ = manager; -} - AsyncPixelTransferManager* GLES2DecoderImpl::GetAsyncPixelTransferManager() { return async_pixel_transfer_manager_.get(); @@ -3867,9 +3860,10 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { case GL_TEXTURE_EXTERNAL_OES: unit.bound_texture_external_oes = texture_ref; if (texture->IsStreamTexture()) { - DCHECK(stream_texture_manager_); + DCHECK(stream_texture_manager()); StreamTexture* stream_tex = - stream_texture_manager_->LookupStreamTexture(texture->service_id()); + stream_texture_manager()->LookupStreamTexture( + texture->service_id()); if (stream_tex) stream_tex->Update(); } @@ -9338,10 +9332,10 @@ error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM( return error::kNoError; } - if (!stream_texture_manager_) + if (!stream_texture_manager()) return error::kInvalidArguments; - GLuint object_id = stream_texture_manager_->CreateStreamTexture( + GLuint object_id = stream_texture_manager()->CreateStreamTexture( texture->service_id(), client_id); if (object_id) { @@ -9361,11 +9355,11 @@ error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM( const cmds::DestroyStreamTextureCHROMIUM& c) { GLuint client_id = c.texture; TextureRef* texture_ref = texture_manager()->GetTexture(client_id); - if (texture_ref && texture_ref->texture()->IsStreamTexture()) { - if (!stream_texture_manager_) + if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) { + if (!stream_texture_manager()) return error::kInvalidArguments; - stream_texture_manager_->DestroyStreamTexture(texture_ref->service_id()); + stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id()); texture_manager()->SetStreamTexture(texture_ref, false); } else { LOCAL_SET_GL_ERROR( @@ -9577,9 +9571,9 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( } if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { - DCHECK(stream_texture_manager_); + DCHECK(stream_texture_manager()); StreamTexture* stream_tex = - stream_texture_manager_->LookupStreamTexture( + stream_texture_manager()->LookupStreamTexture( source_texture->service_id()); if (!stream_tex) { LOCAL_SET_GL_ERROR( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 1526cfb..97c8f58 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -176,8 +176,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, virtual void SetResizeCallback( const base::Callback<void(gfx::Size, float)>& callback) = 0; - virtual void SetStreamTextureManager(StreamTextureManager* manager) = 0; - // Interface to performing async pixel transfers. virtual AsyncPixelTransferManager* GetAsyncPixelTransferManager() = 0; virtual void ResetAsyncPixelTransferManagerForTest() = 0; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 93dd09d..abac629 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -71,7 +71,6 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(GetVertexArrayManager, gpu::gles2::VertexArrayManager*()); MOCK_METHOD1( SetResizeCallback, void(const base::Callback<void(gfx::Size, float)>&)); - MOCK_METHOD1(SetStreamTextureManager, void(StreamTextureManager*)); MOCK_METHOD0(GetAsyncPixelTransferDelegate, AsyncPixelTransferDelegate*()); MOCK_METHOD0(GetAsyncPixelTransferManager, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 313323b..09ed184 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -5628,11 +5628,8 @@ TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUM) { false, // request stencil true); // bind generates resource - StrictMock<MockStreamTextureManager> manager; - decoder_->SetStreamTextureManager(&manager); - - EXPECT_CALL(manager, CreateStreamTexture(kServiceTextureId, - client_texture_id_)) + EXPECT_CALL(*stream_texture_manager(), CreateStreamTexture( + kServiceTextureId, client_texture_id_)) .WillOnce(Return(kObjectId)) .RetiresOnSaturation(); @@ -5646,6 +5643,10 @@ TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUM) { TextureRef* texture_ref = GetTexture(client_texture_id_); EXPECT_TRUE(texture_ref != NULL); EXPECT_TRUE(texture_ref->texture()->IsStreamTexture()); + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); } TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMBadId) { @@ -5707,6 +5708,11 @@ TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMAlreadySet) { cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); } TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUM) { @@ -5720,9 +5726,7 @@ TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUM) { false, // request stencil true); // bind generates resource - StrictMock<MockStreamTextureManager> manager; StrictMock<MockStreamTexture> stream_texture; - decoder_->SetStreamTextureManager(&manager); TextureRef* texture_ref = GetTexture(client_texture_id_); group().texture_manager()->SetStreamTexture(texture_ref, true); @@ -5730,7 +5734,7 @@ TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUM) { EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kServiceTextureId)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(manager, LookupStreamTexture(kServiceTextureId)) + EXPECT_CALL(*stream_texture_manager(), LookupStreamTexture(kServiceTextureId)) .WillOnce(Return(&stream_texture)) .RetiresOnSaturation(); EXPECT_CALL(stream_texture, Update()) @@ -5741,6 +5745,11 @@ TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUM) { cmd.Init(GL_TEXTURE_EXTERNAL_OES, client_texture_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); } TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUMInvalid) { @@ -5766,6 +5775,11 @@ TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUMInvalid) { cmd2.Init(GL_TEXTURE_CUBE_MAP, client_texture_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); } TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUM) { @@ -5779,13 +5793,11 @@ TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUM) { false, // request stencil true); // bind generates resource - StrictMock<MockStreamTextureManager> manager; - decoder_->SetStreamTextureManager(&manager); - TextureRef* texture_ref = GetTexture(client_texture_id_); group().texture_manager()->SetStreamTexture(texture_ref, true); - EXPECT_CALL(manager, DestroyStreamTexture(kServiceTextureId)) + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) .Times(1) .RetiresOnSaturation(); @@ -5808,9 +5820,6 @@ TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUMInvalid) { false, // request stencil true); // bind generates resource - TextureRef* texture_ref = GetTexture(client_texture_id_); - group().texture_manager()->SetStreamTexture(texture_ref, false); - DestroyStreamTextureCHROMIUM cmd; cmd.Init(client_texture_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -5836,7 +5845,7 @@ TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUMBadId) { TEST_F(GLES2DecoderManualInitTest, StreamTextureCHROMIUMNullMgr) { InitDecoder( - "GL_CHROMIUM_stream_texture", // extensions + "", // extensions false, // has alpha false, // has depth false, // has stencil @@ -5871,21 +5880,20 @@ TEST_F(GLES2DecoderManualInitTest, ReCreateStreamTextureCHROMIUM) { false, // request stencil true); // bind generates resource - StrictMock<MockStreamTextureManager> manager; StrictMock<MockStreamTexture> stream_texture; - decoder_->SetStreamTextureManager(&manager); - EXPECT_CALL(manager, LookupStreamTexture(kServiceTextureId)) + EXPECT_CALL(*stream_texture_manager(), LookupStreamTexture(kServiceTextureId)) .WillOnce(Return(&stream_texture)) .RetiresOnSaturation(); EXPECT_CALL(stream_texture, Update()) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(manager, DestroyStreamTexture(kServiceTextureId)) + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(manager, CreateStreamTexture(kServiceTextureId, - client_texture_id_)) + EXPECT_CALL(*stream_texture_manager(), + CreateStreamTexture(kServiceTextureId, client_texture_id_)) .WillOnce(Return(kObjectId)) .RetiresOnSaturation(); @@ -5906,6 +5914,11 @@ TEST_F(GLES2DecoderManualInitTest, ReCreateStreamTextureCHROMIUM) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); EXPECT_TRUE(texture_ref->texture()->IsStreamTexture()); + + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); } TEST_F(GLES2DecoderManualInitTest, ProduceAndConsumeStreamTextureCHROMIUM) { @@ -5919,9 +5932,7 @@ TEST_F(GLES2DecoderManualInitTest, ProduceAndConsumeStreamTextureCHROMIUM) { false, // request stencil true); // bind generates resource - StrictMock<MockStreamTextureManager> manager; StrictMock<MockStreamTexture> stream_texture; - decoder_->SetStreamTextureManager(&manager); TextureRef* texture_ref = GetTexture(client_texture_id_); group().texture_manager()->SetStreamTexture(texture_ref, true); @@ -5929,7 +5940,7 @@ TEST_F(GLES2DecoderManualInitTest, ProduceAndConsumeStreamTextureCHROMIUM) { EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kServiceTextureId)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(manager, LookupStreamTexture(kServiceTextureId)) + EXPECT_CALL(*stream_texture_manager(), LookupStreamTexture(kServiceTextureId)) .WillOnce(Return(&stream_texture)) .RetiresOnSaturation(); EXPECT_CALL(stream_texture, Update()) @@ -5979,6 +5990,11 @@ TEST_F(GLES2DecoderManualInitTest, ProduceAndConsumeStreamTextureCHROMIUM) { // Service ID is restored. EXPECT_EQ(kServiceTextureId, texture_ref->service_id()); + + EXPECT_CALL(*stream_texture_manager(), + DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); } TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) { 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 7f29323..f4cb2a0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -9,6 +9,7 @@ #include <vector> #include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" @@ -90,10 +91,18 @@ void GLES2DecoderTestBase::InitDecoder( Framebuffer::ClearFramebufferCompleteComboMap(); gl_.reset(new StrictMock<MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); + + // Only create stream texture manager if extension is requested. + std::vector<std::string> list; + base::SplitString(std::string(extensions), ' ', &list); + if (std::find(list.begin(), list.end(), + "GL_CHROMIUM_stream_texture") != list.end()) + stream_texture_manager_.reset(new StrictMock<MockStreamTextureManager>); group_ = scoped_refptr<ContextGroup>(new ContextGroup( NULL, NULL, memory_tracker_, + stream_texture_manager_.get(), bind_generates_resource)); // These two workarounds are always turned on. group_->feature_info( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 55dc7e4..0adae2d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -16,6 +16,7 @@ #include "gpu/command_buffer/service/query_manager.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/shader_manager.h" +#include "gpu/command_buffer/service/stream_texture_manager_mock.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/vertex_array_manager.h" @@ -137,6 +138,11 @@ class GLES2DecoderTestBase : public testing::Test { return group_->program_manager(); } + ::testing::StrictMock<MockStreamTextureManager>* + stream_texture_manager() const { + return stream_texture_manager_.get(); + } + void DoCreateProgram(GLuint client_id, GLuint service_id); void DoCreateShader(GLenum shader_type, GLuint client_id, GLuint service_id); @@ -527,6 +533,8 @@ class GLES2DecoderTestBase : public testing::Test { void AddExpectationsForVertexAttribManager(); scoped_ptr< ::testing::StrictMock<MockCommandBufferEngine> > engine_; + scoped_ptr< ::testing::StrictMock<MockStreamTextureManager> > + stream_texture_manager_; scoped_refptr<ContextGroup> group_; }; diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 117e951..486bdac 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -12,6 +12,7 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" +#include "gpu/command_buffer/service/stream_texture_manager.h" namespace gpu { namespace gles2 { @@ -802,7 +803,8 @@ TextureRef::TextureRef(TextureManager* manager, Texture* texture) : manager_(manager), texture_(texture), - client_id_(client_id) { + client_id_(client_id), + is_stream_texture_owner_(false) { DCHECK(manager_); DCHECK(texture_); texture_->AddTextureRef(this); @@ -832,6 +834,7 @@ TextureManager::TextureManager( new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), feature_info_(feature_info), framebuffer_manager_(NULL), + stream_texture_manager_(NULL), max_texture_size_(max_texture_size), max_cube_map_texture_size_(max_cube_map_texture_size), max_levels_(ComputeMipMapCount(max_texture_size, @@ -979,7 +982,15 @@ void TextureManager::SetTarget(TextureRef* ref, GLenum target) { void TextureManager::SetStreamTexture(TextureRef* ref, bool stream_texture) { DCHECK(ref); + // Only the owner can mark as non-stream texture. + DCHECK_EQ(stream_texture, !ref->is_stream_texture_owner_); ref->texture()->SetStreamTexture(stream_texture); + ref->set_is_stream_texture_owner(stream_texture); +} + +bool TextureManager::IsStreamTextureOwner(TextureRef* ref) { + DCHECK(ref); + return ref->is_stream_texture_owner(); } void TextureManager::SetLevelCleared(TextureRef* ref, @@ -1128,6 +1139,11 @@ void TextureManager::StopTracking(TextureRef* ref) { OnTextureRefDestroying(ref)); Texture* texture = ref->texture(); + if (ref->is_stream_texture_owner_ && stream_texture_manager_) { + DCHECK(texture->IsStreamTexture()); + stream_texture_manager_->DestroyStreamTexture(texture->service_id()); + } + --texture_count_; if (!texture->CanRender(feature_info_.get())) { DCHECK_NE(0, num_unrenderable_textures_); diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index f803732..cbc659c 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -21,6 +21,9 @@ #include "ui/gl/gl_image.h" namespace gpu { + +class StreamTextureManager; + namespace gles2 { class GLES2Decoder; @@ -386,6 +389,13 @@ class GPU_EXPORT Texture { // with a client id, though it can outlive the client id if it's still bound to // a FBO or another context when destroyed. // Multiple TextureRef can point to the same texture with cross-context sharing. +// +// Note: for stream textures, the TextureRef that created the stream texture is +// set as the "owner" of the stream texture, i.e. it will call +// DestroyStreamTexture on destruction. This is because the StreamTextureManager +// isn't generally shared between ContextGroups, so ownership can't be at the +// Texture level. We also can't have multiple StreamTexture on the same service +// id, so there can be only one owner. class GPU_EXPORT TextureRef : public base::RefCounted<TextureRef> { public: TextureRef(TextureManager* manager, GLuint client_id, Texture* texture); @@ -406,10 +416,15 @@ class GPU_EXPORT TextureRef : public base::RefCounted<TextureRef> { const TextureManager* manager() const { return manager_; } TextureManager* manager() { return manager_; } void reset_client_id() { client_id_ = 0; } + void set_is_stream_texture_owner(bool owner) { + is_stream_texture_owner_ = owner; + } + bool is_stream_texture_owner() const { return is_stream_texture_owner_; } TextureManager* manager_; Texture* texture_; GLuint client_id_; + bool is_stream_texture_owner_; DISALLOW_COPY_AND_ASSIGN(TextureRef); }; @@ -454,6 +469,10 @@ class GPU_EXPORT TextureManager { framebuffer_manager_ = manager; } + void set_stream_texture_manager(StreamTextureManager* manager) { + stream_texture_manager_ = manager; + } + // Init the texture manager. bool Initialize(); @@ -511,9 +530,13 @@ class GPU_EXPORT TextureManager { TextureRef* ref, GLenum target); - // Marks a texture as a stream texture. + // Marks a texture as a stream texture, and the ref as the stream texture + // owner. void SetStreamTexture(TextureRef* ref, bool stream_texture); + // Whether the TextureRef is the stream texture owner. + bool IsStreamTextureOwner(TextureRef* ref); + // Set the info for a particular level in a TexureInfo. void SetLevelInfo( TextureRef* ref, @@ -673,6 +696,7 @@ class GPU_EXPORT TextureManager { scoped_refptr<FeatureInfo> feature_info_; FramebufferManager* framebuffer_manager_; + StreamTextureManager* stream_texture_manager_; // Info for each texture in the system. typedef base::hash_map<GLuint, scoped_refptr<TextureRef> > TextureMap; diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index e78328b..f4f6c36 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc @@ -133,6 +133,7 @@ void GLManager::Initialize(const GLManager::Options& options) { context_group = new gles2::ContextGroup(mailbox_manager_.get(), options.image_manager, NULL, + NULL, options.bind_generates_resource); } diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index fd288c7..3974604 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -80,7 +80,7 @@ bool Window::CreateRenderContext(gfx::AcceleratedWidget hwnd) { } scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup( - NULL, NULL, NULL, true)); + NULL, NULL, NULL, NULL, true)); decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get())); if (!decoder_.get()) diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 5288a9b..3c06259 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc @@ -113,7 +113,7 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config, return NULL; scoped_refptr<gpu::gles2::ContextGroup> group( - new gpu::gles2::ContextGroup(NULL, NULL, NULL, true)); + new gpu::gles2::ContextGroup(NULL, NULL, NULL, NULL, true)); decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get())); if (!decoder_.get()) |