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