diff options
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 9 | ||||
-rw-r--r-- | gpu/command_buffer/client/atomicops.cc | 77 | ||||
-rw-r--r-- | gpu/command_buffer/client/atomicops.h | 37 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.cc | 309 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.h | 40 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation_autogen.h | 28 | ||||
-rw-r--r-- | gpu/command_buffer/client/program_info_manager.cc | 11 | ||||
-rw-r--r-- | gpu/command_buffer/client/share_group.cc | 303 | ||||
-rw-r--r-- | gpu/command_buffer/client/share_group.h | 57 | ||||
-rw-r--r-- | gpu/command_buffer/client/share_group_unittest.cc | 2 |
10 files changed, 564 insertions, 309 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 64e3240..c658053 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -2761,8 +2761,8 @@ class GENnHandler(TypeHandler): for arg in func.GetOriginalArgs(): arg.WriteClientSideValidationCode(file, func) code = """ GPU_CLIENT_SINGLE_THREAD_CHECK(); - id_handlers_[id_namespaces::k%(resource_types)s]-> - MakeIds(0, %(args)s); + GetIdHandler(id_namespaces::k%(resource_types)s)-> + MakeIds(this, 0, %(args)s); helper_->%(name)sImmediate(%(args)s); %(log_code)s } @@ -3011,8 +3011,9 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { for arg in func.GetOriginalArgs(): arg.WriteClientSideValidationCode(file, func) file.Write(" GLuint client_id;\n") - file.Write(" id_handlers_[id_namespaces::kProgramsAndShaders]->\n") - file.Write(" MakeIds(0, 1, &client_id);\n") + file.Write( + " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n") + file.Write(" MakeIds(this, 0, 1, &client_id);\n") file.Write(" helper_->%s(%s);\n" % (func.name, func.MakeCmdArgString(""))) file.Write(' GPU_CLIENT_LOG("returned " << client_id);\n') diff --git a/gpu/command_buffer/client/atomicops.cc b/gpu/command_buffer/client/atomicops.cc index 142ab9c..318c337 100644 --- a/gpu/command_buffer/client/atomicops.cc +++ b/gpu/command_buffer/client/atomicops.cc @@ -3,9 +3,13 @@ // found in the LICENSE file. #include "../client/atomicops.h" +#include "../common/logging.h" #if !defined(__native_client__) #include "base/atomicops.h" +#include "base/synchronization/lock.h" +#else +#include <pthread.h> #endif namespace gpu { @@ -18,5 +22,78 @@ void MemoryBarrier() { #endif } +#if defined(__native_client__) + +class LockImpl { + public: + LockImpl() + : acquired_(false) { + pthread_mutex_init(&mutex_, NULL); + } + + ~LockImpl() { + pthread_mutex_destroy(&mutex_); + } + + void Acquire() { + pthread_mutex_lock(&mutex_); + acquired_ = true; + } + + void Release() { + GPU_DCHECK(acquired_); + acquired_ = false; + pthread_mutex_unlock(&mutex_); + } + + bool Try() { + bool acquired = pthread_mutex_trylock(&mutex_) == 0; + if (acquired) { + acquired_ = true; + } + return acquired; + } + + void AssertAcquired() const { + GPU_DCHECK(acquired_); + } + + private: + bool acquired_; + pthread_mutex_t mutex_; + + DISALLOW_COPY_AND_ASSIGN(LockImpl); +}; + +#else // !__native_client__ + +class LockImpl : public base::Lock { +}; + +#endif // !__native_client__ + +Lock::Lock() + : lock_(new LockImpl()) { +} + +Lock::~Lock() { +} + +void Lock::Acquire() { + lock_->Acquire(); +} + +void Lock::Release() { + lock_->Release(); +} + +bool Lock::Try() { + return lock_->Try(); +} + +void Lock::AssertAcquired() const { + return lock_->AssertAcquired(); +} + } // namespace gpu diff --git a/gpu/command_buffer/client/atomicops.h b/gpu/command_buffer/client/atomicops.h index ffd274c..7fa68bd 100644 --- a/gpu/command_buffer/client/atomicops.h +++ b/gpu/command_buffer/client/atomicops.h @@ -5,10 +5,47 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_ATOMICOPS_H_ #define GPU_COMMAND_BUFFER_CLIENT_ATOMICOPS_H_ +#include "../../gpu_export.h" +#include "../common/scoped_ptr.h" +#include "../common/types.h" + namespace gpu { void MemoryBarrier(); +class LockImpl; +class GPU_EXPORT Lock { + public: + Lock(); + ~Lock(); + void Acquire(); + void Release(); + bool Try(); + void AssertAcquired() const; + + private: + scoped_ptr<LockImpl> lock_; + + DISALLOW_COPY_AND_ASSIGN(Lock); +}; + +// A helper class that acquires the given Lock while the AutoLock is in scope. +class GPU_EXPORT AutoLock { + public: + explicit AutoLock(Lock& lock) : lock_(lock) { + lock_.Acquire(); + } + + ~AutoLock() { + lock_.AssertAcquired(); + lock_.Release(); + } + + private: + Lock& lock_; + DISALLOW_COPY_AND_ASSIGN(AutoLock); +}; + } // namespace gpu #endif // GPU_COMMAND_BUFFER_CLIENT_ATOMICOPS_H_ diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 06aa79e..cfd4063 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -13,10 +13,8 @@ #include "../client/mapped_memory.h" #include "../client/program_info_manager.h" #include "../client/query_tracker.h" -#include "../client/share_group.h" #include "../client/transfer_buffer.h" #include "../common/gles2_cmd_utils.h" -#include "../common/id_allocator.h" #include "../common/trace_event.h" #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) @@ -36,198 +34,6 @@ static GLuint ToGLuint(const void* ptr) { return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); } -// An id handler for non-shared ids. -class NonSharedIdHandler : public IdHandlerInterface { - public: - NonSharedIdHandler() { } - virtual ~NonSharedIdHandler() { } - - // Overridden from IdHandlerInterface. - virtual void MakeIds(GLuint id_offset, GLsizei n, GLuint* ids) { - if (id_offset == 0) { - for (GLsizei ii = 0; ii < n; ++ii) { - ids[ii] = id_allocator_.AllocateID(); - } - } else { - for (GLsizei ii = 0; ii < n; ++ii) { - ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset); - id_offset = ids[ii] + 1; - } - } - } - - // Overridden from IdHandlerInterface. - virtual bool FreeIds(GLsizei n, const GLuint* ids) { - for (GLsizei ii = 0; ii < n; ++ii) { - id_allocator_.FreeID(ids[ii]); - } - return true; - } - - // Overridden from IdHandlerInterface. - virtual bool MarkAsUsedForBind(GLuint id) { - return id == 0 ? true : id_allocator_.MarkAsUsed(id); - } - private: - IdAllocator id_allocator_; -}; - -// An id handler for non-shared ids that are never reused. -class NonSharedNonReusedIdHandler : public IdHandlerInterface { - public: - NonSharedNonReusedIdHandler() : last_id_(0) { } - virtual ~NonSharedNonReusedIdHandler() { } - - // Overridden from IdHandlerInterface. - virtual void MakeIds(GLuint id_offset, GLsizei n, GLuint* ids) { - for (GLsizei ii = 0; ii < n; ++ii) { - ids[ii] = ++last_id_ + id_offset; - } - } - - // Overridden from IdHandlerInterface. - virtual bool FreeIds(GLsizei /* n */, const GLuint* /* ids */) { - // Ids are never freed. - return true; - } - - // Overridden from IdHandlerInterface. - virtual bool MarkAsUsedForBind(GLuint /* id */) { - // This is only used for Shaders and Programs which have no bind. - return false; - } - - private: - GLuint last_id_; -}; - -// An id handler for shared ids. -class SharedIdHandler : public IdHandlerInterface { - public: - SharedIdHandler( - GLES2Implementation* gles2, - id_namespaces::IdNamespaces id_namespace) - : gles2_(gles2), - id_namespace_(id_namespace) { - } - - virtual ~SharedIdHandler() { } - - virtual void MakeIds(GLuint id_offset, GLsizei n, GLuint* ids) { - gles2_->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids); - } - - virtual bool FreeIds(GLsizei n, const GLuint* ids) { - gles2_->DeleteSharedIdsCHROMIUM(id_namespace_, n, ids); - // We need to ensure that the delete call is evaluated on the service side - // before any other contexts issue commands using these client ids. - gles2_->helper()->CommandBufferHelper::Flush(); - return true; - } - - virtual bool MarkAsUsedForBind(GLuint /* id */) { - // This has no meaning for shared resources. - return true; - } - - private: - GLES2Implementation* gles2_; - id_namespaces::IdNamespaces id_namespace_; -}; - -// An id handler for shared ids that requires ids are made before using and -// that only the context that created the id can delete it. -// Assumes the service will enforce that non made ids generate an error. -class StrictSharedIdHandler : public IdHandlerInterface { - public: - StrictSharedIdHandler( - GLES2Implementation* gles2, - id_namespaces::IdNamespaces id_namespace) - : gles2_(gles2), - id_namespace_(id_namespace) { - } - - virtual ~StrictSharedIdHandler() { - Destroy(); - } - - virtual void MakeIds(GLuint id_offset, GLsizei n, GLuint* ids) { - for (GLsizei ii = 0; ii < n; ++ii) { - ids[ii] = GetId(id_offset); - } - } - - virtual bool FreeIds(GLsizei n, const GLuint* ids) { - // OpenGL sematics. If any id is bad none of them get freed. - for (GLsizei ii = 0; ii < n; ++ii) { - GLuint id = ids[ii]; - if (id != 0) { - ResourceIdSet::iterator it = used_ids_.find(id); - if (it == used_ids_.end()) { - return false; - } - } - } - for (GLsizei ii = 0; ii < n; ++ii) { - GLuint id = ids[ii]; - if (id != 0) { - ResourceIdSet::iterator it = used_ids_.find(id); - if (it != used_ids_.end()) { - used_ids_.erase(it); - free_ids_.push(id); - } - } - } - return true; - } - - virtual bool MarkAsUsedForBind(GLuint /* id */) { - // This has no meaning for shared resources. - return true; - } - - private: - static const GLsizei kNumIdsToGet = 2048; - typedef std::queue<GLuint> ResourceIdQueue; - typedef std::set<GLuint> ResourceIdSet; - - void Destroy() { - // Free all the ids not being used. - while (!free_ids_.empty()) { - GLuint ids[kNumIdsToGet]; - int count = 0; - while (count < kNumIdsToGet && !free_ids_.empty()) { - ids[count++] = free_ids_.front(); - free_ids_.pop(); - } - gles2_->DeleteSharedIdsCHROMIUM(id_namespace_, count, ids); - } - } - - GLuint GetId(GLuint id_offset) { - if (free_ids_.empty()) { - GLuint ids[kNumIdsToGet]; - gles2_->GenSharedIdsCHROMIUM(id_namespace_, id_offset, kNumIdsToGet, ids); - for (GLsizei ii = 0; ii < kNumIdsToGet; ++ii) { - free_ids_.push(ids[ii]); - } - } - GLuint id = free_ids_.front(); - free_ids_.pop(); - used_ids_.insert(id); - return id; - } - - GLES2Implementation* gles2_; - id_namespaces::IdNamespaces id_namespace_; - ResourceIdSet used_ids_; - ResourceIdQueue free_ids_; -}; - -#ifndef _MSC_VER -const GLsizei StrictSharedIdHandler::kNumIdsToGet; -#endif - static GLsizei RoundUpToMultipleOf4(GLsizei size) { return (size + 3) & ~3; } @@ -559,9 +365,6 @@ const size_t GLES2Implementation::kMaxSizeOfSimpleResult; const unsigned int GLES2Implementation::kStartingOffset; #endif -COMPILE_ASSERT(gpu::kInvalidResource == 0, - INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS); - GLES2Implementation::SingleThreadChecker::SingleThreadChecker( GLES2Implementation* gles2_implementation) : gles2_implementation_(gles2_implementation) { @@ -596,8 +399,6 @@ GLES2Implementation::GLES2Implementation( client_side_element_array_id_(0), error_bits_(0), debug_(false), - sharing_resources_(share_resources), - bind_generates_resource_(bind_generates_resource), use_count_(0), current_query_(NULL), error_message_callback_(NULL) { @@ -608,7 +409,8 @@ GLES2Implementation::GLES2Implementation( switches::kEnableGPUClientLogging); }); - share_group_ = (share_group ? share_group : new ShareGroup()); + share_group_ = (share_group ? share_group : new ShareGroup( + share_resources, bind_generates_resource)); memset(&reserved_ids_, 0, sizeof(reserved_ids_)); } @@ -634,27 +436,6 @@ bool GLES2Implementation::Initialize( mapped_memory_.reset(new MappedMemoryManager(helper_)); SetSharedMemoryChunkSizeMultiple(1024 * 1024 * 2); - if (sharing_resources_) { - if (!bind_generates_resource_) { - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { - id_handlers_[i].reset(new StrictSharedIdHandler( - this, static_cast<id_namespaces::IdNamespaces>(i))); - } - } else { - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { - id_handlers_[i].reset(new SharedIdHandler( - this, static_cast<id_namespaces::IdNamespaces>(i))); - } - } - } else { - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { - if (i == id_namespaces::kProgramsAndShaders) - id_handlers_[i].reset(new NonSharedNonReusedIdHandler); - else - id_handlers_[i].reset(new NonSharedIdHandler); - } - } - static const GLenum pnames[] = { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_CUBE_MAP_TEXTURE_SIZE, @@ -682,12 +463,11 @@ bool GLES2Implementation::Initialize( texture_units_.reset( new TextureUnit[gl_state_.max_combined_texture_image_units]); - program_info_manager_.reset(ProgramInfoManager::Create(sharing_resources_)); query_tracker_.reset(new QueryTracker(mapped_memory_.get())); #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) - id_handlers_[id_namespaces::kBuffers]->MakeIds( - kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); + GetIdHandler(id_namespaces::kBuffers)->MakeIds( + this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); client_side_buffer_helper_.reset(new ClientSideBufferHelper( gl_state_.max_vertex_attribs, @@ -709,13 +489,29 @@ GLES2Implementation::~GLES2Implementation() { #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); #endif - for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { - id_handlers_[i].reset(); - } + // The share group needs to be able to use a command buffer to talk + // to service if it's destroyed so set one for it then release the reference. + // If it's destroyed it will use this GLES2Implemenation. + share_group_->SetGLES2ImplementationForDestruction(this); + share_group_ = NULL; // Make sure the commands make it the service. Finish(); } +GLuint GLES2Implementation::MakeTextureId() { + GLuint id; + GetIdHandler(id_namespaces::kTextures)->MakeIds(this, 0, 1, &id); + return id; +} + +void GLES2Implementation::FreeTextureId(GLuint id) { + GetIdHandler(id_namespaces::kTextures)->FreeIds(this, 1, &id); +} + +IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { + return share_group_->GetIdHandler(namespace_id); +} + void* GLES2Implementation::GetResultBuffer() { return transfer_buffer_->GetResultBuffer(); } @@ -961,13 +757,13 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { *params = gl_state_.num_shader_binary_formats; return true; case GL_ARRAY_BUFFER_BINDING: - if (bind_generates_resource_) { + if (share_group_->bind_generates_resource()) { *params = bound_array_buffer_id_; return true; } return false; case GL_ELEMENT_ARRAY_BUFFER_BINDING: - if (bind_generates_resource_) { + if (share_group_->bind_generates_resource()) { *params = bound_element_array_buffer_id_; return true; } @@ -976,25 +772,25 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { *params = active_texture_unit_ + GL_TEXTURE0; return true; case GL_TEXTURE_BINDING_2D: - if (bind_generates_resource_) { + if (share_group_->bind_generates_resource()) { *params = texture_units_[active_texture_unit_].bound_texture_2d; return true; } return false; case GL_TEXTURE_BINDING_CUBE_MAP: - if (bind_generates_resource_) { + if (share_group_->bind_generates_resource()) { *params = texture_units_[active_texture_unit_].bound_texture_cube_map; return true; } return false; case GL_FRAMEBUFFER_BINDING: - if (bind_generates_resource_) { + if (share_group_->bind_generates_resource()) { *params = bound_framebuffer_; return true; } return false; case GL_RENDERBUFFER_BINDING: - if (bind_generates_resource_) { + if (share_group_->bind_generates_resource()) { *params = bound_renderbuffer_; return true; } @@ -1275,25 +1071,27 @@ void GLES2Implementation::GetVertexAttribPointerv( } bool GLES2Implementation::DeleteProgramHelper(GLuint program) { - if (!id_handlers_[id_namespaces::kProgramsAndShaders]->FreeIds(1, &program)) { + if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( + this, 1, &program)) { SetGLError( GL_INVALID_VALUE, "glDeleteProgram: id not created by this context."); return false; } - program_info_manager_->DeleteInfo(program); + share_group_->program_info_manager()->DeleteInfo(program); helper_->DeleteProgram(program); return true; } bool GLES2Implementation::DeleteShaderHelper(GLuint shader) { - if (!id_handlers_[id_namespaces::kProgramsAndShaders]->FreeIds(1, &shader)) { + if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( + this, 1, &shader)) { SetGLError( GL_INVALID_VALUE, "glDeleteShader: id not created by this context."); return false; } - program_info_manager_->DeleteInfo(shader); + share_group_->program_info_manager()->DeleteInfo(shader); helper_->DeleteShader(shader); return true; } @@ -1320,7 +1118,8 @@ GLint GLES2Implementation::GetAttribLocation( GPU_CLIENT_LOG("[" << this << "] glGetAttribLocation(" << program << ", " << name << ")"); TRACE_EVENT0("gpu", "GLES2::GetAttribLocation"); - GLint loc = program_info_manager_->GetAttribLocation(this, program, name); + GLint loc = share_group_->program_info_manager()->GetAttribLocation( + this, program, name); GPU_CLIENT_LOG("returned " << loc); return loc; } @@ -1347,21 +1146,23 @@ GLint GLES2Implementation::GetUniformLocation( GPU_CLIENT_LOG("[" << this << "] glGetUniformLocation(" << program << ", " << name << ")"); TRACE_EVENT0("gpu", "GLES2::GetUniformLocation"); - GLint loc = program_info_manager_->GetUniformLocation(this, program, name); + GLint loc = share_group_->program_info_manager()->GetUniformLocation( + this, program, name); GPU_CLIENT_LOG("returned " << loc); return loc; } bool GLES2Implementation::GetProgramivHelper( GLuint program, GLenum pname, GLint* params) { - return program_info_manager_->GetProgramiv(this, program, pname, params); + return share_group_->program_info_manager()->GetProgramiv( + this, program, pname, params); } void GLES2Implementation::LinkProgram(GLuint program) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << this << "] glLinkProgram(" << program << ")"); helper_->LinkProgram(program); - program_info_manager_->CreateInfo(program); + share_group_->program_info_manager()->CreateInfo(program); } void GLES2Implementation::ShaderBinary( @@ -1953,7 +1754,7 @@ void GLES2Implementation::GetActiveAttrib( return; } TRACE_EVENT0("gpu", "GLES2::GetActiveAttrib"); - bool success = program_info_manager_->GetActiveAttrib( + bool success = share_group_->program_info_manager()->GetActiveAttrib( this, program, index, bufsize, length, size, type, name); if (success) { if (size) { @@ -2023,7 +1824,7 @@ void GLES2Implementation::GetActiveUniform( return; } TRACE_EVENT0("gpu", "GLES2::GetActiveUniform"); - bool success = program_info_manager_->GetActiveUniform( + bool success = share_group_->program_info_manager()->GetActiveUniform( this, program, index, bufsize, length, size, type, name); if (success) { if (size) { @@ -2343,7 +2144,7 @@ void GLES2Implementation::BindBufferHelper( } // TODO(gman): There's a bug here. If the target is invalid the ID will not be // used even though it's marked it as used here. - id_handlers_[id_namespaces::kBuffers]->MarkAsUsedForBind(buffer); + GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); } void GLES2Implementation::BindFramebufferHelper( @@ -2358,7 +2159,7 @@ void GLES2Implementation::BindFramebufferHelper( } // TODO(gman): There's a bug here. If the target is invalid the ID will not be // used even though it's marked it as used here. - id_handlers_[id_namespaces::kFramebuffers]->MarkAsUsedForBind(framebuffer); + GetIdHandler(id_namespaces::kFramebuffers)->MarkAsUsedForBind(framebuffer); } void GLES2Implementation::BindRenderbufferHelper( @@ -2373,7 +2174,7 @@ void GLES2Implementation::BindRenderbufferHelper( } // TODO(gman): There's a bug here. If the target is invalid the ID will not be // used even though it's marked it as used here. - id_handlers_[id_namespaces::kRenderbuffers]->MarkAsUsedForBind(renderbuffer); + GetIdHandler(id_namespaces::kRenderbuffers)->MarkAsUsedForBind(renderbuffer); } void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { @@ -2391,7 +2192,7 @@ void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { } // TODO(gman): There's a bug here. If the target is invalid the ID will not be // used. even though it's marked it as used here. - id_handlers_[id_namespaces::kTextures]->MarkAsUsedForBind(texture); + GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); } #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) @@ -2411,7 +2212,7 @@ bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) { void GLES2Implementation::DeleteBuffersHelper( GLsizei n, const GLuint* buffers) { - if (!id_handlers_[id_namespaces::kBuffers]->FreeIds(n, buffers)) { + if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds(this, n, buffers)) { SetGLError( GL_INVALID_VALUE, "glDeleteBuffers: id not created by this context."); @@ -2430,7 +2231,8 @@ void GLES2Implementation::DeleteBuffersHelper( void GLES2Implementation::DeleteFramebuffersHelper( GLsizei n, const GLuint* framebuffers) { - if (!id_handlers_[id_namespaces::kFramebuffers]->FreeIds(n, framebuffers)) { + if (!GetIdHandler(id_namespaces::kFramebuffers)->FreeIds( + this, n, framebuffers)) { SetGLError( GL_INVALID_VALUE, "glDeleteFramebuffers: id not created by this context."); @@ -2446,7 +2248,8 @@ void GLES2Implementation::DeleteFramebuffersHelper( void GLES2Implementation::DeleteRenderbuffersHelper( GLsizei n, const GLuint* renderbuffers) { - if (!id_handlers_[id_namespaces::kRenderbuffers]->FreeIds(n, renderbuffers)) { + if (!GetIdHandler(id_namespaces::kRenderbuffers)->FreeIds( + this, n, renderbuffers)) { SetGLError( GL_INVALID_VALUE, "glDeleteRenderbuffers: id not created by this context."); @@ -2462,7 +2265,8 @@ void GLES2Implementation::DeleteRenderbuffersHelper( void GLES2Implementation::DeleteTexturesHelper( GLsizei n, const GLuint* textures) { - if (!id_handlers_[id_namespaces::kTextures]->FreeIds(n, textures)) { + if (!GetIdHandler(id_namespaces::kTextures)->FreeIds( + this, n, textures)) { SetGLError( GL_INVALID_VALUE, "glDeleteTextures: id not created by this context."); @@ -2991,7 +2795,8 @@ void GLES2Implementation::PostSubBufferCHROMIUM( void GLES2Implementation::DeleteQueriesEXTHelper( GLsizei n, const GLuint* queries) { - if (!id_handlers_[id_namespaces::kQueries]->FreeIds(n, queries)) { + if (!GetIdHandler(id_namespaces::kQueries)->FreeIds( + this, n, queries)) { SetGLError( GL_INVALID_VALUE, "glDeleteTextures: id not created by this context."); diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 352a947..ba1aef8 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -19,6 +19,7 @@ #include "../client/gles2_cmd_helper.h" #include "../client/query_tracker.h" #include "../client/ring_buffer.h" +#include "../client/share_group.h" #include "gles2_impl_export.h" #if !defined(NDEBUG) && !defined(__native_client__) && !defined(GLES2_CONFORMANCE_TESTS) // NOLINT @@ -83,24 +84,6 @@ class TransferBufferInterface; namespace gles2 { class ClientSideBufferHelper; -class ProgramInfoManager; -class ShareGroup; - -// Base class for IdHandlers -class IdHandlerInterface { - public: - IdHandlerInterface() { } - virtual ~IdHandlerInterface() { } - - // Makes some ids at or above id_offset. - virtual void MakeIds(GLuint id_offset, GLsizei n, GLuint* ids) = 0; - - // Frees some ids. - virtual bool FreeIds(GLsizei n, const GLuint* ids) = 0; - - // Marks an id as used for glBind functions. id = 0 does nothing. - virtual bool MarkAsUsedForBind(GLuint id) = 0; -}; // This class emulates GLES2 over command buffers. It can be used by a client // program so that the program does not need deal with shared memory and command @@ -209,15 +192,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation { GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); - GLuint MakeTextureId() { - GLuint id; - id_handlers_[id_namespaces::kTextures]->MakeIds(0, 1, &id); - return id; - } - - void FreeTextureId(GLuint id) { - id_handlers_[id_namespaces::kTextures]->FreeIds(1, &id); - } + GLuint MakeTextureId(); + void FreeTextureId(GLuint id); void SetSharedMemoryChunkSizeMultiple(unsigned int multiple); @@ -454,10 +430,11 @@ class GLES2_IMPL_EXPORT GLES2Implementation { bool IsExtensionAvailable(const char* ext); + IdHandlerInterface* GetIdHandler(int id_namespace) const; + GLES2Util util_; GLES2CmdHelper* helper_; TransferBufferInterface* transfer_buffer_; - scoped_ptr<IdHandlerInterface> id_handlers_[id_namespaces::kNumIdNamespaces]; std::string last_error_; std::queue<int32> swap_buffers_tokens_; @@ -509,11 +486,6 @@ class GLES2_IMPL_EXPORT GLES2Implementation { // Whether or not to print debugging info. bool debug_; - // Whether or not this context is sharing resources. - bool sharing_resources_; - - bool bind_generates_resource_; - // Used to check for single threaded access. int use_count_; @@ -534,8 +506,6 @@ class GLES2_IMPL_EXPORT GLES2Implementation { scoped_ptr<MappedMemoryManager> mapped_memory_; - scoped_ptr<ProgramInfoManager> program_info_manager_; - scoped_refptr<ShareGroup> share_group_; scoped_ptr<QueryTracker> query_tracker_; diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 495a913..dbebd67 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -206,8 +206,8 @@ GLuint CreateProgram() { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << this << "] glCreateProgram(" << ")"); GLuint client_id; - id_handlers_[id_namespaces::kProgramsAndShaders]-> - MakeIds(0, 1, &client_id); + GetIdHandler(id_namespaces::kProgramsAndShaders)-> + MakeIds(this, 0, 1, &client_id); helper_->CreateProgram(client_id); GPU_CLIENT_LOG("returned " << client_id); return client_id; @@ -217,8 +217,8 @@ GLuint CreateShader(GLenum type) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << this << "] glCreateShader(" << GLES2Util::GetStringShaderType(type) << ")"); // NOLINT GLuint client_id; - id_handlers_[id_namespaces::kProgramsAndShaders]-> - MakeIds(0, 1, &client_id); + GetIdHandler(id_namespaces::kProgramsAndShaders)-> + MakeIds(this, 0, 1, &client_id); helper_->CreateShader(type, client_id); GPU_CLIENT_LOG("returned " << client_id); return client_id; @@ -402,8 +402,8 @@ void GenBuffers(GLsizei n, GLuint* buffers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - id_handlers_[id_namespaces::kBuffers]-> - MakeIds(0, n, buffers); + GetIdHandler(id_namespaces::kBuffers)-> + MakeIds(this, 0, n, buffers); helper_->GenBuffersImmediate(n, buffers); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { @@ -425,8 +425,8 @@ void GenFramebuffers(GLsizei n, GLuint* framebuffers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - id_handlers_[id_namespaces::kFramebuffers]-> - MakeIds(0, n, framebuffers); + GetIdHandler(id_namespaces::kFramebuffers)-> + MakeIds(this, 0, n, framebuffers); helper_->GenFramebuffersImmediate(n, framebuffers); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { @@ -442,8 +442,8 @@ void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - id_handlers_[id_namespaces::kRenderbuffers]-> - MakeIds(0, n, renderbuffers); + GetIdHandler(id_namespaces::kRenderbuffers)-> + MakeIds(this, 0, n, renderbuffers); helper_->GenRenderbuffersImmediate(n, renderbuffers); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { @@ -459,8 +459,8 @@ void GenTextures(GLsizei n, GLuint* textures) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - id_handlers_[id_namespaces::kTextures]-> - MakeIds(0, n, textures); + GetIdHandler(id_namespaces::kTextures)-> + MakeIds(this, 0, n, textures); helper_->GenTexturesImmediate(n, textures); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { @@ -1416,8 +1416,8 @@ void GenQueriesEXT(GLsizei n, GLuint* queries) { return; } GPU_CLIENT_SINGLE_THREAD_CHECK(); - id_handlers_[id_namespaces::kQueries]-> - MakeIds(0, n, queries); + GetIdHandler(id_namespaces::kQueries)-> + MakeIds(this, 0, n, queries); helper_->GenQueriesEXTImmediate(n, queries); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc index 57a037d..d953914 100644 --- a/gpu/command_buffer/client/program_info_manager.cc +++ b/gpu/command_buffer/client/program_info_manager.cc @@ -1,8 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "../client/program_info_manager.h" +#include "../client/atomicops.h" #include "../client/gles2_implementation.h" #include <map> @@ -193,6 +194,8 @@ class CachedProgramInfoManager : public ProgramInfoManager { typedef std::map<GLuint, ProgramInfo> ProgramInfoMap; ProgramInfoMap program_infos_; + + mutable Lock lock_; }; CachedProgramInfoManager::ProgramInfo::UniformInfo::UniformInfo( @@ -372,6 +375,7 @@ CachedProgramInfoManager::ProgramInfo* } void CachedProgramInfoManager::CreateInfo(GLuint program) { + AutoLock auto_lock(lock_); DeleteInfo(program); std::pair<ProgramInfoMap::iterator, bool> result = program_infos_.insert(std::make_pair(program, ProgramInfo())); @@ -385,6 +389,7 @@ void CachedProgramInfoManager::DeleteInfo(GLuint program) { bool CachedProgramInfoManager::GetProgramiv( GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { + AutoLock auto_lock(lock_); ProgramInfo* info = GetProgramInfo(gl, program); if (!info) { return false; @@ -394,6 +399,7 @@ bool CachedProgramInfoManager::GetProgramiv( GLint CachedProgramInfoManager::GetAttribLocation( GLES2Implementation* gl, GLuint program, const char* name) { + AutoLock auto_lock(lock_); ProgramInfo* info = GetProgramInfo(gl, program); if (info) { return info->GetAttribLocation(name); @@ -403,6 +409,7 @@ GLint CachedProgramInfoManager::GetAttribLocation( GLint CachedProgramInfoManager::GetUniformLocation( GLES2Implementation* gl, GLuint program, const char* name) { + AutoLock auto_lock(lock_); ProgramInfo* info = GetProgramInfo(gl, program); if (info) { return info->GetUniformLocation(name); @@ -414,6 +421,7 @@ bool CachedProgramInfoManager::GetActiveAttrib( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { + AutoLock auto_lock(lock_); ProgramInfo* info = GetProgramInfo(gl, program); if (info) { const ProgramInfo::VertexAttribInfo* attrib_info = @@ -448,6 +456,7 @@ bool CachedProgramInfoManager::GetActiveUniform( GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { + AutoLock auto_lock(lock_); ProgramInfo* info = GetProgramInfo(gl, program); if (info) { const ProgramInfo::UniformInfo* uniform_info = info->GetUniformInfo(index); diff --git a/gpu/command_buffer/client/share_group.cc b/gpu/command_buffer/client/share_group.cc index 3e3b7e6..98b13c5 100644 --- a/gpu/command_buffer/client/share_group.cc +++ b/gpu/command_buffer/client/share_group.cc @@ -2,19 +2,320 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "../client/atomicops.h" #include "../client/share_group.h" +#include "../client/gles2_implementation.h" +#include "../client/program_info_manager.h" +#include "../common/id_allocator.h" #include "../common/logging.h" namespace gpu { namespace gles2 { -ShareGroup::ShareGroup() { +COMPILE_ASSERT(gpu::kInvalidResource == 0, + INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS); + +// An id handler for non-shared ids. +class NonSharedIdHandler : public IdHandlerInterface { + public: + NonSharedIdHandler() { } + virtual ~NonSharedIdHandler() { } + + // Overridden from IdHandlerInterface. + virtual void Destroy(GLES2Implementation* /* gl_impl */) { + } + + // Overridden from IdHandlerInterface. + virtual void MakeIds( + GLES2Implementation* /* gl_impl */, + GLuint id_offset, GLsizei n, GLuint* ids) { + if (id_offset == 0) { + for (GLsizei ii = 0; ii < n; ++ii) { + ids[ii] = id_allocator_.AllocateID(); + } + } else { + for (GLsizei ii = 0; ii < n; ++ii) { + ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset); + id_offset = ids[ii] + 1; + } + } + } + + // Overridden from IdHandlerInterface. + virtual bool FreeIds( + GLES2Implementation* /* gl_impl */, + GLsizei n, const GLuint* ids) { + for (GLsizei ii = 0; ii < n; ++ii) { + id_allocator_.FreeID(ids[ii]); + } + return true; + } + + // Overridden from IdHandlerInterface. + virtual bool MarkAsUsedForBind(GLuint id) { + return id == 0 ? true : id_allocator_.MarkAsUsed(id); + } + private: + IdAllocator id_allocator_; +}; + +// An id handler for non-shared ids that are never reused. +class NonSharedNonReusedIdHandler : public IdHandlerInterface { + public: + NonSharedNonReusedIdHandler() : last_id_(0) { } + virtual ~NonSharedNonReusedIdHandler() { } + + // Overridden from IdHandlerInterface. + virtual void Destroy(GLES2Implementation* /* gl_impl */) { + } + + // Overridden from IdHandlerInterface. + virtual void MakeIds( + GLES2Implementation* /* gl_impl */, + GLuint id_offset, GLsizei n, GLuint* ids) { + for (GLsizei ii = 0; ii < n; ++ii) { + ids[ii] = ++last_id_ + id_offset; + } + } + + // Overridden from IdHandlerInterface. + virtual bool FreeIds( + GLES2Implementation* /* gl_impl */, + GLsizei /* n */, const GLuint* /* ids */) { + // Ids are never freed. + return true; + } + + // Overridden from IdHandlerInterface. + virtual bool MarkAsUsedForBind(GLuint /* id */) { + // This is only used for Shaders and Programs which have no bind. + return false; + } + + private: + GLuint last_id_; +}; + +// An id handler for shared ids. +class SharedIdHandler : public IdHandlerInterface { + public: + SharedIdHandler( + id_namespaces::IdNamespaces id_namespace) + : id_namespace_(id_namespace) { + } + + virtual ~SharedIdHandler() { } + + // Overridden from IdHandlerInterface. + virtual void Destroy(GLES2Implementation* /* gl_impl */) { + } + + virtual void MakeIds( + GLES2Implementation* gl_impl, + GLuint id_offset, GLsizei n, GLuint* ids) { + gl_impl->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids); + } + + virtual bool FreeIds( + GLES2Implementation* gl_impl, + GLsizei n, const GLuint* ids) { + gl_impl->DeleteSharedIdsCHROMIUM(id_namespace_, n, ids); + // We need to ensure that the delete call is evaluated on the service side + // before any other contexts issue commands using these client ids. + gl_impl->helper()->CommandBufferHelper::Flush(); + return true; + } + + virtual bool MarkAsUsedForBind(GLuint /* id */) { + // This has no meaning for shared resources. + return true; + } + + private: + id_namespaces::IdNamespaces id_namespace_; +}; + +// An id handler for shared ids that requires ids are made before using and +// that only the context that created the id can delete it. +// Assumes the service will enforce that non made ids generate an error. +class StrictSharedIdHandler : public IdHandlerInterface { + public: + StrictSharedIdHandler( + id_namespaces::IdNamespaces id_namespace) + : id_namespace_(id_namespace) { + } + + virtual ~StrictSharedIdHandler() { + } + + // Overridden from IdHandlerInterface. + virtual void Destroy(GLES2Implementation* gl_impl) { + GPU_DCHECK(gl_impl); + // Free all the ids not being used. + while (!free_ids_.empty()) { + GLuint ids[kNumIdsToGet]; + int count = 0; + while (count < kNumIdsToGet && !free_ids_.empty()) { + ids[count++] = free_ids_.front(); + free_ids_.pop(); + } + gl_impl->DeleteSharedIdsCHROMIUM(id_namespace_, count, ids); + } + } + + virtual void MakeIds( + GLES2Implementation* gl_impl, + GLuint id_offset, GLsizei n, GLuint* ids) { + GPU_DCHECK(gl_impl); + for (GLsizei ii = 0; ii < n; ++ii) { + ids[ii] = GetId(gl_impl, id_offset); + } + } + + virtual bool FreeIds( + GLES2Implementation* /* gl_impl */, + GLsizei n, const GLuint* ids) { + // OpenGL sematics. If any id is bad none of them get freed. + for (GLsizei ii = 0; ii < n; ++ii) { + GLuint id = ids[ii]; + if (id != 0) { + ResourceIdSet::iterator it = used_ids_.find(id); + if (it == used_ids_.end()) { + return false; + } + } + } + for (GLsizei ii = 0; ii < n; ++ii) { + GLuint id = ids[ii]; + if (id != 0) { + ResourceIdSet::iterator it = used_ids_.find(id); + if (it != used_ids_.end()) { + used_ids_.erase(it); + free_ids_.push(id); + } + } + } + return true; + } + + virtual bool MarkAsUsedForBind(GLuint id) { + GPU_DCHECK(id == 0 || used_ids_.find(id) != used_ids_.end()); + // This has no meaning for shared resources. + return true; + } + + private: + static const GLsizei kNumIdsToGet = 2048; + typedef std::queue<GLuint> ResourceIdQueue; + typedef std::set<GLuint> ResourceIdSet; + + GLuint GetId(GLES2Implementation* gl_impl, GLuint id_offset) { + GPU_DCHECK(gl_impl); + if (free_ids_.empty()) { + GLuint ids[kNumIdsToGet]; + gl_impl->GenSharedIdsCHROMIUM( + id_namespace_, id_offset, kNumIdsToGet, ids); + for (GLsizei ii = 0; ii < kNumIdsToGet; ++ii) { + free_ids_.push(ids[ii]); + } + } + GLuint id = free_ids_.front(); + free_ids_.pop(); + used_ids_.insert(id); + return id; + } + + id_namespaces::IdNamespaces id_namespace_; + ResourceIdSet used_ids_; + ResourceIdQueue free_ids_; +}; + +#ifndef _MSC_VER +const GLsizei StrictSharedIdHandler::kNumIdsToGet; +#endif + +class ThreadSafeIdHandlerWrapper : public IdHandlerInterface { + public: + ThreadSafeIdHandlerWrapper(IdHandlerInterface* id_handler) + : id_handler_(id_handler) { + } + virtual ~ThreadSafeIdHandlerWrapper() { } + + // Overridden from IdHandlerInterface. + virtual void Destroy(GLES2Implementation* gl_impl) { + AutoLock auto_lock(lock_); + id_handler_->Destroy(gl_impl); + } + + // Overridden from IdHandlerInterface. + virtual void MakeIds( + GLES2Implementation* gl_impl, GLuint id_offset, GLsizei n, GLuint* ids) { + AutoLock auto_lock(lock_); + id_handler_->MakeIds(gl_impl, id_offset, n, ids); + } + + // Overridden from IdHandlerInterface. + virtual bool FreeIds( + GLES2Implementation* gl_impl, GLsizei n, const GLuint* ids) { + AutoLock auto_lock(lock_); + return id_handler_->FreeIds(gl_impl, n, ids); + } + + // Overridden from IdHandlerInterface. + virtual bool MarkAsUsedForBind(GLuint id) { + AutoLock auto_lock(lock_); + return id_handler_->MarkAsUsedForBind(id); + } + + private: + IdHandlerInterface* id_handler_; + Lock lock_; +}; + +ShareGroup::ShareGroup(bool share_resources, bool bind_generates_resource) + : sharing_resources_(share_resources), + bind_generates_resource_(bind_generates_resource), + gles2_(NULL) { GPU_CHECK(ShareGroup::ImplementsThreadSafeReferenceCounting()); + + if (sharing_resources_) { + if (!bind_generates_resource_) { + for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { + id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper( + new StrictSharedIdHandler( + static_cast<id_namespaces::IdNamespaces>(i)))); + } + } else { + for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { + id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper( + new SharedIdHandler( + static_cast<id_namespaces::IdNamespaces>(i)))); + } + } + } else { + for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { + if (i == id_namespaces::kProgramsAndShaders) + id_handlers_[i].reset(new NonSharedNonReusedIdHandler); + else + id_handlers_[i].reset(new NonSharedIdHandler); + } + } + program_info_manager_.reset(ProgramInfoManager::Create(sharing_resources_)); } ShareGroup::~ShareGroup() { + for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { + id_handlers_[i]->Destroy(gles2_); + id_handlers_[i].reset(); + } +} + +void ShareGroup::SetGLES2ImplementationForDestruction( + GLES2Implementation* gl_impl) { + gles2_ = gl_impl; } + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/client/share_group.h b/gpu/command_buffer/client/share_group.h index 8ce940a..cf3c44b 100644 --- a/gpu/command_buffer/client/share_group.h +++ b/gpu/command_buffer/client/share_group.h @@ -5,24 +5,79 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_SHARE_GROUP_H_ #define GPU_COMMAND_BUFFER_CLIENT_SHARE_GROUP_H_ +#include <GLES2/gl2.h> #include "../client/ref_counted.h" +#include "../common/gles2_cmd_format.h" +#include "../common/scoped_ptr.h" #include "gles2_impl_export.h" namespace gpu { namespace gles2 { +class GLES2Implementation; +class ProgramInfoManager; + +// Base class for IdHandlers +class IdHandlerInterface { + public: + IdHandlerInterface() { } + virtual ~IdHandlerInterface() { } + + // Free everything. + virtual void Destroy(GLES2Implementation* gl_impl) = 0; + + // Makes some ids at or above id_offset. + virtual void MakeIds( + GLES2Implementation* gl_impl, + GLuint id_offset, GLsizei n, GLuint* ids) = 0; + + // Frees some ids. + virtual bool FreeIds( + GLES2Implementation* gl_impl, GLsizei n, const GLuint* ids) = 0; + + // Marks an id as used for glBind functions. id = 0 does nothing. + virtual bool MarkAsUsedForBind(GLuint id) = 0; +}; + // ShareGroup manages shared resources for contexts that are sharing resources. class GLES2_IMPL_EXPORT ShareGroup : public gpu::RefCountedThreadSafe<ShareGroup> { public: typedef scoped_refptr<ShareGroup> Ref; - ShareGroup(); + ShareGroup(bool share_resources, bool bind_generates_resource); ~ShareGroup(); + void SetGLES2ImplementationForDestruction(GLES2Implementation* gl_impl); + + bool sharing_resources() const { + return sharing_resources_; + } + + bool bind_generates_resource() const { + return bind_generates_resource_; + } + bool Initialize(); + IdHandlerInterface* GetIdHandler(int namespace_id) const { + return id_handlers_[namespace_id].get(); + } + + ProgramInfoManager* program_info_manager() { + return program_info_manager_.get(); + } + private: + scoped_ptr<IdHandlerInterface> id_handlers_[id_namespaces::kNumIdNamespaces]; + scoped_ptr<ProgramInfoManager> program_info_manager_; + + // Whether or not this context is sharing resources. + bool sharing_resources_; + bool bind_generates_resource_; + + GLES2Implementation* gles2_; + DISALLOW_COPY_AND_ASSIGN(ShareGroup); }; diff --git a/gpu/command_buffer/client/share_group_unittest.cc b/gpu/command_buffer/client/share_group_unittest.cc index e0e643e..053cbfa 100644 --- a/gpu/command_buffer/client/share_group_unittest.cc +++ b/gpu/command_buffer/client/share_group_unittest.cc @@ -16,7 +16,7 @@ class ShareGroupTest : public testing::Test { protected: virtual void SetUp() { - share_group_ = ShareGroup::Ref(new ShareGroup()); + share_group_ = ShareGroup::Ref(new ShareGroup(false, false)); } virtual void TearDown() { |