diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-03 19:14:10 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-03 19:14:10 +0000 |
commit | 066849e369dae48bf61ae0cf70c9e9acaf9f1045 (patch) | |
tree | 479aebcba9d2f1d3b054dc3ea64baa9a7c753f15 | |
parent | 0411509f65aae2b1ba684bf87343a14253246de0 (diff) | |
download | chromium_src-066849e369dae48bf61ae0cf70c9e9acaf9f1045.zip chromium_src-066849e369dae48bf61ae0cf70c9e9acaf9f1045.tar.gz chromium_src-066849e369dae48bf61ae0cf70c9e9acaf9f1045.tar.bz2 |
Adds support for shared resources.
It's not clear how to test this easily
it seems like we an integration test
is needed at some point. I did run the
conformance tests with share_resources
set to true and it rand without crashing.
TEST=unit tests
BUG=none
Review URL: http://codereview.chromium.org/1817002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46264 0039d316-1c4b-4281-b951-d872f2087c98
29 files changed, 900 insertions, 99 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc index a6f1314..1d2c14a 100644 --- a/chrome/renderer/ggl/ggl.cc +++ b/chrome/renderer/ggl/ggl.cc @@ -174,7 +174,8 @@ bool Context::Initialize(gfx::NativeViewId view, const gfx::Size& size) { gles2_helper_, transfer_buffer.size, transfer_buffer.ptr, - transfer_buffer_id_); + transfer_buffer_id_, + false); return true; } diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 1a74b4e..b22a304 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -178,6 +178,9 @@ GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, // Non-GL commands. GL_APICALL void GL_APIENTRY glSwapBuffers (void); GL_APICALL GLuint GL_APIENTRY glGetMaxValueInBuffer (GLidBuffer buffer_id, GLsizei count, GLenumIndexType type, GLuint offset); +GL_APICALL void GL_APIENTRY glGenSharedIds (GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); +GL_APICALL void GL_APIENTRY glDeleteSharedIds (GLuint namespace_id, GLsizei n, const GLuint* ids); +GL_APICALL void GL_APIENTRY glRegisterSharedIds (GLuint namespace_id, GLsizei n, const GLuint* ids); """ # This is the list of all commmands that will be generated and their Id. @@ -369,6 +372,9 @@ _CMD_ID_TABLE = { 'ShaderBinary': 436, 'ReleaseShaderCompiler': 437, 'GetMaxValueInBuffer': 438, + 'GenSharedIds': 439, + 'DeleteSharedIds': 440, + 'RegisterSharedIds': 441, } # This is a list of enum names and their valid values. It is used to map @@ -1006,12 +1012,19 @@ _FUNCTION_INFO = { 'type': 'DELn', 'gl_test_func': 'glDeleteFramebuffersEXT', }, - 'DeleteProgram': {'type': 'Custom', 'decoder_func': 'DoDeleteProgram'}, + 'DeleteProgram': {'type': 'Delete', 'decoder_func': 'DoDeleteProgram'}, 'DeleteRenderbuffers': { 'type': 'DELn', 'gl_test_func': 'glDeleteRenderbuffersEXT', }, - 'DeleteShader': {'type': 'Custom', 'decoder_func': 'DoDeleteShader'}, + 'DeleteShader': {'type': 'Delete', 'decoder_func': 'DoDeleteShader'}, + 'DeleteSharedIds': { + 'type': 'Custom', + 'decoder_func': 'DoDeleteSharedIds', + 'impl_func': False, + 'expectation': False, + 'immediate': False, + }, 'DeleteTextures': {'type': 'DELn'}, 'DepthRangef': {'decoder_func': 'glDepthRange'}, 'DetachShader': {'decoder_func': 'DoDetachShader'}, @@ -1054,6 +1067,13 @@ _FUNCTION_INFO = { 'GenFramebuffers': {'type': 'GENn', 'gl_test_func': 'glGenFramebuffersEXT'}, 'GenRenderbuffers': {'type': 'GENn', 'gl_test_func': 'glGenRenderbuffersEXT'}, 'GenTextures': {'type': 'GENn', 'gl_test_func': 'glGenTextures'}, + 'GenSharedIds': { + 'type': 'Custom', + 'decoder_func': 'DoGenSharedIds', + 'impl_func': False, + 'expectation': False, + 'immediate': False, + }, 'GetActiveAttrib': { 'type': 'Custom', 'immediate': False, @@ -1263,6 +1283,13 @@ _FUNCTION_INFO = { 'uint32 result_shm_id, uint32 result_shm_offset', 'result': ['uint32'], }, + 'RegisterSharedIds': { + 'type': 'Custom', + 'decoder_func': 'DoRegisterSharedIds', + 'impl_func': False, + 'expectation': False, + 'immediate': False, + }, 'ReleaseShaderCompiler': { 'decoder_func': 'DoReleaseShaderCompiler', 'unit_test': False, @@ -2206,9 +2233,7 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { SetGLError(GL_INVALID_OPERATION, "%(name)s: %(id)s reserved id"); return; } - if (%(id)s != 0) { - %(lc_type)s_id_allocator_.MarkAsUsed(%(id)s); - } + %(lc_type)s_id_handler_->MarkAsUsedForBind(%(id)s); helper_->%(name)s(%(arg_string)s); } @@ -2260,7 +2285,7 @@ class GENnHandler(TypeHandler): def WriteGLES2ImplementationHeader(self, func, file): """Overrriden from TypeHandler.""" code = """%(return_type)s %(name)s(%(typed_args)s) { - MakeIds(&%(resource_type)s_id_allocator_, %(args)s); + %(resource_type)s_id_handler_->MakeIds(0, %(args)s); helper_->%(name)sImmediate(%(args)s); } @@ -2493,7 +2518,7 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { (func.return_type, func.original_name, func.MakeTypedOriginalArgString(""))) file.Write(" GLuint client_id;\n") - file.Write(" MakeIds(&program_and_shader_id_allocator_, 1, &client_id);\n") + file.Write(" program_and_shader_id_handler_->MakeIds(0, 1, &client_id);\n") file.Write(" helper_->%s(%s);\n" % (func.name, func.MakeCmdArgString(""))) file.Write(" return client_id;\n") @@ -2501,6 +2526,29 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) { file.Write("\n") +class DeleteHandler(TypeHandler): + """Handler for glDelete___ single resource type functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" program_and_shader_id_handler_->FreeIds(1, &%s);\n" % + func.GetOriginalArgs()[-1].name) + file.Write(" helper_->%s(%s);\n" % + (func.name, func.MakeCmdArgString(""))) + file.Write("}\n") + file.Write("\n") + + class DELnHandler(TypeHandler): """Handler for glDelete___ type functions.""" @@ -2602,7 +2650,7 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs) { file.Write("%s %s(%s) {\n" % (func.return_type, func.original_name, func.MakeTypedOriginalArgString(""))) - file.Write(" FreeIds(&%s_id_allocator_, %s);\n" % + file.Write(" %s_id_handler_->FreeIds(%s);\n" % (func.name[6:-1].lower(), func.MakeOriginalArgString(""))) file.Write(" helper_->%sImmediate(%s);\n" % (func.name, func.MakeOriginalArgString(""))) @@ -4349,6 +4397,7 @@ class GLGenerator(object): 'Create': CreateHandler(), 'Custom': CustomHandler(), 'Data': DataHandler(), + 'Delete': DeleteHandler(), 'DELn': DELnHandler(), 'GENn': GENnHandler(), 'GETn': GETnHandler(), diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index c3e445a..73cd6ce 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -508,6 +508,17 @@ GLuint GLES2GetMaxValueInBuffer( return gles2::GetGLContext()->GetMaxValueInBuffer( buffer_id, count, type, offset); } +void GLES2GenSharedIds( + GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { + gles2::GetGLContext()->GenSharedIds(namespace_id, id_offset, n, ids); +} +void GLES2DeleteSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids) { + gles2::GetGLContext()->DeleteSharedIds(namespace_id, n, ids); +} +void GLES2RegisterSharedIds( + GLuint namespace_id, GLsizei n, const GLuint* ids) { + gles2::GetGLContext()->RegisterSharedIds(namespace_id, n, ids); +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index bb37150..652579d 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1127,5 +1127,26 @@ c.Init(buffer_id, count, type, offset, result_shm_id, result_shm_offset); } + void GenSharedIds( + GLuint namespace_id, GLuint id_offset, GLsizei n, uint32 ids_shm_id, + uint32 ids_shm_offset) { + gles2::GenSharedIds& c = GetCmdSpace<gles2::GenSharedIds>(); + c.Init(namespace_id, id_offset, n, ids_shm_id, ids_shm_offset); + } + + void DeleteSharedIds( + GLuint namespace_id, GLsizei n, uint32 ids_shm_id, + uint32 ids_shm_offset) { + gles2::DeleteSharedIds& c = GetCmdSpace<gles2::DeleteSharedIds>(); + c.Init(namespace_id, n, ids_shm_id, ids_shm_offset); + } + + void RegisterSharedIds( + GLuint namespace_id, GLsizei n, uint32 ids_shm_id, + uint32 ids_shm_offset) { + gles2::RegisterSharedIds& c = GetCmdSpace<gles2::RegisterSharedIds>(); + c.Init(namespace_id, n, ids_shm_id, ids_shm_offset); + } + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc index 3e9ea77..b2a0497 100644 --- a/gpu/command_buffer/client/gles2_demo.cc +++ b/gpu/command_buffer/client/gles2_demo.cc @@ -84,7 +84,8 @@ bool GLES2Demo::Setup(void* hwnd, int32 size) { gles2::SetGLContext(new GLES2Implementation(helper, transfer_buffer.size, transfer_buffer.ptr, - transfer_buffer_id)); + transfer_buffer_id, + false)); GLFromCPPInit(); diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 3886b95..551e361 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -6,6 +6,7 @@ #include "../client/gles2_implementation.h" #include "../common/gles2_cmd_utils.h" +#include "../common/id_allocator.h" namespace gpu { namespace gles2 { @@ -21,6 +22,71 @@ static GLsizei RoundUpToMultipleOf4(GLsizei size) { return (size + 3) & ~3; } +// 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 void FreeIds(GLsizei n, const GLuint* ids) { + for (GLsizei ii = 0; ii < n; ++ii) { + id_allocator_.FreeID(ids[ii]); + } + } + + // Overridden from IdHandlerInterface. + virtual bool MarkAsUsedForBind(GLuint id) { + return id == 0 ? true : id_allocator_.MarkAsUsed(id); + } + private: + IdAllocator id_allocator_; +}; + +// 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_->GenSharedIds(id_namespace_, id_offset, n, ids); + } + + virtual void FreeIds(GLsizei n, const GLuint* ids) { + gles2_->DeleteSharedIds(id_namespace_, n, ids); + } + + virtual bool MarkAsUsedForBind(GLuint) { // NOLINT + // This has no meaning for shared resources. + return true; + } + + private: + GLES2Implementation* gles2_; + id_namespaces::IdNamespaces id_namespace_; +}; + // This class tracks VertexAttribPointers and helps emulate client side buffers. // // The way client side buffers work is we shadow all the Vertex Attribs so we @@ -331,7 +397,8 @@ GLES2Implementation::GLES2Implementation( GLES2CmdHelper* helper, size_t transfer_buffer_size, void* transfer_buffer, - int32 transfer_buffer_id) + int32 transfer_buffer_id, + bool share_resources) : util_(0), // TODO(gman): Get real number of compressed texture formats. helper_(helper), transfer_buffer_( @@ -345,45 +412,49 @@ GLES2Implementation::GLES2Implementation( #if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS) bound_array_buffer_id_(0), bound_element_array_buffer_id_(0), + client_side_array_id_(0), + client_side_element_array_id_(0), #endif error_bits_(0) { // Allocate space for simple GL results. result_buffer_ = transfer_buffer; result_shm_offset_ = 0; + if (share_resources) { + buffer_id_handler_.reset( + new SharedIdHandler(this, id_namespaces::kBuffers)); + framebuffer_id_handler_.reset( + new SharedIdHandler(this, id_namespaces::kFramebuffers)); + renderbuffer_id_handler_.reset( + new SharedIdHandler(this, id_namespaces::kRenderbuffers)); + program_and_shader_id_handler_.reset( + new SharedIdHandler(this, id_namespaces::kProgramsAndShaders)); + texture_id_handler_.reset( + new SharedIdHandler(this, id_namespaces::kTextures)); + } else { + buffer_id_handler_.reset(new NonSharedIdHandler()); + framebuffer_id_handler_.reset(new NonSharedIdHandler()); + renderbuffer_id_handler_.reset(new NonSharedIdHandler()); + program_and_shader_id_handler_.reset(new NonSharedIdHandler()); + texture_id_handler_.reset(new NonSharedIdHandler()); + } + #if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS) GLint max_vertex_attribs; GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs); - buffer_id_allocator_.MarkAsUsed(kClientSideArrayId); - buffer_id_allocator_.MarkAsUsed(kClientSideElementArrayId); - reserved_ids_[0] = kClientSideArrayId; - reserved_ids_[1] = kClientSideElementArrayId; + buffer_id_handler_->MakeIds( + kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); client_side_buffer_helper_.reset(new ClientSideBufferHelper( max_vertex_attribs, - kClientSideArrayId, - kClientSideElementArrayId)); + reserved_ids_[0], + reserved_ids_[1])); #endif } GLES2Implementation::~GLES2Implementation() { - GLuint buffers[] = { kClientSideArrayId, kClientSideElementArrayId, }; - DeleteBuffers(arraysize(buffers), &buffers[0]); -} - -void GLES2Implementation::MakeIds( - IdAllocator* id_allocator, GLsizei n, GLuint* ids) { - for (GLsizei ii = 0; ii < n; ++ii) { - ids[ii] = id_allocator->AllocateID(); - } -} - -void GLES2Implementation::FreeIds( - IdAllocator* id_allocator, GLsizei n, const GLuint* ids) { - for (GLsizei ii = 0; ii < n; ++ii) { - id_allocator->FreeID(ids[ii]); - } + DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); } void GLES2Implementation::WaitForCmd() { @@ -580,6 +651,39 @@ void GLES2Implementation::SwapBuffers() { Flush(); } +void GLES2Implementation::GenSharedIds( + GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { + GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n); + helper_->GenSharedIds(namespace_id, id_offset, n, + transfer_buffer_id_, + transfer_buffer_.GetOffset(id_buffer)); + WaitForCmd(); + memcpy(ids, id_buffer, sizeof(*ids) * n); + transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken()); +} + +void GLES2Implementation::DeleteSharedIds( + GLuint namespace_id, GLsizei n, const GLuint* ids) { + GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n); + memcpy(id_buffer, ids, sizeof(*ids) * n); + helper_->DeleteSharedIds(namespace_id, n, + transfer_buffer_id_, + transfer_buffer_.GetOffset(id_buffer)); + WaitForCmd(); + transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken()); +} + +void GLES2Implementation::RegisterSharedIds( + GLuint namespace_id, GLsizei n, const GLuint* ids) { + GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n); + memcpy(id_buffer, ids, sizeof(*ids) * n); + helper_->RegisterSharedIds(namespace_id, n, + transfer_buffer_id_, + transfer_buffer_.GetOffset(id_buffer)); + WaitForCmd(); + transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken()); +} + void GLES2Implementation::BindAttribLocation( GLuint program, GLuint index, const char* name) { SetBucketAsString(kResultBucketId, name); @@ -1155,7 +1259,7 @@ void GLES2Implementation::ReadPixels( } transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); // If it was not marked as successful exit. - if (*result == 0) { + if (*result != 0) { return; } yoffset += num_rows; @@ -1222,9 +1326,7 @@ void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { SetGLError(GL_INVALID_OPERATION, "glBindBuffer: reserved buffer id"); return; } - if (buffer != 0) { - buffer_id_allocator_.MarkAsUsed(buffer); - } + buffer_id_handler_->MarkAsUsedForBind(buffer); switch (target) { case GL_ARRAY_BUFFER: bound_array_buffer_id_ = buffer; @@ -1239,7 +1341,7 @@ void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { } void GLES2Implementation::DeleteBuffers(GLsizei n, const GLuint* buffers) { - FreeIds(&buffer_id_allocator_, n, buffers); + buffer_id_handler_->FreeIds(n, buffers); for (GLsizei ii = 0; ii < n; ++ii) { if (buffers[ii] == bound_array_buffer_id_) { bound_array_buffer_id_ = 0; diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 4d0e53e..5ff41a2 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -11,7 +11,6 @@ #include "../common/gles2_cmd_utils.h" #include "../common/scoped_ptr.h" #include "../client/gles2_cmd_helper.h" -#include "../client/id_allocator.h" #include "../client/ring_buffer.h" #define GLES2_SUPPORT_CLIENT_SIDE_BUFFERS 1 @@ -21,6 +20,22 @@ namespace gles2 { class ClientSideBufferHelper; +// 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 void 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 // buffer management. See gl2_lib.h. Note that there is a performance gain to @@ -49,7 +64,8 @@ class GLES2Implementation { GLES2CmdHelper* helper, size_t transfer_buffer_size, void* transfer_buffer, - int32 transfer_buffer_id); + int32 transfer_buffer_id, + bool share_resources); ~GLES2Implementation(); @@ -126,17 +142,15 @@ class GLES2Implementation { } #endif - void MakeIds(IdAllocator* id_allocator, GLsizei n, GLuint* ids); + GLuint MakeTextureId() { + GLuint id; + texture_id_handler_->MakeIds(0, 1, &id); + return id; + } - void FreeIds(IdAllocator* id_allocator, GLsizei n, const GLuint* ids); - - GLuint MakeTextureId() { - return texture_id_allocator_.AllocateID(); - } - - void FreeTextureId(GLuint id) { - texture_id_allocator_.FreeID(id); - } + void FreeTextureId(GLuint id) { + texture_id_handler_->FreeIds(1, &id); + } private: // Wraps RingBufferWrapper to provide aligned allocations. @@ -231,11 +245,11 @@ class GLES2Implementation { GLES2Util util_; GLES2CmdHelper* helper_; - IdAllocator buffer_id_allocator_; - IdAllocator framebuffer_id_allocator_; - IdAllocator renderbuffer_id_allocator_; - IdAllocator program_and_shader_id_allocator_; - IdAllocator texture_id_allocator_; + scoped_ptr<IdHandlerInterface> buffer_id_handler_; + scoped_ptr<IdHandlerInterface> framebuffer_id_handler_; + scoped_ptr<IdHandlerInterface> renderbuffer_id_handler_; + scoped_ptr<IdHandlerInterface> program_and_shader_id_handler_; + scoped_ptr<IdHandlerInterface> texture_id_handler_; AlignedRingBuffer transfer_buffer_; int transfer_buffer_id_; void* result_buffer_; @@ -255,6 +269,10 @@ class GLES2Implementation { // The currently bound element array buffer. GLuint bound_element_array_buffer_id_; + // GL names for the buffers used to emulate client side buffers. + GLuint client_side_array_id_; + GLuint client_side_element_array_id_; + // Info for each vertex attribute saved so we can simulate client side // buffers. scoped_ptr<ClientSideBufferHelper> client_side_buffer_helper_; diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 06bcdcc..63d0b53 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -25,9 +25,7 @@ void BindFramebuffer(GLenum target, GLuint framebuffer) { GL_INVALID_OPERATION, "BindFramebuffer: framebuffer reserved id"); return; } - if (framebuffer != 0) { - framebuffer_id_allocator_.MarkAsUsed(framebuffer); - } + framebuffer_id_handler_->MarkAsUsedForBind(framebuffer); helper_->BindFramebuffer(target, framebuffer); } @@ -37,9 +35,7 @@ void BindRenderbuffer(GLenum target, GLuint renderbuffer) { GL_INVALID_OPERATION, "BindRenderbuffer: renderbuffer reserved id"); return; } - if (renderbuffer != 0) { - renderbuffer_id_allocator_.MarkAsUsed(renderbuffer); - } + renderbuffer_id_handler_->MarkAsUsedForBind(renderbuffer); helper_->BindRenderbuffer(target, renderbuffer); } @@ -48,9 +44,7 @@ void BindTexture(GLenum target, GLuint texture) { SetGLError(GL_INVALID_OPERATION, "BindTexture: texture reserved id"); return; } - if (texture != 0) { - texture_id_allocator_.MarkAsUsed(texture); - } + texture_id_handler_->MarkAsUsedForBind(texture); helper_->BindTexture(target, texture); } @@ -156,14 +150,14 @@ void CopyTexSubImage2D( GLuint CreateProgram() { GLuint client_id; - MakeIds(&program_and_shader_id_allocator_, 1, &client_id); + program_and_shader_id_handler_->MakeIds(0, 1, &client_id); helper_->CreateProgram(client_id); return client_id; } GLuint CreateShader(GLenum type) { GLuint client_id; - MakeIds(&program_and_shader_id_allocator_, 1, &client_id); + program_and_shader_id_handler_->MakeIds(0, 1, &client_id); helper_->CreateShader(type, client_id); return client_id; } @@ -173,25 +167,27 @@ void CullFace(GLenum mode) { } void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { - FreeIds(&framebuffer_id_allocator_, n, framebuffers); + framebuffer_id_handler_->FreeIds(n, framebuffers); helper_->DeleteFramebuffersImmediate(n, framebuffers); } void DeleteProgram(GLuint program) { + program_and_shader_id_handler_->FreeIds(1, &program); helper_->DeleteProgram(program); } void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { - FreeIds(&renderbuffer_id_allocator_, n, renderbuffers); + renderbuffer_id_handler_->FreeIds(n, renderbuffers); helper_->DeleteRenderbuffersImmediate(n, renderbuffers); } void DeleteShader(GLuint shader) { + program_and_shader_id_handler_->FreeIds(1, &shader); helper_->DeleteShader(shader); } void DeleteTextures(GLsizei n, const GLuint* textures) { - FreeIds(&texture_id_allocator_, n, textures); + texture_id_handler_->FreeIds(n, textures); helper_->DeleteTexturesImmediate(n, textures); } @@ -244,7 +240,7 @@ void FrontFace(GLenum mode) { } void GenBuffers(GLsizei n, GLuint* buffers) { - MakeIds(&buffer_id_allocator_, n, buffers); + buffer_id_handler_->MakeIds(0, n, buffers); helper_->GenBuffersImmediate(n, buffers); } @@ -253,17 +249,17 @@ void GenerateMipmap(GLenum target) { } void GenFramebuffers(GLsizei n, GLuint* framebuffers) { - MakeIds(&framebuffer_id_allocator_, n, framebuffers); + framebuffer_id_handler_->MakeIds(0, n, framebuffers); helper_->GenFramebuffersImmediate(n, framebuffers); } void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { - MakeIds(&renderbuffer_id_allocator_, n, renderbuffers); + renderbuffer_id_handler_->MakeIds(0, n, renderbuffers); helper_->GenRenderbuffersImmediate(n, renderbuffers); } void GenTextures(GLsizei n, GLuint* textures) { - MakeIds(&texture_id_allocator_, n, textures); + texture_id_handler_->MakeIds(0, n, textures); helper_->GenTexturesImmediate(n, textures); } @@ -759,5 +755,12 @@ GLuint GetMaxValueInBuffer( return *result; } +void GenSharedIds( + GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); + +void DeleteSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids); + +void RegisterSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids); + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 93710fc..e43bf84 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -152,7 +152,6 @@ class GLES2ImplementationTest : public testing::Test { command_buffer_.reset(new MockGLES2CommandBuffer()); command_buffer_->Initialize(kNumCommandEntries); - EXPECT_EQ(kTransferBufferId, command_buffer_->CreateTransferBuffer(kTransferBufferSize)); transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); @@ -171,7 +170,8 @@ class GLES2ImplementationTest : public testing::Test { helper_.get(), kTransferBufferSize, transfer_buffer_.ptr, - kTransferBufferId)); + kTransferBufferId, + false)); EXPECT_CALL(*command_buffer_, OnFlush(_)).Times(1).RetiresOnSaturation(); helper_->CommandBufferHelper::Flush(); diff --git a/gpu/command_buffer/client/ring_buffer.h b/gpu/command_buffer/client/ring_buffer.h index 0b55661..38ee912 100644 --- a/gpu/command_buffer/client/ring_buffer.h +++ b/gpu/command_buffer/client/ring_buffer.h @@ -128,7 +128,7 @@ class RingBufferWrapper { // Returns: // the pointer to the allocated memory block, or NULL if out of // memory. - void *Alloc(unsigned int size) { + void* Alloc(unsigned int size) { RingBuffer::Offset offset = allocator_.Alloc(size); return GetPointer(offset); } @@ -144,8 +144,8 @@ class RingBufferWrapper { // Returns: // the pointer to the allocated memory block, or NULL if out of // memory. - template <typename T> T *AllocTyped(unsigned int count) { - return static_cast<T *>(Alloc(count * sizeof(T))); + template <typename T> T* AllocTyped(unsigned int count) { + return static_cast<T*>(Alloc(count * sizeof(T))); } // Frees a block of memory, pending the passage of a token. That memory won't @@ -154,18 +154,18 @@ class RingBufferWrapper { // Parameters: // pointer: the pointer to the memory block to free. // token: the token value to wait for before re-using the memory. - void FreePendingToken(void *pointer, unsigned int token) { + void FreePendingToken(void* pointer, unsigned int token) { DCHECK(pointer); allocator_.FreePendingToken(GetOffset(pointer), token); } // Gets a pointer to a memory block given the base memory and the offset. - void *GetPointer(RingBuffer::Offset offset) { + void* GetPointer(RingBuffer::Offset offset) { return static_cast<int8*>(base_) + offset; } // Gets the offset to a memory block given the base memory and the address. - RingBuffer::Offset GetOffset(void *pointer) { + RingBuffer::Offset GetOffset(void* pointer) { return static_cast<int8*>(pointer) - static_cast<int8*>(base_); } @@ -182,7 +182,7 @@ class RingBufferWrapper { private: RingBuffer allocator_; - void *base_; + void* base_; RingBuffer::Offset base_offset_; DISALLOW_IMPLICIT_CONSTRUCTORS(RingBufferWrapper); }; diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h index 6935380..2be1e36 100644 --- a/gpu/command_buffer/common/gles2_cmd_format.h +++ b/gpu/command_buffer/common/gles2_cmd_format.h @@ -39,6 +39,26 @@ namespace gles2 { #pragma pack(push, 1) +namespace id_namespaces { + +// These are used when contexts share resources. +enum IdNamespaces { + kBuffers, + kFramebuffers, + kProgramsAndShaders, + kRenderbuffers, + kTextures, +}; + +// These numbers must not change +COMPILE_ASSERT(kBuffers == 0, kBuffers_is_not_0); +COMPILE_ASSERT(kFramebuffers == 1, kFramebuffers_is_not_1); +COMPILE_ASSERT(kProgramsAndShaders == 2, kProgramsAndShaders_is_not_2); +COMPILE_ASSERT(kRenderbuffers == 3, kRenderbuffers_is_not_3); +COMPILE_ASSERT(kTextures == 4, kTextures_is_not_4); + +} // namespace id_namespaces + // Used for some glGetXXX commands that return a result through a pointer. We // need to know if the command succeeded or not and the size of the result. If // the command failed its result size will 0. diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index b6b8128..7e07dd7 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -8280,6 +8280,164 @@ COMPILE_ASSERT(offsetof(GetMaxValueInBuffer, result_shm_id) == 20, COMPILE_ASSERT(offsetof(GetMaxValueInBuffer, result_shm_offset) == 24, OffsetOf_GetMaxValueInBuffer_result_shm_offset_not_24); +struct GenSharedIds { + typedef GenSharedIds ValueType; + static const CommandId kCmdId = kGenSharedIds; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _namespace_id, GLuint _id_offset, GLsizei _n, uint32 _ids_shm_id, + uint32 _ids_shm_offset) { + SetHeader(); + namespace_id = _namespace_id; + id_offset = _id_offset; + n = _n; + ids_shm_id = _ids_shm_id; + ids_shm_offset = _ids_shm_offset; + } + + void* Set( + void* cmd, GLuint _namespace_id, GLuint _id_offset, GLsizei _n, + uint32 _ids_shm_id, uint32 _ids_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _namespace_id, _id_offset, _n, _ids_shm_id, _ids_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 namespace_id; + uint32 id_offset; + int32 n; + uint32 ids_shm_id; + uint32 ids_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GenSharedIds) == 24, + Sizeof_GenSharedIds_is_not_24); +COMPILE_ASSERT(offsetof(GenSharedIds, header) == 0, + OffsetOf_GenSharedIds_header_not_0); +COMPILE_ASSERT(offsetof(GenSharedIds, namespace_id) == 4, + OffsetOf_GenSharedIds_namespace_id_not_4); +COMPILE_ASSERT(offsetof(GenSharedIds, id_offset) == 8, + OffsetOf_GenSharedIds_id_offset_not_8); +COMPILE_ASSERT(offsetof(GenSharedIds, n) == 12, + OffsetOf_GenSharedIds_n_not_12); +COMPILE_ASSERT(offsetof(GenSharedIds, ids_shm_id) == 16, + OffsetOf_GenSharedIds_ids_shm_id_not_16); +COMPILE_ASSERT(offsetof(GenSharedIds, ids_shm_offset) == 20, + OffsetOf_GenSharedIds_ids_shm_offset_not_20); + +struct DeleteSharedIds { + typedef DeleteSharedIds ValueType; + static const CommandId kCmdId = kDeleteSharedIds; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _namespace_id, GLsizei _n, uint32 _ids_shm_id, + uint32 _ids_shm_offset) { + SetHeader(); + namespace_id = _namespace_id; + n = _n; + ids_shm_id = _ids_shm_id; + ids_shm_offset = _ids_shm_offset; + } + + void* Set( + void* cmd, GLuint _namespace_id, GLsizei _n, uint32 _ids_shm_id, + uint32 _ids_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_namespace_id, _n, _ids_shm_id, _ids_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 namespace_id; + int32 n; + uint32 ids_shm_id; + uint32 ids_shm_offset; +}; + +COMPILE_ASSERT(sizeof(DeleteSharedIds) == 20, + Sizeof_DeleteSharedIds_is_not_20); +COMPILE_ASSERT(offsetof(DeleteSharedIds, header) == 0, + OffsetOf_DeleteSharedIds_header_not_0); +COMPILE_ASSERT(offsetof(DeleteSharedIds, namespace_id) == 4, + OffsetOf_DeleteSharedIds_namespace_id_not_4); +COMPILE_ASSERT(offsetof(DeleteSharedIds, n) == 8, + OffsetOf_DeleteSharedIds_n_not_8); +COMPILE_ASSERT(offsetof(DeleteSharedIds, ids_shm_id) == 12, + OffsetOf_DeleteSharedIds_ids_shm_id_not_12); +COMPILE_ASSERT(offsetof(DeleteSharedIds, ids_shm_offset) == 16, + OffsetOf_DeleteSharedIds_ids_shm_offset_not_16); + +struct RegisterSharedIds { + typedef RegisterSharedIds ValueType; + static const CommandId kCmdId = kRegisterSharedIds; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _namespace_id, GLsizei _n, uint32 _ids_shm_id, + uint32 _ids_shm_offset) { + SetHeader(); + namespace_id = _namespace_id; + n = _n; + ids_shm_id = _ids_shm_id; + ids_shm_offset = _ids_shm_offset; + } + + void* Set( + void* cmd, GLuint _namespace_id, GLsizei _n, uint32 _ids_shm_id, + uint32 _ids_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_namespace_id, _n, _ids_shm_id, _ids_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 namespace_id; + int32 n; + uint32 ids_shm_id; + uint32 ids_shm_offset; +}; + +COMPILE_ASSERT(sizeof(RegisterSharedIds) == 20, + Sizeof_RegisterSharedIds_is_not_20); +COMPILE_ASSERT(offsetof(RegisterSharedIds, header) == 0, + OffsetOf_RegisterSharedIds_header_not_0); +COMPILE_ASSERT(offsetof(RegisterSharedIds, namespace_id) == 4, + OffsetOf_RegisterSharedIds_namespace_id_not_4); +COMPILE_ASSERT(offsetof(RegisterSharedIds, n) == 8, + OffsetOf_RegisterSharedIds_n_not_8); +COMPILE_ASSERT(offsetof(RegisterSharedIds, ids_shm_id) == 12, + OffsetOf_RegisterSharedIds_ids_shm_id_not_12); +COMPILE_ASSERT(offsetof(RegisterSharedIds, ids_shm_offset) == 16, + OffsetOf_RegisterSharedIds_ids_shm_offset_not_16); + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index d498249..4e003eb 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3270,5 +3270,64 @@ TEST(GLES2FormatTest, GetMaxValueInBuffer) { EXPECT_EQ(static_cast<uint32>(16), cmd.result_shm_offset); } +TEST(GLES2FormatTest, GenSharedIds) { + GenSharedIds cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12), + static_cast<GLsizei>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(static_cast<uint32>(GenSharedIds::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<char*>(next_cmd), + reinterpret_cast<char*>(&cmd) + sizeof(cmd)); + EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id); + EXPECT_EQ(static_cast<GLuint>(12), cmd.id_offset); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.n); + EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.ids_shm_offset); +} + +TEST(GLES2FormatTest, DeleteSharedIds) { + DeleteSharedIds cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(static_cast<uint32>(DeleteSharedIds::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<char*>(next_cmd), + reinterpret_cast<char*>(&cmd) + sizeof(cmd)); + EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.n); + EXPECT_EQ(static_cast<uint32>(13), cmd.ids_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_offset); +} + +TEST(GLES2FormatTest, RegisterSharedIds) { + RegisterSharedIds cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(static_cast<uint32>(RegisterSharedIds::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<char*>(next_cmd), + reinterpret_cast<char*>(&cmd) + sizeof(cmd)); + EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.n); + EXPECT_EQ(static_cast<uint32>(13), cmd.ids_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_offset); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h index 7092c1e..ba87b28 100644 --- a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h @@ -377,6 +377,12 @@ TEST(GLES2CommandIdTest, CommandIdsMatch) { GLES2_SwapBuffers_kCmdId_mismatch); COMPILE_ASSERT(GetMaxValueInBuffer::kCmdId == 438, GLES2_GetMaxValueInBuffer_kCmdId_mismatch); + COMPILE_ASSERT(GenSharedIds::kCmdId == 439, + GLES2_GenSharedIds_kCmdId_mismatch); + COMPILE_ASSERT(DeleteSharedIds::kCmdId == 440, + GLES2_DeleteSharedIds_kCmdId_mismatch); + COMPILE_ASSERT(RegisterSharedIds::kCmdId == 441, + GLES2_RegisterSharedIds_kCmdId_mismatch); } #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_ID_TEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 4ce2215..eebe3ff 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -191,6 +191,9 @@ OP(ShaderBinary) /* 436 */ \ OP(ReleaseShaderCompiler) /* 437 */ \ OP(GetMaxValueInBuffer) /* 438 */ \ + OP(GenSharedIds) /* 439 */ \ + OP(DeleteSharedIds) /* 440 */ \ + OP(RegisterSharedIds) /* 441 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/client/id_allocator.cc b/gpu/command_buffer/common/id_allocator.cc index 2d244d0..22c55e3 100644 --- a/gpu/command_buffer/client/id_allocator.cc +++ b/gpu/command_buffer/common/id_allocator.cc @@ -4,7 +4,7 @@ // This file contains the implementation of IdAllocator. -#include "../client/id_allocator.h" +#include "../common/id_allocator.h" #include "../common/logging.h" namespace gpu { @@ -12,7 +12,7 @@ namespace gpu { IdAllocator::IdAllocator() { } -unsigned int IdAllocator::FindFirstFree() const { +ResourceId IdAllocator::FindFirstFree() const { ResourceId id = 1; for (ResourceIdSet::const_iterator it = used_ids_.begin(); it != used_ids_.end(); ++it) { @@ -24,4 +24,12 @@ unsigned int IdAllocator::FindFirstFree() const { return id; } +ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) { + DCHECK_LT(static_cast<ResourceId>(used_ids_.size()), + static_cast<ResourceId>(-1)); + for (; InUse(desired_id); ++desired_id); + MarkAsUsed(desired_id); + return desired_id; +} + } // namespace gpu diff --git a/gpu/command_buffer/client/id_allocator.h b/gpu/command_buffer/common/id_allocator.h index 615f020..76edc34 100644 --- a/gpu/command_buffer/client/id_allocator.h +++ b/gpu/command_buffer/common/id_allocator.h @@ -30,6 +30,10 @@ class IdAllocator { return id; } + // Allocates an Id starting at or above desired_id. + // Note: may wrap if it starts near limit. + ResourceId AllocateIDAtOrAbove(ResourceId desired_id); + // Marks an id as used. Returns false if id was already used. bool MarkAsUsed(ResourceId id) { std::pair<ResourceIdSet::iterator, bool> result = used_ids_.insert(id); @@ -43,11 +47,11 @@ class IdAllocator { // Checks whether or not a resource ID is in use. bool InUse(ResourceId id) const { - return used_ids_.find(id) != used_ids_.end(); + return id == kInvalidResource || used_ids_.find(id) != used_ids_.end(); } private: - // TODO(gman): This would work much better with ranges. + // TODO(gman): This would work much better with ranges or a hash table. typedef std::set<ResourceId> ResourceIdSet; ResourceId FindFirstFree() const; diff --git a/gpu/command_buffer/client/id_allocator_test.cc b/gpu/command_buffer/common/id_allocator_test.cc index eafadd7..6869f33 100644 --- a/gpu/command_buffer/client/id_allocator_test.cc +++ b/gpu/command_buffer/common/id_allocator_test.cc @@ -4,7 +4,7 @@ // This file has the unit tests for the IdAllocator class. -#include "gpu/command_buffer/client/id_allocator.h" +#include "gpu/command_buffer/common/id_allocator.h" #include "testing/gtest/include/gtest/gtest.h" namespace gpu { @@ -66,7 +66,7 @@ TEST_F(IdAllocatorTest, TestAdvanced) { EXPECT_EQ(id1, id2); } -// Check that we can choose our own ids and they won't be reused. +// Checks that we can choose our own ids and they won't be reused. TEST_F(IdAllocatorTest, MarkAsUsed) { IdAllocator* allocator = id_allocator(); ResourceId id = allocator->AllocateID(); @@ -83,4 +83,16 @@ TEST_F(IdAllocatorTest, MarkAsUsed) { EXPECT_EQ(id3, id2 + 2); } +// Checks AllocateIdAtOrAbove. +TEST_F(IdAllocatorTest, AllocateIdAtOrAbove) { + const ResourceId kOffset = 123456; + IdAllocator* allocator = id_allocator(); + ResourceId id1 = allocator->AllocateIDAtOrAbove(kOffset); + EXPECT_EQ(kOffset, id1); + ResourceId id2 = allocator->AllocateIDAtOrAbove(kOffset); + EXPECT_GT(id2, kOffset); + ResourceId id3 = allocator->AllocateIDAtOrAbove(kOffset); + EXPECT_GT(id3, kOffset); +} + } // namespace gpu diff --git a/gpu/command_buffer/docs/gles2_cmd_format_docs.txt b/gpu/command_buffer/docs/gles2_cmd_format_docs.txt index d1f7326..73882c4 100644 --- a/gpu/command_buffer/docs/gles2_cmd_format_docs.txt +++ b/gpu/command_buffer/docs/gles2_cmd_format_docs.txt @@ -2179,4 +2179,39 @@ struct GetMaxValueInBuffer { uint32 result_shm_offset; //!< uint32 }; +//! Command that generates shared ids for contexts that share resources. +struct GenSharedIds { + static const CommandId kCmdId = 439; + + CommandHeader header; + uint32 namespace_id; //!< GLuint + uint32 id_offset; //!< GLuint + int32 n; //!< GLsizei + uint32 ids_shm_id; //!< uint32 + uint32 ids_shm_offset; //!< uint32 +}; + +//! Command that deletes shared ids. +struct DeleteSharedIds { + static const CommandId kCmdId = 440; + + CommandHeader header; + uint32 namespace_id; //!< GLuint + int32 n; //!< GLsizei + uint32 ids_shm_id; //!< uint32 + uint32 ids_shm_offset; //!< uint32 +}; + +//! Command that registers shared ids. It is an error to attempt +//! to register an id that is already registered. +struct RegisterSharedIds { + static const CommandId kCmdId = 441; + + CommandHeader header; + uint32 namespace_id; //!< GLuint + int32 n; //!< GLsizei + uint32 ids_shm_id; //!< uint32 + uint32 ids_shm_offset; //!< uint32 +}; + diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 6e85e30..7a62c72 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/context_group.h" +#include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/service/buffer_manager.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/program_manager.h" @@ -55,6 +56,16 @@ bool ContextGroup::Initialize() { return true; } +IdAllocator* ContextGroup::GetIdAllocator(unsigned namespace_id) { + IdAllocatorMap::iterator it = id_namespaces_.find(namespace_id); + if (it != id_namespaces_.end()) { + return it->second.get(); + } + IdAllocator* id_allocator = new IdAllocator(); + id_namespaces_[namespace_id] = linked_ptr<IdAllocator>(id_allocator); + return id_allocator; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 8ccbb62..2b0bf46 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -5,11 +5,15 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_ #define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_ -#include <vector> +#include <map> #include "base/basictypes.h" +#include "base/linked_ptr.h" #include "base/scoped_ptr.h" namespace gpu { + +class IdAllocator; + namespace gles2 { class GLES2Decoder; @@ -62,6 +66,8 @@ class ContextGroup { return shader_manager_.get(); } + IdAllocator* GetIdAllocator(unsigned namepsace_id); + private: // Whether or not this context is initialized. bool initialized_; @@ -82,6 +88,9 @@ class ContextGroup { scoped_ptr<ShaderManager> shader_manager_; + typedef std::map<uint32, linked_ptr<IdAllocator> > IdAllocatorMap; + IdAllocatorMap id_namespaces_; + DISALLOW_COPY_AND_ASSIGN(ContextGroup); }; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 39e9e20..988bc18 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -13,13 +13,13 @@ #include "app/gfx/gl/gl_context.h" #include "base/callback.h" -#include "base/linked_ptr.h" #include "base/scoped_ptr.h" #include "base/weak_ptr.h" #include "build/build_config.h" #define GLES2_GPU_SERVICE 1 #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/service/buffer_manager.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" @@ -637,6 +637,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Wrapper for glCompileShader. void DoCompileShader(GLuint shader); + // Helper for DeleteSharedIds commands. + void DoDeleteSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids); + // Wrapper for glDetachShader void DoDetachShader(GLuint client_program_id, GLint client_shader_id); @@ -662,6 +665,10 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Wrapper for glGenerateMipmap void DoGenerateMipmap(GLenum target); + // Helper for GenSharedIds commands. + void DoGenSharedIds( + GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); + // Wrapper for DoGetBooleanv. void DoGetBooleanv(GLenum pname, GLboolean* params); @@ -701,6 +708,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Wrapper for glLinkProgram void DoLinkProgram(GLuint program); + // Helper for RegisterSharedIds. + void DoRegisterSharedIds(GLuint namespace_id, GLsizei n, const GLuint* ids); + // Wrapper for glRenderbufferStorage. void DoRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width, GLsizei height); @@ -1740,6 +1750,9 @@ void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { glGenBuffersARB(1, &service_id); CreateBufferInfo(client_id, service_id); info = GetBufferInfo(client_id); + IdAllocator* id_allocator = + group_->GetIdAllocator(id_namespaces::kBuffers); + id_allocator->MarkAsUsed(client_id); } } if (info) { @@ -1779,6 +1792,9 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { glGenFramebuffersEXT(1, &service_id); CreateFramebufferInfo(client_id, service_id); info = GetFramebufferInfo(client_id); + IdAllocator* id_allocator = + group_->GetIdAllocator(id_namespaces::kFramebuffers); + id_allocator->MarkAsUsed(client_id); } else { service_id = info->service_id(); } @@ -1802,6 +1818,10 @@ void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { // It's a new id so make a renderbuffer info for it. glGenRenderbuffersEXT(1, &service_id); CreateRenderbufferInfo(client_id, service_id); + info = GetRenderbufferInfo(client_id); + IdAllocator* id_allocator = + group_->GetIdAllocator(id_namespaces::kRenderbuffers); + id_allocator->MarkAsUsed(client_id); } else { service_id = info->service_id(); } @@ -1820,6 +1840,9 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { glGenTextures(1, &service_id); CreateTextureInfo(client_id, service_id); info = GetTextureInfo(client_id); + IdAllocator* id_allocator = + group_->GetIdAllocator(id_namespaces::kTextures); + id_allocator->MarkAsUsed(client_id); } } else { info = texture_manager()->GetDefaultTextureInfo(target); @@ -2063,6 +2086,109 @@ error::Error GLES2DecoderImpl::HandleDeleteProgram( return error::kNoError; } +void GLES2DecoderImpl::DoDeleteSharedIds( + GLuint namespace_id, GLsizei n, const GLuint* ids) { + IdAllocator* id_allocator = group_->GetIdAllocator(namespace_id); + for (GLsizei ii = 0; ii < n; ++ii) { + id_allocator->FreeID(ids[ii]); + } +} + +error::Error GLES2DecoderImpl::HandleDeleteSharedIds( + uint32 immediate_data_size, const gles2::DeleteSharedIds& c) { + GLuint namespace_id = static_cast<GLuint>(c.namespace_id); + GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + const GLuint* ids = GetSharedMemoryAs<const GLuint*>( + c.ids_shm_id, c.ids_shm_offset, data_size); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "DeleteSharedIds: n < 0"); + return error::kNoError; + } + if (ids == NULL) { + return error::kOutOfBounds; + } + DoDeleteSharedIds(namespace_id, n, ids); + return error::kNoError; +} + +void GLES2DecoderImpl::DoGenSharedIds( + GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { + IdAllocator* id_allocator = group_->GetIdAllocator(namespace_id); + 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; + } + } +} + +error::Error GLES2DecoderImpl::HandleGenSharedIds( + uint32 immediate_data_size, const gles2::GenSharedIds& c) { + GLuint namespace_id = static_cast<GLuint>(c.namespace_id); + GLuint id_offset = static_cast<GLuint>(c.id_offset); + GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + GLuint* ids = GetSharedMemoryAs<GLuint*>( + c.ids_shm_id, c.ids_shm_offset, data_size); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "GenSharedIds: n < 0"); + return error::kNoError; + } + if (ids == NULL) { + return error::kOutOfBounds; + } + DoGenSharedIds(namespace_id, id_offset, n, ids); + return error::kNoError; +} + +void GLES2DecoderImpl::DoRegisterSharedIds( + GLuint namespace_id, GLsizei n, const GLuint* ids) { + IdAllocator* id_allocator = group_->GetIdAllocator(namespace_id); + for (GLsizei ii = 0; ii < n; ++ii) { + if (!id_allocator->MarkAsUsed(ids[ii])) { + for (GLsizei jj = 0; jj < ii; ++jj) { + id_allocator->FreeID(ids[jj]); + } + SetGLError( + GL_INVALID_VALUE, + "RegisterSharedIds: attempt to register id that already exists"); + return; + } + } +} + +error::Error GLES2DecoderImpl::HandleRegisterSharedIds( + uint32 immediate_data_size, const gles2::RegisterSharedIds& c) { + GLuint namespace_id = static_cast<GLuint>(c.namespace_id); + GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size; + if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { + return error::kOutOfBounds; + } + GLuint* ids = GetSharedMemoryAs<GLuint*>( + c.ids_shm_id, c.ids_shm_offset, data_size); + if (n < 0) { + SetGLError(GL_INVALID_VALUE, "RegisterSharedIds: n < 0"); + return error::kNoError; + } + if (ids == NULL) { + return error::kOutOfBounds; + } + DoRegisterSharedIds(namespace_id, n, ids); + return error::kNoError; +} + void GLES2DecoderImpl::DoDrawArrays( GLenum mode, GLint first, GLsizei count) { if (IsDrawValid(first + count - 1)) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 1e9a9d0..759e54c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -5,6 +5,7 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/service/gl_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" @@ -1954,6 +1955,123 @@ TEST_F(GLES2DecoderWithShaderTest, GetMaxValueInBuffer) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_F(GLES2DecoderTest, SharedIds) { + GenSharedIds gen_cmd; + RegisterSharedIds reg_cmd; + DeleteSharedIds del_cmd; + + const GLuint kNamespaceId = id_namespaces::kTextures; + const GLuint kExpectedId1 = 1; + const GLuint kExpectedId2 = 2; + const GLuint kExpectedId3 = 4; + const GLuint kRegisterId = 3; + GLuint* ids = GetSharedMemoryAs<GLuint*>(); + gen_cmd.Init(kNamespaceId, 0, 2, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + IdAllocator* id_allocator = GetIdAllocator(kNamespaceId); + ASSERT_TRUE(id_allocator != NULL); + // This check is implementation dependant but it's kind of hard to check + // otherwise. + EXPECT_EQ(kExpectedId1, ids[0]); + EXPECT_EQ(kExpectedId2, ids[1]); + EXPECT_TRUE(id_allocator->InUse(kExpectedId1)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); + EXPECT_FALSE(id_allocator->InUse(kRegisterId)); + EXPECT_FALSE(id_allocator->InUse(kExpectedId3)); + + ClearSharedMemory(); + ids[0] = kRegisterId; + reg_cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(reg_cmd)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId1)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); + EXPECT_TRUE(id_allocator->InUse(kRegisterId)); + EXPECT_FALSE(id_allocator->InUse(kExpectedId3)); + + ClearSharedMemory(); + gen_cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(kExpectedId3, ids[0]); + EXPECT_TRUE(id_allocator->InUse(kExpectedId1)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); + EXPECT_TRUE(id_allocator->InUse(kRegisterId)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId3)); + + ClearSharedMemory(); + ids[0] = kExpectedId1; + ids[1] = kRegisterId; + del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd)); + EXPECT_FALSE(id_allocator->InUse(kExpectedId1)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); + EXPECT_FALSE(id_allocator->InUse(kRegisterId)); + EXPECT_TRUE(id_allocator->InUse(kExpectedId3)); + + ClearSharedMemory(); + ids[0] = kExpectedId3; + ids[1] = kExpectedId2; + del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd)); + EXPECT_FALSE(id_allocator->InUse(kExpectedId1)); + EXPECT_FALSE(id_allocator->InUse(kExpectedId2)); + EXPECT_FALSE(id_allocator->InUse(kRegisterId)); + EXPECT_FALSE(id_allocator->InUse(kExpectedId3)); + + // Check passing in an id_offset. + ClearSharedMemory(); + const GLuint kOffset = 0xABCDEF; + gen_cmd.Init(kNamespaceId, kOffset, 2, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(kOffset, ids[0]); + EXPECT_EQ(kOffset + 1, ids[1]); +} + +TEST_F(GLES2DecoderTest, GenSharedIdsBadArgs) { + const GLuint kNamespaceId = id_namespaces::kTextures; + GenSharedIds cmd; + cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 0, 1, kInvalidSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest, RegisterSharedIdsBadArgs) { + const GLuint kNamespaceId = id_namespaces::kTextures; + RegisterSharedIds cmd; + cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest, RegisterSharedIdsDuplicateIds) { + const GLuint kNamespaceId = id_namespaces::kTextures; + const GLuint kRegisterId = 3; + RegisterSharedIds cmd; + GLuint* ids = GetSharedMemoryAs<GLuint*>(); + ids[0] = kRegisterId; + cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderTest, DeleteSharedIdsBadArgs) { + const GLuint kNamespaceId = id_namespaces::kTextures; + DeleteSharedIds cmd; + cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + // TODO(gman): BufferData // TODO(gman): BufferDataImmediate diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index dbad983..ede9af9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -550,8 +550,15 @@ TEST_F(GLES2DecoderTest1, DeleteFramebuffersImmediateInvalidArgs) { EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); } -// TODO(gman): DeleteProgram +TEST_F(GLES2DecoderTest1, DeleteProgramValidArgs) { + EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId)); + SpecializedSetup<DeleteProgram, 0>(); + DeleteProgram cmd; + cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} TEST_F(GLES2DecoderTest1, DeleteRenderbuffersValidArgs) { EXPECT_CALL( @@ -601,8 +608,15 @@ TEST_F(GLES2DecoderTest1, DeleteRenderbuffersImmediateInvalidArgs) { EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); } -// TODO(gman): DeleteShader +TEST_F(GLES2DecoderTest1, DeleteShaderValidArgs) { + EXPECT_CALL(*gl_, DeleteShader(kServiceShaderId)); + SpecializedSetup<DeleteShader, 0>(); + DeleteShader cmd; + cmd.Init(client_shader_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} TEST_F(GLES2DecoderTest1, DeleteTexturesValidArgs) { EXPECT_CALL( @@ -1805,5 +1819,7 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { // TODO(gman): GetUniformiv +// TODO(gman): GetUniformLocation + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index ae27310..6bc3097 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -8,8 +8,6 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ -// TODO(gman): GetUniformLocation - // TODO(gman): GetUniformLocationImmediate // TODO(gman): GetUniformLocationBucket @@ -1622,5 +1620,11 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) { } // TODO(gman): SwapBuffers // TODO(gman): GetMaxValueInBuffer +// TODO(gman): GenSharedIds + +// TODO(gman): DeleteSharedIds + +// TODO(gman): RegisterSharedIds + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ 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 bff12c1..8920f31 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -125,6 +125,10 @@ class GLES2DecoderTestBase : public testing::Test { return reinterpret_cast<T>(ptr); } + IdAllocator* GetIdAllocator(GLuint namespace_id) { + return group_.GetIdAllocator(namespace_id); + } + BufferManager::BufferInfo* GetBufferInfo(GLuint service_id) { return group_.buffer_manager()->GetBufferInfo(service_id); } diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 5e3a309..fce2a08 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -84,7 +84,8 @@ bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { ::gles2::SetGLContext(new GLES2Implementation(helper, transfer_buffer.size, transfer_buffer.ptr, - transfer_buffer_id)); + transfer_buffer_id, + false)); return command_buffer.release() != NULL; } diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 64490bf..dc2c87b 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -155,6 +155,8 @@ 'command_buffer/common/gles2_cmd_format.h', 'command_buffer/common/gles2_cmd_utils.cc', 'command_buffer/common/gles2_cmd_utils.h', + 'command_buffer/common/id_allocator.cc', + 'command_buffer/common/id_allocator.h', 'command_buffer/common/logging.h', 'command_buffer/common/mocks.h', 'command_buffer/common/thread_local.h', @@ -231,8 +233,6 @@ 'command_buffer/client/cmd_buffer_helper.h', 'command_buffer/client/fenced_allocator.cc', 'command_buffer/client/fenced_allocator.h', - 'command_buffer/client/id_allocator.cc', - 'command_buffer/client/id_allocator.h', 'command_buffer/client/ring_buffer.cc', 'command_buffer/client/ring_buffer.h', ], @@ -341,7 +341,6 @@ 'command_buffer/client/cmd_buffer_helper_test.cc', 'command_buffer/client/fenced_allocator_test.cc', 'command_buffer/client/gles2_implementation_unittest.cc', - 'command_buffer/client/id_allocator_test.cc', 'command_buffer/client/ring_buffer_test.cc', 'command_buffer/common/bitfield_helpers_test.cc', 'command_buffer/common/gles2_cmd_format_test.cc', @@ -356,6 +355,7 @@ 'command_buffer/common/gles2_cmd_format_test_autogen.h', 'command_buffer/common/gles2_cmd_id_test.cc', 'command_buffer/common/gles2_cmd_id_test_autogen.h', + 'command_buffer/common/id_allocator_test.cc', 'command_buffer/service/buffer_manager_unittest.cc', 'command_buffer/service/context_group_unittest.cc', 'command_buffer/service/cmd_parser_test.cc', diff --git a/gpu/pgl/pgl.cc b/gpu/pgl/pgl.cc index 3e42854..b373478 100644 --- a/gpu/pgl/pgl.cc +++ b/gpu/pgl/pgl.cc @@ -84,7 +84,8 @@ PGLBoolean PGLContextImpl::Initialize(int32 transfer_buffer_size) { gles2_helper_, transfer_buffer.size, transfer_buffer.ptr, - transfer_buffer_id_); + transfer_buffer_id_, + false); return PGL_TRUE; } } |