diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 23:02:25 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 23:02:25 +0000 |
commit | 0bfd9882d39c63727676616ef1401d7618fdd26c (patch) | |
tree | f81bccc6d5a6f652cb600d5b61fa95b72181a513 /gpu | |
parent | ed0cf569f40ba5e11402c691c6bef6304d3d45c6 (diff) | |
download | chromium_src-0bfd9882d39c63727676616ef1401d7618fdd26c.zip chromium_src-0bfd9882d39c63727676616ef1401d7618fdd26c.tar.gz chromium_src-0bfd9882d39c63727676616ef1401d7618fdd26c.tar.bz2 |
Adds
glGetActiveAttrib
glGetActiveUniform
glGetAttachedShaders
glGetShaderPrecision
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/577017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38270 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
16 files changed, 1359 insertions, 507 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 5988631..92fe5b9 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -101,7 +101,7 @@ GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLidProgram program, GL GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenumRenderBufferTarget target, GLenumRenderBufferParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetShaderiv (GLidShader shader, GLenumShaderParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLidShader shader, GLsizei bufsize, GLsizei* length, char* infolog); -GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenumShaderType shadertype, GLenumShaderPercision precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenumShaderType shadertype, GLenumShaderPrecision precisiontype, GLint* range, GLint* precision); GL_APICALL void GL_APIENTRY glGetShaderSource (GLidShader shader, GLsizei bufsize, GLsizei* length, char* source); GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenumStringType name); GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenumTextureTarget target, GLenumTextureParameter pname, GLfloat* params); @@ -620,7 +620,7 @@ _ENUM_LISTS = { 'GL_SHADER_SOURCE_LENGTH', ], }, - 'ShaderPercision': { + 'ShaderPrecision': { 'type': 'GLenum', 'valid': [ 'GL_LOW_FLOAT', @@ -877,9 +877,36 @@ _FUNCTION_INFO = { 'GenFramebuffers': {'type': 'GENn', 'gl_test_func': 'glGenFramebuffersEXT'}, 'GenRenderbuffers': {'type': 'GENn', 'gl_test_func': 'glGenRenderbuffersEXT'}, 'GenTextures': {'type': 'GENn', 'gl_test_func': 'glGenTextures'}, - 'GetActiveAttrib': {'type': 'Custom'}, - 'GetActiveUniform': {'type': 'Custom'}, - 'GetAttachedShaders': {'type': 'Custom'}, + 'GetActiveAttrib': { + 'type': 'Custom', + 'immediate': False, + 'cmd_args': + 'GLidProgram program, GLuint index, uint32 name_bucket_id, ' + 'void* result', + 'result': [ + 'int32 success', + 'int32 size', + 'int32 type', + ], + }, + 'GetActiveUniform': { + 'type': 'Custom', + 'immediate': False, + 'cmd_args': + 'GLidProgram program, GLuint index, uint32 name_bucket_id, ' + 'void* result', + 'result': [ + 'int32 success', + 'int32 size', + 'int32 type', + ], + }, + 'GetAttachedShaders': { + 'type': 'Custom', + 'immediate': False, + 'cmd_args': 'GLidProgram program, void* result, uint32 result_size', + 'result': ['SizedResult<GLuint>'], + }, 'GetAttribLocation': { 'type': 'HandWritten', 'immediate': True, @@ -904,12 +931,32 @@ _FUNCTION_INFO = { }, 'GetShaderiv': {'type': 'GETn'}, 'GetShaderInfoLog': {'type': 'STRn'}, - 'GetShaderPrecisionFormat': {'type': 'Custom'}, + 'GetShaderPrecisionFormat': { + 'type': 'Custom', + 'immediate': False, + 'cmd_args': + 'GLenumShaderType shadertype, GLenumShaderPrecision precisiontype, ' + 'void* result', + 'result': [ + 'int32 success', + 'int32 min_range', + 'int32 max_range', + 'int32 precision', + ], + }, 'GetShaderSource': {'type': 'STRn'}, 'GetTexParameterfv': {'type': 'GETn'}, 'GetTexParameteriv': {'type': 'GETn'}, - 'GetUniformfv': {'type': 'Custom', 'immediate': False}, - 'GetUniformiv': {'type': 'Custom', 'immediate': False}, + 'GetUniformfv': { + 'type': 'Custom', + 'immediate': False, + 'result': ['SizedResult<GLfloat>'], + }, + 'GetUniformiv': { + 'type': 'Custom', + 'immediate': False, + 'result': ['SizedResult<GLint>'], + }, 'GetUniformLocation': { 'type': 'HandWritten', 'immediate': True, @@ -919,7 +966,11 @@ _FUNCTION_INFO = { }, 'GetVertexAttribfv': {'type': 'GETn'}, 'GetVertexAttribiv': {'type': 'GETn'}, - 'GetVertexAttribPointerv': {'type': 'Custom', 'immediate': False}, + 'GetVertexAttribPointerv': { + 'type': 'Custom', + 'immediate': False, + 'result': ['SizedResult<GLuint>'], + }, 'IsBuffer': {'type': 'Is'}, 'IsEnabled': {'type': 'Is'}, 'IsFramebuffer': {'type': 'Is', 'DecoderFunc': 'glIsFramebufferEXT'}, @@ -1019,7 +1070,10 @@ class CWriter(object): i = self.__FindSplit(line) if i > 0: line1 = line[0:i + 1] - self.file.write(line1 + '\n') + nolint = '' + if len(line1) > 80: + nolint = ' // NOLINT' + self.file.write(line1 + nolint + '\n') match = re.match("( +)", line1) indent = "" if match: @@ -1029,7 +1083,10 @@ class CWriter(object): indent = " " + indent self.__WriteLine(indent + line[i + 1:].lstrip(), True) return - self.file.write(line) + nolint = '' + if len(line) > 80: + nolint = ' // NOLINT' + self.file.write(line + nolint) if ends_with_eol: self.file.write('\n') @@ -1090,6 +1147,15 @@ class TypeHandler(object): file.Write(" static const CommandId kCmdId = k%s;\n" % func.name) func.WriteCmdArgFlag(file) file.Write("\n") + result = func.GetInfo('result') + if not result == None: + if len(result) == 1: + file.Write(" typedef %s Result;\n\n" % result[0]) + else: + file.Write(" struct Result {\n") + for line in result: + file.Write(" %s;\n" % line) + file.Write(" };\n\n") func.WriteCmdComputeSize(file) func.WriteCmdSetHeader(file) @@ -1115,6 +1181,21 @@ class TypeHandler(object): file.Write(" OffsetOf_%s_%s_not_%d);\n" % (func.name, arg.name, offset)) offset += _SIZE_OF_UINT32 + if not result == None and len(result) > 1: + offset = 0; + for line in result: + parts = line.split() + name = parts[-1] + check = """ +COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d, + OffsetOf_%(cmd_name)s_Result_%(field_name)s_not_%(offset)d); +""" + file.Write((check.strip() + "\n") % { + 'cmd_name': func.name, + 'field_name': name, + 'offset': offset, + }) + offset += _SIZE_OF_UINT32 file.Write("\n") def WriteHandlerImplementation(self, func, file): diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h index 72984d1..c65a23a 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/gpu/command_buffer/client/cmd_buffer_helper.h @@ -117,6 +117,78 @@ class CommandBufferHelper { cmd.Init(token); } + void Jump(uint32 offset) { + cmd::Jump& cmd = GetCmdSpace<cmd::Jump>(); + cmd.Init(offset); + } + + void JumpRelative(int32 offset) { + cmd::JumpRelative& cmd = GetCmdSpace<cmd::JumpRelative>(); + cmd.Init(offset); + } + + void Call(uint32 offset) { + cmd::Call& cmd = GetCmdSpace<cmd::Call>(); + cmd.Init(offset); + } + + void CallRelative(int32 offset) { + cmd::CallRelative& cmd = GetCmdSpace<cmd::CallRelative>(); + cmd.Init(offset); + } + + void Return() { + cmd::Return& cmd = GetCmdSpace<cmd::Return>(); + cmd.Init(); + } + + void SetBucketSize(uint32 bucket_id, uint32 size) { + cmd::SetBucketSize& cmd = GetCmdSpace<cmd::SetBucketSize>(); + cmd.Init(bucket_id, size); + } + + void SetBucketData(uint32 bucket_id, + uint32 offset, + uint32 size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + cmd::SetBucketData& cmd = GetCmdSpace<cmd::SetBucketData>(); + cmd.Init(bucket_id, + offset, + size, + shared_memory_id, + shared_memory_offset); + } + + void SetBucketDataImmediate( + uint32 bucket_id, uint32 offset, const void* data, uint32 size) { + cmd::SetBucketDataImmediate& cmd = + GetImmediateCmdSpace<cmd::SetBucketDataImmediate>(size); + cmd.Init(bucket_id, offset, size); + memcpy(ImmediateDataAddress(&cmd), data, size); + } + + void GetBucketSize(uint32 bucket_id, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + cmd::GetBucketSize& cmd = GetCmdSpace<cmd::GetBucketSize>(); + cmd.Init(bucket_id, + shared_memory_id, + shared_memory_offset); + } + + void GetBucketData(uint32 bucket_id, + uint32 offset, + uint32 size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + cmd::GetBucketData& cmd = GetCmdSpace<cmd::GetBucketData>(); + cmd.Init(bucket_id, + offset, + size, + shared_memory_id, + shared_memory_offset); + } private: // Waits until get changes, updating the value of get_. diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 66eea9d..5e63eb8 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -425,37 +425,24 @@ } void GetActiveAttrib( - GLuint program, GLuint index, GLsizei bufsize, uint32 length_shm_id, - uint32 length_shm_offset, uint32 size_shm_id, uint32 size_shm_offset, - uint32 type_shm_id, uint32 type_shm_offset, uint32 name_shm_id, - uint32 name_shm_offset) { + GLuint program, GLuint index, uint32 name_bucket_id, uint32 result_shm_id, + uint32 result_shm_offset) { gles2::GetActiveAttrib& c = GetCmdSpace<gles2::GetActiveAttrib>(); - c.Init( - program, index, bufsize, length_shm_id, length_shm_offset, size_shm_id, - size_shm_offset, type_shm_id, type_shm_offset, name_shm_id, - name_shm_offset); + c.Init(program, index, name_bucket_id, result_shm_id, result_shm_offset); } void GetActiveUniform( - GLuint program, GLuint index, GLsizei bufsize, uint32 length_shm_id, - uint32 length_shm_offset, uint32 size_shm_id, uint32 size_shm_offset, - uint32 type_shm_id, uint32 type_shm_offset, uint32 name_shm_id, - uint32 name_shm_offset) { + GLuint program, GLuint index, uint32 name_bucket_id, uint32 result_shm_id, + uint32 result_shm_offset) { gles2::GetActiveUniform& c = GetCmdSpace<gles2::GetActiveUniform>(); - c.Init( - program, index, bufsize, length_shm_id, length_shm_offset, size_shm_id, - size_shm_offset, type_shm_id, type_shm_offset, name_shm_id, - name_shm_offset); + c.Init(program, index, name_bucket_id, result_shm_id, result_shm_offset); } void GetAttachedShaders( - GLuint program, GLsizei maxcount, uint32 count_shm_id, - uint32 count_shm_offset, uint32 shaders_shm_id, - uint32 shaders_shm_offset) { + GLuint program, uint32 result_shm_id, uint32 result_shm_offset, + uint32 result_size) { gles2::GetAttachedShaders& c = GetCmdSpace<gles2::GetAttachedShaders>(); - c.Init( - program, maxcount, count_shm_id, count_shm_offset, shaders_shm_id, - shaders_shm_offset); + c.Init(program, result_shm_id, result_shm_offset, result_size); } void GetBooleanv( @@ -540,14 +527,11 @@ } void GetShaderPrecisionFormat( - GLenum shadertype, GLenum precisiontype, uint32 range_shm_id, - uint32 range_shm_offset, uint32 precision_shm_id, - uint32 precision_shm_offset) { + GLenum shadertype, GLenum precisiontype, uint32 result_shm_id, + uint32 result_shm_offset) { gles2::GetShaderPrecisionFormat& c = GetCmdSpace<gles2::GetShaderPrecisionFormat>(); - c.Init( - shadertype, precisiontype, range_shm_id, range_shm_offset, - precision_shm_id, precision_shm_offset); + c.Init(shadertype, precisiontype, result_shm_id, result_shm_offset); } void GetShaderSource( diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 8ea20ab..edeb1fa 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -54,15 +54,71 @@ void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) { } } -void GLES2Implementation::CopyResult(void* dst) { - SizedResult* result = static_cast<SizedResult*>(result_buffer_); - memcpy(dst, result->GetDataAs<void*>(), result->size); -} - void GLES2Implementation::WaitForCmd() { helper_->CommandBufferHelper::Finish(); } +void GLES2Implementation::GetBucketContents(uint32 bucket_id, + std::vector<int8>* data) { + DCHECK(data); + helper_->GetBucketSize(bucket_id, result_shm_id(), result_shm_offset()); + WaitForCmd(); + uint32 size = GetResultAs<cmd::GetBucketSize::Result>(); + data->resize(size); + if (size > 0u) { + uint32 max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); + uint32 offset = 0; + while (size) { + uint32 part_size = std::min(max_size, size); + void* buffer = transfer_buffer_.Alloc(part_size); + helper_->GetBucketData( + bucket_id, offset, part_size, + transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); + WaitForCmd(); + memcpy(&(*data)[offset], buffer, part_size); + transfer_buffer_.Free(buffer); + offset += part_size; + size -= part_size; + } + // Free the bucket. This is not required but it does free up the memory. + // and we don't have to wait for the result so from the client's perspective + // it's cheap. + helper_->SetBucketSize(bucket_id, 0); + } +} + +void GLES2Implementation::SetBucketContents( + uint32 bucket_id, const void* data, size_t size) { + DCHECK(data); + helper_->SetBucketSize(bucket_id, size); + if (size > 0u) { + uint32 max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); + uint32 offset = 0; + while (size) { + uint32 part_size = std::min(static_cast<size_t>(max_size), size); + void* buffer = transfer_buffer_.Alloc(part_size); + memcpy(buffer, static_cast<const int8*>(data) + offset, part_size); + helper_->SetBucketData( + bucket_id, offset, part_size, + transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); + transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); + offset += part_size; + size -= part_size; + } + } +} + +std::string GLES2Implementation::GetBucketAsString(uint32 bucket_id) { + std::vector<int8> data; + GetBucketContents(bucket_id, &data); + return std::string(reinterpret_cast<char*>(&data[0]), data.size()); +} + +void GLES2Implementation::SetBucketAsString( + uint32 bucket_id, const std::string& str) { + SetBucketContents(bucket_id, str.c_str(), str.size()); +} + void GLES2Implementation::DrawElements( GLenum mode, GLsizei count, GLenum type, const void* indices) { helper_->DrawElements(mode, count, type, ToGLuint(indices)); @@ -79,7 +135,7 @@ void GLES2Implementation::Flush() { void GLES2Implementation::Finish() { // Insert the cmd to call glFinish helper_->Finish(); - // Flinish our command buffer + // Finish our command buffer // (tell the service to execute upto the Finish cmd and wait for it to // execute.) helper_->CommandBufferHelper::Finish(); @@ -95,7 +151,8 @@ void GLES2Implementation::GetVertexAttribPointerv( helper_->GetVertexAttribPointerv( index, pname, result_shm_id(), result_shm_offset()); WaitForCmd(); - CopyResult(ptr); + static_cast<gles2::GetVertexAttribPointerv::Result*>( + result_buffer_)->CopyResult(ptr); }; GLint GLES2Implementation::GetAttribLocation( @@ -299,18 +356,82 @@ GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) { void GLES2Implementation::GetActiveAttrib( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - // TODO(gman): implement. + typedef gles2::GetActiveAttrib::Result Result; + Result* result = static_cast<Result*>(result_buffer_); + helper_->GetActiveAttrib(program, index, kResultBucketId, + result_shm_id(), result_shm_offset()); + WaitForCmd(); + if (result->success) { + if (size) { + *size = result->size; + } + if (type) { + *type = result->type; + } + if (length || name) { + std::vector<int8> str; + GetBucketContents(kResultBucketId, &str); + GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, + str.size()); + if (length) { + *length = max_size; + } + if (name && bufsize > 0) { + memcpy(name, &str[0], max_size); + name[max_size] = '\0'; + } + } + } } void GLES2Implementation::GetActiveUniform( GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - // TODO(gman): implement. + typedef gles2::GetActiveUniform::Result Result; + Result* result = static_cast<Result*>(result_buffer_); + helper_->GetActiveUniform(program, index, kResultBucketId, + result_shm_id(), result_shm_offset()); + WaitForCmd(); + if (result->success) { + if (size) { + *size = result->size; + } + if (type) { + *type = result->type; + } + if (length || name) { + std::vector<int8> str; + GetBucketContents(kResultBucketId, &str); + GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, + str.size()); + if (length) { + *length = max_size; + } + if (name && bufsize > 0) { + memcpy(name, &str[0], max_size); + name[max_size] = '\0'; + } + } + } } void GLES2Implementation::GetAttachedShaders( GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { - // TODO(gman): implement. + typedef gles2::GetAttachedShaders::Result Result; + uint32 size = Result::ComputeSize(maxcount); + Result* result = transfer_buffer_.AllocTyped<Result>(size); + helper_->GetAttachedShaders( + program, + transfer_buffer_id_, + transfer_buffer_.GetOffset(result), + size); + int32 token = helper_->InsertToken(); + WaitForCmd(); + if (count) { + *count = result->GetNumResults(); + } + result->CopyResult(shaders); + transfer_buffer_.FreePendingToken(result, token); } void GLES2Implementation::GetProgramInfoLog( @@ -325,7 +446,20 @@ void GLES2Implementation::GetShaderInfoLog( void GLES2Implementation::GetShaderPrecisionFormat( GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { - // TODO(gman): implement. + typedef gles2::GetShaderPrecisionFormat::Result Result; + Result* result = static_cast<Result*>(result_buffer_); + helper_->GetShaderPrecisionFormat( + shadertype, precisiontype, result_shm_id(), result_shm_offset()); + WaitForCmd(); + if (result->success) { + if (range) { + range[0] = result->min_range; + range[1] = result->max_range; + } + if (precision) { + precision[0] = result->precision; + } + } } void GLES2Implementation::GetShaderSource( @@ -343,7 +477,7 @@ void GLES2Implementation::GetUniformfv( helper_->GetUniformfv( program, location, result_shm_id(), result_shm_offset()); WaitForCmd(); - CopyResult(params); + static_cast<gles2::GetUniformfv::Result*>(result_buffer_)->CopyResult(params); } void GLES2Implementation::GetUniformiv( @@ -351,7 +485,7 @@ void GLES2Implementation::GetUniformiv( helper_->GetUniformiv( program, location, result_shm_id(), result_shm_offset()); WaitForCmd(); - CopyResult(params); + static_cast<gles2::GetUniformfv::Result*>(result_buffer_)->CopyResult(params); } void GLES2Implementation::ReadPixels( diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index ac519f9..579e0d3 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -5,6 +5,8 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_ #define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_ +#include <string> +#include <vector> #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/id_allocator.h" @@ -63,14 +65,28 @@ class GLES2Implementation { return *static_cast<T*>(result_buffer_); } - // Copies the result. - void CopyResult(void* dst); - // Waits for all commands to execute. void WaitForCmd(); + // TODO(gman): These bucket functions really seem like they belong in + // CommandBufferHelper (or maybe BucketHelper?). Unfortunately they need + // a transfer buffer to function which is currently managed by this class. + + // Gets the contents of a bucket. + void GetBucketContents(uint32 bucket_id, std::vector<int8>* data); + + // Sets the contents of a bucket. + void SetBucketContents(uint32 bucket_id, const void* data, size_t size); + + // Gets the contents of a bucket as a string. + std::string GetBucketAsString(uint32 bucket_id); + + // Sets the contents of a bucket as a string. + void SetBucketAsString(uint32 bucket_id, const std::string& str); + // The maxiumum result size from simple GL get commands. - static const size_t kMaxSizeOfSimpleResult = 4 * sizeof(uint32); // NOLINT. + static const size_t kMaxSizeOfSimpleResult = 16 * sizeof(uint32); // NOLINT. + static const uint32 kResultBucketId = 1; GLES2Util util_; GLES2CmdHelper* helper_; diff --git a/gpu/command_buffer/common/cmd_buffer_common.h b/gpu/command_buffer/common/cmd_buffer_common.h index 5b23620..222b440 100644 --- a/gpu/command_buffer/common/cmd_buffer_common.h +++ b/gpu/command_buffer/common/cmd_buffer_common.h @@ -541,6 +541,8 @@ struct GetBucketSize { static const CommandId kCmdId = kGetBucketSize; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + typedef uint32 Result; + void SetHeader() { header.SetCmd<ValueType>(); } diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h index d6d3beb..c642892 100644 --- a/gpu/command_buffer/common/gles2_cmd_format.h +++ b/gpu/command_buffer/common/gles2_cmd_format.h @@ -13,12 +13,12 @@ #if defined(UNIT_TEST) #include "gpu/command_buffer/service/gl_mock.h" #elif defined(GLES2_GPU_SERVICE) -#include <GL/glew.h> +#include <GL/glew.h> // NOLINT #if defined(OS_WIN) -#include <GL/wglew.h> +#include <GL/wglew.h> // NOLINT #endif #else -#include <GLES2/gl2types.h> +#include <GLES2/gl2types.h> // NOLINT #endif #include "base/basictypes.h" @@ -35,25 +35,52 @@ namespace gles2 { // Used for some glGetXXX commands that return a result through a pointer. We // need to know if the command succeeded or not and the size of the result. If // the command failed its result size will 0. +template <typename T> struct SizedResult { - template <typename T> - T GetDataAs() { - return static_cast<T>(static_cast<void*>(&data)); + T* GetData() { + 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 + // Returns the total size in bytes of the SizedResult for a given number of + // results including the size field. + static size_t ComputeSize(size_t num_results) { + return sizeof(T) * num_results + sizeof(uint32); // NOLINT + } + + // Returns the total size in bytes of the SizedResult for a given size of + // results. + static size_t ComputeSizeFromBytes(size_t size_of_result_in_bytes) { + return size_of_result_in_bytes + sizeof(uint32); // NOLINT + } + + // Returns the maximum number of results for a given buffer size. + static uint32 ComputeMaxResults(size_t size_of_buffer) { + return (size_of_buffer - sizeof(uint32)) / sizeof(T); // NOLINT + } + + // Set the size for a given number of results. + void SetNumResults(size_t num_results) { + size = sizeof(T) * num_results; // NOLINT + } + + // Get the number of elements in the result + int32 GetNumResults() const { + return size / sizeof(T); // NOLINT + } + + // Copy the result. + void CopyResult(void* dst) const { + memcpy(dst, &data, size); } 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, +COMPILE_ASSERT(sizeof(SizedResult<int8>) == 8, SizedResult_size_not_8); +COMPILE_ASSERT(offsetof(SizedResult<int8>, size) == 0, OffsetOf_SizedResult_size_not_0); -COMPILE_ASSERT(offsetof(SizedResult, data) == 4, +COMPILE_ASSERT(offsetof(SizedResult<int8>, data) == 4, OffsetOf_SizedResult_data_not_4); #include "gpu/command_buffer/common/gles2_cmd_format_autogen.h" diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 868fac1..d07c475 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -2930,6 +2930,12 @@ struct GetActiveAttrib { static const CommandId kCmdId = kGetActiveAttrib; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + struct Result { + int32 success; + int32 size; + int32 type; + }; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -2939,83 +2945,66 @@ struct GetActiveAttrib { } void Init( - GLuint _program, GLuint _index, GLsizei _bufsize, uint32 _length_shm_id, - uint32 _length_shm_offset, uint32 _size_shm_id, uint32 _size_shm_offset, - uint32 _type_shm_id, uint32 _type_shm_offset, uint32 _name_shm_id, - uint32 _name_shm_offset) { + GLuint _program, GLuint _index, uint32 _name_bucket_id, + uint32 _result_shm_id, uint32 _result_shm_offset) { SetHeader(); program = _program; index = _index; - bufsize = _bufsize; - length_shm_id = _length_shm_id; - length_shm_offset = _length_shm_offset; - size_shm_id = _size_shm_id; - size_shm_offset = _size_shm_offset; - type_shm_id = _type_shm_id; - type_shm_offset = _type_shm_offset; - name_shm_id = _name_shm_id; - name_shm_offset = _name_shm_offset; + name_bucket_id = _name_bucket_id; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; } void* Set( - void* cmd, GLuint _program, GLuint _index, GLsizei _bufsize, - uint32 _length_shm_id, uint32 _length_shm_offset, uint32 _size_shm_id, - uint32 _size_shm_offset, uint32 _type_shm_id, uint32 _type_shm_offset, - uint32 _name_shm_id, uint32 _name_shm_offset) { + void* cmd, GLuint _program, GLuint _index, uint32 _name_bucket_id, + uint32 _result_shm_id, uint32 _result_shm_offset) { static_cast<ValueType*>( cmd)->Init( - _program, _index, _bufsize, _length_shm_id, _length_shm_offset, - _size_shm_id, _size_shm_offset, _type_shm_id, _type_shm_offset, - _name_shm_id, _name_shm_offset); + _program, _index, _name_bucket_id, _result_shm_id, + _result_shm_offset); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; uint32 program; uint32 index; - int32 bufsize; - uint32 length_shm_id; - uint32 length_shm_offset; - uint32 size_shm_id; - uint32 size_shm_offset; - uint32 type_shm_id; - uint32 type_shm_offset; - uint32 name_shm_id; - uint32 name_shm_offset; + uint32 name_bucket_id; + uint32 result_shm_id; + uint32 result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetActiveAttrib) == 48, - Sizeof_GetActiveAttrib_is_not_48); +COMPILE_ASSERT(sizeof(GetActiveAttrib) == 24, + Sizeof_GetActiveAttrib_is_not_24); COMPILE_ASSERT(offsetof(GetActiveAttrib, header) == 0, OffsetOf_GetActiveAttrib_header_not_0); COMPILE_ASSERT(offsetof(GetActiveAttrib, program) == 4, OffsetOf_GetActiveAttrib_program_not_4); COMPILE_ASSERT(offsetof(GetActiveAttrib, index) == 8, OffsetOf_GetActiveAttrib_index_not_8); -COMPILE_ASSERT(offsetof(GetActiveAttrib, bufsize) == 12, - OffsetOf_GetActiveAttrib_bufsize_not_12); -COMPILE_ASSERT(offsetof(GetActiveAttrib, length_shm_id) == 16, - OffsetOf_GetActiveAttrib_length_shm_id_not_16); -COMPILE_ASSERT(offsetof(GetActiveAttrib, length_shm_offset) == 20, - OffsetOf_GetActiveAttrib_length_shm_offset_not_20); -COMPILE_ASSERT(offsetof(GetActiveAttrib, size_shm_id) == 24, - OffsetOf_GetActiveAttrib_size_shm_id_not_24); -COMPILE_ASSERT(offsetof(GetActiveAttrib, size_shm_offset) == 28, - OffsetOf_GetActiveAttrib_size_shm_offset_not_28); -COMPILE_ASSERT(offsetof(GetActiveAttrib, type_shm_id) == 32, - OffsetOf_GetActiveAttrib_type_shm_id_not_32); -COMPILE_ASSERT(offsetof(GetActiveAttrib, type_shm_offset) == 36, - OffsetOf_GetActiveAttrib_type_shm_offset_not_36); -COMPILE_ASSERT(offsetof(GetActiveAttrib, name_shm_id) == 40, - OffsetOf_GetActiveAttrib_name_shm_id_not_40); -COMPILE_ASSERT(offsetof(GetActiveAttrib, name_shm_offset) == 44, - OffsetOf_GetActiveAttrib_name_shm_offset_not_44); +COMPILE_ASSERT(offsetof(GetActiveAttrib, name_bucket_id) == 12, + OffsetOf_GetActiveAttrib_name_bucket_id_not_12); +COMPILE_ASSERT(offsetof(GetActiveAttrib, result_shm_id) == 16, + OffsetOf_GetActiveAttrib_result_shm_id_not_16); +COMPILE_ASSERT(offsetof(GetActiveAttrib, result_shm_offset) == 20, + OffsetOf_GetActiveAttrib_result_shm_offset_not_20); +COMPILE_ASSERT(offsetof(GetActiveAttrib::Result, success) == 0, + OffsetOf_GetActiveAttrib_Result_success_not_0); +COMPILE_ASSERT(offsetof(GetActiveAttrib::Result, size) == 4, + OffsetOf_GetActiveAttrib_Result_size_not_4); +COMPILE_ASSERT(offsetof(GetActiveAttrib::Result, type) == 8, + OffsetOf_GetActiveAttrib_Result_type_not_8); struct GetActiveUniform { typedef GetActiveUniform ValueType; static const CommandId kCmdId = kGetActiveUniform; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + struct Result { + int32 success; + int32 size; + int32 type; + }; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -3025,83 +3014,62 @@ struct GetActiveUniform { } void Init( - GLuint _program, GLuint _index, GLsizei _bufsize, uint32 _length_shm_id, - uint32 _length_shm_offset, uint32 _size_shm_id, uint32 _size_shm_offset, - uint32 _type_shm_id, uint32 _type_shm_offset, uint32 _name_shm_id, - uint32 _name_shm_offset) { + GLuint _program, GLuint _index, uint32 _name_bucket_id, + uint32 _result_shm_id, uint32 _result_shm_offset) { SetHeader(); program = _program; index = _index; - bufsize = _bufsize; - length_shm_id = _length_shm_id; - length_shm_offset = _length_shm_offset; - size_shm_id = _size_shm_id; - size_shm_offset = _size_shm_offset; - type_shm_id = _type_shm_id; - type_shm_offset = _type_shm_offset; - name_shm_id = _name_shm_id; - name_shm_offset = _name_shm_offset; + name_bucket_id = _name_bucket_id; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; } void* Set( - void* cmd, GLuint _program, GLuint _index, GLsizei _bufsize, - uint32 _length_shm_id, uint32 _length_shm_offset, uint32 _size_shm_id, - uint32 _size_shm_offset, uint32 _type_shm_id, uint32 _type_shm_offset, - uint32 _name_shm_id, uint32 _name_shm_offset) { + void* cmd, GLuint _program, GLuint _index, uint32 _name_bucket_id, + uint32 _result_shm_id, uint32 _result_shm_offset) { static_cast<ValueType*>( cmd)->Init( - _program, _index, _bufsize, _length_shm_id, _length_shm_offset, - _size_shm_id, _size_shm_offset, _type_shm_id, _type_shm_offset, - _name_shm_id, _name_shm_offset); + _program, _index, _name_bucket_id, _result_shm_id, + _result_shm_offset); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; uint32 program; uint32 index; - int32 bufsize; - uint32 length_shm_id; - uint32 length_shm_offset; - uint32 size_shm_id; - uint32 size_shm_offset; - uint32 type_shm_id; - uint32 type_shm_offset; - uint32 name_shm_id; - uint32 name_shm_offset; + uint32 name_bucket_id; + uint32 result_shm_id; + uint32 result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetActiveUniform) == 48, - Sizeof_GetActiveUniform_is_not_48); +COMPILE_ASSERT(sizeof(GetActiveUniform) == 24, + Sizeof_GetActiveUniform_is_not_24); COMPILE_ASSERT(offsetof(GetActiveUniform, header) == 0, OffsetOf_GetActiveUniform_header_not_0); COMPILE_ASSERT(offsetof(GetActiveUniform, program) == 4, OffsetOf_GetActiveUniform_program_not_4); COMPILE_ASSERT(offsetof(GetActiveUniform, index) == 8, OffsetOf_GetActiveUniform_index_not_8); -COMPILE_ASSERT(offsetof(GetActiveUniform, bufsize) == 12, - OffsetOf_GetActiveUniform_bufsize_not_12); -COMPILE_ASSERT(offsetof(GetActiveUniform, length_shm_id) == 16, - OffsetOf_GetActiveUniform_length_shm_id_not_16); -COMPILE_ASSERT(offsetof(GetActiveUniform, length_shm_offset) == 20, - OffsetOf_GetActiveUniform_length_shm_offset_not_20); -COMPILE_ASSERT(offsetof(GetActiveUniform, size_shm_id) == 24, - OffsetOf_GetActiveUniform_size_shm_id_not_24); -COMPILE_ASSERT(offsetof(GetActiveUniform, size_shm_offset) == 28, - OffsetOf_GetActiveUniform_size_shm_offset_not_28); -COMPILE_ASSERT(offsetof(GetActiveUniform, type_shm_id) == 32, - OffsetOf_GetActiveUniform_type_shm_id_not_32); -COMPILE_ASSERT(offsetof(GetActiveUniform, type_shm_offset) == 36, - OffsetOf_GetActiveUniform_type_shm_offset_not_36); -COMPILE_ASSERT(offsetof(GetActiveUniform, name_shm_id) == 40, - OffsetOf_GetActiveUniform_name_shm_id_not_40); -COMPILE_ASSERT(offsetof(GetActiveUniform, name_shm_offset) == 44, - OffsetOf_GetActiveUniform_name_shm_offset_not_44); +COMPILE_ASSERT(offsetof(GetActiveUniform, name_bucket_id) == 12, + OffsetOf_GetActiveUniform_name_bucket_id_not_12); +COMPILE_ASSERT(offsetof(GetActiveUniform, result_shm_id) == 16, + OffsetOf_GetActiveUniform_result_shm_id_not_16); +COMPILE_ASSERT(offsetof(GetActiveUniform, result_shm_offset) == 20, + OffsetOf_GetActiveUniform_result_shm_offset_not_20); +COMPILE_ASSERT(offsetof(GetActiveUniform::Result, success) == 0, + OffsetOf_GetActiveUniform_Result_success_not_0); +COMPILE_ASSERT(offsetof(GetActiveUniform::Result, size) == 4, + OffsetOf_GetActiveUniform_Result_size_not_4); +COMPILE_ASSERT(offsetof(GetActiveUniform::Result, type) == 8, + OffsetOf_GetActiveUniform_Result_type_not_8); struct GetAttachedShaders { typedef GetAttachedShaders ValueType; static const CommandId kCmdId = kGetAttachedShaders; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + typedef SizedResult<GLuint> Result; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -3111,54 +3079,42 @@ struct GetAttachedShaders { } void Init( - GLuint _program, GLsizei _maxcount, uint32 _count_shm_id, - uint32 _count_shm_offset, uint32 _shaders_shm_id, - uint32 _shaders_shm_offset) { + GLuint _program, uint32 _result_shm_id, uint32 _result_shm_offset, + uint32 _result_size) { SetHeader(); program = _program; - maxcount = _maxcount; - count_shm_id = _count_shm_id; - count_shm_offset = _count_shm_offset; - shaders_shm_id = _shaders_shm_id; - shaders_shm_offset = _shaders_shm_offset; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + result_size = _result_size; } void* Set( - void* cmd, GLuint _program, GLsizei _maxcount, uint32 _count_shm_id, - uint32 _count_shm_offset, uint32 _shaders_shm_id, - uint32 _shaders_shm_offset) { + void* cmd, GLuint _program, uint32 _result_shm_id, + uint32 _result_shm_offset, uint32 _result_size) { static_cast<ValueType*>( - cmd)->Init( - _program, _maxcount, _count_shm_id, _count_shm_offset, - _shaders_shm_id, _shaders_shm_offset); + cmd)->Init(_program, _result_shm_id, _result_shm_offset, _result_size); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; uint32 program; - int32 maxcount; - uint32 count_shm_id; - uint32 count_shm_offset; - uint32 shaders_shm_id; - uint32 shaders_shm_offset; + uint32 result_shm_id; + uint32 result_shm_offset; + uint32 result_size; }; -COMPILE_ASSERT(sizeof(GetAttachedShaders) == 28, - Sizeof_GetAttachedShaders_is_not_28); +COMPILE_ASSERT(sizeof(GetAttachedShaders) == 20, + Sizeof_GetAttachedShaders_is_not_20); COMPILE_ASSERT(offsetof(GetAttachedShaders, header) == 0, OffsetOf_GetAttachedShaders_header_not_0); COMPILE_ASSERT(offsetof(GetAttachedShaders, program) == 4, OffsetOf_GetAttachedShaders_program_not_4); -COMPILE_ASSERT(offsetof(GetAttachedShaders, maxcount) == 8, - OffsetOf_GetAttachedShaders_maxcount_not_8); -COMPILE_ASSERT(offsetof(GetAttachedShaders, count_shm_id) == 12, - OffsetOf_GetAttachedShaders_count_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetAttachedShaders, count_shm_offset) == 16, - OffsetOf_GetAttachedShaders_count_shm_offset_not_16); -COMPILE_ASSERT(offsetof(GetAttachedShaders, shaders_shm_id) == 20, - OffsetOf_GetAttachedShaders_shaders_shm_id_not_20); -COMPILE_ASSERT(offsetof(GetAttachedShaders, shaders_shm_offset) == 24, - OffsetOf_GetAttachedShaders_shaders_shm_offset_not_24); +COMPILE_ASSERT(offsetof(GetAttachedShaders, result_shm_id) == 8, + OffsetOf_GetAttachedShaders_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(GetAttachedShaders, result_shm_offset) == 12, + OffsetOf_GetAttachedShaders_result_shm_offset_not_12); +COMPILE_ASSERT(offsetof(GetAttachedShaders, result_size) == 16, + OffsetOf_GetAttachedShaders_result_size_not_16); struct GetBooleanv { typedef GetBooleanv ValueType; @@ -3392,10 +3348,10 @@ COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, pname) == 12, OffsetOf_GetFramebufferAttachmentParameteriv_pname_not_12); COMPILE_ASSERT( offsetof(GetFramebufferAttachmentParameteriv, params_shm_id) == 16, - OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_id_not_16); + OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_id_not_16); // NOLINT COMPILE_ASSERT( offsetof(GetFramebufferAttachmentParameteriv, params_shm_offset) == 20, - OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_offset_not_20); + OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_offset_not_20); // NOLINT struct GetIntegerv { typedef GetIntegerv ValueType; @@ -3726,6 +3682,13 @@ struct GetShaderPrecisionFormat { static const CommandId kCmdId = kGetShaderPrecisionFormat; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + struct Result { + int32 success; + int32 min_range; + int32 max_range; + int32 precision; + }; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -3735,54 +3698,51 @@ struct GetShaderPrecisionFormat { } void Init( - GLenum _shadertype, GLenum _precisiontype, uint32 _range_shm_id, - uint32 _range_shm_offset, uint32 _precision_shm_id, - uint32 _precision_shm_offset) { + GLenum _shadertype, GLenum _precisiontype, uint32 _result_shm_id, + uint32 _result_shm_offset) { SetHeader(); shadertype = _shadertype; precisiontype = _precisiontype; - range_shm_id = _range_shm_id; - range_shm_offset = _range_shm_offset; - precision_shm_id = _precision_shm_id; - precision_shm_offset = _precision_shm_offset; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; } void* Set( void* cmd, GLenum _shadertype, GLenum _precisiontype, - uint32 _range_shm_id, uint32 _range_shm_offset, uint32 _precision_shm_id, - uint32 _precision_shm_offset) { + uint32 _result_shm_id, uint32 _result_shm_offset) { static_cast<ValueType*>( cmd)->Init( - _shadertype, _precisiontype, _range_shm_id, _range_shm_offset, - _precision_shm_id, _precision_shm_offset); + _shadertype, _precisiontype, _result_shm_id, _result_shm_offset); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; uint32 shadertype; uint32 precisiontype; - uint32 range_shm_id; - uint32 range_shm_offset; - uint32 precision_shm_id; - uint32 precision_shm_offset; + uint32 result_shm_id; + uint32 result_shm_offset; }; -COMPILE_ASSERT(sizeof(GetShaderPrecisionFormat) == 28, - Sizeof_GetShaderPrecisionFormat_is_not_28); +COMPILE_ASSERT(sizeof(GetShaderPrecisionFormat) == 20, + Sizeof_GetShaderPrecisionFormat_is_not_20); COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, header) == 0, OffsetOf_GetShaderPrecisionFormat_header_not_0); COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, shadertype) == 4, OffsetOf_GetShaderPrecisionFormat_shadertype_not_4); COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precisiontype) == 8, OffsetOf_GetShaderPrecisionFormat_precisiontype_not_8); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, range_shm_id) == 12, - OffsetOf_GetShaderPrecisionFormat_range_shm_id_not_12); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, range_shm_offset) == 16, - OffsetOf_GetShaderPrecisionFormat_range_shm_offset_not_16); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precision_shm_id) == 20, - OffsetOf_GetShaderPrecisionFormat_precision_shm_id_not_20); -COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precision_shm_offset) == 24, - OffsetOf_GetShaderPrecisionFormat_precision_shm_offset_not_24); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, result_shm_id) == 12, + OffsetOf_GetShaderPrecisionFormat_result_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, result_shm_offset) == 16, + OffsetOf_GetShaderPrecisionFormat_result_shm_offset_not_16); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, success) == 0, + OffsetOf_GetShaderPrecisionFormat_Result_success_not_0); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, min_range) == 4, + OffsetOf_GetShaderPrecisionFormat_Result_min_range_not_4); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, max_range) == 8, + OffsetOf_GetShaderPrecisionFormat_Result_max_range_not_8); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat::Result, precision) == 12, + OffsetOf_GetShaderPrecisionFormat_Result_precision_not_12); struct GetShaderSource { typedef GetShaderSource ValueType; @@ -3988,6 +3948,8 @@ struct GetUniformfv { static const CommandId kCmdId = kGetUniformfv; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + typedef SizedResult<GLfloat> Result; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -4039,6 +4001,8 @@ struct GetUniformiv { static const CommandId kCmdId = kGetUniformiv; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + typedef SizedResult<GLint> Result; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -4192,6 +4156,8 @@ struct GetVertexAttribPointerv { static const CommandId kCmdId = kGetVertexAttribPointerv; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + typedef SizedResult<GLuint> Result; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } 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 6dbd8a0c..ed27296 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -1097,15 +1097,9 @@ TEST(GLES2FormatTest, GetActiveAttrib) { &cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), - static_cast<GLsizei>(13), + static_cast<uint32>(13), static_cast<uint32>(14), - static_cast<uint32>(15), - static_cast<uint32>(16), - static_cast<uint32>(17), - static_cast<uint32>(18), - static_cast<uint32>(19), - static_cast<uint32>(20), - static_cast<uint32>(21)); + static_cast<uint32>(15)); EXPECT_EQ(static_cast<uint32>(GetActiveAttrib::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); @@ -1113,15 +1107,9 @@ TEST(GLES2FormatTest, GetActiveAttrib) { reinterpret_cast<char*>(&cmd) + sizeof(cmd)); EXPECT_EQ(static_cast<GLuint>(11), cmd.program); EXPECT_EQ(static_cast<GLuint>(12), cmd.index); - EXPECT_EQ(static_cast<GLsizei>(13), cmd.bufsize); - EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_id); - EXPECT_EQ(static_cast<uint32>(15), cmd.length_shm_offset); - EXPECT_EQ(static_cast<uint32>(16), cmd.size_shm_id); - EXPECT_EQ(static_cast<uint32>(17), cmd.size_shm_offset); - EXPECT_EQ(static_cast<uint32>(18), cmd.type_shm_id); - EXPECT_EQ(static_cast<uint32>(19), cmd.type_shm_offset); - EXPECT_EQ(static_cast<uint32>(20), cmd.name_shm_id); - EXPECT_EQ(static_cast<uint32>(21), cmd.name_shm_offset); + EXPECT_EQ(static_cast<uint32>(13), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.result_shm_offset); } TEST(GLES2FormatTest, GetActiveUniform) { @@ -1130,15 +1118,9 @@ TEST(GLES2FormatTest, GetActiveUniform) { &cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), - static_cast<GLsizei>(13), + static_cast<uint32>(13), static_cast<uint32>(14), - static_cast<uint32>(15), - static_cast<uint32>(16), - static_cast<uint32>(17), - static_cast<uint32>(18), - static_cast<uint32>(19), - static_cast<uint32>(20), - static_cast<uint32>(21)); + static_cast<uint32>(15)); EXPECT_EQ(static_cast<uint32>(GetActiveUniform::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); @@ -1146,15 +1128,9 @@ TEST(GLES2FormatTest, GetActiveUniform) { reinterpret_cast<char*>(&cmd) + sizeof(cmd)); EXPECT_EQ(static_cast<GLuint>(11), cmd.program); EXPECT_EQ(static_cast<GLuint>(12), cmd.index); - EXPECT_EQ(static_cast<GLsizei>(13), cmd.bufsize); - EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_id); - EXPECT_EQ(static_cast<uint32>(15), cmd.length_shm_offset); - EXPECT_EQ(static_cast<uint32>(16), cmd.size_shm_id); - EXPECT_EQ(static_cast<uint32>(17), cmd.size_shm_offset); - EXPECT_EQ(static_cast<uint32>(18), cmd.type_shm_id); - EXPECT_EQ(static_cast<uint32>(19), cmd.type_shm_offset); - EXPECT_EQ(static_cast<uint32>(20), cmd.name_shm_id); - EXPECT_EQ(static_cast<uint32>(21), cmd.name_shm_offset); + EXPECT_EQ(static_cast<uint32>(13), cmd.name_bucket_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.result_shm_offset); } TEST(GLES2FormatTest, GetAttachedShaders) { @@ -1162,22 +1138,18 @@ TEST(GLES2FormatTest, GetAttachedShaders) { 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>(16)); + static_cast<uint32>(14)); EXPECT_EQ(static_cast<uint32>(GetAttachedShaders::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.program); - EXPECT_EQ(static_cast<GLsizei>(12), cmd.maxcount); - EXPECT_EQ(static_cast<uint32>(13), cmd.count_shm_id); - EXPECT_EQ(static_cast<uint32>(14), cmd.count_shm_offset); - EXPECT_EQ(static_cast<uint32>(15), cmd.shaders_shm_id); - EXPECT_EQ(static_cast<uint32>(16), cmd.shaders_shm_offset); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); + EXPECT_EQ(static_cast<uint32>(14), cmd.result_size); } // TODO(gman): Write test for GetAttribLocation @@ -1398,9 +1370,7 @@ TEST(GLES2FormatTest, GetShaderPrecisionFormat) { static_cast<GLenum>(11), static_cast<GLenum>(12), static_cast<uint32>(13), - static_cast<uint32>(14), - static_cast<uint32>(15), - static_cast<uint32>(16)); + static_cast<uint32>(14)); EXPECT_EQ(static_cast<uint32>(GetShaderPrecisionFormat::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); @@ -1408,10 +1378,8 @@ TEST(GLES2FormatTest, GetShaderPrecisionFormat) { reinterpret_cast<char*>(&cmd) + sizeof(cmd)); EXPECT_EQ(static_cast<GLenum>(11), cmd.shadertype); EXPECT_EQ(static_cast<GLenum>(12), cmd.precisiontype); - EXPECT_EQ(static_cast<uint32>(13), cmd.range_shm_id); - EXPECT_EQ(static_cast<uint32>(14), cmd.range_shm_offset); - EXPECT_EQ(static_cast<uint32>(15), cmd.precision_shm_id); - EXPECT_EQ(static_cast<uint32>(16), cmd.precision_shm_offset); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.result_shm_offset); } TEST(GLES2FormatTest, GetShaderSource) { diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc index 6b2d116..3dbe967 100644 --- a/gpu/command_buffer/service/common_decoder.cc +++ b/gpu/command_buffer/service/common_decoder.cc @@ -32,6 +32,11 @@ bool CommonDecoder::Bucket::SetData( return false; } +void CommonDecoder::Bucket::SetFromString(const std::string& str) { + SetSize(str.size()); + SetData(str.c_str(), 0, str.size()); +} + void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id, unsigned int offset, unsigned int size) { @@ -66,6 +71,15 @@ CommonDecoder::Bucket* CommonDecoder::GetBucket(uint32 bucket_id) const { return iter != buckets_.end() ? &(*iter->second) : NULL; } +CommonDecoder::Bucket* CommonDecoder::CreateBucket(uint32 bucket_id) { + Bucket* bucket = GetBucket(bucket_id); + if (!bucket) { + bucket = new Bucket(); + buckets_[bucket_id] = linked_ptr<Bucket>(bucket); + } + return bucket; +} + namespace { // Returns the address of the first byte after a struct. @@ -202,12 +216,7 @@ error::Error CommonDecoder::HandleSetBucketSize( uint32 bucket_id = args.bucket_id; uint32 size = args.size; - Bucket* bucket = GetBucket(bucket_id); - if (!bucket) { - bucket = new Bucket(); - buckets_[bucket_id] = linked_ptr<Bucket>(bucket); - } - + Bucket* bucket = CreateBucket(bucket_id); bucket->SetSize(size); return error::kNoError; } diff --git a/gpu/command_buffer/service/common_decoder.h b/gpu/command_buffer/service/common_decoder.h index f4c0e67..2300e5a 100644 --- a/gpu/command_buffer/service/common_decoder.h +++ b/gpu/command_buffer/service/common_decoder.h @@ -7,6 +7,7 @@ #include <map> #include <stack> +#include <string> #include "base/linked_ptr.h" #include "base/scoped_ptr.h" #include "gpu/command_buffer/service/cmd_parser.h" @@ -70,6 +71,9 @@ class CommonDecoder : public AsyncAPIInterface { // Returns false if offset or size is out of range. bool SetData(const void* src, size_t offset, size_t size); + // Sets the bucket data from a string. + void SetFromString(const std::string& str); + private: bool OffsetSizeValid(size_t offset, size_t size) const { size_t temp = offset + size; @@ -93,6 +97,9 @@ class CommonDecoder : public AsyncAPIInterface { engine_ = engine; } + // Gets a bucket. Returns NULL if the bucket does not exist. + Bucket* GetBucket(uint32 bucket_id) const; + protected: // Executes a common command. // Parameters: @@ -131,14 +138,14 @@ class CommonDecoder : public AsyncAPIInterface { // Gets an name for a common command. const char* GetCommonCommandName(cmd::CommandId command_id) const; - // Gets a bucket. Returns NULL if the bucket does not exist. - Bucket* GetBucket(uint32 bucket_id) const; + // Creates a bucket. If the bucket already exists returns that bucket. + Bucket* CreateBucket(uint32 bucket_id); private: // Generate a member function prototype for each command in an automated and // typesafe way. #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ - error::Error Handle ## name( \ + error::Error Handle##name( \ uint32 immediate_data_size, \ const cmd::name& args); \ diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h index 65df9f5..6edc287 100644 --- a/gpu/command_buffer/service/gl_utils.h +++ b/gpu/command_buffer/service/gl_utils.h @@ -13,12 +13,22 @@ #if defined(UNIT_TEST) #include "gpu/command_buffer/service/gl_mock.h" #else -#include <GL/glew.h> +#include <GL/glew.h> // NOLINT #if defined(OS_WIN) -#include <GL/wglew.h> +#include <GL/wglew.h> // NOLINT #elif defined(OS_LINUX) -#include <GL/glxew.h> +#include <GL/glxew.h> // NOLINT #endif // OS_WIN + +// GLES2 defines not part of Desktop GL +// Shader Precision-Specified Types +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + #endif // UNIT_TEST #define GL_GLEXT_PROTOTYPES 1 diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 684e579..adfea53 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -9,8 +9,9 @@ #include <vector> #include <string> #include <map> -#include <build/build_config.h> +#include <build/build_config.h> // NOLINT #include "base/scoped_ptr.h" +#include "base/string_util.h" #define GLES2_GPU_SERVICE 1 #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" @@ -68,6 +69,12 @@ static size_t GetGLTypeSize(GLenum type) { } } +bool IsInvalidPrefix(const char* name, size_t length) { + static const char kInvalidPrefix[] = { 'g', 'l', '_' }; + return (length >= sizeof(kInvalidPrefix) && + memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); +} + // Returns the address of the first byte after a struct. template <typename T> const void* AddressAfterStruct(const T& pod) { @@ -323,30 +330,142 @@ class ProgramManager { class ProgramInfo { public: struct UniformInfo { - GLsizei GetSizeInBytes() const; - + GLsizei size; + GLenum type; + std::string name; + std::vector<GLint> element_locations; + }; + struct VertexAttribInfo { GLsizei size; GLenum type; GLint location; + std::string name; }; typedef std::vector<UniformInfo> UniformInfoVector; - typedef std::vector<GLuint> AttribLocationVector; + typedef std::vector<VertexAttribInfo> AttribInfoVector; - ProgramInfo() { + explicit ProgramInfo(GLuint program) + : program_(program) { } - void SetNumAttributes(int num_attribs) { - attrib_locations_.resize(num_attribs); + void Update() { + GLint num_attribs = 0; + GLint max_len = 0; + glGetProgramiv(program_, GL_ACTIVE_ATTRIBUTES, &num_attribs); + 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]); + for (GLint ii = 0; ii < num_attribs; ++ii) { + GLsizei length; + GLsizei size; + GLenum type; + glGetActiveAttrib( + program_, ii, max_len, &length, &size, &type, name_buffer.get()); + // TODO(gman): Should we check for error? + GLint location = IsInvalidPrefix(name_buffer.get(), length) ? -1 : + glGetAttribLocation(program_, name_buffer.get()); + SetAttributeInfo(ii, size, type, location, name_buffer.get()); + } + GLint num_uniforms; + glGetProgramiv(program_, GL_ACTIVE_UNIFORMS, &num_uniforms); + 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 = IsInvalidPrefix(name_buffer.get(), length) ? -1 : + glGetUniformLocation(program_, name_buffer.get()); + SetUniformInfo(ii, size, type, location, name_buffer.get()); + } } - void SetAttributeLocation(GLuint index, int location) { - DCHECK(index < attrib_locations_.size()); - attrib_locations_[index] = location; + const AttribInfoVector& GetAttribInfos() const { + return attrib_infos_; + } + + const VertexAttribInfo* GetAttribInfo(GLint index) const { + return (static_cast<size_t>(index) < attrib_infos_.size()) ? + &attrib_infos_[index] : NULL; + } + + GLint GetAttribLocation(const std::string& name) { + for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { + const VertexAttribInfo& info = attrib_infos_[ii]; + if (info.name == name) { + return info.location; + } + } + return -1; + } + + const UniformInfo* GetUniformInfo(GLint index) const { + return (static_cast<size_t>(index) < uniform_infos_.size()) ? + &uniform_infos_[index] : NULL; + } + + GLint GetUniformLocation(const std::string& name) { + for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { + const UniformInfo& info = uniform_infos_[ii]; + if (info.name == name) { + return info.element_locations[0]; + } else if (name.size() >= 3 && name[name.size() - 1] == ']') { + // Look for an array specfication. + size_t open_pos = name.find_last_of('['); + if (open_pos != std::string::npos && open_pos < name.size() - 2) { + GLuint index = 0; + size_t last = name.size() - 1; + bool bad = false; + for (size_t pos = open_pos + 1; pos < last; ++pos) { + int8 digit = name[pos] - '0'; + if (digit < 0 || digit > 9) { + bad = true; + break; + } + index = index * 10 + digit; + } + if (!bad) { + return index; + } + } + } + } + return -1; + } + + bool GetUniformTypeByLocation(GLint location, GLenum* type) const { + for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { + const UniformInfo& info = uniform_infos_[ii]; + for (GLsizei jj = 0; jj < info.size; ++jj) { + if (info.element_locations[jj] == location) { + *type = info.type; + return true; + } + } + } + return false; + } + + private: + void SetNumAttributes(int num_attribs) { + attrib_infos_.resize(num_attribs); } - const AttribLocationVector& GetAttribLocations() const { - return attrib_locations_; + void SetAttributeInfo( + GLint index, GLsizei size, GLenum type, GLint location, + const std::string& name) { + DCHECK(static_cast<unsigned>(index) < attrib_infos_.size()); + VertexAttribInfo& info = attrib_infos_[index]; + info.size = size; + info.type = type; + info.name = name; + info.location = location; } void SetNumUniforms(int num_uniforms) { @@ -354,28 +473,34 @@ class ProgramManager { } void SetUniformInfo( - GLint index, GLsizei size, GLenum type, GLint location) { + GLint index, GLsizei size, GLenum type, GLint location, + const std::string& name) { + DCHECK(static_cast<unsigned>(index) < uniform_infos_.size()); 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]; + info.name = name; + info.element_locations.resize(size); + info.element_locations[0] = location; + // Go through the array element locations looking for a match. + // We can skip the first element because it's the same as the + // the location without the array operators. + if (size > 1) { + for (GLsizei ii = 1; ii < info.size; ++ii) { + std::string element_name(name + "[" + IntToString(ii) + "]"); + info.element_locations[ii] = + glGetUniformLocation(program_, element_name.c_str()); } } - return NULL; } - - private: - AttribLocationVector attrib_locations_; + AttribInfoVector attrib_infos_; // Uniform info by info. UniformInfoVector uniform_infos_; + + // The program this ProgramInfo is tracking. + GLuint program_; }; ProgramInfo* GetProgramInfo(GLuint program); @@ -393,10 +518,6 @@ 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; @@ -406,42 +527,11 @@ void ProgramManager::UpdateProgramInfo(GLuint program) { ProgramInfo* info = GetProgramInfo(program); if (!info) { std::pair<ProgramInfoMap::iterator, bool> result = - program_infos_.insert(std::make_pair(program, ProgramInfo())); + program_infos_.insert(std::make_pair(program, ProgramInfo(program))); DCHECK(result.second); info = &result.first->second; } - GLint num_attribs = 0; - GLint max_len = 0; - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs); - 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]); - for (GLint ii = 0; ii < num_attribs; ++ii) { - GLsizei length; - GLsizei size; - GLenum type; - glGetActiveAttrib( - 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); - } + info->Update(); } void ProgramManager::RemoveProgramInfo(GLuint program) { @@ -693,7 +783,7 @@ class GLES2DecoderImpl : public GLES2Decoder { bool GetUniformSetup( GLuint program, GLint location, uint32 shm_id, uint32 shm_offset, - error::Error* error, GLuint* service_id, SizedResult** result); + error::Error* error, GLuint* service_id, void** result); // Generate a member function prototype for each command in an automated and // typesafe way. @@ -1647,11 +1737,14 @@ bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) { return false; } // Validate that all attribs current program needs are setup correctly. - const ProgramManager::ProgramInfo::AttribLocationVector& locations = - info->GetAttribLocations(); - for (size_t ii = 0; ii < locations.size(); ++ii) { - GLuint location = locations[ii]; - DCHECK_LT(location, max_vertex_attribs_); + const ProgramManager::ProgramInfo::AttribInfoVector& infos = + info->GetAttribInfos(); + for (size_t ii = 0; ii < infos.size(); ++ii) { + GLint location = infos[ii].location; + if (location < 0) { + return false; + } + DCHECK_LT(static_cast<GLuint>(location), max_vertex_attribs_); if (!vertex_attrib_infos_[location].CanAccess(max_vertex_accessed)) { SetGLError(GL_INVALID_OPERATION); return false; @@ -1875,6 +1968,12 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocation( SetGLError(GL_INVALID_VALUE); return error::kNoError; } + ProgramManager::ProgramInfo* info = GetProgramInfo(program); + if (!info) { + // Program was not linked successfully. (ie, glLinkProgram) + SetGLError(GL_INVALID_OPERATION); + return error::kNoError; + } uint32 name_size = c.data_size; const char* name = GetSharedMemoryAs<const char*>( c.name_shm_id, c.name_shm_offset, name_size); @@ -1884,7 +1983,7 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocation( return error::kOutOfBounds; } String name_str(name, name_size); - *location = glGetAttribLocation(program, name_str.c_str()); + *location = info->GetAttribLocation(name_str); return error::kNoError; } @@ -1895,6 +1994,12 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate( SetGLError(GL_INVALID_VALUE); return error::kNoError; } + ProgramManager::ProgramInfo* info = GetProgramInfo(program); + if (!info) { + // Program was not linked successfully. (ie, glLinkProgram) + SetGLError(GL_INVALID_OPERATION); + return error::kNoError; + } uint32 name_size = c.data_size; const char* name = GetImmediateDataAs<const char*>( c, name_size, immediate_data_size); @@ -1904,7 +2009,7 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate( return error::kOutOfBounds; } String name_str(name, name_size); - *location = glGetAttribLocation(program, name_str.c_str()); + *location = info->GetAttribLocation(name_str); return error::kNoError; } @@ -1915,6 +2020,12 @@ error::Error GLES2DecoderImpl::HandleGetUniformLocation( SetGLError(GL_INVALID_VALUE); return error::kNoError; } + ProgramManager::ProgramInfo* info = GetProgramInfo(program); + if (!info) { + // Program was not linked successfully. (ie, glLinkProgram) + SetGLError(GL_INVALID_OPERATION); + return error::kNoError; + } uint32 name_size = c.data_size; const char* name = GetSharedMemoryAs<const char*>( c.name_shm_id, c.name_shm_offset, name_size); @@ -1924,7 +2035,7 @@ error::Error GLES2DecoderImpl::HandleGetUniformLocation( return error::kOutOfBounds; } String name_str(name, name_size); - *location = glGetUniformLocation(program, name_str.c_str()); + *location = info->GetUniformLocation(name_str); return error::kNoError; } @@ -1935,6 +2046,12 @@ error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate( SetGLError(GL_INVALID_VALUE); return error::kNoError; } + ProgramManager::ProgramInfo* info = GetProgramInfo(program); + if (!info) { + // Program was not linked successfully. (ie, glLinkProgram) + SetGLError(GL_INVALID_OPERATION); + return error::kNoError; + } uint32 name_size = c.data_size; const char* name = GetImmediateDataAs<const char*>( c, name_size, immediate_data_size); @@ -1944,7 +2061,7 @@ error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate( return error::kOutOfBounds; } String name_str(name, name_size); - *location = glGetUniformLocation(program, name_str.c_str()); + *location = info->GetUniformLocation(name_str); return error::kNoError; } @@ -2145,8 +2262,9 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) { GLuint index = static_cast<GLuint>(c.index); GLenum pname = static_cast<GLenum>(c.pname); - SizedResult* result = GetSharedMemoryAs<SizedResult*>( - c.pointer_shm_id, c.pointer_shm_offset, sizeof(SizedResult)); + typedef gles2::GetVertexAttribPointerv::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1)); if (!result) { return error::kOutOfBounds; } @@ -2159,25 +2277,27 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( SetGLError(GL_INVALID_VALUE); return error::kNoError; } - result->size = sizeof(GLuint); - *result->GetDataAs<GLuint*>() = vertex_attrib_infos_[index].offset(); + result->SetNumResults(1); + *result->GetData() = vertex_attrib_infos_[index].offset(); 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* error, GLuint* service_id, void** result_pointer) { *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) { + SizedResult<GLint>* result; + result = GetSharedMemoryAs<SizedResult<GLint>*>( + shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0)); + if (!result) { *error = error::kOutOfBounds; return false; } + *result_pointer = result; // Set the result size to 0 so the client does not have to check for success. - (*result)->size = 0; + result->SetNumResults(0); if (!id_manager_->GetServiceId(program, service_id)) { SetGLError(GL_INVALID_VALUE); return error::kNoError; @@ -2188,25 +2308,24 @@ bool GLES2DecoderImpl::GetUniformSetup( SetGLError(GL_INVALID_OPERATION); return false; } - const ProgramManager::ProgramInfo::UniformInfo* uniform_info = - info->GetUniformInfoByLocation(location); - if (!uniform_info) { + GLenum type; + if (!info->GetUniformTypeByLocation(location, &type)) { // No such location. SetGLError(GL_INVALID_OPERATION); return false; } - GLsizei size = uniform_info->GetSizeInBytes(); + GLsizei size = GLES2Util::GetGLDataTypeSize(type); if (size == 0) { SetGLError(GL_INVALID_OPERATION); return false; } - *result = GetSharedMemoryAs<SizedResult*>( - shm_id, shm_offset, SizedResult::GetSize(size)); - if (!*result) { + result = GetSharedMemoryAs<SizedResult<GLint>*>( + shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size)); + if (!result) { *error = error::kOutOfBounds; return false; } - (*result)->size = size; + result->size = size; return true; } @@ -2216,11 +2335,13 @@ error::Error GLES2DecoderImpl::HandleGetUniformiv( GLint location = c.location; GLuint service_id; Error error; - SizedResult* result; + void* result; if (GetUniformSetup( program, location, c.params_shm_id, c.params_shm_offset, &error, &service_id, &result)) { - glGetUniformiv(service_id, location, result->GetDataAs<GLint*>()); + glGetUniformiv( + service_id, location, + static_cast<gles2::GetUniformiv::Result*>(result)->GetData()); } return error; } @@ -2231,40 +2352,156 @@ error::Error GLES2DecoderImpl::HandleGetUniformfv( GLint location = c.location; GLuint service_id; Error error; - SizedResult* result; + void* result; + typedef gles2::GetUniformfv::Result Result; if (GetUniformSetup( program, location, c.params_shm_id, c.params_shm_offset, &error, &service_id, &result)) { - glGetUniformfv(service_id, location, result->GetDataAs<GLfloat*>()); + glGetUniformfv( + service_id, + location, + static_cast<gles2::GetUniformfv::Result*>(result)->GetData()); } return error; } error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) { - // TODO(gman): Implement. - NOTREACHED(); + GLenum shader_type = static_cast<GLenum>(c.shadertype); + GLenum precision_type = static_cast<GLenum>(c.precisiontype); + typedef gles2::GetShaderPrecisionFormat::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + if (!ValidateGLenumShaderType(shader_type) || + !ValidateGLenumShaderPrecision(precision_type)) { + result->success = 0; // false + SetGLError(GL_INVALID_ENUM); + } else { + result->success = 1; // true + switch (precision_type) { + case GL_LOW_INT: + case GL_MEDIUM_INT: + case GL_HIGH_INT: + result->min_range = -31; + result->max_range = 31; + result->precision = 0; + case GL_LOW_FLOAT: + case GL_MEDIUM_FLOAT: + case GL_HIGH_FLOAT: + result->min_range = -62; + result->max_range = 62; + result->precision = -16; + break; + default: + NOTREACHED(); + break; + } + } return error::kNoError; } error::Error GLES2DecoderImpl::HandleGetAttachedShaders( uint32 immediate_data_size, const gles2::GetAttachedShaders& c) { - // TODO(gman): Implement. - NOTREACHED(); + GLuint service_id; + uint32 result_size = c.result_size; + if (!id_manager_->GetServiceId(c.program, &service_id)) { + SetGLError(GL_INVALID_VALUE); + return error::kNoError; + } + typedef gles2::GetAttachedShaders::Result Result; + uint32 max_count = Result::ComputeMaxResults(result_size); + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count)); + if (!result) { + return error::kOutOfBounds; + } + GLsizei count = 0; + glGetAttachedShaders(service_id, max_count, &count, result->GetData()); + for (GLsizei ii = 0; ii < count; ++ii) { + if (!id_manager_->GetClientId(result->GetData()[ii], + &result->GetData()[ii])) { + NOTREACHED(); + return error::kGenericError; + } + } + result->SetNumResults(count); return error::kNoError; } error::Error GLES2DecoderImpl::HandleGetActiveUniform( uint32 immediate_data_size, const gles2::GetActiveUniform& c) { - // TODO(gman): Implement. - NOTREACHED(); + GLuint program = c.program; + GLuint index = c.index; + uint32 name_bucket_id = c.name_bucket_id; + GLuint service_id; + typedef gles2::GetActiveUniform::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + result->success = 0; // false. + 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 error::kNoError; + } + const ProgramManager::ProgramInfo::UniformInfo* uniform_info = + info->GetUniformInfo(index); + if (!uniform_info) { + SetGLError(GL_INVALID_VALUE); + return error::kNoError; + } + result->success = 1; // true. + result->size = uniform_info->size; + result->type = uniform_info->type; + Bucket* bucket = CreateBucket(name_bucket_id); + bucket->SetFromString(uniform_info->name); return error::kNoError; } error::Error GLES2DecoderImpl::HandleGetActiveAttrib( uint32 immediate_data_size, const gles2::GetActiveAttrib& c) { - // TODO(gman): Implement. - NOTREACHED(); + GLuint program = c.program; + GLuint index = c.index; + uint32 name_bucket_id = c.name_bucket_id; + GLuint service_id; + typedef gles2::GetActiveAttrib::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + if (!result) { + return error::kOutOfBounds; + } + result->success = 0; // false. + 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 error::kNoError; + } + const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = + info->GetAttribInfo(index); + if (!attrib_info) { + SetGLError(GL_INVALID_VALUE); + return error::kNoError; + } + result->success = 1; // true. + result->size = attrib_info->size; + result->type = attrib_info->type; + Bucket* bucket = CreateBucket(name_bucket_id); + bucket->SetFromString(attrib_info->name); 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 6cb0b54..1b8d0e8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "base/string_util.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" @@ -19,10 +20,20 @@ using ::testing::Return; using ::testing::SetArrayArgument; using ::testing::SetArgumentPointee; using ::testing::StrEq; +using ::testing::StrictMock; namespace gpu { namespace gles2 { +namespace { + +bool IsInvalidPrefix(const char* name) { + static const char kInvalidPrefix[] = { 'g', 'l', '_' }; + return memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0; +} + +} // anonymous namespace + class GLES2DecoderTest : public testing::Test { public: GLES2DecoderTest() @@ -52,7 +63,8 @@ class GLES2DecoderTest : public testing::Test { static const uint32 kSharedMemoryOffset = 132; static const int32 kInvalidSharedMemoryId = 402; static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1; - static const uint32 kInitialResult = 0xDEADBEEFu; + static const uint32 kInitialResult = 0xBDBDBDBDu; + static const uint8 kInitialMemoryValue = 0xBDu; static const uint32 kNewClientId = 501; static const uint32 kNewServiceId = 502; @@ -84,8 +96,12 @@ class GLES2DecoderTest : public testing::Test { reinterpret_cast<T>(ImmediateDataAddress(cmd)); } + void ClearSharedMemory() { + engine_->ClearSharedMemory(); + } + virtual void SetUp() { - gl_.reset(new MockGLInterface()); + gl_.reset(new StrictMock<MockGLInterface>()); ::gles2::GLInterface::SetGLInterface(gl_.get()); EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) @@ -94,7 +110,7 @@ class GLES2DecoderTest : public testing::Test { EXPECT_CALL(*gl_, GetError()) .WillRepeatedly(Return(GL_NO_ERROR)); - engine_.reset(new MockCommandBufferEngine()); + engine_.reset(new StrictMock<MockCommandBufferEngine>()); Buffer buffer = engine_->GetSharedMemoryBuffer(kSharedMemoryId); shared_memory_offset_ = kSharedMemoryOffset; shared_memory_address_ = reinterpret_cast<int8*>(buffer.ptr) + @@ -147,11 +163,6 @@ class GLES2DecoderTest : public testing::Test { } EXPECT_EQ(GL_NO_ERROR, GetGLError()); - - result_ = GetSharedMemoryAs<SizedResult*>(); - GLuint* result_value = result_->GetDataAs<GLuint*>(); - result_->size = kInitialResult; - *result_value = kInitialResult; } virtual void TearDown() { @@ -203,7 +214,8 @@ class GLES2DecoderTest : public testing::Test { return static_cast<GLint>(*GetSharedMemoryAs<GLenum*>()); } - scoped_ptr<MockGLInterface> gl_; + // Use StrictMock to make 100% sure we know how GL will be called. + scoped_ptr<StrictMock<MockGLInterface> > gl_; scoped_ptr<GLES2Decoder> decoder_; GLuint client_buffer_id_; @@ -217,7 +229,6 @@ class GLES2DecoderTest : public testing::Test { uint32 shared_memory_id_; uint32 shared_memory_offset_; void* shared_memory_address_; - SizedResult* result_; int8 immediate_buffer_[256]; @@ -226,6 +237,7 @@ class GLES2DecoderTest : public testing::Test { public: MockCommandBufferEngine() { data_.reset(new int8[kSharedBufferSize]); + ClearSharedMemory(); valid_buffer_.ptr = data_.get(); valid_buffer_.size = kSharedBufferSize; } @@ -237,6 +249,10 @@ class GLES2DecoderTest : public testing::Test { return shm_id == kSharedMemoryId ? valid_buffer_ : invalid_buffer_; } + void ClearSharedMemory() { + memset(data_.get(), kInitialMemoryValue, kSharedBufferSize); + } + void set_token(int32 token) { DCHECK(false); } @@ -259,7 +275,7 @@ class GLES2DecoderTest : public testing::Test { Buffer invalid_buffer_; }; - scoped_ptr<MockCommandBufferEngine> engine_; + scoped_ptr<StrictMock<MockCommandBufferEngine> > engine_; }; const GLint GLES2DecoderTest::kNumVertexAttribs; @@ -311,12 +327,23 @@ 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 kAttrib1Size = 1; + static const GLint kAttrib2Size = 1; + static const GLint kAttrib3Size = 1; + static const GLint kAttrib1Location = 0; + static const GLint kAttrib2Location = 1; + static const GLint kAttrib3Location = 2; + static const GLenum kAttrib1Type = GL_FLOAT_VEC4; + static const GLenum kAttrib2Type = GL_FLOAT_VEC2; + static const GLenum kAttrib3Type = GL_FLOAT_VEC3; + static const GLint kInvalidAttribLocation = 30; + static const GLint kBadAttribIndex = kNumVertexAttribs; + static const GLint kMaxUniformLength = 10; static const char* kUniform1Name; static const char* kUniform2Name; @@ -324,120 +351,144 @@ class GLES2DecoderWithShaderTest : public GLES2DecoderTest { 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 GLint kUniform1Location = 3; + static const GLint kUniform2Location = 10; + static const GLint kUniform2ElementLocation = 12; + static const GLint kUniform3Location = 20; 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; + static const GLint kInvalidUniformLocation = 30; + static const GLint kBadUniformIndex = 1000; protected: + struct AttribInfo { + const char* name; + GLint size; + GLenum type; + GLint location; + }; + + struct UniformInfo { + const char* name; + GLint size; + GLenum type; + GLint location; + }; + virtual void SetUp() { GLES2DecoderTest::SetUp(); { - struct AttribInfo { - const char* name; - GLint size; - GLenum type; - GLint location; - }; static AttribInfo attribs[] = { - { kAttrib1Name, 1, GL_FLOAT_VEC4, 0, }, - { kAttrib2Name, 1, GL_FLOAT_VEC2, 1, }, - { kAttrib3Name, 1, GL_FLOAT_VEC3, 2, }, - }; - struct UniformInfo { - const char* name; - GLint size; - GLenum type; - GLint location; + { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, + { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, }, + { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, }, }; static UniformInfo uniforms[] = { { kUniform1Name, kUniform1Size, GL_FLOAT_VEC4, kUniform1Location, }, { kUniform2Name, kUniform2Size, GL_INT_VEC2, kUniform2Location, }, { kUniform3Name, kUniform3Size, GL_FLOAT_VEC3, kUniform3Location, }, }; + SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms), + client_program_id_, kServiceProgramId); + } - LinkProgram cmd; + { + EXPECT_CALL(*gl_, UseProgram(kServiceProgramId)) + .Times(1) + .RetiresOnSaturation(); + UseProgram cmd; cmd.Init(client_program_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + } + } - { - 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(); + virtual void TearDown() { + GLES2DecoderTest::TearDown(); + } + + void SetupShader(AttribInfo* attribs, size_t num_attribs, + UniformInfo* uniforms, size_t num_uniforms, + GLuint client_id, GLuint service_id) { + LinkProgram cmd; + cmd.Init(client_id); + + { + InSequence s; + EXPECT_CALL(*gl_, LinkProgram(service_id)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _)) + .WillOnce(SetArgumentPointee<2>(num_attribs)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(kMaxAttribLength)) + .RetiresOnSaturation(); + for (size_t ii = 0; ii < num_attribs; ++ii) { + const AttribInfo& info = attribs[ii]; EXPECT_CALL(*gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(kMaxAttribLength)) + GetActiveAttrib(service_id, ii, + kMaxAttribLength, _, _, _, _)) + .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(); - for (GLint ii = 0; ii < kNumAttribs; ++ii) { - const AttribInfo& info = attribs[ii]; - EXPECT_CALL(*gl_, - GetActiveAttrib(kServiceProgramId, ii, - kMaxAttribLength, _, _, _, _)) - .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_, GetAttribLocation(kServiceProgramId, + if (!IsInvalidPrefix(info.name)) { + EXPECT_CALL(*gl_, GetAttribLocation(service_id, StrEq(info.name))) .WillOnce(Return(info.location)) .RetiresOnSaturation(); } + } + EXPECT_CALL(*gl_, + GetProgramiv(service_id, GL_ACTIVE_UNIFORMS, _)) + .WillOnce(SetArgumentPointee<2>(num_uniforms)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, + GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(kMaxUniformLength)) + .RetiresOnSaturation(); + for (size_t ii = 0; ii < num_uniforms; ++ii) { + const UniformInfo& info = uniforms[ii]; 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)) + GetActiveUniform(service_id, 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(); - 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, + if (!IsInvalidPrefix(info.name)) { + EXPECT_CALL(*gl_, GetUniformLocation(service_id, StrEq(info.name))) .WillOnce(Return(info.location)) .RetiresOnSaturation(); + if (info.size > 1) { + for (GLsizei jj = 1; jj < info.size; ++jj) { + std::string element_name( + std::string(info.name) + "[" + IntToString(jj) + "]"); + EXPECT_CALL(*gl_, GetUniformLocation(service_id, + StrEq(element_name))) + .WillOnce(Return(info.location + jj)) + .RetiresOnSaturation(); + } + } } } - - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - } - - { - EXPECT_CALL(*gl_, UseProgram(kServiceProgramId)) - .Times(1) - .RetiresOnSaturation(); - UseProgram cmd; - cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } - } - virtual void TearDown() { - GLES2DecoderTest::TearDown(); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } inline GLvoid* BufferOffset(unsigned i) { @@ -540,7 +591,6 @@ class GLES2DecoderWithShaderTest : public GLES2DecoderTest { } }; -const GLint GLES2DecoderWithShaderTest::kNumAttribs; const GLint GLES2DecoderWithShaderTest::kMaxAttribLength; const GLsizei GLES2DecoderWithShaderTest::kNumVertices; const GLsizei GLES2DecoderWithShaderTest::kNumIndices; @@ -802,13 +852,15 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { const float dummy = 0; const GLuint kOffsetToTestFor = sizeof(dummy) * 4; const GLuint kIndexToTest = 1; - const GLuint* result_value = result_->GetDataAs<const GLuint*>(); + GetVertexAttribPointerv::Result* result = + static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); + const GLuint* result_value = result->GetData(); // Test that initial value is 0. GetVertexAttribPointerv cmd; cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(sizeof(*result_value), result_->size); + EXPECT_EQ(sizeof(*result_value), result->size); EXPECT_EQ(0u, *result_value); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -816,20 +868,22 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { SetupVertexBuffer(); DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(sizeof(*result_value), result_->size); + EXPECT_EQ(sizeof(*result_value), result->size); EXPECT_EQ(kOffsetToTestFor, *result_value); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { const GLuint kIndexToTest = 1; - const GLuint* result_value = result_->GetDataAs<const GLuint*>(); + GetVertexAttribPointerv::Result* result = + static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); + const GLuint* result_value = result->GetData(); // Test pname invalid fails. GetVertexAttribPointerv cmd; cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER + 1, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result_->size); + EXPECT_EQ(0u, result->size); EXPECT_EQ(kInitialResult, *result_value); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); @@ -837,7 +891,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { cmd.Init(kNumVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_POINTER, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0u, result_->size); + EXPECT_EQ(0u, result->size); EXPECT_EQ(kInitialResult, *result_value); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); @@ -853,17 +907,33 @@ TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { } TEST_F(GLES2DecoderWithShaderTest, GetUniformivSucceeds) { + GetUniformiv::Result* result = + static_cast<GetUniformiv::Result*>(shared_memory_address_); 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); + EXPECT_EQ(GLES2Util::GetGLDataTypeSize(kUniform2Type), result->size); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) { + GetUniformiv::Result* result = + static_cast<GetUniformiv::Result*>(shared_memory_address_); + GetUniformiv cmd; + cmd.Init(client_program_id_, kUniform2ElementLocation, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, + GetUniformiv(kServiceProgramId, kUniform2ElementLocation, _)) + .Times(1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GLES2Util::GetGLDataTypeSize(kUniform2Type), result->size); } TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { + GetUniformiv::Result* result = + static_cast<GetUniformiv::Result*>(shared_memory_address_); GetUniformiv cmd; // non-existant program cmd.Init(kInvalidClientId, kUniform2Location, @@ -871,15 +941,15 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { EXPECT_CALL(*gl_, GetUniformiv(_, _, _)) .Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + 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; + result->size = kInitialResult; cmd.Init(client_texture_id_, kUniform2Location, kSharedMemoryId, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + EXPECT_EQ(0, result->size); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); // Unlinked program EXPECT_CALL(*gl_, CreateProgram()) @@ -889,15 +959,17 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) { CreateProgram cmd2; cmd2.Init(kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); - result_->size = kInitialResult; + result->size = kInitialResult; cmd.Init(kNewClientId, kUniform2Location, kSharedMemoryId, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + EXPECT_EQ(0, result->size); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) { + GetUniformiv::Result* result = + static_cast<GetUniformiv::Result*>(shared_memory_address_); GetUniformiv cmd; // invalid location cmd.Init(client_program_id_, kInvalidUniformLocation, @@ -905,7 +977,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) { EXPECT_CALL(*gl_, GetUniformiv(_, _, _)) .Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + EXPECT_EQ(0, result->size); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } @@ -922,17 +994,33 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) { }; TEST_F(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) { + GetUniformfv::Result* result = + static_cast<GetUniformfv::Result*>(shared_memory_address_); 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); + EXPECT_EQ(GLES2Util::GetGLDataTypeSize(kUniform2Type), result->size); +} + +TEST_F(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) { + GetUniformfv::Result* result = + static_cast<GetUniformfv::Result*>(shared_memory_address_); + GetUniformfv cmd; + cmd.Init(client_program_id_, kUniform2ElementLocation, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, + GetUniformfv(kServiceProgramId, kUniform2ElementLocation, _)) + .Times(1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GLES2Util::GetGLDataTypeSize(kUniform2Type), result->size); } TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { + GetUniformfv::Result* result = + static_cast<GetUniformfv::Result*>(shared_memory_address_); GetUniformfv cmd; // non-existant program cmd.Init(kInvalidClientId, kUniform2Location, @@ -940,15 +1028,15 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { EXPECT_CALL(*gl_, GetUniformfv(_, _, _)) .Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + 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; + result->size = kInitialResult; cmd.Init(client_texture_id_, kUniform2Location, kSharedMemoryId, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + EXPECT_EQ(0, result->size); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); // Unlinked program EXPECT_CALL(*gl_, CreateProgram()) @@ -958,15 +1046,17 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) { CreateProgram cmd2; cmd2.Init(kNewClientId); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); - result_->size = kInitialResult; + result->size = kInitialResult; cmd.Init(kNewClientId, kUniform2Location, kSharedMemoryId, kSharedMemoryOffset); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + EXPECT_EQ(0, result->size); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) { + GetUniformfv::Result* result = + static_cast<GetUniformfv::Result*>(shared_memory_address_); GetUniformfv cmd; // invalid location cmd.Init(client_program_id_, kInvalidUniformLocation, @@ -974,7 +1064,7 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) { EXPECT_CALL(*gl_, GetUniformfv(_, _, _)) .Times(0); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(0, result_->size); + EXPECT_EQ(0, result->size); EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } @@ -990,6 +1080,255 @@ TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) { EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); }; +TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) { + GetAttachedShaders cmd; + typedef GetAttachedShaders::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _)) + .WillOnce(DoAll(SetArgumentPointee<2>(1), + SetArgumentPointee<3>(kServiceShaderId))); + cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_, + Result::ComputeSize(1)); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(1, result->GetNumResults()); + EXPECT_EQ(client_shader_id_, result->GetData()[0]); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadProgramFails) { + GetAttachedShaders cmd; + typedef GetAttachedShaders::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)) + .Times(0); + cmd.Init(kInvalidClientId, shared_memory_id_, shared_memory_offset_, + Result::ComputeSize(1)); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->size); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadSharedMemoryFails) { + GetAttachedShaders cmd; + typedef GetAttachedShaders::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_, + Result::ComputeSize(1)); + EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)) + .Times(0); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset, + Result::ComputeSize(1)); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) { + GetShaderPrecisionFormat cmd; + typedef GetShaderPrecisionFormat::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + // NOTE: GL will not be called. There is no equivalent Desktop OpenGL + // function. + cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_NE(0, result->success); + EXPECT_EQ(-62, result->min_range); + EXPECT_EQ(62, result->max_range); + EXPECT_EQ(-16, result->precision); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatBadArgsFails) { + GetShaderPrecisionFormat cmd; + typedef GetShaderPrecisionFormat::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(GL_TEXTURE_2D, GL_HIGH_FLOAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, + GetShaderPrecisionFormatBadSharedMemoryFails) { + GetShaderPrecisionFormat cmd; + typedef GetShaderPrecisionFormat::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT, + kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D, + shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformSucceeds) { + const GLuint kUniformIndex = 1; + const uint32 kBucketId = 123; + GetActiveUniform cmd; + typedef GetActiveUniform::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(client_program_id_, kUniformIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_NE(0, result->success); + EXPECT_EQ(kUniform2Size, result->size); + EXPECT_EQ(kUniform2Type, result->type); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kUniform2Name, + bucket->size())); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadProgramFails) { + const GLuint kUniformIndex = 1; + const uint32 kBucketId = 123; + GetActiveUniform cmd; + typedef GetActiveUniform::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(kInvalidClientId, kUniformIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + cmd.Init(client_texture_id_, kUniformIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadIndexFails) { + const uint32 kBucketId = 123; + GetActiveUniform cmd; + typedef GetActiveUniform::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(client_program_id_, kBadUniformIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadSharedMemoryFails) { + const GLuint kUniformIndex = 1; + const uint32 kBucketId = 123; + GetActiveUniform cmd; + typedef GetActiveUniform::Result Result; + cmd.Init(client_program_id_, kUniformIndex, kBucketId, + kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, kUniformIndex, kBucketId, + shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) { + const GLuint kAttribIndex = 1; + const uint32 kBucketId = 123; + GetActiveAttrib cmd; + typedef GetActiveAttrib::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(client_program_id_, kAttribIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_NE(0, result->success); + EXPECT_EQ(kAttrib2Size, result->size); + EXPECT_EQ(kAttrib2Type, result->type); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId); + ASSERT_TRUE(bucket != NULL); + EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kAttrib2Name, + bucket->size())); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadProgramFails) { + const GLuint kAttribIndex = 1; + const uint32 kBucketId = 123; + GetActiveAttrib cmd; + typedef GetActiveAttrib::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(kInvalidClientId, kAttribIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + cmd.Init(client_texture_id_, kAttribIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadIndexFails) { + const uint32 kBucketId = 123; + GetActiveAttrib cmd; + typedef GetActiveAttrib::Result Result; + Result* result = static_cast<Result*>(shared_memory_address_); + cmd.Init(client_program_id_, kBadAttribIndex, kBucketId, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(0, result->success); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) { + const GLuint kAttribIndex = 1; + const uint32 kBucketId = 123; + GetActiveAttrib cmd; + typedef GetActiveAttrib::Result Result; + cmd.Init(client_program_id_, kAttribIndex, kBucketId, + kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); + cmd.Init(client_program_id_, kAttribIndex, kBucketId, + shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); +} + +// TODO(gman): BindAttribLocation + +// TODO(gman): BindAttribLocationImmediate + +// TODO(gman): BufferData + +// TODO(gman): BufferDataImmediate + +// TODO(gman): BufferSubData + +// TODO(gman): BufferSubDataImmediate + +// TODO(gman): CompressedTexImage2D + +// TODO(gman): CompressedTexImage2DImmediate + +// TODO(gman): CompressedTexSubImage2D + +// TODO(gman): CompressedTexSubImage2DImmediate + +// TODO(gman): DeleteProgram + +// TODO(gman): DeleteShader + +// TODO(gman): GetAttribLocation + +// TODO(gman): GetAttribLocationImmediate + +// TODO(gman): GetUniformLocation + +// TODO(gman): GetUniformLocationImmediate + +// TODO(gman): PixelStorei + +// 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_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index c7047a6..0573e3c 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -33,7 +33,7 @@ bool ValidateGLenumRenderBufferFormat(GLenum value); bool ValidateGLenumRenderBufferParameter(GLenum value); bool ValidateGLenumRenderBufferTarget(GLenum value); bool ValidateGLenumShaderParameter(GLenum value); -bool ValidateGLenumShaderPercision(GLenum value); +bool ValidateGLenumShaderPrecision(GLenum value); bool ValidateGLenumShaderType(GLenum value); bool ValidateGLenumSrcBlendFactor(GLenum value); bool ValidateGLenumStencilOp(GLenum value); diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 1513a43..b082c09 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -4,8 +4,8 @@ // This file is auto-generated. DO NOT EDIT! -#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ +#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ // NOLINT +#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ // NOLINT bool ValidateGLenumAttachment(GLenum value) { switch (value) { @@ -325,7 +325,7 @@ bool ValidateGLenumShaderParameter(GLenum value) { } } -bool ValidateGLenumShaderPercision(GLenum value) { +bool ValidateGLenumShaderPrecision(GLenum value) { switch (value) { case GL_LOW_FLOAT: case GL_MEDIUM_FLOAT: @@ -509,5 +509,5 @@ bool ValidateGLenumVertexPointer(GLenum value) { } } -#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ +#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ // NOLINT |