Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Unified Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 9918027: Make ShareGroup thread safe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add id==0 check Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/client/gles2_implementation.cc
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 06aa79e0f2f8bb12915ba004ce3e561de029fbff..cfd4063f9137c21af13122f887792293b6afac01 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.");
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.h ('k') | gpu/command_buffer/client/gles2_implementation_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698