diff options
| author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-03 01:11:37 +0000 |
|---|---|---|
| committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-03 01:11:37 +0000 |
| commit | f7b85373bada6dc2da2ca3b47c38fc25d89dcf2e (patch) | |
| tree | b14cdb3fd116c4287f2d61cd0f4e75c91cdf13b4 /gpu | |
| parent | 50d22375941bee74a33e504c78e4355c878c30b9 (diff) | |
| download | chromium_src-f7b85373bada6dc2da2ca3b47c38fc25d89dcf2e.zip chromium_src-f7b85373bada6dc2da2ca3b47c38fc25d89dcf2e.tar.gz chromium_src-f7b85373bada6dc2da2ca3b47c38fc25d89dcf2e.tar.bz2 | |
Implements glGetUniformiv and glGetUniformfv.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/566019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37918 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
| -rw-r--r-- | gpu/command_buffer/client/gles2_implementation.cc | 11 | ||||
| -rw-r--r-- | gpu/command_buffer/common/gles2_cmd_format.h | 12 | ||||
| -rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils.cc | 41 | ||||
| -rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils.h | 2 | ||||
| -rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 142 | ||||
| -rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 233 |
6 files changed, 413 insertions, 28 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index e0cbb04..8ea20ab 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -291,7 +291,6 @@ void GLES2Implementation::TexSubImage2D( } } - GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) { // TODO(gman): implement. return 0; @@ -341,12 +340,18 @@ const GLubyte* GLES2Implementation::GetString(GLenum name) { void GLES2Implementation::GetUniformfv( GLuint program, GLint location, GLfloat* params) { - // TODO(gman): implement. + helper_->GetUniformfv( + program, location, result_shm_id(), result_shm_offset()); + WaitForCmd(); + CopyResult(params); } void GLES2Implementation::GetUniformiv( GLuint program, GLint location, GLint* params) { - // TODO(gman): implement. + helper_->GetUniformiv( + program, location, result_shm_id(), result_shm_offset()); + WaitForCmd(); + CopyResult(params); } void GLES2Implementation::ReadPixels( diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h index 7598318..d6d3beb 100644 --- a/gpu/command_buffer/common/gles2_cmd_format.h +++ b/gpu/command_buffer/common/gles2_cmd_format.h @@ -40,10 +40,22 @@ struct SizedResult { T GetDataAs() { return static_cast<T>(static_cast<void*>(&data)); } + + // Returns the size of the SizedResult for a given size of result. + static size_t GetSize(size_t size_of_result) { + return size_of_result + sizeof(uint32); // NOLINT + } + uint32 size; // in bytes. int32 data; // this is just here to get an offset. }; +COMPILE_ASSERT(sizeof(SizedResult) == 8, SizedResult_size_not_8); +COMPILE_ASSERT(offsetof(SizedResult, size) == 0, + OffsetOf_SizedResult_size_not_0); +COMPILE_ASSERT(offsetof(SizedResult, data) == 4, + OffsetOf_SizedResult_data_not_4); + #include "gpu/command_buffer/common/gles2_cmd_format_autogen.h" // These are hand written commands. diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc index 8145315..aac4b84 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -343,6 +343,47 @@ uint32 GLES2Util::ComputeImageDataSize( return height * row_size; } +uint32 GLES2Util::GetGLDataTypeSize(int type) { + switch (type) { + case GL_FLOAT: + return sizeof(GLfloat); // NOLINT + case GL_FLOAT_VEC2: + return sizeof(GLfloat) * 2; // NOLINT + case GL_FLOAT_VEC3: + return sizeof(GLfloat) * 3; // NOLINT + case GL_FLOAT_VEC4: + return sizeof(GLfloat) * 4; // NOLINT + case GL_INT: + return sizeof(GLint); // NOLINT + case GL_INT_VEC2: + return sizeof(GLint) * 2; // NOLINT + case GL_INT_VEC3: + return sizeof(GLint) * 3; // NOLINT + case GL_INT_VEC4: + return sizeof(GLint) * 4; // NOLINT + case GL_BOOL: + return sizeof(GLint); // NOLINT + case GL_BOOL_VEC2: + return sizeof(GLint) * 1; // NOLINT + case GL_BOOL_VEC3: + return sizeof(GLint) * 2; // NOLINT + case GL_BOOL_VEC4: + return sizeof(GLint) * 3; // NOLINT + case GL_FLOAT_MAT2: + return sizeof(GLfloat) * 2 * 2; // NOLINT + case GL_FLOAT_MAT3: + return sizeof(GLfloat) * 3 * 3; // NOLINT + case GL_FLOAT_MAT4: + return sizeof(GLfloat) * 4 * 4; // NOLINT + case GL_SAMPLER_2D: + return sizeof(GLint); // NOLINT + case GL_SAMPLER_CUBE: + return sizeof(GLint); // NOLINT + default: + return 0; + } +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h index 6a14133..1d2139d 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/gpu/command_buffer/common/gles2_cmd_utils.h @@ -30,6 +30,8 @@ class GLES2Util { static uint32 ComputeImageDataSize( int width, int height, int format, int type, int unpack_alignment); + static uint32 GetGLDataTypeSize(int type); + private: int num_compressed_texture_formats_; }; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 7abccc9..e708a69 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -35,6 +35,8 @@ COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT GLint_not_same_size_as_uint32); COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT GLint_not_same_size_as_uint32); +COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT + GLfloat_not_same_size_as_float); namespace { @@ -309,6 +311,15 @@ class ProgramManager { // or if enabled that it points to a valid source. class ProgramInfo { public: + struct UniformInfo { + GLsizei GetSizeInBytes() const; + + GLsizei size; + GLenum type; + GLint location; + }; + + typedef std::vector<UniformInfo> UniformInfoVector; typedef std::vector<GLuint> AttribLocationVector; ProgramInfo() { @@ -326,8 +337,34 @@ class ProgramManager { const AttribLocationVector& GetAttribLocations() const { return attrib_locations_; } + + void SetNumUniforms(int num_uniforms) { + uniform_infos_.resize(num_uniforms); + } + + void SetUniformInfo( + GLint index, GLsizei size, GLenum type, GLint location) { + UniformInfo& info = uniform_infos_[index]; + info.size = size; + info.type = type; + info.location = location; + } + + const UniformInfo* GetUniformInfoByLocation(GLint location) { + for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { + if (uniform_infos_[ii].location == location) { + return &uniform_infos_[ii]; + } + } + return NULL; + } + + private: AttribLocationVector attrib_locations_; + + // Uniform info by info. + UniformInfoVector uniform_infos_; }; ProgramInfo* GetProgramInfo(GLuint program); @@ -345,6 +382,10 @@ class ProgramManager { ProgramInfoMap program_infos_; }; +GLsizei ProgramManager::ProgramInfo::UniformInfo::GetSizeInBytes() const { + return GLES2Util::GetGLDataTypeSize(type) * size; +} + ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program) { ProgramInfoMap::iterator it = program_infos_.find(program); return it != program_infos_.end() ? &it->second : NULL; @@ -364,17 +405,32 @@ void ProgramManager::UpdateProgramInfo(GLuint program) { info->SetNumAttributes(num_attribs); glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); // TODO(gman): Should we check for error? - scoped_array<char> name_buffer(new char[max_len + 1]); + scoped_array<char> name_buffer(new char[max_len]); for (GLint ii = 0; ii < num_attribs; ++ii) { GLsizei length; GLsizei size; GLenum type; glGetActiveAttrib( - program, ii, max_len + 1, &length, &size, &type, name_buffer.get()); + program, ii, max_len, &length, &size, &type, name_buffer.get()); // TODO(gman): Should we check for error? GLint location = glGetAttribLocation(program, name_buffer.get()); info->SetAttributeLocation(ii, location); } + GLint num_uniforms; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &num_uniforms); + info->SetNumUniforms(num_uniforms); + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); + name_buffer.reset(new char[max_len]); + for (GLint ii = 0; ii < num_uniforms; ++ii) { + GLsizei length; + GLsizei size; + GLenum type; + glGetActiveUniform( + program, ii, max_len, &length, &size, &type, name_buffer.get()); + // TODO(gman): Should we check for error? + GLint location = glGetUniformLocation(program, name_buffer.get()); + info->SetUniformInfo(ii, size, type, location); + } } void ProgramManager::RemoveProgramInfo(GLuint program) { @@ -613,6 +669,14 @@ class GLES2DecoderImpl : public GLES2Decoder { bound_element_array_buffer_; } + // Validates the program and location for a glGetUniform call and returns + // a SizeResult setup to receive the result. Returns true if glGetUniform + // should be called. + bool GetUniformSetup( + GLuint program, GLint location, + uint32 shm_id, uint32 shm_offset, + error::Error* error, GLuint* service_id, SizedResult** result); + // Generate a member function prototype for each command in an automated and // typesafe way. #define GLES2_CMD_OP(name) \ @@ -1863,18 +1927,80 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( return error::kNoError; } +bool GLES2DecoderImpl::GetUniformSetup( + GLuint program, GLint location, + uint32 shm_id, uint32 shm_offset, + error::Error* error, GLuint* service_id, SizedResult** result) { + *error = error::kNoError; + // Make sure we have enough room for the result on failure. + *result = GetSharedMemoryAs<SizedResult*>( + shm_id, shm_offset, SizedResult::GetSize(0)); + if (!*result) { + *error = error::kOutOfBounds; + return false; + } + // Set the result size to 0 so the client does not have to check for success. + (*result)->size = 0; + if (!id_manager_->GetServiceId(program, service_id)) { + SetGLError(GL_INVALID_VALUE); + return error::kNoError; + } + ProgramManager::ProgramInfo* info = GetProgramInfo(*service_id); + if (!info) { + // Program was not linked successfully. (ie, glLinkProgram) + SetGLError(GL_INVALID_OPERATION); + return false; + } + const ProgramManager::ProgramInfo::UniformInfo* uniform_info = + info->GetUniformInfoByLocation(location); + if (!uniform_info) { + // No such location. + SetGLError(GL_INVALID_OPERATION); + return false; + } + GLsizei size = uniform_info->GetSizeInBytes(); + if (size == 0) { + SetGLError(GL_INVALID_OPERATION); + return false; + } + *result = GetSharedMemoryAs<SizedResult*>( + shm_id, shm_offset, SizedResult::GetSize(size)); + if (!*result) { + *error = error::kOutOfBounds; + return false; + } + (*result)->size = size; + return true; +} + error::Error GLES2DecoderImpl::HandleGetUniformiv( uint32 immediate_data_size, const gles2::GetUniformiv& c) { - // TODO(gman): Implement. - NOTREACHED(); - return error::kNoError; + GLuint program = c.program; + GLint location = c.location; + GLuint service_id; + Error error; + SizedResult* result; + if (GetUniformSetup( + program, location, c.params_shm_id, c.params_shm_offset, + &error, &service_id, &result)) { + glGetUniformiv(service_id, location, result->GetDataAs<GLint*>()); + } + return error; } error::Error GLES2DecoderImpl::HandleGetUniformfv( uint32 immediate_data_size, const gles2::GetUniformfv& c) { - // TODO(gman): Implement. - NOTREACHED(); - return error::kNoError; + GLuint program = c.program; + GLint location = c.location; + GLuint service_id; + Error error; + SizedResult* result; + if (GetUniformSetup( + program, location, c.params_shm_id, c.params_shm_offset, + &error, &service_id, &result)) { + glGetUniformfv(service_id, location, result->GetDataAs<GLfloat*>()); + } + return error; } error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 7133eab..6cb0b54 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -4,6 +4,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/service/gl_mock.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "testing/gtest/include/gtest/gtest.h" @@ -288,6 +289,12 @@ void GLES2DecoderTest::SpecializedSetup<LinkProgram, 0>() { *gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) .WillOnce(SetArgumentPointee<2>(0)); + EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgumentPointee<2>(0)); + EXPECT_CALL( + *gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(0)); }; @@ -297,8 +304,6 @@ class GLES2DecoderWithShaderTest : public GLES2DecoderTest { : GLES2DecoderTest() { } - static const GLint kNumAttribs = 3; - static const GLint kMaxAttribLength = 10; static const GLsizei kNumVertices = 100; static const GLsizei kNumIndices = 10; static const int kValidIndexRangeStart = 1; @@ -306,9 +311,26 @@ class GLES2DecoderWithShaderTest : public GLES2DecoderTest { static const int kInvalidIndexRangeStart = 0; static const int kInvalidIndexRangeCount = 7; static const int kOutOfRangeIndexRangeEnd = 10; + static const GLint kNumAttribs = 3; + static const GLint kMaxAttribLength = 10; static const char* kAttrib1Name; static const char* kAttrib2Name; static const char* kAttrib3Name; + static const GLint kNumUniforms = 3; + static const GLint kMaxUniformLength = 10; + static const char* kUniform1Name; + static const char* kUniform2Name; + static const char* kUniform3Name; + static const GLint kUniform1Size = 1; + static const GLint kUniform2Size = 3; + static const GLint kUniform3Size = 2; + static const GLint kUniform1Location = 0; + static const GLint kUniform2Location = 1; + static const GLint kUniform3Location = 2; + static const GLenum kUniform1Type = GL_FLOAT_VEC4; + static const GLenum kUniform2Type = GL_INT_VEC2; + static const GLenum kUniform3Type = GL_FLOAT_VEC3; + static const GLint kInvalidUniformLocation = 3; protected: virtual void SetUp() { @@ -326,30 +348,42 @@ class GLES2DecoderWithShaderTest : public GLES2DecoderTest { { kAttrib2Name, 1, GL_FLOAT_VEC2, 1, }, { kAttrib3Name, 1, GL_FLOAT_VEC3, 2, }, }; + struct UniformInfo { + const char* name; + GLint size; + GLenum type; + GLint location; + }; + static UniformInfo uniforms[] = { + { kUniform1Name, kUniform1Size, GL_FLOAT_VEC4, kUniform1Location, }, + { kUniform2Name, kUniform2Size, GL_INT_VEC2, kUniform2Location, }, + { kUniform3Name, kUniform3Size, GL_FLOAT_VEC3, kUniform3Location, }, + }; + LinkProgram cmd; cmd.Init(client_program_id_); - EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, GetError()) - .WillOnce(Return(GL_NO_ERROR)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) - .WillOnce(SetArgumentPointee<2>(kNumAttribs)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(kMaxAttribLength)) - .RetiresOnSaturation(); { InSequence s; + EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) + .WillOnce(SetArgumentPointee<2>(kNumAttribs)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(kMaxAttribLength)) + .RetiresOnSaturation(); for (GLint ii = 0; ii < kNumAttribs; ++ii) { const AttribInfo& info = attribs[ii]; EXPECT_CALL(*gl_, GetActiveAttrib(kServiceProgramId, ii, - kMaxAttribLength + 1, _, _, _, _)) + kMaxAttribLength, _, _, _, _)) .WillOnce(DoAll( SetArgumentPointee<3>(strlen(info.name)), SetArgumentPointee<4>(info.size), @@ -362,6 +396,31 @@ class GLES2DecoderWithShaderTest : public GLES2DecoderTest { .WillOnce(Return(info.location)) .RetiresOnSaturation(); } + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgumentPointee<2>(kNumUniforms)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(kMaxUniformLength)) + .RetiresOnSaturation(); + for (GLint ii = 0; ii < kNumUniforms; ++ii) { + const UniformInfo& info = uniforms[ii]; + EXPECT_CALL(*gl_, + GetActiveUniform(kServiceProgramId, ii, + kMaxUniformLength, _, _, _, _)) + .WillOnce(DoAll( + SetArgumentPointee<3>(strlen(info.name)), + SetArgumentPointee<4>(info.size), + SetArgumentPointee<5>(info.type), + SetArrayArgument<6>(info.name, + info.name + strlen(info.name) + 1))) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetUniformLocation(kServiceProgramId, + StrEq(info.name))) + .WillOnce(Return(info.location)) + .RetiresOnSaturation(); + } } EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -493,6 +552,9 @@ const int GLES2DecoderWithShaderTest::kOutOfRangeIndexRangeEnd; const char* GLES2DecoderWithShaderTest::kAttrib1Name = "attrib1"; const char* GLES2DecoderWithShaderTest::kAttrib2Name = "attrib2"; const char* GLES2DecoderWithShaderTest::kAttrib3Name = "attrib3"; +const char* GLES2DecoderWithShaderTest::kUniform1Name = "uniform1"; +const char* GLES2DecoderWithShaderTest::kUniform2Name = "uniform2"; +const char* GLES2DecoderWithShaderTest::kUniform3Name = "uniform3"; TEST_F(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) { EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) @@ -790,6 +852,143 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_F(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { + GetUniformiv cmd; + cmd.Init(client_program_id_, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2Location, _)) + .Times(1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kUniform2Size * GLES2Util::GetGLDataTypeSize(kUniform2Type), + result_->size); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { + GetUniformiv cmd; + // non-existant program + cmd.Init(kInvalidClientId, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformiv(_, _, _)) + .Times(0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Valid id that is not a program. The GL spec requires a different error for + // this case. + result_->size = kInitialResult; + cmd.Init(client_texture_id_, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + // Unlinked program + EXPECT_CALL(*gl_, CreateProgram()) + .Times(1) + .WillOnce(Return(kNewServiceId)) + .RetiresOnSaturation(); + CreateProgram cmd2; + cmd2.Init(kNewClientId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); + result_->size = kInitialResult; + cmd.Init(kNewClientId, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) { + GetUniformiv cmd; + // invalid location + cmd.Init(client_program_id_, kInvalidUniformLocation, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformiv(_, _, _)) + .Times(0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) { + GetUniformiv cmd; + cmd.Init(client_program_id_, kUniform2Location, + kInvalidSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformiv(_, _, _)) + .Times(0); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, kUniform2Location, + kSharedMemoryId, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +}; + +TEST_F(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { + GetUniformfv cmd; + cmd.Init(client_program_id_, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2Location, _)) + .Times(1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kUniform2Size * GLES2Util::GetGLDataTypeSize(kUniform2Type), + result_->size); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { + GetUniformfv cmd; + // non-existant program + cmd.Init(kInvalidClientId, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformfv(_, _, _)) + .Times(0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Valid id that is not a program. The GL spec requires a different error for + // this case. + result_->size = kInitialResult; + cmd.Init(client_texture_id_, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + // Unlinked program + EXPECT_CALL(*gl_, CreateProgram()) + .Times(1) + .WillOnce(Return(kNewServiceId)) + .RetiresOnSaturation(); + CreateProgram cmd2; + cmd2.Init(kNewClientId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); + result_->size = kInitialResult; + cmd.Init(kNewClientId, kUniform2Location, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) { + GetUniformfv cmd; + // invalid location + cmd.Init(client_program_id_, kInvalidUniformLocation, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformfv(_, _, _)) + .Times(0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result_->size); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) { + GetUniformfv cmd; + cmd.Init(client_program_id_, kUniform2Location, + kInvalidSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, GetUniformfv(_, _, _)) + .Times(0); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, kUniform2Location, + kSharedMemoryId, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +}; #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h" |
