summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 16:13:58 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 16:13:58 +0000
commit6b8cf1ad4ff0c7c145154d78e557eef666247a50 (patch)
tree56b75e13699c5faf75ba687624dc2dc2ac12abf0 /gpu
parentab50f5225ec04327d77e9bf3fe0fbc66473c77ab (diff)
downloadchromium_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')
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc35
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc38
-rw-r--r--gpu/command_buffer/service/buffer_manager.cc12
-rw-r--r--gpu/command_buffer/service/buffer_manager.h3
-rw-r--r--gpu/command_buffer/service/buffer_manager_unittest.cc3
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.cc13
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h3
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc245
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc7
-rw-r--r--gpu/command_buffer/service/program_manager.cc15
-rw-r--r--gpu/command_buffer/service/program_manager.h3
-rw-r--r--gpu/command_buffer/service/program_manager_unittest.cc3
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.cc13
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.h3
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager_unittest.cc3
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc3
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.