| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| index 861fc4a42633459fcf3bc6265e12aab416f979be..dd459a3a33dd9ef3761b80bb3f4ea42beb89a8ab 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -7704,17 +7704,86 @@ void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
|
| error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
|
| uint32 immediate_data_size,
|
| const void* cmd_data) {
|
| - // TODO(zmo): Unsafe ES3 API, missing states update.
|
| if (!unsafe_es3_apis_enabled())
|
| return error::kUnknownCommand;
|
| const gles2::cmds::VertexAttribIPointer& c =
|
| *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
|
| +
|
| + if (!state_.bound_array_buffer.get() ||
|
| + state_.bound_array_buffer->IsDeleted()) {
|
| + if (state_.vertex_attrib_manager.get() ==
|
| + state_.default_vertex_attrib_manager.get()) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glVertexAttribIPointer", "no array buffer bound");
|
| + return error::kNoError;
|
| + } else if (c.offset != 0) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE,
|
| + "glVertexAttribIPointer", "client side arrays are not allowed");
|
| + return error::kNoError;
|
| + }
|
| + }
|
| +
|
| GLuint indx = c.indx;
|
| GLint size = c.size;
|
| GLenum type = c.type;
|
| GLsizei stride = c.stride;
|
| GLsizei offset = c.offset;
|
| const void* ptr = reinterpret_cast<const void*>(offset);
|
| + if (!validators_->vertex_attrib_i_type.IsValid(type)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribIPointer", type, "type");
|
| + return error::kNoError;
|
| + }
|
| + if (!validators_->vertex_attrib_size.IsValid(size)) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glVertexAttribIPointer", "size GL_INVALID_VALUE");
|
| + return error::kNoError;
|
| + }
|
| + if (indx >= group_->max_vertex_attribs()) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glVertexAttribIPointer", "index out of range");
|
| + return error::kNoError;
|
| + }
|
| + if (stride < 0) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glVertexAttribIPointer", "stride < 0");
|
| + return error::kNoError;
|
| + }
|
| + if (stride > 255) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glVertexAttribIPointer", "stride > 255");
|
| + return error::kNoError;
|
| + }
|
| + if (offset < 0) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glVertexAttribIPointer", "offset < 0");
|
| + return error::kNoError;
|
| + }
|
| + GLsizei component_size =
|
| + GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
|
| + // component_size must be a power of two to use & as optimized modulo.
|
| + DCHECK(GLES2Util::IsPOT(component_size));
|
| + if (offset & (component_size - 1)) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_OPERATION,
|
| + "glVertexAttribIPointer", "offset not valid for type");
|
| + return error::kNoError;
|
| + }
|
| + if (stride & (component_size - 1)) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_OPERATION,
|
| + "glVertexAttribIPointer", "stride not valid for type");
|
| + return error::kNoError;
|
| + }
|
| + state_.vertex_attrib_manager
|
| + ->SetAttribInfo(indx,
|
| + state_.bound_array_buffer.get(),
|
| + size,
|
| + type,
|
| + GL_FALSE,
|
| + stride,
|
| + stride != 0 ? stride : component_size * size,
|
| + offset);
|
| glVertexAttribIPointer(indx, size, type, stride, ptr);
|
| return error::kNoError;
|
| }
|
|
|