diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-05 04:21:51 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-05 04:21:51 +0000 |
commit | cb5702720ccb5bf80e174e0749a185d9486aea8a (patch) | |
tree | 8834dc40c46746176bcebe59c630c45d5a58fc6c /gpu | |
parent | e7ff519084d384ed51d11e66c1b029329f14eba9 (diff) | |
download | chromium_src-cb5702720ccb5bf80e174e0749a185d9486aea8a.zip chromium_src-cb5702720ccb5bf80e174e0749a185d9486aea8a.tar.gz chromium_src-cb5702720ccb5bf80e174e0749a185d9486aea8a.tar.bz2 |
Flush command streams after deleting resources
When share groups and pooled IDs are in use, a race condition exists when destroying resources since
the IDs are marked as free before the resource is actually freed. Consider:
Context A creates a framebuffer with id 1
Context B is created in the same sharegroup as A
Context A destroys its framebuffer:
- the ID is freed (via FreeIDs(), which is a synchronous call)
- a DeleteFrameBuffersImmediate command is entered into A's command buffer but does not immediately execute
Context B creates a framebuffer
- genFramebuffer() makes a sync call to the service side, which reports that id 1 is available
At this point, if the service side processes and commands in context B's command stream, it will throw kInvalidArguments
because as far as the service side is concerned framebuffer 1 has never been released.
This patch adds a Flush() after destroying a resource so that the service side will process the resource destruction
command before servicing other command streams. There's still a potential race condition if multiple contexts in the
same share groups are making calls from different threads, but today all contexts in the same share group are on the same thread.
BUG=80703
TEST=none
Review URL: http://codereview.chromium.org/7574024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95576 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
3 files changed, 10 insertions, 2 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 1158825..ee7d6de 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -3072,6 +3072,7 @@ class DeleteHandler(TypeHandler): func.GetOriginalArgs()[-1].name) file.Write(" helper_->%s(%s);\n" % (func.name, func.MakeCmdArgString(""))) + file.Write(" Flush();\n") file.Write("}\n") file.Write("\n") @@ -3201,6 +3202,7 @@ TEST_F(%(test_name)s, %(name)sInvalidArgs) { arg.WriteClientSideValidationCode(file, func) code = """ %(name)sHelper(%(args)s); helper_->%(name)sImmediate(%(args)s); + Flush(); } """ diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 281c4d7..728ef5e 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -222,6 +222,7 @@ void DeleteBuffers(GLsizei n, const GLuint* buffers) { } DeleteBuffersHelper(n, buffers); helper_->DeleteBuffersImmediate(n, buffers); + Flush(); } void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { @@ -242,6 +243,7 @@ void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { } DeleteFramebuffersHelper(n, framebuffers); helper_->DeleteFramebuffersImmediate(n, framebuffers); + Flush(); } void DeleteProgram(GLuint program) { @@ -249,6 +251,7 @@ void DeleteProgram(GLuint program) { GPU_CLIENT_DCHECK(program != 0); program_and_shader_id_handler_->FreeIds(1, &program); helper_->DeleteProgram(program); + Flush(); } void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { @@ -269,6 +272,7 @@ void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { } DeleteRenderbuffersHelper(n, renderbuffers); helper_->DeleteRenderbuffersImmediate(n, renderbuffers); + Flush(); } void DeleteShader(GLuint shader) { @@ -276,6 +280,7 @@ void DeleteShader(GLuint shader) { GPU_CLIENT_DCHECK(shader != 0); program_and_shader_id_handler_->FreeIds(1, &shader); helper_->DeleteShader(shader); + Flush(); } void DeleteTextures(GLsizei n, const GLuint* textures) { @@ -296,6 +301,7 @@ void DeleteTextures(GLsizei n, const GLuint* textures) { } DeleteTexturesHelper(n, textures); helper_->DeleteTexturesImmediate(n, textures); + Flush(); } void DepthFunc(GLenum func) { diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index e8a1798..953875c 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -179,7 +179,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x00000400, "GL_STENCIL_BUFFER_BIT", }, { 0x800A, "GL_FUNC_SUBTRACT", }, { 0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV", }, - { 0x8508, "GL_DECR_WRAP", }, + { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", }, { 0x8006, "GL_FUNC_ADD", }, { 0x8007, "GL_MIN_EXT", }, { 0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA", }, @@ -406,7 +406,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x80CA, "GL_BLEND_DST_ALPHA", }, { 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", }, { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS", }, - { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", }, + { 0x8508, "GL_DECR_WRAP", }, { 0x8507, "GL_INCR_WRAP", }, { 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING", }, { 0x8894, "GL_ARRAY_BUFFER_BINDING", }, |