diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 16:13:58 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 16:13:58 +0000 |
commit | 6b8cf1ad4ff0c7c145154d78e557eef666247a50 (patch) | |
tree | 56b75e13699c5faf75ba687624dc2dc2ac12abf0 /gpu | |
parent | ab50f5225ec04327d77e9bf3fe0fbc66473c77ab (diff) | |
download | chromium_src-6b8cf1ad4ff0c7c145154d78e557eef666247a50.zip chromium_src-6b8cf1ad4ff0c7c145154d78e557eef666247a50.tar.gz chromium_src-6b8cf1ad4ff0c7c145154d78e557eef666247a50.tar.bz2 |
Various fixes for the OpenGL ES 2.0 conformance tests.
Was failing 268 of 1198
Now failing 266 of 1198
ugh! all those changes only fixed 2 tests :-(
TEST=some unit test and conformance tests.
BUG=none
Review URL: http://codereview.chromium.org/1942004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46572 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
19 files changed, 318 insertions, 95 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 6b2efad..8e7867c 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -809,12 +809,10 @@ void GLES2Implementation::ShaderSource( // Compute the total size. uint32 total_size = 1; for (GLsizei ii = 0; ii < count; ++ii) { - // I shouldn't have to check for this. The spec doesn't allow this - if (!source[ii]) { - SetGLError(GL_INVALID_VALUE, "glShaderSource: null passed for string."); - return; + if (source[ii]) { + total_size += + (length && length[ii] >= 0) ? length[ii] : strlen(source[ii]); } - total_size += (length && length[ii] >= 0) ? length[ii] : strlen(source[ii]); } // Concatenate all the strings in to a bucket on the service. @@ -823,19 +821,20 @@ void GLES2Implementation::ShaderSource( uint32 offset = 0; for (GLsizei ii = 0; ii <= count; ++ii) { const char* src = ii < count ? source[ii] : ""; - - uint32 size = ii < count ? (length ? length[ii] : strlen(src)) : 1; - while (size) { - uint32 part_size = std::min(size, max_size); - void* buffer = transfer_buffer_.Alloc(part_size); - memcpy(buffer, src, part_size); - helper_->SetBucketData(kResultBucketId, offset, part_size, - transfer_buffer_id_, - transfer_buffer_.GetOffset(buffer)); - transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); - offset += part_size; - src += part_size; - size -= part_size; + if (src) { + uint32 size = ii < count ? (length ? length[ii] : strlen(src)) : 1; + while (size) { + uint32 part_size = std::min(size, max_size); + void* buffer = transfer_buffer_.Alloc(part_size); + memcpy(buffer, src, part_size); + helper_->SetBucketData(kResultBucketId, offset, part_size, + transfer_buffer_id_, + transfer_buffer_.GetOffset(buffer)); + transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); + offset += part_size; + src += part_size; + size -= part_size; + } } } diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index e43bf84..b73b889 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -626,6 +626,8 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS) + TEST_F(GLES2ImplementationTest, ReservedIds) { // Only the get error command should be issued. struct Cmds { @@ -650,8 +652,42 @@ TEST_F(GLES2ImplementationTest, ReservedIds) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS) +TEST_F(GLES2ImplementationTest, ReadPixels2Reads) { + struct Cmds { + ReadPixels read1; + cmd::SetToken set_token1; + ReadPixels read2; + cmd::SetToken set_token2; + }; + const GLint kBytesPerPixel = 4; + const GLint kWidth = + (kTransferBufferSize - GLES2Implementation::kStartingOffset) / + kBytesPerPixel; + const GLint kHeight = 2; + const GLenum kFormat = GL_RGBA; + const GLenum kType = GL_UNSIGNED_BYTE; + + int32 token = 1; + uint32 offset = GLES2Implementation::kStartingOffset; + Cmds expected; + expected.read1.Init(0, 0, kWidth, kHeight / 2, kFormat, kType, + kTransferBufferId, offset, + kTransferBufferId, 0); + expected.set_token1.Init(token++); + expected.read2.Init(0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, + kTransferBufferId, offset, + kTransferBufferId, 0); + expected.set_token2.Init(token++); + scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) + .WillOnce(SetMemory(uint32(1))) + .RetiresOnSaturation(); + + gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get()); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc index dbc382c..ab5ab8ac 100644 --- a/gpu/command_buffer/service/buffer_manager.cc +++ b/gpu/command_buffer/service/buffer_manager.cc @@ -124,6 +124,18 @@ bool BufferManager::BufferInfo::GetMaxValueForRange( return true; } +bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const { + // This doesn't need to be fast. It's only used during slow queries. + for (BufferInfoMap::const_iterator it = buffer_infos_.begin(); + it != buffer_infos_.end(); ++it) { + if (it->second->service_id() == service_id) { + *client_id = it->first; + return true; + } + } + return false; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index 7eefd52..d944532 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h @@ -142,6 +142,9 @@ class BufferManager { // Removes a buffer info for the given buffer. void RemoveBufferInfo(GLuint client_id); + // Gets a client id for a given service id. + bool GetClientId(GLuint service_id, GLuint* client_id) const; + private: // Info for each buffer in the system. // TODO(gman): Choose a faster container. diff --git a/gpu/command_buffer/service/buffer_manager_unittest.cc b/gpu/command_buffer/service/buffer_manager_unittest.cc index 2346f7c..83a33fd 100644 --- a/gpu/command_buffer/service/buffer_manager_unittest.cc +++ b/gpu/command_buffer/service/buffer_manager_unittest.cc @@ -37,6 +37,9 @@ TEST_F(BufferManagerTest, Basic) { EXPECT_EQ(0, info1->size()); EXPECT_FALSE(info1->IsDeleted()); EXPECT_EQ(kServiceBuffer1Id, info1->service_id()); + GLuint client_id = 0; + EXPECT_TRUE(manager_.GetClientId(info1->service_id(), &client_id)); + EXPECT_EQ(kClientBuffer1Id, client_id); info1->set_target(GL_ELEMENT_ARRAY_BUFFER); EXPECT_EQ(static_cast<GLenum>(GL_ELEMENT_ARRAY_BUFFER), info1->target()); // Check we and set its size. diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index fb1014a..1a7d739 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -46,6 +46,19 @@ void FramebufferManager::FramebufferInfo::AttachRenderbuffer( } } +bool FramebufferManager::GetClientId( + GLuint service_id, GLuint* client_id) const { + // This doesn't need to be fast. It's only used during slow queries. + for (FramebufferInfoMap::const_iterator it = framebuffer_infos_.begin(); + it != framebuffer_infos_.end(); ++it) { + if (it->second->service_id() == service_id) { + *client_id = it->first; + return true; + } + } + return false; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h index db05c5b..3ecb54b 100644 --- a/gpu/command_buffer/service/framebuffer_manager.h +++ b/gpu/command_buffer/service/framebuffer_manager.h @@ -73,6 +73,9 @@ class FramebufferManager { // Removes a framebuffer info for the given framebuffer. void RemoveFramebufferInfo(GLuint client_id); + // Gets a client id for a given service id. + bool GetClientId(GLuint service_id, GLuint* client_id) const; + private: // Info for each framebuffer in the system. // TODO(gman): Choose a faster container. diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 1c57c85..75d0da6 100644 --- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -35,6 +35,9 @@ TEST_F(FramebufferManagerTest, Basic) { ASSERT_TRUE(info1 != NULL); EXPECT_FALSE(info1->IsDeleted()); EXPECT_EQ(kService1Id, info1->service_id()); + GLuint client_id = 0; + EXPECT_TRUE(manager_.GetClientId(info1->service_id(), &client_id)); + EXPECT_EQ(kClient1Id, client_id); // Check we get nothing for a non-existent framebuffer. EXPECT_TRUE(manager_.GetFramebufferInfo(kClient2Id) == NULL); // Check trying to a remove non-existent framebuffers does not crash. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 988bc18..93f28f9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -506,6 +506,25 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, return (info && !info->IsDeleted()) ? info : NULL; } + // Gets the program info for the given program. If it's not a program + // generates a GL error. Returns NULL if not program. + ProgramManager::ProgramInfo* GetProgramInfoNotShader( + GLuint client_id, const char* function_name) { + ProgramManager::ProgramInfo* info = GetProgramInfo(client_id); + if (!info) { + if (GetShaderInfo(client_id)) { + SetGLError(GL_INVALID_OPERATION, + (std::string(function_name) + + ": shader passed for program").c_str()); + } else { + SetGLError(GL_INVALID_VALUE, + (std::string(function_name) + ": unknown program").c_str()); + } + } + return info; + } + + // Deletes the program info for the given program. void RemoveProgramInfo(GLuint client_id) { program_manager()->RemoveProgramInfo(client_id); @@ -525,6 +544,25 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, return (info && !info->IsDeleted()) ? info : NULL; } + // Gets the shader info for the given shader. If it's not a shader generates a + // GL error. Returns NULL if not shader. + ShaderManager::ShaderInfo* GetShaderInfoNotProgram( + GLuint client_id, const char* function_name) { + ShaderManager::ShaderInfo* info = GetShaderInfo(client_id); + if (!info) { + if (GetProgramInfo(client_id)) { + SetGLError( + GL_INVALID_OPERATION, + (std::string(function_name) + + ": program passed for shader").c_str()); + } else { + SetGLError(GL_INVALID_VALUE, + (std::string(function_name) + ": unknown shader").c_str()); + } + } + return info; + } + // Deletes the shader info for the given shader. void RemoveShaderInfo(GLuint client_id) { shader_manager()->RemoveShaderInfo(client_id); @@ -1949,6 +1987,87 @@ bool GLES2DecoderImpl::GetHelper( *num_written = 1; *params = GL_TRUE; return true; + case GL_ARRAY_BUFFER_BINDING: + *num_written = 1; + if (bound_array_buffer_) { + GLuint client_id = 0; + buffer_manager()->GetClientId(bound_array_buffer_->service_id(), + &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + *num_written = 1; + if (bound_element_array_buffer_) { + GLuint client_id = 0; + buffer_manager()->GetClientId(bound_element_array_buffer_->service_id(), + &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + case GL_FRAMEBUFFER_BINDING: + *num_written = 1; + if (bound_framebuffer_) { + GLuint client_id = 0; + framebuffer_manager()->GetClientId( + bound_framebuffer_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + case GL_RENDERBUFFER_BINDING: + *num_written = 1; + if (bound_renderbuffer_) { + GLuint client_id = 0; + renderbuffer_manager()->GetClientId( + bound_renderbuffer_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + case GL_CURRENT_PROGRAM: + *num_written = 1; + if (current_program_) { + GLuint client_id = 0; + program_manager()->GetClientId( + current_program_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + case GL_TEXTURE_BINDING_2D: { + *num_written = 1; + TextureUnit& unit = texture_units_[active_texture_unit_]; + if (unit.bound_texture_2d) { + GLuint client_id = 0; + texture_manager()->GetClientId( + unit.bound_texture_2d->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + } + case GL_TEXTURE_BINDING_CUBE_MAP: { + *num_written = 1; + TextureUnit& unit = texture_units_[active_texture_unit_]; + if (unit.bound_texture_cube_map) { + GLuint client_id = 0; + texture_manager()->GetClientId( + unit.bound_texture_cube_map->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } + return true; + } default: return false; } @@ -1992,9 +2111,9 @@ void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { void GLES2DecoderImpl::DoGetProgramiv( GLuint program_id, GLenum pname, GLint* params) { - ProgramManager::ProgramInfo* info = GetProgramInfo(program_id); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program_id, "glGetProgramiv"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetProgramiv: unknown program"); return; } info->GetProgramiv(pname, params); @@ -2002,9 +2121,10 @@ void GLES2DecoderImpl::DoGetProgramiv( error::Error GLES2DecoderImpl::HandleBindAttribLocation( uint32 immediate_data_size, const gles2::BindAttribLocation& c) { - ProgramManager::ProgramInfo* info = GetProgramInfo(c.program); + GLuint program = static_cast<GLuint>(c.program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glBindAttribLocation"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glBindAttribLocation: unknown program"); return error::kNoError; } GLuint index = static_cast<GLuint>(c.index); @@ -2021,9 +2141,10 @@ error::Error GLES2DecoderImpl::HandleBindAttribLocation( error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate( uint32 immediate_data_size, const gles2::BindAttribLocationImmediate& c) { - ProgramManager::ProgramInfo* info = GetProgramInfo(c.program); + GLuint program = static_cast<GLuint>(c.program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glBindAttribLocation"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glBindAttribLocation: unknown program"); return error::kNoError; } GLuint index = static_cast<GLuint>(c.index); @@ -2040,9 +2161,10 @@ error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate( error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( uint32 immediate_data_size, const gles2::BindAttribLocationBucket& c) { - ProgramManager::ProgramInfo* info = GetProgramInfo(c.program); + GLuint program = static_cast<GLuint>(c.program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glBindAttribLocation"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glBindAttribLocation: unknown program"); return error::kNoError; } GLuint index = static_cast<GLuint>(c.index); @@ -2283,19 +2405,18 @@ void GLES2DecoderImpl::DoRenderbufferStorage( } void GLES2DecoderImpl::DoLinkProgram(GLuint program) { - ProgramManager::ProgramInfo* info = GetProgramInfo(program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glLinkProgram"); if (!info) { - SetGLError(GL_INVALID_OPERATION, "glLinkProgram: unknown program"); return; } - CopyRealGLErrorsToWrapper(); glLinkProgram(info->service_id()); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - info->Reset(); - SetGLError(error, NULL); - } else { + GLint success = 0; + glGetProgramiv(info->service_id(), GL_LINK_STATUS, &success); + if (success) { info->Update(); + } else { + info->Reset(); } }; @@ -2368,9 +2489,8 @@ void GLES2DecoderImpl::DoUseProgram(GLuint program) { GLuint service_id = 0; ProgramManager::ProgramInfo* info = NULL; if (program) { - info = GetProgramInfo(program); + info = GetProgramInfoNotShader(program, "glUseProgram"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glUseProgram: unknown program"); return; } if (!info->IsValid()) { @@ -2618,9 +2738,9 @@ GLuint GLES2DecoderImpl::DoGetMaxValueInBuffer( // memory.) error::Error GLES2DecoderImpl::ShaderSourceHelper( GLuint client_id, const char* data, uint32 data_size) { - ShaderManager::ShaderInfo* info = GetShaderInfo(client_id); + ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( + client_id, "glShaderSource"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glShaderSource: unknown shader"); return error::kNoError; } // Note: We don't actually call glShaderSource here. We wait until @@ -2663,9 +2783,9 @@ error::Error GLES2DecoderImpl::HandleShaderSourceBucket( } void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { - ShaderManager::ShaderInfo* info = GetShaderInfo(client_id); + ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( + client_id, "glCompileShader"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glCompileShader: unknown shader"); return; } // Translate GL ES 2.0 shader to Desktop GL shader and pass that to @@ -2711,9 +2831,9 @@ void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { void GLES2DecoderImpl::DoGetShaderiv( GLuint shader, GLenum pname, GLint* params) { - ShaderManager::ShaderInfo* info = GetShaderInfo(shader); + ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( + shader, "glGetShaderiv"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetShaderiv: unknown shader"); return; } if (pname == GL_SHADER_SOURCE_LENGTH) { @@ -2726,12 +2846,12 @@ void GLES2DecoderImpl::DoGetShaderiv( error::Error GLES2DecoderImpl::HandleGetShaderSource( uint32 immediate_data_size, const gles2::GetShaderSource& c) { GLuint shader = c.shader; - ShaderManager::ShaderInfo* info = GetShaderInfo(shader); uint32 bucket_id = static_cast<uint32>(c.bucket_id); Bucket* bucket = CreateBucket(bucket_id); + ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( + shader, "glGetShaderSource"); if (!info) { bucket->SetSize(0); - SetGLError(GL_INVALID_VALUE, "glGetShaderSource: unknown shader"); return error::kNoError; } bucket->SetFromString(info->source()); @@ -2741,15 +2861,15 @@ error::Error GLES2DecoderImpl::HandleGetShaderSource( error::Error GLES2DecoderImpl::HandleGetProgramInfoLog( uint32 immediate_data_size, const gles2::GetProgramInfoLog& c) { GLuint program = c.program; - ProgramManager::ProgramInfo* info = GetProgramInfo(program); + uint32 bucket_id = static_cast<uint32>(c.bucket_id); + Bucket* bucket = CreateBucket(bucket_id); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glGetProgramInfoLog"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetProgramInfoLog: unknown program"); return error::kNoError; } - uint32 bucket_id = static_cast<uint32>(c.bucket_id); GLint len = 0; glGetProgramiv(info->service_id(), GL_INFO_LOG_LENGTH, &len); - Bucket* bucket = CreateBucket(bucket_id); bucket->SetSize(len + 1); glGetProgramInfoLog( info->service_id(), @@ -2760,15 +2880,16 @@ error::Error GLES2DecoderImpl::HandleGetProgramInfoLog( error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( uint32 immediate_data_size, const gles2::GetShaderInfoLog& c) { GLuint shader = c.shader; - ShaderManager::ShaderInfo* info = GetShaderInfo(shader); + uint32 bucket_id = static_cast<uint32>(c.bucket_id); + Bucket* bucket = CreateBucket(bucket_id); + ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( + shader, "glGetShaderInfoLog"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetShaderInfoLog: unknown shader"); + bucket->SetSize(0); return error::kNoError; } - uint32 bucket_id = static_cast<uint32>(c.bucket_id); GLint len = 0; glGetShaderiv(info->service_id(), GL_INFO_LOG_LENGTH, &len); - Bucket* bucket = CreateBucket(bucket_id); bucket->SetSize(len + 1); glGetShaderInfoLog( info->service_id(), @@ -2802,14 +2923,14 @@ bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) { void GLES2DecoderImpl::DoAttachShader( GLuint program_client_id, GLint shader_client_id) { - ProgramManager::ProgramInfo* program_info = GetProgramInfo(program_client_id); + ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader( + program_client_id, "glAttachShader"); if (!program_info) { - SetGLError(GL_INVALID_VALUE, "glAttachShader: unknown program"); return; } - ShaderManager::ShaderInfo* shader_info = GetShaderInfo(shader_client_id); + ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram( + shader_client_id, "glAttachShader"); if (!shader_info) { - SetGLError(GL_INVALID_VALUE, "glAttachShader: unknown shader"); return; } glAttachShader(program_info->service_id(), shader_info->service_id()); @@ -2817,23 +2938,23 @@ void GLES2DecoderImpl::DoAttachShader( void GLES2DecoderImpl::DoDetachShader( GLuint program_client_id, GLint shader_client_id) { - ProgramManager::ProgramInfo* program_info = GetProgramInfo(program_client_id); + ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader( + program_client_id, "glDetachShader"); if (!program_info) { - SetGLError(GL_INVALID_VALUE, "glDetachShader: unknown program"); return; } - ShaderManager::ShaderInfo* shader_info = GetShaderInfo(shader_client_id); + ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram( + shader_client_id, "glDetachShader"); if (!shader_info) { - SetGLError(GL_INVALID_VALUE, "glDetachShader: unknown shader"); return; } glDetachShader(program_info->service_id(), shader_info->service_id()); } void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) { - ProgramManager::ProgramInfo* info = GetProgramInfo(program_client_id); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program_client_id, "glValidateProgram"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glValidateProgram: unknown program"); return; } glValidateProgram(info->service_id()); @@ -2951,6 +3072,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels( return error::kNoError; } + glFinish(); if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) { // The user requested an out of range area. Get the results 1 line // at a time. @@ -3041,9 +3163,9 @@ error::Error GLES2DecoderImpl::HandlePixelStorei( error::Error GLES2DecoderImpl::GetAttribLocationHelper( GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, const std::string& name_str) { - ProgramManager::ProgramInfo* info = GetProgramInfo(client_id); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + client_id, "glGetAttribLocation"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetAttribLocation: unknown program"); return error::kNoError; } if (!info->IsValid()) { @@ -3105,9 +3227,9 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket( error::Error GLES2DecoderImpl::GetUniformLocationHelper( GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, const std::string& name_str) { - ProgramManager::ProgramInfo* info = GetProgramInfo(client_id); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + client_id, "glUniformLocation"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetUniformLocation: unknown program"); return error::kNoError; } if (!info->IsValid()) { @@ -3518,9 +3640,9 @@ bool GLES2DecoderImpl::GetUniformSetup( *result_pointer = result; // Set the result size to 0 so the client does not have to check for success. result->SetNumResults(0); - ProgramManager::ProgramInfo* info = GetProgramInfo(program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glGetUniform"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetUniform: unknown program"); return false; } if (!info->IsValid()) { @@ -3636,9 +3758,10 @@ error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( error::Error GLES2DecoderImpl::HandleGetAttachedShaders( uint32 immediate_data_size, const gles2::GetAttachedShaders& c) { uint32 result_size = c.result_size; - ProgramManager::ProgramInfo* info = GetProgramInfo(c.program); + GLuint program = static_cast<GLuint>(c.program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glGetAttachedShaders"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetAttachedShaders: unknown program"); return error::kNoError; } typedef gles2::GetAttachedShaders::Result Result; @@ -3681,14 +3804,9 @@ error::Error GLES2DecoderImpl::HandleGetActiveUniform( if (result->success != 0) { return error::kInvalidArguments; } - ProgramManager::ProgramInfo* info = GetProgramInfo(program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glGetActiveUniform"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetActiveUniform: unknown program"); - return error::kNoError; - } - if (!info->IsValid()) { - // Program was not linked successfully. (ie, glLinkProgram) - SetGLError(GL_INVALID_OPERATION, "glGetActiveUniform: program not linked"); return error::kNoError; } const ProgramManager::ProgramInfo::UniformInfo* uniform_info = @@ -3720,14 +3838,9 @@ error::Error GLES2DecoderImpl::HandleGetActiveAttrib( if (result->success != 0) { return error::kInvalidArguments; } - ProgramManager::ProgramInfo* info = GetProgramInfo(program); + ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( + program, "glGetActiveAttrib"); if (!info) { - SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib: unknown program"); - return error::kNoError; - } - if (!info->IsValid()) { - // Program was not linked successfully. (ie, glLinkProgram) - SetGLError(GL_INVALID_OPERATION, "glGetActiveAttrib: program not linked"); return error::kNoError; } const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 759e54c..859e4d3 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -1317,6 +1317,7 @@ void GLES2DecoderTest::CheckReadPixelsOutOfRange( GLint read_end_y = std::max(0, std::min(kHeight, in_read_y + in_read_height)); GLint read_width = read_end_x - read_x; GLint read_height = read_end_y - read_y; + EXPECT_CALL(*gl_, Finish()).Times(1).RetiresOnSaturation(); if (read_width > 0 && read_height > 0) { for (GLint yy = read_y; yy < read_end_y; ++yy) { EXPECT_CALL( @@ -1399,6 +1400,7 @@ TEST_F(GLES2DecoderTest, ReadPixels) { .WillOnce(Return(GL_NO_ERROR)) .WillOnce(Return(GL_NO_ERROR)) .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Finish()).Times(1).RetiresOnSaturation(); EXPECT_CALL( *gl_, ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _)) .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels)); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc index caadef6..832e0c5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc @@ -34,11 +34,9 @@ class GLES2DecoderTest2 : public GLES2DecoderTestBase { template <> void GLES2DecoderTestBase::SpecializedSetup<LinkProgram, 0>() { - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); InSequence dummy; + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _)) + .WillOnce(SetArgumentPointee<2>(1)); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) .WillOnce(SetArgumentPointee<2>(0)); EXPECT_CALL( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 9da6955..e16f0a4 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -296,14 +296,11 @@ void GLES2DecoderWithShaderTestBase::SetupShader( { InSequence s; - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); EXPECT_CALL(*gl_, LinkProgram(service_id)) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) + EXPECT_CALL(*gl_, GetProgramiv(service_id, GL_LINK_STATUS, _)) + .WillOnce(SetArgumentPointee<2>(1)) .RetiresOnSaturation(); EXPECT_CALL(*gl_, GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _)) diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index afd9bce..5b86014 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc @@ -51,7 +51,8 @@ void ProgramManager::ProgramInfo::Update() { } } - GLint num_uniforms; + GLint num_uniforms = 0; + max_len = 0; glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); name_buffer.reset(new char[max_len]); @@ -257,6 +258,18 @@ void ProgramManager::RemoveProgramInfo(GLuint client_id) { } } +bool ProgramManager::GetClientId(GLuint service_id, GLuint* client_id) const { + // This doesn't need to be fast. It's only used during slow queries. + for (ProgramInfoMap::const_iterator it = program_infos_.begin(); + it != program_infos_.end(); ++it) { + if (it->second->service_id() == service_id) { + *client_id = it->first; + return true; + } + } + return false; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h index 078f8a5..feb263c 100644 --- a/gpu/command_buffer/service/program_manager.h +++ b/gpu/command_buffer/service/program_manager.h @@ -168,6 +168,9 @@ class ProgramManager { // Deletes the program info for the given program. void RemoveProgramInfo(GLuint client_id); + // Gets a client id for a given service id. + bool GetClientId(GLuint service_id, GLuint* client_id) const; + // Returns true if prefix is invalid for gl. static bool IsInvalidPrefix(const char* name, size_t length); diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc index b8b318c..6767646 100644 --- a/gpu/command_buffer/service/program_manager_unittest.cc +++ b/gpu/command_buffer/service/program_manager_unittest.cc @@ -47,6 +47,9 @@ TEST_F(ProgramManagerTest, Basic) { ProgramManager::ProgramInfo* info1 = manager_.GetProgramInfo(kClient1Id); ASSERT_TRUE(info1 != NULL); EXPECT_EQ(kService1Id, info1->service_id()); + GLuint client_id = 0; + EXPECT_TRUE(manager_.GetClientId(info1->service_id(), &client_id)); + EXPECT_EQ(kClient1Id, client_id); // Check we get nothing for a non-existent program. EXPECT_TRUE(manager_.GetProgramInfo(kClient2Id) == NULL); // Check trying to a remove non-existent programs does not crash. diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc index fe07d01..63aee26 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.cc +++ b/gpu/command_buffer/service/renderbuffer_manager.cc @@ -34,6 +34,19 @@ void RenderbufferManager::RemoveRenderbufferInfo(GLuint client_id) { } } +bool RenderbufferManager::GetClientId( + GLuint service_id, GLuint* client_id) const { + // This doesn't need to be fast. It's only used during slow queries. + for (RenderbufferInfoMap::const_iterator it = renderbuffer_infos_.begin(); + it != renderbuffer_infos_.end(); ++it) { + if (it->second->service_id() == service_id) { + *client_id = it->first; + return true; + } + } + return false; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h index 8e2f70b..e896117 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.h +++ b/gpu/command_buffer/service/renderbuffer_manager.h @@ -73,6 +73,9 @@ class RenderbufferManager { // Removes a renderbuffer info for the given renderbuffer. void RemoveRenderbufferInfo(GLuint client_id); + // Gets a client id for a given service id. + bool GetClientId(GLuint service_id, GLuint* client_id) const; + private: // Info for each renderbuffer in the system. // TODO(gman): Choose a faster container. diff --git a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc index bebd8fc..0cedaea 100644 --- a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc @@ -33,6 +33,9 @@ TEST_F(RenderbufferManagerTest, Basic) { RenderbufferManager::RenderbufferInfo* info1 = manager_.GetRenderbufferInfo(kClient1Id); ASSERT_TRUE(info1 != NULL); + GLuint client_id = 0; + EXPECT_TRUE(manager_.GetClientId(info1->service_id(), &client_id)); + EXPECT_EQ(kClient1Id, client_id); EXPECT_FALSE(info1->cleared()); info1->set_cleared(); EXPECT_TRUE(info1->cleared()); diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index 50af31a..9c5fa3e 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -47,6 +47,9 @@ TEST_F(TextureManagerTest, Basic) { TextureManager::TextureInfo* info1 = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info1 != NULL); EXPECT_EQ(kService1Id, info1->service_id()); + GLuint client_id = 0; + EXPECT_TRUE(manager_.GetClientId(info1->service_id(), &client_id)); + EXPECT_EQ(kClient1Id, client_id); // Check we get nothing for a non-existent texture. EXPECT_TRUE(manager_.GetTextureInfo(kClient2Id) == NULL); // Check trying to a remove non-existent textures does not crash. |