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