diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-12 00:11:31 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-12 00:11:31 +0000 |
commit | 45bf51517d9281be03680c5f99ae04657a7a8c19 (patch) | |
tree | b95d9846485a10971c9a98f374a0eacd997bba43 /gpu | |
parent | 9a1cd5f0fd0c97db72a702e7323b6e0080b823f8 (diff) | |
download | chromium_src-45bf51517d9281be03680c5f99ae04657a7a8c19.zip chromium_src-45bf51517d9281be03680c5f99ae04657a7a8c19.tar.gz chromium_src-45bf51517d9281be03680c5f99ae04657a7a8c19.tar.bz2 |
Reimplemented glShaderSource in preparation for shader
compiler to make GLSL shaders DesktopGL complient.
Shader source is now saved by the decoder because
when glGetShaderSource is called we must return
the source that was passed, not the munged source.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/594037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38858 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
9 files changed, 284 insertions, 97 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 5ca1243..6809aaf 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -834,6 +834,7 @@ _ENUM_LISTS = { # needs_size: If true a data_size field is added to the command. # data_type: The type of data the command uses. For PUTn or PUT types. # count: The number of units per element. For PUTn or PUT types. +# unit_test: If False no unit test will be generated. _FUNCTION_INFO = { 'BindAttribLocation': {'type': 'GLchar'}, @@ -844,6 +845,7 @@ _FUNCTION_INFO = { 'BufferSubData': {'type': 'Data'}, 'CheckFramebufferStatus': {'DecoderFunc': 'glCheckFramebufferStatusEXT'}, 'ClearDepthf': {'DecoderFunc': 'glClearDepth'}, + 'CompileShader': {'DecoderFunc': 'DoCompileShader', 'unit_test': False}, 'CompressedTexImage2D': {'type': 'Manual','immediate': True}, 'CompressedTexSubImage2D': {'type': 'Data'}, 'CreateProgram': {'type': 'Create'}, @@ -944,7 +946,7 @@ _FUNCTION_INFO = { 'int32 precision', ], }, - 'GetShaderSource': {'type': 'STRn'}, + 'GetShaderSource': {'type': 'STRn', 'DecoderFunc': 'DoGetShaderSource'}, 'GetTexParameterfv': {'type': 'GETn'}, 'GetTexParameteriv': {'type': 'GETn'}, 'GetUniformfv': { @@ -989,7 +991,7 @@ _FUNCTION_INFO = { 'immediate': True, 'needs_size': True, 'cmd_args': - 'GLuint shader, GLsizei count, const char* data', + 'GLuint shader, const char* data', }, 'TexImage2D': {'type': 'Manual', 'immediate': True}, 'TexParameterfv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 1}, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 5e63eb8..2b6185a 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -690,17 +690,17 @@ } void ShaderSource( - GLuint shader, GLsizei count, uint32 data_shm_id, uint32 data_shm_offset, + GLuint shader, uint32 data_shm_id, uint32 data_shm_offset, uint32 data_size) { gles2::ShaderSource& c = GetCmdSpace<gles2::ShaderSource>(); - c.Init(shader, count, data_shm_id, data_shm_offset, data_size); + c.Init(shader, data_shm_id, data_shm_offset, data_size); } - void ShaderSourceImmediate(GLuint shader, GLsizei count, uint32 data_size) { + void ShaderSourceImmediate(GLuint shader, uint32 data_size) { const uint32 s = 0; // TODO(gman): compute correct size gles2::ShaderSourceImmediate& c = GetImmediateCmdSpaceTotalSize<gles2::ShaderSourceImmediate>(s); - c.Init(shader, count, data_size); + c.Init(shader, data_size); } void StencilFunc(GLenum func, GLint ref, GLuint mask) { diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index edeb1fa..17e4bbf 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -198,25 +198,25 @@ void GLES2Implementation::ShaderSource( // TODO(gman): change to use buckets and check that there is enough room. // Compute the total size. - uint32 total_size = count * sizeof(total_size); + uint32 total_size = 0; for (GLsizei ii = 0; ii < count; ++ii) { total_size += length ? length[ii] : strlen(source[ii]); } - // Create string table in transfer buffer. + // Concatenate all the strings in to the transfer buffer. char* strings = transfer_buffer_.AllocTyped<char>(total_size); - uint32* offsets = reinterpret_cast<uint32*>(strings); - uint32 offset = count * sizeof(*offsets); + uint32 offset = 0; for (GLsizei ii = 0; ii < count; ++ii) { uint32 len = length ? length[ii] : strlen(source[ii]); memcpy(strings + offset, source[ii], len); offset += len; - offsets[ii] = offset; } + DCHECK_EQ(total_size, offset); - helper_->ShaderSource(shader, count, + helper_->ShaderSource(shader, transfer_buffer_id_, - transfer_buffer_.GetOffset(strings), offset); + transfer_buffer_.GetOffset(strings), + total_size); transfer_buffer_.FreePendingToken(strings, helper_->InsertToken()); } diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 694060a..57a8a4e 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -4924,47 +4924,42 @@ struct ShaderSource { } void Init( - GLuint _shader, GLsizei _count, uint32 _data_shm_id, - uint32 _data_shm_offset, uint32 _data_size) { + GLuint _shader, uint32 _data_shm_id, uint32 _data_shm_offset, + uint32 _data_size) { SetHeader(); shader = _shader; - count = _count; data_shm_id = _data_shm_id; data_shm_offset = _data_shm_offset; data_size = _data_size; } void* Set( - void* cmd, GLuint _shader, GLsizei _count, uint32 _data_shm_id, - uint32 _data_shm_offset, uint32 _data_size) { + void* cmd, GLuint _shader, uint32 _data_shm_id, uint32 _data_shm_offset, + uint32 _data_size) { static_cast<ValueType*>( - cmd)->Init( - _shader, _count, _data_shm_id, _data_shm_offset, _data_size); + cmd)->Init(_shader, _data_shm_id, _data_shm_offset, _data_size); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; uint32 shader; - int32 count; uint32 data_shm_id; uint32 data_shm_offset; uint32 data_size; }; -COMPILE_ASSERT(sizeof(ShaderSource) == 24, - Sizeof_ShaderSource_is_not_24); +COMPILE_ASSERT(sizeof(ShaderSource) == 20, + Sizeof_ShaderSource_is_not_20); COMPILE_ASSERT(offsetof(ShaderSource, header) == 0, OffsetOf_ShaderSource_header_not_0); COMPILE_ASSERT(offsetof(ShaderSource, shader) == 4, OffsetOf_ShaderSource_shader_not_4); -COMPILE_ASSERT(offsetof(ShaderSource, count) == 8, - OffsetOf_ShaderSource_count_not_8); -COMPILE_ASSERT(offsetof(ShaderSource, data_shm_id) == 12, - OffsetOf_ShaderSource_data_shm_id_not_12); -COMPILE_ASSERT(offsetof(ShaderSource, data_shm_offset) == 16, - OffsetOf_ShaderSource_data_shm_offset_not_16); -COMPILE_ASSERT(offsetof(ShaderSource, data_size) == 20, - OffsetOf_ShaderSource_data_size_not_20); +COMPILE_ASSERT(offsetof(ShaderSource, data_shm_id) == 8, + OffsetOf_ShaderSource_data_shm_id_not_8); +COMPILE_ASSERT(offsetof(ShaderSource, data_shm_offset) == 12, + OffsetOf_ShaderSource_data_shm_offset_not_12); +COMPILE_ASSERT(offsetof(ShaderSource, data_size) == 16, + OffsetOf_ShaderSource_data_size_not_16); struct ShaderSourceImmediate { typedef ShaderSourceImmediate ValueType; @@ -4981,36 +4976,32 @@ struct ShaderSourceImmediate { header.SetCmdByTotalSize<ValueType>(size_in_bytes); } - void Init(GLuint _shader, GLsizei _count, uint32 _data_size) { + void Init(GLuint _shader, uint32 _data_size) { uint32 total_size = ComputeSize(_data_size); SetHeader(total_size); shader = _shader; - count = _count; data_size = _data_size; } - void* Set(void* cmd, GLuint _shader, GLsizei _count, uint32 _data_size) { + void* Set(void* cmd, GLuint _shader, uint32 _data_size) { uint32 total_size = ComputeSize(_data_size); - static_cast<ValueType*>(cmd)->Init(_shader, _count, _data_size); + static_cast<ValueType*>(cmd)->Init(_shader, _data_size); return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); } gpu::CommandHeader header; uint32 shader; - int32 count; uint32 data_size; }; -COMPILE_ASSERT(sizeof(ShaderSourceImmediate) == 16, - Sizeof_ShaderSourceImmediate_is_not_16); +COMPILE_ASSERT(sizeof(ShaderSourceImmediate) == 12, + Sizeof_ShaderSourceImmediate_is_not_12); COMPILE_ASSERT(offsetof(ShaderSourceImmediate, header) == 0, OffsetOf_ShaderSourceImmediate_header_not_0); COMPILE_ASSERT(offsetof(ShaderSourceImmediate, shader) == 4, OffsetOf_ShaderSourceImmediate_shader_not_4); -COMPILE_ASSERT(offsetof(ShaderSourceImmediate, count) == 8, - OffsetOf_ShaderSourceImmediate_count_not_8); -COMPILE_ASSERT(offsetof(ShaderSourceImmediate, data_size) == 12, - OffsetOf_ShaderSourceImmediate_data_size_not_12); +COMPILE_ASSERT(offsetof(ShaderSourceImmediate, data_size) == 8, + OffsetOf_ShaderSourceImmediate_data_size_not_8); struct StencilFunc { typedef StencilFunc ValueType; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index ed27296..949cb77 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -1828,20 +1828,18 @@ TEST(GLES2FormatTest, ShaderSource) { void* next_cmd = cmd.Set( &cmd, static_cast<GLuint>(11), - static_cast<GLsizei>(12), + static_cast<uint32>(12), static_cast<uint32>(13), - static_cast<uint32>(14), - static_cast<uint32>(15)); + static_cast<uint32>(14)); EXPECT_EQ(static_cast<uint32>(ShaderSource::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); EXPECT_EQ(static_cast<char*>(next_cmd), reinterpret_cast<char*>(&cmd) + sizeof(cmd)); EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); - EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); - EXPECT_EQ(static_cast<uint32>(13), cmd.data_shm_id); - EXPECT_EQ(static_cast<uint32>(14), cmd.data_shm_offset); - EXPECT_EQ(static_cast<uint32>(15), cmd.data_size); + EXPECT_EQ(static_cast<uint32>(12), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.data_shm_offset); + EXPECT_EQ(static_cast<uint32>(14), cmd.data_size); } // TODO(gman): Implement test for ShaderSourceImmediate diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 81c3a66..1b2830e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -541,6 +541,72 @@ void ProgramManager::RemoveProgramInfo(GLuint program) { } } +// Tracks the Shaders. +// +// NOTE: To support shared resources an instance of this class will +// need to be shared by multiple GLES2Decoders. +class ShaderManager { + public: + // This is used to keep the source code for a shader. This is because in order + // to emluate GLES2 the shaders will have to be re-written before passed to + // the underlying OpenGL. But, when the user calls glGetShaderSource they + // should get the source they passed in, not the re-written source. + class ShaderInfo { + public: + explicit ShaderInfo(GLuint shader) + : shader_(shader) { + } + + void Update(const std::string& source) { + source_ = source; + } + + const std::string& source() { + return source_; + } + + private: + // The shader this ShaderInfo is tracking. + GLuint shader_; + + // The shader source as passed to glShaderSource. + std::string source_; + }; + + // Creates a shader info for the given shader ID. + void CreateShaderInfo(GLuint shader); + + // Gets an existing shader info for the given shader ID. Returns NULL if none + // exists. + ShaderInfo* GetShaderInfo(GLuint shader); + + // Deletes the shader info for the given shader. + void RemoveShaderInfo(GLuint shader); + + private: + // Info for each shader by service side shader Id. + typedef std::map<GLuint, ShaderInfo> ShaderInfoMap; + ShaderInfoMap shader_infos_; +}; + +void ShaderManager::CreateShaderInfo(GLuint shader) { + std::pair<ShaderInfoMap::iterator, bool> result = + shader_infos_.insert(std::make_pair(shader, ShaderInfo(shader))); + DCHECK(result.second); +} + +ShaderManager::ShaderInfo* ShaderManager::GetShaderInfo(GLuint shader) { + ShaderInfoMap::iterator it = shader_infos_.find(shader); + return it != shader_infos_.end() ? &it->second : NULL; +} + +void ShaderManager::RemoveShaderInfo(GLuint shader) { + ShaderInfoMap::iterator it = shader_infos_.find(shader); + if (it != shader_infos_.end()) { + shader_infos_.erase(it); + } +} + // This class implements GLES2Decoder so we don't have to expose all the GLES2 // cmd stuff to outside this class. class GLES2DecoderImpl : public GLES2Decoder { @@ -720,6 +786,25 @@ class GLES2DecoderImpl : public GLES2Decoder { program_manager_->RemoveProgramInfo(program); } + // Creates a ShaderInfo for the given shader. + void CreateShaderInfo(GLuint shader) { + shader_manager_->CreateShaderInfo(shader); + } + + // Gets the shader info for the given shader. Returns NULL if none exists. + ShaderManager::ShaderInfo* GetShaderInfo(GLuint shader) { + return shader_manager_->GetShaderInfo(shader); + } + + // Deletes the shader info for the given shader. + void RemoveShaderInfo(GLuint shader) { + shader_manager_->RemoveShaderInfo(shader); + } + + // Helper for glShaderSource. + error::Error ShaderSourceHelper( + GLuint shader, const char* data, uint32 data_size); + // Gets the buffer info for the given buffer. BufferManager::BufferInfo* GetBufferInfo(GLuint buffer) { return buffer_manager_->GetBufferInfo(buffer); @@ -737,6 +822,9 @@ class GLES2DecoderImpl : public GLES2Decoder { // Wrapper for glBindBuffer since we need to track the current targets. void DoBindBuffer(GLenum target, GLuint buffer); + // Wrapper for glCompileShader. + void DoCompileShader(GLuint shader); + // Wrapper for glDrawArrays. void DoDrawArrays(GLenum mode, GLint first, GLsizei count); @@ -746,6 +834,10 @@ class GLES2DecoderImpl : public GLES2Decoder { // Wrapper for glEnableVertexAttribArray. void DoEnableVertexAttribArray(GLuint index); + // Wrapper for glGetShaderSource. + void DoGetShaderSource( + GLuint shader, GLsizei bufsize, GLsizei* length, char* dst); + // Wrapper for glLinkProgram void DoLinkProgram(GLuint program); @@ -830,6 +922,8 @@ class GLES2DecoderImpl : public GLES2Decoder { scoped_ptr<ProgramManager> program_manager_; + scoped_ptr<ShaderManager> shader_manager_; + // The program in use by glUseProgram GLuint current_program_; @@ -896,6 +990,7 @@ bool GLES2DecoderImpl::Initialize() { id_manager_.reset(new IdManager()); buffer_manager_.reset(new BufferManager()); + shader_manager_.reset(new ShaderManager()); program_manager_.reset(new ProgramManager()); if (InitPlatformSpecific()) { @@ -1563,6 +1658,7 @@ void GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { GLuint service_id = glCreateShader(type); if (service_id) { id_manager_->AddMapping(client_id, service_id); + CreateShaderInfo(service_id); } } @@ -1607,6 +1703,7 @@ error::Error GLES2DecoderImpl::HandleDeleteShader( SetGLError(GL_INVALID_VALUE); return error::kNoError; } + RemoveShaderInfo(service_id); glDeleteShader(service_id); id_manager_->RemoveMapping(shader, service_id); return error::kNoError; @@ -1810,39 +1907,23 @@ error::Error GLES2DecoderImpl::HandleDrawElements( return error::kNoError; } -// TODO(kbr): the use of this anonymous namespace core dumps the -// linker on Mac OS X 10.6 when the symbol ordering file is used -// namespace { - // Calls glShaderSource for the various versions of the ShaderSource command. // Assumes that data / data_size points to a piece of memory that is in range // of whatever context it came from (shared memory, immediate memory, bucket // memory.) -error::Error ShaderSourceHelper( - GLuint shader, GLsizei count, const char* data, uint32 data_size) { - std::vector<std::string> strings(count); - scoped_array<const char*> string_pointers(new const char* [count]); - - const uint32* ends = reinterpret_cast<const uint32*>(data); - uint32 start_offset = count * sizeof(*ends); - if (start_offset > data_size) { - return error::kOutOfBounds; - } - for (GLsizei ii = 0; ii < count; ++ii) { - uint32 end_offset = ends[ii]; - if (end_offset > data_size || end_offset < start_offset) { - return error::kOutOfBounds; - } - strings[ii] = std::string(data + start_offset, end_offset - start_offset); - string_pointers[ii] = strings[ii].c_str(); +error::Error GLES2DecoderImpl::ShaderSourceHelper( + GLuint shader, const char* data, uint32 data_size) { + ShaderManager::ShaderInfo* info = GetShaderInfo(shader); + if (!info) { + SetGLError(GL_INVALID_OPERATION); + return error::kNoError; } - - glShaderSource(shader, count, string_pointers.get(), NULL); + // Note: We don't actually call glShaderSource here. We wait until + // the call to glCompileShader. + info->Update(std::string(data, data + data_size)); return error::kNoError; } -// } // anonymous namespace. - error::Error GLES2DecoderImpl::HandleShaderSource( uint32 immediate_data_size, const gles2::ShaderSource& c) { GLuint shader; @@ -1850,15 +1931,13 @@ error::Error GLES2DecoderImpl::HandleShaderSource( SetGLError(GL_INVALID_VALUE); return error::kNoError; } - GLsizei count = c.count; uint32 data_size = c.data_size; - const char** data = GetSharedMemoryAs<const char**>( + const char* data = GetSharedMemoryAs<const char*>( c.data_shm_id, c.data_shm_offset, data_size); if (!data) { return error::kOutOfBounds; } - return ShaderSourceHelper( - shader, count, reinterpret_cast<const char*>(data), data_size); + return ShaderSourceHelper(shader, data, data_size); } error::Error GLES2DecoderImpl::HandleShaderSourceImmediate( @@ -1868,15 +1947,43 @@ error::Error GLES2DecoderImpl::HandleShaderSourceImmediate( SetGLError(GL_INVALID_VALUE); return error::kNoError; } - GLsizei count = c.count; uint32 data_size = c.data_size; - const char** data = GetImmediateDataAs<const char**>( + const char* data = GetImmediateDataAs<const char*>( c, data_size, immediate_data_size); if (!data) { return error::kOutOfBounds; } - return ShaderSourceHelper( - shader, count, reinterpret_cast<const char*>(data), data_size); + return ShaderSourceHelper(shader, data, data_size); +} + +void GLES2DecoderImpl::DoCompileShader(GLuint shader) { + ShaderManager::ShaderInfo* info = GetShaderInfo(shader); + if (!info) { + SetGLError(GL_INVALID_OPERATION); + return; + } + // TODO(gman): Run shader through compiler that converts GL ES 2.0 shader + // to DesktopGL shader and pass that to glShaderSource and then + // glCompileShader. + const char* ptr = info->source().c_str(); + glShaderSource(shader, 1, &ptr, NULL); + glCompileShader(shader); +}; + +void GLES2DecoderImpl::DoGetShaderSource( + GLuint shader, GLsizei bufsize, GLsizei* length, char* dst) { + ShaderManager::ShaderInfo* info = GetShaderInfo(shader); + if (!info) { + SetGLError(GL_INVALID_OPERATION); + return; + } + const std::string& source = info->source(); + GLsizei size = std::min(bufsize - 1, static_cast<GLsizei>(source.size())); + if (length) { + *length = size; + } + memcpy(dst, source.c_str(), size); + dst[size] = '\0'; } error::Error GLES2DecoderImpl::HandleVertexAttribPointer( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index f25512c..4b70cce 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -309,7 +309,7 @@ error::Error GLES2DecoderImpl::HandleCompileShader( SetGLError(GL_INVALID_VALUE); return error::kNoError; } - glCompileShader(shader); + DoCompileShader(shader); return error::kNoError; } @@ -1089,7 +1089,7 @@ error::Error GLES2DecoderImpl::HandleGetShaderSource( if (source == NULL) { return error::kOutOfBounds; } - glGetShaderSource(shader, bufsize, length, source); + DoGetShaderSource(shader, bufsize, length, source); return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 427f360..8e1d410 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -93,7 +93,7 @@ class GLES2DecoderTest : public testing::Test { template <typename T, typename Command> T GetImmediateDataAs(Command* cmd) { - reinterpret_cast<T>(ImmediateDataAddress(cmd)); + return reinterpret_cast<T>(ImmediateDataAddress(cmd)); } void ClearSharedMemory() { @@ -194,6 +194,12 @@ class GLES2DecoderTest : public testing::Test { return reinterpret_cast<T>(shared_memory_address_); } + template <typename T> + T GetSharedMemoryAsWithOffset(uint32 offset) { + void* ptr = reinterpret_cast<int8*>(shared_memory_address_) + offset; + return reinterpret_cast<T>(ptr); + } + uint32 GetServiceId(uint32 client_id) { return decoder_->GetServiceIdForTesting(client_id); } @@ -1308,6 +1314,100 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); } +TEST_F(GLES2DecoderTest, CompileShaderValidArgs) { + EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _)); + EXPECT_CALL(*gl_, CompileShader(kServiceShaderId)); + CompileShader cmd; + cmd.Init(client_shader_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest, CompileShaderInvalidArgs) { + CompileShader cmd; + cmd.Init(kInvalidClientId); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + cmd.Init(client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderTest, ShaderSourceAndGetShaderSourceValidArgs) { + const char kSource[] = "hello"; + const uint32 kSourceSize = sizeof(kSource) - 1; + memcpy(shared_memory_address_, kSource, kSourceSize); + ShaderSource cmd; + cmd.Init(client_shader_id_, + kSharedMemoryId, kSharedMemoryOffset, kSourceSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + memset(shared_memory_address_, 0, kSourceSize); + // TODO(gman): GetShaderSource has to change format so result is always set. + GetShaderSource get_cmd; + get_cmd.Init(client_shader_id_, kSourceSize + 1, + kSharedMemoryId, kSharedMemoryOffset, + kSharedMemoryId, kSharedMemoryOffset + sizeof(kSourceSize)); + EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd)); + EXPECT_EQ(kSourceSize, *GetSharedMemoryAs<uint32*>()); + EXPECT_EQ(0, memcmp(GetSharedMemoryAsWithOffset<void*>(sizeof(kSourceSize)), + kSource, kSourceSize)); +} + +TEST_F(GLES2DecoderTest, ShaderSourceInvalidArgs) { + const char kSource[] = "hello"; + const uint32 kSourceSize = sizeof(kSource) - 1; + memcpy(shared_memory_address_, kSource, kSourceSize); + ShaderSource cmd; + cmd.Init(kInvalidClientId, + kSharedMemoryId, kSharedMemoryOffset, kSourceSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + cmd.Init(client_texture_id_, + kSharedMemoryId, kSharedMemoryOffset, kSourceSize); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + cmd.Init(client_shader_id_, + kInvalidSharedMemoryId, kSharedMemoryOffset, kSourceSize); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_shader_id_, + kSharedMemoryId, kInvalidSharedMemoryOffset, kSourceSize); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_shader_id_, + kSharedMemoryId, kSharedMemoryOffset, kSharedBufferSize); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderTest, ShaderSourceImmediateAndGetShaderSourceValidArgs) { + const char kSource[] = "hello"; + const uint32 kSourceSize = sizeof(kSource) - 1; + ShaderSourceImmediate& cmd = *GetImmediateAs<ShaderSourceImmediate>(); + cmd.Init(client_shader_id_, kSourceSize); + memcpy(GetImmediateDataAs<void*>(&cmd), kSource, kSourceSize); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kSourceSize)); + memset(shared_memory_address_, 0, kSourceSize); + // TODO(gman): GetShaderSource has to change format so result is always set. + GetShaderSource get_cmd; + get_cmd.Init(client_shader_id_, kSourceSize + 1, + kSharedMemoryId, kSharedMemoryOffset, + kSharedMemoryId, kSharedMemoryOffset + sizeof(kSourceSize)); + EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd)); + EXPECT_EQ(kSourceSize, *GetSharedMemoryAs<uint32*>()); + EXPECT_EQ(0, memcmp(GetSharedMemoryAsWithOffset<void*>(sizeof(kSourceSize)), + kSource, kSourceSize)); +} + +TEST_F(GLES2DecoderTest, ShaderSourceImmediateInvalidArgs) { + const char kSource[] = "hello"; + const uint32 kSourceSize = sizeof(kSource) - 1; + ShaderSourceImmediate& cmd = *GetImmediateAs<ShaderSourceImmediate>(); + cmd.Init(kInvalidClientId, kSourceSize); + memcpy(GetImmediateDataAs<void*>(&cmd), kSource, kSourceSize); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kSourceSize)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + cmd.Init(client_texture_id_, kSourceSize); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, kSourceSize)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + // TODO(gman): BindAttribLocation // TODO(gman): BindAttribLocationImmediate @@ -1344,10 +1444,6 @@ TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) { // TODO(gman): ReadPixels -// TODO(gman): ShaderSource - -// TODO(gman): ShaderSourceImmediate - #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h" } // namespace gles2 diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h index 1675153..905a451 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h @@ -229,14 +229,7 @@ TEST_F(GLES2DecoderTest, ColorMaskValidArgs) { cmd.Init(1, 2, 3, 4); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } - -TEST_F(GLES2DecoderTest, CompileShaderValidArgs) { - EXPECT_CALL(*gl_, CompileShader(kServiceShaderId)); - SpecializedSetup<CompileShader, 0>(); - CompileShader cmd; - cmd.Init(client_shader_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); -} +// TODO(gman): CompileShader // TODO(gman): CompressedTexImage2D // TODO(gman): CompressedTexImage2DImmediate |