1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file is auto-generated from
6// gpu/command_buffer/build_gles2_cmd_buffer.py
7// DO NOT EDIT!
8
9// It is included by gles2_cmd_decoder.cc
10#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
11#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
12
13error::Error GLES2DecoderImpl::HandleActiveTexture(
14    uint32 immediate_data_size, const gles2::cmds::ActiveTexture& c) {
15  GLenum texture = static_cast<GLenum>(c.texture);
16  DoActiveTexture(texture);
17  return error::kNoError;
18}
19
20error::Error GLES2DecoderImpl::HandleAttachShader(
21    uint32 immediate_data_size, const gles2::cmds::AttachShader& c) {
22  GLuint program = c.program;
23  GLuint shader = c.shader;
24  DoAttachShader(program, shader);
25  return error::kNoError;
26}
27
28error::Error GLES2DecoderImpl::HandleBindBuffer(
29    uint32 immediate_data_size, const gles2::cmds::BindBuffer& c) {
30  GLenum target = static_cast<GLenum>(c.target);
31  GLuint buffer = c.buffer;
32  if (!validators_->buffer_target.IsValid(target)) {
33    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindBuffer", target, "target");
34    return error::kNoError;
35  }
36  DoBindBuffer(target, buffer);
37  return error::kNoError;
38}
39
40error::Error GLES2DecoderImpl::HandleBindFramebuffer(
41    uint32 immediate_data_size, const gles2::cmds::BindFramebuffer& c) {
42  GLenum target = static_cast<GLenum>(c.target);
43  GLuint framebuffer = c.framebuffer;
44  if (!validators_->frame_buffer_target.IsValid(target)) {
45    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindFramebuffer", target, "target");
46    return error::kNoError;
47  }
48  DoBindFramebuffer(target, framebuffer);
49  return error::kNoError;
50}
51
52error::Error GLES2DecoderImpl::HandleBindRenderbuffer(
53    uint32 immediate_data_size, const gles2::cmds::BindRenderbuffer& c) {
54  GLenum target = static_cast<GLenum>(c.target);
55  GLuint renderbuffer = c.renderbuffer;
56  if (!validators_->render_buffer_target.IsValid(target)) {
57    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindRenderbuffer", target, "target");
58    return error::kNoError;
59  }
60  DoBindRenderbuffer(target, renderbuffer);
61  return error::kNoError;
62}
63
64error::Error GLES2DecoderImpl::HandleBindTexture(
65    uint32 immediate_data_size, const gles2::cmds::BindTexture& c) {
66  GLenum target = static_cast<GLenum>(c.target);
67  GLuint texture = c.texture;
68  if (!validators_->texture_bind_target.IsValid(target)) {
69    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindTexture", target, "target");
70    return error::kNoError;
71  }
72  DoBindTexture(target, texture);
73  return error::kNoError;
74}
75
76error::Error GLES2DecoderImpl::HandleBlendColor(
77    uint32 immediate_data_size, const gles2::cmds::BlendColor& c) {
78  GLclampf red = static_cast<GLclampf>(c.red);
79  GLclampf green = static_cast<GLclampf>(c.green);
80  GLclampf blue = static_cast<GLclampf>(c.blue);
81  GLclampf alpha = static_cast<GLclampf>(c.alpha);
82  if (state_.blend_color_red != red ||
83      state_.blend_color_green != green ||
84      state_.blend_color_blue != blue ||
85      state_.blend_color_alpha != alpha) {
86    state_.blend_color_red = red;
87    state_.blend_color_green = green;
88    state_.blend_color_blue = blue;
89    state_.blend_color_alpha = alpha;
90    glBlendColor(red, green, blue, alpha);
91  }
92  return error::kNoError;
93}
94
95error::Error GLES2DecoderImpl::HandleBlendEquation(
96    uint32 immediate_data_size, const gles2::cmds::BlendEquation& c) {
97  GLenum mode = static_cast<GLenum>(c.mode);
98  if (!validators_->equation.IsValid(mode)) {
99    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendEquation", mode, "mode");
100    return error::kNoError;
101  }
102  if (state_.blend_equation_rgb != mode ||
103      state_.blend_equation_alpha != mode) {
104    state_.blend_equation_rgb = mode;
105    state_.blend_equation_alpha = mode;
106    glBlendEquation(mode);
107  }
108  return error::kNoError;
109}
110
111error::Error GLES2DecoderImpl::HandleBlendEquationSeparate(
112    uint32 immediate_data_size, const gles2::cmds::BlendEquationSeparate& c) {
113  GLenum modeRGB = static_cast<GLenum>(c.modeRGB);
114  GLenum modeAlpha = static_cast<GLenum>(c.modeAlpha);
115  if (!validators_->equation.IsValid(modeRGB)) {
116    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendEquationSeparate", modeRGB,
117    "modeRGB");
118    return error::kNoError;
119  }
120  if (!validators_->equation.IsValid(modeAlpha)) {
121    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendEquationSeparate", modeAlpha,
122    "modeAlpha");
123    return error::kNoError;
124  }
125  if (state_.blend_equation_rgb != modeRGB ||
126      state_.blend_equation_alpha != modeAlpha) {
127    state_.blend_equation_rgb = modeRGB;
128    state_.blend_equation_alpha = modeAlpha;
129    glBlendEquationSeparate(modeRGB, modeAlpha);
130  }
131  return error::kNoError;
132}
133
134error::Error GLES2DecoderImpl::HandleBlendFunc(
135    uint32 immediate_data_size, const gles2::cmds::BlendFunc& c) {
136  GLenum sfactor = static_cast<GLenum>(c.sfactor);
137  GLenum dfactor = static_cast<GLenum>(c.dfactor);
138  if (!validators_->src_blend_factor.IsValid(sfactor)) {
139    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFunc", sfactor, "sfactor");
140    return error::kNoError;
141  }
142  if (!validators_->dst_blend_factor.IsValid(dfactor)) {
143    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFunc", dfactor, "dfactor");
144    return error::kNoError;
145  }
146  if (state_.blend_source_rgb != sfactor ||
147      state_.blend_dest_rgb != dfactor ||
148      state_.blend_source_alpha != sfactor ||
149      state_.blend_dest_alpha != dfactor) {
150    state_.blend_source_rgb = sfactor;
151    state_.blend_dest_rgb = dfactor;
152    state_.blend_source_alpha = sfactor;
153    state_.blend_dest_alpha = dfactor;
154    glBlendFunc(sfactor, dfactor);
155  }
156  return error::kNoError;
157}
158
159error::Error GLES2DecoderImpl::HandleBlendFuncSeparate(
160    uint32 immediate_data_size, const gles2::cmds::BlendFuncSeparate& c) {
161  GLenum srcRGB = static_cast<GLenum>(c.srcRGB);
162  GLenum dstRGB = static_cast<GLenum>(c.dstRGB);
163  GLenum srcAlpha = static_cast<GLenum>(c.srcAlpha);
164  GLenum dstAlpha = static_cast<GLenum>(c.dstAlpha);
165  if (!validators_->src_blend_factor.IsValid(srcRGB)) {
166    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", srcRGB, "srcRGB");
167    return error::kNoError;
168  }
169  if (!validators_->dst_blend_factor.IsValid(dstRGB)) {
170    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", dstRGB, "dstRGB");
171    return error::kNoError;
172  }
173  if (!validators_->src_blend_factor.IsValid(srcAlpha)) {
174    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", srcAlpha,
175    "srcAlpha");
176    return error::kNoError;
177  }
178  if (!validators_->dst_blend_factor.IsValid(dstAlpha)) {
179    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlendFuncSeparate", dstAlpha,
180    "dstAlpha");
181    return error::kNoError;
182  }
183  if (state_.blend_source_rgb != srcRGB ||
184      state_.blend_dest_rgb != dstRGB ||
185      state_.blend_source_alpha != srcAlpha ||
186      state_.blend_dest_alpha != dstAlpha) {
187    state_.blend_source_rgb = srcRGB;
188    state_.blend_dest_rgb = dstRGB;
189    state_.blend_source_alpha = srcAlpha;
190    state_.blend_dest_alpha = dstAlpha;
191    glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
192  }
193  return error::kNoError;
194}
195
196error::Error GLES2DecoderImpl::HandleBufferSubData(
197    uint32 immediate_data_size, const gles2::cmds::BufferSubData& c) {
198  GLenum target = static_cast<GLenum>(c.target);
199  GLintptr offset = static_cast<GLintptr>(c.offset);
200  GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
201  uint32 data_size = size;
202  const void* data = GetSharedMemoryAs<const void*>(
203      c.data_shm_id, c.data_shm_offset, data_size);
204  if (!validators_->buffer_target.IsValid(target)) {
205    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferSubData", target, "target");
206    return error::kNoError;
207  }
208  if (size < 0) {
209    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "size < 0");
210    return error::kNoError;
211  }
212  if (data == NULL) {
213    return error::kOutOfBounds;
214  }
215  DoBufferSubData(target, offset, size, data);
216  return error::kNoError;
217}
218
219error::Error GLES2DecoderImpl::HandleBufferSubDataImmediate(
220    uint32 immediate_data_size, const gles2::cmds::BufferSubDataImmediate& c) {
221  GLenum target = static_cast<GLenum>(c.target);
222  GLintptr offset = static_cast<GLintptr>(c.offset);
223  GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
224  uint32 data_size = size;
225  const void* data = GetImmediateDataAs<const void*>(
226      c, data_size, immediate_data_size);
227  if (!validators_->buffer_target.IsValid(target)) {
228    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferSubData", target, "target");
229    return error::kNoError;
230  }
231  if (size < 0) {
232    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "size < 0");
233    return error::kNoError;
234  }
235  if (data == NULL) {
236    return error::kOutOfBounds;
237  }
238  DoBufferSubData(target, offset, size, data);
239  return error::kNoError;
240}
241
242error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus(
243    uint32 immediate_data_size, const gles2::cmds::CheckFramebufferStatus& c) {
244  GLenum target = static_cast<GLenum>(c.target);
245  typedef cmds::CheckFramebufferStatus::Result Result;
246  Result* result_dst = GetSharedMemoryAs<Result*>(
247      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
248  if (!result_dst) {
249    return error::kOutOfBounds;
250  }
251  if (!validators_->frame_buffer_target.IsValid(target)) {
252    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCheckFramebufferStatus", target,
253    "target");
254    return error::kNoError;
255  }
256  *result_dst = DoCheckFramebufferStatus(target);
257  return error::kNoError;
258}
259
260error::Error GLES2DecoderImpl::HandleClear(
261    uint32 immediate_data_size, const gles2::cmds::Clear& c) {
262  if (ShouldDeferDraws())
263    return error::kDeferCommandUntilLater;
264  GLbitfield mask = static_cast<GLbitfield>(c.mask);
265  DoClear(mask);
266  return error::kNoError;
267}
268
269error::Error GLES2DecoderImpl::HandleClearColor(
270    uint32 immediate_data_size, const gles2::cmds::ClearColor& c) {
271  GLclampf red = static_cast<GLclampf>(c.red);
272  GLclampf green = static_cast<GLclampf>(c.green);
273  GLclampf blue = static_cast<GLclampf>(c.blue);
274  GLclampf alpha = static_cast<GLclampf>(c.alpha);
275  if (state_.color_clear_red != red ||
276      state_.color_clear_green != green ||
277      state_.color_clear_blue != blue ||
278      state_.color_clear_alpha != alpha) {
279    state_.color_clear_red = red;
280    state_.color_clear_green = green;
281    state_.color_clear_blue = blue;
282    state_.color_clear_alpha = alpha;
283    glClearColor(red, green, blue, alpha);
284  }
285  return error::kNoError;
286}
287
288error::Error GLES2DecoderImpl::HandleClearDepthf(
289    uint32 immediate_data_size, const gles2::cmds::ClearDepthf& c) {
290  GLclampf depth = static_cast<GLclampf>(c.depth);
291  if (state_.depth_clear != depth) {
292    state_.depth_clear = depth;
293    glClearDepth(depth);
294  }
295  return error::kNoError;
296}
297
298error::Error GLES2DecoderImpl::HandleClearStencil(
299    uint32 immediate_data_size, const gles2::cmds::ClearStencil& c) {
300  GLint s = static_cast<GLint>(c.s);
301  if (state_.stencil_clear != s) {
302    state_.stencil_clear = s;
303    glClearStencil(s);
304  }
305  return error::kNoError;
306}
307
308error::Error GLES2DecoderImpl::HandleColorMask(
309    uint32 immediate_data_size, const gles2::cmds::ColorMask& c) {
310  GLboolean red = static_cast<GLboolean>(c.red);
311  GLboolean green = static_cast<GLboolean>(c.green);
312  GLboolean blue = static_cast<GLboolean>(c.blue);
313  GLboolean alpha = static_cast<GLboolean>(c.alpha);
314  if (state_.color_mask_red != red ||
315      state_.color_mask_green != green ||
316      state_.color_mask_blue != blue ||
317      state_.color_mask_alpha != alpha) {
318    state_.color_mask_red = red;
319    state_.color_mask_green = green;
320    state_.color_mask_blue = blue;
321    state_.color_mask_alpha = alpha;
322    clear_state_dirty_ = true;
323  }
324  return error::kNoError;
325}
326
327error::Error GLES2DecoderImpl::HandleCompileShader(
328    uint32 immediate_data_size, const gles2::cmds::CompileShader& c) {
329  GLuint shader = c.shader;
330  DoCompileShader(shader);
331  return error::kNoError;
332}
333
334error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D(
335    uint32 immediate_data_size,
336    const gles2::cmds::CompressedTexSubImage2D& c) {
337  GLenum target = static_cast<GLenum>(c.target);
338  GLint level = static_cast<GLint>(c.level);
339  GLint xoffset = static_cast<GLint>(c.xoffset);
340  GLint yoffset = static_cast<GLint>(c.yoffset);
341  GLsizei width = static_cast<GLsizei>(c.width);
342  GLsizei height = static_cast<GLsizei>(c.height);
343  GLenum format = static_cast<GLenum>(c.format);
344  GLsizei imageSize = static_cast<GLsizei>(c.imageSize);
345  uint32 data_size = imageSize;
346  const void* data = GetSharedMemoryAs<const void*>(
347      c.data_shm_id, c.data_shm_offset, data_size);
348  if (!validators_->texture_target.IsValid(target)) {
349    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", target,
350    "target");
351    return error::kNoError;
352  }
353  if (width < 0) {
354    LOCAL_SET_GL_ERROR(
355        GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
356    return error::kNoError;
357  }
358  if (height < 0) {
359    LOCAL_SET_GL_ERROR(
360        GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
361    return error::kNoError;
362  }
363  if (!validators_->compressed_texture_format.IsValid(format)) {
364    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", format,
365    "format");
366    return error::kNoError;
367  }
368  if (imageSize < 0) {
369    LOCAL_SET_GL_ERROR(
370        GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
371    return error::kNoError;
372  }
373  if (data == NULL) {
374    return error::kOutOfBounds;
375  }
376  DoCompressedTexSubImage2D(
377      target, level, xoffset, yoffset, width, height, format, imageSize, data);
378  return error::kNoError;
379}
380
381error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DImmediate(
382    uint32 immediate_data_size,
383    const gles2::cmds::CompressedTexSubImage2DImmediate& c) {
384  GLenum target = static_cast<GLenum>(c.target);
385  GLint level = static_cast<GLint>(c.level);
386  GLint xoffset = static_cast<GLint>(c.xoffset);
387  GLint yoffset = static_cast<GLint>(c.yoffset);
388  GLsizei width = static_cast<GLsizei>(c.width);
389  GLsizei height = static_cast<GLsizei>(c.height);
390  GLenum format = static_cast<GLenum>(c.format);
391  GLsizei imageSize = static_cast<GLsizei>(c.imageSize);
392  uint32 data_size = imageSize;
393  const void* data = GetImmediateDataAs<const void*>(
394      c, data_size, immediate_data_size);
395  if (!validators_->texture_target.IsValid(target)) {
396    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", target,
397    "target");
398    return error::kNoError;
399  }
400  if (width < 0) {
401    LOCAL_SET_GL_ERROR(
402        GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
403    return error::kNoError;
404  }
405  if (height < 0) {
406    LOCAL_SET_GL_ERROR(
407        GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
408    return error::kNoError;
409  }
410  if (!validators_->compressed_texture_format.IsValid(format)) {
411    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCompressedTexSubImage2D", format,
412    "format");
413    return error::kNoError;
414  }
415  if (imageSize < 0) {
416    LOCAL_SET_GL_ERROR(
417        GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
418    return error::kNoError;
419  }
420  if (data == NULL) {
421    return error::kOutOfBounds;
422  }
423  DoCompressedTexSubImage2D(
424      target, level, xoffset, yoffset, width, height, format, imageSize, data);
425  return error::kNoError;
426}
427
428error::Error GLES2DecoderImpl::HandleCopyTexImage2D(
429    uint32 immediate_data_size, const gles2::cmds::CopyTexImage2D& c) {
430  if (ShouldDeferReads())
431    return error::kDeferCommandUntilLater;
432  GLenum target = static_cast<GLenum>(c.target);
433  GLint level = static_cast<GLint>(c.level);
434  GLenum internalformat = static_cast<GLenum>(c.internalformat);
435  GLint x = static_cast<GLint>(c.x);
436  GLint y = static_cast<GLint>(c.y);
437  GLsizei width = static_cast<GLsizei>(c.width);
438  GLsizei height = static_cast<GLsizei>(c.height);
439  GLint border = static_cast<GLint>(c.border);
440  if (!validators_->texture_target.IsValid(target)) {
441    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTexImage2D", target, "target");
442    return error::kNoError;
443  }
444  if (!validators_->texture_internal_format.IsValid(internalformat)) {
445    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTexImage2D", internalformat,
446    "internalformat");
447    return error::kNoError;
448  }
449  if (width < 0) {
450    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexImage2D", "width < 0");
451    return error::kNoError;
452  }
453  if (height < 0) {
454    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexImage2D", "height < 0");
455    return error::kNoError;
456  }
457  if (!validators_->texture_border.IsValid(border)) {
458    LOCAL_SET_GL_ERROR(
459        GL_INVALID_VALUE, "glCopyTexImage2D", "border GL_INVALID_VALUE");
460    return error::kNoError;
461  }
462  DoCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
463  return error::kNoError;
464}
465
466error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D(
467    uint32 immediate_data_size, const gles2::cmds::CopyTexSubImage2D& c) {
468  if (ShouldDeferReads())
469    return error::kDeferCommandUntilLater;
470  GLenum target = static_cast<GLenum>(c.target);
471  GLint level = static_cast<GLint>(c.level);
472  GLint xoffset = static_cast<GLint>(c.xoffset);
473  GLint yoffset = static_cast<GLint>(c.yoffset);
474  GLint x = static_cast<GLint>(c.x);
475  GLint y = static_cast<GLint>(c.y);
476  GLsizei width = static_cast<GLsizei>(c.width);
477  GLsizei height = static_cast<GLsizei>(c.height);
478  if (!validators_->texture_target.IsValid(target)) {
479    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTexSubImage2D", target, "target");
480    return error::kNoError;
481  }
482  if (width < 0) {
483    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexSubImage2D", "width < 0");
484    return error::kNoError;
485  }
486  if (height < 0) {
487    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyTexSubImage2D", "height < 0");
488    return error::kNoError;
489  }
490  DoCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
491  return error::kNoError;
492}
493
494error::Error GLES2DecoderImpl::HandleCreateProgram(
495    uint32 immediate_data_size, const gles2::cmds::CreateProgram& c) {
496  uint32 client_id = c.client_id;
497  if (!CreateProgramHelper(client_id)) {
498    return error::kInvalidArguments;
499  }
500  return error::kNoError;
501}
502
503error::Error GLES2DecoderImpl::HandleCreateShader(
504    uint32 immediate_data_size, const gles2::cmds::CreateShader& c) {
505  GLenum type = static_cast<GLenum>(c.type);
506  if (!validators_->shader_type.IsValid(type)) {
507    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCreateShader", type, "type");
508    return error::kNoError;
509  }
510  uint32 client_id = c.client_id;
511  if (!CreateShaderHelper(type, client_id)) {
512    return error::kInvalidArguments;
513  }
514  return error::kNoError;
515}
516
517error::Error GLES2DecoderImpl::HandleCullFace(
518    uint32 immediate_data_size, const gles2::cmds::CullFace& c) {
519  GLenum mode = static_cast<GLenum>(c.mode);
520  if (!validators_->face_type.IsValid(mode)) {
521    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCullFace", mode, "mode");
522    return error::kNoError;
523  }
524  if (state_.cull_mode != mode) {
525    state_.cull_mode = mode;
526    glCullFace(mode);
527  }
528  return error::kNoError;
529}
530
531error::Error GLES2DecoderImpl::HandleDeleteBuffers(
532    uint32 immediate_data_size, const gles2::cmds::DeleteBuffers& c) {
533  GLsizei n = static_cast<GLsizei>(c.n);
534  uint32 data_size;
535  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
536    return error::kOutOfBounds;
537  }
538  const GLuint* buffers = GetSharedMemoryAs<const GLuint*>(
539      c.buffers_shm_id, c.buffers_shm_offset, data_size);
540  if (buffers == NULL) {
541    return error::kOutOfBounds;
542  }
543  DeleteBuffersHelper(n, buffers);
544  return error::kNoError;
545}
546
547error::Error GLES2DecoderImpl::HandleDeleteBuffersImmediate(
548    uint32 immediate_data_size, const gles2::cmds::DeleteBuffersImmediate& c) {
549  GLsizei n = static_cast<GLsizei>(c.n);
550  uint32 data_size;
551  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
552    return error::kOutOfBounds;
553  }
554  const GLuint* buffers = GetImmediateDataAs<const GLuint*>(
555      c, data_size, immediate_data_size);
556  if (buffers == NULL) {
557    return error::kOutOfBounds;
558  }
559  DeleteBuffersHelper(n, buffers);
560  return error::kNoError;
561}
562
563error::Error GLES2DecoderImpl::HandleDeleteFramebuffers(
564    uint32 immediate_data_size, const gles2::cmds::DeleteFramebuffers& c) {
565  GLsizei n = static_cast<GLsizei>(c.n);
566  uint32 data_size;
567  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
568    return error::kOutOfBounds;
569  }
570  const GLuint* framebuffers = GetSharedMemoryAs<const GLuint*>(
571      c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size);
572  if (framebuffers == NULL) {
573    return error::kOutOfBounds;
574  }
575  DeleteFramebuffersHelper(n, framebuffers);
576  return error::kNoError;
577}
578
579error::Error GLES2DecoderImpl::HandleDeleteFramebuffersImmediate(
580    uint32 immediate_data_size,
581    const gles2::cmds::DeleteFramebuffersImmediate& c) {
582  GLsizei n = static_cast<GLsizei>(c.n);
583  uint32 data_size;
584  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
585    return error::kOutOfBounds;
586  }
587  const GLuint* framebuffers = GetImmediateDataAs<const GLuint*>(
588      c, data_size, immediate_data_size);
589  if (framebuffers == NULL) {
590    return error::kOutOfBounds;
591  }
592  DeleteFramebuffersHelper(n, framebuffers);
593  return error::kNoError;
594}
595
596error::Error GLES2DecoderImpl::HandleDeleteRenderbuffers(
597    uint32 immediate_data_size, const gles2::cmds::DeleteRenderbuffers& c) {
598  GLsizei n = static_cast<GLsizei>(c.n);
599  uint32 data_size;
600  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
601    return error::kOutOfBounds;
602  }
603  const GLuint* renderbuffers = GetSharedMemoryAs<const GLuint*>(
604      c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size);
605  if (renderbuffers == NULL) {
606    return error::kOutOfBounds;
607  }
608  DeleteRenderbuffersHelper(n, renderbuffers);
609  return error::kNoError;
610}
611
612error::Error GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate(
613    uint32 immediate_data_size,
614    const gles2::cmds::DeleteRenderbuffersImmediate& c) {
615  GLsizei n = static_cast<GLsizei>(c.n);
616  uint32 data_size;
617  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
618    return error::kOutOfBounds;
619  }
620  const GLuint* renderbuffers = GetImmediateDataAs<const GLuint*>(
621      c, data_size, immediate_data_size);
622  if (renderbuffers == NULL) {
623    return error::kOutOfBounds;
624  }
625  DeleteRenderbuffersHelper(n, renderbuffers);
626  return error::kNoError;
627}
628
629error::Error GLES2DecoderImpl::HandleDeleteTextures(
630    uint32 immediate_data_size, const gles2::cmds::DeleteTextures& c) {
631  GLsizei n = static_cast<GLsizei>(c.n);
632  uint32 data_size;
633  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
634    return error::kOutOfBounds;
635  }
636  const GLuint* textures = GetSharedMemoryAs<const GLuint*>(
637      c.textures_shm_id, c.textures_shm_offset, data_size);
638  if (textures == NULL) {
639    return error::kOutOfBounds;
640  }
641  DeleteTexturesHelper(n, textures);
642  return error::kNoError;
643}
644
645error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate(
646    uint32 immediate_data_size,
647    const gles2::cmds::DeleteTexturesImmediate& c) {
648  GLsizei n = static_cast<GLsizei>(c.n);
649  uint32 data_size;
650  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
651    return error::kOutOfBounds;
652  }
653  const GLuint* textures = GetImmediateDataAs<const GLuint*>(
654      c, data_size, immediate_data_size);
655  if (textures == NULL) {
656    return error::kOutOfBounds;
657  }
658  DeleteTexturesHelper(n, textures);
659  return error::kNoError;
660}
661
662error::Error GLES2DecoderImpl::HandleDepthFunc(
663    uint32 immediate_data_size, const gles2::cmds::DepthFunc& c) {
664  GLenum func = static_cast<GLenum>(c.func);
665  if (!validators_->cmp_function.IsValid(func)) {
666    LOCAL_SET_GL_ERROR_INVALID_ENUM("glDepthFunc", func, "func");
667    return error::kNoError;
668  }
669  if (state_.depth_func != func) {
670    state_.depth_func = func;
671    glDepthFunc(func);
672  }
673  return error::kNoError;
674}
675
676error::Error GLES2DecoderImpl::HandleDepthMask(
677    uint32 immediate_data_size, const gles2::cmds::DepthMask& c) {
678  GLboolean flag = static_cast<GLboolean>(c.flag);
679  if (state_.depth_mask != flag) {
680    state_.depth_mask = flag;
681    clear_state_dirty_ = true;
682  }
683  return error::kNoError;
684}
685
686error::Error GLES2DecoderImpl::HandleDepthRangef(
687    uint32 immediate_data_size, const gles2::cmds::DepthRangef& c) {
688  GLclampf zNear = static_cast<GLclampf>(c.zNear);
689  GLclampf zFar = static_cast<GLclampf>(c.zFar);
690  DoDepthRangef(zNear, zFar);
691  return error::kNoError;
692}
693
694error::Error GLES2DecoderImpl::HandleDetachShader(
695    uint32 immediate_data_size, const gles2::cmds::DetachShader& c) {
696  GLuint program = c.program;
697  GLuint shader = c.shader;
698  DoDetachShader(program, shader);
699  return error::kNoError;
700}
701
702error::Error GLES2DecoderImpl::HandleDisable(
703    uint32 immediate_data_size, const gles2::cmds::Disable& c) {
704  GLenum cap = static_cast<GLenum>(c.cap);
705  if (!validators_->capability.IsValid(cap)) {
706    LOCAL_SET_GL_ERROR_INVALID_ENUM("glDisable", cap, "cap");
707    return error::kNoError;
708  }
709  DoDisable(cap);
710  return error::kNoError;
711}
712
713error::Error GLES2DecoderImpl::HandleDisableVertexAttribArray(
714    uint32 immediate_data_size,
715    const gles2::cmds::DisableVertexAttribArray& c) {
716  GLuint index = static_cast<GLuint>(c.index);
717  DoDisableVertexAttribArray(index);
718  return error::kNoError;
719}
720
721error::Error GLES2DecoderImpl::HandleEnable(
722    uint32 immediate_data_size, const gles2::cmds::Enable& c) {
723  GLenum cap = static_cast<GLenum>(c.cap);
724  if (!validators_->capability.IsValid(cap)) {
725    LOCAL_SET_GL_ERROR_INVALID_ENUM("glEnable", cap, "cap");
726    return error::kNoError;
727  }
728  DoEnable(cap);
729  return error::kNoError;
730}
731
732error::Error GLES2DecoderImpl::HandleEnableVertexAttribArray(
733    uint32 immediate_data_size,
734    const gles2::cmds::EnableVertexAttribArray& c) {
735  GLuint index = static_cast<GLuint>(c.index);
736  DoEnableVertexAttribArray(index);
737  return error::kNoError;
738}
739
740error::Error GLES2DecoderImpl::HandleFinish(
741    uint32 immediate_data_size, const gles2::cmds::Finish& c) {
742  if (ShouldDeferReads())
743    return error::kDeferCommandUntilLater;
744  DoFinish();
745  return error::kNoError;
746}
747
748error::Error GLES2DecoderImpl::HandleFlush(
749    uint32 immediate_data_size, const gles2::cmds::Flush& c) {
750  DoFlush();
751  return error::kNoError;
752}
753
754error::Error GLES2DecoderImpl::HandleFramebufferRenderbuffer(
755    uint32 immediate_data_size,
756    const gles2::cmds::FramebufferRenderbuffer& c) {
757  GLenum target = static_cast<GLenum>(c.target);
758  GLenum attachment = static_cast<GLenum>(c.attachment);
759  GLenum renderbuffertarget = static_cast<GLenum>(c.renderbuffertarget);
760  GLuint renderbuffer = c.renderbuffer;
761  if (!validators_->frame_buffer_target.IsValid(target)) {
762    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferRenderbuffer", target,
763    "target");
764    return error::kNoError;
765  }
766  if (!validators_->attachment.IsValid(attachment)) {
767    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferRenderbuffer", attachment,
768    "attachment");
769    return error::kNoError;
770  }
771  if (!validators_->render_buffer_target.IsValid(renderbuffertarget)) {
772    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferRenderbuffer", renderbuffertarget, "renderbuffertarget");  // NOLINT
773    return error::kNoError;
774  }
775  DoFramebufferRenderbuffer(
776      target, attachment, renderbuffertarget, renderbuffer);
777  return error::kNoError;
778}
779
780error::Error GLES2DecoderImpl::HandleFramebufferTexture2D(
781    uint32 immediate_data_size, const gles2::cmds::FramebufferTexture2D& c) {
782  GLenum target = static_cast<GLenum>(c.target);
783  GLenum attachment = static_cast<GLenum>(c.attachment);
784  GLenum textarget = static_cast<GLenum>(c.textarget);
785  GLuint texture = c.texture;
786  GLint level = static_cast<GLint>(c.level);
787  if (!validators_->frame_buffer_target.IsValid(target)) {
788    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2D", target,
789    "target");
790    return error::kNoError;
791  }
792  if (!validators_->attachment.IsValid(attachment)) {
793    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2D", attachment,
794    "attachment");
795    return error::kNoError;
796  }
797  if (!validators_->texture_target.IsValid(textarget)) {
798    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2D", textarget,
799    "textarget");
800    return error::kNoError;
801  }
802  if (!validators_->zero_only.IsValid(level)) {
803    LOCAL_SET_GL_ERROR(
804        GL_INVALID_VALUE, "glFramebufferTexture2D", "level GL_INVALID_VALUE");
805    return error::kNoError;
806  }
807  DoFramebufferTexture2D(target, attachment, textarget, texture, level);
808  return error::kNoError;
809}
810
811error::Error GLES2DecoderImpl::HandleFrontFace(
812    uint32 immediate_data_size, const gles2::cmds::FrontFace& c) {
813  GLenum mode = static_cast<GLenum>(c.mode);
814  if (!validators_->face_mode.IsValid(mode)) {
815    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFrontFace", mode, "mode");
816    return error::kNoError;
817  }
818  if (state_.front_face != mode) {
819    state_.front_face = mode;
820    glFrontFace(mode);
821  }
822  return error::kNoError;
823}
824
825error::Error GLES2DecoderImpl::HandleGenBuffers(
826    uint32 immediate_data_size, const gles2::cmds::GenBuffers& c) {
827  GLsizei n = static_cast<GLsizei>(c.n);
828  uint32 data_size;
829  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
830    return error::kOutOfBounds;
831  }
832  GLuint* buffers = GetSharedMemoryAs<GLuint*>(
833      c.buffers_shm_id, c.buffers_shm_offset, data_size);
834  if (buffers == NULL) {
835    return error::kOutOfBounds;
836  }
837  if (!GenBuffersHelper(n, buffers)) {
838    return error::kInvalidArguments;
839  }
840  return error::kNoError;
841}
842
843error::Error GLES2DecoderImpl::HandleGenBuffersImmediate(
844    uint32 immediate_data_size, const gles2::cmds::GenBuffersImmediate& c) {
845  GLsizei n = static_cast<GLsizei>(c.n);
846  uint32 data_size;
847  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
848    return error::kOutOfBounds;
849  }
850  GLuint* buffers = GetImmediateDataAs<GLuint*>(
851      c, data_size, immediate_data_size);
852  if (buffers == NULL) {
853    return error::kOutOfBounds;
854  }
855  if (!GenBuffersHelper(n, buffers)) {
856    return error::kInvalidArguments;
857  }
858  return error::kNoError;
859}
860
861error::Error GLES2DecoderImpl::HandleGenerateMipmap(
862    uint32 immediate_data_size, const gles2::cmds::GenerateMipmap& c) {
863  GLenum target = static_cast<GLenum>(c.target);
864  if (!validators_->texture_bind_target.IsValid(target)) {
865    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGenerateMipmap", target, "target");
866    return error::kNoError;
867  }
868  DoGenerateMipmap(target);
869  return error::kNoError;
870}
871
872error::Error GLES2DecoderImpl::HandleGenFramebuffers(
873    uint32 immediate_data_size, const gles2::cmds::GenFramebuffers& c) {
874  GLsizei n = static_cast<GLsizei>(c.n);
875  uint32 data_size;
876  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
877    return error::kOutOfBounds;
878  }
879  GLuint* framebuffers = GetSharedMemoryAs<GLuint*>(
880      c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size);
881  if (framebuffers == NULL) {
882    return error::kOutOfBounds;
883  }
884  if (!GenFramebuffersHelper(n, framebuffers)) {
885    return error::kInvalidArguments;
886  }
887  return error::kNoError;
888}
889
890error::Error GLES2DecoderImpl::HandleGenFramebuffersImmediate(
891    uint32 immediate_data_size,
892    const gles2::cmds::GenFramebuffersImmediate& c) {
893  GLsizei n = static_cast<GLsizei>(c.n);
894  uint32 data_size;
895  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
896    return error::kOutOfBounds;
897  }
898  GLuint* framebuffers = GetImmediateDataAs<GLuint*>(
899      c, data_size, immediate_data_size);
900  if (framebuffers == NULL) {
901    return error::kOutOfBounds;
902  }
903  if (!GenFramebuffersHelper(n, framebuffers)) {
904    return error::kInvalidArguments;
905  }
906  return error::kNoError;
907}
908
909error::Error GLES2DecoderImpl::HandleGenRenderbuffers(
910    uint32 immediate_data_size, const gles2::cmds::GenRenderbuffers& c) {
911  GLsizei n = static_cast<GLsizei>(c.n);
912  uint32 data_size;
913  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
914    return error::kOutOfBounds;
915  }
916  GLuint* renderbuffers = GetSharedMemoryAs<GLuint*>(
917      c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size);
918  if (renderbuffers == NULL) {
919    return error::kOutOfBounds;
920  }
921  if (!GenRenderbuffersHelper(n, renderbuffers)) {
922    return error::kInvalidArguments;
923  }
924  return error::kNoError;
925}
926
927error::Error GLES2DecoderImpl::HandleGenRenderbuffersImmediate(
928    uint32 immediate_data_size,
929    const gles2::cmds::GenRenderbuffersImmediate& c) {
930  GLsizei n = static_cast<GLsizei>(c.n);
931  uint32 data_size;
932  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
933    return error::kOutOfBounds;
934  }
935  GLuint* renderbuffers = GetImmediateDataAs<GLuint*>(
936      c, data_size, immediate_data_size);
937  if (renderbuffers == NULL) {
938    return error::kOutOfBounds;
939  }
940  if (!GenRenderbuffersHelper(n, renderbuffers)) {
941    return error::kInvalidArguments;
942  }
943  return error::kNoError;
944}
945
946error::Error GLES2DecoderImpl::HandleGenTextures(
947    uint32 immediate_data_size, const gles2::cmds::GenTextures& c) {
948  GLsizei n = static_cast<GLsizei>(c.n);
949  uint32 data_size;
950  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
951    return error::kOutOfBounds;
952  }
953  GLuint* textures = GetSharedMemoryAs<GLuint*>(
954      c.textures_shm_id, c.textures_shm_offset, data_size);
955  if (textures == NULL) {
956    return error::kOutOfBounds;
957  }
958  if (!GenTexturesHelper(n, textures)) {
959    return error::kInvalidArguments;
960  }
961  return error::kNoError;
962}
963
964error::Error GLES2DecoderImpl::HandleGenTexturesImmediate(
965    uint32 immediate_data_size, const gles2::cmds::GenTexturesImmediate& c) {
966  GLsizei n = static_cast<GLsizei>(c.n);
967  uint32 data_size;
968  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
969    return error::kOutOfBounds;
970  }
971  GLuint* textures = GetImmediateDataAs<GLuint*>(
972      c, data_size, immediate_data_size);
973  if (textures == NULL) {
974    return error::kOutOfBounds;
975  }
976  if (!GenTexturesHelper(n, textures)) {
977    return error::kInvalidArguments;
978  }
979  return error::kNoError;
980}
981
982error::Error GLES2DecoderImpl::HandleGetBooleanv(
983    uint32 immediate_data_size, const gles2::cmds::GetBooleanv& c) {
984  GLenum pname = static_cast<GLenum>(c.pname);
985  typedef cmds::GetBooleanv::Result Result;
986  GLsizei num_values = 0;
987  GetNumValuesReturnedForGLGet(pname, &num_values);
988  Result* result = GetSharedMemoryAs<Result*>(
989      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
990  GLboolean* params = result ? result->GetData() : NULL;
991  if (!validators_->g_l_state.IsValid(pname)) {
992    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetBooleanv", pname, "pname");
993    return error::kNoError;
994  }
995  if (params == NULL) {
996    return error::kOutOfBounds;
997  }
998  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetBooleanv");
999  // Check that the client initialized the result.
1000  if (result->size != 0) {
1001    return error::kInvalidArguments;
1002  }
1003  DoGetBooleanv(pname, params);
1004  GLenum error = glGetError();
1005  if (error == GL_NO_ERROR) {
1006    result->SetNumResults(num_values);
1007  } else {
1008    LOCAL_SET_GL_ERROR(error, "GetBooleanv", "");
1009  }
1010  return error::kNoError;
1011}
1012
1013error::Error GLES2DecoderImpl::HandleGetBufferParameteriv(
1014    uint32 immediate_data_size, const gles2::cmds::GetBufferParameteriv& c) {
1015  GLenum target = static_cast<GLenum>(c.target);
1016  GLenum pname = static_cast<GLenum>(c.pname);
1017  typedef cmds::GetBufferParameteriv::Result Result;
1018  GLsizei num_values = 0;
1019  GetNumValuesReturnedForGLGet(pname, &num_values);
1020  Result* result = GetSharedMemoryAs<Result*>(
1021      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1022  GLint* params = result ? result->GetData() : NULL;
1023  if (!validators_->buffer_target.IsValid(target)) {
1024    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetBufferParameteriv", target,
1025    "target");
1026    return error::kNoError;
1027  }
1028  if (!validators_->buffer_parameter.IsValid(pname)) {
1029    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetBufferParameteriv", pname, "pname");
1030    return error::kNoError;
1031  }
1032  if (params == NULL) {
1033    return error::kOutOfBounds;
1034  }
1035  // Check that the client initialized the result.
1036  if (result->size != 0) {
1037    return error::kInvalidArguments;
1038  }
1039  DoGetBufferParameteriv(target, pname, params);
1040  result->SetNumResults(num_values);
1041  return error::kNoError;
1042}
1043error::Error GLES2DecoderImpl::HandleGetError(
1044    uint32 immediate_data_size, const gles2::cmds::GetError& c) {
1045  typedef cmds::GetError::Result Result;
1046  Result* result_dst = GetSharedMemoryAs<Result*>(
1047      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1048  if (!result_dst) {
1049    return error::kOutOfBounds;
1050  }
1051  *result_dst = GetErrorState()->GetGLError();
1052  return error::kNoError;
1053}
1054
1055error::Error GLES2DecoderImpl::HandleGetFloatv(
1056    uint32 immediate_data_size, const gles2::cmds::GetFloatv& c) {
1057  GLenum pname = static_cast<GLenum>(c.pname);
1058  typedef cmds::GetFloatv::Result Result;
1059  GLsizei num_values = 0;
1060  GetNumValuesReturnedForGLGet(pname, &num_values);
1061  Result* result = GetSharedMemoryAs<Result*>(
1062      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1063  GLfloat* params = result ? result->GetData() : NULL;
1064  if (!validators_->g_l_state.IsValid(pname)) {
1065    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFloatv", pname, "pname");
1066    return error::kNoError;
1067  }
1068  if (params == NULL) {
1069    return error::kOutOfBounds;
1070  }
1071  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetFloatv");
1072  // Check that the client initialized the result.
1073  if (result->size != 0) {
1074    return error::kInvalidArguments;
1075  }
1076  DoGetFloatv(pname, params);
1077  GLenum error = glGetError();
1078  if (error == GL_NO_ERROR) {
1079    result->SetNumResults(num_values);
1080  } else {
1081    LOCAL_SET_GL_ERROR(error, "GetFloatv", "");
1082  }
1083  return error::kNoError;
1084}
1085
1086error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv(
1087    uint32 immediate_data_size,
1088    const gles2::cmds::GetFramebufferAttachmentParameteriv& c) {
1089  GLenum target = static_cast<GLenum>(c.target);
1090  GLenum attachment = static_cast<GLenum>(c.attachment);
1091  GLenum pname = static_cast<GLenum>(c.pname);
1092  typedef cmds::GetFramebufferAttachmentParameteriv::Result Result;
1093  GLsizei num_values = 0;
1094  GetNumValuesReturnedForGLGet(pname, &num_values);
1095  Result* result = GetSharedMemoryAs<Result*>(
1096      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1097  GLint* params = result ? result->GetData() : NULL;
1098  if (!validators_->frame_buffer_target.IsValid(target)) {
1099    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", target, "target");  // NOLINT
1100    return error::kNoError;
1101  }
1102  if (!validators_->attachment.IsValid(attachment)) {
1103    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", attachment, "attachment");  // NOLINT
1104    return error::kNoError;
1105  }
1106  if (!validators_->frame_buffer_parameter.IsValid(pname)) {
1107    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", pname, "pname");  // NOLINT
1108    return error::kNoError;
1109  }
1110  if (params == NULL) {
1111    return error::kOutOfBounds;
1112  }
1113  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetFramebufferAttachmentParameteriv");
1114  // Check that the client initialized the result.
1115  if (result->size != 0) {
1116    return error::kInvalidArguments;
1117  }
1118  DoGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
1119  GLenum error = glGetError();
1120  if (error == GL_NO_ERROR) {
1121    result->SetNumResults(num_values);
1122  } else {
1123    LOCAL_SET_GL_ERROR(error, "GetFramebufferAttachmentParameteriv", "");
1124  }
1125  return error::kNoError;
1126}
1127
1128error::Error GLES2DecoderImpl::HandleGetIntegerv(
1129    uint32 immediate_data_size, const gles2::cmds::GetIntegerv& c) {
1130  GLenum pname = static_cast<GLenum>(c.pname);
1131  typedef cmds::GetIntegerv::Result Result;
1132  GLsizei num_values = 0;
1133  GetNumValuesReturnedForGLGet(pname, &num_values);
1134  Result* result = GetSharedMemoryAs<Result*>(
1135      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1136  GLint* params = result ? result->GetData() : NULL;
1137  if (!validators_->g_l_state.IsValid(pname)) {
1138    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetIntegerv", pname, "pname");
1139    return error::kNoError;
1140  }
1141  if (params == NULL) {
1142    return error::kOutOfBounds;
1143  }
1144  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetIntegerv");
1145  // Check that the client initialized the result.
1146  if (result->size != 0) {
1147    return error::kInvalidArguments;
1148  }
1149  DoGetIntegerv(pname, params);
1150  GLenum error = glGetError();
1151  if (error == GL_NO_ERROR) {
1152    result->SetNumResults(num_values);
1153  } else {
1154    LOCAL_SET_GL_ERROR(error, "GetIntegerv", "");
1155  }
1156  return error::kNoError;
1157}
1158
1159error::Error GLES2DecoderImpl::HandleGetProgramiv(
1160    uint32 immediate_data_size, const gles2::cmds::GetProgramiv& c) {
1161  GLuint program = c.program;
1162  GLenum pname = static_cast<GLenum>(c.pname);
1163  typedef cmds::GetProgramiv::Result Result;
1164  GLsizei num_values = 0;
1165  GetNumValuesReturnedForGLGet(pname, &num_values);
1166  Result* result = GetSharedMemoryAs<Result*>(
1167      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1168  GLint* params = result ? result->GetData() : NULL;
1169  if (!validators_->program_parameter.IsValid(pname)) {
1170    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetProgramiv", pname, "pname");
1171    return error::kNoError;
1172  }
1173  if (params == NULL) {
1174    return error::kOutOfBounds;
1175  }
1176  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetProgramiv");
1177  // Check that the client initialized the result.
1178  if (result->size != 0) {
1179    return error::kInvalidArguments;
1180  }
1181  DoGetProgramiv(program, pname, params);
1182  GLenum error = glGetError();
1183  if (error == GL_NO_ERROR) {
1184    result->SetNumResults(num_values);
1185  } else {
1186    LOCAL_SET_GL_ERROR(error, "GetProgramiv", "");
1187  }
1188  return error::kNoError;
1189}
1190
1191error::Error GLES2DecoderImpl::HandleGetRenderbufferParameteriv(
1192    uint32 immediate_data_size,
1193    const gles2::cmds::GetRenderbufferParameteriv& c) {
1194  GLenum target = static_cast<GLenum>(c.target);
1195  GLenum pname = static_cast<GLenum>(c.pname);
1196  typedef cmds::GetRenderbufferParameteriv::Result Result;
1197  GLsizei num_values = 0;
1198  GetNumValuesReturnedForGLGet(pname, &num_values);
1199  Result* result = GetSharedMemoryAs<Result*>(
1200      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1201  GLint* params = result ? result->GetData() : NULL;
1202  if (!validators_->render_buffer_target.IsValid(target)) {
1203    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetRenderbufferParameteriv", target,
1204    "target");
1205    return error::kNoError;
1206  }
1207  if (!validators_->render_buffer_parameter.IsValid(pname)) {
1208    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetRenderbufferParameteriv", pname,
1209    "pname");
1210    return error::kNoError;
1211  }
1212  if (params == NULL) {
1213    return error::kOutOfBounds;
1214  }
1215  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetRenderbufferParameteriv");
1216  // Check that the client initialized the result.
1217  if (result->size != 0) {
1218    return error::kInvalidArguments;
1219  }
1220  DoGetRenderbufferParameteriv(target, pname, params);
1221  GLenum error = glGetError();
1222  if (error == GL_NO_ERROR) {
1223    result->SetNumResults(num_values);
1224  } else {
1225    LOCAL_SET_GL_ERROR(error, "GetRenderbufferParameteriv", "");
1226  }
1227  return error::kNoError;
1228}
1229
1230error::Error GLES2DecoderImpl::HandleGetShaderiv(
1231    uint32 immediate_data_size, const gles2::cmds::GetShaderiv& c) {
1232  GLuint shader = c.shader;
1233  GLenum pname = static_cast<GLenum>(c.pname);
1234  typedef cmds::GetShaderiv::Result Result;
1235  GLsizei num_values = 0;
1236  GetNumValuesReturnedForGLGet(pname, &num_values);
1237  Result* result = GetSharedMemoryAs<Result*>(
1238      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1239  GLint* params = result ? result->GetData() : NULL;
1240  if (!validators_->shader_parameter.IsValid(pname)) {
1241    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetShaderiv", pname, "pname");
1242    return error::kNoError;
1243  }
1244  if (params == NULL) {
1245    return error::kOutOfBounds;
1246  }
1247  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetShaderiv");
1248  // Check that the client initialized the result.
1249  if (result->size != 0) {
1250    return error::kInvalidArguments;
1251  }
1252  DoGetShaderiv(shader, pname, params);
1253  GLenum error = glGetError();
1254  if (error == GL_NO_ERROR) {
1255    result->SetNumResults(num_values);
1256  } else {
1257    LOCAL_SET_GL_ERROR(error, "GetShaderiv", "");
1258  }
1259  return error::kNoError;
1260}
1261
1262error::Error GLES2DecoderImpl::HandleGetTexParameterfv(
1263    uint32 immediate_data_size, const gles2::cmds::GetTexParameterfv& c) {
1264  GLenum target = static_cast<GLenum>(c.target);
1265  GLenum pname = static_cast<GLenum>(c.pname);
1266  typedef cmds::GetTexParameterfv::Result Result;
1267  GLsizei num_values = 0;
1268  GetNumValuesReturnedForGLGet(pname, &num_values);
1269  Result* result = GetSharedMemoryAs<Result*>(
1270      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1271  GLfloat* params = result ? result->GetData() : NULL;
1272  if (!validators_->get_tex_param_target.IsValid(target)) {
1273    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameterfv", target, "target");
1274    return error::kNoError;
1275  }
1276  if (!validators_->texture_parameter.IsValid(pname)) {
1277    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameterfv", pname, "pname");
1278    return error::kNoError;
1279  }
1280  if (params == NULL) {
1281    return error::kOutOfBounds;
1282  }
1283  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTexParameterfv");
1284  // Check that the client initialized the result.
1285  if (result->size != 0) {
1286    return error::kInvalidArguments;
1287  }
1288  glGetTexParameterfv(target, pname, params);
1289  GLenum error = glGetError();
1290  if (error == GL_NO_ERROR) {
1291    result->SetNumResults(num_values);
1292  } else {
1293    LOCAL_SET_GL_ERROR(error, "GetTexParameterfv", "");
1294  }
1295  return error::kNoError;
1296}
1297
1298error::Error GLES2DecoderImpl::HandleGetTexParameteriv(
1299    uint32 immediate_data_size, const gles2::cmds::GetTexParameteriv& c) {
1300  GLenum target = static_cast<GLenum>(c.target);
1301  GLenum pname = static_cast<GLenum>(c.pname);
1302  typedef cmds::GetTexParameteriv::Result Result;
1303  GLsizei num_values = 0;
1304  GetNumValuesReturnedForGLGet(pname, &num_values);
1305  Result* result = GetSharedMemoryAs<Result*>(
1306      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1307  GLint* params = result ? result->GetData() : NULL;
1308  if (!validators_->get_tex_param_target.IsValid(target)) {
1309    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameteriv", target, "target");
1310    return error::kNoError;
1311  }
1312  if (!validators_->texture_parameter.IsValid(pname)) {
1313    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetTexParameteriv", pname, "pname");
1314    return error::kNoError;
1315  }
1316  if (params == NULL) {
1317    return error::kOutOfBounds;
1318  }
1319  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTexParameteriv");
1320  // Check that the client initialized the result.
1321  if (result->size != 0) {
1322    return error::kInvalidArguments;
1323  }
1324  glGetTexParameteriv(target, pname, params);
1325  GLenum error = glGetError();
1326  if (error == GL_NO_ERROR) {
1327    result->SetNumResults(num_values);
1328  } else {
1329    LOCAL_SET_GL_ERROR(error, "GetTexParameteriv", "");
1330  }
1331  return error::kNoError;
1332}
1333
1334error::Error GLES2DecoderImpl::HandleGetVertexAttribfv(
1335    uint32 immediate_data_size, const gles2::cmds::GetVertexAttribfv& c) {
1336  GLuint index = static_cast<GLuint>(c.index);
1337  GLenum pname = static_cast<GLenum>(c.pname);
1338  typedef cmds::GetVertexAttribfv::Result Result;
1339  GLsizei num_values = 0;
1340  GetNumValuesReturnedForGLGet(pname, &num_values);
1341  Result* result = GetSharedMemoryAs<Result*>(
1342      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1343  GLfloat* params = result ? result->GetData() : NULL;
1344  if (!validators_->vertex_attribute.IsValid(pname)) {
1345    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetVertexAttribfv", pname, "pname");
1346    return error::kNoError;
1347  }
1348  if (params == NULL) {
1349    return error::kOutOfBounds;
1350  }
1351  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetVertexAttribfv");
1352  // Check that the client initialized the result.
1353  if (result->size != 0) {
1354    return error::kInvalidArguments;
1355  }
1356  DoGetVertexAttribfv(index, pname, params);
1357  GLenum error = glGetError();
1358  if (error == GL_NO_ERROR) {
1359    result->SetNumResults(num_values);
1360  } else {
1361    LOCAL_SET_GL_ERROR(error, "GetVertexAttribfv", "");
1362  }
1363  return error::kNoError;
1364}
1365
1366error::Error GLES2DecoderImpl::HandleGetVertexAttribiv(
1367    uint32 immediate_data_size, const gles2::cmds::GetVertexAttribiv& c) {
1368  GLuint index = static_cast<GLuint>(c.index);
1369  GLenum pname = static_cast<GLenum>(c.pname);
1370  typedef cmds::GetVertexAttribiv::Result Result;
1371  GLsizei num_values = 0;
1372  GetNumValuesReturnedForGLGet(pname, &num_values);
1373  Result* result = GetSharedMemoryAs<Result*>(
1374      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
1375  GLint* params = result ? result->GetData() : NULL;
1376  if (!validators_->vertex_attribute.IsValid(pname)) {
1377    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetVertexAttribiv", pname, "pname");
1378    return error::kNoError;
1379  }
1380  if (params == NULL) {
1381    return error::kOutOfBounds;
1382  }
1383  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetVertexAttribiv");
1384  // Check that the client initialized the result.
1385  if (result->size != 0) {
1386    return error::kInvalidArguments;
1387  }
1388  DoGetVertexAttribiv(index, pname, params);
1389  GLenum error = glGetError();
1390  if (error == GL_NO_ERROR) {
1391    result->SetNumResults(num_values);
1392  } else {
1393    LOCAL_SET_GL_ERROR(error, "GetVertexAttribiv", "");
1394  }
1395  return error::kNoError;
1396}
1397
1398error::Error GLES2DecoderImpl::HandleHint(
1399    uint32 immediate_data_size, const gles2::cmds::Hint& c) {
1400  GLenum target = static_cast<GLenum>(c.target);
1401  GLenum mode = static_cast<GLenum>(c.mode);
1402  if (!validators_->hint_target.IsValid(target)) {
1403    LOCAL_SET_GL_ERROR_INVALID_ENUM("glHint", target, "target");
1404    return error::kNoError;
1405  }
1406  if (!validators_->hint_mode.IsValid(mode)) {
1407    LOCAL_SET_GL_ERROR_INVALID_ENUM("glHint", mode, "mode");
1408    return error::kNoError;
1409  }
1410  switch (target) {
1411    case GL_GENERATE_MIPMAP_HINT:
1412      if (state_.hint_generate_mipmap != mode) {
1413        state_.hint_generate_mipmap = mode;
1414        glHint(target, mode);
1415      }
1416      break;
1417    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1418      if (state_.hint_fragment_shader_derivative != mode) {
1419        state_.hint_fragment_shader_derivative = mode;
1420        glHint(target, mode);
1421      }
1422      break;
1423    default:
1424      NOTREACHED();
1425  }
1426  return error::kNoError;
1427}
1428
1429error::Error GLES2DecoderImpl::HandleIsBuffer(
1430    uint32 immediate_data_size, const gles2::cmds::IsBuffer& c) {
1431  GLuint buffer = c.buffer;
1432  typedef cmds::IsBuffer::Result Result;
1433  Result* result_dst = GetSharedMemoryAs<Result*>(
1434      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1435  if (!result_dst) {
1436    return error::kOutOfBounds;
1437  }
1438  *result_dst = DoIsBuffer(buffer);
1439  return error::kNoError;
1440}
1441
1442error::Error GLES2DecoderImpl::HandleIsEnabled(
1443    uint32 immediate_data_size, const gles2::cmds::IsEnabled& c) {
1444  GLenum cap = static_cast<GLenum>(c.cap);
1445  typedef cmds::IsEnabled::Result Result;
1446  Result* result_dst = GetSharedMemoryAs<Result*>(
1447      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1448  if (!result_dst) {
1449    return error::kOutOfBounds;
1450  }
1451  if (!validators_->capability.IsValid(cap)) {
1452    LOCAL_SET_GL_ERROR_INVALID_ENUM("glIsEnabled", cap, "cap");
1453    return error::kNoError;
1454  }
1455  *result_dst = DoIsEnabled(cap);
1456  return error::kNoError;
1457}
1458
1459error::Error GLES2DecoderImpl::HandleIsFramebuffer(
1460    uint32 immediate_data_size, const gles2::cmds::IsFramebuffer& c) {
1461  GLuint framebuffer = c.framebuffer;
1462  typedef cmds::IsFramebuffer::Result Result;
1463  Result* result_dst = GetSharedMemoryAs<Result*>(
1464      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1465  if (!result_dst) {
1466    return error::kOutOfBounds;
1467  }
1468  *result_dst = DoIsFramebuffer(framebuffer);
1469  return error::kNoError;
1470}
1471
1472error::Error GLES2DecoderImpl::HandleIsProgram(
1473    uint32 immediate_data_size, const gles2::cmds::IsProgram& c) {
1474  GLuint program = c.program;
1475  typedef cmds::IsProgram::Result Result;
1476  Result* result_dst = GetSharedMemoryAs<Result*>(
1477      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1478  if (!result_dst) {
1479    return error::kOutOfBounds;
1480  }
1481  *result_dst = DoIsProgram(program);
1482  return error::kNoError;
1483}
1484
1485error::Error GLES2DecoderImpl::HandleIsRenderbuffer(
1486    uint32 immediate_data_size, const gles2::cmds::IsRenderbuffer& c) {
1487  GLuint renderbuffer = c.renderbuffer;
1488  typedef cmds::IsRenderbuffer::Result Result;
1489  Result* result_dst = GetSharedMemoryAs<Result*>(
1490      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1491  if (!result_dst) {
1492    return error::kOutOfBounds;
1493  }
1494  *result_dst = DoIsRenderbuffer(renderbuffer);
1495  return error::kNoError;
1496}
1497
1498error::Error GLES2DecoderImpl::HandleIsShader(
1499    uint32 immediate_data_size, const gles2::cmds::IsShader& c) {
1500  GLuint shader = c.shader;
1501  typedef cmds::IsShader::Result Result;
1502  Result* result_dst = GetSharedMemoryAs<Result*>(
1503      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1504  if (!result_dst) {
1505    return error::kOutOfBounds;
1506  }
1507  *result_dst = DoIsShader(shader);
1508  return error::kNoError;
1509}
1510
1511error::Error GLES2DecoderImpl::HandleIsTexture(
1512    uint32 immediate_data_size, const gles2::cmds::IsTexture& c) {
1513  GLuint texture = c.texture;
1514  typedef cmds::IsTexture::Result Result;
1515  Result* result_dst = GetSharedMemoryAs<Result*>(
1516      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
1517  if (!result_dst) {
1518    return error::kOutOfBounds;
1519  }
1520  *result_dst = DoIsTexture(texture);
1521  return error::kNoError;
1522}
1523
1524error::Error GLES2DecoderImpl::HandleLineWidth(
1525    uint32 immediate_data_size, const gles2::cmds::LineWidth& c) {
1526  GLfloat width = static_cast<GLfloat>(c.width);
1527  if (width <= 0.0f) {
1528    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "LineWidth", "width out of range");
1529    return error::kNoError;
1530  }
1531  if (state_.line_width != width) {
1532    state_.line_width = width;
1533    glLineWidth(width);
1534  }
1535  return error::kNoError;
1536}
1537
1538error::Error GLES2DecoderImpl::HandleLinkProgram(
1539    uint32 immediate_data_size, const gles2::cmds::LinkProgram& c) {
1540  GLuint program = c.program;
1541  DoLinkProgram(program);
1542  return error::kNoError;
1543}
1544
1545error::Error GLES2DecoderImpl::HandlePolygonOffset(
1546    uint32 immediate_data_size, const gles2::cmds::PolygonOffset& c) {
1547  GLfloat factor = static_cast<GLfloat>(c.factor);
1548  GLfloat units = static_cast<GLfloat>(c.units);
1549  if (state_.polygon_offset_factor != factor ||
1550      state_.polygon_offset_units != units) {
1551    state_.polygon_offset_factor = factor;
1552    state_.polygon_offset_units = units;
1553    glPolygonOffset(factor, units);
1554  }
1555  return error::kNoError;
1556}
1557
1558error::Error GLES2DecoderImpl::HandleReleaseShaderCompiler(
1559    uint32 immediate_data_size, const gles2::cmds::ReleaseShaderCompiler& c) {
1560  DoReleaseShaderCompiler();
1561  return error::kNoError;
1562}
1563
1564error::Error GLES2DecoderImpl::HandleRenderbufferStorage(
1565    uint32 immediate_data_size, const gles2::cmds::RenderbufferStorage& c) {
1566  GLenum target = static_cast<GLenum>(c.target);
1567  GLenum internalformat = static_cast<GLenum>(c.internalformat);
1568  GLsizei width = static_cast<GLsizei>(c.width);
1569  GLsizei height = static_cast<GLsizei>(c.height);
1570  if (!validators_->render_buffer_target.IsValid(target)) {
1571    LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorage", target, "target");
1572    return error::kNoError;
1573  }
1574  if (!validators_->render_buffer_format.IsValid(internalformat)) {
1575    LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorage", internalformat,
1576    "internalformat");
1577    return error::kNoError;
1578  }
1579  if (width < 0) {
1580    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRenderbufferStorage", "width < 0");
1581    return error::kNoError;
1582  }
1583  if (height < 0) {
1584    LOCAL_SET_GL_ERROR(
1585        GL_INVALID_VALUE, "glRenderbufferStorage", "height < 0");
1586    return error::kNoError;
1587  }
1588  DoRenderbufferStorage(target, internalformat, width, height);
1589  return error::kNoError;
1590}
1591
1592error::Error GLES2DecoderImpl::HandleSampleCoverage(
1593    uint32 immediate_data_size, const gles2::cmds::SampleCoverage& c) {
1594  GLclampf value = static_cast<GLclampf>(c.value);
1595  GLboolean invert = static_cast<GLboolean>(c.invert);
1596  DoSampleCoverage(value, invert);
1597  return error::kNoError;
1598}
1599
1600error::Error GLES2DecoderImpl::HandleScissor(
1601    uint32 immediate_data_size, const gles2::cmds::Scissor& c) {
1602  GLint x = static_cast<GLint>(c.x);
1603  GLint y = static_cast<GLint>(c.y);
1604  GLsizei width = static_cast<GLsizei>(c.width);
1605  GLsizei height = static_cast<GLsizei>(c.height);
1606  if (width < 0) {
1607    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScissor", "width < 0");
1608    return error::kNoError;
1609  }
1610  if (height < 0) {
1611    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScissor", "height < 0");
1612    return error::kNoError;
1613  }
1614  if (state_.scissor_x != x ||
1615      state_.scissor_y != y ||
1616      state_.scissor_width != width ||
1617      state_.scissor_height != height) {
1618    state_.scissor_x = x;
1619    state_.scissor_y = y;
1620    state_.scissor_width = width;
1621    state_.scissor_height = height;
1622    glScissor(x, y, width, height);
1623  }
1624  return error::kNoError;
1625}
1626
1627error::Error GLES2DecoderImpl::HandleStencilFunc(
1628    uint32 immediate_data_size, const gles2::cmds::StencilFunc& c) {
1629  GLenum func = static_cast<GLenum>(c.func);
1630  GLint ref = static_cast<GLint>(c.ref);
1631  GLuint mask = static_cast<GLuint>(c.mask);
1632  if (!validators_->cmp_function.IsValid(func)) {
1633    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFunc", func, "func");
1634    return error::kNoError;
1635  }
1636  if (state_.stencil_front_func != func ||
1637      state_.stencil_front_ref != ref ||
1638      state_.stencil_front_mask != mask ||
1639      state_.stencil_back_func != func ||
1640      state_.stencil_back_ref != ref ||
1641      state_.stencil_back_mask != mask) {
1642    state_.stencil_front_func = func;
1643    state_.stencil_front_ref = ref;
1644    state_.stencil_front_mask = mask;
1645    state_.stencil_back_func = func;
1646    state_.stencil_back_ref = ref;
1647    state_.stencil_back_mask = mask;
1648    glStencilFunc(func, ref, mask);
1649  }
1650  return error::kNoError;
1651}
1652
1653error::Error GLES2DecoderImpl::HandleStencilFuncSeparate(
1654    uint32 immediate_data_size, const gles2::cmds::StencilFuncSeparate& c) {
1655  GLenum face = static_cast<GLenum>(c.face);
1656  GLenum func = static_cast<GLenum>(c.func);
1657  GLint ref = static_cast<GLint>(c.ref);
1658  GLuint mask = static_cast<GLuint>(c.mask);
1659  if (!validators_->face_type.IsValid(face)) {
1660    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFuncSeparate", face, "face");
1661    return error::kNoError;
1662  }
1663  if (!validators_->cmp_function.IsValid(func)) {
1664    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilFuncSeparate", func, "func");
1665    return error::kNoError;
1666  }
1667  bool changed = false;
1668  if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
1669    changed |= state_.stencil_front_func != func ||
1670        state_.stencil_front_ref != ref ||
1671        state_.stencil_front_mask != mask;
1672  }
1673  if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
1674    changed |= state_.stencil_back_func != func ||
1675        state_.stencil_back_ref != ref ||
1676        state_.stencil_back_mask != mask;
1677  }
1678  if (changed) {
1679    if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
1680      state_.stencil_front_func = func;
1681      state_.stencil_front_ref = ref;
1682      state_.stencil_front_mask = mask;
1683    }
1684    if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
1685      state_.stencil_back_func = func;
1686      state_.stencil_back_ref = ref;
1687      state_.stencil_back_mask = mask;
1688    }
1689    glStencilFuncSeparate(face, func, ref, mask);
1690  }
1691  return error::kNoError;
1692}
1693
1694error::Error GLES2DecoderImpl::HandleStencilMask(
1695    uint32 immediate_data_size, const gles2::cmds::StencilMask& c) {
1696  GLuint mask = static_cast<GLuint>(c.mask);
1697  if (state_.stencil_front_writemask != mask ||
1698      state_.stencil_back_writemask != mask) {
1699    state_.stencil_front_writemask = mask;
1700    state_.stencil_back_writemask = mask;
1701    clear_state_dirty_ = true;
1702  }
1703  return error::kNoError;
1704}
1705
1706error::Error GLES2DecoderImpl::HandleStencilMaskSeparate(
1707    uint32 immediate_data_size, const gles2::cmds::StencilMaskSeparate& c) {
1708  GLenum face = static_cast<GLenum>(c.face);
1709  GLuint mask = static_cast<GLuint>(c.mask);
1710  if (!validators_->face_type.IsValid(face)) {
1711    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilMaskSeparate", face, "face");
1712    return error::kNoError;
1713  }
1714  bool changed = false;
1715  if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
1716    changed |= state_.stencil_front_writemask != mask;
1717  }
1718  if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
1719    changed |= state_.stencil_back_writemask != mask;
1720  }
1721  if (changed) {
1722    if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
1723      state_.stencil_front_writemask = mask;
1724    }
1725    if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
1726      state_.stencil_back_writemask = mask;
1727    }
1728    clear_state_dirty_ = true;
1729  }
1730  return error::kNoError;
1731}
1732
1733error::Error GLES2DecoderImpl::HandleStencilOp(
1734    uint32 immediate_data_size, const gles2::cmds::StencilOp& c) {
1735  GLenum fail = static_cast<GLenum>(c.fail);
1736  GLenum zfail = static_cast<GLenum>(c.zfail);
1737  GLenum zpass = static_cast<GLenum>(c.zpass);
1738  if (!validators_->stencil_op.IsValid(fail)) {
1739    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOp", fail, "fail");
1740    return error::kNoError;
1741  }
1742  if (!validators_->stencil_op.IsValid(zfail)) {
1743    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOp", zfail, "zfail");
1744    return error::kNoError;
1745  }
1746  if (!validators_->stencil_op.IsValid(zpass)) {
1747    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOp", zpass, "zpass");
1748    return error::kNoError;
1749  }
1750  if (state_.stencil_front_fail_op != fail ||
1751      state_.stencil_front_z_fail_op != zfail ||
1752      state_.stencil_front_z_pass_op != zpass ||
1753      state_.stencil_back_fail_op != fail ||
1754      state_.stencil_back_z_fail_op != zfail ||
1755      state_.stencil_back_z_pass_op != zpass) {
1756    state_.stencil_front_fail_op = fail;
1757    state_.stencil_front_z_fail_op = zfail;
1758    state_.stencil_front_z_pass_op = zpass;
1759    state_.stencil_back_fail_op = fail;
1760    state_.stencil_back_z_fail_op = zfail;
1761    state_.stencil_back_z_pass_op = zpass;
1762    glStencilOp(fail, zfail, zpass);
1763  }
1764  return error::kNoError;
1765}
1766
1767error::Error GLES2DecoderImpl::HandleStencilOpSeparate(
1768    uint32 immediate_data_size, const gles2::cmds::StencilOpSeparate& c) {
1769  GLenum face = static_cast<GLenum>(c.face);
1770  GLenum fail = static_cast<GLenum>(c.fail);
1771  GLenum zfail = static_cast<GLenum>(c.zfail);
1772  GLenum zpass = static_cast<GLenum>(c.zpass);
1773  if (!validators_->face_type.IsValid(face)) {
1774    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", face, "face");
1775    return error::kNoError;
1776  }
1777  if (!validators_->stencil_op.IsValid(fail)) {
1778    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", fail, "fail");
1779    return error::kNoError;
1780  }
1781  if (!validators_->stencil_op.IsValid(zfail)) {
1782    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", zfail, "zfail");
1783    return error::kNoError;
1784  }
1785  if (!validators_->stencil_op.IsValid(zpass)) {
1786    LOCAL_SET_GL_ERROR_INVALID_ENUM("glStencilOpSeparate", zpass, "zpass");
1787    return error::kNoError;
1788  }
1789  bool changed = false;
1790  if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
1791    changed |= state_.stencil_front_fail_op != fail ||
1792        state_.stencil_front_z_fail_op != zfail ||
1793        state_.stencil_front_z_pass_op != zpass;
1794  }
1795  if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
1796    changed |= state_.stencil_back_fail_op != fail ||
1797        state_.stencil_back_z_fail_op != zfail ||
1798        state_.stencil_back_z_pass_op != zpass;
1799  }
1800  if (changed) {
1801    if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
1802      state_.stencil_front_fail_op = fail;
1803      state_.stencil_front_z_fail_op = zfail;
1804      state_.stencil_front_z_pass_op = zpass;
1805    }
1806    if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
1807      state_.stencil_back_fail_op = fail;
1808      state_.stencil_back_z_fail_op = zfail;
1809      state_.stencil_back_z_pass_op = zpass;
1810    }
1811    glStencilOpSeparate(face, fail, zfail, zpass);
1812  }
1813  return error::kNoError;
1814}
1815
1816error::Error GLES2DecoderImpl::HandleTexParameterf(
1817    uint32 immediate_data_size, const gles2::cmds::TexParameterf& c) {
1818  GLenum target = static_cast<GLenum>(c.target);
1819  GLenum pname = static_cast<GLenum>(c.pname);
1820  GLfloat param = static_cast<GLfloat>(c.param);
1821  if (!validators_->texture_bind_target.IsValid(target)) {
1822    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterf", target, "target");
1823    return error::kNoError;
1824  }
1825  if (!validators_->texture_parameter.IsValid(pname)) {
1826    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterf", pname, "pname");
1827    return error::kNoError;
1828  }
1829  DoTexParameterf(target, pname, param);
1830  return error::kNoError;
1831}
1832
1833error::Error GLES2DecoderImpl::HandleTexParameterfv(
1834    uint32 immediate_data_size, const gles2::cmds::TexParameterfv& c) {
1835  GLenum target = static_cast<GLenum>(c.target);
1836  GLenum pname = static_cast<GLenum>(c.pname);
1837  uint32 data_size;
1838  if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
1839    return error::kOutOfBounds;
1840  }
1841  const GLfloat* params = GetSharedMemoryAs<const GLfloat*>(
1842      c.params_shm_id, c.params_shm_offset, data_size);
1843  if (!validators_->texture_bind_target.IsValid(target)) {
1844    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", target, "target");
1845    return error::kNoError;
1846  }
1847  if (!validators_->texture_parameter.IsValid(pname)) {
1848    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", pname, "pname");
1849    return error::kNoError;
1850  }
1851  if (params == NULL) {
1852    return error::kOutOfBounds;
1853  }
1854  DoTexParameterfv(target, pname, params);
1855  return error::kNoError;
1856}
1857
1858error::Error GLES2DecoderImpl::HandleTexParameterfvImmediate(
1859    uint32 immediate_data_size,
1860    const gles2::cmds::TexParameterfvImmediate& c) {
1861  GLenum target = static_cast<GLenum>(c.target);
1862  GLenum pname = static_cast<GLenum>(c.pname);
1863  uint32 data_size;
1864  if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
1865    return error::kOutOfBounds;
1866  }
1867  if (data_size > immediate_data_size) {
1868    return error::kOutOfBounds;
1869  }
1870  const GLfloat* params = GetImmediateDataAs<const GLfloat*>(
1871      c, data_size, immediate_data_size);
1872  if (!validators_->texture_bind_target.IsValid(target)) {
1873    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", target, "target");
1874    return error::kNoError;
1875  }
1876  if (!validators_->texture_parameter.IsValid(pname)) {
1877    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameterfv", pname, "pname");
1878    return error::kNoError;
1879  }
1880  if (params == NULL) {
1881    return error::kOutOfBounds;
1882  }
1883  DoTexParameterfv(target, pname, params);
1884  return error::kNoError;
1885}
1886
1887error::Error GLES2DecoderImpl::HandleTexParameteri(
1888    uint32 immediate_data_size, const gles2::cmds::TexParameteri& c) {
1889  GLenum target = static_cast<GLenum>(c.target);
1890  GLenum pname = static_cast<GLenum>(c.pname);
1891  GLint param = static_cast<GLint>(c.param);
1892  if (!validators_->texture_bind_target.IsValid(target)) {
1893    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteri", target, "target");
1894    return error::kNoError;
1895  }
1896  if (!validators_->texture_parameter.IsValid(pname)) {
1897    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteri", pname, "pname");
1898    return error::kNoError;
1899  }
1900  DoTexParameteri(target, pname, param);
1901  return error::kNoError;
1902}
1903
1904error::Error GLES2DecoderImpl::HandleTexParameteriv(
1905    uint32 immediate_data_size, const gles2::cmds::TexParameteriv& c) {
1906  GLenum target = static_cast<GLenum>(c.target);
1907  GLenum pname = static_cast<GLenum>(c.pname);
1908  uint32 data_size;
1909  if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
1910    return error::kOutOfBounds;
1911  }
1912  const GLint* params = GetSharedMemoryAs<const GLint*>(
1913      c.params_shm_id, c.params_shm_offset, data_size);
1914  if (!validators_->texture_bind_target.IsValid(target)) {
1915    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", target, "target");
1916    return error::kNoError;
1917  }
1918  if (!validators_->texture_parameter.IsValid(pname)) {
1919    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", pname, "pname");
1920    return error::kNoError;
1921  }
1922  if (params == NULL) {
1923    return error::kOutOfBounds;
1924  }
1925  DoTexParameteriv(target, pname, params);
1926  return error::kNoError;
1927}
1928
1929error::Error GLES2DecoderImpl::HandleTexParameterivImmediate(
1930    uint32 immediate_data_size,
1931    const gles2::cmds::TexParameterivImmediate& c) {
1932  GLenum target = static_cast<GLenum>(c.target);
1933  GLenum pname = static_cast<GLenum>(c.pname);
1934  uint32 data_size;
1935  if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
1936    return error::kOutOfBounds;
1937  }
1938  if (data_size > immediate_data_size) {
1939    return error::kOutOfBounds;
1940  }
1941  const GLint* params = GetImmediateDataAs<const GLint*>(
1942      c, data_size, immediate_data_size);
1943  if (!validators_->texture_bind_target.IsValid(target)) {
1944    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", target, "target");
1945    return error::kNoError;
1946  }
1947  if (!validators_->texture_parameter.IsValid(pname)) {
1948    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexParameteriv", pname, "pname");
1949    return error::kNoError;
1950  }
1951  if (params == NULL) {
1952    return error::kOutOfBounds;
1953  }
1954  DoTexParameteriv(target, pname, params);
1955  return error::kNoError;
1956}
1957
1958error::Error GLES2DecoderImpl::HandleUniform1f(
1959    uint32 immediate_data_size, const gles2::cmds::Uniform1f& c) {
1960  GLint location = static_cast<GLint>(c.location);
1961  GLfloat x = static_cast<GLfloat>(c.x);
1962  GLfloat temp[1] = { x, };
1963  DoUniform1fv(location, 1, &temp[0]);
1964  return error::kNoError;
1965}
1966
1967error::Error GLES2DecoderImpl::HandleUniform1fv(
1968    uint32 immediate_data_size, const gles2::cmds::Uniform1fv& c) {
1969  GLint location = static_cast<GLint>(c.location);
1970  GLsizei count = static_cast<GLsizei>(c.count);
1971  uint32 data_size;
1972  if (!ComputeDataSize(count, sizeof(GLfloat), 1, &data_size)) {
1973    return error::kOutOfBounds;
1974  }
1975  const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
1976      c.v_shm_id, c.v_shm_offset, data_size);
1977  if (v == NULL) {
1978    return error::kOutOfBounds;
1979  }
1980  DoUniform1fv(location, count, v);
1981  return error::kNoError;
1982}
1983
1984error::Error GLES2DecoderImpl::HandleUniform1fvImmediate(
1985    uint32 immediate_data_size, const gles2::cmds::Uniform1fvImmediate& c) {
1986  GLint location = static_cast<GLint>(c.location);
1987  GLsizei count = static_cast<GLsizei>(c.count);
1988  uint32 data_size;
1989  if (!ComputeDataSize(count, sizeof(GLfloat), 1, &data_size)) {
1990    return error::kOutOfBounds;
1991  }
1992  if (data_size > immediate_data_size) {
1993    return error::kOutOfBounds;
1994  }
1995  const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
1996      c, data_size, immediate_data_size);
1997  if (v == NULL) {
1998    return error::kOutOfBounds;
1999  }
2000  DoUniform1fv(location, count, v);
2001  return error::kNoError;
2002}
2003
2004error::Error GLES2DecoderImpl::HandleUniform1i(
2005    uint32 immediate_data_size, const gles2::cmds::Uniform1i& c) {
2006  GLint location = static_cast<GLint>(c.location);
2007  GLint x = static_cast<GLint>(c.x);
2008  DoUniform1i(location, x);
2009  return error::kNoError;
2010}
2011
2012error::Error GLES2DecoderImpl::HandleUniform1iv(
2013    uint32 immediate_data_size, const gles2::cmds::Uniform1iv& c) {
2014  GLint location = static_cast<GLint>(c.location);
2015  GLsizei count = static_cast<GLsizei>(c.count);
2016  uint32 data_size;
2017  if (!ComputeDataSize(count, sizeof(GLint), 1, &data_size)) {
2018    return error::kOutOfBounds;
2019  }
2020  const GLint* v = GetSharedMemoryAs<const GLint*>(
2021      c.v_shm_id, c.v_shm_offset, data_size);
2022  if (v == NULL) {
2023    return error::kOutOfBounds;
2024  }
2025  DoUniform1iv(location, count, v);
2026  return error::kNoError;
2027}
2028
2029error::Error GLES2DecoderImpl::HandleUniform1ivImmediate(
2030    uint32 immediate_data_size, const gles2::cmds::Uniform1ivImmediate& c) {
2031  GLint location = static_cast<GLint>(c.location);
2032  GLsizei count = static_cast<GLsizei>(c.count);
2033  uint32 data_size;
2034  if (!ComputeDataSize(count, sizeof(GLint), 1, &data_size)) {
2035    return error::kOutOfBounds;
2036  }
2037  if (data_size > immediate_data_size) {
2038    return error::kOutOfBounds;
2039  }
2040  const GLint* v = GetImmediateDataAs<const GLint*>(
2041      c, data_size, immediate_data_size);
2042  if (v == NULL) {
2043    return error::kOutOfBounds;
2044  }
2045  DoUniform1iv(location, count, v);
2046  return error::kNoError;
2047}
2048
2049error::Error GLES2DecoderImpl::HandleUniform2f(
2050    uint32 immediate_data_size, const gles2::cmds::Uniform2f& c) {
2051  GLint location = static_cast<GLint>(c.location);
2052  GLfloat x = static_cast<GLfloat>(c.x);
2053  GLfloat y = static_cast<GLfloat>(c.y);
2054  GLfloat temp[2] = { x, y, };
2055  DoUniform2fv(location, 1, &temp[0]);
2056  return error::kNoError;
2057}
2058
2059error::Error GLES2DecoderImpl::HandleUniform2fv(
2060    uint32 immediate_data_size, const gles2::cmds::Uniform2fv& c) {
2061  GLint location = static_cast<GLint>(c.location);
2062  GLsizei count = static_cast<GLsizei>(c.count);
2063  uint32 data_size;
2064  if (!ComputeDataSize(count, sizeof(GLfloat), 2, &data_size)) {
2065    return error::kOutOfBounds;
2066  }
2067  const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
2068      c.v_shm_id, c.v_shm_offset, data_size);
2069  if (v == NULL) {
2070    return error::kOutOfBounds;
2071  }
2072  DoUniform2fv(location, count, v);
2073  return error::kNoError;
2074}
2075
2076error::Error GLES2DecoderImpl::HandleUniform2fvImmediate(
2077    uint32 immediate_data_size, const gles2::cmds::Uniform2fvImmediate& c) {
2078  GLint location = static_cast<GLint>(c.location);
2079  GLsizei count = static_cast<GLsizei>(c.count);
2080  uint32 data_size;
2081  if (!ComputeDataSize(count, sizeof(GLfloat), 2, &data_size)) {
2082    return error::kOutOfBounds;
2083  }
2084  if (data_size > immediate_data_size) {
2085    return error::kOutOfBounds;
2086  }
2087  const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
2088      c, data_size, immediate_data_size);
2089  if (v == NULL) {
2090    return error::kOutOfBounds;
2091  }
2092  DoUniform2fv(location, count, v);
2093  return error::kNoError;
2094}
2095
2096error::Error GLES2DecoderImpl::HandleUniform2i(
2097    uint32 immediate_data_size, const gles2::cmds::Uniform2i& c) {
2098  GLint location = static_cast<GLint>(c.location);
2099  GLint x = static_cast<GLint>(c.x);
2100  GLint y = static_cast<GLint>(c.y);
2101  GLint temp[2] = { x, y, };
2102  DoUniform2iv(location, 1, &temp[0]);
2103  return error::kNoError;
2104}
2105
2106error::Error GLES2DecoderImpl::HandleUniform2iv(
2107    uint32 immediate_data_size, const gles2::cmds::Uniform2iv& c) {
2108  GLint location = static_cast<GLint>(c.location);
2109  GLsizei count = static_cast<GLsizei>(c.count);
2110  uint32 data_size;
2111  if (!ComputeDataSize(count, sizeof(GLint), 2, &data_size)) {
2112    return error::kOutOfBounds;
2113  }
2114  const GLint* v = GetSharedMemoryAs<const GLint*>(
2115      c.v_shm_id, c.v_shm_offset, data_size);
2116  if (v == NULL) {
2117    return error::kOutOfBounds;
2118  }
2119  DoUniform2iv(location, count, v);
2120  return error::kNoError;
2121}
2122
2123error::Error GLES2DecoderImpl::HandleUniform2ivImmediate(
2124    uint32 immediate_data_size, const gles2::cmds::Uniform2ivImmediate& c) {
2125  GLint location = static_cast<GLint>(c.location);
2126  GLsizei count = static_cast<GLsizei>(c.count);
2127  uint32 data_size;
2128  if (!ComputeDataSize(count, sizeof(GLint), 2, &data_size)) {
2129    return error::kOutOfBounds;
2130  }
2131  if (data_size > immediate_data_size) {
2132    return error::kOutOfBounds;
2133  }
2134  const GLint* v = GetImmediateDataAs<const GLint*>(
2135      c, data_size, immediate_data_size);
2136  if (v == NULL) {
2137    return error::kOutOfBounds;
2138  }
2139  DoUniform2iv(location, count, v);
2140  return error::kNoError;
2141}
2142
2143error::Error GLES2DecoderImpl::HandleUniform3f(
2144    uint32 immediate_data_size, const gles2::cmds::Uniform3f& c) {
2145  GLint location = static_cast<GLint>(c.location);
2146  GLfloat x = static_cast<GLfloat>(c.x);
2147  GLfloat y = static_cast<GLfloat>(c.y);
2148  GLfloat z = static_cast<GLfloat>(c.z);
2149  GLfloat temp[3] = { x, y, z, };
2150  DoUniform3fv(location, 1, &temp[0]);
2151  return error::kNoError;
2152}
2153
2154error::Error GLES2DecoderImpl::HandleUniform3fv(
2155    uint32 immediate_data_size, const gles2::cmds::Uniform3fv& c) {
2156  GLint location = static_cast<GLint>(c.location);
2157  GLsizei count = static_cast<GLsizei>(c.count);
2158  uint32 data_size;
2159  if (!ComputeDataSize(count, sizeof(GLfloat), 3, &data_size)) {
2160    return error::kOutOfBounds;
2161  }
2162  const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
2163      c.v_shm_id, c.v_shm_offset, data_size);
2164  if (v == NULL) {
2165    return error::kOutOfBounds;
2166  }
2167  DoUniform3fv(location, count, v);
2168  return error::kNoError;
2169}
2170
2171error::Error GLES2DecoderImpl::HandleUniform3fvImmediate(
2172    uint32 immediate_data_size, const gles2::cmds::Uniform3fvImmediate& c) {
2173  GLint location = static_cast<GLint>(c.location);
2174  GLsizei count = static_cast<GLsizei>(c.count);
2175  uint32 data_size;
2176  if (!ComputeDataSize(count, sizeof(GLfloat), 3, &data_size)) {
2177    return error::kOutOfBounds;
2178  }
2179  if (data_size > immediate_data_size) {
2180    return error::kOutOfBounds;
2181  }
2182  const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
2183      c, data_size, immediate_data_size);
2184  if (v == NULL) {
2185    return error::kOutOfBounds;
2186  }
2187  DoUniform3fv(location, count, v);
2188  return error::kNoError;
2189}
2190
2191error::Error GLES2DecoderImpl::HandleUniform3i(
2192    uint32 immediate_data_size, const gles2::cmds::Uniform3i& c) {
2193  GLint location = static_cast<GLint>(c.location);
2194  GLint x = static_cast<GLint>(c.x);
2195  GLint y = static_cast<GLint>(c.y);
2196  GLint z = static_cast<GLint>(c.z);
2197  GLint temp[3] = { x, y, z, };
2198  DoUniform3iv(location, 1, &temp[0]);
2199  return error::kNoError;
2200}
2201
2202error::Error GLES2DecoderImpl::HandleUniform3iv(
2203    uint32 immediate_data_size, const gles2::cmds::Uniform3iv& c) {
2204  GLint location = static_cast<GLint>(c.location);
2205  GLsizei count = static_cast<GLsizei>(c.count);
2206  uint32 data_size;
2207  if (!ComputeDataSize(count, sizeof(GLint), 3, &data_size)) {
2208    return error::kOutOfBounds;
2209  }
2210  const GLint* v = GetSharedMemoryAs<const GLint*>(
2211      c.v_shm_id, c.v_shm_offset, data_size);
2212  if (v == NULL) {
2213    return error::kOutOfBounds;
2214  }
2215  DoUniform3iv(location, count, v);
2216  return error::kNoError;
2217}
2218
2219error::Error GLES2DecoderImpl::HandleUniform3ivImmediate(
2220    uint32 immediate_data_size, const gles2::cmds::Uniform3ivImmediate& c) {
2221  GLint location = static_cast<GLint>(c.location);
2222  GLsizei count = static_cast<GLsizei>(c.count);
2223  uint32 data_size;
2224  if (!ComputeDataSize(count, sizeof(GLint), 3, &data_size)) {
2225    return error::kOutOfBounds;
2226  }
2227  if (data_size > immediate_data_size) {
2228    return error::kOutOfBounds;
2229  }
2230  const GLint* v = GetImmediateDataAs<const GLint*>(
2231      c, data_size, immediate_data_size);
2232  if (v == NULL) {
2233    return error::kOutOfBounds;
2234  }
2235  DoUniform3iv(location, count, v);
2236  return error::kNoError;
2237}
2238
2239error::Error GLES2DecoderImpl::HandleUniform4f(
2240    uint32 immediate_data_size, const gles2::cmds::Uniform4f& c) {
2241  GLint location = static_cast<GLint>(c.location);
2242  GLfloat x = static_cast<GLfloat>(c.x);
2243  GLfloat y = static_cast<GLfloat>(c.y);
2244  GLfloat z = static_cast<GLfloat>(c.z);
2245  GLfloat w = static_cast<GLfloat>(c.w);
2246  GLfloat temp[4] = { x, y, z, w, };
2247  DoUniform4fv(location, 1, &temp[0]);
2248  return error::kNoError;
2249}
2250
2251error::Error GLES2DecoderImpl::HandleUniform4fv(
2252    uint32 immediate_data_size, const gles2::cmds::Uniform4fv& c) {
2253  GLint location = static_cast<GLint>(c.location);
2254  GLsizei count = static_cast<GLsizei>(c.count);
2255  uint32 data_size;
2256  if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
2257    return error::kOutOfBounds;
2258  }
2259  const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
2260      c.v_shm_id, c.v_shm_offset, data_size);
2261  if (v == NULL) {
2262    return error::kOutOfBounds;
2263  }
2264  DoUniform4fv(location, count, v);
2265  return error::kNoError;
2266}
2267
2268error::Error GLES2DecoderImpl::HandleUniform4fvImmediate(
2269    uint32 immediate_data_size, const gles2::cmds::Uniform4fvImmediate& c) {
2270  GLint location = static_cast<GLint>(c.location);
2271  GLsizei count = static_cast<GLsizei>(c.count);
2272  uint32 data_size;
2273  if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
2274    return error::kOutOfBounds;
2275  }
2276  if (data_size > immediate_data_size) {
2277    return error::kOutOfBounds;
2278  }
2279  const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
2280      c, data_size, immediate_data_size);
2281  if (v == NULL) {
2282    return error::kOutOfBounds;
2283  }
2284  DoUniform4fv(location, count, v);
2285  return error::kNoError;
2286}
2287
2288error::Error GLES2DecoderImpl::HandleUniform4i(
2289    uint32 immediate_data_size, const gles2::cmds::Uniform4i& c) {
2290  GLint location = static_cast<GLint>(c.location);
2291  GLint x = static_cast<GLint>(c.x);
2292  GLint y = static_cast<GLint>(c.y);
2293  GLint z = static_cast<GLint>(c.z);
2294  GLint w = static_cast<GLint>(c.w);
2295  GLint temp[4] = { x, y, z, w, };
2296  DoUniform4iv(location, 1, &temp[0]);
2297  return error::kNoError;
2298}
2299
2300error::Error GLES2DecoderImpl::HandleUniform4iv(
2301    uint32 immediate_data_size, const gles2::cmds::Uniform4iv& c) {
2302  GLint location = static_cast<GLint>(c.location);
2303  GLsizei count = static_cast<GLsizei>(c.count);
2304  uint32 data_size;
2305  if (!ComputeDataSize(count, sizeof(GLint), 4, &data_size)) {
2306    return error::kOutOfBounds;
2307  }
2308  const GLint* v = GetSharedMemoryAs<const GLint*>(
2309      c.v_shm_id, c.v_shm_offset, data_size);
2310  if (v == NULL) {
2311    return error::kOutOfBounds;
2312  }
2313  DoUniform4iv(location, count, v);
2314  return error::kNoError;
2315}
2316
2317error::Error GLES2DecoderImpl::HandleUniform4ivImmediate(
2318    uint32 immediate_data_size, const gles2::cmds::Uniform4ivImmediate& c) {
2319  GLint location = static_cast<GLint>(c.location);
2320  GLsizei count = static_cast<GLsizei>(c.count);
2321  uint32 data_size;
2322  if (!ComputeDataSize(count, sizeof(GLint), 4, &data_size)) {
2323    return error::kOutOfBounds;
2324  }
2325  if (data_size > immediate_data_size) {
2326    return error::kOutOfBounds;
2327  }
2328  const GLint* v = GetImmediateDataAs<const GLint*>(
2329      c, data_size, immediate_data_size);
2330  if (v == NULL) {
2331    return error::kOutOfBounds;
2332  }
2333  DoUniform4iv(location, count, v);
2334  return error::kNoError;
2335}
2336
2337error::Error GLES2DecoderImpl::HandleUniformMatrix2fv(
2338    uint32 immediate_data_size, const gles2::cmds::UniformMatrix2fv& c) {
2339  GLint location = static_cast<GLint>(c.location);
2340  GLsizei count = static_cast<GLsizei>(c.count);
2341  GLboolean transpose = static_cast<GLboolean>(c.transpose);
2342  uint32 data_size;
2343  if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
2344    return error::kOutOfBounds;
2345  }
2346  const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
2347      c.value_shm_id, c.value_shm_offset, data_size);
2348  if (!validators_->false_only.IsValid(transpose)) {
2349    LOCAL_SET_GL_ERROR(
2350        GL_INVALID_VALUE, "glUniformMatrix2fv", "transpose GL_INVALID_VALUE");
2351    return error::kNoError;
2352  }
2353  if (value == NULL) {
2354    return error::kOutOfBounds;
2355  }
2356  DoUniformMatrix2fv(location, count, transpose, value);
2357  return error::kNoError;
2358}
2359
2360error::Error GLES2DecoderImpl::HandleUniformMatrix2fvImmediate(
2361    uint32 immediate_data_size,
2362    const gles2::cmds::UniformMatrix2fvImmediate& c) {
2363  GLint location = static_cast<GLint>(c.location);
2364  GLsizei count = static_cast<GLsizei>(c.count);
2365  GLboolean transpose = static_cast<GLboolean>(c.transpose);
2366  uint32 data_size;
2367  if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
2368    return error::kOutOfBounds;
2369  }
2370  if (data_size > immediate_data_size) {
2371    return error::kOutOfBounds;
2372  }
2373  const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
2374      c, data_size, immediate_data_size);
2375  if (!validators_->false_only.IsValid(transpose)) {
2376    LOCAL_SET_GL_ERROR(
2377        GL_INVALID_VALUE, "glUniformMatrix2fv", "transpose GL_INVALID_VALUE");
2378    return error::kNoError;
2379  }
2380  if (value == NULL) {
2381    return error::kOutOfBounds;
2382  }
2383  DoUniformMatrix2fv(location, count, transpose, value);
2384  return error::kNoError;
2385}
2386
2387error::Error GLES2DecoderImpl::HandleUniformMatrix3fv(
2388    uint32 immediate_data_size, const gles2::cmds::UniformMatrix3fv& c) {
2389  GLint location = static_cast<GLint>(c.location);
2390  GLsizei count = static_cast<GLsizei>(c.count);
2391  GLboolean transpose = static_cast<GLboolean>(c.transpose);
2392  uint32 data_size;
2393  if (!ComputeDataSize(count, sizeof(GLfloat), 9, &data_size)) {
2394    return error::kOutOfBounds;
2395  }
2396  const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
2397      c.value_shm_id, c.value_shm_offset, data_size);
2398  if (!validators_->false_only.IsValid(transpose)) {
2399    LOCAL_SET_GL_ERROR(
2400        GL_INVALID_VALUE, "glUniformMatrix3fv", "transpose GL_INVALID_VALUE");
2401    return error::kNoError;
2402  }
2403  if (value == NULL) {
2404    return error::kOutOfBounds;
2405  }
2406  DoUniformMatrix3fv(location, count, transpose, value);
2407  return error::kNoError;
2408}
2409
2410error::Error GLES2DecoderImpl::HandleUniformMatrix3fvImmediate(
2411    uint32 immediate_data_size,
2412    const gles2::cmds::UniformMatrix3fvImmediate& c) {
2413  GLint location = static_cast<GLint>(c.location);
2414  GLsizei count = static_cast<GLsizei>(c.count);
2415  GLboolean transpose = static_cast<GLboolean>(c.transpose);
2416  uint32 data_size;
2417  if (!ComputeDataSize(count, sizeof(GLfloat), 9, &data_size)) {
2418    return error::kOutOfBounds;
2419  }
2420  if (data_size > immediate_data_size) {
2421    return error::kOutOfBounds;
2422  }
2423  const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
2424      c, data_size, immediate_data_size);
2425  if (!validators_->false_only.IsValid(transpose)) {
2426    LOCAL_SET_GL_ERROR(
2427        GL_INVALID_VALUE, "glUniformMatrix3fv", "transpose GL_INVALID_VALUE");
2428    return error::kNoError;
2429  }
2430  if (value == NULL) {
2431    return error::kOutOfBounds;
2432  }
2433  DoUniformMatrix3fv(location, count, transpose, value);
2434  return error::kNoError;
2435}
2436
2437error::Error GLES2DecoderImpl::HandleUniformMatrix4fv(
2438    uint32 immediate_data_size, const gles2::cmds::UniformMatrix4fv& c) {
2439  GLint location = static_cast<GLint>(c.location);
2440  GLsizei count = static_cast<GLsizei>(c.count);
2441  GLboolean transpose = static_cast<GLboolean>(c.transpose);
2442  uint32 data_size;
2443  if (!ComputeDataSize(count, sizeof(GLfloat), 16, &data_size)) {
2444    return error::kOutOfBounds;
2445  }
2446  const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
2447      c.value_shm_id, c.value_shm_offset, data_size);
2448  if (!validators_->false_only.IsValid(transpose)) {
2449    LOCAL_SET_GL_ERROR(
2450        GL_INVALID_VALUE, "glUniformMatrix4fv", "transpose GL_INVALID_VALUE");
2451    return error::kNoError;
2452  }
2453  if (value == NULL) {
2454    return error::kOutOfBounds;
2455  }
2456  DoUniformMatrix4fv(location, count, transpose, value);
2457  return error::kNoError;
2458}
2459
2460error::Error GLES2DecoderImpl::HandleUniformMatrix4fvImmediate(
2461    uint32 immediate_data_size,
2462    const gles2::cmds::UniformMatrix4fvImmediate& c) {
2463  GLint location = static_cast<GLint>(c.location);
2464  GLsizei count = static_cast<GLsizei>(c.count);
2465  GLboolean transpose = static_cast<GLboolean>(c.transpose);
2466  uint32 data_size;
2467  if (!ComputeDataSize(count, sizeof(GLfloat), 16, &data_size)) {
2468    return error::kOutOfBounds;
2469  }
2470  if (data_size > immediate_data_size) {
2471    return error::kOutOfBounds;
2472  }
2473  const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
2474      c, data_size, immediate_data_size);
2475  if (!validators_->false_only.IsValid(transpose)) {
2476    LOCAL_SET_GL_ERROR(
2477        GL_INVALID_VALUE, "glUniformMatrix4fv", "transpose GL_INVALID_VALUE");
2478    return error::kNoError;
2479  }
2480  if (value == NULL) {
2481    return error::kOutOfBounds;
2482  }
2483  DoUniformMatrix4fv(location, count, transpose, value);
2484  return error::kNoError;
2485}
2486
2487error::Error GLES2DecoderImpl::HandleUseProgram(
2488    uint32 immediate_data_size, const gles2::cmds::UseProgram& c) {
2489  GLuint program = c.program;
2490  DoUseProgram(program);
2491  return error::kNoError;
2492}
2493
2494error::Error GLES2DecoderImpl::HandleValidateProgram(
2495    uint32 immediate_data_size, const gles2::cmds::ValidateProgram& c) {
2496  GLuint program = c.program;
2497  DoValidateProgram(program);
2498  return error::kNoError;
2499}
2500
2501error::Error GLES2DecoderImpl::HandleVertexAttrib1f(
2502    uint32 immediate_data_size, const gles2::cmds::VertexAttrib1f& c) {
2503  GLuint indx = static_cast<GLuint>(c.indx);
2504  GLfloat x = static_cast<GLfloat>(c.x);
2505  DoVertexAttrib1f(indx, x);
2506  return error::kNoError;
2507}
2508
2509error::Error GLES2DecoderImpl::HandleVertexAttrib1fv(
2510    uint32 immediate_data_size, const gles2::cmds::VertexAttrib1fv& c) {
2511  GLuint indx = static_cast<GLuint>(c.indx);
2512  uint32 data_size;
2513  if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
2514    return error::kOutOfBounds;
2515  }
2516  const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
2517      c.values_shm_id, c.values_shm_offset, data_size);
2518  if (values == NULL) {
2519    return error::kOutOfBounds;
2520  }
2521  DoVertexAttrib1fv(indx, values);
2522  return error::kNoError;
2523}
2524
2525error::Error GLES2DecoderImpl::HandleVertexAttrib1fvImmediate(
2526    uint32 immediate_data_size,
2527    const gles2::cmds::VertexAttrib1fvImmediate& c) {
2528  GLuint indx = static_cast<GLuint>(c.indx);
2529  uint32 data_size;
2530  if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
2531    return error::kOutOfBounds;
2532  }
2533  if (data_size > immediate_data_size) {
2534    return error::kOutOfBounds;
2535  }
2536  const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
2537      c, data_size, immediate_data_size);
2538  if (values == NULL) {
2539    return error::kOutOfBounds;
2540  }
2541  DoVertexAttrib1fv(indx, values);
2542  return error::kNoError;
2543}
2544
2545error::Error GLES2DecoderImpl::HandleVertexAttrib2f(
2546    uint32 immediate_data_size, const gles2::cmds::VertexAttrib2f& c) {
2547  GLuint indx = static_cast<GLuint>(c.indx);
2548  GLfloat x = static_cast<GLfloat>(c.x);
2549  GLfloat y = static_cast<GLfloat>(c.y);
2550  DoVertexAttrib2f(indx, x, y);
2551  return error::kNoError;
2552}
2553
2554error::Error GLES2DecoderImpl::HandleVertexAttrib2fv(
2555    uint32 immediate_data_size, const gles2::cmds::VertexAttrib2fv& c) {
2556  GLuint indx = static_cast<GLuint>(c.indx);
2557  uint32 data_size;
2558  if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
2559    return error::kOutOfBounds;
2560  }
2561  const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
2562      c.values_shm_id, c.values_shm_offset, data_size);
2563  if (values == NULL) {
2564    return error::kOutOfBounds;
2565  }
2566  DoVertexAttrib2fv(indx, values);
2567  return error::kNoError;
2568}
2569
2570error::Error GLES2DecoderImpl::HandleVertexAttrib2fvImmediate(
2571    uint32 immediate_data_size,
2572    const gles2::cmds::VertexAttrib2fvImmediate& c) {
2573  GLuint indx = static_cast<GLuint>(c.indx);
2574  uint32 data_size;
2575  if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
2576    return error::kOutOfBounds;
2577  }
2578  if (data_size > immediate_data_size) {
2579    return error::kOutOfBounds;
2580  }
2581  const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
2582      c, data_size, immediate_data_size);
2583  if (values == NULL) {
2584    return error::kOutOfBounds;
2585  }
2586  DoVertexAttrib2fv(indx, values);
2587  return error::kNoError;
2588}
2589
2590error::Error GLES2DecoderImpl::HandleVertexAttrib3f(
2591    uint32 immediate_data_size, const gles2::cmds::VertexAttrib3f& c) {
2592  GLuint indx = static_cast<GLuint>(c.indx);
2593  GLfloat x = static_cast<GLfloat>(c.x);
2594  GLfloat y = static_cast<GLfloat>(c.y);
2595  GLfloat z = static_cast<GLfloat>(c.z);
2596  DoVertexAttrib3f(indx, x, y, z);
2597  return error::kNoError;
2598}
2599
2600error::Error GLES2DecoderImpl::HandleVertexAttrib3fv(
2601    uint32 immediate_data_size, const gles2::cmds::VertexAttrib3fv& c) {
2602  GLuint indx = static_cast<GLuint>(c.indx);
2603  uint32 data_size;
2604  if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
2605    return error::kOutOfBounds;
2606  }
2607  const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
2608      c.values_shm_id, c.values_shm_offset, data_size);
2609  if (values == NULL) {
2610    return error::kOutOfBounds;
2611  }
2612  DoVertexAttrib3fv(indx, values);
2613  return error::kNoError;
2614}
2615
2616error::Error GLES2DecoderImpl::HandleVertexAttrib3fvImmediate(
2617    uint32 immediate_data_size,
2618    const gles2::cmds::VertexAttrib3fvImmediate& c) {
2619  GLuint indx = static_cast<GLuint>(c.indx);
2620  uint32 data_size;
2621  if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
2622    return error::kOutOfBounds;
2623  }
2624  if (data_size > immediate_data_size) {
2625    return error::kOutOfBounds;
2626  }
2627  const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
2628      c, data_size, immediate_data_size);
2629  if (values == NULL) {
2630    return error::kOutOfBounds;
2631  }
2632  DoVertexAttrib3fv(indx, values);
2633  return error::kNoError;
2634}
2635
2636error::Error GLES2DecoderImpl::HandleVertexAttrib4f(
2637    uint32 immediate_data_size, const gles2::cmds::VertexAttrib4f& c) {
2638  GLuint indx = static_cast<GLuint>(c.indx);
2639  GLfloat x = static_cast<GLfloat>(c.x);
2640  GLfloat y = static_cast<GLfloat>(c.y);
2641  GLfloat z = static_cast<GLfloat>(c.z);
2642  GLfloat w = static_cast<GLfloat>(c.w);
2643  DoVertexAttrib4f(indx, x, y, z, w);
2644  return error::kNoError;
2645}
2646
2647error::Error GLES2DecoderImpl::HandleVertexAttrib4fv(
2648    uint32 immediate_data_size, const gles2::cmds::VertexAttrib4fv& c) {
2649  GLuint indx = static_cast<GLuint>(c.indx);
2650  uint32 data_size;
2651  if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
2652    return error::kOutOfBounds;
2653  }
2654  const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
2655      c.values_shm_id, c.values_shm_offset, data_size);
2656  if (values == NULL) {
2657    return error::kOutOfBounds;
2658  }
2659  DoVertexAttrib4fv(indx, values);
2660  return error::kNoError;
2661}
2662
2663error::Error GLES2DecoderImpl::HandleVertexAttrib4fvImmediate(
2664    uint32 immediate_data_size,
2665    const gles2::cmds::VertexAttrib4fvImmediate& c) {
2666  GLuint indx = static_cast<GLuint>(c.indx);
2667  uint32 data_size;
2668  if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
2669    return error::kOutOfBounds;
2670  }
2671  if (data_size > immediate_data_size) {
2672    return error::kOutOfBounds;
2673  }
2674  const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
2675      c, data_size, immediate_data_size);
2676  if (values == NULL) {
2677    return error::kOutOfBounds;
2678  }
2679  DoVertexAttrib4fv(indx, values);
2680  return error::kNoError;
2681}
2682
2683error::Error GLES2DecoderImpl::HandleViewport(
2684    uint32 immediate_data_size, const gles2::cmds::Viewport& c) {
2685  GLint x = static_cast<GLint>(c.x);
2686  GLint y = static_cast<GLint>(c.y);
2687  GLsizei width = static_cast<GLsizei>(c.width);
2688  GLsizei height = static_cast<GLsizei>(c.height);
2689  if (width < 0) {
2690    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glViewport", "width < 0");
2691    return error::kNoError;
2692  }
2693  if (height < 0) {
2694    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glViewport", "height < 0");
2695    return error::kNoError;
2696  }
2697  DoViewport(x, y, width, height);
2698  return error::kNoError;
2699}
2700
2701error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT(
2702    uint32 immediate_data_size, const gles2::cmds::BlitFramebufferEXT& c) {
2703  if (ShouldDeferDraws() || ShouldDeferReads())
2704    return error::kDeferCommandUntilLater;
2705  GLint srcX0 = static_cast<GLint>(c.srcX0);
2706  GLint srcY0 = static_cast<GLint>(c.srcY0);
2707  GLint srcX1 = static_cast<GLint>(c.srcX1);
2708  GLint srcY1 = static_cast<GLint>(c.srcY1);
2709  GLint dstX0 = static_cast<GLint>(c.dstX0);
2710  GLint dstY0 = static_cast<GLint>(c.dstY0);
2711  GLint dstX1 = static_cast<GLint>(c.dstX1);
2712  GLint dstY1 = static_cast<GLint>(c.dstY1);
2713  GLbitfield mask = static_cast<GLbitfield>(c.mask);
2714  GLenum filter = static_cast<GLenum>(c.filter);
2715  if (!validators_->blit_filter.IsValid(filter)) {
2716    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBlitFramebufferEXT", filter, "filter");
2717    return error::kNoError;
2718  }
2719  DoBlitFramebufferEXT(
2720      srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2721  return error::kNoError;
2722}
2723
2724error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT(
2725    uint32 immediate_data_size,
2726    const gles2::cmds::RenderbufferStorageMultisampleEXT& c) {
2727  GLenum target = static_cast<GLenum>(c.target);
2728  GLsizei samples = static_cast<GLsizei>(c.samples);
2729  GLenum internalformat = static_cast<GLenum>(c.internalformat);
2730  GLsizei width = static_cast<GLsizei>(c.width);
2731  GLsizei height = static_cast<GLsizei>(c.height);
2732  if (!validators_->render_buffer_target.IsValid(target)) {
2733    LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorageMultisampleEXT", target, "target");  // NOLINT
2734    return error::kNoError;
2735  }
2736  if (samples < 0) {
2737    LOCAL_SET_GL_ERROR(
2738        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "samples < 0");
2739    return error::kNoError;
2740  }
2741  if (!validators_->render_buffer_format.IsValid(internalformat)) {
2742    LOCAL_SET_GL_ERROR_INVALID_ENUM("glRenderbufferStorageMultisampleEXT", internalformat, "internalformat");  // NOLINT
2743    return error::kNoError;
2744  }
2745  if (width < 0) {
2746    LOCAL_SET_GL_ERROR(
2747        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "width < 0");
2748    return error::kNoError;
2749  }
2750  if (height < 0) {
2751    LOCAL_SET_GL_ERROR(
2752        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "height < 0");
2753    return error::kNoError;
2754  }
2755  DoRenderbufferStorageMultisample(
2756      target, samples, internalformat, width, height);
2757  return error::kNoError;
2758}
2759
2760error::Error GLES2DecoderImpl::HandleFramebufferTexture2DMultisampleEXT(
2761    uint32 immediate_data_size,
2762    const gles2::cmds::FramebufferTexture2DMultisampleEXT& c) {
2763  GLenum target = static_cast<GLenum>(c.target);
2764  GLenum attachment = static_cast<GLenum>(c.attachment);
2765  GLenum textarget = static_cast<GLenum>(c.textarget);
2766  GLuint texture = c.texture;
2767  GLint level = static_cast<GLint>(c.level);
2768  GLsizei samples = static_cast<GLsizei>(c.samples);
2769  if (!validators_->frame_buffer_target.IsValid(target)) {
2770    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", target, "target");  // NOLINT
2771    return error::kNoError;
2772  }
2773  if (!validators_->attachment.IsValid(attachment)) {
2774    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", attachment, "attachment");  // NOLINT
2775    return error::kNoError;
2776  }
2777  if (!validators_->texture_target.IsValid(textarget)) {
2778    LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", textarget, "textarget");  // NOLINT
2779    return error::kNoError;
2780  }
2781  if (!validators_->zero_only.IsValid(level)) {
2782    LOCAL_SET_GL_ERROR(
2783        GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "level GL_INVALID_VALUE");  // NOLINT
2784    return error::kNoError;
2785  }
2786  if (samples < 0) {
2787    LOCAL_SET_GL_ERROR(
2788        GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "samples < 0");  // NOLINT
2789    return error::kNoError;
2790  }
2791  DoFramebufferTexture2DMultisample(
2792      target, attachment, textarget, texture, level, samples);
2793  return error::kNoError;
2794}
2795
2796error::Error GLES2DecoderImpl::HandleTexStorage2DEXT(
2797    uint32 immediate_data_size, const gles2::cmds::TexStorage2DEXT& c) {
2798  GLenum target = static_cast<GLenum>(c.target);
2799  GLsizei levels = static_cast<GLsizei>(c.levels);
2800  GLenum internalFormat = static_cast<GLenum>(c.internalFormat);
2801  GLsizei width = static_cast<GLsizei>(c.width);
2802  GLsizei height = static_cast<GLsizei>(c.height);
2803  if (!validators_->texture_target.IsValid(target)) {
2804    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage2DEXT", target, "target");
2805    return error::kNoError;
2806  }
2807  if (levels < 0) {
2808    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DEXT", "levels < 0");
2809    return error::kNoError;
2810  }
2811  if (!validators_->texture_internal_format_storage.IsValid(internalFormat)) {
2812    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage2DEXT", internalFormat,
2813    "internalFormat");
2814    return error::kNoError;
2815  }
2816  if (width < 0) {
2817    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DEXT", "width < 0");
2818    return error::kNoError;
2819  }
2820  if (height < 0) {
2821    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DEXT", "height < 0");
2822    return error::kNoError;
2823  }
2824  DoTexStorage2DEXT(target, levels, internalFormat, width, height);
2825  return error::kNoError;
2826}
2827
2828error::Error GLES2DecoderImpl::HandleGenQueriesEXT(
2829    uint32 immediate_data_size, const gles2::cmds::GenQueriesEXT& c) {
2830  GLsizei n = static_cast<GLsizei>(c.n);
2831  uint32 data_size;
2832  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2833    return error::kOutOfBounds;
2834  }
2835  GLuint* queries = GetSharedMemoryAs<GLuint*>(
2836      c.queries_shm_id, c.queries_shm_offset, data_size);
2837  if (queries == NULL) {
2838    return error::kOutOfBounds;
2839  }
2840  if (!GenQueriesEXTHelper(n, queries)) {
2841    return error::kInvalidArguments;
2842  }
2843  return error::kNoError;
2844}
2845
2846error::Error GLES2DecoderImpl::HandleGenQueriesEXTImmediate(
2847    uint32 immediate_data_size, const gles2::cmds::GenQueriesEXTImmediate& c) {
2848  GLsizei n = static_cast<GLsizei>(c.n);
2849  uint32 data_size;
2850  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2851    return error::kOutOfBounds;
2852  }
2853  GLuint* queries = GetImmediateDataAs<GLuint*>(
2854      c, data_size, immediate_data_size);
2855  if (queries == NULL) {
2856    return error::kOutOfBounds;
2857  }
2858  if (!GenQueriesEXTHelper(n, queries)) {
2859    return error::kInvalidArguments;
2860  }
2861  return error::kNoError;
2862}
2863
2864error::Error GLES2DecoderImpl::HandleDeleteQueriesEXT(
2865    uint32 immediate_data_size, const gles2::cmds::DeleteQueriesEXT& c) {
2866  GLsizei n = static_cast<GLsizei>(c.n);
2867  uint32 data_size;
2868  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2869    return error::kOutOfBounds;
2870  }
2871  const GLuint* queries = GetSharedMemoryAs<const GLuint*>(
2872      c.queries_shm_id, c.queries_shm_offset, data_size);
2873  if (queries == NULL) {
2874    return error::kOutOfBounds;
2875  }
2876  DeleteQueriesEXTHelper(n, queries);
2877  return error::kNoError;
2878}
2879
2880error::Error GLES2DecoderImpl::HandleDeleteQueriesEXTImmediate(
2881    uint32 immediate_data_size,
2882    const gles2::cmds::DeleteQueriesEXTImmediate& c) {
2883  GLsizei n = static_cast<GLsizei>(c.n);
2884  uint32 data_size;
2885  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2886    return error::kOutOfBounds;
2887  }
2888  const GLuint* queries = GetImmediateDataAs<const GLuint*>(
2889      c, data_size, immediate_data_size);
2890  if (queries == NULL) {
2891    return error::kOutOfBounds;
2892  }
2893  DeleteQueriesEXTHelper(n, queries);
2894  return error::kNoError;
2895}
2896
2897error::Error GLES2DecoderImpl::HandleInsertEventMarkerEXT(
2898  uint32 immediate_data_size, const gles2::cmds::InsertEventMarkerEXT& c) {
2899  GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
2900  Bucket* bucket = GetBucket(bucket_id);
2901  if (!bucket || bucket->size() == 0) {
2902    return error::kInvalidArguments;
2903  }
2904  std::string str;
2905  if (!bucket->GetAsString(&str)) {
2906    return error::kInvalidArguments;
2907  }
2908  DoInsertEventMarkerEXT(0, str.c_str());
2909  return error::kNoError;
2910}
2911
2912error::Error GLES2DecoderImpl::HandlePushGroupMarkerEXT(
2913  uint32 immediate_data_size, const gles2::cmds::PushGroupMarkerEXT& c) {
2914  GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
2915  Bucket* bucket = GetBucket(bucket_id);
2916  if (!bucket || bucket->size() == 0) {
2917    return error::kInvalidArguments;
2918  }
2919  std::string str;
2920  if (!bucket->GetAsString(&str)) {
2921    return error::kInvalidArguments;
2922  }
2923  DoPushGroupMarkerEXT(0, str.c_str());
2924  return error::kNoError;
2925}
2926
2927error::Error GLES2DecoderImpl::HandlePopGroupMarkerEXT(
2928    uint32 immediate_data_size, const gles2::cmds::PopGroupMarkerEXT& c) {
2929  DoPopGroupMarkerEXT();
2930  return error::kNoError;
2931}
2932
2933error::Error GLES2DecoderImpl::HandleGenVertexArraysOES(
2934    uint32 immediate_data_size, const gles2::cmds::GenVertexArraysOES& c) {
2935  GLsizei n = static_cast<GLsizei>(c.n);
2936  uint32 data_size;
2937  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2938    return error::kOutOfBounds;
2939  }
2940  GLuint* arrays = GetSharedMemoryAs<GLuint*>(
2941      c.arrays_shm_id, c.arrays_shm_offset, data_size);
2942  if (arrays == NULL) {
2943    return error::kOutOfBounds;
2944  }
2945  if (!GenVertexArraysOESHelper(n, arrays)) {
2946    return error::kInvalidArguments;
2947  }
2948  return error::kNoError;
2949}
2950
2951error::Error GLES2DecoderImpl::HandleGenVertexArraysOESImmediate(
2952    uint32 immediate_data_size,
2953    const gles2::cmds::GenVertexArraysOESImmediate& c) {
2954  GLsizei n = static_cast<GLsizei>(c.n);
2955  uint32 data_size;
2956  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2957    return error::kOutOfBounds;
2958  }
2959  GLuint* arrays = GetImmediateDataAs<GLuint*>(
2960      c, data_size, immediate_data_size);
2961  if (arrays == NULL) {
2962    return error::kOutOfBounds;
2963  }
2964  if (!GenVertexArraysOESHelper(n, arrays)) {
2965    return error::kInvalidArguments;
2966  }
2967  return error::kNoError;
2968}
2969
2970error::Error GLES2DecoderImpl::HandleDeleteVertexArraysOES(
2971    uint32 immediate_data_size, const gles2::cmds::DeleteVertexArraysOES& c) {
2972  GLsizei n = static_cast<GLsizei>(c.n);
2973  uint32 data_size;
2974  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2975    return error::kOutOfBounds;
2976  }
2977  const GLuint* arrays = GetSharedMemoryAs<const GLuint*>(
2978      c.arrays_shm_id, c.arrays_shm_offset, data_size);
2979  if (arrays == NULL) {
2980    return error::kOutOfBounds;
2981  }
2982  DeleteVertexArraysOESHelper(n, arrays);
2983  return error::kNoError;
2984}
2985
2986error::Error GLES2DecoderImpl::HandleDeleteVertexArraysOESImmediate(
2987    uint32 immediate_data_size,
2988    const gles2::cmds::DeleteVertexArraysOESImmediate& c) {
2989  GLsizei n = static_cast<GLsizei>(c.n);
2990  uint32 data_size;
2991  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
2992    return error::kOutOfBounds;
2993  }
2994  const GLuint* arrays = GetImmediateDataAs<const GLuint*>(
2995      c, data_size, immediate_data_size);
2996  if (arrays == NULL) {
2997    return error::kOutOfBounds;
2998  }
2999  DeleteVertexArraysOESHelper(n, arrays);
3000  return error::kNoError;
3001}
3002
3003error::Error GLES2DecoderImpl::HandleIsVertexArrayOES(
3004    uint32 immediate_data_size, const gles2::cmds::IsVertexArrayOES& c) {
3005  GLuint array = c.array;
3006  typedef cmds::IsVertexArrayOES::Result Result;
3007  Result* result_dst = GetSharedMemoryAs<Result*>(
3008      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
3009  if (!result_dst) {
3010    return error::kOutOfBounds;
3011  }
3012  *result_dst = DoIsVertexArrayOES(array);
3013  return error::kNoError;
3014}
3015
3016error::Error GLES2DecoderImpl::HandleBindVertexArrayOES(
3017    uint32 immediate_data_size, const gles2::cmds::BindVertexArrayOES& c) {
3018  GLuint array = c.array;
3019  DoBindVertexArrayOES(array);
3020  return error::kNoError;
3021}
3022
3023error::Error GLES2DecoderImpl::HandleSwapBuffers(
3024    uint32 immediate_data_size, const gles2::cmds::SwapBuffers& c) {
3025  DoSwapBuffers();
3026  return error::kNoError;
3027}
3028
3029error::Error GLES2DecoderImpl::HandleGetMaxValueInBufferCHROMIUM(
3030    uint32 immediate_data_size,
3031    const gles2::cmds::GetMaxValueInBufferCHROMIUM& c) {
3032  GLuint buffer_id = c.buffer_id;
3033  GLsizei count = static_cast<GLsizei>(c.count);
3034  GLenum type = static_cast<GLenum>(c.type);
3035  GLuint offset = static_cast<GLuint>(c.offset);
3036  typedef cmds::GetMaxValueInBufferCHROMIUM::Result Result;
3037  Result* result_dst = GetSharedMemoryAs<Result*>(
3038      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
3039  if (!result_dst) {
3040    return error::kOutOfBounds;
3041  }
3042  if (count < 0) {
3043    LOCAL_SET_GL_ERROR(
3044        GL_INVALID_VALUE, "glGetMaxValueInBufferCHROMIUM", "count < 0");
3045    return error::kNoError;
3046  }
3047  if (!validators_->get_max_index_type.IsValid(type)) {
3048    LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetMaxValueInBufferCHROMIUM", type,
3049    "type");
3050    return error::kNoError;
3051  }
3052  *result_dst = DoGetMaxValueInBufferCHROMIUM(buffer_id, count, type, offset);
3053  return error::kNoError;
3054}
3055
3056error::Error GLES2DecoderImpl::HandleTexImageIOSurface2DCHROMIUM(
3057    uint32 immediate_data_size,
3058    const gles2::cmds::TexImageIOSurface2DCHROMIUM& c) {
3059  GLenum target = static_cast<GLenum>(c.target);
3060  GLsizei width = static_cast<GLsizei>(c.width);
3061  GLsizei height = static_cast<GLsizei>(c.height);
3062  GLuint ioSurfaceId = static_cast<GLuint>(c.ioSurfaceId);
3063  GLuint plane = static_cast<GLuint>(c.plane);
3064  if (!validators_->texture_bind_target.IsValid(target)) {
3065    LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexImageIOSurface2DCHROMIUM", target,
3066    "target");
3067    return error::kNoError;
3068  }
3069  if (width < 0) {
3070    LOCAL_SET_GL_ERROR(
3071        GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "width < 0");
3072    return error::kNoError;
3073  }
3074  if (height < 0) {
3075    LOCAL_SET_GL_ERROR(
3076        GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "height < 0");
3077    return error::kNoError;
3078  }
3079  DoTexImageIOSurface2DCHROMIUM(target, width, height, ioSurfaceId, plane);
3080  return error::kNoError;
3081}
3082
3083error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM(
3084    uint32 immediate_data_size, const gles2::cmds::CopyTextureCHROMIUM& c) {
3085  GLenum target = static_cast<GLenum>(c.target);
3086  GLenum source_id = static_cast<GLenum>(c.source_id);
3087  GLenum dest_id = static_cast<GLenum>(c.dest_id);
3088  GLint level = static_cast<GLint>(c.level);
3089  GLint internalformat = static_cast<GLint>(c.internalformat);
3090  GLenum dest_type = static_cast<GLenum>(c.dest_type);
3091  if (!validators_->texture_internal_format.IsValid(internalformat)) {
3092    LOCAL_SET_GL_ERROR(
3093        GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "internalformat GL_INVALID_VALUE");  // NOLINT
3094    return error::kNoError;
3095  }
3096  if (!validators_->pixel_type.IsValid(dest_type)) {
3097    LOCAL_SET_GL_ERROR_INVALID_ENUM("glCopyTextureCHROMIUM", dest_type,
3098    "dest_type");
3099    return error::kNoError;
3100  }
3101  DoCopyTextureCHROMIUM(
3102      target, source_id, dest_id, level, internalformat, dest_type);
3103  return error::kNoError;
3104}
3105
3106error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUM(
3107    uint32 immediate_data_size, const gles2::cmds::ProduceTextureCHROMIUM& c) {
3108  GLenum target = static_cast<GLenum>(c.target);
3109  uint32 data_size;
3110  if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
3111    return error::kOutOfBounds;
3112  }
3113  const GLbyte* mailbox = GetSharedMemoryAs<const GLbyte*>(
3114      c.mailbox_shm_id, c.mailbox_shm_offset, data_size);
3115  if (!validators_->texture_bind_target.IsValid(target)) {
3116    LOCAL_SET_GL_ERROR_INVALID_ENUM("glProduceTextureCHROMIUM", target,
3117    "target");
3118    return error::kNoError;
3119  }
3120  if (mailbox == NULL) {
3121    return error::kOutOfBounds;
3122  }
3123  DoProduceTextureCHROMIUM(target, mailbox);
3124  return error::kNoError;
3125}
3126
3127error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUMImmediate(
3128    uint32 immediate_data_size,
3129    const gles2::cmds::ProduceTextureCHROMIUMImmediate& c) {
3130  GLenum target = static_cast<GLenum>(c.target);
3131  uint32 data_size;
3132  if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
3133    return error::kOutOfBounds;
3134  }
3135  if (data_size > immediate_data_size) {
3136    return error::kOutOfBounds;
3137  }
3138  const GLbyte* mailbox = GetImmediateDataAs<const GLbyte*>(
3139      c, data_size, immediate_data_size);
3140  if (!validators_->texture_bind_target.IsValid(target)) {
3141    LOCAL_SET_GL_ERROR_INVALID_ENUM("glProduceTextureCHROMIUM", target,
3142    "target");
3143    return error::kNoError;
3144  }
3145  if (mailbox == NULL) {
3146    return error::kOutOfBounds;
3147  }
3148  DoProduceTextureCHROMIUM(target, mailbox);
3149  return error::kNoError;
3150}
3151
3152error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUM(
3153    uint32 immediate_data_size, const gles2::cmds::ConsumeTextureCHROMIUM& c) {
3154  GLenum target = static_cast<GLenum>(c.target);
3155  uint32 data_size;
3156  if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
3157    return error::kOutOfBounds;
3158  }
3159  const GLbyte* mailbox = GetSharedMemoryAs<const GLbyte*>(
3160      c.mailbox_shm_id, c.mailbox_shm_offset, data_size);
3161  if (!validators_->texture_bind_target.IsValid(target)) {
3162    LOCAL_SET_GL_ERROR_INVALID_ENUM("glConsumeTextureCHROMIUM", target,
3163    "target");
3164    return error::kNoError;
3165  }
3166  if (mailbox == NULL) {
3167    return error::kOutOfBounds;
3168  }
3169  DoConsumeTextureCHROMIUM(target, mailbox);
3170  return error::kNoError;
3171}
3172
3173error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUMImmediate(
3174    uint32 immediate_data_size,
3175    const gles2::cmds::ConsumeTextureCHROMIUMImmediate& c) {
3176  GLenum target = static_cast<GLenum>(c.target);
3177  uint32 data_size;
3178  if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
3179    return error::kOutOfBounds;
3180  }
3181  if (data_size > immediate_data_size) {
3182    return error::kOutOfBounds;
3183  }
3184  const GLbyte* mailbox = GetImmediateDataAs<const GLbyte*>(
3185      c, data_size, immediate_data_size);
3186  if (!validators_->texture_bind_target.IsValid(target)) {
3187    LOCAL_SET_GL_ERROR_INVALID_ENUM("glConsumeTextureCHROMIUM", target,
3188    "target");
3189    return error::kNoError;
3190  }
3191  if (mailbox == NULL) {
3192    return error::kOutOfBounds;
3193  }
3194  DoConsumeTextureCHROMIUM(target, mailbox);
3195  return error::kNoError;
3196}
3197
3198error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM(
3199    uint32 immediate_data_size, const gles2::cmds::BindTexImage2DCHROMIUM& c) {
3200  GLenum target = static_cast<GLenum>(c.target);
3201  GLint imageId = static_cast<GLint>(c.imageId);
3202  if (!validators_->texture_bind_target.IsValid(target)) {
3203    LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindTexImage2DCHROMIUM", target,
3204    "target");
3205    return error::kNoError;
3206  }
3207  DoBindTexImage2DCHROMIUM(target, imageId);
3208  return error::kNoError;
3209}
3210
3211error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM(
3212    uint32 immediate_data_size,
3213    const gles2::cmds::ReleaseTexImage2DCHROMIUM& c) {
3214  GLenum target = static_cast<GLenum>(c.target);
3215  GLint imageId = static_cast<GLint>(c.imageId);
3216  if (!validators_->texture_bind_target.IsValid(target)) {
3217    LOCAL_SET_GL_ERROR_INVALID_ENUM("glReleaseTexImage2DCHROMIUM", target,
3218    "target");
3219    return error::kNoError;
3220  }
3221  DoReleaseTexImage2DCHROMIUM(target, imageId);
3222  return error::kNoError;
3223}
3224
3225error::Error GLES2DecoderImpl::HandleTraceEndCHROMIUM(
3226    uint32 immediate_data_size, const gles2::cmds::TraceEndCHROMIUM& c) {
3227  DoTraceEndCHROMIUM();
3228  return error::kNoError;
3229}
3230
3231error::Error GLES2DecoderImpl::HandleDiscardFramebufferEXT(
3232    uint32 immediate_data_size, const gles2::cmds::DiscardFramebufferEXT& c) {
3233  GLenum target = static_cast<GLenum>(c.target);
3234  GLsizei count = static_cast<GLsizei>(c.count);
3235  uint32 data_size;
3236  if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
3237    return error::kOutOfBounds;
3238  }
3239  const GLenum* attachments = GetSharedMemoryAs<const GLenum*>(
3240      c.attachments_shm_id, c.attachments_shm_offset, data_size);
3241  if (count < 0) {
3242    LOCAL_SET_GL_ERROR(
3243        GL_INVALID_VALUE, "glDiscardFramebufferEXT", "count < 0");
3244    return error::kNoError;
3245  }
3246  if (attachments == NULL) {
3247    return error::kOutOfBounds;
3248  }
3249  DoDiscardFramebufferEXT(target, count, attachments);
3250  return error::kNoError;
3251}
3252
3253error::Error GLES2DecoderImpl::HandleDiscardFramebufferEXTImmediate(
3254    uint32 immediate_data_size,
3255    const gles2::cmds::DiscardFramebufferEXTImmediate& c) {
3256  GLenum target = static_cast<GLenum>(c.target);
3257  GLsizei count = static_cast<GLsizei>(c.count);
3258  uint32 data_size;
3259  if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
3260    return error::kOutOfBounds;
3261  }
3262  if (data_size > immediate_data_size) {
3263    return error::kOutOfBounds;
3264  }
3265  const GLenum* attachments = GetImmediateDataAs<const GLenum*>(
3266      c, data_size, immediate_data_size);
3267  if (count < 0) {
3268    LOCAL_SET_GL_ERROR(
3269        GL_INVALID_VALUE, "glDiscardFramebufferEXT", "count < 0");
3270    return error::kNoError;
3271  }
3272  if (attachments == NULL) {
3273    return error::kOutOfBounds;
3274  }
3275  DoDiscardFramebufferEXT(target, count, attachments);
3276  return error::kNoError;
3277}
3278
3279error::Error GLES2DecoderImpl::HandleDrawBuffersEXT(
3280    uint32 immediate_data_size, const gles2::cmds::DrawBuffersEXT& c) {
3281  GLsizei count = static_cast<GLsizei>(c.count);
3282  uint32 data_size;
3283  if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
3284    return error::kOutOfBounds;
3285  }
3286  const GLenum* bufs = GetSharedMemoryAs<const GLenum*>(
3287      c.bufs_shm_id, c.bufs_shm_offset, data_size);
3288  if (count < 0) {
3289    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDrawBuffersEXT", "count < 0");
3290    return error::kNoError;
3291  }
3292  if (bufs == NULL) {
3293    return error::kOutOfBounds;
3294  }
3295  DoDrawBuffersEXT(count, bufs);
3296  return error::kNoError;
3297}
3298
3299error::Error GLES2DecoderImpl::HandleDrawBuffersEXTImmediate(
3300    uint32 immediate_data_size,
3301    const gles2::cmds::DrawBuffersEXTImmediate& c) {
3302  GLsizei count = static_cast<GLsizei>(c.count);
3303  uint32 data_size;
3304  if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
3305    return error::kOutOfBounds;
3306  }
3307  if (data_size > immediate_data_size) {
3308    return error::kOutOfBounds;
3309  }
3310  const GLenum* bufs = GetImmediateDataAs<const GLenum*>(
3311      c, data_size, immediate_data_size);
3312  if (count < 0) {
3313    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDrawBuffersEXT", "count < 0");
3314    return error::kNoError;
3315  }
3316  if (bufs == NULL) {
3317    return error::kOutOfBounds;
3318  }
3319  DoDrawBuffersEXT(count, bufs);
3320  return error::kNoError;
3321}
3322
3323
3324bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
3325  switch (cap) {
3326    case GL_BLEND:
3327      state_.enable_flags.blend = enabled;
3328      return true;
3329    case GL_CULL_FACE:
3330      state_.enable_flags.cull_face = enabled;
3331      return true;
3332    case GL_DEPTH_TEST:
3333      if (state_.enable_flags.depth_test != enabled) {
3334        state_.enable_flags.depth_test = enabled;
3335        clear_state_dirty_ = true;
3336      }
3337      return false;
3338    case GL_DITHER:
3339      state_.enable_flags.dither = enabled;
3340      return true;
3341    case GL_POLYGON_OFFSET_FILL:
3342      state_.enable_flags.polygon_offset_fill = enabled;
3343      return true;
3344    case GL_SAMPLE_ALPHA_TO_COVERAGE:
3345      state_.enable_flags.sample_alpha_to_coverage = enabled;
3346      return true;
3347    case GL_SAMPLE_COVERAGE:
3348      state_.enable_flags.sample_coverage = enabled;
3349      return true;
3350    case GL_SCISSOR_TEST:
3351      if (state_.enable_flags.scissor_test != enabled) {
3352        state_.enable_flags.scissor_test = enabled;
3353        clear_state_dirty_ = true;
3354      }
3355      return false;
3356    case GL_STENCIL_TEST:
3357      if (state_.enable_flags.stencil_test != enabled) {
3358        state_.enable_flags.stencil_test = enabled;
3359        clear_state_dirty_ = true;
3360      }
3361      return false;
3362    default:
3363      NOTREACHED();
3364      return false;
3365  }
3366}
3367#endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
3368
3369