| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| ===================================================================
|
| --- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 33021)
|
| +++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy)
|
| @@ -43,11 +43,11 @@
|
| // Checks if there is enough immediate data.
|
| template<typename T>
|
| bool CheckImmediateDataSize(
|
| - unsigned int arg_count,
|
| + uint32 immediate_data_size,
|
| GLuint count,
|
| size_t size,
|
| unsigned int elements_per_unit) {
|
| - return ImmediateDataSize<T>(arg_count) == count * size * elements_per_unit;
|
| + return immediate_data_size == count * size * elements_per_unit;
|
| }
|
|
|
| // A struct to hold info about each command.
|
| @@ -149,13 +149,17 @@
|
|
|
| } // anonymous namespace.
|
|
|
| +#if defined(OS_LINUX)
|
| GLES2Decoder::GLES2Decoder()
|
| -#ifdef OS_LINUX
|
| - : window_(NULL) {
|
| + : debug_(false),
|
| + window_(NULL) {
|
| +#elif defined(OS_WIN)
|
| +GLES2Decoder::GLES2Decoder()
|
| + : debug_(false),
|
| + hwnd_(NULL) {
|
| +#else
|
| +GLES2Decoder::GLES2Decoder() {
|
| #endif
|
| -#ifdef OS_WIN
|
| - : hwnd_(NULL) {
|
| -#endif
|
| }
|
|
|
| // This class maps one set of ids to another.
|
| @@ -311,7 +315,7 @@
|
| // typesafe way.
|
| #define GLES2_CMD_OP(name) \
|
| ParseError Handle ## name( \
|
| - unsigned int arg_count, \
|
| + uint32 immediate_data_size, \
|
| const gles2::name& args); \
|
|
|
| GLES2_COMMAND_LIST(GLES2_CMD_OP)
|
| @@ -669,28 +673,44 @@
|
| unsigned int command,
|
| unsigned int arg_count,
|
| const void* cmd_data) {
|
| + parse_error::ParseError result;
|
| + if (debug()) {
|
| + // TODO(gman): Change output to something useful for NaCl.
|
| + const char* f = GetCommandName(command);
|
| + printf("cmd: %s\n", GetCommandName(command));
|
| + }
|
| unsigned int command_index = command - kStartPoint - 1;
|
| if (command_index < arraysize(g_command_info)) {
|
| const CommandInfo& info = g_command_info[command_index];
|
| unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
|
| if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
|
| (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
|
| + uint32 immediate_data_size =
|
| + (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
|
| switch (command) {
|
| #define GLES2_CMD_OP(name) \
|
| case name::kCmdId: \
|
| - return Handle ## name( \
|
| - arg_count, \
|
| + result = Handle ## name( \
|
| + immediate_data_size, \
|
| *static_cast<const name*>(cmd_data)); \
|
| + break; \
|
|
|
| GLES2_COMMAND_LIST(GLES2_CMD_OP)
|
| -
|
| #undef GLES2_CMD_OP
|
| + if (debug()) {
|
| + if (glGetError() != 0) {
|
| + // TODO(gman): Change output to something useful for NaCl.
|
| + printf("GL ERROR b4: %s\n", GetCommandName(command));
|
| + }
|
| + }
|
| }
|
| } else {
|
| - return parse_error::kParseInvalidArguments;
|
| + result = parse_error::kParseInvalidArguments;
|
| }
|
| + } else {
|
| + result = DoCommonCommand(command, arg_count, cmd_data);
|
| }
|
| - return DoCommonCommand(command, arg_count, cmd_data);
|
| + return result;
|
| }
|
|
|
| } // namespace gles2
|
| @@ -786,7 +806,7 @@
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleDrawElements(
|
| - unsigned int arg_count, const gles2::DrawElements& c) {
|
| + uint32 immediate_data_size, const gles2::DrawElements& c) {
|
| if (bound_element_array_buffer_ != 0) {
|
| GLenum mode = c.mode;
|
| GLsizei count = c.count;
|
| @@ -831,14 +851,21 @@
|
| } // anonymous namespace.
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleShaderSource(
|
| - unsigned int arg_count, const gles2::ShaderSource& c) {
|
| - GLuint shader = c.shader;
|
| + uint32 immediate_data_size, const gles2::ShaderSource& c) {
|
| + GLuint shader;
|
| + if (!id_map_.GetServiceId(c.shader, &shader)) {
|
| + SetGLError(GL_INVALID_VALUE);
|
| + return parse_error::kParseNoError;
|
| + }
|
| GLsizei count = c.count;
|
| uint32 data_size = c.data_size;
|
| const char** data = GetSharedMemoryAs<const char**>(
|
| c.data_shm_id, c.data_shm_offset, data_size);
|
| parse_error::ParseError result =
|
| - ValidateShaderSource(this, arg_count, shader, count, data, NULL);
|
| + // TODO(gman): Manually implement validation.
|
| + ValidateShaderSource(
|
| + this, immediate_data_size, shader, count, data,
|
| + reinterpret_cast<const GLint*>(1));
|
| if (result != parse_error::kParseNoError) {
|
| return result;
|
| }
|
| @@ -847,15 +874,19 @@
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate(
|
| - unsigned int arg_count, const gles2::ShaderSourceImmediate& c) {
|
| - GLuint shader = c.shader;
|
| + uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) {
|
| + GLuint shader;
|
| + if (!id_map_.GetServiceId(c.shader, &shader)) {
|
| + SetGLError(GL_INVALID_VALUE);
|
| + return parse_error::kParseNoError;
|
| + }
|
| GLsizei count = c.count;
|
| uint32 data_size = c.data_size;
|
| // TODO(gman): need to check that data_size is in range for arg_count.
|
| const char** data = GetImmediateDataAs<const char**>(c);
|
| parse_error::ParseError result =
|
| ValidateShaderSourceImmediate(
|
| - this, arg_count, shader, count, data, NULL);
|
| + this, immediate_data_size, shader, count, data, NULL);
|
| if (result != parse_error::kParseNoError) {
|
| return result;
|
| }
|
| @@ -864,7 +895,7 @@
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer(
|
| - unsigned int arg_count, const gles2::VertexAttribPointer& c) {
|
| + uint32 immediate_data_size, const gles2::VertexAttribPointer& c) {
|
| if (bound_array_buffer_ != 0) {
|
| GLuint indx = c.indx;
|
| GLint size = c.size;
|
| @@ -873,9 +904,11 @@
|
| GLsizei stride = c.stride;
|
| GLuint offset = c.offset;
|
| const void* ptr = reinterpret_cast<const void*>(c.offset);
|
| + // TODO(gman): Do manual validation.
|
| parse_error::ParseError result =
|
| ValidateVertexAttribPointer(
|
| - this, arg_count, indx, size, type, normalized, stride, ptr);
|
| + this, immediate_data_size, indx, size, type, normalized, stride,
|
| + reinterpret_cast<const void*>(1));
|
| if (result != parse_error::kParseNoError) {
|
| return result;
|
| }
|
| @@ -887,55 +920,308 @@
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleReadPixels(
|
| - unsigned int arg_count, const gles2::ReadPixels& c) {
|
| + uint32 immediate_data_size, const gles2::ReadPixels& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandlePixelStorei(
|
| - unsigned int arg_count, const gles2::PixelStorei& c) {
|
| - // TODO(gman): Implement.
|
| + uint32 immediate_data_size, const gles2::PixelStorei& c) {
|
| + GLenum pname = c.pname;
|
| + GLenum param = c.param;
|
| + parse_error::ParseError result =
|
| + ValidatePixelStorei(this, immediate_data_size, pname, param);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + glPixelStorei(pname, param);
|
| + switch (pname) {
|
| + case GL_PACK_ALIGNMENT:
|
| + pack_alignment_ = param;
|
| + break;
|
| + case GL_UNPACK_ALIGNMENT:
|
| + unpack_alignment_ = param;
|
| + break;
|
| + default:
|
| + // Validation should have prevented us from getting here.
|
| + DCHECK(false);
|
| + break;
|
| + }
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| +parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocation(
|
| + uint32 immediate_data_size, const gles2::GetAttribLocation& c) {
|
| + GLuint program;
|
| + if (!id_map_.GetServiceId(c.program, &program)) {
|
| + SetGLError(GL_INVALID_VALUE);
|
| + return parse_error::kParseNoError;
|
| + }
|
| + uint32 name_size = c.data_size;
|
| + const char* name = GetSharedMemoryAs<const char*>(
|
| + c.name_shm_id, c.name_shm_offset, name_size);
|
| + GLint* location = GetSharedMemoryAs<GLint*>(
|
| + c.location_shm_id, c.location_shm_offset, sizeof(GLint));
|
| + if (!location || !name) {
|
| + return parse_error::kParseOutOfBounds;
|
| + }
|
| + String name_str(name, name_size);
|
| + *location = glGetAttribLocation(program, name_str.c_str());
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate(
|
| + uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) {
|
| + GLuint program;
|
| + if (!id_map_.GetServiceId(c.program, &program)) {
|
| + SetGLError(GL_INVALID_VALUE);
|
| + return parse_error::kParseNoError;
|
| + }
|
| + uint32 name_size = c.data_size;
|
| + const char* name = GetImmediateDataAs<const char*>(c);
|
| + // TODO(gman): Make sure validate checks arg_count
|
| + // covers data_size.
|
| + GLint* location = GetSharedMemoryAs<GLint*>(
|
| + c.location_shm_id, c.location_shm_offset, sizeof(GLint));
|
| + if (!location || !name) {
|
| + return parse_error::kParseOutOfBounds;
|
| + }
|
| + String name_str(name, name_size);
|
| + *location = glGetAttribLocation(program, name_str.c_str());
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocation(
|
| + uint32 immediate_data_size, const gles2::GetUniformLocation& c) {
|
| + GLuint program;
|
| + if (!id_map_.GetServiceId(c.program, &program)) {
|
| + SetGLError(GL_INVALID_VALUE);
|
| + return parse_error::kParseNoError;
|
| + }
|
| + uint32 name_size = c.data_size;
|
| + const char* name = GetSharedMemoryAs<const char*>(
|
| + c.name_shm_id, c.name_shm_offset, name_size);
|
| + GLint* location = GetSharedMemoryAs<GLint*>(
|
| + c.location_shm_id, c.location_shm_offset, sizeof(GLint));
|
| + if (!location || !name) {
|
| + return parse_error::kParseOutOfBounds;
|
| + }
|
| + String name_str(name, name_size);
|
| + *location = glGetUniformLocation(program, name_str.c_str());
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate(
|
| + uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) {
|
| + GLuint program;
|
| + if (!id_map_.GetServiceId(c.program, &program)) {
|
| + SetGLError(GL_INVALID_VALUE);
|
| + return parse_error::kParseNoError;
|
| + }
|
| + uint32 name_size = c.data_size;
|
| + const char* name = GetImmediateDataAs<const char*>(c);
|
| + // TODO(gman): Make sure validate checks arg_count
|
| + // covers data_size.
|
| + GLint* location = GetSharedMemoryAs<GLint*>(
|
| + c.location_shm_id, c.location_shm_offset, sizeof(GLint));
|
| + if (!location || !name) {
|
| + return parse_error::kParseOutOfBounds;
|
| + }
|
| + String name_str(name, name_size);
|
| + *location = glGetUniformLocation(program, name_str.c_str());
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleBufferData(
|
| + uint32 immediate_data_size, const gles2::BufferData& c) {
|
| + GLenum target = static_cast<GLenum>(c.target);
|
| + GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
|
| + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
|
| + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
|
| + GLenum usage = static_cast<GLenum>(c.usage);
|
| + const void* data = NULL;
|
| + if (data_shm_id != 0 || data_shm_offset != 0) {
|
| + data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
|
| + parse_error::ParseError result =
|
| + ValidateBufferData(this, immediate_data_size, target, size, data,
|
| + usage);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + }
|
| + // TODO(gman): Validate case where data is NULL.
|
| + glBufferData(target, size, data, usage);
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate(
|
| + uint32 immediate_data_size, const gles2::BufferDataImmediate& c) {
|
| + GLenum target = static_cast<GLenum>(c.target);
|
| + GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
|
| + const void* data = GetImmediateDataAs<const void*>(c);
|
| + GLenum usage = static_cast<GLenum>(c.usage);
|
| + // Immediate version.
|
| + // TODO(gman): Handle case where data is NULL.
|
| + parse_error::ParseError result =
|
| + ValidateBufferDataImmediate(this, immediate_data_size, target, size, data,
|
| + usage);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + glBufferData(target, size, data, usage);
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D(
|
| + uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
|
| + GLenum target = static_cast<GLenum>(c.target);
|
| + GLint level = static_cast<GLint>(c.level);
|
| + GLenum internal_format = static_cast<GLenum>(c.internalformat);
|
| + GLsizei width = static_cast<GLsizei>(c.width);
|
| + GLsizei height = static_cast<GLsizei>(c.height);
|
| + GLint border = static_cast<GLint>(c.border);
|
| + GLsizei image_size = static_cast<GLsizei>(c.imageSize);
|
| + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
|
| + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
|
| + const void* data = NULL;
|
| + if (data_shm_id != 0 || data_shm_offset != 0) {
|
| + data = GetSharedMemoryAs<const void*>(
|
| + data_shm_id, data_shm_offset, image_size);
|
| + parse_error::ParseError result =
|
| + ValidateCompressedTexImage2D(
|
| + this, immediate_data_size, target, level, internal_format, width,
|
| + height, border, image_size, data);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + }
|
| + // TODO(gman): Validate case where data is NULL.
|
| + glCompressedTexImage2D(
|
| + target, level, internal_format, width, height, border, image_size, data);
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
|
| + uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) {
|
| + GLenum target = static_cast<GLenum>(c.target);
|
| + GLint level = static_cast<GLint>(c.level);
|
| + GLenum internal_format = static_cast<GLenum>(c.internalformat);
|
| + GLsizei width = static_cast<GLsizei>(c.width);
|
| + GLsizei height = static_cast<GLsizei>(c.height);
|
| + GLint border = static_cast<GLint>(c.border);
|
| + GLsizei image_size = static_cast<GLsizei>(c.imageSize);
|
| + const void* data = GetImmediateDataAs<const void*>(c);
|
| + // Immediate version.
|
| + // TODO(gman): Handle case where data is NULL.
|
| + parse_error::ParseError result =
|
| + ValidateCompressedTexImage2DImmediate(
|
| + this, immediate_data_size, target, level, internal_format, width,
|
| + height, border, image_size, data);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + glCompressedTexImage2D(
|
| + target, level, internal_format, width, height, border, image_size, data);
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleTexImage2D(
|
| + uint32 immediate_data_size, const gles2::TexImage2D& c) {
|
| + GLenum target = static_cast<GLenum>(c.target);
|
| + GLint level = static_cast<GLint>(c.level);
|
| + GLint internal_format = static_cast<GLint>(c.internalformat);
|
| + GLsizei width = static_cast<GLsizei>(c.width);
|
| + GLsizei height = static_cast<GLsizei>(c.height);
|
| + GLint border = static_cast<GLint>(c.border);
|
| + GLenum format = static_cast<GLenum>(c.format);
|
| + GLenum type = static_cast<GLenum>(c.type);
|
| + uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
|
| + uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
|
| + uint32 pixels_size = GLES2Util::ComputeImageDataSize(
|
| + width, height, format, type, unpack_alignment_);
|
| + const void* pixels = NULL;
|
| + if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
|
| + pixels = GetSharedMemoryAs<const void*>(
|
| + pixels_shm_id, pixels_shm_offset, pixels_size);
|
| + parse_error::ParseError result =
|
| + ValidateTexImage2D(
|
| + this, immediate_data_size, target, level, internal_format, width,
|
| + height, border, format, type, pixels);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + }
|
| + // TODO(gman): Validate case where data is NULL.
|
| + glTexImage2D(
|
| + target, level, internal_format, width, height, border, format, type,
|
| + pixels);
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| +parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate(
|
| + uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) {
|
| + GLenum target = static_cast<GLenum>(c.target);
|
| + GLint level = static_cast<GLint>(c.level);
|
| + GLint internalformat = static_cast<GLint>(c.internalformat);
|
| + GLsizei width = static_cast<GLsizei>(c.width);
|
| + GLsizei height = static_cast<GLsizei>(c.height);
|
| + GLint border = static_cast<GLint>(c.border);
|
| + GLenum format = static_cast<GLenum>(c.format);
|
| + GLenum type = static_cast<GLenum>(c.type);
|
| + const void* pixels = GetImmediateDataAs<const void*>(c);
|
| + // Immediate version.
|
| + // TODO(gman): Handle case where data is NULL.
|
| + parse_error::ParseError result =
|
| + ValidateTexImage2DImmediate(
|
| + this, immediate_data_size, target, level, internalformat, width,
|
| + height, border, format, type, pixels);
|
| + if (result != parse_error::kParseNoError) {
|
| + return result;
|
| + }
|
| + glTexImage2D(
|
| + target, level, internalformat, width, height, border, format, type,
|
| + pixels);
|
| + return parse_error::kParseNoError;
|
| +}
|
| +
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetVertexAttribPointerv(
|
| - unsigned int arg_count, const gles2::GetVertexAttribPointerv& c) {
|
| + uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetUniformiv(
|
| - unsigned int arg_count, const gles2::GetUniformiv& c) {
|
| + uint32 immediate_data_size, const gles2::GetUniformiv& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetUniformfv(
|
| - unsigned int arg_count, const gles2::GetUniformfv& c) {
|
| + uint32 immediate_data_size, const gles2::GetUniformfv& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
|
| - unsigned int arg_count, const gles2::GetShaderPrecisionFormat& c) {
|
| + uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetAttachedShaders(
|
| - unsigned int arg_count, const gles2::GetAttachedShaders& c) {
|
| + uint32 immediate_data_size, const gles2::GetAttachedShaders& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetActiveUniform(
|
| - unsigned int arg_count, const gles2::GetActiveUniform& c) {
|
| + uint32 immediate_data_size, const gles2::GetActiveUniform& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError GLES2DecoderImpl::HandleGetActiveAttrib(
|
| - unsigned int arg_count, const gles2::GetActiveAttrib& c) {
|
| + uint32 immediate_data_size, const gles2::GetActiveAttrib& c) {
|
| // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|