build_gles2_cmd_buffer.py revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""code generator for GLES2 command buffers."""
7
8import itertools
9import os
10import os.path
11import sys
12import re
13from optparse import OptionParser
14from subprocess import call
15
16_SIZE_OF_UINT32 = 4
17_SIZE_OF_COMMAND_HEADER = 4
18_FIRST_SPECIFIC_COMMAND_ID = 256
19
20_LICENSE = """// Copyright 2014 The Chromium Authors. All rights reserved.
21// Use of this source code is governed by a BSD-style license that can be
22// found in the LICENSE file.
23
24"""
25
26_DO_NOT_EDIT_WARNING = """// This file is auto-generated from
27// gpu/command_buffer/build_gles2_cmd_buffer.py
28// It's formatted by clang-format using chromium coding style:
29//    clang-format -i -style=chromium filename
30// DO NOT EDIT!
31
32"""
33
34# This string is copied directly out of the gl2.h file from GLES2.0
35#
36# Edits:
37#
38# *) Any argument that is a resourceID has been changed to GLid<Type>.
39#    (not pointer arguments) and if it's allowed to be zero it's GLidZero<Type>
40#    If it's allowed to not exist it's GLidBind<Type>
41#
42# *) All GLenums have been changed to GLenumTypeOfEnum
43#
44_GL_TYPES = {
45  'GLenum': 'unsigned int',
46  'GLboolean': 'unsigned char',
47  'GLbitfield': 'unsigned int',
48  'GLbyte': 'signed char',
49  'GLshort': 'short',
50  'GLint': 'int',
51  'GLsizei': 'int',
52  'GLubyte': 'unsigned char',
53  'GLushort': 'unsigned short',
54  'GLuint': 'unsigned int',
55  'GLfloat': 'float',
56  'GLclampf': 'float',
57  'GLvoid': 'void',
58  'GLfixed': 'int',
59  'GLclampx': 'int'
60}
61
62_GL_TYPES_32 = {
63  'GLintptr': 'long int',
64  'GLsizeiptr': 'long int'
65}
66
67_GL_TYPES_64 = {
68  'GLintptr': 'long long int',
69  'GLsizeiptr': 'long long int'
70}
71
72# Capabilites selected with glEnable
73_CAPABILITY_FLAGS = [
74  {'name': 'blend'},
75  {'name': 'cull_face'},
76  {'name': 'depth_test', 'state_flag': 'framebuffer_state_.clear_state_dirty'},
77  {'name': 'dither', 'default': True},
78  {'name': 'polygon_offset_fill'},
79  {'name': 'sample_alpha_to_coverage'},
80  {'name': 'sample_coverage'},
81  {'name': 'scissor_test',
82   'state_flag': 'framebuffer_state_.clear_state_dirty'},
83  {'name': 'stencil_test',
84   'state_flag': 'framebuffer_state_.clear_state_dirty'},
85]
86
87_STATES = {
88  'ClearColor': {
89    'type': 'Normal',
90    'func': 'ClearColor',
91    'enum': 'GL_COLOR_CLEAR_VALUE',
92    'states': [
93      {'name': 'color_clear_red', 'type': 'GLfloat', 'default': '0.0f'},
94      {'name': 'color_clear_green', 'type': 'GLfloat', 'default': '0.0f'},
95      {'name': 'color_clear_blue', 'type': 'GLfloat', 'default': '0.0f'},
96      {'name': 'color_clear_alpha', 'type': 'GLfloat', 'default': '0.0f'},
97    ],
98  },
99  'ClearDepthf': {
100    'type': 'Normal',
101    'func': 'ClearDepth',
102    'enum': 'GL_DEPTH_CLEAR_VALUE',
103    'states': [
104      {'name': 'depth_clear', 'type': 'GLclampf', 'default': '1.0f'},
105    ],
106  },
107  'ColorMask': {
108    'type': 'Normal',
109    'func': 'ColorMask',
110    'enum': 'GL_COLOR_WRITEMASK',
111    'states': [
112      {'name': 'color_mask_red', 'type': 'GLboolean', 'default': 'true'},
113      {'name': 'color_mask_green', 'type': 'GLboolean', 'default': 'true'},
114      {'name': 'color_mask_blue', 'type': 'GLboolean', 'default': 'true'},
115      {'name': 'color_mask_alpha', 'type': 'GLboolean', 'default': 'true'},
116    ],
117    'state_flag': 'framebuffer_state_.clear_state_dirty',
118  },
119  'ClearStencil': {
120    'type': 'Normal',
121    'func': 'ClearStencil',
122    'enum': 'GL_STENCIL_CLEAR_VALUE',
123    'states': [
124      {'name': 'stencil_clear', 'type': 'GLint', 'default': '0'},
125    ],
126  },
127  'BlendColor': {
128    'type': 'Normal',
129    'func': 'BlendColor',
130    'enum': 'GL_BLEND_COLOR',
131    'states': [
132      {'name': 'blend_color_red', 'type': 'GLfloat', 'default': '0.0f'},
133      {'name': 'blend_color_green', 'type': 'GLfloat', 'default': '0.0f'},
134      {'name': 'blend_color_blue', 'type': 'GLfloat', 'default': '0.0f'},
135      {'name': 'blend_color_alpha', 'type': 'GLfloat', 'default': '0.0f'},
136    ],
137  },
138  'BlendEquation': {
139    'type': 'SrcDst',
140    'func': 'BlendEquationSeparate',
141    'states': [
142      {
143        'name': 'blend_equation_rgb',
144        'type': 'GLenum',
145        'enum': 'GL_BLEND_EQUATION_RGB',
146        'default': 'GL_FUNC_ADD',
147      },
148      {
149        'name': 'blend_equation_alpha',
150        'type': 'GLenum',
151        'enum': 'GL_BLEND_EQUATION_ALPHA',
152        'default': 'GL_FUNC_ADD',
153      },
154    ],
155  },
156  'BlendFunc': {
157    'type': 'SrcDst',
158    'func': 'BlendFuncSeparate',
159    'states': [
160      {
161        'name': 'blend_source_rgb',
162        'type': 'GLenum',
163        'enum': 'GL_BLEND_SRC_RGB',
164        'default': 'GL_ONE',
165      },
166      {
167        'name': 'blend_dest_rgb',
168        'type': 'GLenum',
169        'enum': 'GL_BLEND_DST_RGB',
170        'default': 'GL_ZERO',
171      },
172      {
173        'name': 'blend_source_alpha',
174        'type': 'GLenum',
175        'enum': 'GL_BLEND_SRC_ALPHA',
176        'default': 'GL_ONE',
177      },
178      {
179        'name': 'blend_dest_alpha',
180        'type': 'GLenum',
181        'enum': 'GL_BLEND_DST_ALPHA',
182        'default': 'GL_ZERO',
183      },
184    ],
185  },
186  'PolygonOffset': {
187    'type': 'Normal',
188    'func': 'PolygonOffset',
189    'states': [
190      {
191        'name': 'polygon_offset_factor',
192        'type': 'GLfloat',
193        'enum': 'GL_POLYGON_OFFSET_FACTOR',
194        'default': '0.0f',
195      },
196      {
197        'name': 'polygon_offset_units',
198        'type': 'GLfloat',
199        'enum': 'GL_POLYGON_OFFSET_UNITS',
200        'default': '0.0f',
201      },
202    ],
203  },
204  'CullFace':  {
205    'type': 'Normal',
206    'func': 'CullFace',
207    'enum': 'GL_CULL_FACE_MODE',
208    'states': [
209      {
210        'name': 'cull_mode',
211        'type': 'GLenum',
212        'default': 'GL_BACK',
213      },
214    ],
215  },
216  'FrontFace': {
217    'type': 'Normal',
218    'func': 'FrontFace',
219    'enum': 'GL_FRONT_FACE',
220    'states': [{'name': 'front_face', 'type': 'GLenum', 'default': 'GL_CCW'}],
221  },
222  'DepthFunc': {
223    'type': 'Normal',
224    'func': 'DepthFunc',
225    'enum': 'GL_DEPTH_FUNC',
226    'states': [{'name': 'depth_func', 'type': 'GLenum', 'default': 'GL_LESS'}],
227  },
228  'DepthRange': {
229    'type': 'Normal',
230    'func': 'DepthRange',
231    'enum': 'GL_DEPTH_RANGE',
232    'states': [
233      {'name': 'z_near', 'type': 'GLclampf', 'default': '0.0f'},
234      {'name': 'z_far', 'type': 'GLclampf', 'default': '1.0f'},
235    ],
236  },
237  'SampleCoverage': {
238    'type': 'Normal',
239    'func': 'SampleCoverage',
240    'states': [
241      {
242        'name': 'sample_coverage_value',
243        'type': 'GLclampf',
244        'enum': 'GL_SAMPLE_COVERAGE_VALUE',
245        'default': '1.0f',
246      },
247      {
248        'name': 'sample_coverage_invert',
249        'type': 'GLboolean',
250        'enum': 'GL_SAMPLE_COVERAGE_INVERT',
251        'default': 'false',
252      },
253    ],
254  },
255  'StencilMask': {
256    'type': 'FrontBack',
257    'func': 'StencilMaskSeparate',
258    'state_flag': 'framebuffer_state_.clear_state_dirty',
259    'states': [
260      {
261        'name': 'stencil_front_writemask',
262        'type': 'GLuint',
263        'enum': 'GL_STENCIL_WRITEMASK',
264        'default': '0xFFFFFFFFU',
265      },
266      {
267        'name': 'stencil_back_writemask',
268        'type': 'GLuint',
269        'enum': 'GL_STENCIL_BACK_WRITEMASK',
270        'default': '0xFFFFFFFFU',
271      },
272    ],
273  },
274  'StencilOp': {
275    'type': 'FrontBack',
276    'func': 'StencilOpSeparate',
277    'states': [
278      {
279        'name': 'stencil_front_fail_op',
280        'type': 'GLenum',
281        'enum': 'GL_STENCIL_FAIL',
282        'default': 'GL_KEEP',
283      },
284      {
285        'name': 'stencil_front_z_fail_op',
286        'type': 'GLenum',
287        'enum': 'GL_STENCIL_PASS_DEPTH_FAIL',
288        'default': 'GL_KEEP',
289      },
290      {
291        'name': 'stencil_front_z_pass_op',
292        'type': 'GLenum',
293        'enum': 'GL_STENCIL_PASS_DEPTH_PASS',
294        'default': 'GL_KEEP',
295      },
296      {
297        'name': 'stencil_back_fail_op',
298        'type': 'GLenum',
299        'enum': 'GL_STENCIL_BACK_FAIL',
300        'default': 'GL_KEEP',
301      },
302      {
303        'name': 'stencil_back_z_fail_op',
304        'type': 'GLenum',
305        'enum': 'GL_STENCIL_BACK_PASS_DEPTH_FAIL',
306        'default': 'GL_KEEP',
307      },
308      {
309        'name': 'stencil_back_z_pass_op',
310        'type': 'GLenum',
311        'enum': 'GL_STENCIL_BACK_PASS_DEPTH_PASS',
312        'default': 'GL_KEEP',
313      },
314    ],
315  },
316  'StencilFunc': {
317    'type': 'FrontBack',
318    'func': 'StencilFuncSeparate',
319    'states': [
320      {
321        'name': 'stencil_front_func',
322        'type': 'GLenum',
323        'enum': 'GL_STENCIL_FUNC',
324        'default': 'GL_ALWAYS',
325      },
326      {
327        'name': 'stencil_front_ref',
328        'type': 'GLint',
329        'enum': 'GL_STENCIL_REF',
330        'default': '0',
331      },
332      {
333        'name': 'stencil_front_mask',
334        'type': 'GLuint',
335        'enum': 'GL_STENCIL_VALUE_MASK',
336        'default': '0xFFFFFFFFU',
337      },
338      {
339        'name': 'stencil_back_func',
340        'type': 'GLenum',
341        'enum': 'GL_STENCIL_BACK_FUNC',
342        'default': 'GL_ALWAYS',
343      },
344      {
345        'name': 'stencil_back_ref',
346        'type': 'GLint',
347        'enum': 'GL_STENCIL_BACK_REF',
348        'default': '0',
349      },
350      {
351        'name': 'stencil_back_mask',
352        'type': 'GLuint',
353        'enum': 'GL_STENCIL_BACK_VALUE_MASK',
354        'default': '0xFFFFFFFFU',
355      },
356    ],
357  },
358  'Hint': {
359    'type': 'NamedParameter',
360    'func': 'Hint',
361    'states': [
362      {
363        'name': 'hint_generate_mipmap',
364        'type': 'GLenum',
365        'enum': 'GL_GENERATE_MIPMAP_HINT',
366        'default': 'GL_DONT_CARE'
367      },
368      {
369        'name': 'hint_fragment_shader_derivative',
370        'type': 'GLenum',
371        'enum': 'GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES',
372        'default': 'GL_DONT_CARE',
373        'extension_flag': 'oes_standard_derivatives'
374      }
375    ],
376  },
377  'PixelStore': {
378    'type': 'NamedParameter',
379    'func': 'PixelStorei',
380    'states': [
381      {
382        'name': 'pack_alignment',
383        'type': 'GLint',
384        'enum': 'GL_PACK_ALIGNMENT',
385        'default': '4'
386      },
387      {
388        'name': 'unpack_alignment',
389        'type': 'GLint',
390        'enum': 'GL_UNPACK_ALIGNMENT',
391        'default': '4'
392      }
393    ],
394  },
395  # TODO: Consider implemenenting these states
396  # GL_ACTIVE_TEXTURE
397  'LineWidth': {
398    'type': 'Normal',
399    'func': 'LineWidth',
400    'enum': 'GL_LINE_WIDTH',
401    'states': [
402      {
403        'name': 'line_width',
404        'type': 'GLfloat',
405        'default': '1.0f',
406        'range_checks': [{'check': "<= 0.0f", 'test_value': "0.0f"}],
407      }],
408  },
409  'DepthMask': {
410    'type': 'Normal',
411    'func': 'DepthMask',
412    'enum': 'GL_DEPTH_WRITEMASK',
413    'states': [
414      {'name': 'depth_mask', 'type': 'GLboolean', 'default': 'true'},
415    ],
416    'state_flag': 'framebuffer_state_.clear_state_dirty',
417  },
418  'Scissor': {
419    'type': 'Normal',
420    'func': 'Scissor',
421    'enum': 'GL_SCISSOR_BOX',
422    'states': [
423      # NOTE: These defaults reset at GLES2DecoderImpl::Initialization.
424      {
425        'name': 'scissor_x',
426        'type': 'GLint',
427        'default': '0',
428        'expected': 'kViewportX',
429      },
430      {
431        'name': 'scissor_y',
432        'type': 'GLint',
433        'default': '0',
434        'expected': 'kViewportY',
435      },
436      {
437        'name': 'scissor_width',
438        'type': 'GLsizei',
439        'default': '1',
440        'expected': 'kViewportWidth',
441      },
442      {
443        'name': 'scissor_height',
444        'type': 'GLsizei',
445        'default': '1',
446        'expected': 'kViewportHeight',
447      },
448    ],
449  },
450  'Viewport': {
451    'type': 'Normal',
452    'func': 'Viewport',
453    'enum': 'GL_VIEWPORT',
454    'states': [
455      # NOTE: These defaults reset at GLES2DecoderImpl::Initialization.
456      {
457        'name': 'viewport_x',
458        'type': 'GLint',
459        'default': '0',
460        'expected': 'kViewportX',
461      },
462      {
463        'name': 'viewport_y',
464        'type': 'GLint',
465        'default': '0',
466        'expected': 'kViewportY',
467      },
468      {
469        'name': 'viewport_width',
470        'type': 'GLsizei',
471        'default': '1',
472        'expected': 'kViewportWidth',
473      },
474      {
475        'name': 'viewport_height',
476        'type': 'GLsizei',
477        'default': '1',
478        'expected': 'kViewportHeight',
479      },
480    ],
481  },
482}
483
484# This is a list of enum names and their valid values. It is used to map
485# GLenum arguments to a specific set of valid values.
486_ENUM_LISTS = {
487  'BlitFilter': {
488    'type': 'GLenum',
489    'valid': [
490      'GL_NEAREST',
491      'GL_LINEAR',
492    ],
493    'invalid': [
494      'GL_LINEAR_MIPMAP_LINEAR',
495    ],
496  },
497  'FrameBufferTarget': {
498    'type': 'GLenum',
499    'valid': [
500      'GL_FRAMEBUFFER',
501    ],
502    'invalid': [
503      'GL_DRAW_FRAMEBUFFER' ,
504      'GL_READ_FRAMEBUFFER' ,
505    ],
506  },
507  'RenderBufferTarget': {
508    'type': 'GLenum',
509    'valid': [
510      'GL_RENDERBUFFER',
511    ],
512    'invalid': [
513      'GL_FRAMEBUFFER',
514    ],
515  },
516  'BufferTarget': {
517    'type': 'GLenum',
518    'valid': [
519      'GL_ARRAY_BUFFER',
520      'GL_ELEMENT_ARRAY_BUFFER',
521    ],
522    'invalid': [
523      'GL_RENDERBUFFER',
524    ],
525  },
526  'BufferUsage': {
527    'type': 'GLenum',
528    'valid': [
529      'GL_STREAM_DRAW',
530      'GL_STATIC_DRAW',
531      'GL_DYNAMIC_DRAW',
532    ],
533    'invalid': [
534      'GL_STATIC_READ',
535    ],
536  },
537  'CompressedTextureFormat': {
538    'type': 'GLenum',
539    'valid': [
540    ],
541  },
542  'GLState': {
543    'type': 'GLenum',
544    'valid': [
545      # NOTE: State an Capability entries added later.
546      'GL_ACTIVE_TEXTURE',
547      'GL_ALIASED_LINE_WIDTH_RANGE',
548      'GL_ALIASED_POINT_SIZE_RANGE',
549      'GL_ALPHA_BITS',
550      'GL_ARRAY_BUFFER_BINDING',
551      'GL_BLUE_BITS',
552      'GL_COMPRESSED_TEXTURE_FORMATS',
553      'GL_CURRENT_PROGRAM',
554      'GL_DEPTH_BITS',
555      'GL_DEPTH_RANGE',
556      'GL_ELEMENT_ARRAY_BUFFER_BINDING',
557      'GL_FRAMEBUFFER_BINDING',
558      'GL_GENERATE_MIPMAP_HINT',
559      'GL_GREEN_BITS',
560      'GL_IMPLEMENTATION_COLOR_READ_FORMAT',
561      'GL_IMPLEMENTATION_COLOR_READ_TYPE',
562      'GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS',
563      'GL_MAX_CUBE_MAP_TEXTURE_SIZE',
564      'GL_MAX_FRAGMENT_UNIFORM_VECTORS',
565      'GL_MAX_RENDERBUFFER_SIZE',
566      'GL_MAX_TEXTURE_IMAGE_UNITS',
567      'GL_MAX_TEXTURE_SIZE',
568      'GL_MAX_VARYING_VECTORS',
569      'GL_MAX_VERTEX_ATTRIBS',
570      'GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS',
571      'GL_MAX_VERTEX_UNIFORM_VECTORS',
572      'GL_MAX_VIEWPORT_DIMS',
573      'GL_NUM_COMPRESSED_TEXTURE_FORMATS',
574      'GL_NUM_SHADER_BINARY_FORMATS',
575      'GL_PACK_ALIGNMENT',
576      'GL_RED_BITS',
577      'GL_RENDERBUFFER_BINDING',
578      'GL_SAMPLE_BUFFERS',
579      'GL_SAMPLE_COVERAGE_INVERT',
580      'GL_SAMPLE_COVERAGE_VALUE',
581      'GL_SAMPLES',
582      'GL_SCISSOR_BOX',
583      'GL_SHADER_BINARY_FORMATS',
584      'GL_SHADER_COMPILER',
585      'GL_SUBPIXEL_BITS',
586      'GL_STENCIL_BITS',
587      'GL_TEXTURE_BINDING_2D',
588      'GL_TEXTURE_BINDING_CUBE_MAP',
589      'GL_UNPACK_ALIGNMENT',
590      'GL_UNPACK_FLIP_Y_CHROMIUM',
591      'GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM',
592      'GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM',
593      'GL_BIND_GENERATES_RESOURCE_CHROMIUM',
594      # we can add this because we emulate it if the driver does not support it.
595      'GL_VERTEX_ARRAY_BINDING_OES',
596      'GL_VIEWPORT',
597    ],
598    'invalid': [
599      'GL_FOG_HINT',
600    ],
601  },
602  'GetTexParamTarget': {
603    'type': 'GLenum',
604    'valid': [
605      'GL_TEXTURE_2D',
606      'GL_TEXTURE_CUBE_MAP',
607    ],
608    'invalid': [
609      'GL_PROXY_TEXTURE_CUBE_MAP',
610    ]
611  },
612  'TextureTarget': {
613    'type': 'GLenum',
614    'valid': [
615      'GL_TEXTURE_2D',
616      'GL_TEXTURE_CUBE_MAP_POSITIVE_X',
617      'GL_TEXTURE_CUBE_MAP_NEGATIVE_X',
618      'GL_TEXTURE_CUBE_MAP_POSITIVE_Y',
619      'GL_TEXTURE_CUBE_MAP_NEGATIVE_Y',
620      'GL_TEXTURE_CUBE_MAP_POSITIVE_Z',
621      'GL_TEXTURE_CUBE_MAP_NEGATIVE_Z',
622    ],
623    'invalid': [
624      'GL_PROXY_TEXTURE_CUBE_MAP',
625    ]
626  },
627  'TextureBindTarget': {
628    'type': 'GLenum',
629    'valid': [
630      'GL_TEXTURE_2D',
631      'GL_TEXTURE_CUBE_MAP',
632    ],
633    'invalid': [
634      'GL_TEXTURE_1D',
635      'GL_TEXTURE_3D',
636    ],
637  },
638  'ShaderType': {
639    'type': 'GLenum',
640    'valid': [
641      'GL_VERTEX_SHADER',
642      'GL_FRAGMENT_SHADER',
643    ],
644    'invalid': [
645      'GL_GEOMETRY_SHADER',
646    ],
647  },
648  'FaceType': {
649    'type': 'GLenum',
650    'valid': [
651      'GL_FRONT',
652      'GL_BACK',
653      'GL_FRONT_AND_BACK',
654    ],
655  },
656  'FaceMode': {
657    'type': 'GLenum',
658    'valid': [
659      'GL_CW',
660      'GL_CCW',
661    ],
662  },
663  'CmpFunction': {
664    'type': 'GLenum',
665    'valid': [
666      'GL_NEVER',
667      'GL_LESS',
668      'GL_EQUAL',
669      'GL_LEQUAL',
670      'GL_GREATER',
671      'GL_NOTEQUAL',
672      'GL_GEQUAL',
673      'GL_ALWAYS',
674    ],
675  },
676  'Equation': {
677    'type': 'GLenum',
678    'valid': [
679      'GL_FUNC_ADD',
680      'GL_FUNC_SUBTRACT',
681      'GL_FUNC_REVERSE_SUBTRACT',
682    ],
683    'invalid': [
684      'GL_MIN',
685      'GL_MAX',
686    ],
687  },
688  'SrcBlendFactor': {
689    'type': 'GLenum',
690    'valid': [
691      'GL_ZERO',
692      'GL_ONE',
693      'GL_SRC_COLOR',
694      'GL_ONE_MINUS_SRC_COLOR',
695      'GL_DST_COLOR',
696      'GL_ONE_MINUS_DST_COLOR',
697      'GL_SRC_ALPHA',
698      'GL_ONE_MINUS_SRC_ALPHA',
699      'GL_DST_ALPHA',
700      'GL_ONE_MINUS_DST_ALPHA',
701      'GL_CONSTANT_COLOR',
702      'GL_ONE_MINUS_CONSTANT_COLOR',
703      'GL_CONSTANT_ALPHA',
704      'GL_ONE_MINUS_CONSTANT_ALPHA',
705      'GL_SRC_ALPHA_SATURATE',
706    ],
707  },
708  'DstBlendFactor': {
709    'type': 'GLenum',
710    'valid': [
711      'GL_ZERO',
712      'GL_ONE',
713      'GL_SRC_COLOR',
714      'GL_ONE_MINUS_SRC_COLOR',
715      'GL_DST_COLOR',
716      'GL_ONE_MINUS_DST_COLOR',
717      'GL_SRC_ALPHA',
718      'GL_ONE_MINUS_SRC_ALPHA',
719      'GL_DST_ALPHA',
720      'GL_ONE_MINUS_DST_ALPHA',
721      'GL_CONSTANT_COLOR',
722      'GL_ONE_MINUS_CONSTANT_COLOR',
723      'GL_CONSTANT_ALPHA',
724      'GL_ONE_MINUS_CONSTANT_ALPHA',
725    ],
726  },
727  'Capability': {
728    'type': 'GLenum',
729    'valid': ["GL_%s" % cap['name'].upper() for cap in _CAPABILITY_FLAGS],
730    'invalid': [
731      'GL_CLIP_PLANE0',
732      'GL_POINT_SPRITE',
733    ],
734  },
735  'DrawMode': {
736    'type': 'GLenum',
737    'valid': [
738      'GL_POINTS',
739      'GL_LINE_STRIP',
740      'GL_LINE_LOOP',
741      'GL_LINES',
742      'GL_TRIANGLE_STRIP',
743      'GL_TRIANGLE_FAN',
744      'GL_TRIANGLES',
745    ],
746    'invalid': [
747      'GL_QUADS',
748      'GL_POLYGON',
749    ],
750  },
751  'IndexType': {
752    'type': 'GLenum',
753    'valid': [
754      'GL_UNSIGNED_BYTE',
755      'GL_UNSIGNED_SHORT',
756    ],
757    'invalid': [
758      'GL_UNSIGNED_INT',
759      'GL_INT',
760    ],
761  },
762  'GetMaxIndexType': {
763    'type': 'GLenum',
764    'valid': [
765      'GL_UNSIGNED_BYTE',
766      'GL_UNSIGNED_SHORT',
767      'GL_UNSIGNED_INT',
768    ],
769    'invalid': [
770      'GL_INT',
771    ],
772  },
773  'Attachment': {
774    'type': 'GLenum',
775    'valid': [
776      'GL_COLOR_ATTACHMENT0',
777      'GL_DEPTH_ATTACHMENT',
778      'GL_STENCIL_ATTACHMENT',
779    ],
780  },
781  'BackbufferAttachment': {
782    'type': 'GLenum',
783    'valid': [
784      'GL_COLOR_EXT',
785      'GL_DEPTH_EXT',
786      'GL_STENCIL_EXT',
787    ],
788  },
789  'BufferParameter': {
790    'type': 'GLenum',
791    'valid': [
792      'GL_BUFFER_SIZE',
793      'GL_BUFFER_USAGE',
794    ],
795    'invalid': [
796      'GL_PIXEL_PACK_BUFFER',
797    ],
798  },
799  'FrameBufferParameter': {
800    'type': 'GLenum',
801    'valid': [
802      'GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE',
803      'GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME',
804      'GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL',
805      'GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE',
806    ],
807  },
808  'ProgramParameter': {
809    'type': 'GLenum',
810    'valid': [
811      'GL_DELETE_STATUS',
812      'GL_LINK_STATUS',
813      'GL_VALIDATE_STATUS',
814      'GL_INFO_LOG_LENGTH',
815      'GL_ATTACHED_SHADERS',
816      'GL_ACTIVE_ATTRIBUTES',
817      'GL_ACTIVE_ATTRIBUTE_MAX_LENGTH',
818      'GL_ACTIVE_UNIFORMS',
819      'GL_ACTIVE_UNIFORM_MAX_LENGTH',
820    ],
821  },
822  'QueryObjectParameter': {
823    'type': 'GLenum',
824    'valid': [
825      'GL_QUERY_RESULT_EXT',
826      'GL_QUERY_RESULT_AVAILABLE_EXT',
827    ],
828  },
829  'QueryParameter': {
830    'type': 'GLenum',
831    'valid': [
832      'GL_CURRENT_QUERY_EXT',
833    ],
834  },
835  'QueryTarget': {
836    'type': 'GLenum',
837    'valid': [
838      'GL_ANY_SAMPLES_PASSED_EXT',
839      'GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT',
840      'GL_COMMANDS_ISSUED_CHROMIUM',
841      'GL_LATENCY_QUERY_CHROMIUM',
842      'GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM',
843      'GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM',
844    ],
845  },
846  'RenderBufferParameter': {
847    'type': 'GLenum',
848    'valid': [
849      'GL_RENDERBUFFER_RED_SIZE',
850      'GL_RENDERBUFFER_GREEN_SIZE',
851      'GL_RENDERBUFFER_BLUE_SIZE',
852      'GL_RENDERBUFFER_ALPHA_SIZE',
853      'GL_RENDERBUFFER_DEPTH_SIZE',
854      'GL_RENDERBUFFER_STENCIL_SIZE',
855      'GL_RENDERBUFFER_WIDTH',
856      'GL_RENDERBUFFER_HEIGHT',
857      'GL_RENDERBUFFER_INTERNAL_FORMAT',
858    ],
859  },
860  'ShaderParameter': {
861    'type': 'GLenum',
862    'valid': [
863      'GL_SHADER_TYPE',
864      'GL_DELETE_STATUS',
865      'GL_COMPILE_STATUS',
866      'GL_INFO_LOG_LENGTH',
867      'GL_SHADER_SOURCE_LENGTH',
868      'GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE',
869    ],
870  },
871  'ShaderPrecision': {
872    'type': 'GLenum',
873    'valid': [
874      'GL_LOW_FLOAT',
875      'GL_MEDIUM_FLOAT',
876      'GL_HIGH_FLOAT',
877      'GL_LOW_INT',
878      'GL_MEDIUM_INT',
879      'GL_HIGH_INT',
880    ],
881  },
882  'StringType': {
883    'type': 'GLenum',
884    'valid': [
885      'GL_VENDOR',
886      'GL_RENDERER',
887      'GL_VERSION',
888      'GL_SHADING_LANGUAGE_VERSION',
889      'GL_EXTENSIONS',
890    ],
891  },
892  'TextureParameter': {
893    'type': 'GLenum',
894    'valid': [
895      'GL_TEXTURE_MAG_FILTER',
896      'GL_TEXTURE_MIN_FILTER',
897      'GL_TEXTURE_POOL_CHROMIUM',
898      'GL_TEXTURE_WRAP_S',
899      'GL_TEXTURE_WRAP_T',
900    ],
901    'invalid': [
902      'GL_GENERATE_MIPMAP',
903    ],
904  },
905  'TexturePool': {
906    'type': 'GLenum',
907    'valid': [
908      'GL_TEXTURE_POOL_MANAGED_CHROMIUM',
909      'GL_TEXTURE_POOL_UNMANAGED_CHROMIUM',
910    ],
911  },
912  'TextureWrapMode': {
913    'type': 'GLenum',
914    'valid': [
915      'GL_CLAMP_TO_EDGE',
916      'GL_MIRRORED_REPEAT',
917      'GL_REPEAT',
918    ],
919  },
920  'TextureMinFilterMode': {
921    'type': 'GLenum',
922    'valid': [
923      'GL_NEAREST',
924      'GL_LINEAR',
925      'GL_NEAREST_MIPMAP_NEAREST',
926      'GL_LINEAR_MIPMAP_NEAREST',
927      'GL_NEAREST_MIPMAP_LINEAR',
928      'GL_LINEAR_MIPMAP_LINEAR',
929    ],
930  },
931  'TextureMagFilterMode': {
932    'type': 'GLenum',
933    'valid': [
934      'GL_NEAREST',
935      'GL_LINEAR',
936    ],
937  },
938  'TextureUsage': {
939    'type': 'GLenum',
940    'valid': [
941      'GL_NONE',
942      'GL_FRAMEBUFFER_ATTACHMENT_ANGLE',
943    ],
944  },
945  'VertexAttribute': {
946    'type': 'GLenum',
947    'valid': [
948      # some enum that the decoder actually passes through to GL needs
949      # to be the first listed here since it's used in unit tests.
950      'GL_VERTEX_ATTRIB_ARRAY_NORMALIZED',
951      'GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING',
952      'GL_VERTEX_ATTRIB_ARRAY_ENABLED',
953      'GL_VERTEX_ATTRIB_ARRAY_SIZE',
954      'GL_VERTEX_ATTRIB_ARRAY_STRIDE',
955      'GL_VERTEX_ATTRIB_ARRAY_TYPE',
956      'GL_CURRENT_VERTEX_ATTRIB',
957    ],
958  },
959  'VertexPointer': {
960    'type': 'GLenum',
961    'valid': [
962      'GL_VERTEX_ATTRIB_ARRAY_POINTER',
963    ],
964  },
965  'HintTarget': {
966    'type': 'GLenum',
967    'valid': [
968      'GL_GENERATE_MIPMAP_HINT',
969    ],
970    'invalid': [
971      'GL_PERSPECTIVE_CORRECTION_HINT',
972    ],
973  },
974  'HintMode': {
975    'type': 'GLenum',
976    'valid': [
977      'GL_FASTEST',
978      'GL_NICEST',
979      'GL_DONT_CARE',
980    ],
981  },
982  'PixelStore': {
983    'type': 'GLenum',
984    'valid': [
985      'GL_PACK_ALIGNMENT',
986      'GL_UNPACK_ALIGNMENT',
987      'GL_UNPACK_FLIP_Y_CHROMIUM',
988      'GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM',
989      'GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM',
990    ],
991    'invalid': [
992      'GL_PACK_SWAP_BYTES',
993      'GL_UNPACK_SWAP_BYTES',
994    ],
995  },
996  'PixelStoreAlignment': {
997    'type': 'GLint',
998    'valid': [
999      '1',
1000      '2',
1001      '4',
1002      '8',
1003    ],
1004    'invalid': [
1005      '3',
1006      '9',
1007    ],
1008  },
1009  'ReadPixelFormat': {
1010    'type': 'GLenum',
1011    'valid': [
1012      'GL_ALPHA',
1013      'GL_RGB',
1014      'GL_RGBA',
1015    ],
1016  },
1017  'PixelType': {
1018    'type': 'GLenum',
1019    'valid': [
1020      'GL_UNSIGNED_BYTE',
1021      'GL_UNSIGNED_SHORT_5_6_5',
1022      'GL_UNSIGNED_SHORT_4_4_4_4',
1023      'GL_UNSIGNED_SHORT_5_5_5_1',
1024    ],
1025    'invalid': [
1026      'GL_SHORT',
1027      'GL_INT',
1028    ],
1029  },
1030  'ReadPixelType': {
1031    'type': 'GLenum',
1032    'valid': [
1033      'GL_UNSIGNED_BYTE',
1034      'GL_UNSIGNED_SHORT_5_6_5',
1035      'GL_UNSIGNED_SHORT_4_4_4_4',
1036      'GL_UNSIGNED_SHORT_5_5_5_1',
1037    ],
1038    'invalid': [
1039      'GL_SHORT',
1040      'GL_INT',
1041    ],
1042  },
1043  'RenderBufferFormat': {
1044    'type': 'GLenum',
1045    'valid': [
1046      'GL_RGBA4',
1047      'GL_RGB565',
1048      'GL_RGB5_A1',
1049      'GL_DEPTH_COMPONENT16',
1050      'GL_STENCIL_INDEX8',
1051    ],
1052  },
1053  'ShaderBinaryFormat': {
1054    'type': 'GLenum',
1055    'valid': [
1056    ],
1057  },
1058  'StencilOp': {
1059    'type': 'GLenum',
1060    'valid': [
1061      'GL_KEEP',
1062      'GL_ZERO',
1063      'GL_REPLACE',
1064      'GL_INCR',
1065      'GL_INCR_WRAP',
1066      'GL_DECR',
1067      'GL_DECR_WRAP',
1068      'GL_INVERT',
1069    ],
1070  },
1071  'TextureFormat': {
1072    'type': 'GLenum',
1073    'valid': [
1074      'GL_ALPHA',
1075      'GL_LUMINANCE',
1076      'GL_LUMINANCE_ALPHA',
1077      'GL_RGB',
1078      'GL_RGBA',
1079    ],
1080    'invalid': [
1081      'GL_BGRA',
1082      'GL_BGR',
1083    ],
1084  },
1085  'TextureInternalFormat': {
1086    'type': 'GLenum',
1087    'valid': [
1088      'GL_ALPHA',
1089      'GL_LUMINANCE',
1090      'GL_LUMINANCE_ALPHA',
1091      'GL_RGB',
1092      'GL_RGBA',
1093    ],
1094    'invalid': [
1095      'GL_BGRA',
1096      'GL_BGR',
1097    ],
1098  },
1099  'TextureInternalFormatStorage': {
1100    'type': 'GLenum',
1101    'valid': [
1102      'GL_RGB565',
1103      'GL_RGBA4',
1104      'GL_RGB5_A1',
1105      'GL_ALPHA8_EXT',
1106      'GL_LUMINANCE8_EXT',
1107      'GL_LUMINANCE8_ALPHA8_EXT',
1108      'GL_RGB8_OES',
1109      'GL_RGBA8_OES',
1110    ],
1111  },
1112  'VertexAttribType': {
1113    'type': 'GLenum',
1114    'valid': [
1115      'GL_BYTE',
1116      'GL_UNSIGNED_BYTE',
1117      'GL_SHORT',
1118      'GL_UNSIGNED_SHORT',
1119    #  'GL_FIXED',  // This is not available on Desktop GL.
1120      'GL_FLOAT',
1121    ],
1122    'invalid': [
1123      'GL_DOUBLE',
1124    ],
1125  },
1126  'TextureBorder': {
1127    'type': 'GLint',
1128    'valid': [
1129      '0',
1130    ],
1131    'invalid': [
1132      '1',
1133    ],
1134  },
1135  'VertexAttribSize': {
1136    'type': 'GLint',
1137    'valid': [
1138      '1',
1139      '2',
1140      '3',
1141      '4',
1142    ],
1143    'invalid': [
1144      '0',
1145      '5',
1146    ],
1147  },
1148  'ZeroOnly': {
1149    'type': 'GLint',
1150    'valid': [
1151      '0',
1152    ],
1153    'invalid': [
1154      '1',
1155    ],
1156  },
1157  'FalseOnly': {
1158    'type': 'GLboolean',
1159    'valid': [
1160      'false',
1161    ],
1162    'invalid': [
1163      'true',
1164    ],
1165  },
1166  'ResetStatus': {
1167    'type': 'GLenum',
1168    'valid': [
1169      'GL_GUILTY_CONTEXT_RESET_ARB',
1170      'GL_INNOCENT_CONTEXT_RESET_ARB',
1171      'GL_UNKNOWN_CONTEXT_RESET_ARB',
1172    ],
1173  },
1174}
1175
1176# This table specifies the different pepper interfaces that are supported for
1177# GL commands. 'dev' is true if it's a dev interface.
1178_PEPPER_INTERFACES = [
1179  {'name': '', 'dev': False},
1180  {'name': 'InstancedArrays', 'dev': False},
1181  {'name': 'FramebufferBlit', 'dev': False},
1182  {'name': 'FramebufferMultisample', 'dev': False},
1183  {'name': 'ChromiumEnableFeature', 'dev': False},
1184  {'name': 'ChromiumMapSub', 'dev': False},
1185  {'name': 'Query', 'dev': False},
1186  {'name': 'DrawBuffers', 'dev': True},
1187]
1188
1189# This table specifies types and other special data for the commands that
1190# will be generated.
1191#
1192# Must match function names specified in "cmd_buffer_functions.txt".
1193#
1194# cmd_comment:  A comment added to the cmd format.
1195# type:         defines which handler will be used to generate code.
1196# decoder_func: defines which function to call in the decoder to execute the
1197#               corresponding GL command. If not specified the GL command will
1198#               be called directly.
1199# gl_test_func: GL function that is expected to be called when testing.
1200# cmd_args:     The arguments to use for the command. This overrides generating
1201#               them based on the GL function arguments.
1202#               a NonImmediate type is a type that stays a pointer even in
1203#               and immediate version of acommand.
1204# gen_cmd:      Whether or not this function geneates a command. Default = True.
1205# immediate:    Whether or not to generate an immediate command for the GL
1206#               function. The default is if there is exactly 1 pointer argument
1207#               in the GL function an immediate command is generated.
1208# bucket:       True to generate a bucket version of the command.
1209# impl_func:    Whether or not to generate the GLES2Implementation part of this
1210#               command.
1211# impl_decl:    Whether or not to generate the GLES2Implementation declaration
1212#               for this command.
1213# needs_size:   If true a data_size field is added to the command.
1214# data_type:    The type of data the command uses. For PUTn or PUT types.
1215# count:        The number of units per element. For PUTn or PUT types.
1216# unit_test:    If False no service side unit test will be generated.
1217# client_test:  If False no client side unit test will be generated.
1218# expectation:  If False the unit test will have no expected calls.
1219# gen_func:     Name of function that generates GL resource for corresponding
1220#               bind function.
1221# states:       array of states that get set by this function corresponding to
1222#               the given arguments
1223# state_flag:   name of flag that is set to true when function is called.
1224# no_gl:        no GL function is called.
1225# valid_args:   A dictionary of argument indices to args to use in unit tests
1226#               when they can not be automatically determined.
1227# pepper_interface: The pepper interface that is used for this extension
1228# pepper_name:  The name of the function as exposed to pepper.
1229# pepper_args:  A string representing the argument list (what would appear in
1230#               C/C++ between the parentheses for the function declaration)
1231#               that the Pepper API expects for this function. Use this only if
1232#               the stable Pepper API differs from the GLES2 argument list.
1233# invalid_test: False if no invalid test needed.
1234# shadowed:     True = the value is shadowed so no glGetXXX call will be made.
1235# first_element_only: For PUT types, True if only the first element of an
1236#               array is used and we end up calling the single value
1237#               corresponding function. eg. TexParameteriv -> TexParameteri
1238
1239_FUNCTION_INFO = {
1240  'ActiveTexture': {
1241    'decoder_func': 'DoActiveTexture',
1242    'unit_test': False,
1243    'impl_func': False,
1244    'client_test': False,
1245  },
1246  'AttachShader': {'decoder_func': 'DoAttachShader'},
1247  'BindAttribLocation': {
1248    'type': 'GLchar',
1249    'bucket': True,
1250    'needs_size': True,
1251    'immediate': False,
1252  },
1253  'BindBuffer': {
1254    'type': 'Bind',
1255    'decoder_func': 'DoBindBuffer',
1256    'gen_func': 'GenBuffersARB',
1257  },
1258  'BindFramebuffer': {
1259    'type': 'Bind',
1260    'decoder_func': 'DoBindFramebuffer',
1261    'gl_test_func': 'glBindFramebufferEXT',
1262    'gen_func': 'GenFramebuffersEXT',
1263    'trace_level': 1,
1264  },
1265  'BindRenderbuffer': {
1266    'type': 'Bind',
1267    'decoder_func': 'DoBindRenderbuffer',
1268    'gl_test_func': 'glBindRenderbufferEXT',
1269    'gen_func': 'GenRenderbuffersEXT',
1270  },
1271  'BindTexture': {
1272    'type': 'Bind',
1273    'decoder_func': 'DoBindTexture',
1274    'gen_func': 'GenTextures',
1275    # TODO(gman): remove this once client side caching works.
1276    'client_test': False,
1277    'trace_level': 1,
1278  },
1279  'BlitFramebufferCHROMIUM': {
1280    'decoder_func': 'DoBlitFramebufferCHROMIUM',
1281    'unit_test': False,
1282    'extension': True,
1283    'pepper_interface': 'FramebufferBlit',
1284    'pepper_name': 'BlitFramebufferEXT',
1285    'defer_reads': True,
1286    'defer_draws': True,
1287    'trace_level': 1,
1288  },
1289  'BufferData': {
1290    'type': 'Manual',
1291    'immediate': False,
1292    'client_test': False,
1293  },
1294  'BufferSubData': {
1295    'type': 'Data',
1296    'client_test': False,
1297    'decoder_func': 'DoBufferSubData',
1298    'immediate': False,
1299  },
1300  'CheckFramebufferStatus': {
1301    'type': 'Is',
1302    'decoder_func': 'DoCheckFramebufferStatus',
1303    'gl_test_func': 'glCheckFramebufferStatusEXT',
1304    'error_value': 'GL_FRAMEBUFFER_UNSUPPORTED',
1305    'result': ['GLenum'],
1306  },
1307  'Clear': {
1308    'decoder_func': 'DoClear',
1309    'defer_draws': True,
1310    'trace_level': 1,
1311  },
1312  'ClearColor': {
1313    'type': 'StateSet',
1314    'state': 'ClearColor',
1315  },
1316  'ClearDepthf': {
1317    'type': 'StateSet',
1318    'state': 'ClearDepthf',
1319    'decoder_func': 'glClearDepth',
1320    'gl_test_func': 'glClearDepth',
1321    'valid_args': {
1322      '0': '0.5f'
1323    },
1324  },
1325  'ColorMask': {
1326    'type': 'StateSet',
1327    'state': 'ColorMask',
1328    'no_gl': True,
1329    'expectation': False,
1330  },
1331  'ConsumeTextureCHROMIUM': {
1332    'decoder_func': 'DoConsumeTextureCHROMIUM',
1333    'impl_func': False,
1334    'type': 'PUT',
1335    'data_type': 'GLbyte',
1336    'count': 64,  # GL_MAILBOX_SIZE_CHROMIUM
1337    'unit_test': False,
1338    'client_test': False,
1339    'extension': True,
1340    'chromium': True,
1341    'trace_level': 1,
1342  },
1343  'ClearStencil': {
1344    'type': 'StateSet',
1345    'state': 'ClearStencil',
1346  },
1347  'EnableFeatureCHROMIUM': {
1348    'type': 'Custom',
1349    'immediate': False,
1350    'decoder_func': 'DoEnableFeatureCHROMIUM',
1351    'expectation': False,
1352    'cmd_args': 'GLuint bucket_id, GLint* result',
1353    'result': ['GLint'],
1354    'extension': True,
1355    'chromium': True,
1356    'pepper_interface': 'ChromiumEnableFeature',
1357  },
1358  'CompileShader': {'decoder_func': 'DoCompileShader', 'unit_test': False},
1359  'CompressedTexImage2D': {
1360    'type': 'Manual',
1361    'immediate': False,
1362    'bucket': True,
1363  },
1364  'CompressedTexSubImage2D': {
1365    'type': 'Data',
1366    'bucket': True,
1367    'decoder_func': 'DoCompressedTexSubImage2D',
1368    'immediate': False,
1369  },
1370  'CopyTexImage2D': {
1371    'decoder_func': 'DoCopyTexImage2D',
1372    'unit_test': False,
1373    'defer_reads': True,
1374  },
1375  'CopyTexSubImage2D': {
1376    'decoder_func': 'DoCopyTexSubImage2D',
1377    'defer_reads': True,
1378  },
1379  'CreateImageCHROMIUM': {
1380    'type': 'Manual',
1381    'cmd_args': 'GLsizei width, GLsizei height, GLenum internalformat',
1382    'result': ['GLuint'],
1383    'client_test': False,
1384    'gen_cmd': False,
1385    'expectation': False,
1386    'extension': True,
1387    'chromium': True,
1388  },
1389  'DestroyImageCHROMIUM': {
1390    'type': 'Manual',
1391    'immediate': False,
1392    'client_test': False,
1393    'gen_cmd': False,
1394    'extension': True,
1395    'chromium': True,
1396  },
1397  'GetImageParameterivCHROMIUM': {
1398    'type': 'Manual',
1399    'client_test': False,
1400    'gen_cmd': False,
1401    'expectation': False,
1402    'extension': True,
1403    'chromium': True,
1404  },
1405  'CreateProgram': {
1406    'type': 'Create',
1407    'client_test': False,
1408  },
1409  'CreateShader': {
1410    'type': 'Create',
1411    'client_test': False,
1412  },
1413  'BlendColor': {
1414    'type': 'StateSet',
1415    'state': 'BlendColor',
1416  },
1417  'BlendEquation': {
1418    'type': 'StateSetRGBAlpha',
1419    'state': 'BlendEquation',
1420    'valid_args': {
1421      '0': 'GL_FUNC_SUBTRACT'
1422    },
1423  },
1424  'BlendEquationSeparate': {
1425    'type': 'StateSet',
1426    'state': 'BlendEquation',
1427    'valid_args': {
1428      '0': 'GL_FUNC_SUBTRACT'
1429    },
1430  },
1431  'BlendFunc': {
1432    'type': 'StateSetRGBAlpha',
1433    'state': 'BlendFunc',
1434  },
1435  'BlendFuncSeparate': {
1436    'type': 'StateSet',
1437    'state': 'BlendFunc',
1438  },
1439  'SampleCoverage': {'decoder_func': 'DoSampleCoverage'},
1440  'StencilFunc': {
1441    'type': 'StateSetFrontBack',
1442    'state': 'StencilFunc',
1443  },
1444  'StencilFuncSeparate': {
1445    'type': 'StateSetFrontBackSeparate',
1446    'state': 'StencilFunc',
1447  },
1448  'StencilOp': {
1449    'type': 'StateSetFrontBack',
1450    'state': 'StencilOp',
1451    'valid_args': {
1452      '1': 'GL_INCR'
1453    },
1454  },
1455  'StencilOpSeparate': {
1456    'type': 'StateSetFrontBackSeparate',
1457    'state': 'StencilOp',
1458    'valid_args': {
1459      '1': 'GL_INCR'
1460    },
1461  },
1462  'Hint': {
1463    'type': 'StateSetNamedParameter',
1464    'state': 'Hint',
1465  },
1466  'CullFace': {'type': 'StateSet', 'state': 'CullFace'},
1467  'FrontFace': {'type': 'StateSet', 'state': 'FrontFace'},
1468  'DepthFunc': {'type': 'StateSet', 'state': 'DepthFunc'},
1469  'LineWidth': {
1470    'type': 'StateSet',
1471    'state': 'LineWidth',
1472    'valid_args': {
1473      '0': '0.5f'
1474    },
1475  },
1476  'PolygonOffset': {
1477    'type': 'StateSet',
1478    'state': 'PolygonOffset',
1479  },
1480  'DeleteBuffers': {
1481    'type': 'DELn',
1482    'gl_test_func': 'glDeleteBuffersARB',
1483    'resource_type': 'Buffer',
1484    'resource_types': 'Buffers',
1485  },
1486  'DeleteFramebuffers': {
1487    'type': 'DELn',
1488    'gl_test_func': 'glDeleteFramebuffersEXT',
1489    'resource_type': 'Framebuffer',
1490    'resource_types': 'Framebuffers',
1491  },
1492  'DeleteProgram': {'type': 'Delete', 'decoder_func': 'DoDeleteProgram'},
1493  'DeleteRenderbuffers': {
1494    'type': 'DELn',
1495    'gl_test_func': 'glDeleteRenderbuffersEXT',
1496    'resource_type': 'Renderbuffer',
1497    'resource_types': 'Renderbuffers',
1498  },
1499  'DeleteShader': {'type': 'Delete', 'decoder_func': 'DoDeleteShader'},
1500  'DeleteSharedIdsCHROMIUM': {
1501    'type': 'Custom',
1502    'decoder_func': 'DoDeleteSharedIdsCHROMIUM',
1503    'impl_func': False,
1504    'expectation': False,
1505    'immediate': False,
1506    'extension': True,
1507    'chromium': True,
1508  },
1509  'DeleteTextures': {
1510    'type': 'DELn',
1511    'resource_type': 'Texture',
1512    'resource_types': 'Textures',
1513  },
1514  'DepthRangef': {
1515    'decoder_func': 'DoDepthRangef',
1516    'gl_test_func': 'glDepthRange',
1517  },
1518  'DepthMask': {
1519    'type': 'StateSet',
1520    'state': 'DepthMask',
1521    'no_gl': True,
1522    'expectation': False,
1523  },
1524  'DetachShader': {'decoder_func': 'DoDetachShader'},
1525  'Disable': {
1526    'decoder_func': 'DoDisable',
1527    'impl_func': False,
1528    'client_test': False,
1529  },
1530  'DisableVertexAttribArray': {
1531    'decoder_func': 'DoDisableVertexAttribArray',
1532    'impl_decl': False,
1533  },
1534  'DrawArrays': {
1535    'type': 'Manual',
1536    'cmd_args': 'GLenumDrawMode mode, GLint first, GLsizei count',
1537    'defer_draws': True,
1538    'trace_level': 2,
1539  },
1540  'DrawElements': {
1541    'type': 'Manual',
1542    'cmd_args': 'GLenumDrawMode mode, GLsizei count, '
1543                'GLenumIndexType type, GLuint index_offset',
1544    'client_test': False,
1545    'defer_draws': True,
1546    'trace_level': 2,
1547  },
1548  'Enable': {
1549    'decoder_func': 'DoEnable',
1550    'impl_func': False,
1551    'client_test': False,
1552  },
1553  'EnableVertexAttribArray': {
1554    'decoder_func': 'DoEnableVertexAttribArray',
1555    'impl_decl': False,
1556  },
1557  'Finish': {
1558    'impl_func': False,
1559    'client_test': False,
1560    'decoder_func': 'DoFinish',
1561    'defer_reads': True,
1562  },
1563  'Flush': {
1564    'impl_func': False,
1565    'decoder_func': 'DoFlush',
1566  },
1567  'FramebufferRenderbuffer': {
1568    'decoder_func': 'DoFramebufferRenderbuffer',
1569    'gl_test_func': 'glFramebufferRenderbufferEXT',
1570  },
1571  'FramebufferTexture2D': {
1572    'decoder_func': 'DoFramebufferTexture2D',
1573    'gl_test_func': 'glFramebufferTexture2DEXT',
1574    'trace_level': 1,
1575  },
1576  'FramebufferTexture2DMultisampleEXT': {
1577    'decoder_func': 'DoFramebufferTexture2DMultisample',
1578    'gl_test_func': 'glFramebufferTexture2DMultisampleEXT',
1579    'expectation': False,
1580    'unit_test': False,
1581    'extension': True,
1582    'trace_level': 1,
1583  },
1584  'GenerateMipmap': {
1585    'decoder_func': 'DoGenerateMipmap',
1586    'gl_test_func': 'glGenerateMipmapEXT',
1587  },
1588  'GenBuffers': {
1589    'type': 'GENn',
1590    'gl_test_func': 'glGenBuffersARB',
1591    'resource_type': 'Buffer',
1592    'resource_types': 'Buffers',
1593  },
1594  'GenMailboxCHROMIUM': {
1595    'type': 'HandWritten',
1596    'immediate': False,
1597    'impl_func': False,
1598    'extension': True,
1599    'chromium': True,
1600  },
1601  'GenFramebuffers': {
1602    'type': 'GENn',
1603    'gl_test_func': 'glGenFramebuffersEXT',
1604    'resource_type': 'Framebuffer',
1605    'resource_types': 'Framebuffers',
1606  },
1607  'GenRenderbuffers': {
1608    'type': 'GENn', 'gl_test_func': 'glGenRenderbuffersEXT',
1609    'resource_type': 'Renderbuffer',
1610    'resource_types': 'Renderbuffers',
1611  },
1612  'GenTextures': {
1613    'type': 'GENn',
1614    'gl_test_func': 'glGenTextures',
1615    'resource_type': 'Texture',
1616    'resource_types': 'Textures',
1617  },
1618  'GenSharedIdsCHROMIUM': {
1619    'type': 'Custom',
1620    'decoder_func': 'DoGenSharedIdsCHROMIUM',
1621    'impl_func': False,
1622    'expectation': False,
1623    'immediate': False,
1624    'extension': True,
1625    'chromium': True,
1626  },
1627  'GetActiveAttrib': {
1628    'type': 'Custom',
1629    'immediate': False,
1630    'cmd_args':
1631        'GLidProgram program, GLuint index, uint32 name_bucket_id, '
1632        'void* result',
1633    'result': [
1634      'int32 success',
1635      'int32 size',
1636      'uint32 type',
1637    ],
1638  },
1639  'GetActiveUniform': {
1640    'type': 'Custom',
1641    'immediate': False,
1642    'cmd_args':
1643        'GLidProgram program, GLuint index, uint32 name_bucket_id, '
1644        'void* result',
1645    'result': [
1646      'int32 success',
1647      'int32 size',
1648      'uint32 type',
1649    ],
1650  },
1651  'GetAttachedShaders': {
1652    'type': 'Custom',
1653    'immediate': False,
1654    'cmd_args': 'GLidProgram program, void* result, uint32 result_size',
1655    'result': ['SizedResult<GLuint>'],
1656  },
1657  'GetAttribLocation': {
1658    'type': 'HandWritten',
1659    'immediate': False,
1660    'bucket': True,
1661    'needs_size': True,
1662    'cmd_args':
1663        'GLidProgram program, const char* name, NonImmediate GLint* location',
1664    'result': ['GLint'],
1665    'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
1666  },
1667  'GetBooleanv': {
1668    'type': 'GETn',
1669    'result': ['SizedResult<GLboolean>'],
1670    'decoder_func': 'DoGetBooleanv',
1671    'gl_test_func': 'glGetBooleanv',
1672  },
1673  'GetBufferParameteriv': {
1674    'type': 'GETn',
1675    'result': ['SizedResult<GLint>'],
1676    'decoder_func': 'DoGetBufferParameteriv',
1677    'expectation': False,
1678    'shadowed': True,
1679  },
1680  'GetError': {
1681    'type': 'Is',
1682    'decoder_func': 'GetErrorState()->GetGLError',
1683    'impl_func': False,
1684    'result': ['GLenum'],
1685    'client_test': False,
1686  },
1687  'GetFloatv': {
1688    'type': 'GETn',
1689    'result': ['SizedResult<GLfloat>'],
1690    'decoder_func': 'DoGetFloatv',
1691    'gl_test_func': 'glGetFloatv',
1692  },
1693  'GetFramebufferAttachmentParameteriv': {
1694    'type': 'GETn',
1695    'decoder_func': 'DoGetFramebufferAttachmentParameteriv',
1696    'gl_test_func': 'glGetFramebufferAttachmentParameterivEXT',
1697    'result': ['SizedResult<GLint>'],
1698  },
1699  'GetIntegerv': {
1700    'type': 'GETn',
1701    'result': ['SizedResult<GLint>'],
1702    'decoder_func': 'DoGetIntegerv',
1703    'client_test': False,
1704  },
1705  'GetMaxValueInBufferCHROMIUM': {
1706    'type': 'Is',
1707    'decoder_func': 'DoGetMaxValueInBufferCHROMIUM',
1708    'result': ['GLuint'],
1709    'unit_test': False,
1710    'client_test': False,
1711    'extension': True,
1712    'chromium': True,
1713    'impl_func': False,
1714  },
1715  'GetMultipleIntegervCHROMIUM': {
1716    'type': 'Custom',
1717    'immediate': False,
1718    'expectation': False,
1719    'extension': True,
1720    'chromium': True,
1721    'client_test': False,
1722  },
1723  'GetProgramiv': {
1724    'type': 'GETn',
1725    'decoder_func': 'DoGetProgramiv',
1726    'result': ['SizedResult<GLint>'],
1727    'expectation': False,
1728  },
1729  'GetProgramInfoCHROMIUM': {
1730    'type': 'Custom',
1731    'immediate': False,
1732    'expectation': False,
1733    'impl_func': False,
1734    'extension': True,
1735    'chromium': True,
1736    'client_test': False,
1737    'cmd_args': 'GLidProgram program, uint32 bucket_id',
1738    'result': [
1739      'uint32 link_status',
1740      'uint32 num_attribs',
1741      'uint32 num_uniforms',
1742    ],
1743  },
1744  'GetProgramInfoLog': {
1745    'type': 'STRn',
1746    'expectation': False,
1747  },
1748  'GetRenderbufferParameteriv': {
1749    'type': 'GETn',
1750    'decoder_func': 'DoGetRenderbufferParameteriv',
1751    'gl_test_func': 'glGetRenderbufferParameterivEXT',
1752    'result': ['SizedResult<GLint>'],
1753  },
1754  'GetShaderiv': {
1755    'type': 'GETn',
1756    'decoder_func': 'DoGetShaderiv',
1757    'result': ['SizedResult<GLint>'],
1758  },
1759  'GetShaderInfoLog': {
1760    'type': 'STRn',
1761    'get_len_func': 'glGetShaderiv',
1762    'get_len_enum': 'GL_INFO_LOG_LENGTH',
1763    'unit_test': False,
1764  },
1765  'GetShaderPrecisionFormat': {
1766    'type': 'Custom',
1767    'immediate': False,
1768    'cmd_args':
1769      'GLenumShaderType shadertype, GLenumShaderPrecision precisiontype, '
1770      'void* result',
1771    'result': [
1772      'int32 success',
1773      'int32 min_range',
1774      'int32 max_range',
1775      'int32 precision',
1776    ],
1777  },
1778  'GetShaderSource': {
1779    'type': 'STRn',
1780    'get_len_func': 'DoGetShaderiv',
1781    'get_len_enum': 'GL_SHADER_SOURCE_LENGTH',
1782    'unit_test': False,
1783    'client_test': False,
1784    },
1785  'GetString': {
1786    'type': 'Custom',
1787    'client_test': False,
1788    'cmd_args': 'GLenumStringType name, uint32 bucket_id',
1789  },
1790  'GetTexParameterfv': {
1791    'type': 'GETn',
1792    'decoder_func': 'DoGetTexParameterfv',
1793    'result': ['SizedResult<GLfloat>']
1794  },
1795  'GetTexParameteriv': {
1796    'type': 'GETn',
1797    'decoder_func': 'DoGetTexParameteriv',
1798    'result': ['SizedResult<GLint>']
1799  },
1800  'GetTranslatedShaderSourceANGLE': {
1801    'type': 'STRn',
1802    'get_len_func': 'DoGetShaderiv',
1803    'get_len_enum': 'GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE',
1804    'unit_test': False,
1805    'extension': True,
1806    },
1807  'GetUniformfv': {
1808    'type': 'Custom',
1809    'immediate': False,
1810    'result': ['SizedResult<GLfloat>'],
1811  },
1812  'GetUniformiv': {
1813    'type': 'Custom',
1814    'immediate': False,
1815    'result': ['SizedResult<GLint>'],
1816  },
1817  'GetUniformLocation': {
1818    'type': 'HandWritten',
1819    'immediate': False,
1820    'bucket': True,
1821    'needs_size': True,
1822    'cmd_args':
1823        'GLidProgram program, const char* name, NonImmediate GLint* location',
1824    'result': ['GLint'],
1825    'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml
1826  },
1827  'GetVertexAttribfv': {
1828    'type': 'GETn',
1829    'result': ['SizedResult<GLfloat>'],
1830    'impl_decl': False,
1831    'decoder_func': 'DoGetVertexAttribfv',
1832    'expectation': False,
1833    'client_test': False,
1834  },
1835  'GetVertexAttribiv': {
1836    'type': 'GETn',
1837    'result': ['SizedResult<GLint>'],
1838    'impl_decl': False,
1839    'decoder_func': 'DoGetVertexAttribiv',
1840    'expectation': False,
1841    'client_test': False,
1842  },
1843  'GetVertexAttribPointerv': {
1844    'type': 'Custom',
1845    'immediate': False,
1846    'result': ['SizedResult<GLuint>'],
1847    'client_test': False,
1848  },
1849  'IsBuffer': {
1850    'type': 'Is',
1851    'decoder_func': 'DoIsBuffer',
1852    'expectation': False,
1853  },
1854  'IsEnabled': {
1855    'type': 'Is',
1856    'decoder_func': 'DoIsEnabled',
1857    'impl_func': False,
1858    'expectation': False,
1859  },
1860  'IsFramebuffer': {
1861    'type': 'Is',
1862    'decoder_func': 'DoIsFramebuffer',
1863    'expectation': False,
1864  },
1865  'IsProgram': {
1866    'type': 'Is',
1867    'decoder_func': 'DoIsProgram',
1868    'expectation': False,
1869  },
1870  'IsRenderbuffer': {
1871    'type': 'Is',
1872    'decoder_func': 'DoIsRenderbuffer',
1873    'expectation': False,
1874  },
1875  'IsShader': {
1876    'type': 'Is',
1877    'decoder_func': 'DoIsShader',
1878    'expectation': False,
1879  },
1880  'IsTexture': {
1881    'type': 'Is',
1882    'decoder_func': 'DoIsTexture',
1883    'expectation': False,
1884  },
1885  'LinkProgram': {
1886    'decoder_func': 'DoLinkProgram',
1887    'impl_func':  False,
1888  },
1889  'MapBufferCHROMIUM': {
1890    'gen_cmd': False,
1891    'extension': True,
1892    'chromium': True,
1893    'client_test': False,
1894  },
1895  'MapBufferSubDataCHROMIUM': {
1896    'gen_cmd': False,
1897    'extension': True,
1898    'chromium': True,
1899    'client_test': False,
1900    'pepper_interface': 'ChromiumMapSub',
1901  },
1902  'MapImageCHROMIUM': {
1903    'gen_cmd': False,
1904    'extension': True,
1905    'chromium': True,
1906    'client_test': False,
1907  },
1908  'MapTexSubImage2DCHROMIUM': {
1909    'gen_cmd': False,
1910    'extension': True,
1911    'chromium': True,
1912    'client_test': False,
1913    'pepper_interface': 'ChromiumMapSub',
1914  },
1915  'PixelStorei': {'type': 'Manual'},
1916  'PostSubBufferCHROMIUM': {
1917      'type': 'Custom',
1918      'impl_func': False,
1919      'unit_test': False,
1920      'client_test': False,
1921      'extension': True,
1922      'chromium': True,
1923  },
1924  'ProduceTextureCHROMIUM': {
1925    'decoder_func': 'DoProduceTextureCHROMIUM',
1926    'impl_func': False,
1927    'type': 'PUT',
1928    'data_type': 'GLbyte',
1929    'count': 64,  # GL_MAILBOX_SIZE_CHROMIUM
1930    'unit_test': False,
1931    'client_test': False,
1932    'extension': True,
1933    'chromium': True,
1934    'trace_level': 1,
1935  },
1936  'RenderbufferStorage': {
1937    'decoder_func': 'DoRenderbufferStorage',
1938    'gl_test_func': 'glRenderbufferStorageEXT',
1939    'expectation': False,
1940  },
1941  'RenderbufferStorageMultisampleCHROMIUM': {
1942    'cmd_comment':
1943        '// GL_CHROMIUM_framebuffer_multisample\n',
1944    'decoder_func': 'DoRenderbufferStorageMultisampleCHROMIUM',
1945    'gl_test_func': 'glRenderbufferStorageMultisampleCHROMIUM',
1946    'expectation': False,
1947    'unit_test': False,
1948    'extension': True,
1949    'pepper_interface': 'FramebufferMultisample',
1950    'pepper_name': 'RenderbufferStorageMultisampleEXT',
1951  },
1952  'RenderbufferStorageMultisampleEXT': {
1953    'cmd_comment':
1954        '// GL_EXT_multisampled_render_to_texture\n',
1955    'decoder_func': 'DoRenderbufferStorageMultisampleEXT',
1956    'gl_test_func': 'glRenderbufferStorageMultisampleEXT',
1957    'expectation': False,
1958    'unit_test': False,
1959    'extension': True,
1960  },
1961  'ReadPixels': {
1962    'cmd_comment':
1963        '// ReadPixels has the result separated from the pixel buffer so that\n'
1964        '// it is easier to specify the result going to some specific place\n'
1965        '// that exactly fits the rectangle of pixels.\n',
1966    'type': 'Custom',
1967    'immediate': False,
1968    'impl_func': False,
1969    'client_test': False,
1970    'cmd_args':
1971        'GLint x, GLint y, GLsizei width, GLsizei height, '
1972        'GLenumReadPixelFormat format, GLenumReadPixelType type, '
1973        'uint32 pixels_shm_id, uint32 pixels_shm_offset, '
1974        'uint32 result_shm_id, uint32 result_shm_offset, '
1975        'GLboolean async',
1976    'result': ['uint32'],
1977    'defer_reads': True,
1978  },
1979  'RegisterSharedIdsCHROMIUM': {
1980    'type': 'Custom',
1981    'decoder_func': 'DoRegisterSharedIdsCHROMIUM',
1982    'impl_func': False,
1983    'expectation': False,
1984    'immediate': False,
1985    'extension': True,
1986    'chromium': True,
1987  },
1988  'ReleaseShaderCompiler': {
1989    'decoder_func': 'DoReleaseShaderCompiler',
1990    'unit_test': False,
1991  },
1992  'ShaderBinary': {
1993    'type': 'Custom',
1994    'client_test': False,
1995  },
1996  'ShaderSource': {
1997    'type': 'Manual',
1998    'immediate': False,
1999    'bucket': True,
2000    'needs_size': True,
2001    'client_test': False,
2002    'cmd_args':
2003        'GLuint shader, const char* data',
2004    'pepper_args':
2005        'GLuint shader, GLsizei count, const char** str, const GLint* length',
2006  },
2007  'StencilMask': {
2008    'type': 'StateSetFrontBack',
2009    'state': 'StencilMask',
2010    'no_gl': True,
2011    'expectation': False,
2012  },
2013  'StencilMaskSeparate': {
2014    'type': 'StateSetFrontBackSeparate',
2015    'state': 'StencilMask',
2016    'no_gl': True,
2017    'expectation': False,
2018  },
2019  'SwapBuffers': {
2020    'impl_func': False,
2021    'decoder_func': 'DoSwapBuffers',
2022    'unit_test': False,
2023    'client_test': False,
2024    'extension': True,
2025    'trace_level': 1,
2026  },
2027  'TexImage2D': {
2028    'type': 'Manual',
2029    'immediate': False,
2030    'client_test': False,
2031  },
2032  'TexParameterf': {
2033    'decoder_func': 'DoTexParameterf',
2034    'valid_args': {
2035      '2': 'GL_NEAREST'
2036    },
2037  },
2038  'TexParameteri': {
2039    'decoder_func': 'DoTexParameteri',
2040    'valid_args': {
2041      '2': 'GL_NEAREST'
2042    },
2043  },
2044  'TexParameterfv': {
2045    'type': 'PUT',
2046    'data_type': 'GLfloat',
2047    'data_value': 'GL_NEAREST',
2048    'count': 1,
2049    'decoder_func': 'DoTexParameterfv',
2050    'gl_test_func': 'glTexParameterf',
2051    'first_element_only': True,
2052  },
2053  'TexParameteriv': {
2054    'type': 'PUT',
2055    'data_type': 'GLint',
2056    'data_value': 'GL_NEAREST',
2057    'count': 1,
2058    'decoder_func': 'DoTexParameteriv',
2059    'gl_test_func': 'glTexParameteri',
2060    'first_element_only': True,
2061  },
2062  'TexSubImage2D': {
2063    'type': 'Manual',
2064    'immediate': False,
2065    'client_test': False,
2066    'cmd_args': 'GLenumTextureTarget target, GLint level, '
2067                'GLint xoffset, GLint yoffset, '
2068                'GLsizei width, GLsizei height, '
2069                'GLenumTextureFormat format, GLenumPixelType type, '
2070                'const void* pixels, GLboolean internal'
2071  },
2072  'Uniform1f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 1},
2073  'Uniform1fv': {
2074    'type': 'PUTn',
2075    'data_type': 'GLfloat',
2076    'count': 1,
2077    'decoder_func': 'DoUniform1fv',
2078  },
2079  'Uniform1i': {'decoder_func': 'DoUniform1i', 'unit_test': False},
2080  'Uniform1iv': {
2081    'type': 'PUTn',
2082    'data_type': 'GLint',
2083    'count': 1,
2084    'decoder_func': 'DoUniform1iv',
2085    'unit_test': False,
2086  },
2087  'Uniform2i': {'type': 'PUTXn', 'data_type': 'GLint', 'count': 2},
2088  'Uniform2f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 2},
2089  'Uniform2fv': {
2090    'type': 'PUTn',
2091    'data_type': 'GLfloat',
2092    'count': 2,
2093    'decoder_func': 'DoUniform2fv',
2094  },
2095  'Uniform2iv': {
2096    'type': 'PUTn',
2097    'data_type': 'GLint',
2098    'count': 2,
2099    'decoder_func': 'DoUniform2iv',
2100  },
2101  'Uniform3i': {'type': 'PUTXn', 'data_type': 'GLint', 'count': 3},
2102  'Uniform3f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 3},
2103  'Uniform3fv': {
2104    'type': 'PUTn',
2105    'data_type': 'GLfloat',
2106    'count': 3,
2107    'decoder_func': 'DoUniform3fv',
2108  },
2109  'Uniform3iv': {
2110    'type': 'PUTn',
2111    'data_type': 'GLint',
2112    'count': 3,
2113    'decoder_func': 'DoUniform3iv',
2114  },
2115  'Uniform4i': {'type': 'PUTXn', 'data_type': 'GLint', 'count': 4},
2116  'Uniform4f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 4},
2117  'Uniform4fv': {
2118    'type': 'PUTn',
2119    'data_type': 'GLfloat',
2120    'count': 4,
2121    'decoder_func': 'DoUniform4fv',
2122  },
2123  'Uniform4iv': {
2124    'type': 'PUTn',
2125    'data_type': 'GLint',
2126    'count': 4,
2127    'decoder_func': 'DoUniform4iv',
2128  },
2129  'UniformMatrix2fv': {
2130    'type': 'PUTn',
2131    'data_type': 'GLfloat',
2132    'count': 4,
2133    'decoder_func': 'DoUniformMatrix2fv',
2134  },
2135  'UniformMatrix3fv': {
2136    'type': 'PUTn',
2137    'data_type': 'GLfloat',
2138    'count': 9,
2139    'decoder_func': 'DoUniformMatrix3fv',
2140  },
2141  'UniformMatrix4fv': {
2142    'type': 'PUTn',
2143    'data_type': 'GLfloat',
2144    'count': 16,
2145    'decoder_func': 'DoUniformMatrix4fv',
2146  },
2147  'UnmapBufferCHROMIUM': {
2148    'gen_cmd': False,
2149    'extension': True,
2150    'chromium': True,
2151    'client_test': False,
2152  },
2153  'UnmapBufferSubDataCHROMIUM': {
2154    'gen_cmd': False,
2155    'extension': True,
2156    'chromium': True,
2157    'client_test': False,
2158    'pepper_interface': 'ChromiumMapSub',
2159  },
2160  'UnmapImageCHROMIUM': {
2161    'gen_cmd': False,
2162    'extension': True,
2163    'chromium': True,
2164    'client_test': False,
2165  },
2166  'UnmapTexSubImage2DCHROMIUM': {
2167    'gen_cmd': False,
2168    'extension': True,
2169    'chromium': True,
2170    'client_test': False,
2171    'pepper_interface': 'ChromiumMapSub',
2172  },
2173  'UseProgram': {
2174    'type': 'Bind',
2175    'decoder_func': 'DoUseProgram',
2176  },
2177  'ValidateProgram': {'decoder_func': 'DoValidateProgram'},
2178  'VertexAttrib1f': {'decoder_func': 'DoVertexAttrib1f'},
2179  'VertexAttrib1fv': {
2180    'type': 'PUT',
2181    'data_type': 'GLfloat',
2182    'count': 1,
2183    'decoder_func': 'DoVertexAttrib1fv',
2184  },
2185  'VertexAttrib2f': {'decoder_func': 'DoVertexAttrib2f'},
2186  'VertexAttrib2fv': {
2187    'type': 'PUT',
2188    'data_type': 'GLfloat',
2189    'count': 2,
2190    'decoder_func': 'DoVertexAttrib2fv',
2191  },
2192  'VertexAttrib3f': {'decoder_func': 'DoVertexAttrib3f'},
2193  'VertexAttrib3fv': {
2194    'type': 'PUT',
2195    'data_type': 'GLfloat',
2196    'count': 3,
2197    'decoder_func': 'DoVertexAttrib3fv',
2198  },
2199  'VertexAttrib4f': {'decoder_func': 'DoVertexAttrib4f'},
2200  'VertexAttrib4fv': {
2201    'type': 'PUT',
2202    'data_type': 'GLfloat',
2203    'count': 4,
2204    'decoder_func': 'DoVertexAttrib4fv',
2205  },
2206  'VertexAttribPointer': {
2207      'type': 'Manual',
2208      'cmd_args': 'GLuint indx, GLintVertexAttribSize size, '
2209                  'GLenumVertexAttribType type, GLboolean normalized, '
2210                  'GLsizei stride, GLuint offset',
2211      'client_test': False,
2212  },
2213  'Scissor': {
2214    'type': 'StateSet',
2215    'state': 'Scissor',
2216  },
2217  'Viewport': {
2218    'decoder_func': 'DoViewport',
2219  },
2220  'ResizeCHROMIUM': {
2221      'type': 'Custom',
2222      'impl_func': False,
2223      'unit_test': False,
2224      'extension': True,
2225      'chromium': True,
2226  },
2227  'GetRequestableExtensionsCHROMIUM': {
2228    'type': 'Custom',
2229    'impl_func': False,
2230    'immediate': False,
2231    'cmd_args': 'uint32 bucket_id',
2232    'extension': True,
2233    'chromium': True,
2234  },
2235  'RequestExtensionCHROMIUM': {
2236    'type': 'Custom',
2237    'impl_func': False,
2238    'immediate': False,
2239    'client_test': False,
2240    'cmd_args': 'uint32 bucket_id',
2241    'extension': True,
2242    'chromium': True,
2243  },
2244  'RateLimitOffscreenContextCHROMIUM': {
2245    'gen_cmd': False,
2246    'extension': True,
2247    'chromium': True,
2248    'client_test': False,
2249  },
2250  'CreateStreamTextureCHROMIUM':  {
2251    'type': 'HandWritten',
2252    'impl_func': False,
2253    'gen_cmd': False,
2254    'immediate': False,
2255    'extension': True,
2256    'chromium': True,
2257  },
2258  'TexImageIOSurface2DCHROMIUM': {
2259    'decoder_func': 'DoTexImageIOSurface2DCHROMIUM',
2260    'unit_test': False,
2261    'extension': True,
2262    'chromium': True,
2263  },
2264  'CopyTextureCHROMIUM': {
2265    'decoder_func': 'DoCopyTextureCHROMIUM',
2266    'unit_test': False,
2267    'extension': True,
2268    'chromium': True,
2269  },
2270  'TexStorage2DEXT': {
2271    'unit_test': False,
2272    'extension': True,
2273    'decoder_func': 'DoTexStorage2DEXT',
2274  },
2275  'DrawArraysInstancedANGLE': {
2276    'type': 'Manual',
2277    'cmd_args': 'GLenumDrawMode mode, GLint first, GLsizei count, '
2278                'GLsizei primcount',
2279    'extension': True,
2280    'unit_test': False,
2281    'pepper_interface': 'InstancedArrays',
2282    'defer_draws': True,
2283  },
2284  'DrawBuffersEXT': {
2285    'type': 'PUTn',
2286    'decoder_func': 'DoDrawBuffersEXT',
2287    'data_type': 'GLenum',
2288    'count': 1,
2289    'client_test': False,
2290    'unit_test': False,
2291    'extension': True,
2292    'pepper_interface': 'DrawBuffers',
2293  },
2294  'DrawElementsInstancedANGLE': {
2295    'type': 'Manual',
2296    'cmd_args': 'GLenumDrawMode mode, GLsizei count, '
2297                'GLenumIndexType type, GLuint index_offset, GLsizei primcount',
2298    'extension': True,
2299    'unit_test': False,
2300    'client_test': False,
2301    'pepper_interface': 'InstancedArrays',
2302    'defer_draws': True,
2303  },
2304  'VertexAttribDivisorANGLE': {
2305    'type': 'Manual',
2306    'cmd_args': 'GLuint index, GLuint divisor',
2307    'extension': True,
2308    'unit_test': False,
2309    'pepper_interface': 'InstancedArrays',
2310  },
2311  'GenQueriesEXT': {
2312    'type': 'GENn',
2313    'gl_test_func': 'glGenQueriesARB',
2314    'resource_type': 'Query',
2315    'resource_types': 'Queries',
2316    'unit_test': False,
2317    'pepper_interface': 'Query',
2318  },
2319  'DeleteQueriesEXT': {
2320    'type': 'DELn',
2321    'gl_test_func': 'glDeleteQueriesARB',
2322    'resource_type': 'Query',
2323    'resource_types': 'Queries',
2324    'unit_test': False,
2325    'pepper_interface': 'Query',
2326  },
2327  'IsQueryEXT': {
2328    'gen_cmd': False,
2329    'client_test': False,
2330    'pepper_interface': 'Query',
2331  },
2332  'BeginQueryEXT': {
2333    'type': 'Manual',
2334    'cmd_args': 'GLenumQueryTarget target, GLidQuery id, void* sync_data',
2335    'immediate': False,
2336    'gl_test_func': 'glBeginQuery',
2337    'pepper_interface': 'Query',
2338  },
2339  'EndQueryEXT': {
2340    'type': 'Manual',
2341    'cmd_args': 'GLenumQueryTarget target, GLuint submit_count',
2342    'gl_test_func': 'glEndnQuery',
2343    'client_test': False,
2344    'pepper_interface': 'Query',
2345  },
2346  'GetQueryivEXT': {
2347    'gen_cmd': False,
2348    'client_test': False,
2349    'gl_test_func': 'glGetQueryiv',
2350    'pepper_interface': 'Query',
2351  },
2352  'GetQueryObjectuivEXT': {
2353    'gen_cmd': False,
2354    'client_test': False,
2355    'gl_test_func': 'glGetQueryObjectuiv',
2356    'pepper_interface': 'Query',
2357  },
2358  'BindUniformLocationCHROMIUM': {
2359    'type': 'GLchar',
2360    'extension': True,
2361    'bucket': True,
2362    'needs_size': True,
2363    'gl_test_func': 'DoBindUniformLocationCHROMIUM',
2364    'immediate': False,
2365  },
2366  'InsertEventMarkerEXT': {
2367    'type': 'GLcharN',
2368    'decoder_func': 'DoInsertEventMarkerEXT',
2369    'expectation': False,
2370    'extension': True,
2371  },
2372  'PushGroupMarkerEXT': {
2373    'type': 'GLcharN',
2374    'decoder_func': 'DoPushGroupMarkerEXT',
2375    'expectation': False,
2376    'extension': True,
2377  },
2378  'PopGroupMarkerEXT': {
2379    'decoder_func': 'DoPopGroupMarkerEXT',
2380    'expectation': False,
2381    'extension': True,
2382    'impl_func': False,
2383  },
2384
2385  'GenVertexArraysOES': {
2386    'type': 'GENn',
2387    'extension': True,
2388    'gl_test_func': 'glGenVertexArraysOES',
2389    'resource_type': 'VertexArray',
2390    'resource_types': 'VertexArrays',
2391    'unit_test': False,
2392  },
2393  'BindVertexArrayOES': {
2394    'type': 'Bind',
2395    'extension': True,
2396    'gl_test_func': 'glBindVertexArrayOES',
2397    'decoder_func': 'DoBindVertexArrayOES',
2398    'gen_func': 'GenVertexArraysOES',
2399    'unit_test': False,
2400    'client_test': False,
2401  },
2402  'DeleteVertexArraysOES': {
2403    'type': 'DELn',
2404    'extension': True,
2405    'gl_test_func': 'glDeleteVertexArraysOES',
2406    'resource_type': 'VertexArray',
2407    'resource_types': 'VertexArrays',
2408    'unit_test': False,
2409  },
2410  'IsVertexArrayOES': {
2411    'type': 'Is',
2412    'extension': True,
2413    'gl_test_func': 'glIsVertexArrayOES',
2414    'decoder_func': 'DoIsVertexArrayOES',
2415    'expectation': False,
2416    'unit_test': False,
2417  },
2418  'BindTexImage2DCHROMIUM': {
2419    'decoder_func': 'DoBindTexImage2DCHROMIUM',
2420    'unit_test': False,
2421    'extension': True,
2422    'chromium': True,
2423  },
2424  'ReleaseTexImage2DCHROMIUM': {
2425    'decoder_func': 'DoReleaseTexImage2DCHROMIUM',
2426    'unit_test': False,
2427    'extension': True,
2428    'chromium': True,
2429  },
2430  'ShallowFinishCHROMIUM': {
2431    'impl_func': False,
2432    'gen_cmd': False,
2433    'extension': True,
2434    'chromium': True,
2435    'client_test': False,
2436  },
2437  'ShallowFlushCHROMIUM': {
2438    'impl_func': False,
2439    'gen_cmd': False,
2440    'extension': True,
2441    'chromium': True,
2442    'client_test': False,
2443  },
2444  'TraceBeginCHROMIUM': {
2445    'type': 'Custom',
2446    'impl_func': False,
2447    'immediate': False,
2448    'client_test': False,
2449    'cmd_args': 'GLuint bucket_id',
2450    'extension': True,
2451    'chromium': True,
2452  },
2453  'TraceEndCHROMIUM': {
2454    'impl_func': False,
2455    'immediate': False,
2456    'client_test': False,
2457    'decoder_func': 'DoTraceEndCHROMIUM',
2458    'unit_test': False,
2459    'extension': True,
2460    'chromium': True,
2461  },
2462  'AsyncTexImage2DCHROMIUM': {
2463    'type': 'Manual',
2464    'immediate': False,
2465    'client_test': False,
2466    'cmd_args': 'GLenumTextureTarget target, GLint level, '
2467        'GLintTextureInternalFormat internalformat, '
2468        'GLsizei width, GLsizei height, '
2469        'GLintTextureBorder border, '
2470        'GLenumTextureFormat format, GLenumPixelType type, '
2471        'const void* pixels, '
2472        'uint32 async_upload_token, '
2473        'void* sync_data',
2474    'extension': True,
2475    'chromium': True,
2476  },
2477  'AsyncTexSubImage2DCHROMIUM': {
2478    'type': 'Manual',
2479    'immediate': False,
2480    'client_test': False,
2481    'cmd_args': 'GLenumTextureTarget target, GLint level, '
2482        'GLint xoffset, GLint yoffset, '
2483        'GLsizei width, GLsizei height, '
2484        'GLenumTextureFormat format, GLenumPixelType type, '
2485        'const void* data, '
2486        'uint32 async_upload_token, '
2487        'void* sync_data',
2488    'extension': True,
2489    'chromium': True,
2490  },
2491  'WaitAsyncTexImage2DCHROMIUM': {
2492    'type': 'Manual',
2493    'immediate': False,
2494    'client_test': False,
2495    'extension': True,
2496    'chromium': True,
2497  },
2498  'WaitAllAsyncTexImage2DCHROMIUM': {
2499    'type': 'Manual',
2500    'immediate': False,
2501    'client_test': False,
2502    'extension': True,
2503    'chromium': True,
2504  },
2505  'DiscardFramebufferEXT': {
2506    'type': 'PUTn',
2507    'count': 1,
2508    'data_type': 'GLenum',
2509    'cmd_args': 'GLenum target, GLsizei count, '
2510        'const GLenum* attachments',
2511    'decoder_func': 'DoDiscardFramebufferEXT',
2512    'unit_test': False,
2513    'client_test': False,
2514    'extension': True,
2515  },
2516  'LoseContextCHROMIUM': {
2517    'type': 'Manual',
2518    'impl_func': True,
2519    'extension': True,
2520    'chromium': True,
2521  },
2522  'InsertSyncPointCHROMIUM': {
2523    'type': 'HandWritten',
2524    'impl_func': False,
2525    'extension': True,
2526    'chromium': True,
2527  },
2528  'WaitSyncPointCHROMIUM': {
2529    'type': 'Custom',
2530    'impl_func': True,
2531    'extension': True,
2532    'chromium': True,
2533    'trace_level': 1,
2534  },
2535  'DiscardBackbufferCHROMIUM': {
2536    'type': 'Custom',
2537    'impl_func': True,
2538    'extension': True,
2539    'chromium': True,
2540  },
2541  'ScheduleOverlayPlaneCHROMIUM': {
2542      'type': 'Custom',
2543      'impl_func': True,
2544      'unit_test': False,
2545      'client_test': False,
2546      'extension': True,
2547      'chromium': True,
2548  },
2549}
2550
2551
2552def Grouper(n, iterable, fillvalue=None):
2553  """Collect data into fixed-length chunks or blocks"""
2554  args = [iter(iterable)] * n
2555  return itertools.izip_longest(fillvalue=fillvalue, *args)
2556
2557
2558def SplitWords(input_string):
2559  """Transforms a input_string into a list of lower-case components.
2560
2561  Args:
2562    input_string: the input string.
2563
2564  Returns:
2565    a list of lower-case words.
2566  """
2567  if input_string.find('_') > -1:
2568    # 'some_TEXT_' -> 'some text'
2569    return input_string.replace('_', ' ').strip().lower().split()
2570  else:
2571    if re.search('[A-Z]', input_string) and re.search('[a-z]', input_string):
2572      # mixed case.
2573      # look for capitalization to cut input_strings
2574      # 'SomeText' -> 'Some Text'
2575      input_string = re.sub('([A-Z])', r' \1', input_string).strip()
2576      # 'Vector3' -> 'Vector 3'
2577      input_string = re.sub('([^0-9])([0-9])', r'\1 \2', input_string)
2578    return input_string.lower().split()
2579
2580
2581def Lower(words):
2582  """Makes a lower-case identifier from words.
2583
2584  Args:
2585    words: a list of lower-case words.
2586
2587  Returns:
2588    the lower-case identifier.
2589  """
2590  return '_'.join(words)
2591
2592
2593def ToUnderscore(input_string):
2594  """converts CamelCase to camel_case."""
2595  words = SplitWords(input_string)
2596  return Lower(words)
2597
2598
2599class CWriter(object):
2600  """Writes to a file formatting it for Google's style guidelines."""
2601
2602  def __init__(self, filename):
2603    self.filename = filename
2604    self.file_num = 0
2605    self.content = []
2606
2607  def SetFileNum(self, num):
2608    """Used to help write number files and tests."""
2609    self.file_num = num
2610
2611  def Write(self, string):
2612    """Writes a string to a file spliting if it's > 80 characters."""
2613    lines = string.splitlines()
2614    num_lines = len(lines)
2615    for ii in range(0, num_lines):
2616      self.content.append(lines[ii])
2617      if ii < (num_lines - 1) or string[-1] == '\n':
2618        self.content.append('\n')
2619
2620  def Close(self):
2621    """Close the file."""
2622    content = "".join(self.content)
2623    write_file = True
2624    if os.path.exists(self.filename):
2625      old_file = open(self.filename, "rb");
2626      old_content = old_file.read()
2627      old_file.close();
2628      if content == old_content:
2629        write_file = False
2630    if write_file:
2631      file = open(self.filename, "wb")
2632      file.write(content)
2633      file.close()
2634
2635
2636class CHeaderWriter(CWriter):
2637  """Writes a C Header file."""
2638
2639  _non_alnum_re = re.compile(r'[^a-zA-Z0-9]')
2640
2641  def __init__(self, filename, file_comment = None):
2642    CWriter.__init__(self, filename)
2643
2644    base = os.path.abspath(filename)
2645    while os.path.basename(base) != 'src':
2646      new_base = os.path.dirname(base)
2647      assert new_base != base  # Prevent infinite loop.
2648      base = new_base
2649
2650    hpath = os.path.relpath(filename, base)
2651    self.guard = self._non_alnum_re.sub('_', hpath).upper() + '_'
2652
2653    self.Write(_LICENSE)
2654    self.Write(_DO_NOT_EDIT_WARNING)
2655    if not file_comment == None:
2656      self.Write(file_comment)
2657    self.Write("#ifndef %s\n" % self.guard)
2658    self.Write("#define %s\n\n" % self.guard)
2659
2660  def Close(self):
2661    self.Write("#endif  // %s\n\n" % self.guard)
2662    CWriter.Close(self)
2663
2664class TypeHandler(object):
2665  """This class emits code for a particular type of function."""
2666
2667  _remove_expected_call_re = re.compile(r'  EXPECT_CALL.*?;\n', re.S)
2668
2669  def __init__(self):
2670    pass
2671
2672  def InitFunction(self, func):
2673    """Add or adjust anything type specific for this function."""
2674    if func.GetInfo('needs_size') and not func.name.endswith('Bucket'):
2675      func.AddCmdArg(DataSizeArgument('data_size'))
2676
2677  def AddImmediateFunction(self, generator, func):
2678    """Adds an immediate version of a function."""
2679    # Generate an immediate command if there is only 1 pointer arg.
2680    immediate = func.GetInfo('immediate')  # can be True, False or None
2681    if immediate == True or immediate == None:
2682      if func.num_pointer_args == 1 or immediate:
2683        generator.AddFunction(ImmediateFunction(func))
2684
2685  def AddBucketFunction(self, generator, func):
2686    """Adds a bucket version of a function."""
2687    # Generate an immediate command if there is only 1 pointer arg.
2688    bucket = func.GetInfo('bucket')  # can be True, False or None
2689    if bucket:
2690      generator.AddFunction(BucketFunction(func))
2691
2692  def WriteStruct(self, func, file):
2693    """Writes a structure that matches the arguments to a function."""
2694    comment = func.GetInfo('cmd_comment')
2695    if not comment == None:
2696      file.Write(comment)
2697    file.Write("struct %s {\n" % func.name)
2698    file.Write("  typedef %s ValueType;\n" % func.name)
2699    file.Write("  static const CommandId kCmdId = k%s;\n" % func.name)
2700    func.WriteCmdArgFlag(file)
2701    func.WriteCmdFlag(file)
2702    file.Write("\n")
2703    result = func.GetInfo('result')
2704    if not result == None:
2705      if len(result) == 1:
2706        file.Write("  typedef %s Result;\n\n" % result[0])
2707      else:
2708        file.Write("  struct Result {\n")
2709        for line in result:
2710          file.Write("    %s;\n" % line)
2711        file.Write("  };\n\n")
2712
2713    func.WriteCmdComputeSize(file)
2714    func.WriteCmdSetHeader(file)
2715    func.WriteCmdInit(file)
2716    func.WriteCmdSet(file)
2717
2718    file.Write("  gpu::CommandHeader header;\n")
2719    args = func.GetCmdArgs()
2720    for arg in args:
2721      file.Write("  %s %s;\n" % (arg.cmd_type, arg.name))
2722    file.Write("};\n")
2723    file.Write("\n")
2724
2725    size = len(args) * _SIZE_OF_UINT32 + _SIZE_OF_COMMAND_HEADER
2726    file.Write("COMPILE_ASSERT(sizeof(%s) == %d,\n" % (func.name, size))
2727    file.Write("               Sizeof_%s_is_not_%d);\n" % (func.name, size))
2728    file.Write("COMPILE_ASSERT(offsetof(%s, header) == 0,\n" % func.name)
2729    file.Write("               OffsetOf_%s_header_not_0);\n" % func.name)
2730    offset = _SIZE_OF_COMMAND_HEADER
2731    for arg in args:
2732      file.Write("COMPILE_ASSERT(offsetof(%s, %s) == %d,\n" %
2733                 (func.name, arg.name, offset))
2734      file.Write("               OffsetOf_%s_%s_not_%d);\n" %
2735                 (func.name, arg.name, offset))
2736      offset += _SIZE_OF_UINT32
2737    if not result == None and len(result) > 1:
2738      offset = 0;
2739      for line in result:
2740        parts = line.split()
2741        name = parts[-1]
2742        check = """
2743COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d,
2744               OffsetOf_%(cmd_name)s_Result_%(field_name)s_not_%(offset)d);
2745"""
2746        file.Write((check.strip() + "\n") % {
2747              'cmd_name': func.name,
2748              'field_name': name,
2749              'offset': offset,
2750            })
2751        offset += _SIZE_OF_UINT32
2752    file.Write("\n")
2753
2754  def WriteHandlerImplementation(self, func, file):
2755    """Writes the handler implementation for this command."""
2756    file.Write("  %s(%s);\n" %
2757               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
2758
2759  def WriteCmdSizeTest(self, func, file):
2760    """Writes the size test for a command."""
2761    file.Write("  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n")
2762
2763  def WriteFormatTest(self, func, file):
2764    """Writes a format test for a command."""
2765    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
2766    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
2767               (func.name, func.name))
2768    file.Write("  void* next_cmd = cmd.Set(\n")
2769    file.Write("      &cmd")
2770    args = func.GetCmdArgs()
2771    for value, arg in enumerate(args):
2772      file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 11))
2773    file.Write(");\n")
2774    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
2775               func.name)
2776    file.Write("            cmd.header.command);\n")
2777    func.type_handler.WriteCmdSizeTest(func, file)
2778    for value, arg in enumerate(args):
2779      file.Write("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" %
2780                 (arg.type, value + 11, arg.name))
2781    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
2782    file.Write("      next_cmd, sizeof(cmd));\n")
2783    file.Write("}\n")
2784    file.Write("\n")
2785
2786  def WriteImmediateFormatTest(self, func, file):
2787    """Writes a format test for an immediate version of a command."""
2788    pass
2789
2790  def WriteBucketFormatTest(self, func, file):
2791    """Writes a format test for a bucket version of a command."""
2792    pass
2793
2794  def WriteGetDataSizeCode(self, func, file):
2795    """Writes the code to set data_size used in validation"""
2796    pass
2797
2798  def WriteImmediateCmdSizeTest(self, func, file):
2799    """Writes a size test for an immediate version of a command."""
2800    file.Write("  // TODO(gman): Compute correct size.\n")
2801    file.Write("  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n")
2802
2803  def WriteImmediateHandlerImplementation (self, func, file):
2804    """Writes the handler impl for the immediate version of a command."""
2805    file.Write("  %s(%s);\n" %
2806               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
2807
2808  def WriteBucketHandlerImplementation (self, func, file):
2809    """Writes the handler impl for the bucket version of a command."""
2810    file.Write("  %s(%s);\n" %
2811               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
2812
2813  def WriteServiceImplementation(self, func, file):
2814    """Writes the service implementation for a command."""
2815    file.Write(
2816        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
2817    file.Write(
2818        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
2819        func.name)
2820    self.WriteHandlerDeferReadWrite(func, file);
2821    if len(func.GetOriginalArgs()) > 0:
2822      last_arg = func.GetLastOriginalArg()
2823      all_but_last_arg = func.GetOriginalArgs()[:-1]
2824      for arg in all_but_last_arg:
2825        arg.WriteGetCode(file)
2826      self.WriteGetDataSizeCode(func, file)
2827      last_arg.WriteGetCode(file)
2828    func.WriteHandlerValidation(file)
2829    func.WriteHandlerImplementation(file)
2830    file.Write("  return error::kNoError;\n")
2831    file.Write("}\n")
2832    file.Write("\n")
2833
2834  def WriteImmediateServiceImplementation(self, func, file):
2835    """Writes the service implementation for an immediate version of command."""
2836    file.Write(
2837        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
2838    file.Write(
2839        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
2840        func.name)
2841    self.WriteHandlerDeferReadWrite(func, file);
2842    last_arg = func.GetLastOriginalArg()
2843    all_but_last_arg = func.GetOriginalArgs()[:-1]
2844    for arg in all_but_last_arg:
2845      arg.WriteGetCode(file)
2846    self.WriteGetDataSizeCode(func, file)
2847    last_arg.WriteGetCode(file)
2848    func.WriteHandlerValidation(file)
2849    func.WriteHandlerImplementation(file)
2850    file.Write("  return error::kNoError;\n")
2851    file.Write("}\n")
2852    file.Write("\n")
2853
2854  def WriteBucketServiceImplementation(self, func, file):
2855    """Writes the service implementation for a bucket version of command."""
2856    file.Write(
2857        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
2858    file.Write(
2859        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
2860        func.name)
2861    self.WriteHandlerDeferReadWrite(func, file);
2862    last_arg = func.GetLastOriginalArg()
2863    all_but_last_arg = func.GetOriginalArgs()[:-1]
2864    for arg in all_but_last_arg:
2865      arg.WriteGetCode(file)
2866    self.WriteGetDataSizeCode(func, file)
2867    last_arg.WriteGetCode(file)
2868    func.WriteHandlerValidation(file)
2869    func.WriteHandlerImplementation(file)
2870    file.Write("  return error::kNoError;\n")
2871    file.Write("}\n")
2872    file.Write("\n")
2873
2874  def WriteHandlerDeferReadWrite(self, func, file):
2875    """Writes the code to handle deferring reads or writes."""
2876    defer_draws = func.GetInfo('defer_draws')
2877    defer_reads = func.GetInfo('defer_reads')
2878    if defer_draws or defer_reads:
2879      file.Write("  error::Error error;\n")
2880    if defer_draws:
2881      file.Write("  error = WillAccessBoundFramebufferForDraw();\n")
2882      file.Write("  if (error != error::kNoError)\n")
2883      file.Write("    return error;\n")
2884    if defer_reads:
2885      file.Write("  error = WillAccessBoundFramebufferForRead();\n")
2886      file.Write("  if (error != error::kNoError)\n")
2887      file.Write("    return error;\n")
2888
2889  def WriteValidUnitTest(self, func, file, test, extra = {}):
2890    """Writes a valid unit test."""
2891    if func.GetInfo('expectation') == False:
2892      test = self._remove_expected_call_re.sub('', test)
2893    name = func.name
2894    arg_strings = []
2895    for count, arg in enumerate(func.GetOriginalArgs()):
2896      arg_strings.append(arg.GetValidArg(func, count, 0))
2897    gl_arg_strings = []
2898    for count, arg in enumerate(func.GetOriginalArgs()):
2899      gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
2900    gl_func_name = func.GetGLTestFunctionName()
2901    vars = {
2902      'test_name': 'GLES2DecoderTest%d' % file.file_num,
2903      'name':name,
2904      'gl_func_name': gl_func_name,
2905      'args': ", ".join(arg_strings),
2906      'gl_args': ", ".join(gl_arg_strings),
2907    }
2908    vars.update(extra)
2909    old_test = ""
2910    while (old_test != test):
2911      old_test = test
2912      test = test % vars
2913    file.Write(test % vars)
2914
2915  def WriteInvalidUnitTest(self, func, file, test, extra = {}):
2916    """Writes a invalid unit test."""
2917    for arg_index, arg in enumerate(func.GetOriginalArgs()):
2918      num_invalid_values = arg.GetNumInvalidValues(func)
2919      for value_index in range(0, num_invalid_values):
2920        arg_strings = []
2921        parse_result = "kNoError"
2922        gl_error = None
2923        for count, arg in enumerate(func.GetOriginalArgs()):
2924          if count == arg_index:
2925            (arg_string, parse_result, gl_error) = arg.GetInvalidArg(
2926                count, value_index)
2927          else:
2928            arg_string = arg.GetValidArg(func, count, 0)
2929          arg_strings.append(arg_string)
2930        gl_arg_strings = []
2931        for arg in func.GetOriginalArgs():
2932          gl_arg_strings.append("_")
2933        gl_func_name = func.GetGLTestFunctionName()
2934        gl_error_test = ''
2935        if not gl_error == None:
2936          gl_error_test = '\n  EXPECT_EQ(%s, GetGLError());' % gl_error
2937
2938        vars = {
2939          'test_name': 'GLES2DecoderTest%d' % file.file_num ,
2940          'name': func.name,
2941          'arg_index': arg_index,
2942          'value_index': value_index,
2943          'gl_func_name': gl_func_name,
2944          'args': ", ".join(arg_strings),
2945          'all_but_last_args': ", ".join(arg_strings[:-1]),
2946          'gl_args': ", ".join(gl_arg_strings),
2947          'parse_result': parse_result,
2948            'gl_error_test': gl_error_test,
2949        }
2950        vars.update(extra)
2951        file.Write(test % vars)
2952
2953  def WriteServiceUnitTest(self, func, file):
2954    """Writes the service unit test for a command."""
2955    valid_test = """
2956TEST_F(%(test_name)s, %(name)sValidArgs) {
2957  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
2958  SpecializedSetup<cmds::%(name)s, 0>(true);
2959  cmds::%(name)s cmd;
2960  cmd.Init(%(args)s);
2961  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2962  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2963}
2964"""
2965    self.WriteValidUnitTest(func, file, valid_test)
2966
2967    invalid_test = """
2968TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
2969  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
2970  SpecializedSetup<cmds::%(name)s, 0>(false);
2971  cmds::%(name)s cmd;
2972  cmd.Init(%(args)s);
2973  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
2974}
2975"""
2976    self.WriteInvalidUnitTest(func, file, invalid_test)
2977
2978  def WriteImmediateServiceUnitTest(self, func, file):
2979    """Writes the service unit test for an immediate command."""
2980    file.Write("// TODO(gman): %s\n" % func.name)
2981
2982  def WriteImmediateValidationCode(self, func, file):
2983    """Writes the validation code for an immediate version of a command."""
2984    pass
2985
2986  def WriteBucketServiceUnitTest(self, func, file):
2987    """Writes the service unit test for a bucket command."""
2988    file.Write("// TODO(gman): %s\n" % func.name)
2989
2990  def WriteBucketValidationCode(self, func, file):
2991    """Writes the validation code for a bucket version of a command."""
2992    file.Write("// TODO(gman): %s\n" % func.name)
2993
2994  def WriteGLES2ImplementationDeclaration(self, func, file):
2995    """Writes the GLES2 Implemention declaration."""
2996    impl_decl = func.GetInfo('impl_decl')
2997    if impl_decl == None or impl_decl == True:
2998      file.Write("virtual %s %s(%s) OVERRIDE;\n" %
2999                 (func.return_type, func.original_name,
3000                  func.MakeTypedOriginalArgString("")))
3001      file.Write("\n")
3002
3003  def WriteGLES2CLibImplementation(self, func, file):
3004    file.Write("%s GLES2%s(%s) {\n" %
3005               (func.return_type, func.name,
3006                func.MakeTypedOriginalArgString("")))
3007    result_string = "return "
3008    if func.return_type == "void":
3009      result_string = ""
3010    file.Write("  %sgles2::GetGLContext()->%s(%s);\n" %
3011               (result_string, func.original_name,
3012                func.MakeOriginalArgString("")))
3013    file.Write("}\n")
3014
3015  def WriteGLES2Header(self, func, file):
3016    """Writes a re-write macro for GLES"""
3017    file.Write("#define gl%s GLES2_GET_FUN(%s)\n" %(func.name, func.name))
3018
3019  def WriteClientGLCallLog(self, func, file):
3020    """Writes a logging macro for the client side code."""
3021    comma = ""
3022    if len(func.GetOriginalArgs()):
3023      comma = " << "
3024    file.Write(
3025        '  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] gl%s("%s%s << ")");\n' %
3026        (func.original_name, comma, func.MakeLogArgString()))
3027
3028  def WriteClientGLReturnLog(self, func, file):
3029    """Writes the return value logging code."""
3030    if func.return_type != "void":
3031      file.Write('  GPU_CLIENT_LOG("return:" << result)\n')
3032
3033  def WriteGLES2ImplementationHeader(self, func, file):
3034    """Writes the GLES2 Implemention."""
3035    self.WriteGLES2ImplementationDeclaration(func, file)
3036
3037  def WriteGLES2TraceImplementationHeader(self, func, file):
3038    """Writes the GLES2 Trace Implemention header."""
3039    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3040               (func.return_type, func.original_name,
3041                func.MakeTypedOriginalArgString("")))
3042
3043  def WriteGLES2TraceImplementation(self, func, file):
3044    """Writes the GLES2 Trace Implemention."""
3045    file.Write("%s GLES2TraceImplementation::%s(%s) {\n" %
3046               (func.return_type, func.original_name,
3047                func.MakeTypedOriginalArgString("")))
3048    result_string = "return "
3049    if func.return_type == "void":
3050      result_string = ""
3051    file.Write('  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::%s");\n' %
3052               func.name)
3053    file.Write("  %sgl_->%s(%s);\n" %
3054               (result_string, func.name, func.MakeOriginalArgString("")))
3055    file.Write("}\n")
3056    file.Write("\n")
3057
3058  def WriteGLES2Implementation(self, func, file):
3059    """Writes the GLES2 Implemention."""
3060    impl_func = func.GetInfo('impl_func')
3061    impl_decl = func.GetInfo('impl_decl')
3062    gen_cmd = func.GetInfo('gen_cmd')
3063    if (func.can_auto_generate and
3064        (impl_func == None or impl_func == True) and
3065        (impl_decl == None or impl_decl == True) and
3066        (gen_cmd == None or gen_cmd == True)):
3067      file.Write("%s GLES2Implementation::%s(%s) {\n" %
3068                 (func.return_type, func.original_name,
3069                  func.MakeTypedOriginalArgString("")))
3070      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
3071      self.WriteClientGLCallLog(func, file)
3072      func.WriteDestinationInitalizationValidation(file)
3073      for arg in func.GetOriginalArgs():
3074        arg.WriteClientSideValidationCode(file, func)
3075      file.Write("  helper_->%s(%s);\n" %
3076                 (func.name, func.MakeOriginalArgString("")))
3077      file.Write("  CheckGLError();\n")
3078      self.WriteClientGLReturnLog(func, file)
3079      file.Write("}\n")
3080      file.Write("\n")
3081
3082  def WriteGLES2InterfaceHeader(self, func, file):
3083    """Writes the GLES2 Interface."""
3084    file.Write("virtual %s %s(%s) = 0;\n" %
3085               (func.return_type, func.original_name,
3086                func.MakeTypedOriginalArgString("")))
3087
3088  def WriteGLES2InterfaceStub(self, func, file):
3089    """Writes the GLES2 Interface stub declaration."""
3090    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3091               (func.return_type, func.original_name,
3092                func.MakeTypedOriginalArgString("")))
3093
3094  def WriteGLES2InterfaceStubImpl(self, func, file):
3095    """Writes the GLES2 Interface stub declaration."""
3096    args = func.GetOriginalArgs()
3097    arg_string = ", ".join(
3098        ["%s /* %s */" % (arg.type, arg.name) for arg in args])
3099    file.Write("%s GLES2InterfaceStub::%s(%s) {\n" %
3100               (func.return_type, func.original_name, arg_string))
3101    if func.return_type != "void":
3102      file.Write("  return 0;\n")
3103    file.Write("}\n")
3104
3105  def WriteGLES2ImplementationUnitTest(self, func, file):
3106    """Writes the GLES2 Implemention unit test."""
3107    client_test = func.GetInfo('client_test')
3108    if (func.can_auto_generate and
3109        (client_test == None or client_test == True)):
3110      code = """
3111TEST_F(GLES2ImplementationTest, %(name)s) {
3112  struct Cmds {
3113    cmds::%(name)s cmd;
3114  };
3115  Cmds expected;
3116  expected.cmd.Init(%(cmd_args)s);
3117
3118  gl_->%(name)s(%(args)s);
3119  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3120}
3121"""
3122      cmd_arg_strings = []
3123      for count, arg in enumerate(func.GetCmdArgs()):
3124        cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
3125        count += 1
3126      gl_arg_strings = []
3127      for count, arg in enumerate(func.GetOriginalArgs()):
3128        gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
3129      file.Write(code % {
3130            'name': func.name,
3131            'args': ", ".join(gl_arg_strings),
3132            'cmd_args': ", ".join(cmd_arg_strings),
3133          })
3134    else:
3135      if client_test != False:
3136        file.Write("// TODO: Implement unit test for %s\n" % func.name)
3137
3138  def WriteDestinationInitalizationValidation(self, func, file):
3139    """Writes the client side destintion initialization validation."""
3140    for arg in func.GetOriginalArgs():
3141      arg.WriteDestinationInitalizationValidation(file, func)
3142
3143  def WriteTraceEvent(self, func, file):
3144    file.Write('  TRACE_EVENT0("gpu", "GLES2Implementation::%s");\n' %
3145               func.original_name)
3146
3147  def WriteImmediateCmdComputeSize(self, func, file):
3148    """Writes the size computation code for the immediate version of a cmd."""
3149    file.Write("  static uint32 ComputeSize(uint32 size_in_bytes) {\n")
3150    file.Write("    return static_cast<uint32>(\n")
3151    file.Write("        sizeof(ValueType) +  // NOLINT\n")
3152    file.Write("        RoundSizeToMultipleOfEntries(size_in_bytes));\n")
3153    file.Write("  }\n")
3154    file.Write("\n")
3155
3156  def WriteImmediateCmdSetHeader(self, func, file):
3157    """Writes the SetHeader function for the immediate version of a cmd."""
3158    file.Write("  void SetHeader(uint32 size_in_bytes) {\n")
3159    file.Write("    header.SetCmdByTotalSize<ValueType>(size_in_bytes);\n")
3160    file.Write("  }\n")
3161    file.Write("\n")
3162
3163  def WriteImmediateCmdInit(self, func, file):
3164    """Writes the Init function for the immediate version of a command."""
3165    raise NotImplementedError(func.name)
3166
3167  def WriteImmediateCmdSet(self, func, file):
3168    """Writes the Set function for the immediate version of a command."""
3169    raise NotImplementedError(func.name)
3170
3171  def WriteCmdHelper(self, func, file):
3172    """Writes the cmd helper definition for a cmd."""
3173    code = """  void %(name)s(%(typed_args)s) {
3174    gles2::cmds::%(name)s* c = GetCmdSpace<gles2::cmds::%(name)s>();
3175    if (c) {
3176      c->Init(%(args)s);
3177    }
3178  }
3179
3180"""
3181    file.Write(code % {
3182          "name": func.name,
3183          "typed_args": func.MakeTypedCmdArgString(""),
3184          "args": func.MakeCmdArgString(""),
3185        })
3186
3187  def WriteImmediateCmdHelper(self, func, file):
3188    """Writes the cmd helper definition for the immediate version of a cmd."""
3189    code = """  void %(name)s(%(typed_args)s) {
3190    const uint32 s = 0;  // TODO(gman): compute correct size
3191    gles2::cmds::%(name)s* c =
3192        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(s);
3193    if (c) {
3194      c->Init(%(args)s);
3195    }
3196  }
3197
3198"""
3199    file.Write(code % {
3200           "name": func.name,
3201           "typed_args": func.MakeTypedCmdArgString(""),
3202           "args": func.MakeCmdArgString(""),
3203        })
3204
3205
3206class StateSetHandler(TypeHandler):
3207  """Handler for commands that simply set state."""
3208
3209  def __init__(self):
3210    TypeHandler.__init__(self)
3211
3212  def WriteHandlerImplementation(self, func, file):
3213    """Overrriden from TypeHandler."""
3214    state_name = func.GetInfo('state')
3215    state = _STATES[state_name]
3216    states = state['states']
3217    args = func.GetOriginalArgs()
3218    code = []
3219    for ndx,item in enumerate(states):
3220      if 'range_checks' in item:
3221        for range_check in item['range_checks']:
3222          code.append("%s %s" % (args[ndx].name, range_check['check']))
3223    if len(code):
3224      file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3225      file.Write(
3226        '    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,'
3227        ' "%s", "%s out of range");\n' %
3228        (func.name, args[ndx].name))
3229      file.Write("    return error::kNoError;\n")
3230      file.Write("  }\n")
3231    code = []
3232    for ndx,item in enumerate(states):
3233      code.append("state_.%s != %s" % (item['name'], args[ndx].name))
3234    file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3235    for ndx,item in enumerate(states):
3236      file.Write("    state_.%s = %s;\n" % (item['name'], args[ndx].name))
3237    if 'state_flag' in state:
3238      file.Write("    %s = true;\n" % state['state_flag'])
3239    if not func.GetInfo("no_gl"):
3240      file.Write("    %s(%s);\n" %
3241                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3242    file.Write("  }\n")
3243
3244  def WriteServiceUnitTest(self, func, file):
3245    """Overrriden from TypeHandler."""
3246    TypeHandler.WriteServiceUnitTest(self, func, file)
3247    state_name = func.GetInfo('state')
3248    state = _STATES[state_name]
3249    states = state['states']
3250    for ndx,item in enumerate(states):
3251      if 'range_checks' in item:
3252        for check_ndx, range_check in enumerate(item['range_checks']):
3253          valid_test = """
3254TEST_F(%(test_name)s, %(name)sInvalidValue%(ndx)d_%(check_ndx)d) {
3255  SpecializedSetup<cmds::%(name)s, 0>(false);
3256  cmds::%(name)s cmd;
3257  cmd.Init(%(args)s);
3258  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3259  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3260}
3261"""
3262          name = func.name
3263          arg_strings = []
3264          for count, arg in enumerate(func.GetOriginalArgs()):
3265            arg_strings.append(arg.GetValidArg(func, count, 0))
3266          arg_strings[ndx] = range_check['test_value']
3267          vars = {
3268            'test_name': 'GLES2DecoderTest%d' % file.file_num,
3269            'name': name,
3270            'ndx': ndx,
3271            'check_ndx': check_ndx,
3272            'args': ", ".join(arg_strings),
3273          }
3274          file.Write(valid_test % vars)
3275
3276
3277class StateSetRGBAlphaHandler(TypeHandler):
3278  """Handler for commands that simply set state that have rgb/alpha."""
3279
3280  def __init__(self):
3281    TypeHandler.__init__(self)
3282
3283  def WriteHandlerImplementation(self, func, file):
3284    """Overrriden from TypeHandler."""
3285    state_name = func.GetInfo('state')
3286    state = _STATES[state_name]
3287    states = state['states']
3288    args = func.GetOriginalArgs()
3289    num_args = len(args)
3290    code = []
3291    for ndx,item in enumerate(states):
3292      code.append("state_.%s != %s" % (item['name'], args[ndx % num_args].name))
3293    file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3294    for ndx, item in enumerate(states):
3295      file.Write("    state_.%s = %s;\n" %
3296                 (item['name'], args[ndx % num_args].name))
3297    if 'state_flag' in state:
3298      file.Write("    %s = true;\n" % state['state_flag'])
3299    if not func.GetInfo("no_gl"):
3300      file.Write("    %s(%s);\n" %
3301                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3302      file.Write("  }\n")
3303
3304
3305class StateSetFrontBackSeparateHandler(TypeHandler):
3306  """Handler for commands that simply set state that have front/back."""
3307
3308  def __init__(self):
3309    TypeHandler.__init__(self)
3310
3311  def WriteHandlerImplementation(self, func, file):
3312    """Overrriden from TypeHandler."""
3313    state_name = func.GetInfo('state')
3314    state = _STATES[state_name]
3315    states = state['states']
3316    args = func.GetOriginalArgs()
3317    face = args[0].name
3318    num_args = len(args)
3319    file.Write("  bool changed = false;\n")
3320    for group_ndx, group in enumerate(Grouper(num_args - 1, states)):
3321      file.Write("  if (%s == %s || %s == GL_FRONT_AND_BACK) {\n" %
3322                 (face, ('GL_FRONT', 'GL_BACK')[group_ndx], face))
3323      code = []
3324      for ndx, item in enumerate(group):
3325        code.append("state_.%s != %s" % (item['name'], args[ndx + 1].name))
3326      file.Write("    changed |= %s;\n" % " ||\n        ".join(code))
3327      file.Write("  }\n")
3328    file.Write("  if (changed) {\n")
3329    for group_ndx, group in enumerate(Grouper(num_args - 1, states)):
3330      file.Write("    if (%s == %s || %s == GL_FRONT_AND_BACK) {\n" %
3331                 (face, ('GL_FRONT', 'GL_BACK')[group_ndx], face))
3332      for ndx, item in enumerate(group):
3333        file.Write("      state_.%s = %s;\n" %
3334                   (item['name'], args[ndx + 1].name))
3335      file.Write("    }\n")
3336    if 'state_flag' in state:
3337      file.Write("    %s = true;\n" % state['state_flag'])
3338    if not func.GetInfo("no_gl"):
3339      file.Write("    %s(%s);\n" %
3340                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3341    file.Write("  }\n")
3342
3343
3344class StateSetFrontBackHandler(TypeHandler):
3345  """Handler for commands that simply set state that set both front/back."""
3346
3347  def __init__(self):
3348    TypeHandler.__init__(self)
3349
3350  def WriteHandlerImplementation(self, func, file):
3351    """Overrriden from TypeHandler."""
3352    state_name = func.GetInfo('state')
3353    state = _STATES[state_name]
3354    states = state['states']
3355    args = func.GetOriginalArgs()
3356    num_args = len(args)
3357    code = []
3358    for group_ndx, group in enumerate(Grouper(num_args, states)):
3359      for ndx, item in enumerate(group):
3360        code.append("state_.%s != %s" % (item['name'], args[ndx].name))
3361    file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3362    for group_ndx, group in enumerate(Grouper(num_args, states)):
3363      for ndx, item in enumerate(group):
3364        file.Write("    state_.%s = %s;\n" % (item['name'], args[ndx].name))
3365    if 'state_flag' in state:
3366      file.Write("    %s = true;\n" % state['state_flag'])
3367    if not func.GetInfo("no_gl"):
3368      file.Write("    %s(%s);\n" %
3369                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3370    file.Write("  }\n")
3371
3372
3373class StateSetNamedParameter(TypeHandler):
3374  """Handler for commands that set a state chosen with an enum parameter."""
3375
3376  def __init__(self):
3377    TypeHandler.__init__(self)
3378
3379  def WriteHandlerImplementation(self, func, file):
3380    """Overridden from TypeHandler."""
3381    state_name = func.GetInfo('state')
3382    state = _STATES[state_name]
3383    states = state['states']
3384    args = func.GetOriginalArgs()
3385    num_args = len(args)
3386    assert num_args == 2
3387    file.Write("  switch (%s) {\n" % args[0].name)
3388    for state in states:
3389      file.Write("    case %s:\n" % state['enum'])
3390      file.Write("      if (state_.%s != %s) {\n" %
3391                 (state['name'], args[1].name))
3392      file.Write("        state_.%s = %s;\n" % (state['name'], args[1].name))
3393      if not func.GetInfo("no_gl"):
3394        file.Write("        %s(%s);\n" %
3395                   (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3396      file.Write("      }\n")
3397      file.Write("      break;\n")
3398    file.Write("    default:\n")
3399    file.Write("      NOTREACHED();\n")
3400    file.Write("  }\n")
3401
3402
3403class CustomHandler(TypeHandler):
3404  """Handler for commands that are auto-generated but require minor tweaks."""
3405
3406  def __init__(self):
3407    TypeHandler.__init__(self)
3408
3409  def WriteServiceImplementation(self, func, file):
3410    """Overrriden from TypeHandler."""
3411    pass
3412
3413  def WriteImmediateServiceImplementation(self, func, file):
3414    """Overrriden from TypeHandler."""
3415    pass
3416
3417  def WriteBucketServiceImplementation(self, func, file):
3418    """Overrriden from TypeHandler."""
3419    pass
3420
3421  def WriteServiceUnitTest(self, func, file):
3422    """Overrriden from TypeHandler."""
3423    file.Write("// TODO(gman): %s\n\n" % func.name)
3424
3425  def WriteImmediateServiceUnitTest(self, func, file):
3426    """Overrriden from TypeHandler."""
3427    file.Write("// TODO(gman): %s\n\n" % func.name)
3428
3429  def WriteImmediateCmdGetTotalSize(self, func, file):
3430    """Overrriden from TypeHandler."""
3431    file.Write("    uint32 total_size = 0;  // TODO(gman): get correct size.\n")
3432
3433  def WriteImmediateCmdInit(self, func, file):
3434    """Overrriden from TypeHandler."""
3435    file.Write("  void Init(%s) {\n" % func.MakeTypedCmdArgString("_"))
3436    self.WriteImmediateCmdGetTotalSize(func, file)
3437    file.Write("    SetHeader(total_size);\n")
3438    args = func.GetCmdArgs()
3439    for arg in args:
3440      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
3441    file.Write("  }\n")
3442    file.Write("\n")
3443
3444  def WriteImmediateCmdSet(self, func, file):
3445    """Overrriden from TypeHandler."""
3446    copy_args = func.MakeCmdArgString("_", False)
3447    file.Write("  void* Set(void* cmd%s) {\n" %
3448               func.MakeTypedCmdArgString("_", True))
3449    self.WriteImmediateCmdGetTotalSize(func, file)
3450    file.Write("    static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args)
3451    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
3452               "cmd, total_size);\n")
3453    file.Write("  }\n")
3454    file.Write("\n")
3455
3456
3457class TodoHandler(CustomHandler):
3458  """Handle for commands that are not yet implemented."""
3459
3460  def AddImmediateFunction(self, generator, func):
3461    """Overrriden from TypeHandler."""
3462    pass
3463
3464  def WriteImmediateFormatTest(self, func, file):
3465    """Overrriden from TypeHandler."""
3466    pass
3467
3468  def WriteGLES2ImplementationUnitTest(self, func, file):
3469    """Overrriden from TypeHandler."""
3470    pass
3471
3472  def WriteGLES2Implementation(self, func, file):
3473    """Overrriden from TypeHandler."""
3474    file.Write("%s GLES2Implementation::%s(%s) {\n" %
3475               (func.return_type, func.original_name,
3476                func.MakeTypedOriginalArgString("")))
3477    file.Write("  // TODO: for now this is a no-op\n")
3478    file.Write(
3479        "  SetGLError("
3480        "GL_INVALID_OPERATION, \"gl%s\", \"not implemented\");\n" %
3481        func.name)
3482    if func.return_type != "void":
3483      file.Write("  return 0;\n")
3484    file.Write("}\n")
3485    file.Write("\n")
3486
3487  def WriteServiceImplementation(self, func, file):
3488    """Overrriden from TypeHandler."""
3489    file.Write(
3490        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
3491    file.Write(
3492        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
3493        func.name)
3494    file.Write("  // TODO: for now this is a no-op\n")
3495    file.Write(
3496        "  LOCAL_SET_GL_ERROR("
3497        "GL_INVALID_OPERATION, \"gl%s\", \"not implemented\");\n" %
3498        func.name)
3499    file.Write("  return error::kNoError;\n")
3500    file.Write("}\n")
3501    file.Write("\n")
3502
3503
3504class HandWrittenHandler(CustomHandler):
3505  """Handler for comands where everything must be written by hand."""
3506
3507  def InitFunction(self, func):
3508    """Add or adjust anything type specific for this function."""
3509    CustomHandler.InitFunction(self, func)
3510    func.can_auto_generate = False
3511
3512  def WriteStruct(self, func, file):
3513    """Overrriden from TypeHandler."""
3514    pass
3515
3516  def WriteDocs(self, func, file):
3517    """Overrriden from TypeHandler."""
3518    pass
3519
3520  def WriteServiceUnitTest(self, func, file):
3521    """Overrriden from TypeHandler."""
3522    file.Write("// TODO(gman): %s\n\n" % func.name)
3523
3524  def WriteImmediateServiceUnitTest(self, func, file):
3525    """Overrriden from TypeHandler."""
3526    file.Write("// TODO(gman): %s\n\n" % func.name)
3527
3528  def WriteBucketServiceUnitTest(self, func, file):
3529    """Overrriden from TypeHandler."""
3530    file.Write("// TODO(gman): %s\n\n" % func.name)
3531
3532  def WriteServiceImplementation(self, func, file):
3533    """Overrriden from TypeHandler."""
3534    pass
3535
3536  def WriteImmediateServiceImplementation(self, func, file):
3537    """Overrriden from TypeHandler."""
3538    pass
3539
3540  def WriteBucketServiceImplementation(self, func, file):
3541    """Overrriden from TypeHandler."""
3542    pass
3543
3544  def WriteImmediateCmdHelper(self, func, file):
3545    """Overrriden from TypeHandler."""
3546    pass
3547
3548  def WriteBucketCmdHelper(self, func, file):
3549    """Overrriden from TypeHandler."""
3550    pass
3551
3552  def WriteCmdHelper(self, func, file):
3553    """Overrriden from TypeHandler."""
3554    pass
3555
3556  def WriteFormatTest(self, func, file):
3557    """Overrriden from TypeHandler."""
3558    file.Write("// TODO(gman): Write test for %s\n" % func.name)
3559
3560  def WriteImmediateFormatTest(self, func, file):
3561    """Overrriden from TypeHandler."""
3562    file.Write("// TODO(gman): Write test for %s\n" % func.name)
3563
3564  def WriteBucketFormatTest(self, func, file):
3565    """Overrriden from TypeHandler."""
3566    file.Write("// TODO(gman): Write test for %s\n" % func.name)
3567
3568
3569
3570class ManualHandler(CustomHandler):
3571  """Handler for commands who's handlers must be written by hand."""
3572
3573  def __init__(self):
3574    CustomHandler.__init__(self)
3575
3576  def InitFunction(self, func):
3577    """Overrriden from TypeHandler."""
3578    if (func.name == 'CompressedTexImage2DBucket'):
3579      func.cmd_args = func.cmd_args[:-1]
3580      func.AddCmdArg(Argument('bucket_id', 'GLuint'))
3581    else:
3582      CustomHandler.InitFunction(self, func)
3583
3584  def WriteServiceImplementation(self, func, file):
3585    """Overrriden from TypeHandler."""
3586    pass
3587
3588  def WriteBucketServiceImplementation(self, func, file):
3589    """Overrriden from TypeHandler."""
3590    pass
3591
3592  def WriteServiceUnitTest(self, func, file):
3593    """Overrriden from TypeHandler."""
3594    file.Write("// TODO(gman): %s\n\n" % func.name)
3595
3596  def WriteImmediateServiceUnitTest(self, func, file):
3597    """Overrriden from TypeHandler."""
3598    file.Write("// TODO(gman): %s\n\n" % func.name)
3599
3600  def WriteImmediateServiceImplementation(self, func, file):
3601    """Overrriden from TypeHandler."""
3602    pass
3603
3604  def WriteImmediateFormatTest(self, func, file):
3605    """Overrriden from TypeHandler."""
3606    file.Write("// TODO(gman): Implement test for %s\n" % func.name)
3607
3608  def WriteGLES2Implementation(self, func, file):
3609    """Overrriden from TypeHandler."""
3610    if func.GetInfo('impl_func'):
3611      super(ManualHandler, self).WriteGLES2Implementation(func, file)
3612
3613  def WriteGLES2ImplementationHeader(self, func, file):
3614    """Overrriden from TypeHandler."""
3615    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3616               (func.return_type, func.original_name,
3617                func.MakeTypedOriginalArgString("")))
3618    file.Write("\n")
3619
3620  def WriteImmediateCmdGetTotalSize(self, func, file):
3621    """Overrriden from TypeHandler."""
3622    # TODO(gman): Move this data to _FUNCTION_INFO?
3623    CustomHandler.WriteImmediateCmdGetTotalSize(self, func, file)
3624
3625
3626class DataHandler(TypeHandler):
3627  """Handler for glBufferData, glBufferSubData, glTexImage2D, glTexSubImage2D,
3628     glCompressedTexImage2D, glCompressedTexImageSub2D."""
3629  def __init__(self):
3630    TypeHandler.__init__(self)
3631
3632  def InitFunction(self, func):
3633    """Overrriden from TypeHandler."""
3634    if func.name == 'CompressedTexSubImage2DBucket':
3635      func.cmd_args = func.cmd_args[:-1]
3636      func.AddCmdArg(Argument('bucket_id', 'GLuint'))
3637
3638  def WriteGetDataSizeCode(self, func, file):
3639    """Overrriden from TypeHandler."""
3640    # TODO(gman): Move this data to _FUNCTION_INFO?
3641    name = func.name
3642    if name.endswith("Immediate"):
3643      name = name[0:-9]
3644    if name == 'BufferData' or name == 'BufferSubData':
3645      file.Write("  uint32 data_size = size;\n")
3646    elif (name == 'CompressedTexImage2D' or
3647          name == 'CompressedTexSubImage2D'):
3648      file.Write("  uint32 data_size = imageSize;\n")
3649    elif (name == 'CompressedTexSubImage2DBucket'):
3650      file.Write("  Bucket* bucket = GetBucket(c.bucket_id);\n")
3651      file.Write("  uint32 data_size = bucket->size();\n")
3652      file.Write("  GLsizei imageSize = data_size;\n")
3653    elif name == 'TexImage2D' or name == 'TexSubImage2D':
3654      code = """  uint32 data_size;
3655  if (!GLES2Util::ComputeImageDataSize(
3656      width, height, format, type, unpack_alignment_, &data_size)) {
3657    return error::kOutOfBounds;
3658  }
3659"""
3660      file.Write(code)
3661    else:
3662      file.Write("// uint32 data_size = 0;  // TODO(gman): get correct size!\n")
3663
3664  def WriteImmediateCmdGetTotalSize(self, func, file):
3665    """Overrriden from TypeHandler."""
3666    pass
3667
3668  def WriteImmediateCmdSizeTest(self, func, file):
3669    """Overrriden from TypeHandler."""
3670    file.Write("  EXPECT_EQ(sizeof(cmd), total_size);\n")
3671
3672  def WriteImmediateCmdInit(self, func, file):
3673    """Overrriden from TypeHandler."""
3674    file.Write("  void Init(%s) {\n" % func.MakeTypedCmdArgString("_"))
3675    self.WriteImmediateCmdGetTotalSize(func, file)
3676    file.Write("    SetHeader(total_size);\n")
3677    args = func.GetCmdArgs()
3678    for arg in args:
3679      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
3680    file.Write("  }\n")
3681    file.Write("\n")
3682
3683  def WriteImmediateCmdSet(self, func, file):
3684    """Overrriden from TypeHandler."""
3685    copy_args = func.MakeCmdArgString("_", False)
3686    file.Write("  void* Set(void* cmd%s) {\n" %
3687               func.MakeTypedCmdArgString("_", True))
3688    self.WriteImmediateCmdGetTotalSize(func, file)
3689    file.Write("    static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args)
3690    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
3691               "cmd, total_size);\n")
3692    file.Write("  }\n")
3693    file.Write("\n")
3694
3695  def WriteImmediateFormatTest(self, func, file):
3696    """Overrriden from TypeHandler."""
3697    # TODO(gman): Remove this exception.
3698    file.Write("// TODO(gman): Implement test for %s\n" % func.name)
3699    return
3700
3701  def WriteServiceUnitTest(self, func, file):
3702    """Overrriden from TypeHandler."""
3703    file.Write("// TODO(gman): %s\n\n" % func.name)
3704
3705  def WriteImmediateServiceUnitTest(self, func, file):
3706    """Overrriden from TypeHandler."""
3707    file.Write("// TODO(gman): %s\n\n" % func.name)
3708
3709  def WriteBucketServiceImplementation(self, func, file):
3710    """Overrriden from TypeHandler."""
3711    if not func.name == 'CompressedTexSubImage2DBucket':
3712      TypeHandler.WriteBucketServiceImplemenation(self, func, file)
3713
3714
3715class BindHandler(TypeHandler):
3716  """Handler for glBind___ type functions."""
3717
3718  def __init__(self):
3719    TypeHandler.__init__(self)
3720
3721  def WriteServiceUnitTest(self, func, file):
3722    """Overrriden from TypeHandler."""
3723
3724    if len(func.GetOriginalArgs()) == 1:
3725      valid_test = """
3726TEST_F(%(test_name)s, %(name)sValidArgs) {
3727  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
3728  SpecializedSetup<cmds::%(name)s, 0>(true);
3729  cmds::%(name)s cmd;
3730  cmd.Init(%(args)s);
3731  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3732  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3733}
3734"""
3735      if func.GetInfo("gen_func"):
3736          valid_test += """
3737TEST_F(%(test_name)s, %(name)sValidArgsNewId) {
3738  EXPECT_CALL(*gl_, %(gl_func_name)s(kNewServiceId));
3739  EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _))
3740     .WillOnce(SetArgumentPointee<1>(kNewServiceId));
3741  SpecializedSetup<cmds::%(name)s, 0>(true);
3742  cmds::%(name)s cmd;
3743  cmd.Init(kNewClientId);
3744  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3745  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3746  EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
3747}
3748"""
3749      self.WriteValidUnitTest(func, file, valid_test, {
3750          'resource_type': func.GetOriginalArgs()[0].resource_type,
3751          'gl_gen_func_name': func.GetInfo("gen_func"),
3752      })
3753    else:
3754      valid_test = """
3755TEST_F(%(test_name)s, %(name)sValidArgs) {
3756  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
3757  SpecializedSetup<cmds::%(name)s, 0>(true);
3758  cmds::%(name)s cmd;
3759  cmd.Init(%(args)s);
3760  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3761  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3762}
3763"""
3764      if func.GetInfo("gen_func"):
3765          valid_test += """
3766TEST_F(%(test_name)s, %(name)sValidArgsNewId) {
3767  EXPECT_CALL(*gl_, %(gl_func_name)s(%(first_gl_arg)s, kNewServiceId));
3768  EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _))
3769     .WillOnce(SetArgumentPointee<1>(kNewServiceId));
3770  SpecializedSetup<cmds::%(name)s, 0>(true);
3771  cmds::%(name)s cmd;
3772  cmd.Init(%(first_arg)s, kNewClientId);
3773  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3774  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3775  EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
3776}
3777"""
3778      self.WriteValidUnitTest(func, file, valid_test, {
3779          'first_arg': func.GetOriginalArgs()[0].GetValidArg(func, 0, 0),
3780          'first_gl_arg': func.GetOriginalArgs()[0].GetValidGLArg(func, 0, 0),
3781          'resource_type': func.GetOriginalArgs()[1].resource_type,
3782          'gl_gen_func_name': func.GetInfo("gen_func"),
3783      })
3784
3785    invalid_test = """
3786TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
3787  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
3788  SpecializedSetup<cmds::%(name)s, 0>(false);
3789  cmds::%(name)s cmd;
3790  cmd.Init(%(args)s);
3791  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
3792}
3793"""
3794    self.WriteInvalidUnitTest(func, file, invalid_test)
3795
3796  def WriteGLES2Implementation(self, func, file):
3797    """Writes the GLES2 Implemention."""
3798
3799    impl_func = func.GetInfo('impl_func')
3800    impl_decl = func.GetInfo('impl_decl')
3801
3802    if (func.can_auto_generate and
3803          (impl_func == None or impl_func == True) and
3804          (impl_decl == None or impl_decl == True)):
3805
3806      file.Write("%s GLES2Implementation::%s(%s) {\n" %
3807                 (func.return_type, func.original_name,
3808                  func.MakeTypedOriginalArgString("")))
3809      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
3810      func.WriteDestinationInitalizationValidation(file)
3811      self.WriteClientGLCallLog(func, file)
3812      for arg in func.GetOriginalArgs():
3813        arg.WriteClientSideValidationCode(file, func)
3814
3815      code = """  if (Is%(type)sReservedId(%(id)s)) {
3816    SetGLError(GL_INVALID_OPERATION, "%(name)s\", \"%(id)s reserved id");
3817    return;
3818  }
3819  if (%(name)sHelper(%(arg_string)s)) {
3820    helper_->%(name)s(%(arg_string)s);
3821  }
3822  CheckGLError();
3823}
3824
3825"""
3826      name_arg = None
3827      if len(func.GetOriginalArgs()) == 1:
3828        # Bind functions that have no target (like BindVertexArrayOES)
3829        name_arg = func.GetOriginalArgs()[0]
3830      else:
3831        # Bind functions that have both a target and a name (like BindTexture)
3832        name_arg = func.GetOriginalArgs()[1]
3833
3834      file.Write(code % {
3835          'name': func.name,
3836          'arg_string': func.MakeOriginalArgString(""),
3837          'id': name_arg.name,
3838          'type': name_arg.resource_type,
3839          'lc_type': name_arg.resource_type.lower(),
3840        })
3841
3842  def WriteGLES2ImplementationUnitTest(self, func, file):
3843    """Overrriden from TypeHandler."""
3844    client_test = func.GetInfo('client_test')
3845    if client_test == False:
3846      return
3847    code = """
3848TEST_F(GLES2ImplementationTest, %(name)s) {
3849  struct Cmds {
3850    cmds::%(name)s cmd;
3851  };
3852  Cmds expected;
3853  expected.cmd.Init(%(cmd_args)s);
3854
3855  gl_->%(name)s(%(args)s);
3856  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3857  ClearCommands();
3858  gl_->%(name)s(%(args)s);
3859  EXPECT_TRUE(NoCommandsWritten());
3860}
3861"""
3862    cmd_arg_strings = []
3863    for count, arg in enumerate(func.GetCmdArgs()):
3864      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
3865      count += 1
3866    gl_arg_strings = []
3867    for count, arg in enumerate(func.GetOriginalArgs()):
3868      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
3869    file.Write(code % {
3870          'name': func.name,
3871          'args': ", ".join(gl_arg_strings),
3872          'cmd_args': ", ".join(cmd_arg_strings),
3873        })
3874
3875
3876class GENnHandler(TypeHandler):
3877  """Handler for glGen___ type functions."""
3878
3879  def __init__(self):
3880    TypeHandler.__init__(self)
3881
3882  def InitFunction(self, func):
3883    """Overrriden from TypeHandler."""
3884    pass
3885
3886  def WriteGetDataSizeCode(self, func, file):
3887    """Overrriden from TypeHandler."""
3888    code = """  uint32 data_size;
3889  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
3890    return error::kOutOfBounds;
3891  }
3892"""
3893    file.Write(code)
3894
3895  def WriteHandlerImplementation (self, func, file):
3896    """Overrriden from TypeHandler."""
3897    file.Write("  if (!%sHelper(n, %s)) {\n"
3898               "    return error::kInvalidArguments;\n"
3899               "  }\n" %
3900               (func.name, func.GetLastOriginalArg().name))
3901
3902  def WriteImmediateHandlerImplementation(self, func, file):
3903    """Overrriden from TypeHandler."""
3904    file.Write("  if (!%sHelper(n, %s)) {\n"
3905               "    return error::kInvalidArguments;\n"
3906               "  }\n" %
3907               (func.original_name, func.GetLastOriginalArg().name))
3908
3909  def WriteGLES2Implementation(self, func, file):
3910    """Overrriden from TypeHandler."""
3911    log_code = ("""  GPU_CLIENT_LOG_CODE_BLOCK({
3912    for (GLsizei i = 0; i < n; ++i) {
3913      GPU_CLIENT_LOG("  " << i << ": " << %s[i]);
3914    }
3915  });""" % func.GetOriginalArgs()[1].name)
3916    args = {
3917        'log_code': log_code,
3918        'return_type': func.return_type,
3919        'name': func.original_name,
3920        'typed_args': func.MakeTypedOriginalArgString(""),
3921        'args': func.MakeOriginalArgString(""),
3922        'resource_types': func.GetInfo('resource_types'),
3923        'count_name': func.GetOriginalArgs()[0].name,
3924      }
3925    file.Write(
3926        "%(return_type)s GLES2Implementation::%(name)s(%(typed_args)s) {\n" %
3927        args)
3928    func.WriteDestinationInitalizationValidation(file)
3929    self.WriteClientGLCallLog(func, file)
3930    for arg in func.GetOriginalArgs():
3931      arg.WriteClientSideValidationCode(file, func)
3932    code = """  GPU_CLIENT_SINGLE_THREAD_CHECK();
3933  GetIdHandler(id_namespaces::k%(resource_types)s)->
3934      MakeIds(this, 0, %(args)s);
3935  %(name)sHelper(%(args)s);
3936  helper_->%(name)sImmediate(%(args)s);
3937  if (share_group_->bind_generates_resource())
3938    helper_->CommandBufferHelper::Flush();
3939%(log_code)s
3940  CheckGLError();
3941}
3942
3943"""
3944    file.Write(code % args)
3945
3946  def WriteGLES2ImplementationUnitTest(self, func, file):
3947    """Overrriden from TypeHandler."""
3948    code = """
3949TEST_F(GLES2ImplementationTest, %(name)s) {
3950  GLuint ids[2] = { 0, };
3951  struct Cmds {
3952    cmds::%(name)sImmediate gen;
3953    GLuint data[2];
3954  };
3955  Cmds expected;
3956  expected.gen.Init(arraysize(ids), &ids[0]);
3957  expected.data[0] = k%(types)sStartId;
3958  expected.data[1] = k%(types)sStartId + 1;
3959  gl_->%(name)s(arraysize(ids), &ids[0]);
3960  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3961  EXPECT_EQ(k%(types)sStartId, ids[0]);
3962  EXPECT_EQ(k%(types)sStartId + 1, ids[1]);
3963}
3964"""
3965    file.Write(code % {
3966          'name': func.name,
3967          'types': func.GetInfo('resource_types'),
3968        })
3969
3970  def WriteServiceUnitTest(self, func, file):
3971    """Overrriden from TypeHandler."""
3972    valid_test = """
3973TEST_F(%(test_name)s, %(name)sValidArgs) {
3974  EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
3975      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
3976  GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
3977  SpecializedSetup<cmds::%(name)s, 0>(true);
3978  cmds::%(name)s cmd;
3979  cmd.Init(%(args)s);
3980  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3981  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3982  EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL);
3983}
3984"""
3985    self.WriteValidUnitTest(func, file, valid_test, {
3986        'resource_name': func.GetInfo('resource_type'),
3987      })
3988    invalid_test = """
3989TEST_F(%(test_name)s, %(name)sInvalidArgs) {
3990  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
3991  GetSharedMemoryAs<GLuint*>()[0] = client_%(resource_name)s_id_;
3992  SpecializedSetup<cmds::%(name)s, 0>(false);
3993  cmds::%(name)s cmd;
3994  cmd.Init(%(args)s);
3995  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
3996}
3997"""
3998    self.WriteValidUnitTest(func, file, invalid_test, {
3999          'resource_name': func.GetInfo('resource_type').lower(),
4000        })
4001
4002  def WriteImmediateServiceUnitTest(self, func, file):
4003    """Overrriden from TypeHandler."""
4004    valid_test = """
4005TEST_F(%(test_name)s, %(name)sValidArgs) {
4006  EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
4007      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
4008  cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
4009  GLuint temp = kNewClientId;
4010  SpecializedSetup<cmds::%(name)s, 0>(true);
4011  cmd->Init(1, &temp);
4012  EXPECT_EQ(error::kNoError,
4013            ExecuteImmediateCmd(*cmd, sizeof(temp)));
4014  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4015  EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL);
4016}
4017"""
4018    self.WriteValidUnitTest(func, file, valid_test, {
4019        'resource_name': func.GetInfo('resource_type'),
4020      })
4021    invalid_test = """
4022TEST_F(%(test_name)s, %(name)sInvalidArgs) {
4023  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
4024  cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
4025  SpecializedSetup<cmds::%(name)s, 0>(false);
4026  cmd->Init(1, &client_%(resource_name)s_id_);
4027  EXPECT_EQ(error::kInvalidArguments,
4028            ExecuteImmediateCmd(*cmd, sizeof(&client_%(resource_name)s_id_)));
4029}
4030"""
4031    self.WriteValidUnitTest(func, file, invalid_test, {
4032          'resource_name': func.GetInfo('resource_type').lower(),
4033        })
4034
4035  def WriteImmediateCmdComputeSize(self, func, file):
4036    """Overrriden from TypeHandler."""
4037    file.Write("  static uint32 ComputeDataSize(GLsizei n) {\n")
4038    file.Write(
4039        "    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT\n")
4040    file.Write("  }\n")
4041    file.Write("\n")
4042    file.Write("  static uint32 ComputeSize(GLsizei n) {\n")
4043    file.Write("    return static_cast<uint32>(\n")
4044    file.Write("        sizeof(ValueType) + ComputeDataSize(n));  // NOLINT\n")
4045    file.Write("  }\n")
4046    file.Write("\n")
4047
4048  def WriteImmediateCmdSetHeader(self, func, file):
4049    """Overrriden from TypeHandler."""
4050    file.Write("  void SetHeader(GLsizei n) {\n")
4051    file.Write("    header.SetCmdByTotalSize<ValueType>(ComputeSize(n));\n")
4052    file.Write("  }\n")
4053    file.Write("\n")
4054
4055  def WriteImmediateCmdInit(self, func, file):
4056    """Overrriden from TypeHandler."""
4057    last_arg = func.GetLastOriginalArg()
4058    file.Write("  void Init(%s, %s _%s) {\n" %
4059               (func.MakeTypedCmdArgString("_"),
4060                last_arg.type, last_arg.name))
4061    file.Write("    SetHeader(_n);\n")
4062    args = func.GetCmdArgs()
4063    for arg in args:
4064      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
4065    file.Write("    memcpy(ImmediateDataAddress(this),\n")
4066    file.Write("           _%s, ComputeDataSize(_n));\n" % last_arg.name)
4067    file.Write("  }\n")
4068    file.Write("\n")
4069
4070  def WriteImmediateCmdSet(self, func, file):
4071    """Overrriden from TypeHandler."""
4072    last_arg = func.GetLastOriginalArg()
4073    copy_args = func.MakeCmdArgString("_", False)
4074    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
4075               (func.MakeTypedCmdArgString("_", True),
4076                last_arg.type, last_arg.name))
4077    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
4078               (copy_args, last_arg.name))
4079    file.Write("    const uint32 size = ComputeSize(_n);\n")
4080    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
4081               "cmd, size);\n")
4082    file.Write("  }\n")
4083    file.Write("\n")
4084
4085  def WriteImmediateCmdHelper(self, func, file):
4086    """Overrriden from TypeHandler."""
4087    code = """  void %(name)s(%(typed_args)s) {
4088    const uint32 size = gles2::cmds::%(name)s::ComputeSize(n);
4089    gles2::cmds::%(name)s* c =
4090        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
4091    if (c) {
4092      c->Init(%(args)s);
4093    }
4094  }
4095
4096"""
4097    file.Write(code % {
4098          "name": func.name,
4099          "typed_args": func.MakeTypedOriginalArgString(""),
4100          "args": func.MakeOriginalArgString(""),
4101        })
4102
4103  def WriteImmediateFormatTest(self, func, file):
4104    """Overrriden from TypeHandler."""
4105    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
4106    file.Write("  static GLuint ids[] = { 12, 23, 34, };\n")
4107    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
4108               (func.name, func.name))
4109    file.Write("  void* next_cmd = cmd.Set(\n")
4110    file.Write("      &cmd, static_cast<GLsizei>(arraysize(ids)), ids);\n")
4111    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
4112               func.name)
4113    file.Write("            cmd.header.command);\n")
4114    file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
4115    file.Write("            RoundSizeToMultipleOfEntries(cmd.n * 4u),\n")
4116    file.Write("            cmd.header.size * 4u);\n")
4117    file.Write("  EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);\n");
4118    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
4119    file.Write("      next_cmd, sizeof(cmd) +\n")
4120    file.Write("      RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));\n")
4121    file.Write("  // TODO(gman): Check that ids were inserted;\n")
4122    file.Write("}\n")
4123    file.Write("\n")
4124
4125
4126class CreateHandler(TypeHandler):
4127  """Handler for glCreate___ type functions."""
4128
4129  def __init__(self):
4130    TypeHandler.__init__(self)
4131
4132  def InitFunction(self, func):
4133    """Overrriden from TypeHandler."""
4134    func.AddCmdArg(Argument("client_id", 'uint32'))
4135
4136  def WriteServiceUnitTest(self, func, file):
4137    """Overrriden from TypeHandler."""
4138    valid_test = """
4139TEST_F(%(test_name)s, %(name)sValidArgs) {
4140  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
4141      .WillOnce(Return(kNewServiceId));
4142  SpecializedSetup<cmds::%(name)s, 0>(true);
4143  cmds::%(name)s cmd;
4144  cmd.Init(%(args)s%(comma)skNewClientId);
4145  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4146  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4147  EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
4148}
4149"""
4150    comma = ""
4151    if len(func.GetOriginalArgs()):
4152      comma =", "
4153    self.WriteValidUnitTest(func, file, valid_test, {
4154          'comma': comma,
4155          'resource_type': func.name[6:],
4156        })
4157    invalid_test = """
4158TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4159  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
4160  SpecializedSetup<cmds::%(name)s, 0>(false);
4161  cmds::%(name)s cmd;
4162  cmd.Init(%(args)s%(comma)skNewClientId);
4163  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));%(gl_error_test)s
4164}
4165"""
4166    self.WriteInvalidUnitTest(func, file, invalid_test, {
4167          'comma': comma,
4168        })
4169
4170  def WriteHandlerImplementation (self, func, file):
4171    """Overrriden from TypeHandler."""
4172    file.Write("  uint32 client_id = c.client_id;\n")
4173    file.Write("  if (!%sHelper(%s)) {\n" %
4174               (func.name, func.MakeCmdArgString("")))
4175    file.Write("    return error::kInvalidArguments;\n")
4176    file.Write("  }\n")
4177
4178  def WriteGLES2Implementation(self, func, file):
4179    """Overrriden from TypeHandler."""
4180    file.Write("%s GLES2Implementation::%s(%s) {\n" %
4181               (func.return_type, func.original_name,
4182                func.MakeTypedOriginalArgString("")))
4183    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4184    func.WriteDestinationInitalizationValidation(file)
4185    self.WriteClientGLCallLog(func, file)
4186    for arg in func.GetOriginalArgs():
4187      arg.WriteClientSideValidationCode(file, func)
4188    file.Write("  GLuint client_id;\n")
4189    file.Write(
4190        "  GetIdHandler(id_namespaces::kProgramsAndShaders)->\n")
4191    file.Write("      MakeIds(this, 0, 1, &client_id);\n")
4192    file.Write("  helper_->%s(%s);\n" %
4193               (func.name, func.MakeCmdArgString("")))
4194    file.Write('  GPU_CLIENT_LOG("returned " << client_id);\n')
4195    file.Write("  CheckGLError();\n")
4196    file.Write("  return client_id;\n")
4197    file.Write("}\n")
4198    file.Write("\n")
4199
4200
4201class DeleteHandler(TypeHandler):
4202  """Handler for glDelete___ single resource type functions."""
4203
4204  def __init__(self):
4205    TypeHandler.__init__(self)
4206
4207  def WriteServiceImplementation(self, func, file):
4208    """Overrriden from TypeHandler."""
4209    pass
4210
4211  def WriteGLES2Implementation(self, func, file):
4212    """Overrriden from TypeHandler."""
4213    file.Write("%s GLES2Implementation::%s(%s) {\n" %
4214               (func.return_type, func.original_name,
4215                func.MakeTypedOriginalArgString("")))
4216    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4217    func.WriteDestinationInitalizationValidation(file)
4218    self.WriteClientGLCallLog(func, file)
4219    for arg in func.GetOriginalArgs():
4220      arg.WriteClientSideValidationCode(file, func)
4221    file.Write(
4222        "  GPU_CLIENT_DCHECK(%s != 0);\n" % func.GetOriginalArgs()[-1].name)
4223    file.Write("  %sHelper(%s);\n" %
4224               (func.original_name, func.GetOriginalArgs()[-1].name))
4225    file.Write("  CheckGLError();\n")
4226    file.Write("}\n")
4227    file.Write("\n")
4228
4229
4230class DELnHandler(TypeHandler):
4231  """Handler for glDelete___ type functions."""
4232
4233  def __init__(self):
4234    TypeHandler.__init__(self)
4235
4236  def WriteGetDataSizeCode(self, func, file):
4237    """Overrriden from TypeHandler."""
4238    code = """  uint32 data_size;
4239  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4240    return error::kOutOfBounds;
4241  }
4242"""
4243    file.Write(code)
4244
4245  def WriteGLES2ImplementationUnitTest(self, func, file):
4246    """Overrriden from TypeHandler."""
4247    code = """
4248TEST_F(GLES2ImplementationTest, %(name)s) {
4249  GLuint ids[2] = { k%(types)sStartId, k%(types)sStartId + 1 };
4250  struct Cmds {
4251    cmds::%(name)sImmediate del;
4252    GLuint data[2];
4253  };
4254  Cmds expected;
4255  expected.del.Init(arraysize(ids), &ids[0]);
4256  expected.data[0] = k%(types)sStartId;
4257  expected.data[1] = k%(types)sStartId + 1;
4258  gl_->%(name)s(arraysize(ids), &ids[0]);
4259  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
4260}
4261"""
4262    file.Write(code % {
4263          'name': func.name,
4264          'types': func.GetInfo('resource_types'),
4265        })
4266
4267  def WriteServiceUnitTest(self, func, file):
4268    """Overrriden from TypeHandler."""
4269    valid_test = """
4270TEST_F(%(test_name)s, %(name)sValidArgs) {
4271  EXPECT_CALL(
4272      *gl_,
4273      %(gl_func_name)s(1, Pointee(kService%(upper_resource_name)sId)))
4274      .Times(1);
4275  GetSharedMemoryAs<GLuint*>()[0] = client_%(resource_name)s_id_;
4276  SpecializedSetup<cmds::%(name)s, 0>(true);
4277  cmds::%(name)s cmd;
4278  cmd.Init(%(args)s);
4279  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4280  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4281  EXPECT_TRUE(
4282      Get%(upper_resource_name)s(client_%(resource_name)s_id_) == NULL);
4283}
4284"""
4285    self.WriteValidUnitTest(func, file, valid_test, {
4286          'resource_name': func.GetInfo('resource_type').lower(),
4287          'upper_resource_name': func.GetInfo('resource_type'),
4288        })
4289    invalid_test = """
4290TEST_F(%(test_name)s, %(name)sInvalidArgs) {
4291  GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
4292  SpecializedSetup<cmds::%(name)s, 0>(false);
4293  cmds::%(name)s cmd;
4294  cmd.Init(%(args)s);
4295  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4296}
4297"""
4298    self.WriteValidUnitTest(func, file, invalid_test)
4299
4300  def WriteImmediateServiceUnitTest(self, func, file):
4301    """Overrriden from TypeHandler."""
4302    valid_test = """
4303TEST_F(%(test_name)s, %(name)sValidArgs) {
4304  EXPECT_CALL(
4305      *gl_,
4306      %(gl_func_name)s(1, Pointee(kService%(upper_resource_name)sId)))
4307      .Times(1);
4308  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4309  SpecializedSetup<cmds::%(name)s, 0>(true);
4310  cmd.Init(1, &client_%(resource_name)s_id_);
4311  EXPECT_EQ(error::kNoError,
4312            ExecuteImmediateCmd(cmd, sizeof(client_%(resource_name)s_id_)));
4313  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4314  EXPECT_TRUE(
4315      Get%(upper_resource_name)s(client_%(resource_name)s_id_) == NULL);
4316}
4317"""
4318    self.WriteValidUnitTest(func, file, valid_test, {
4319          'resource_name': func.GetInfo('resource_type').lower(),
4320          'upper_resource_name': func.GetInfo('resource_type'),
4321        })
4322    invalid_test = """
4323TEST_F(%(test_name)s, %(name)sInvalidArgs) {
4324  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4325  SpecializedSetup<cmds::%(name)s, 0>(false);
4326  GLuint temp = kInvalidClientId;
4327  cmd.Init(1, &temp);
4328  EXPECT_EQ(error::kNoError,
4329            ExecuteImmediateCmd(cmd, sizeof(temp)));
4330}
4331"""
4332    self.WriteValidUnitTest(func, file, invalid_test)
4333
4334  def WriteHandlerImplementation (self, func, file):
4335    """Overrriden from TypeHandler."""
4336    file.Write("  %sHelper(n, %s);\n" %
4337               (func.name, func.GetLastOriginalArg().name))
4338
4339  def WriteImmediateHandlerImplementation (self, func, file):
4340    """Overrriden from TypeHandler."""
4341    file.Write("  %sHelper(n, %s);\n" %
4342               (func.original_name, func.GetLastOriginalArg().name))
4343
4344  def WriteGLES2Implementation(self, func, file):
4345    """Overrriden from TypeHandler."""
4346    impl_decl = func.GetInfo('impl_decl')
4347    if impl_decl == None or impl_decl == True:
4348      args = {
4349          'return_type': func.return_type,
4350          'name': func.original_name,
4351          'typed_args': func.MakeTypedOriginalArgString(""),
4352          'args': func.MakeOriginalArgString(""),
4353          'resource_type': func.GetInfo('resource_type').lower(),
4354          'count_name': func.GetOriginalArgs()[0].name,
4355        }
4356      file.Write(
4357          "%(return_type)s GLES2Implementation::%(name)s(%(typed_args)s) {\n" %
4358          args)
4359      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4360      func.WriteDestinationInitalizationValidation(file)
4361      self.WriteClientGLCallLog(func, file)
4362      file.Write("""  GPU_CLIENT_LOG_CODE_BLOCK({
4363    for (GLsizei i = 0; i < n; ++i) {
4364      GPU_CLIENT_LOG("  " << i << ": " << %s[i]);
4365    }
4366  });
4367""" % func.GetOriginalArgs()[1].name)
4368      file.Write("""  GPU_CLIENT_DCHECK_CODE_BLOCK({
4369    for (GLsizei i = 0; i < n; ++i) {
4370      DCHECK(%s[i] != 0);
4371    }
4372  });
4373""" % func.GetOriginalArgs()[1].name)
4374      for arg in func.GetOriginalArgs():
4375        arg.WriteClientSideValidationCode(file, func)
4376      code = """  %(name)sHelper(%(args)s);
4377  CheckGLError();
4378}
4379
4380"""
4381      file.Write(code % args)
4382
4383  def WriteImmediateCmdComputeSize(self, func, file):
4384    """Overrriden from TypeHandler."""
4385    file.Write("  static uint32 ComputeDataSize(GLsizei n) {\n")
4386    file.Write(
4387        "    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT\n")
4388    file.Write("  }\n")
4389    file.Write("\n")
4390    file.Write("  static uint32 ComputeSize(GLsizei n) {\n")
4391    file.Write("    return static_cast<uint32>(\n")
4392    file.Write("        sizeof(ValueType) + ComputeDataSize(n));  // NOLINT\n")
4393    file.Write("  }\n")
4394    file.Write("\n")
4395
4396  def WriteImmediateCmdSetHeader(self, func, file):
4397    """Overrriden from TypeHandler."""
4398    file.Write("  void SetHeader(GLsizei n) {\n")
4399    file.Write("    header.SetCmdByTotalSize<ValueType>(ComputeSize(n));\n")
4400    file.Write("  }\n")
4401    file.Write("\n")
4402
4403  def WriteImmediateCmdInit(self, func, file):
4404    """Overrriden from TypeHandler."""
4405    last_arg = func.GetLastOriginalArg()
4406    file.Write("  void Init(%s, %s _%s) {\n" %
4407               (func.MakeTypedCmdArgString("_"),
4408                last_arg.type, last_arg.name))
4409    file.Write("    SetHeader(_n);\n")
4410    args = func.GetCmdArgs()
4411    for arg in args:
4412      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
4413    file.Write("    memcpy(ImmediateDataAddress(this),\n")
4414    file.Write("           _%s, ComputeDataSize(_n));\n" % last_arg.name)
4415    file.Write("  }\n")
4416    file.Write("\n")
4417
4418  def WriteImmediateCmdSet(self, func, file):
4419    """Overrriden from TypeHandler."""
4420    last_arg = func.GetLastOriginalArg()
4421    copy_args = func.MakeCmdArgString("_", False)
4422    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
4423               (func.MakeTypedCmdArgString("_", True),
4424                last_arg.type, last_arg.name))
4425    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
4426               (copy_args, last_arg.name))
4427    file.Write("    const uint32 size = ComputeSize(_n);\n")
4428    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
4429               "cmd, size);\n")
4430    file.Write("  }\n")
4431    file.Write("\n")
4432
4433  def WriteImmediateCmdHelper(self, func, file):
4434    """Overrriden from TypeHandler."""
4435    code = """  void %(name)s(%(typed_args)s) {
4436    const uint32 size = gles2::cmds::%(name)s::ComputeSize(n);
4437    gles2::cmds::%(name)s* c =
4438        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
4439    if (c) {
4440      c->Init(%(args)s);
4441    }
4442  }
4443
4444"""
4445    file.Write(code % {
4446          "name": func.name,
4447          "typed_args": func.MakeTypedOriginalArgString(""),
4448          "args": func.MakeOriginalArgString(""),
4449        })
4450
4451  def WriteImmediateFormatTest(self, func, file):
4452    """Overrriden from TypeHandler."""
4453    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
4454    file.Write("  static GLuint ids[] = { 12, 23, 34, };\n")
4455    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
4456               (func.name, func.name))
4457    file.Write("  void* next_cmd = cmd.Set(\n")
4458    file.Write("      &cmd, static_cast<GLsizei>(arraysize(ids)), ids);\n")
4459    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
4460               func.name)
4461    file.Write("            cmd.header.command);\n")
4462    file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
4463    file.Write("            RoundSizeToMultipleOfEntries(cmd.n * 4u),\n")
4464    file.Write("            cmd.header.size * 4u);\n")
4465    file.Write("  EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);\n");
4466    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
4467    file.Write("      next_cmd, sizeof(cmd) +\n")
4468    file.Write("      RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));\n")
4469    file.Write("  // TODO(gman): Check that ids were inserted;\n")
4470    file.Write("}\n")
4471    file.Write("\n")
4472
4473
4474class GETnHandler(TypeHandler):
4475  """Handler for GETn for glGetBooleanv, glGetFloatv, ... type functions."""
4476
4477  def __init__(self):
4478    TypeHandler.__init__(self)
4479
4480  def AddImmediateFunction(self, generator, func):
4481    """Overrriden from TypeHandler."""
4482    pass
4483
4484  def WriteServiceImplementation(self, func, file):
4485    """Overrriden from TypeHandler."""
4486    file.Write(
4487        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
4488    file.Write(
4489        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
4490        func.name)
4491    last_arg = func.GetLastOriginalArg()
4492
4493    all_but_last_args = func.GetOriginalArgs()[:-1]
4494    for arg in all_but_last_args:
4495      arg.WriteGetCode(file)
4496
4497    code = """  typedef cmds::%(func_name)s::Result Result;
4498  GLsizei num_values = 0;
4499  GetNumValuesReturnedForGLGet(pname, &num_values);
4500  Result* result = GetSharedMemoryAs<Result*>(
4501      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
4502  %(last_arg_type)s params = result ? result->GetData() : NULL;
4503"""
4504    file.Write(code % {
4505        'last_arg_type': last_arg.type,
4506        'func_name': func.name,
4507      })
4508    func.WriteHandlerValidation(file)
4509    code = """  // Check that the client initialized the result.
4510  if (result->size != 0) {
4511    return error::kInvalidArguments;
4512  }
4513"""
4514    shadowed = func.GetInfo('shadowed')
4515    if not shadowed:
4516      file.Write('  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("%s");\n' % func.name)
4517    file.Write(code)
4518    func.WriteHandlerImplementation(file)
4519    if shadowed:
4520      code = """  result->SetNumResults(num_values);
4521  return error::kNoError;
4522}
4523"""
4524    else:
4525     code = """  GLenum error = glGetError();
4526  if (error == GL_NO_ERROR) {
4527    result->SetNumResults(num_values);
4528  } else {
4529    LOCAL_SET_GL_ERROR(error, "%(func_name)s", "");
4530  }
4531  return error::kNoError;
4532}
4533
4534"""
4535    file.Write(code % {'func_name': func.name})
4536
4537  def WriteGLES2Implementation(self, func, file):
4538    """Overrriden from TypeHandler."""
4539    impl_decl = func.GetInfo('impl_decl')
4540    if impl_decl == None or impl_decl == True:
4541      file.Write("%s GLES2Implementation::%s(%s) {\n" %
4542                 (func.return_type, func.original_name,
4543                  func.MakeTypedOriginalArgString("")))
4544      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4545      func.WriteDestinationInitalizationValidation(file)
4546      self.WriteClientGLCallLog(func, file)
4547      for arg in func.GetOriginalArgs():
4548        arg.WriteClientSideValidationCode(file, func)
4549      all_but_last_args = func.GetOriginalArgs()[:-1]
4550      arg_string = (
4551          ", ".join(["%s" % arg.name for arg in all_but_last_args]))
4552      all_arg_string = (
4553          ", ".join(["%s" % arg.name for arg in func.GetOriginalArgs()]))
4554      self.WriteTraceEvent(func, file)
4555      code = """  if (%(func_name)sHelper(%(all_arg_string)s)) {
4556    return;
4557  }
4558  typedef cmds::%(func_name)s::Result Result;
4559  Result* result = GetResultAs<Result*>();
4560  if (!result) {
4561    return;
4562  }
4563  result->SetNumResults(0);
4564  helper_->%(func_name)s(%(arg_string)s,
4565      GetResultShmId(), GetResultShmOffset());
4566  WaitForCmd();
4567  result->CopyResult(params);
4568  GPU_CLIENT_LOG_CODE_BLOCK({
4569    for (int32 i = 0; i < result->GetNumResults(); ++i) {
4570      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
4571    }
4572  });
4573  CheckGLError();
4574}
4575"""
4576      file.Write(code % {
4577          'func_name': func.name,
4578          'arg_string': arg_string,
4579          'all_arg_string': all_arg_string,
4580        })
4581
4582  def WriteGLES2ImplementationUnitTest(self, func, file):
4583    """Writes the GLES2 Implemention unit test."""
4584    code = """
4585TEST_F(GLES2ImplementationTest, %(name)s) {
4586  struct Cmds {
4587    cmds::%(name)s cmd;
4588  };
4589  typedef cmds::%(name)s::Result Result;
4590  Result::Type result = 0;
4591  Cmds expected;
4592  ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
4593  expected.cmd.Init(%(cmd_args)s, result1.id, result1.offset);
4594  EXPECT_CALL(*command_buffer(), OnFlush())
4595      .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
4596      .RetiresOnSaturation();
4597  gl_->%(name)s(%(args)s, &result);
4598  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
4599  EXPECT_EQ(static_cast<Result::Type>(1), result);
4600}
4601"""
4602    cmd_arg_strings = []
4603    for count, arg in enumerate(func.GetCmdArgs()[0:-2]):
4604      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
4605    cmd_arg_strings[0] = '123'
4606    gl_arg_strings = []
4607    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
4608      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
4609    gl_arg_strings[0] = '123'
4610    file.Write(code % {
4611          'name': func.name,
4612          'args': ", ".join(gl_arg_strings),
4613          'cmd_args': ", ".join(cmd_arg_strings),
4614        })
4615
4616  def WriteServiceUnitTest(self, func, file):
4617    """Overrriden from TypeHandler."""
4618    valid_test = """
4619TEST_F(%(test_name)s, %(name)sValidArgs) {
4620  EXPECT_CALL(*gl_, GetError())
4621      .WillOnce(Return(GL_NO_ERROR))
4622      .WillOnce(Return(GL_NO_ERROR))
4623      .RetiresOnSaturation();
4624  SpecializedSetup<cmds::%(name)s, 0>(true);
4625  typedef cmds::%(name)s::Result Result;
4626  Result* result = static_cast<Result*>(shared_memory_address_);
4627  EXPECT_CALL(*gl_, %(gl_func_name)s(%(local_gl_args)s));
4628  result->size = 0;
4629  cmds::%(name)s cmd;
4630  cmd.Init(%(args)s);
4631  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4632  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
4633                %(valid_pname)s),
4634            result->GetNumResults());
4635  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4636}
4637"""
4638    gl_arg_strings = []
4639    valid_pname = ''
4640    for count, arg in enumerate(func.GetOriginalArgs()[:-1]):
4641      arg_value = arg.GetValidGLArg(func, count, 0)
4642      gl_arg_strings.append(arg_value)
4643      if arg.name == 'pname':
4644        valid_pname = arg_value
4645    if func.GetInfo('gl_test_func') == 'glGetIntegerv':
4646      gl_arg_strings.append("_")
4647    else:
4648      gl_arg_strings.append("result->GetData()")
4649
4650    self.WriteValidUnitTest(func, file, valid_test, {
4651        'local_gl_args': ", ".join(gl_arg_strings),
4652        'valid_pname': valid_pname,
4653      })
4654
4655    invalid_test = """
4656TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4657  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
4658  SpecializedSetup<cmds::%(name)s, 0>(false);
4659  cmds::%(name)s::Result* result =
4660      static_cast<cmds::%(name)s::Result*>(shared_memory_address_);
4661  result->size = 0;
4662  cmds::%(name)s cmd;
4663  cmd.Init(%(args)s);
4664  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));
4665  EXPECT_EQ(0u, result->size);%(gl_error_test)s
4666}
4667"""
4668    self.WriteInvalidUnitTest(func, file, invalid_test)
4669
4670
4671class PUTHandler(TypeHandler):
4672  """Handler for glTexParameter_v, glVertexAttrib_v functions."""
4673
4674  def __init__(self):
4675    TypeHandler.__init__(self)
4676
4677  def WriteServiceUnitTest(self, func, file):
4678    """Writes the service unit test for a command."""
4679    expected_call = "EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));"
4680    if func.GetInfo("first_element_only"):
4681      gl_arg_strings = []
4682      for count, arg in enumerate(func.GetOriginalArgs()):
4683        gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
4684      gl_arg_strings[-1] = "*" + gl_arg_strings[-1]
4685      expected_call = ("EXPECT_CALL(*gl_, %%(gl_func_name)s(%s));" %
4686          ", ".join(gl_arg_strings))
4687    valid_test = """
4688TEST_F(%(test_name)s, %(name)sValidArgs) {
4689  SpecializedSetup<cmds::%(name)s, 0>(true);
4690  cmds::%(name)s cmd;
4691  cmd.Init(%(args)s);
4692  GetSharedMemoryAs<%(data_type)s*>()[0] = %(data_value)s;
4693  %(expected_call)s
4694  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4695  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4696}
4697"""
4698    extra = {
4699      'data_type': func.GetInfo('data_type'),
4700      'data_value': func.GetInfo('data_value') or '0',
4701      'expected_call': expected_call,
4702    }
4703    self.WriteValidUnitTest(func, file, valid_test, extra)
4704
4705    invalid_test = """
4706TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4707  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
4708  SpecializedSetup<cmds::%(name)s, 0>(false);
4709  cmds::%(name)s cmd;
4710  cmd.Init(%(args)s);
4711  GetSharedMemoryAs<%(data_type)s*>()[0] = %(data_value)s;
4712  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
4713}
4714"""
4715    self.WriteInvalidUnitTest(func, file, invalid_test, extra)
4716
4717  def WriteImmediateServiceUnitTest(self, func, file):
4718    """Writes the service unit test for a command."""
4719    valid_test = """
4720TEST_F(%(test_name)s, %(name)sValidArgs) {
4721  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4722  SpecializedSetup<cmds::%(name)s, 0>(true);
4723  %(data_type)s temp[%(data_count)s] = { %(data_value)s, };
4724  cmd.Init(%(gl_args)s, &temp[0]);
4725  EXPECT_CALL(
4726      *gl_,
4727      %(gl_func_name)s(%(gl_args)s, %(data_ref)sreinterpret_cast<
4728          %(data_type)s*>(ImmediateDataAddress(&cmd))));
4729  EXPECT_EQ(error::kNoError,
4730            ExecuteImmediateCmd(cmd, sizeof(temp)));
4731  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4732}
4733"""
4734    gl_arg_strings = []
4735    gl_any_strings = []
4736    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
4737      gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
4738      gl_any_strings.append("_")
4739    extra = {
4740      'data_ref': ("*" if func.GetInfo('first_element_only') else ""),
4741      'data_type': func.GetInfo('data_type'),
4742      'data_count': func.GetInfo('count'),
4743      'data_value': func.GetInfo('data_value') or '0',
4744      'gl_args': ", ".join(gl_arg_strings),
4745      'gl_any_args': ", ".join(gl_any_strings),
4746    }
4747    self.WriteValidUnitTest(func, file, valid_test, extra)
4748
4749    invalid_test = """
4750TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4751  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4752  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
4753  SpecializedSetup<cmds::%(name)s, 0>(false);
4754  %(data_type)s temp[%(data_count)s] = { %(data_value)s, };
4755  cmd.Init(%(all_but_last_args)s, &temp[0]);
4756  EXPECT_EQ(error::%(parse_result)s,
4757            ExecuteImmediateCmd(cmd, sizeof(temp)));%(gl_error_test)s
4758}
4759"""
4760    self.WriteInvalidUnitTest(func, file, invalid_test, extra)
4761
4762  def WriteGetDataSizeCode(self, func, file):
4763    """Overrriden from TypeHandler."""
4764    code = """  uint32 data_size;
4765  if (!ComputeDataSize(1, sizeof(%s), %d, &data_size)) {
4766    return error::kOutOfBounds;
4767  }
4768"""
4769    file.Write(code % (func.info.data_type, func.info.count))
4770    if func.is_immediate:
4771      file.Write("  if (data_size > immediate_data_size) {\n")
4772      file.Write("    return error::kOutOfBounds;\n")
4773      file.Write("  }\n")
4774
4775  def WriteGLES2Implementation(self, func, file):
4776    """Overrriden from TypeHandler."""
4777    impl_func = func.GetInfo('impl_func')
4778    if (impl_func != None and impl_func != True):
4779      return;
4780    file.Write("%s GLES2Implementation::%s(%s) {\n" %
4781               (func.return_type, func.original_name,
4782                func.MakeTypedOriginalArgString("")))
4783    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4784    func.WriteDestinationInitalizationValidation(file)
4785    self.WriteClientGLCallLog(func, file)
4786    last_arg_name = func.GetLastOriginalArg().name
4787    values_str = ' << ", " << '.join(
4788        ["%s[%d]" % (last_arg_name, ndx) for ndx in range(0, func.info.count)])
4789    file.Write('  GPU_CLIENT_LOG("values: " << %s);\n' % values_str)
4790    for arg in func.GetOriginalArgs():
4791      arg.WriteClientSideValidationCode(file, func)
4792    file.Write("  helper_->%sImmediate(%s);\n" %
4793               (func.name, func.MakeOriginalArgString("")))
4794    file.Write("  CheckGLError();\n")
4795    file.Write("}\n")
4796    file.Write("\n")
4797
4798  def WriteGLES2ImplementationUnitTest(self, func, file):
4799    """Writes the GLES2 Implemention unit test."""
4800    client_test = func.GetInfo('client_test')
4801    if (client_test != None and client_test != True):
4802      return;
4803    code = """
4804TEST_F(GLES2ImplementationTest, %(name)s) {
4805  %(type)s data[%(count)d] = {0};
4806  struct Cmds {
4807    cmds::%(name)sImmediate cmd;
4808    %(type)s data[%(count)d];
4809  };
4810
4811  for (int jj = 0; jj < %(count)d; ++jj) {
4812    data[jj] = static_cast<%(type)s>(jj);
4813  }
4814  Cmds expected;
4815  expected.cmd.Init(%(cmd_args)s, &data[0]);
4816  gl_->%(name)s(%(args)s, &data[0]);
4817  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
4818}
4819"""
4820    cmd_arg_strings = []
4821    for count, arg in enumerate(func.GetCmdArgs()[0:-2]):
4822      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
4823    gl_arg_strings = []
4824    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
4825      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
4826    file.Write(code % {
4827          'name': func.name,
4828          'type': func.GetInfo('data_type'),
4829          'count': func.GetInfo('count'),
4830          'args': ", ".join(gl_arg_strings),
4831          'cmd_args': ", ".join(cmd_arg_strings),
4832        })
4833
4834  def WriteImmediateCmdComputeSize(self, func, file):
4835    """Overrriden from TypeHandler."""
4836    file.Write("  static uint32 ComputeDataSize() {\n")
4837    file.Write("    return static_cast<uint32>(\n")
4838    file.Write("        sizeof(%s) * %d);  // NOLINT\n" %
4839               (func.info.data_type, func.info.count))
4840    file.Write("  }\n")
4841    file.Write("\n")
4842    file.Write("  static uint32 ComputeSize() {\n")
4843    file.Write("    return static_cast<uint32>(\n")
4844    file.Write(
4845        "        sizeof(ValueType) + ComputeDataSize());  // NOLINT\n")
4846    file.Write("  }\n")
4847    file.Write("\n")
4848
4849  def WriteImmediateCmdSetHeader(self, func, file):
4850    """Overrriden from TypeHandler."""
4851    file.Write("  void SetHeader() {\n")
4852    file.Write(
4853        "    header.SetCmdByTotalSize<ValueType>(ComputeSize());\n")
4854    file.Write("  }\n")
4855    file.Write("\n")
4856
4857  def WriteImmediateCmdInit(self, func, file):
4858    """Overrriden from TypeHandler."""
4859    last_arg = func.GetLastOriginalArg()
4860    file.Write("  void Init(%s, %s _%s) {\n" %
4861               (func.MakeTypedCmdArgString("_"),
4862                last_arg.type, last_arg.name))
4863    file.Write("    SetHeader();\n")
4864    args = func.GetCmdArgs()
4865    for arg in args:
4866      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
4867    file.Write("    memcpy(ImmediateDataAddress(this),\n")
4868    file.Write("           _%s, ComputeDataSize());\n" % last_arg.name)
4869    file.Write("  }\n")
4870    file.Write("\n")
4871
4872  def WriteImmediateCmdSet(self, func, file):
4873    """Overrriden from TypeHandler."""
4874    last_arg = func.GetLastOriginalArg()
4875    copy_args = func.MakeCmdArgString("_", False)
4876    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
4877               (func.MakeTypedCmdArgString("_", True),
4878                last_arg.type, last_arg.name))
4879    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
4880               (copy_args, last_arg.name))
4881    file.Write("    const uint32 size = ComputeSize();\n")
4882    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
4883               "cmd, size);\n")
4884    file.Write("  }\n")
4885    file.Write("\n")
4886
4887  def WriteImmediateCmdHelper(self, func, file):
4888    """Overrriden from TypeHandler."""
4889    code = """  void %(name)s(%(typed_args)s) {
4890    const uint32 size = gles2::cmds::%(name)s::ComputeSize();
4891    gles2::cmds::%(name)s* c =
4892        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
4893    if (c) {
4894      c->Init(%(args)s);
4895    }
4896  }
4897
4898"""
4899    file.Write(code % {
4900          "name": func.name,
4901          "typed_args": func.MakeTypedOriginalArgString(""),
4902          "args": func.MakeOriginalArgString(""),
4903        })
4904
4905  def WriteImmediateFormatTest(self, func, file):
4906    """Overrriden from TypeHandler."""
4907    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
4908    file.Write("  const int kSomeBaseValueToTestWith = 51;\n")
4909    file.Write("  static %s data[] = {\n" % func.info.data_type)
4910    for v in range(0, func.info.count):
4911      file.Write("    static_cast<%s>(kSomeBaseValueToTestWith + %d),\n" %
4912                 (func.info.data_type, v))
4913    file.Write("  };\n")
4914    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
4915               (func.name, func.name))
4916    file.Write("  void* next_cmd = cmd.Set(\n")
4917    file.Write("      &cmd")
4918    args = func.GetCmdArgs()
4919    for value, arg in enumerate(args):
4920      file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 11))
4921    file.Write(",\n      data);\n")
4922    args = func.GetCmdArgs()
4923    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n"
4924               % func.name)
4925    file.Write("            cmd.header.command);\n")
4926    file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
4927    file.Write("            RoundSizeToMultipleOfEntries(sizeof(data)),\n")
4928    file.Write("            cmd.header.size * 4u);\n")
4929    for value, arg in enumerate(args):
4930      file.Write("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" %
4931                 (arg.type, value + 11, arg.name))
4932    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
4933    file.Write("      next_cmd, sizeof(cmd) +\n")
4934    file.Write("      RoundSizeToMultipleOfEntries(sizeof(data)));\n")
4935    file.Write("  // TODO(gman): Check that data was inserted;\n")
4936    file.Write("}\n")
4937    file.Write("\n")
4938
4939
4940class PUTnHandler(TypeHandler):
4941  """Handler for PUTn 'glUniform__v' type functions."""
4942
4943  def __init__(self):
4944    TypeHandler.__init__(self)
4945
4946  def WriteServiceUnitTest(self, func, file):
4947    """Overridden from TypeHandler."""
4948    TypeHandler.WriteServiceUnitTest(self, func, file)
4949
4950    valid_test = """
4951TEST_F(%(test_name)s, %(name)sValidArgsCountTooLarge) {
4952  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
4953  SpecializedSetup<cmds::%(name)s, 0>(true);
4954  cmds::%(name)s cmd;
4955  cmd.Init(%(args)s);
4956  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4957  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4958}
4959"""
4960    gl_arg_strings = []
4961    arg_strings = []
4962    for count, arg in enumerate(func.GetOriginalArgs()):
4963      # hardcoded to match unit tests.
4964      if count == 0:
4965        # the location of the second element of the 2nd uniform.
4966        # defined in GLES2DecoderBase::SetupShaderForUniform
4967        gl_arg_strings.append("3")
4968        arg_strings.append("ProgramManager::MakeFakeLocation(1, 1)")
4969      elif count == 1:
4970        # the number of elements that gl will be called with.
4971        gl_arg_strings.append("3")
4972        # the number of elements requested in the command.
4973        arg_strings.append("5")
4974      else:
4975        gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
4976        arg_strings.append(arg.GetValidArg(func, count, 0))
4977    extra = {
4978      'gl_args': ", ".join(gl_arg_strings),
4979      'args': ", ".join(arg_strings),
4980    }
4981    self.WriteValidUnitTest(func, file, valid_test, extra)
4982
4983  def WriteImmediateServiceUnitTest(self, func, file):
4984    """Overridden from TypeHandler."""
4985    valid_test = """
4986TEST_F(%(test_name)s, %(name)sValidArgs) {
4987  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4988  EXPECT_CALL(
4989      *gl_,
4990      %(gl_func_name)s(%(gl_args)s,
4991          reinterpret_cast<%(data_type)s*>(ImmediateDataAddress(&cmd))));
4992  SpecializedSetup<cmds::%(name)s, 0>(true);
4993  %(data_type)s temp[%(data_count)s * 2] = { 0, };
4994  cmd.Init(%(args)s, &temp[0]);
4995  EXPECT_EQ(error::kNoError,
4996            ExecuteImmediateCmd(cmd, sizeof(temp)));
4997  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4998}
4999"""
5000    gl_arg_strings = []
5001    gl_any_strings = []
5002    arg_strings = []
5003    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
5004      gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
5005      gl_any_strings.append("_")
5006      arg_strings.append(arg.GetValidArg(func, count, 0))
5007    extra = {
5008      'data_type': func.GetInfo('data_type'),
5009      'data_count': func.GetInfo('count'),
5010      'args': ", ".join(arg_strings),
5011      'gl_args': ", ".join(gl_arg_strings),
5012      'gl_any_args': ", ".join(gl_any_strings),
5013    }
5014    self.WriteValidUnitTest(func, file, valid_test, extra)
5015
5016    invalid_test = """
5017TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
5018  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
5019  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
5020  SpecializedSetup<cmds::%(name)s, 0>(false);
5021  %(data_type)s temp[%(data_count)s * 2] = { 0, };
5022  cmd.Init(%(all_but_last_args)s, &temp[0]);
5023  EXPECT_EQ(error::%(parse_result)s,
5024            ExecuteImmediateCmd(cmd, sizeof(temp)));%(gl_error_test)s
5025}
5026"""
5027    self.WriteInvalidUnitTest(func, file, invalid_test, extra)
5028
5029  def WriteGetDataSizeCode(self, func, file):
5030    """Overrriden from TypeHandler."""
5031    code = """  uint32 data_size;
5032  if (!ComputeDataSize(count, sizeof(%s), %d, &data_size)) {
5033    return error::kOutOfBounds;
5034  }
5035"""
5036    file.Write(code % (func.info.data_type, func.info.count))
5037    if func.is_immediate:
5038      file.Write("  if (data_size > immediate_data_size) {\n")
5039      file.Write("    return error::kOutOfBounds;\n")
5040      file.Write("  }\n")
5041
5042  def WriteGLES2Implementation(self, func, file):
5043    """Overrriden from TypeHandler."""
5044    file.Write("%s GLES2Implementation::%s(%s) {\n" %
5045               (func.return_type, func.original_name,
5046                func.MakeTypedOriginalArgString("")))
5047    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
5048    func.WriteDestinationInitalizationValidation(file)
5049    self.WriteClientGLCallLog(func, file)
5050    last_arg_name = func.GetLastOriginalArg().name
5051    file.Write("""  GPU_CLIENT_LOG_CODE_BLOCK({
5052    for (GLsizei i = 0; i < count; ++i) {
5053""")
5054    values_str = ' << ", " << '.join(
5055        ["%s[%d + i * %d]" % (
5056            last_arg_name, ndx, func.info.count) for ndx in range(
5057                0, func.info.count)])
5058    file.Write('       GPU_CLIENT_LOG("  " << i << ": " << %s);\n' % values_str)
5059    file.Write("    }\n  });\n")
5060    for arg in func.GetOriginalArgs():
5061      arg.WriteClientSideValidationCode(file, func)
5062    file.Write("  helper_->%sImmediate(%s);\n" %
5063               (func.name, func.MakeOriginalArgString("")))
5064    file.Write("  CheckGLError();\n")
5065    file.Write("}\n")
5066    file.Write("\n")
5067
5068  def WriteGLES2ImplementationUnitTest(self, func, file):
5069    """Writes the GLES2 Implemention unit test."""
5070    code = """
5071TEST_F(GLES2ImplementationTest, %(name)s) {
5072  %(type)s data[%(count_param)d][%(count)d] = {{0}};
5073  struct Cmds {
5074    cmds::%(name)sImmediate cmd;
5075    %(type)s data[%(count_param)d][%(count)d];
5076  };
5077
5078  Cmds expected;
5079  for (int ii = 0; ii < %(count_param)d; ++ii) {
5080    for (int jj = 0; jj < %(count)d; ++jj) {
5081      data[ii][jj] = static_cast<%(type)s>(ii * %(count)d + jj);
5082    }
5083  }
5084  expected.cmd.Init(%(cmd_args)s, &data[0][0]);
5085  gl_->%(name)s(%(args)s, &data[0][0]);
5086  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
5087}
5088"""
5089    cmd_arg_strings = []
5090    for count, arg in enumerate(func.GetCmdArgs()[0:-2]):
5091      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
5092    gl_arg_strings = []
5093    count_param = 0
5094    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
5095      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
5096      if arg.name == "count":
5097        count_param = int(arg.GetValidClientSideArg(func, count, 0))
5098    file.Write(code % {
5099          'name': func.name,
5100          'type': func.GetInfo('data_type'),
5101          'count': func.GetInfo('count'),
5102          'args': ", ".join(gl_arg_strings),
5103          'cmd_args': ", ".join(cmd_arg_strings),
5104          'count_param': count_param,
5105        })
5106
5107  def WriteImmediateCmdComputeSize(self, func, file):
5108    """Overrriden from TypeHandler."""
5109    file.Write("  static uint32 ComputeDataSize(GLsizei count) {\n")
5110    file.Write("    return static_cast<uint32>(\n")
5111    file.Write("        sizeof(%s) * %d * count);  // NOLINT\n" %
5112               (func.info.data_type, func.info.count))
5113    file.Write("  }\n")
5114    file.Write("\n")
5115    file.Write("  static uint32 ComputeSize(GLsizei count) {\n")
5116    file.Write("    return static_cast<uint32>(\n")
5117    file.Write(
5118        "        sizeof(ValueType) + ComputeDataSize(count));  // NOLINT\n")
5119    file.Write("  }\n")
5120    file.Write("\n")
5121
5122  def WriteImmediateCmdSetHeader(self, func, file):
5123    """Overrriden from TypeHandler."""
5124    file.Write("  void SetHeader(GLsizei count) {\n")
5125    file.Write(
5126        "    header.SetCmdByTotalSize<ValueType>(ComputeSize(count));\n")
5127    file.Write("  }\n")
5128    file.Write("\n")
5129
5130  def WriteImmediateCmdInit(self, func, file):
5131    """Overrriden from TypeHandler."""
5132    last_arg = func.GetLastOriginalArg()
5133    file.Write("  void Init(%s, %s _%s) {\n" %
5134               (func.MakeTypedCmdArgString("_"),
5135                last_arg.type, last_arg.name))
5136    file.Write("    SetHeader(_count);\n")
5137    args = func.GetCmdArgs()
5138    for arg in args:
5139      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
5140    file.Write("    memcpy(ImmediateDataAddress(this),\n")
5141    file.Write("           _%s, ComputeDataSize(_count));\n" % last_arg.name)
5142    file.Write("  }\n")
5143    file.Write("\n")
5144
5145  def WriteImmediateCmdSet(self, func, file):
5146    """Overrriden from TypeHandler."""
5147    last_arg = func.GetLastOriginalArg()
5148    copy_args = func.MakeCmdArgString("_", False)
5149    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
5150               (func.MakeTypedCmdArgString("_", True),
5151                last_arg.type, last_arg.name))
5152    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
5153               (copy_args, last_arg.name))
5154    file.Write("    const uint32 size = ComputeSize(_count);\n")
5155    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
5156               "cmd, size);\n")
5157    file.Write("  }\n")
5158    file.Write("\n")
5159
5160  def WriteImmediateCmdHelper(self, func, file):
5161    """Overrriden from TypeHandler."""
5162    code = """  void %(name)s(%(typed_args)s) {
5163    const uint32 size = gles2::cmds::%(name)s::ComputeSize(count);
5164    gles2::cmds::%(name)s* c =
5165        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
5166    if (c) {
5167      c->Init(%(args)s);
5168    }
5169  }
5170
5171"""
5172    file.Write(code % {
5173          "name": func.name,
5174          "typed_args": func.MakeTypedOriginalArgString(""),
5175          "args": func.MakeOriginalArgString(""),
5176        })
5177
5178  def WriteImmediateFormatTest(self, func, file):
5179    """Overrriden from TypeHandler."""
5180    args = func.GetCmdArgs()
5181    count_param = 0
5182    for value, arg in enumerate(args):
5183      if arg.name == "count":
5184        count_param = int(arg.GetValidClientSideArg(func, value, 0))
5185    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
5186    file.Write("  const int kSomeBaseValueToTestWith = 51;\n")
5187    file.Write("  static %s data[] = {\n" % func.info.data_type)
5188    for v in range(0, func.info.count * count_param):
5189      file.Write("    static_cast<%s>(kSomeBaseValueToTestWith + %d),\n" %
5190                 (func.info.data_type, v))
5191    file.Write("  };\n")
5192    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
5193               (func.name, func.name))
5194    file.Write("  const GLsizei kNumElements = %d;\n" % count_param)
5195    file.Write("  const size_t kExpectedCmdSize =\n")
5196    file.Write("      sizeof(cmd) + kNumElements * sizeof(%s) * %d;\n" %
5197               (func.info.data_type, func.info.count))
5198    file.Write("  void* next_cmd = cmd.Set(\n")
5199    file.Write("      &cmd")
5200    for value, arg in enumerate(args):
5201      file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 1))
5202    file.Write(",\n      data);\n")
5203    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
5204               func.name)
5205    file.Write("            cmd.header.command);\n")
5206    file.Write("  EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);\n")
5207    for value, arg in enumerate(args):
5208      file.Write("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" %
5209                 (arg.type, value + 1, arg.name))
5210    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
5211    file.Write("      next_cmd, sizeof(cmd) +\n")
5212    file.Write("      RoundSizeToMultipleOfEntries(sizeof(data)));\n")
5213    file.Write("  // TODO(gman): Check that data was inserted;\n")
5214    file.Write("}\n")
5215    file.Write("\n")
5216
5217
5218class PUTXnHandler(TypeHandler):
5219  """Handler for glUniform?f functions."""
5220  def __init__(self):
5221    TypeHandler.__init__(self)
5222
5223  def WriteHandlerImplementation(self, func, file):
5224    """Overrriden from TypeHandler."""
5225    code = """  %(type)s temp[%(count)s] = { %(values)s};
5226  Do%(name)sv(%(location)s, 1, &temp[0]);
5227"""
5228    values = ""
5229    args = func.GetOriginalArgs()
5230    count = int(func.GetInfo('count'))
5231    num_args = len(args)
5232    for ii in range(count):
5233      values += "%s, " % args[len(args) - count + ii].name
5234
5235    file.Write(code % {
5236        'name': func.name,
5237        'count': func.GetInfo('count'),
5238        'type': func.GetInfo('data_type'),
5239        'location': args[0].name,
5240        'args': func.MakeOriginalArgString(""),
5241        'values': values,
5242      })
5243
5244  def WriteServiceUnitTest(self, func, file):
5245    """Overrriden from TypeHandler."""
5246    valid_test = """
5247TEST_F(%(test_name)s, %(name)sValidArgs) {
5248  EXPECT_CALL(*gl_, %(name)sv(%(local_args)s));
5249  SpecializedSetup<cmds::%(name)s, 0>(true);
5250  cmds::%(name)s cmd;
5251  cmd.Init(%(args)s);
5252  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5253  EXPECT_EQ(GL_NO_ERROR, GetGLError());
5254}
5255"""
5256    args = func.GetOriginalArgs()
5257    local_args = "%s, 1, _" % args[0].GetValidGLArg(func, 0, 0)
5258    self.WriteValidUnitTest(func, file, valid_test, {
5259        'name': func.name,
5260        'count': func.GetInfo('count'),
5261        'local_args': local_args,
5262      })
5263
5264    invalid_test = """
5265TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
5266  EXPECT_CALL(*gl_, %(name)sv(_, _, _).Times(0);
5267  SpecializedSetup<cmds::%(name)s, 0>(false);
5268  cmds::%(name)s cmd;
5269  cmd.Init(%(args)s);
5270  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
5271}
5272"""
5273    self.WriteInvalidUnitTest(func, file, invalid_test, {
5274        'name': func.GetInfo('name'),
5275        'count': func.GetInfo('count'),
5276      })
5277
5278
5279class GLcharHandler(CustomHandler):
5280  """Handler for functions that pass a single string ."""
5281
5282  def __init__(self):
5283    CustomHandler.__init__(self)
5284
5285  def WriteImmediateCmdComputeSize(self, func, file):
5286    """Overrriden from TypeHandler."""
5287    file.Write("  static uint32 ComputeSize(uint32 data_size) {\n")
5288    file.Write("    return static_cast<uint32>(\n")
5289    file.Write("        sizeof(ValueType) + data_size);  // NOLINT\n")
5290    file.Write("  }\n")
5291
5292  def WriteImmediateCmdSetHeader(self, func, file):
5293    """Overrriden from TypeHandler."""
5294    code = """
5295  void SetHeader(uint32 data_size) {
5296    header.SetCmdBySize<ValueType>(data_size);
5297  }
5298"""
5299    file.Write(code)
5300
5301  def WriteImmediateCmdInit(self, func, file):
5302    """Overrriden from TypeHandler."""
5303    last_arg = func.GetLastOriginalArg()
5304    args = func.GetCmdArgs()
5305    set_code = []
5306    for arg in args:
5307      set_code.append("    %s = _%s;" % (arg.name, arg.name))
5308    code = """
5309  void Init(%(typed_args)s, uint32 _data_size) {
5310    SetHeader(_data_size);
5311%(set_code)s
5312    memcpy(ImmediateDataAddress(this), _%(last_arg)s, _data_size);
5313  }
5314
5315"""
5316    file.Write(code % {
5317          "typed_args": func.MakeTypedOriginalArgString("_"),
5318          "set_code": "\n".join(set_code),
5319          "last_arg": last_arg.name
5320        })
5321
5322  def WriteImmediateCmdSet(self, func, file):
5323    """Overrriden from TypeHandler."""
5324    last_arg = func.GetLastOriginalArg()
5325    file.Write("  void* Set(void* cmd%s, uint32 _data_size) {\n" %
5326               func.MakeTypedOriginalArgString("_", True))
5327    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _data_size);\n" %
5328               func.MakeOriginalArgString("_"))
5329    file.Write("    return NextImmediateCmdAddress<ValueType>("
5330               "cmd, _data_size);\n")
5331    file.Write("  }\n")
5332    file.Write("\n")
5333
5334  def WriteImmediateCmdHelper(self, func, file):
5335    """Overrriden from TypeHandler."""
5336    code = """  void %(name)s(%(typed_args)s) {
5337    const uint32 data_size = strlen(name);
5338    gles2::cmds::%(name)s* c =
5339        GetImmediateCmdSpace<gles2::cmds::%(name)s>(data_size);
5340    if (c) {
5341      c->Init(%(args)s, data_size);
5342    }
5343  }
5344
5345"""
5346    file.Write(code % {
5347          "name": func.name,
5348          "typed_args": func.MakeTypedOriginalArgString(""),
5349          "args": func.MakeOriginalArgString(""),
5350        })
5351
5352
5353  def WriteImmediateFormatTest(self, func, file):
5354    """Overrriden from TypeHandler."""
5355    init_code = []
5356    check_code = []
5357    all_but_last_arg = func.GetCmdArgs()[:-1]
5358    for value, arg in enumerate(all_but_last_arg):
5359      init_code.append("      static_cast<%s>(%d)," % (arg.type, value + 11))
5360    for value, arg in enumerate(all_but_last_arg):
5361      check_code.append("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);" %
5362                        (arg.type, value + 11, arg.name))
5363    code = """
5364TEST_F(GLES2FormatTest, %(func_name)s) {
5365  cmds::%(func_name)s& cmd = *GetBufferAs<cmds::%(func_name)s>();
5366  static const char* const test_str = \"test string\";
5367  void* next_cmd = cmd.Set(
5368      &cmd,
5369%(init_code)s
5370      test_str,
5371      strlen(test_str));
5372  EXPECT_EQ(static_cast<uint32>(cmds::%(func_name)s::kCmdId),
5373            cmd.header.command);
5374  EXPECT_EQ(sizeof(cmd) +
5375            RoundSizeToMultipleOfEntries(strlen(test_str)),
5376            cmd.header.size * 4u);
5377  EXPECT_EQ(static_cast<char*>(next_cmd),
5378            reinterpret_cast<char*>(&cmd) + sizeof(cmd) +
5379                RoundSizeToMultipleOfEntries(strlen(test_str)));
5380%(check_code)s
5381  EXPECT_EQ(static_cast<uint32>(strlen(test_str)), cmd.data_size);
5382  EXPECT_EQ(0, memcmp(test_str, ImmediateDataAddress(&cmd), strlen(test_str)));
5383  CheckBytesWritten(
5384      next_cmd,
5385      sizeof(cmd) + RoundSizeToMultipleOfEntries(strlen(test_str)),
5386      sizeof(cmd) + strlen(test_str));
5387}
5388
5389"""
5390    file.Write(code % {
5391          'func_name': func.name,
5392          'init_code': "\n".join(init_code),
5393          'check_code': "\n".join(check_code),
5394        })
5395
5396
5397class GLcharNHandler(CustomHandler):
5398  """Handler for functions that pass a single string with an optional len."""
5399
5400  def __init__(self):
5401    CustomHandler.__init__(self)
5402
5403  def InitFunction(self, func):
5404    """Overrriden from TypeHandler."""
5405    func.cmd_args = []
5406    func.AddCmdArg(Argument('bucket_id', 'GLuint'))
5407
5408  def AddImmediateFunction(self, generator, func):
5409    """Overrriden from TypeHandler."""
5410    pass
5411
5412  def AddBucketFunction(self, generator, func):
5413    """Overrriden from TypeHandler."""
5414    pass
5415
5416  def WriteServiceImplementation(self, func, file):
5417    """Overrriden from TypeHandler."""
5418    file.Write("""error::Error GLES2DecoderImpl::Handle%(name)s(
5419  uint32 immediate_data_size, const gles2::cmds::%(name)s& c) {
5420  GLuint bucket_id = static_cast<GLuint>(c.%(bucket_id)s);
5421  Bucket* bucket = GetBucket(bucket_id);
5422  if (!bucket || bucket->size() == 0) {
5423    return error::kInvalidArguments;
5424  }
5425  std::string str;
5426  if (!bucket->GetAsString(&str)) {
5427    return error::kInvalidArguments;
5428  }
5429  %(gl_func_name)s(0, str.c_str());
5430  return error::kNoError;
5431}
5432
5433""" % {
5434    'name': func.name,
5435    'gl_func_name': func.GetGLFunctionName(),
5436    'bucket_id': func.cmd_args[0].name,
5437  })
5438
5439
5440class IsHandler(TypeHandler):
5441  """Handler for glIs____ type and glGetError functions."""
5442
5443  def __init__(self):
5444    TypeHandler.__init__(self)
5445
5446  def InitFunction(self, func):
5447    """Overrriden from TypeHandler."""
5448    func.AddCmdArg(Argument("result_shm_id", 'uint32'))
5449    func.AddCmdArg(Argument("result_shm_offset", 'uint32'))
5450    if func.GetInfo('result') == None:
5451      func.AddInfo('result', ['uint32'])
5452
5453  def WriteServiceUnitTest(self, func, file):
5454    """Overrriden from TypeHandler."""
5455    valid_test = """
5456TEST_F(%(test_name)s, %(name)sValidArgs) {
5457  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
5458  SpecializedSetup<cmds::%(name)s, 0>(true);
5459  cmds::%(name)s cmd;
5460  cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);
5461  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5462  EXPECT_EQ(GL_NO_ERROR, GetGLError());
5463}
5464"""
5465    comma = ""
5466    if len(func.GetOriginalArgs()):
5467      comma =", "
5468    self.WriteValidUnitTest(func, file, valid_test, {
5469          'comma': comma,
5470        })
5471
5472    invalid_test = """
5473TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
5474  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
5475  SpecializedSetup<cmds::%(name)s, 0>(false);
5476  cmds::%(name)s cmd;
5477  cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);
5478  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
5479}
5480"""
5481    self.WriteInvalidUnitTest(func, file, invalid_test, {
5482          'comma': comma,
5483        })
5484
5485    invalid_test = """
5486TEST_F(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
5487  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
5488  SpecializedSetup<cmds::%(name)s, 0>(false);
5489  cmds::%(name)s cmd;
5490  cmd.Init(%(args)s%(comma)skInvalidSharedMemoryId, shared_memory_offset_);
5491  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
5492  cmd.Init(%(args)s%(comma)sshared_memory_id_, kInvalidSharedMemoryOffset);
5493  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
5494}
5495"""
5496    self.WriteValidUnitTest(func, file, invalid_test, {
5497          'comma': comma,
5498        })
5499
5500  def WriteServiceImplementation(self, func, file):
5501    """Overrriden from TypeHandler."""
5502    file.Write(
5503        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
5504    file.Write(
5505        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
5506        func.name)
5507    args = func.GetOriginalArgs()
5508    for arg in args:
5509      arg.WriteGetCode(file)
5510
5511    code = """  typedef cmds::%(func_name)s::Result Result;
5512  Result* result_dst = GetSharedMemoryAs<Result*>(
5513      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
5514  if (!result_dst) {
5515    return error::kOutOfBounds;
5516  }
5517"""
5518    file.Write(code % {'func_name': func.name})
5519    func.WriteHandlerValidation(file)
5520    file.Write("  *result_dst = %s(%s);\n" %
5521               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
5522    file.Write("  return error::kNoError;\n")
5523    file.Write("}\n")
5524    file.Write("\n")
5525
5526  def WriteGLES2Implementation(self, func, file):
5527    """Overrriden from TypeHandler."""
5528    impl_func = func.GetInfo('impl_func')
5529    if impl_func == None or impl_func == True:
5530      error_value = func.GetInfo("error_value") or "GL_FALSE"
5531      file.Write("%s GLES2Implementation::%s(%s) {\n" %
5532                 (func.return_type, func.original_name,
5533                  func.MakeTypedOriginalArgString("")))
5534      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
5535      self.WriteTraceEvent(func, file)
5536      func.WriteDestinationInitalizationValidation(file)
5537      self.WriteClientGLCallLog(func, file)
5538      file.Write("  typedef cmds::%s::Result Result;\n" % func.name)
5539      file.Write("  Result* result = GetResultAs<Result*>();\n")
5540      file.Write("  if (!result) {\n")
5541      file.Write("    return %s;\n" % error_value)
5542      file.Write("  }\n")
5543      file.Write("  *result = 0;\n")
5544      arg_string = func.MakeOriginalArgString("")
5545      comma = ""
5546      if len(arg_string) > 0:
5547        comma = ", "
5548      file.Write(
5549          "  helper_->%s(%s%sGetResultShmId(), GetResultShmOffset());\n" %
5550                 (func.name, arg_string, comma))
5551      file.Write("  WaitForCmd();\n")
5552      file.Write("  %s result_value = *result;\n" % func.return_type)
5553      file.Write('  GPU_CLIENT_LOG("returned " << result_value);\n')
5554      file.Write("  CheckGLError();\n")
5555      file.Write("  return result_value;\n")
5556      file.Write("}\n")
5557      file.Write("\n")
5558
5559  def WriteGLES2ImplementationUnitTest(self, func, file):
5560    """Overrriden from TypeHandler."""
5561    client_test = func.GetInfo('client_test')
5562    if client_test == None or client_test == True:
5563      code = """
5564TEST_F(GLES2ImplementationTest, %(name)s) {
5565  struct Cmds {
5566    cmds::%(name)s cmd;
5567  };
5568
5569  Cmds expected;
5570  ExpectedMemoryInfo result1 =
5571      GetExpectedResultMemory(sizeof(cmds::%(name)s::Result));
5572  expected.cmd.Init(1, result1.id, result1.offset);
5573
5574  EXPECT_CALL(*command_buffer(), OnFlush())
5575      .WillOnce(SetMemory(result1.ptr, uint32(1)))
5576      .RetiresOnSaturation();
5577
5578  GLboolean result = gl_->%(name)s(1);
5579  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
5580  EXPECT_TRUE(result);
5581}
5582"""
5583      file.Write(code % {
5584            'name': func.name,
5585          })
5586
5587
5588class STRnHandler(TypeHandler):
5589  """Handler for GetProgramInfoLog, GetShaderInfoLog, GetShaderSource, and
5590  GetTranslatedShaderSourceANGLE."""
5591
5592  def __init__(self):
5593    TypeHandler.__init__(self)
5594
5595  def InitFunction(self, func):
5596    """Overrriden from TypeHandler."""
5597    # remove all but the first cmd args.
5598    cmd_args = func.GetCmdArgs()
5599    func.ClearCmdArgs()
5600    func.AddCmdArg(cmd_args[0])
5601    # add on a bucket id.
5602    func.AddCmdArg(Argument('bucket_id', 'uint32'))
5603
5604  def WriteGLES2Implementation(self, func, file):
5605    """Overrriden from TypeHandler."""
5606    code_1 = """%(return_type)s GLES2Implementation::%(func_name)s(%(args)s) {
5607  GPU_CLIENT_SINGLE_THREAD_CHECK();
5608"""
5609    code_2 = """  GPU_CLIENT_LOG("[" << GetLogPrefix()
5610      << "] gl%(func_name)s" << "("
5611      << %(arg0)s << ", "
5612      << %(arg1)s << ", "
5613      << static_cast<void*>(%(arg2)s) << ", "
5614      << static_cast<void*>(%(arg3)s) << ")");
5615  helper_->SetBucketSize(kResultBucketId, 0);
5616  helper_->%(func_name)s(%(id_name)s, kResultBucketId);
5617  std::string str;
5618  GLsizei max_size = 0;
5619  if (GetBucketAsString(kResultBucketId, &str)) {
5620    if (bufsize > 0) {
5621      max_size =
5622          std::min(static_cast<size_t>(%(bufsize_name)s) - 1, str.size());
5623      memcpy(%(dest_name)s, str.c_str(), max_size);
5624      %(dest_name)s[max_size] = '\\0';
5625      GPU_CLIENT_LOG("------\\n" << %(dest_name)s << "\\n------");
5626    }
5627  }
5628  if (%(length_name)s != NULL) {
5629    *%(length_name)s = max_size;
5630  }
5631  CheckGLError();
5632}
5633"""
5634    args = func.GetOriginalArgs()
5635    str_args = {
5636      'return_type': func.return_type,
5637      'func_name': func.original_name,
5638      'args': func.MakeTypedOriginalArgString(""),
5639      'id_name': args[0].name,
5640      'bufsize_name': args[1].name,
5641      'length_name': args[2].name,
5642      'dest_name': args[3].name,
5643      'arg0': args[0].name,
5644      'arg1': args[1].name,
5645      'arg2': args[2].name,
5646      'arg3': args[3].name,
5647    }
5648    file.Write(code_1 % str_args)
5649    func.WriteDestinationInitalizationValidation(file)
5650    file.Write(code_2 % str_args)
5651
5652  def WriteServiceUnitTest(self, func, file):
5653    """Overrriden from TypeHandler."""
5654    valid_test = """
5655TEST_F(%(test_name)s, %(name)sValidArgs) {
5656  const char* kInfo = "hello";
5657  const uint32 kBucketId = 123;
5658  SpecializedSetup<cmds::%(name)s, 0>(true);
5659%(expect_len_code)s
5660  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
5661      .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
5662                      SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1)));
5663  cmds::%(name)s cmd;
5664  cmd.Init(%(args)s);
5665  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5666  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
5667  ASSERT_TRUE(bucket != NULL);
5668  EXPECT_EQ(strlen(kInfo) + 1, bucket->size());
5669  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kInfo,
5670                      bucket->size()));
5671  EXPECT_EQ(GL_NO_ERROR, GetGLError());
5672}
5673"""
5674    args = func.GetOriginalArgs()
5675    id_name = args[0].GetValidGLArg(func, 0, 0)
5676    get_len_func = func.GetInfo('get_len_func')
5677    get_len_enum = func.GetInfo('get_len_enum')
5678    sub = {
5679        'id_name': id_name,
5680        'get_len_func': get_len_func,
5681        'get_len_enum': get_len_enum,
5682        'gl_args': '%s, strlen(kInfo) + 1, _, _' %
5683             args[0].GetValidGLArg(func, 0, 0),
5684        'args': '%s, kBucketId' % args[0].GetValidArg(func, 0, 0),
5685        'expect_len_code': '',
5686    }
5687    if get_len_func and get_len_func[0:2] == 'gl':
5688      sub['expect_len_code'] = (
5689        "  EXPECT_CALL(*gl_, %s(%s, %s, _))\n"
5690        "      .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1));") % (
5691            get_len_func[2:], id_name, get_len_enum)
5692    self.WriteValidUnitTest(func, file, valid_test, sub)
5693
5694    invalid_test = """
5695TEST_F(%(test_name)s, %(name)sInvalidArgs) {
5696  const uint32 kBucketId = 123;
5697  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _, _, _))
5698      .Times(0);
5699  cmds::%(name)s cmd;
5700  cmd.Init(kInvalidClientId, kBucketId);
5701  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5702  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5703}
5704"""
5705    self.WriteValidUnitTest(func, file, invalid_test)
5706
5707  def WriteServiceImplementation(self, func, file):
5708    """Overrriden from TypeHandler."""
5709    pass
5710
5711
5712class FunctionInfo(object):
5713  """Holds info about a function."""
5714
5715  def __init__(self, info, type_handler):
5716    for key in info:
5717      setattr(self, key, info[key])
5718    self.type_handler = type_handler
5719    if not 'type' in info:
5720      self.type = ''
5721
5722
5723class Argument(object):
5724  """A class that represents a function argument."""
5725
5726  cmd_type_map_ = {
5727    'GLenum': 'uint32',
5728    'GLint': 'int32',
5729    'GLintptr': 'int32',
5730    'GLsizei': 'int32',
5731    'GLsizeiptr': 'int32',
5732    'GLfloat': 'float',
5733    'GLclampf': 'float',
5734  }
5735  need_validation_ = ['GLsizei*', 'GLboolean*', 'GLenum*', 'GLint*']
5736
5737  def __init__(self, name, type):
5738    self.name = name
5739    self.optional = type.endswith("Optional*")
5740    if self.optional:
5741      type = type[:-9] + "*"
5742    self.type = type
5743
5744    if type in self.cmd_type_map_:
5745      self.cmd_type = self.cmd_type_map_[type]
5746    else:
5747      self.cmd_type = 'uint32'
5748
5749  def IsPointer(self):
5750    """Returns true if argument is a pointer."""
5751    return False
5752
5753  def AddCmdArgs(self, args):
5754    """Adds command arguments for this argument to the given list."""
5755    return args.append(self)
5756
5757  def AddInitArgs(self, args):
5758    """Adds init arguments for this argument to the given list."""
5759    return args.append(self)
5760
5761  def GetValidArg(self, func, offset, index):
5762    """Gets a valid value for this argument."""
5763    valid_arg = func.GetValidArg(offset)
5764    if valid_arg != None:
5765      return valid_arg
5766    return str(offset + 1)
5767
5768  def GetValidClientSideArg(self, func, offset, index):
5769    """Gets a valid value for this argument."""
5770    return str(offset + 1)
5771
5772  def GetValidClientSideCmdArg(self, func, offset, index):
5773    """Gets a valid value for this argument."""
5774    return str(offset + 1)
5775
5776  def GetValidGLArg(self, func, offset, index):
5777    """Gets a valid GL value for this argument."""
5778    valid_arg = func.GetValidArg(offset)
5779    if valid_arg != None:
5780      return valid_arg
5781    return str(offset + 1)
5782
5783  def GetNumInvalidValues(self, func):
5784    """returns the number of invalid values to be tested."""
5785    return 0
5786
5787  def GetInvalidArg(self, offset, index):
5788    """returns an invalid value and expected parse result by index."""
5789    return ("---ERROR0---", "---ERROR2---", None)
5790
5791  def GetLogArg(self):
5792    """Get argument appropriate for LOG macro."""
5793    if self.type == 'GLboolean':
5794      return 'GLES2Util::GetStringBool(%s)' % self.name
5795    if self.type == 'GLenum':
5796      return 'GLES2Util::GetStringEnum(%s)' % self.name
5797    return self.name
5798
5799  def WriteGetCode(self, file):
5800    """Writes the code to get an argument from a command structure."""
5801    file.Write("  %s %s = static_cast<%s>(c.%s);\n" %
5802               (self.type, self.name, self.type, self.name))
5803
5804  def WriteValidationCode(self, file, func):
5805    """Writes the validation code for an argument."""
5806    pass
5807
5808  def WriteClientSideValidationCode(self, file, func):
5809    """Writes the validation code for an argument."""
5810    pass
5811
5812  def WriteDestinationInitalizationValidation(self, file, func):
5813    """Writes the client side destintion initialization validation."""
5814    pass
5815
5816  def WriteDestinationInitalizationValidatationIfNeeded(self, file, func):
5817    """Writes the client side destintion initialization validation if needed."""
5818    parts = self.type.split(" ")
5819    if len(parts) > 1:
5820      return
5821    if parts[0] in self.need_validation_:
5822      file.Write(
5823          "  GPU_CLIENT_VALIDATE_DESTINATION_%sINITALIZATION(%s, %s);\n" %
5824          ("OPTIONAL_" if self.optional else "", self.type[:-1], self.name))
5825
5826
5827  def WriteGetAddress(self, file):
5828    """Writes the code to get the address this argument refers to."""
5829    pass
5830
5831  def GetImmediateVersion(self):
5832    """Gets the immediate version of this argument."""
5833    return self
5834
5835  def GetBucketVersion(self):
5836    """Gets the bucket version of this argument."""
5837    return self
5838
5839
5840class BoolArgument(Argument):
5841  """class for GLboolean"""
5842
5843  def __init__(self, name, type):
5844    Argument.__init__(self, name, 'GLboolean')
5845
5846  def GetValidArg(self, func, offset, index):
5847    """Gets a valid value for this argument."""
5848    return 'true'
5849
5850  def GetValidClientSideArg(self, func, offset, index):
5851    """Gets a valid value for this argument."""
5852    return 'true'
5853
5854  def GetValidClientSideCmdArg(self, func, offset, index):
5855    """Gets a valid value for this argument."""
5856    return 'true'
5857
5858  def GetValidGLArg(self, func, offset, index):
5859    """Gets a valid GL value for this argument."""
5860    return 'true'
5861
5862
5863class UniformLocationArgument(Argument):
5864  """class for uniform locations."""
5865
5866  def __init__(self, name):
5867    Argument.__init__(self, name, "GLint")
5868
5869  def WriteGetCode(self, file):
5870    """Writes the code to get an argument from a command structure."""
5871    code = """  %s %s = static_cast<%s>(c.%s);
5872"""
5873    file.Write(code % (self.type, self.name, self.type, self.name))
5874
5875  def GetValidArg(self, func, offset, index):
5876    """Gets a valid value for this argument."""
5877    return "%d" % (offset + 1)
5878
5879
5880class DataSizeArgument(Argument):
5881  """class for data_size which Bucket commands do not need."""
5882
5883  def __init__(self, name):
5884    Argument.__init__(self, name, "uint32")
5885
5886  def GetBucketVersion(self):
5887    return None
5888
5889
5890class SizeArgument(Argument):
5891  """class for GLsizei and GLsizeiptr."""
5892
5893  def __init__(self, name, type):
5894    Argument.__init__(self, name, type)
5895
5896  def GetNumInvalidValues(self, func):
5897    """overridden from Argument."""
5898    if func.is_immediate:
5899      return 0
5900    return 1
5901
5902  def GetInvalidArg(self, offset, index):
5903    """overridden from Argument."""
5904    return ("-1", "kNoError", "GL_INVALID_VALUE")
5905
5906  def WriteValidationCode(self, file, func):
5907    """overridden from Argument."""
5908    file.Write("  if (%s < 0) {\n" % self.name)
5909    file.Write(
5910        "    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, \"gl%s\", \"%s < 0\");\n" %
5911        (func.original_name, self.name))
5912    file.Write("    return error::kNoError;\n")
5913    file.Write("  }\n")
5914
5915  def WriteClientSideValidationCode(self, file, func):
5916    """overridden from Argument."""
5917    file.Write("  if (%s < 0) {\n" % self.name)
5918    file.Write(
5919        "    SetGLError(GL_INVALID_VALUE, \"gl%s\", \"%s < 0\");\n" %
5920        (func.original_name, self.name))
5921    file.Write("    return;\n")
5922    file.Write("  }\n")
5923
5924
5925class SizeNotNegativeArgument(SizeArgument):
5926  """class for GLsizeiNotNegative. It's NEVER allowed to be negative"""
5927
5928  def __init__(self, name, type, gl_type):
5929    SizeArgument.__init__(self, name, gl_type)
5930
5931  def GetInvalidArg(self, offset, index):
5932    """overridden from SizeArgument."""
5933    return ("-1", "kOutOfBounds", "GL_NO_ERROR")
5934
5935  def WriteValidationCode(self, file, func):
5936    """overridden from SizeArgument."""
5937    pass
5938
5939
5940class EnumBaseArgument(Argument):
5941  """Base class for EnumArgument, IntArgument and ValidatedBoolArgument"""
5942
5943  def __init__(self, name, gl_type, type, gl_error):
5944    Argument.__init__(self, name, gl_type)
5945
5946    self.local_type = type
5947    self.gl_error = gl_error
5948    name = type[len(gl_type):]
5949    self.type_name = name
5950    self.enum_info = _ENUM_LISTS[name]
5951
5952  def WriteValidationCode(self, file, func):
5953    file.Write("  if (!validators_->%s.IsValid(%s)) {\n" %
5954        (ToUnderscore(self.type_name), self.name))
5955    if self.gl_error == "GL_INVALID_ENUM":
5956      file.Write(
5957          "    LOCAL_SET_GL_ERROR_INVALID_ENUM(\"gl%s\", %s, \"%s\");\n" %
5958          (func.original_name, self.name, self.name))
5959    else:
5960      file.Write(
5961          "    LOCAL_SET_GL_ERROR(%s, \"gl%s\", \"%s %s\");\n" %
5962          (self.gl_error, func.original_name, self.name, self.gl_error))
5963    file.Write("    return error::kNoError;\n")
5964    file.Write("  }\n")
5965
5966  def GetValidArg(self, func, offset, index):
5967    valid_arg = func.GetValidArg(offset)
5968    if valid_arg != None:
5969      return valid_arg
5970    if 'valid' in self.enum_info:
5971      valid = self.enum_info['valid']
5972      num_valid = len(valid)
5973      if index >= num_valid:
5974        index = num_valid - 1
5975      return valid[index]
5976    return str(offset + 1)
5977
5978  def GetValidClientSideArg(self, func, offset, index):
5979    """Gets a valid value for this argument."""
5980    return self.GetValidArg(func, offset, index)
5981
5982  def GetValidClientSideCmdArg(self, func, offset, index):
5983    """Gets a valid value for this argument."""
5984    return self.GetValidArg(func, offset, index)
5985
5986  def GetValidGLArg(self, func, offset, index):
5987    """Gets a valid value for this argument."""
5988    return self.GetValidArg(func, offset, index)
5989
5990  def GetNumInvalidValues(self, func):
5991    """returns the number of invalid values to be tested."""
5992    if 'invalid' in self.enum_info:
5993      invalid = self.enum_info['invalid']
5994      return len(invalid)
5995    return 0
5996
5997  def GetInvalidArg(self, offset, index):
5998    """returns an invalid value by index."""
5999    if 'invalid' in self.enum_info:
6000      invalid = self.enum_info['invalid']
6001      num_invalid = len(invalid)
6002      if index >= num_invalid:
6003        index = num_invalid - 1
6004      return (invalid[index], "kNoError", self.gl_error)
6005    return ("---ERROR1---", "kNoError", self.gl_error)
6006
6007
6008class EnumArgument(EnumBaseArgument):
6009  """A class that represents a GLenum argument"""
6010
6011  def __init__(self, name, type):
6012    EnumBaseArgument.__init__(self, name, "GLenum", type, "GL_INVALID_ENUM")
6013
6014  def GetLogArg(self):
6015    """Overridden from Argument."""
6016    return ("GLES2Util::GetString%s(%s)" %
6017            (self.type_name, self.name))
6018
6019
6020class IntArgument(EnumBaseArgument):
6021  """A class for a GLint argument that can only except specific values.
6022
6023  For example glTexImage2D takes a GLint for its internalformat
6024  argument instead of a GLenum.
6025  """
6026
6027  def __init__(self, name, type):
6028    EnumBaseArgument.__init__(self, name, "GLint", type, "GL_INVALID_VALUE")
6029
6030
6031class ValidatedBoolArgument(EnumBaseArgument):
6032  """A class for a GLboolean argument that can only except specific values.
6033
6034  For example glUniformMatrix takes a GLboolean for it's transpose but it
6035  must be false.
6036  """
6037
6038  def __init__(self, name, type):
6039    EnumBaseArgument.__init__(self, name, "GLboolean", type, "GL_INVALID_VALUE")
6040
6041  def GetLogArg(self):
6042    """Overridden from Argument."""
6043    return 'GLES2Util::GetStringBool(%s)' % self.name
6044
6045
6046class ImmediatePointerArgument(Argument):
6047  """A class that represents an immediate argument to a function.
6048
6049  An immediate argument is one where the data follows the command.
6050  """
6051
6052  def __init__(self, name, type):
6053    Argument.__init__(self, name, type)
6054
6055  def AddCmdArgs(self, args):
6056    """Overridden from Argument."""
6057    pass
6058
6059  def WriteGetCode(self, file):
6060    """Overridden from Argument."""
6061    file.Write(
6062      "  %s %s = GetImmediateDataAs<%s>(\n" %
6063      (self.type, self.name, self.type))
6064    file.Write("      c, data_size, immediate_data_size);\n")
6065
6066  def WriteValidationCode(self, file, func):
6067    """Overridden from Argument."""
6068    file.Write("  if (%s == NULL) {\n" % self.name)
6069    file.Write("    return error::kOutOfBounds;\n")
6070    file.Write("  }\n")
6071
6072  def GetImmediateVersion(self):
6073    """Overridden from Argument."""
6074    return None
6075
6076  def WriteDestinationInitalizationValidation(self, file, func):
6077    """Overridden from Argument."""
6078    self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
6079
6080  def GetLogArg(self):
6081    """Overridden from Argument."""
6082    return "static_cast<const void*>(%s)" % self.name
6083
6084
6085class BucketPointerArgument(Argument):
6086  """A class that represents an bucket argument to a function."""
6087
6088  def __init__(self, name, type):
6089    Argument.__init__(self, name, type)
6090
6091  def AddCmdArgs(self, args):
6092    """Overridden from Argument."""
6093    pass
6094
6095  def WriteGetCode(self, file):
6096    """Overridden from Argument."""
6097    file.Write(
6098      "  %s %s = bucket->GetData(0, data_size);\n" %
6099      (self.type, self.name))
6100
6101  def WriteValidationCode(self, file, func):
6102    """Overridden from Argument."""
6103    pass
6104
6105  def GetImmediateVersion(self):
6106    """Overridden from Argument."""
6107    return None
6108
6109  def WriteDestinationInitalizationValidation(self, file, func):
6110    """Overridden from Argument."""
6111    self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
6112
6113  def GetLogArg(self):
6114    """Overridden from Argument."""
6115    return "static_cast<const void*>(%s)" % self.name
6116
6117
6118class PointerArgument(Argument):
6119  """A class that represents a pointer argument to a function."""
6120
6121  def __init__(self, name, type):
6122    Argument.__init__(self, name, type)
6123
6124  def IsPointer(self):
6125    """Returns true if argument is a pointer."""
6126    return True
6127
6128  def GetValidArg(self, func, offset, index):
6129    """Overridden from Argument."""
6130    return "shared_memory_id_, shared_memory_offset_"
6131
6132  def GetValidGLArg(self, func, offset, index):
6133    """Overridden from Argument."""
6134    return "reinterpret_cast<%s>(shared_memory_address_)" % self.type
6135
6136  def GetNumInvalidValues(self, func):
6137    """Overridden from Argument."""
6138    return 2
6139
6140  def GetInvalidArg(self, offset, index):
6141    """Overridden from Argument."""
6142    if index == 0:
6143      return ("kInvalidSharedMemoryId, 0", "kOutOfBounds", None)
6144    else:
6145      return ("shared_memory_id_, kInvalidSharedMemoryOffset",
6146              "kOutOfBounds", None)
6147
6148  def GetLogArg(self):
6149    """Overridden from Argument."""
6150    return "static_cast<const void*>(%s)" % self.name
6151
6152  def AddCmdArgs(self, args):
6153    """Overridden from Argument."""
6154    args.append(Argument("%s_shm_id" % self.name, 'uint32'))
6155    args.append(Argument("%s_shm_offset" % self.name, 'uint32'))
6156
6157  def WriteGetCode(self, file):
6158    """Overridden from Argument."""
6159    file.Write(
6160        "  %s %s = GetSharedMemoryAs<%s>(\n" %
6161        (self.type, self.name, self.type))
6162    file.Write(
6163        "      c.%s_shm_id, c.%s_shm_offset, data_size);\n" %
6164        (self.name, self.name))
6165
6166  def WriteGetAddress(self, file):
6167    """Overridden from Argument."""
6168    file.Write(
6169        "  %s %s = GetSharedMemoryAs<%s>(\n" %
6170        (self.type, self.name, self.type))
6171    file.Write(
6172        "      %s_shm_id, %s_shm_offset, %s_size);\n" %
6173        (self.name, self.name, self.name))
6174
6175  def WriteValidationCode(self, file, func):
6176    """Overridden from Argument."""
6177    file.Write("  if (%s == NULL) {\n" % self.name)
6178    file.Write("    return error::kOutOfBounds;\n")
6179    file.Write("  }\n")
6180
6181  def GetImmediateVersion(self):
6182    """Overridden from Argument."""
6183    return ImmediatePointerArgument(self.name, self.type)
6184
6185  def GetBucketVersion(self):
6186    """Overridden from Argument."""
6187    if self.type == "const char*":
6188      return InputStringBucketArgument(self.name, self.type)
6189    return BucketPointerArgument(self.name, self.type)
6190
6191  def WriteDestinationInitalizationValidation(self, file, func):
6192    """Overridden from Argument."""
6193    self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
6194
6195
6196class InputStringBucketArgument(Argument):
6197  """An string input argument where the string is passed in a bucket."""
6198
6199  def __init__(self, name, type):
6200    Argument.__init__(self, name + "_bucket_id", "uint32")
6201
6202  def WriteGetCode(self, file):
6203    """Overridden from Argument."""
6204    code = """
6205  Bucket* %(name)s_bucket = GetBucket(c.%(name)s);
6206  if (!%(name)s_bucket) {
6207    return error::kInvalidArguments;
6208  }
6209  std::string %(name)s_str;
6210  if (!%(name)s_bucket->GetAsString(&%(name)s_str)) {
6211    return error::kInvalidArguments;
6212  }
6213  const char* %(name)s = %(name)s_str.c_str();
6214"""
6215    file.Write(code % {
6216        'name': self.name,
6217      })
6218
6219  def GetValidArg(self, func, offset, index):
6220    return "kNameBucketId"
6221
6222  def GetValidGLArg(self, func, offset, index):
6223    return "_"
6224
6225
6226class NonImmediatePointerArgument(PointerArgument):
6227  """A pointer argument that stays a pointer even in an immediate cmd."""
6228
6229  def __init__(self, name, type):
6230    PointerArgument.__init__(self, name, type)
6231
6232  def IsPointer(self):
6233    """Returns true if argument is a pointer."""
6234    return False
6235
6236  def GetImmediateVersion(self):
6237    """Overridden from Argument."""
6238    return self
6239
6240
6241class ResourceIdArgument(Argument):
6242  """A class that represents a resource id argument to a function."""
6243
6244  def __init__(self, name, type):
6245    match = re.match("(GLid\w+)", type)
6246    self.resource_type = match.group(1)[4:]
6247    type = type.replace(match.group(1), "GLuint")
6248    Argument.__init__(self, name, type)
6249
6250  def WriteGetCode(self, file):
6251    """Overridden from Argument."""
6252    file.Write("  %s %s = c.%s;\n" % (self.type, self.name, self.name))
6253
6254  def GetValidArg(self, func, offset, index):
6255    return "client_%s_id_" % self.resource_type.lower()
6256
6257  def GetValidGLArg(self, func, offset, index):
6258    return "kService%sId" % self.resource_type
6259
6260
6261class ResourceIdBindArgument(Argument):
6262  """Represents a resource id argument to a bind function."""
6263
6264  def __init__(self, name, type):
6265    match = re.match("(GLidBind\w+)", type)
6266    self.resource_type = match.group(1)[8:]
6267    type = type.replace(match.group(1), "GLuint")
6268    Argument.__init__(self, name, type)
6269
6270  def WriteGetCode(self, file):
6271    """Overridden from Argument."""
6272    code = """  %(type)s %(name)s = c.%(name)s;
6273"""
6274    file.Write(code % {'type': self.type, 'name': self.name})
6275
6276  def GetValidArg(self, func, offset, index):
6277    return "client_%s_id_" % self.resource_type.lower()
6278
6279  def GetValidGLArg(self, func, offset, index):
6280    return "kService%sId" % self.resource_type
6281
6282
6283class ResourceIdZeroArgument(Argument):
6284  """Represents a resource id argument to a function that can be zero."""
6285
6286  def __init__(self, name, type):
6287    match = re.match("(GLidZero\w+)", type)
6288    self.resource_type = match.group(1)[8:]
6289    type = type.replace(match.group(1), "GLuint")
6290    Argument.__init__(self, name, type)
6291
6292  def WriteGetCode(self, file):
6293    """Overridden from Argument."""
6294    file.Write("  %s %s = c.%s;\n" % (self.type, self.name, self.name))
6295
6296  def GetValidArg(self, func, offset, index):
6297    return "client_%s_id_" % self.resource_type.lower()
6298
6299  def GetValidGLArg(self, func, offset, index):
6300    return "kService%sId" % self.resource_type
6301
6302  def GetNumInvalidValues(self, func):
6303    """returns the number of invalid values to be tested."""
6304    return 1
6305
6306  def GetInvalidArg(self, offset, index):
6307    """returns an invalid value by index."""
6308    return ("kInvalidClientId", "kNoError", "GL_INVALID_VALUE")
6309
6310
6311class Function(object):
6312  """A class that represents a function."""
6313
6314  def __init__(self, original_name, name, info, return_type, original_args,
6315               args_for_cmds, cmd_args, init_args, num_pointer_args):
6316    self.name = name
6317    self.original_name = original_name
6318    self.info = info
6319    self.type_handler = info.type_handler
6320    self.return_type = return_type
6321    self.original_args = original_args
6322    self.num_pointer_args = num_pointer_args
6323    self.can_auto_generate = num_pointer_args == 0 and return_type == "void"
6324    self.cmd_args = cmd_args
6325    self.init_args = init_args
6326    self.InitFunction()
6327    self.args_for_cmds = args_for_cmds
6328    self.is_immediate = False
6329
6330  def IsType(self, type_name):
6331    """Returns true if function is a certain type."""
6332    return self.info.type == type_name
6333
6334  def InitFunction(self):
6335    """Calls the init function for the type handler."""
6336    self.type_handler.InitFunction(self)
6337
6338  def GetInfo(self, name):
6339    """Returns a value from the function info for this function."""
6340    if hasattr(self.info, name):
6341      return getattr(self.info, name)
6342    return None
6343
6344  def GetValidArg(self, index):
6345    """Gets a valid arg from the function info if one exists."""
6346    valid_args = self.GetInfo('valid_args')
6347    if valid_args and str(index) in valid_args:
6348      return valid_args[str(index)]
6349    return None
6350
6351  def AddInfo(self, name, value):
6352    """Adds an info."""
6353    setattr(self.info, name, value)
6354
6355  def IsCoreGLFunction(self):
6356    return (not self.GetInfo('extension') and
6357            not self.GetInfo('pepper_interface'))
6358
6359  def InPepperInterface(self, interface):
6360    ext = self.GetInfo('pepper_interface')
6361    if not interface.GetName():
6362      return self.IsCoreGLFunction()
6363    return ext == interface.GetName()
6364
6365  def InAnyPepperExtension(self):
6366    return self.IsCoreGLFunction() or self.GetInfo('pepper_interface')
6367
6368  def GetGLFunctionName(self):
6369    """Gets the function to call to execute GL for this command."""
6370    if self.GetInfo('decoder_func'):
6371      return self.GetInfo('decoder_func')
6372    return "gl%s" % self.original_name
6373
6374  def GetGLTestFunctionName(self):
6375    gl_func_name = self.GetInfo('gl_test_func')
6376    if gl_func_name == None:
6377      gl_func_name = self.GetGLFunctionName()
6378    if gl_func_name.startswith("gl"):
6379      gl_func_name = gl_func_name[2:]
6380    else:
6381      gl_func_name = self.original_name
6382    return gl_func_name
6383
6384  def AddCmdArg(self, arg):
6385    """Adds a cmd argument to this function."""
6386    self.cmd_args.append(arg)
6387
6388  def GetCmdArgs(self):
6389    """Gets the command args for this function."""
6390    return self.cmd_args
6391
6392  def ClearCmdArgs(self):
6393    """Clears the command args for this function."""
6394    self.cmd_args = []
6395
6396  def GetInitArgs(self):
6397    """Gets the init args for this function."""
6398    return self.init_args
6399
6400  def GetOriginalArgs(self):
6401    """Gets the original arguments to this function."""
6402    return self.original_args
6403
6404  def GetLastOriginalArg(self):
6405    """Gets the last original argument to this function."""
6406    return self.original_args[len(self.original_args) - 1]
6407
6408  def __MaybePrependComma(self, arg_string, add_comma):
6409    """Adds a comma if arg_string is not empty and add_comma is true."""
6410    comma = ""
6411    if add_comma and len(arg_string):
6412      comma = ", "
6413    return "%s%s" % (comma, arg_string)
6414
6415  def MakeTypedOriginalArgString(self, prefix, add_comma = False):
6416    """Gets a list of arguments as they are in GL."""
6417    args = self.GetOriginalArgs()
6418    arg_string = ", ".join(
6419        ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
6420    return self.__MaybePrependComma(arg_string, add_comma)
6421
6422  def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "):
6423    """Gets the list of arguments as they are in GL."""
6424    args = self.GetOriginalArgs()
6425    arg_string = separator.join(
6426        ["%s%s" % (prefix, arg.name) for arg in args])
6427    return self.__MaybePrependComma(arg_string, add_comma)
6428
6429  def MakeTypedPepperArgString(self, prefix):
6430    """Gets a list of arguments as they need to be for Pepper."""
6431    if self.GetInfo("pepper_args"):
6432      return self.GetInfo("pepper_args")
6433    else:
6434      return self.MakeTypedOriginalArgString(prefix, False)
6435
6436  def GetPepperName(self):
6437    if self.GetInfo("pepper_name"):
6438      return self.GetInfo("pepper_name")
6439    return self.name
6440
6441  def MakeTypedCmdArgString(self, prefix, add_comma = False):
6442    """Gets a typed list of arguments as they need to be for command buffers."""
6443    args = self.GetCmdArgs()
6444    arg_string = ", ".join(
6445        ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
6446    return self.__MaybePrependComma(arg_string, add_comma)
6447
6448  def MakeCmdArgString(self, prefix, add_comma = False):
6449    """Gets the list of arguments as they need to be for command buffers."""
6450    args = self.GetCmdArgs()
6451    arg_string = ", ".join(
6452        ["%s%s" % (prefix, arg.name) for arg in args])
6453    return self.__MaybePrependComma(arg_string, add_comma)
6454
6455  def MakeTypedInitString(self, prefix, add_comma = False):
6456    """Gets a typed list of arguments as they need to be for cmd Init/Set."""
6457    args = self.GetInitArgs()
6458    arg_string = ", ".join(
6459        ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
6460    return self.__MaybePrependComma(arg_string, add_comma)
6461
6462  def MakeInitString(self, prefix, add_comma = False):
6463    """Gets the list of arguments as they need to be for cmd Init/Set."""
6464    args = self.GetInitArgs()
6465    arg_string = ", ".join(
6466        ["%s%s" % (prefix, arg.name) for arg in args])
6467    return self.__MaybePrependComma(arg_string, add_comma)
6468
6469  def MakeLogArgString(self):
6470    """Makes a string of the arguments for the LOG macros"""
6471    args = self.GetOriginalArgs()
6472    return ' << ", " << '.join([arg.GetLogArg() for arg in args])
6473
6474  def WriteCommandDescription(self, file):
6475    """Writes a description of the command."""
6476    file.Write("//! Command that corresponds to gl%s.\n" % self.original_name)
6477
6478  def WriteHandlerValidation(self, file):
6479    """Writes validation code for the function."""
6480    for arg in self.GetOriginalArgs():
6481      arg.WriteValidationCode(file, self)
6482    self.WriteValidationCode(file)
6483
6484  def WriteHandlerImplementation(self, file):
6485    """Writes the handler implementation for this command."""
6486    self.type_handler.WriteHandlerImplementation(self, file)
6487
6488  def WriteValidationCode(self, file):
6489    """Writes the validation code for a command."""
6490    pass
6491
6492  def WriteCmdFlag(self, file):
6493    """Writes the cmd cmd_flags constant."""
6494    flags = []
6495    trace_level = 3  # By default trace only at the highest level
6496    if hasattr(self.info, 'trace_level'):
6497      if (self.info.trace_level < 0) or (self.info.trace_level > 3):
6498        raise KeyError("Unhandled trace_level: %d" % self.info.trace_level)
6499      trace_level = self.info.trace_level
6500
6501    flags.append('CMD_FLAG_SET_TRACE_LEVEL(%d)' % trace_level)
6502
6503    if len(flags) > 0:
6504      cmd_flags = ' | '.join(flags)
6505    else:
6506      cmd_flags = 0
6507
6508    file.Write("  static const uint8 cmd_flags = %s;\n" % cmd_flags)
6509
6510
6511  def WriteCmdArgFlag(self, file):
6512    """Writes the cmd kArgFlags constant."""
6513    file.Write("  static const cmd::ArgFlags kArgFlags = cmd::kFixed;\n")
6514
6515  def WriteCmdComputeSize(self, file):
6516    """Writes the ComputeSize function for the command."""
6517    file.Write("  static uint32 ComputeSize() {\n")
6518    file.Write(
6519        "    return static_cast<uint32>(sizeof(ValueType));  // NOLINT\n")
6520    file.Write("  }\n")
6521    file.Write("\n")
6522
6523  def WriteCmdSetHeader(self, file):
6524    """Writes the cmd's SetHeader function."""
6525    file.Write("  void SetHeader() {\n")
6526    file.Write("    header.SetCmd<ValueType>();\n")
6527    file.Write("  }\n")
6528    file.Write("\n")
6529
6530  def WriteCmdInit(self, file):
6531    """Writes the cmd's Init function."""
6532    file.Write("  void Init(%s) {\n" % self.MakeTypedCmdArgString("_"))
6533    file.Write("    SetHeader();\n")
6534    args = self.GetCmdArgs()
6535    for arg in args:
6536      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
6537    file.Write("  }\n")
6538    file.Write("\n")
6539
6540  def WriteCmdSet(self, file):
6541    """Writes the cmd's Set function."""
6542    copy_args = self.MakeCmdArgString("_", False)
6543    file.Write("  void* Set(void* cmd%s) {\n" %
6544               self.MakeTypedCmdArgString("_", True))
6545    file.Write("    static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args)
6546    file.Write("    return NextCmdAddress<ValueType>(cmd);\n")
6547    file.Write("  }\n")
6548    file.Write("\n")
6549
6550  def WriteStruct(self, file):
6551    self.type_handler.WriteStruct(self, file)
6552
6553  def WriteDocs(self, file):
6554    self.type_handler.WriteDocs(self, file)
6555
6556  def WriteCmdHelper(self, file):
6557    """Writes the cmd's helper."""
6558    self.type_handler.WriteCmdHelper(self, file)
6559
6560  def WriteServiceImplementation(self, file):
6561    """Writes the service implementation for a command."""
6562    self.type_handler.WriteServiceImplementation(self, file)
6563
6564  def WriteServiceUnitTest(self, file):
6565    """Writes the service implementation for a command."""
6566    self.type_handler.WriteServiceUnitTest(self, file)
6567
6568  def WriteGLES2CLibImplementation(self, file):
6569    """Writes the GLES2 C Lib Implemention."""
6570    self.type_handler.WriteGLES2CLibImplementation(self, file)
6571
6572  def WriteGLES2InterfaceHeader(self, file):
6573    """Writes the GLES2 Interface declaration."""
6574    self.type_handler.WriteGLES2InterfaceHeader(self, file)
6575
6576  def WriteGLES2InterfaceStub(self, file):
6577    """Writes the GLES2 Interface Stub declaration."""
6578    self.type_handler.WriteGLES2InterfaceStub(self, file)
6579
6580  def WriteGLES2InterfaceStubImpl(self, file):
6581    """Writes the GLES2 Interface Stub declaration."""
6582    self.type_handler.WriteGLES2InterfaceStubImpl(self, file)
6583
6584  def WriteGLES2ImplementationHeader(self, file):
6585    """Writes the GLES2 Implemention declaration."""
6586    self.type_handler.WriteGLES2ImplementationHeader(self, file)
6587
6588  def WriteGLES2Implementation(self, file):
6589    """Writes the GLES2 Implemention definition."""
6590    self.type_handler.WriteGLES2Implementation(self, file)
6591
6592  def WriteGLES2TraceImplementationHeader(self, file):
6593    """Writes the GLES2 Trace Implemention declaration."""
6594    self.type_handler.WriteGLES2TraceImplementationHeader(self, file)
6595
6596  def WriteGLES2TraceImplementation(self, file):
6597    """Writes the GLES2 Trace Implemention definition."""
6598    self.type_handler.WriteGLES2TraceImplementation(self, file)
6599
6600  def WriteGLES2Header(self, file):
6601    """Writes the GLES2 Implemention unit test."""
6602    self.type_handler.WriteGLES2Header(self, file)
6603
6604  def WriteGLES2ImplementationUnitTest(self, file):
6605    """Writes the GLES2 Implemention unit test."""
6606    self.type_handler.WriteGLES2ImplementationUnitTest(self, file)
6607
6608  def WriteDestinationInitalizationValidation(self, file):
6609    """Writes the client side destintion initialization validation."""
6610    self.type_handler.WriteDestinationInitalizationValidation(self, file)
6611
6612  def WriteFormatTest(self, file):
6613    """Writes the cmd's format test."""
6614    self.type_handler.WriteFormatTest(self, file)
6615
6616
6617class PepperInterface(object):
6618  """A class that represents a function."""
6619
6620  def __init__(self, info):
6621    self.name = info["name"]
6622    self.dev = info["dev"]
6623
6624  def GetName(self):
6625    return self.name
6626
6627  def GetInterfaceName(self):
6628    upperint = ""
6629    dev = ""
6630    if self.name:
6631      upperint = "_" + self.name.upper()
6632    if self.dev:
6633      dev = "_DEV"
6634    return "PPB_OPENGLES2%s%s_INTERFACE" % (upperint, dev)
6635
6636  def GetInterfaceString(self):
6637    dev = ""
6638    if self.dev:
6639      dev = "(Dev)"
6640    return "PPB_OpenGLES2%s%s" % (self.name, dev)
6641
6642  def GetStructName(self):
6643    dev = ""
6644    if self.dev:
6645      dev = "_Dev"
6646    return "PPB_OpenGLES2%s%s" % (self.name, dev)
6647
6648
6649class ImmediateFunction(Function):
6650  """A class that represnets an immediate function command."""
6651
6652  def __init__(self, func):
6653    new_args = []
6654    for arg in func.GetOriginalArgs():
6655      new_arg = arg.GetImmediateVersion()
6656      if new_arg:
6657        new_args.append(new_arg)
6658
6659    cmd_args = []
6660    new_args_for_cmds = []
6661    for arg in func.args_for_cmds:
6662      new_arg = arg.GetImmediateVersion()
6663      if new_arg:
6664        new_args_for_cmds.append(new_arg)
6665        new_arg.AddCmdArgs(cmd_args)
6666
6667    new_init_args = []
6668    for arg in new_args_for_cmds:
6669      arg.AddInitArgs(new_init_args)
6670
6671    Function.__init__(
6672        self,
6673        func.original_name,
6674        "%sImmediate" % func.name,
6675        func.info,
6676        func.return_type,
6677        new_args,
6678        new_args_for_cmds,
6679        cmd_args,
6680        new_init_args,
6681        0)
6682    self.is_immediate = True
6683
6684  def WriteCommandDescription(self, file):
6685    """Overridden from Function"""
6686    file.Write("//! Immediate version of command that corresponds to gl%s.\n" %
6687        self.original_name)
6688
6689  def WriteServiceImplementation(self, file):
6690    """Overridden from Function"""
6691    self.type_handler.WriteImmediateServiceImplementation(self, file)
6692
6693  def WriteHandlerImplementation(self, file):
6694    """Overridden from Function"""
6695    self.type_handler.WriteImmediateHandlerImplementation(self, file)
6696
6697  def WriteServiceUnitTest(self, file):
6698    """Writes the service implementation for a command."""
6699    self.type_handler.WriteImmediateServiceUnitTest(self, file)
6700
6701  def WriteValidationCode(self, file):
6702    """Overridden from Function"""
6703    self.type_handler.WriteImmediateValidationCode(self, file)
6704
6705  def WriteCmdArgFlag(self, file):
6706    """Overridden from Function"""
6707    file.Write("  static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;\n")
6708
6709  def WriteCmdComputeSize(self, file):
6710    """Overridden from Function"""
6711    self.type_handler.WriteImmediateCmdComputeSize(self, file)
6712
6713  def WriteCmdSetHeader(self, file):
6714    """Overridden from Function"""
6715    self.type_handler.WriteImmediateCmdSetHeader(self, file)
6716
6717  def WriteCmdInit(self, file):
6718    """Overridden from Function"""
6719    self.type_handler.WriteImmediateCmdInit(self, file)
6720
6721  def WriteCmdSet(self, file):
6722    """Overridden from Function"""
6723    self.type_handler.WriteImmediateCmdSet(self, file)
6724
6725  def WriteCmdHelper(self, file):
6726    """Overridden from Function"""
6727    self.type_handler.WriteImmediateCmdHelper(self, file)
6728
6729  def WriteFormatTest(self, file):
6730    """Overridden from Function"""
6731    self.type_handler.WriteImmediateFormatTest(self, file)
6732
6733
6734class BucketFunction(Function):
6735  """A class that represnets a bucket version of a function command."""
6736
6737  def __init__(self, func):
6738    new_args = []
6739    for arg in func.GetOriginalArgs():
6740      new_arg = arg.GetBucketVersion()
6741      if new_arg:
6742        new_args.append(new_arg)
6743
6744    cmd_args = []
6745    new_args_for_cmds = []
6746    for arg in func.args_for_cmds:
6747      new_arg = arg.GetBucketVersion()
6748      if new_arg:
6749        new_args_for_cmds.append(new_arg)
6750        new_arg.AddCmdArgs(cmd_args)
6751
6752    new_init_args = []
6753    for arg in new_args_for_cmds:
6754      arg.AddInitArgs(new_init_args)
6755
6756    Function.__init__(
6757        self,
6758        func.original_name,
6759        "%sBucket" % func.name,
6760        func.info,
6761        func.return_type,
6762        new_args,
6763        new_args_for_cmds,
6764        cmd_args,
6765        new_init_args,
6766        0)
6767
6768#  def InitFunction(self):
6769#    """Overridden from Function"""
6770#    pass
6771
6772  def WriteCommandDescription(self, file):
6773    """Overridden from Function"""
6774    file.Write("//! Bucket version of command that corresponds to gl%s.\n" %
6775        self.original_name)
6776
6777  def WriteServiceImplementation(self, file):
6778    """Overridden from Function"""
6779    self.type_handler.WriteBucketServiceImplementation(self, file)
6780
6781  def WriteHandlerImplementation(self, file):
6782    """Overridden from Function"""
6783    self.type_handler.WriteBucketHandlerImplementation(self, file)
6784
6785  def WriteServiceUnitTest(self, file):
6786    """Writes the service implementation for a command."""
6787    self.type_handler.WriteBucketServiceUnitTest(self, file)
6788
6789
6790def CreateArg(arg_string):
6791  """Creates an Argument."""
6792  arg_parts = arg_string.split()
6793  if len(arg_parts) == 1 and arg_parts[0] == 'void':
6794    return None
6795  # Is this a pointer argument?
6796  elif arg_string.find('*') >= 0:
6797    if arg_parts[0] == 'NonImmediate':
6798      return NonImmediatePointerArgument(
6799          arg_parts[-1],
6800          " ".join(arg_parts[1:-1]))
6801    else:
6802      return PointerArgument(
6803          arg_parts[-1],
6804          " ".join(arg_parts[0:-1]))
6805  # Is this a resource argument? Must come after pointer check.
6806  elif arg_parts[0].startswith('GLidBind'):
6807    return ResourceIdBindArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6808  elif arg_parts[0].startswith('GLidZero'):
6809    return ResourceIdZeroArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6810  elif arg_parts[0].startswith('GLid'):
6811    return ResourceIdArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6812  elif arg_parts[0].startswith('GLenum') and len(arg_parts[0]) > 6:
6813    return EnumArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6814  elif arg_parts[0].startswith('GLboolean') and len(arg_parts[0]) > 9:
6815    return ValidatedBoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6816  elif arg_parts[0].startswith('GLboolean'):
6817    return BoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6818  elif arg_parts[0].startswith('GLintUniformLocation'):
6819    return UniformLocationArgument(arg_parts[-1])
6820  elif (arg_parts[0].startswith('GLint') and len(arg_parts[0]) > 5 and
6821        not arg_parts[0].startswith('GLintptr')):
6822    return IntArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6823  elif (arg_parts[0].startswith('GLsizeiNotNegative') or
6824        arg_parts[0].startswith('GLintptrNotNegative')):
6825    return SizeNotNegativeArgument(arg_parts[-1],
6826                                   " ".join(arg_parts[0:-1]),
6827                                   arg_parts[0][0:-11])
6828  elif arg_parts[0].startswith('GLsize'):
6829    return SizeArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6830  else:
6831    return Argument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6832
6833
6834class GLGenerator(object):
6835  """A class to generate GL command buffers."""
6836
6837  _function_re = re.compile(r'GL_APICALL(.*?)GL_APIENTRY (.*?) \((.*?)\);')
6838
6839  def __init__(self, verbose):
6840    self.original_functions = []
6841    self.functions = []
6842    self.verbose = verbose
6843    self.errors = 0
6844    self._function_info = {}
6845    self._empty_type_handler = TypeHandler()
6846    self._empty_function_info = FunctionInfo({}, self._empty_type_handler)
6847    self.pepper_interfaces = []
6848    self.interface_info = {}
6849
6850    self._type_handlers = {
6851      'Bind': BindHandler(),
6852      'Create': CreateHandler(),
6853      'Custom': CustomHandler(),
6854      'Data': DataHandler(),
6855      'Delete': DeleteHandler(),
6856      'DELn': DELnHandler(),
6857      'GENn': GENnHandler(),
6858      'GETn': GETnHandler(),
6859      'GLchar': GLcharHandler(),
6860      'GLcharN': GLcharNHandler(),
6861      'HandWritten': HandWrittenHandler(),
6862      'Is': IsHandler(),
6863      'Manual': ManualHandler(),
6864      'PUT': PUTHandler(),
6865      'PUTn': PUTnHandler(),
6866      'PUTXn': PUTXnHandler(),
6867      'StateSet': StateSetHandler(),
6868      'StateSetRGBAlpha': StateSetRGBAlphaHandler(),
6869      'StateSetFrontBack': StateSetFrontBackHandler(),
6870      'StateSetFrontBackSeparate': StateSetFrontBackSeparateHandler(),
6871      'StateSetNamedParameter': StateSetNamedParameter(),
6872      'STRn': STRnHandler(),
6873      'Todo': TodoHandler(),
6874    }
6875
6876    for func_name in _FUNCTION_INFO:
6877      info = _FUNCTION_INFO[func_name]
6878      type = ''
6879      if 'type' in info:
6880        type = info['type']
6881      self._function_info[func_name] = FunctionInfo(info,
6882                                                    self.GetTypeHandler(type))
6883    for interface in _PEPPER_INTERFACES:
6884      interface = PepperInterface(interface)
6885      self.pepper_interfaces.append(interface)
6886      self.interface_info[interface.GetName()] = interface
6887
6888  def AddFunction(self, func):
6889    """Adds a function."""
6890    self.functions.append(func)
6891
6892  def GetTypeHandler(self, name):
6893    """Gets a type info for the given type."""
6894    if len(name):
6895      if name in self._type_handlers:
6896        return self._type_handlers[name]
6897      else:
6898        raise KeyError("no such type handler: %s" % name)
6899    return self._empty_type_handler
6900
6901  def GetFunctionInfo(self, name):
6902    """Gets a type info for the given function name."""
6903    if name in self._function_info:
6904      return self._function_info[name]
6905    return self._empty_function_info
6906
6907  def Log(self, msg):
6908    """Prints something if verbose is true."""
6909    if self.verbose:
6910      print msg
6911
6912  def Error(self, msg):
6913    """Prints an error."""
6914    print "Error: %s" % msg
6915    self.errors += 1
6916
6917  def WriteLicense(self, file):
6918    """Writes the license."""
6919    file.Write(_LICENSE)
6920
6921  def WriteNamespaceOpen(self, file):
6922    """Writes the code for the namespace."""
6923    file.Write("namespace gpu {\n")
6924    file.Write("namespace gles2 {\n")
6925    file.Write("\n")
6926
6927  def WriteNamespaceClose(self, file):
6928    """Writes the code to close the namespace."""
6929    file.Write("}  // namespace gles2\n")
6930    file.Write("}  // namespace gpu\n")
6931    file.Write("\n")
6932
6933  def ParseArgs(self, arg_string):
6934    """Parses a function arg string."""
6935    args = []
6936    num_pointer_args = 0
6937    parts = arg_string.split(',')
6938    is_gl_enum = False
6939    for arg_string in parts:
6940      if arg_string.startswith('GLenum '):
6941        is_gl_enum = True
6942      arg = CreateArg(arg_string)
6943      if arg:
6944        args.append(arg)
6945        if arg.IsPointer():
6946          num_pointer_args += 1
6947    return (args, num_pointer_args, is_gl_enum)
6948
6949  def ParseGLH(self, filename):
6950    """Parses the cmd_buffer_functions.txt file and extracts the functions"""
6951    f = open(filename, "r")
6952    functions = f.read()
6953    f.close()
6954    for line in functions.splitlines():
6955      match = self._function_re.match(line)
6956      if match:
6957        func_name = match.group(2)[2:]
6958        func_info = self.GetFunctionInfo(func_name)
6959        if func_info.type != 'Noop':
6960          return_type = match.group(1).strip()
6961          arg_string = match.group(3)
6962          (args, num_pointer_args, is_gl_enum) = self.ParseArgs(arg_string)
6963          # comment in to find out which functions use bare enums.
6964          # if is_gl_enum:
6965          #   self.Log("%s uses bare GLenum" % func_name)
6966          args_for_cmds = args
6967          if hasattr(func_info, 'cmd_args'):
6968            (args_for_cmds, num_pointer_args, is_gl_enum) = (
6969                self.ParseArgs(getattr(func_info, 'cmd_args')))
6970          cmd_args = []
6971          for arg in args_for_cmds:
6972            arg.AddCmdArgs(cmd_args)
6973          init_args = []
6974          for arg in args_for_cmds:
6975            arg.AddInitArgs(init_args)
6976          return_arg = CreateArg(return_type + " result")
6977          if return_arg:
6978            init_args.append(return_arg)
6979          f = Function(func_name, func_name, func_info, return_type, args,
6980                       args_for_cmds, cmd_args, init_args, num_pointer_args)
6981          self.original_functions.append(f)
6982          gen_cmd = f.GetInfo('gen_cmd')
6983          if gen_cmd == True or gen_cmd == None:
6984            self.AddFunction(f)
6985            f.type_handler.AddImmediateFunction(self, f)
6986            f.type_handler.AddBucketFunction(self, f)
6987
6988    self.Log("Auto Generated Functions    : %d" %
6989             len([f for f in self.functions if f.can_auto_generate or
6990                  (not f.IsType('') and not f.IsType('Custom') and
6991                   not f.IsType('Todo'))]))
6992
6993    funcs = [f for f in self.functions if not f.can_auto_generate and
6994             (f.IsType('') or f.IsType('Custom') or f.IsType('Todo'))]
6995    self.Log("Non Auto Generated Functions: %d" % len(funcs))
6996
6997    for f in funcs:
6998      self.Log("  %-10s %-20s gl%s" % (f.info.type, f.return_type, f.name))
6999
7000  def WriteCommandIds(self, filename):
7001    """Writes the command buffer format"""
7002    file = CHeaderWriter(filename)
7003    file.Write("#define GLES2_COMMAND_LIST(OP) \\\n")
7004    id = 256
7005    for func in self.functions:
7006      file.Write("  %-60s /* %d */ \\\n" %
7007                 ("OP(%s)" % func.name, id))
7008      id += 1
7009    file.Write("\n")
7010
7011    file.Write("enum CommandId {\n")
7012    file.Write("  kStartPoint = cmd::kLastCommonId,  "
7013               "// All GLES2 commands start after this.\n")
7014    file.Write("#define GLES2_CMD_OP(name) k ## name,\n")
7015    file.Write("  GLES2_COMMAND_LIST(GLES2_CMD_OP)\n")
7016    file.Write("#undef GLES2_CMD_OP\n")
7017    file.Write("  kNumCommands\n")
7018    file.Write("};\n")
7019    file.Write("\n")
7020    file.Close()
7021
7022  def WriteFormat(self, filename):
7023    """Writes the command buffer format"""
7024    file = CHeaderWriter(filename)
7025    for func in self.functions:
7026      if True:
7027      #gen_cmd = func.GetInfo('gen_cmd')
7028      #if gen_cmd == True or gen_cmd == None:
7029        func.WriteStruct(file)
7030    file.Write("\n")
7031    file.Close()
7032
7033  def WriteDocs(self, filename):
7034    """Writes the command buffer doc version of the commands"""
7035    file = CWriter(filename)
7036    for func in self.functions:
7037      if True:
7038      #gen_cmd = func.GetInfo('gen_cmd')
7039      #if gen_cmd == True or gen_cmd == None:
7040        func.WriteDocs(file)
7041    file.Write("\n")
7042    file.Close()
7043
7044  def WriteFormatTest(self, filename):
7045    """Writes the command buffer format test."""
7046    file = CHeaderWriter(
7047      filename,
7048      "// This file contains unit tests for gles2 commmands\n"
7049      "// It is included by gles2_cmd_format_test.cc\n"
7050      "\n")
7051
7052    for func in self.functions:
7053      if True:
7054      #gen_cmd = func.GetInfo('gen_cmd')
7055      #if gen_cmd == True or gen_cmd == None:
7056        func.WriteFormatTest(file)
7057
7058    file.Close()
7059
7060  def WriteCmdHelperHeader(self, filename):
7061    """Writes the gles2 command helper."""
7062    file = CHeaderWriter(filename)
7063
7064    for func in self.functions:
7065      if True:
7066      #gen_cmd = func.GetInfo('gen_cmd')
7067      #if gen_cmd == True or gen_cmd == None:
7068        func.WriteCmdHelper(file)
7069
7070    file.Close()
7071
7072  def WriteServiceContextStateHeader(self, filename):
7073    """Writes the service context state header."""
7074    file = CHeaderWriter(
7075        filename,
7076        "// It is included by context_state.h\n")
7077    file.Write("struct EnableFlags {\n")
7078    file.Write("  EnableFlags();\n")
7079    for capability in _CAPABILITY_FLAGS:
7080      file.Write("  bool %s;\n" % capability['name'])
7081    file.Write("};\n\n")
7082
7083    for state_name in sorted(_STATES.keys()):
7084      state = _STATES[state_name]
7085      for item in state['states']:
7086        file.Write("%s %s;\n" % (item['type'], item['name']))
7087    file.Write("\n")
7088
7089    file.Close()
7090
7091  def WriteClientContextStateHeader(self, filename):
7092    """Writes the client context state header."""
7093    file = CHeaderWriter(
7094        filename,
7095        "// It is included by client_context_state.h\n")
7096    file.Write("struct EnableFlags {\n")
7097    file.Write("  EnableFlags();\n")
7098    for capability in _CAPABILITY_FLAGS:
7099      file.Write("  bool %s;\n" % capability['name'])
7100    file.Write("};\n\n")
7101
7102    file.Close()
7103
7104  def WriteContextStateGetters(self, file, class_name):
7105    """Writes the state getters."""
7106    for gl_type in ["GLint", "GLfloat"]:
7107      file.Write("""
7108bool %s::GetStateAs%s(
7109    GLenum pname, %s* params, GLsizei* num_written) const {
7110  switch (pname) {
7111""" % (class_name, gl_type, gl_type))
7112      for state_name in sorted(_STATES.keys()):
7113        state = _STATES[state_name]
7114        if 'enum' in state:
7115          file.Write("    case %s:\n" % state['enum'])
7116          file.Write("      *num_written = %d;\n" % len(state['states']))
7117          file.Write("      if (params) {\n")
7118          for ndx,item in enumerate(state['states']):
7119            file.Write("        params[%d] = static_cast<%s>(%s);\n" %
7120                       (ndx, gl_type, item['name']))
7121          file.Write("      }\n")
7122          file.Write("      return true;\n")
7123        else:
7124          for item in state['states']:
7125            file.Write("    case %s:\n" % item['enum'])
7126            file.Write("      *num_written = 1;\n")
7127            file.Write("      if (params) {\n")
7128            file.Write("        params[0] = static_cast<%s>(%s);\n" %
7129                       (gl_type, item['name']))
7130            file.Write("      }\n")
7131            file.Write("      return true;\n")
7132      for capability in _CAPABILITY_FLAGS:
7133            file.Write("    case GL_%s:\n" % capability['name'].upper())
7134            file.Write("      *num_written = 1;\n")
7135            file.Write("      if (params) {\n")
7136            file.Write(
7137                "        params[0] = static_cast<%s>(enable_flags.%s);\n" %
7138                (gl_type, capability['name']))
7139            file.Write("      }\n")
7140            file.Write("      return true;\n")
7141      file.Write("""    default:
7142      return false;
7143  }
7144}
7145""")
7146
7147  def WriteServiceContextStateImpl(self, filename):
7148    """Writes the context state service implementation."""
7149    file = CHeaderWriter(
7150        filename,
7151        "// It is included by context_state.cc\n")
7152    code = []
7153    for capability in _CAPABILITY_FLAGS:
7154      code.append("%s(%s)" %
7155                  (capability['name'],
7156                   ('false', 'true')['default' in capability]))
7157    file.Write("ContextState::EnableFlags::EnableFlags()\n    : %s {\n}\n" %
7158               ",\n      ".join(code))
7159    file.Write("\n")
7160
7161    file.Write("void ContextState::Initialize() {\n")
7162    for state_name in sorted(_STATES.keys()):
7163      state = _STATES[state_name]
7164      for item in state['states']:
7165        file.Write("  %s = %s;\n" % (item['name'], item['default']))
7166    file.Write("}\n")
7167
7168    file.Write("""
7169void ContextState::InitCapabilities(const ContextState* prev_state) const {
7170""")
7171    def WriteCapabilities(test_prev):
7172      for capability in _CAPABILITY_FLAGS:
7173        capability_name = capability['name']
7174        if test_prev:
7175          file.Write("  if (prev_state->enable_flags.%s != enable_flags.%s)\n" %
7176                     (capability_name, capability_name))
7177        file.Write("    EnableDisable(GL_%s, enable_flags.%s);\n" %
7178                   (capability_name.upper(), capability_name))
7179
7180    file.Write("  if (prev_state) {")
7181    WriteCapabilities(True)
7182    file.Write("  } else {")
7183    WriteCapabilities(False)
7184    file.Write("  }")
7185
7186    file.Write("""}
7187
7188void ContextState::InitState(const ContextState *prev_state) const {
7189""")
7190
7191    def WriteStates(test_prev):
7192      # We need to sort the keys so the expectations match
7193      for state_name in sorted(_STATES.keys()):
7194        state = _STATES[state_name]
7195        if state['type'] == 'FrontBack':
7196          num_states = len(state['states'])
7197          for ndx, group in enumerate(Grouper(num_states / 2, state['states'])):
7198            if test_prev:
7199              file.Write("  if (")
7200            args = []
7201            for place, item in enumerate(group):
7202              item_name = item['name']
7203              args.append('%s' % item_name)
7204              if test_prev:
7205                if place > 0:
7206                  file.Write(' ||\n')
7207                file.Write("(%s != prev_state->%s)" % (item_name, item_name))
7208            if test_prev:
7209              file.Write(")\n")
7210            file.Write(
7211                "  gl%s(%s, %s);\n" %
7212                (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args)))
7213        elif state['type'] == 'NamedParameter':
7214          for item in state['states']:
7215            if 'extension_flag' in item:
7216              file.Write("  if (feature_info_->feature_flags().%s)\n  " %
7217                         item['extension_flag'])
7218            if test_prev:
7219              file.Write("  if (prev_state->%s != %s)\n" %
7220                         (item['name'], item['name']))
7221            file.Write("  gl%s(%s, %s);\n" %
7222                       (state['func'], item['enum'], item['name']))
7223        else:
7224          if test_prev:
7225            file.Write("  if (")
7226          args = []
7227          for place, item in enumerate(state['states']):
7228            item_name = item['name']
7229            args.append('%s' % item_name)
7230            if test_prev:
7231              if place > 0:
7232                file.Write(' ||\n')
7233              file.Write("(%s != prev_state->%s)" %
7234                         (item_name, item_name))
7235          if test_prev:
7236            file.Write("    )\n")
7237          file.Write("  gl%s(%s);\n" % (state['func'], ", ".join(args)))
7238
7239    file.Write("  if (prev_state) {")
7240    WriteStates(True)
7241    file.Write("  } else {")
7242    WriteStates(False)
7243    file.Write("  }")
7244
7245    file.Write("}\n")
7246
7247    file.Write("""bool ContextState::GetEnabled(GLenum cap) const {
7248  switch (cap) {
7249""")
7250    for capability in _CAPABILITY_FLAGS:
7251      file.Write("    case GL_%s:\n" % capability['name'].upper())
7252      file.Write("      return enable_flags.%s;\n" % capability['name'])
7253    file.Write("""    default:
7254      NOTREACHED();
7255      return false;
7256  }
7257}
7258""")
7259
7260    self.WriteContextStateGetters(file, "ContextState")
7261    file.Close()
7262
7263  def WriteClientContextStateImpl(self, filename):
7264    """Writes the context state client side implementation."""
7265    file = CHeaderWriter(
7266        filename,
7267        "// It is included by client_context_state.cc\n")
7268    code = []
7269    for capability in _CAPABILITY_FLAGS:
7270      code.append("%s(%s)" %
7271                  (capability['name'],
7272                   ('false', 'true')['default' in capability]))
7273    file.Write(
7274      "ClientContextState::EnableFlags::EnableFlags()\n    : %s {\n}\n" %
7275      ",\n      ".join(code))
7276    file.Write("\n")
7277
7278    file.Write("""
7279bool ClientContextState::SetCapabilityState(
7280    GLenum cap, bool enabled, bool* changed) {
7281  *changed = false;
7282  switch (cap) {
7283""")
7284    for capability in _CAPABILITY_FLAGS:
7285      file.Write("    case GL_%s:\n" % capability['name'].upper())
7286      file.Write("""      if (enable_flags.%(name)s != enabled) {
7287         *changed = true;
7288         enable_flags.%(name)s = enabled;
7289      }
7290      return true;
7291""" % capability)
7292    file.Write("""    default:
7293      return false;
7294  }
7295}
7296""")
7297    file.Write("""bool ClientContextState::GetEnabled(
7298    GLenum cap, bool* enabled) const {
7299  switch (cap) {
7300""")
7301    for capability in _CAPABILITY_FLAGS:
7302      file.Write("    case GL_%s:\n" % capability['name'].upper())
7303      file.Write("      *enabled = enable_flags.%s;\n" % capability['name'])
7304      file.Write("      return true;\n")
7305    file.Write("""    default:
7306      return false;
7307  }
7308}
7309""")
7310    file.Close()
7311
7312  def WriteServiceImplementation(self, filename):
7313    """Writes the service decorder implementation."""
7314    file = CHeaderWriter(
7315        filename,
7316        "// It is included by gles2_cmd_decoder.cc\n")
7317
7318    for func in self.functions:
7319      if True:
7320      #gen_cmd = func.GetInfo('gen_cmd')
7321      #if gen_cmd == True or gen_cmd == None:
7322        func.WriteServiceImplementation(file)
7323
7324    file.Write("""
7325bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
7326  switch (cap) {
7327""")
7328    for capability in _CAPABILITY_FLAGS:
7329      file.Write("    case GL_%s:\n" % capability['name'].upper())
7330      if 'state_flag' in capability:
7331        file.Write("""      if (state_.enable_flags.%(name)s != enabled) {
7332        state_.enable_flags.%(name)s = enabled;
7333        %(state_flag)s = true;
7334      }
7335      return false;
7336""" % capability)
7337      else:
7338        file.Write("""      state_.enable_flags.%(name)s = enabled;
7339      return true;
7340""" % capability)
7341    file.Write("""    default:
7342      NOTREACHED();
7343      return false;
7344  }
7345}
7346""")
7347    file.Close()
7348
7349  def WriteServiceUnitTests(self, filename):
7350    """Writes the service decorder unit tests."""
7351    num_tests = len(self.functions)
7352    FUNCTIONS_PER_FILE = 98  # hard code this so it doesn't change.
7353    count = 0
7354    for test_num in range(0, num_tests, FUNCTIONS_PER_FILE):
7355      count += 1
7356      name = filename % count
7357      file = CHeaderWriter(
7358          name,
7359          "// It is included by gles2_cmd_decoder_unittest_%d.cc\n" % count)
7360      file.SetFileNum(count)
7361      end = test_num + FUNCTIONS_PER_FILE
7362      if end > num_tests:
7363        end = num_tests
7364      for idx in range(test_num, end):
7365        func = self.functions[idx]
7366        if True:
7367        #gen_cmd = func.GetInfo('gen_cmd')
7368        #if gen_cmd == True or gen_cmd == None:
7369          if func.GetInfo('unit_test') == False:
7370            file.Write("// TODO(gman): %s\n" % func.name)
7371          else:
7372            func.WriteServiceUnitTest(file)
7373
7374      file.Close()
7375    file = CHeaderWriter(
7376        filename % 0,
7377        "// It is included by gles2_cmd_decoder_unittest_base.cc\n")
7378    file.Write(
7379"""void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations() {
7380""")
7381    for capability in _CAPABILITY_FLAGS:
7382      file.Write("  ExpectEnableDisable(GL_%s, %s);\n" %
7383                 (capability['name'].upper(),
7384                  ('false', 'true')['default' in capability]))
7385    file.Write("""}
7386
7387void GLES2DecoderTestBase::SetupInitStateExpectations() {
7388""")
7389
7390    # We need to sort the keys so the expectations match
7391    for state_name in sorted(_STATES.keys()):
7392      state = _STATES[state_name]
7393      if state['type'] == 'FrontBack':
7394        num_states = len(state['states'])
7395        for ndx, group in enumerate(Grouper(num_states / 2, state['states'])):
7396          args = []
7397          for item in group:
7398            if 'expected' in item:
7399              args.append(item['expected'])
7400            else:
7401              args.append(item['default'])
7402          file.Write(
7403              "  EXPECT_CALL(*gl_, %s(%s, %s))\n" %
7404              (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args)))
7405          file.Write("      .Times(1)\n")
7406          file.Write("      .RetiresOnSaturation();\n")
7407      elif state['type'] == 'NamedParameter':
7408        for item in state['states']:
7409          if 'extension_flag' in item:
7410            continue
7411          file.Write(
7412              "  EXPECT_CALL(*gl_, %s(%s, %s))\n" %
7413              (state['func'], item['enum'], item['default']))
7414          file.Write("      .Times(1)\n")
7415          file.Write("      .RetiresOnSaturation();\n")
7416      else:
7417        args = []
7418        for item in state['states']:
7419          if 'expected' in item:
7420            args.append(item['expected'])
7421          else:
7422            args.append(item['default'])
7423        file.Write("  EXPECT_CALL(*gl_, %s(%s))\n" %
7424                   (state['func'], ", ".join(args)))
7425        file.Write("      .Times(1)\n")
7426        file.Write("      .RetiresOnSaturation();\n")
7427    file.Write("""}
7428""")
7429    file.Close()
7430
7431  def WriteGLES2Header(self, filename):
7432    """Writes the GLES2 header."""
7433    file = CHeaderWriter(
7434        filename,
7435        "// This file contains Chromium-specific GLES2 declarations.\n\n")
7436
7437    for func in self.original_functions:
7438      func.WriteGLES2Header(file)
7439
7440    file.Write("\n")
7441    file.Close()
7442
7443  def WriteGLES2CLibImplementation(self, filename):
7444    """Writes the GLES2 c lib implementation."""
7445    file = CHeaderWriter(
7446        filename,
7447        "// These functions emulate GLES2 over command buffers.\n")
7448
7449    for func in self.original_functions:
7450      func.WriteGLES2CLibImplementation(file)
7451
7452    file.Write("""
7453namespace gles2 {
7454
7455extern const NameToFunc g_gles2_function_table[] = {
7456""")
7457    for func in self.original_functions:
7458      file.Write(
7459          '  { "gl%s", reinterpret_cast<GLES2FunctionPointer>(gl%s), },\n' %
7460          (func.name, func.name))
7461    file.Write("""  { NULL, NULL, },
7462};
7463
7464}  // namespace gles2
7465""")
7466    file.Close()
7467
7468  def WriteGLES2InterfaceHeader(self, filename):
7469    """Writes the GLES2 interface header."""
7470    file = CHeaderWriter(
7471        filename,
7472        "// This file is included by gles2_interface.h to declare the\n"
7473        "// GL api functions.\n")
7474    for func in self.original_functions:
7475      func.WriteGLES2InterfaceHeader(file)
7476    file.Close()
7477
7478  def WriteGLES2InterfaceStub(self, filename):
7479    """Writes the GLES2 interface stub header."""
7480    file = CHeaderWriter(
7481        filename,
7482        "// This file is included by gles2_interface_stub.h.\n")
7483    for func in self.original_functions:
7484      func.WriteGLES2InterfaceStub(file)
7485    file.Close()
7486
7487  def WriteGLES2InterfaceStubImpl(self, filename):
7488    """Writes the GLES2 interface header."""
7489    file = CHeaderWriter(
7490        filename,
7491        "// This file is included by gles2_interface_stub.cc.\n")
7492    for func in self.original_functions:
7493      func.WriteGLES2InterfaceStubImpl(file)
7494    file.Close()
7495
7496  def WriteGLES2ImplementationHeader(self, filename):
7497    """Writes the GLES2 Implementation header."""
7498    file = CHeaderWriter(
7499        filename,
7500        "// This file is included by gles2_implementation.h to declare the\n"
7501        "// GL api functions.\n")
7502    for func in self.original_functions:
7503      func.WriteGLES2ImplementationHeader(file)
7504    file.Close()
7505
7506  def WriteGLES2Implementation(self, filename):
7507    """Writes the GLES2 Implementation."""
7508    file = CHeaderWriter(
7509        filename,
7510        "// This file is included by gles2_implementation.cc to define the\n"
7511        "// GL api functions.\n")
7512    for func in self.original_functions:
7513      func.WriteGLES2Implementation(file)
7514    file.Close()
7515
7516  def WriteGLES2TraceImplementationHeader(self, filename):
7517    """Writes the GLES2 Trace Implementation header."""
7518    file = CHeaderWriter(
7519        filename,
7520        "// This file is included by gles2_trace_implementation.h\n")
7521    for func in self.original_functions:
7522      func.WriteGLES2TraceImplementationHeader(file)
7523    file.Close()
7524
7525  def WriteGLES2TraceImplementation(self, filename):
7526    """Writes the GLES2 Trace Implementation."""
7527    file = CHeaderWriter(
7528        filename,
7529        "// This file is included by gles2_trace_implementation.cc\n")
7530    for func in self.original_functions:
7531      func.WriteGLES2TraceImplementation(file)
7532    file.Close()
7533
7534  def WriteGLES2ImplementationUnitTests(self, filename):
7535    """Writes the GLES2 helper header."""
7536    file = CHeaderWriter(
7537        filename,
7538        "// This file is included by gles2_implementation.h to declare the\n"
7539        "// GL api functions.\n")
7540    for func in self.original_functions:
7541      func.WriteGLES2ImplementationUnitTest(file)
7542    file.Close()
7543
7544  def WriteServiceUtilsHeader(self, filename):
7545    """Writes the gles2 auto generated utility header."""
7546    file = CHeaderWriter(filename)
7547    for enum in sorted(_ENUM_LISTS.keys()):
7548      file.Write("ValueValidator<%s> %s;\n" %
7549                 (_ENUM_LISTS[enum]['type'], ToUnderscore(enum)))
7550    file.Write("\n")
7551    file.Close()
7552
7553  def WriteServiceUtilsImplementation(self, filename):
7554    """Writes the gles2 auto generated utility implementation."""
7555    file = CHeaderWriter(filename)
7556    enums = sorted(_ENUM_LISTS.keys())
7557    for enum in enums:
7558      if len(_ENUM_LISTS[enum]['valid']) > 0:
7559        file.Write("static const %s valid_%s_table[] = {\n" %
7560                   (_ENUM_LISTS[enum]['type'], ToUnderscore(enum)))
7561        for value in _ENUM_LISTS[enum]['valid']:
7562          file.Write("  %s,\n" % value)
7563        file.Write("};\n")
7564        file.Write("\n")
7565    file.Write("Validators::Validators()\n")
7566    pre = ': '
7567    post = ','
7568    for count, enum in enumerate(enums):
7569      if count + 1 == len(enums):
7570        post = ' {'
7571      if len(_ENUM_LISTS[enum]['valid']) > 0:
7572        code = """    %(pre)s%(name)s(
7573          valid_%(name)s_table, arraysize(valid_%(name)s_table))%(post)s
7574"""
7575      else:
7576        code = """    %(pre)s%(name)s()%(post)s
7577"""
7578      file.Write(code % {
7579          'name': ToUnderscore(enum),
7580          'pre': pre,
7581          'post': post,
7582        })
7583      pre = '  '
7584    file.Write("}\n\n");
7585    file.Close()
7586
7587  def WriteCommonUtilsHeader(self, filename):
7588    """Writes the gles2 common utility header."""
7589    file = CHeaderWriter(filename)
7590    enums = sorted(_ENUM_LISTS.keys())
7591    for enum in enums:
7592      if _ENUM_LISTS[enum]['type'] == 'GLenum':
7593        file.Write("static std::string GetString%s(uint32 value);\n" % enum)
7594    file.Write("\n")
7595    file.Close()
7596
7597  def WriteCommonUtilsImpl(self, filename):
7598    """Writes the gles2 common utility header."""
7599    enum_re = re.compile(r'\#define\s+(GL_[a-zA-Z0-9_]+)\s+([0-9A-Fa-fx]+)')
7600    dict = {}
7601    for fname in ['../../third_party/khronos/GLES2/gl2.h',
7602                  '../../third_party/khronos/GLES2/gl2ext.h',
7603                  '../../gpu/GLES2/gl2chromium.h',
7604                  '../../gpu/GLES2/gl2extchromium.h']:
7605      lines = open(fname).readlines()
7606      for line in lines:
7607        m = enum_re.match(line)
7608        if m:
7609          name = m.group(1)
7610          value = m.group(2)
7611          if len(value) <= 10 and not value in dict:
7612            dict[value] = name
7613
7614    file = CHeaderWriter(filename)
7615    file.Write("static const GLES2Util::EnumToString "
7616               "enum_to_string_table[] = {\n")
7617    for value in dict:
7618      file.Write('  { %s, "%s", },\n' % (value, dict[value]))
7619    file.Write("""};
7620
7621const GLES2Util::EnumToString* const GLES2Util::enum_to_string_table_ =
7622    enum_to_string_table;
7623const size_t GLES2Util::enum_to_string_table_len_ =
7624    sizeof(enum_to_string_table) / sizeof(enum_to_string_table[0]);
7625
7626""")
7627
7628    enums = sorted(_ENUM_LISTS.keys())
7629    for enum in enums:
7630      if _ENUM_LISTS[enum]['type'] == 'GLenum':
7631        file.Write("std::string GLES2Util::GetString%s(uint32 value) {\n" %
7632                   enum)
7633        if len(_ENUM_LISTS[enum]['valid']) > 0:
7634          file.Write("  static const EnumToString string_table[] = {\n")
7635          for value in _ENUM_LISTS[enum]['valid']:
7636            file.Write('    { %s, "%s" },\n' % (value, value))
7637          file.Write("""  };
7638  return GLES2Util::GetQualifiedEnumString(
7639      string_table, arraysize(string_table), value);
7640}
7641
7642""")
7643        else:
7644          file.Write("""  return GLES2Util::GetQualifiedEnumString(
7645      NULL, 0, value);
7646}
7647
7648""")
7649    file.Close()
7650
7651  def WritePepperGLES2Interface(self, filename, dev):
7652    """Writes the Pepper OpenGLES interface definition."""
7653    file = CHeaderWriter(
7654        filename,
7655        "// OpenGL ES interface.\n")
7656
7657    file.Write("#include \"ppapi/c/pp_resource.h\"\n")
7658    if dev:
7659      file.Write("#include \"ppapi/c/ppb_opengles2.h\"\n\n")
7660    else:
7661      file.Write("\n#ifndef __gl2_h_\n")
7662      for (k, v) in _GL_TYPES.iteritems():
7663        file.Write("typedef %s %s;\n" % (v, k))
7664      file.Write("#ifdef _WIN64\n")
7665      for (k, v) in _GL_TYPES_64.iteritems():
7666        file.Write("typedef %s %s;\n" % (v, k))
7667      file.Write("#else\n")
7668      for (k, v) in _GL_TYPES_32.iteritems():
7669        file.Write("typedef %s %s;\n" % (v, k))
7670      file.Write("#endif  // _WIN64\n")
7671      file.Write("#endif  // __gl2_h_\n\n")
7672
7673    for interface in self.pepper_interfaces:
7674      if interface.dev != dev:
7675        continue
7676      file.Write("#define %s_1_0 \"%s;1.0\"\n" %
7677                 (interface.GetInterfaceName(), interface.GetInterfaceString()))
7678      file.Write("#define %s %s_1_0\n" %
7679                 (interface.GetInterfaceName(), interface.GetInterfaceName()))
7680
7681      file.Write("\nstruct %s {\n" % interface.GetStructName())
7682      for func in self.original_functions:
7683        if not func.InPepperInterface(interface):
7684          continue
7685
7686        original_arg = func.MakeTypedPepperArgString("")
7687        context_arg = "PP_Resource context"
7688        if len(original_arg):
7689          arg = context_arg + ", " + original_arg
7690        else:
7691          arg = context_arg
7692        file.Write("  %s (*%s)(%s);\n" %
7693                   (func.return_type, func.GetPepperName(), arg))
7694      file.Write("};\n\n")
7695
7696
7697    file.Close()
7698
7699  def WritePepperGLES2Implementation(self, filename):
7700    """Writes the Pepper OpenGLES interface implementation."""
7701
7702    file = CWriter(filename)
7703    file.Write(_LICENSE)
7704    file.Write(_DO_NOT_EDIT_WARNING)
7705
7706    file.Write("#include \"ppapi/shared_impl/ppb_opengles2_shared.h\"\n\n")
7707    file.Write("#include \"base/logging.h\"\n")
7708    file.Write("#include \"gpu/command_buffer/client/gles2_implementation.h\"\n")
7709    file.Write("#include \"ppapi/shared_impl/ppb_graphics_3d_shared.h\"\n")
7710    file.Write("#include \"ppapi/thunk/enter.h\"\n\n")
7711
7712    file.Write("namespace ppapi {\n\n")
7713    file.Write("namespace {\n\n")
7714
7715    file.Write("typedef thunk::EnterResource<thunk::PPB_Graphics3D_API>"
7716               " Enter3D;\n\n")
7717
7718    file.Write("gpu::gles2::GLES2Implementation* ToGles2Impl(Enter3D*"
7719               " enter) {\n")
7720    file.Write("  DCHECK(enter);\n")
7721    file.Write("  DCHECK(enter->succeeded());\n")
7722    file.Write("  return static_cast<PPB_Graphics3D_Shared*>(enter->object())->"
7723               "gles2_impl();\n");
7724    file.Write("}\n\n");
7725
7726    for func in self.original_functions:
7727      if not func.InAnyPepperExtension():
7728        continue
7729
7730      original_arg = func.MakeTypedPepperArgString("")
7731      context_arg = "PP_Resource context_id"
7732      if len(original_arg):
7733        arg = context_arg + ", " + original_arg
7734      else:
7735        arg = context_arg
7736      file.Write("%s %s(%s) {\n" %
7737                 (func.return_type, func.GetPepperName(), arg))
7738      file.Write("  Enter3D enter(context_id, true);\n")
7739      file.Write("  if (enter.succeeded()) {\n")
7740
7741      return_str = "" if func.return_type == "void" else "return "
7742      file.Write("    %sToGles2Impl(&enter)->%s(%s);\n" %
7743                 (return_str, func.original_name,
7744                  func.MakeOriginalArgString("")))
7745      file.Write("  }")
7746      if func.return_type == "void":
7747        file.Write("\n")
7748      else:
7749        file.Write(" else {\n")
7750        error_return = "0"
7751        if func.GetInfo("error_return"):
7752          error_return = func.GetInfo("error_return")
7753        elif func.return_type == "GLboolean":
7754          error_return = "GL_FALSE"
7755        elif "*" in func.return_type:
7756          error_return = "NULL"
7757        file.Write("    return %s;\n" % error_return)
7758        file.Write("  }\n")
7759      file.Write("}\n\n")
7760
7761    file.Write("}  // namespace\n")
7762
7763    for interface in self.pepper_interfaces:
7764      file.Write("const %s* PPB_OpenGLES2_Shared::Get%sInterface() {\n" %
7765                 (interface.GetStructName(), interface.GetName()))
7766      file.Write("  static const struct %s "
7767                 "ppb_opengles2 = {\n" % interface.GetStructName())
7768      file.Write("    &")
7769      file.Write(",\n    &".join(
7770        f.GetPepperName() for f in self.original_functions
7771          if f.InPepperInterface(interface)))
7772      file.Write("\n")
7773
7774      file.Write("  };\n")
7775      file.Write("  return &ppb_opengles2;\n")
7776      file.Write("}\n")
7777
7778    file.Write("}  // namespace ppapi\n")
7779    file.Close()
7780
7781  def WriteGLES2ToPPAPIBridge(self, filename):
7782    """Connects GLES2 helper library to PPB_OpenGLES2 interface"""
7783
7784    file = CWriter(filename)
7785    file.Write(_LICENSE)
7786    file.Write(_DO_NOT_EDIT_WARNING)
7787
7788    file.Write("#ifndef GL_GLEXT_PROTOTYPES\n")
7789    file.Write("#define GL_GLEXT_PROTOTYPES\n")
7790    file.Write("#endif\n")
7791    file.Write("#include <GLES2/gl2.h>\n")
7792    file.Write("#include <GLES2/gl2ext.h>\n")
7793    file.Write("#include \"ppapi/lib/gl/gles2/gl2ext_ppapi.h\"\n\n")
7794
7795    for func in self.original_functions:
7796      if not func.InAnyPepperExtension():
7797        continue
7798
7799      interface = self.interface_info[func.GetInfo('pepper_interface') or '']
7800
7801      file.Write("%s GL_APIENTRY gl%s(%s) {\n" %
7802                 (func.return_type, func.GetPepperName(),
7803                  func.MakeTypedPepperArgString("")))
7804      return_str = "" if func.return_type == "void" else "return "
7805      interface_str = "glGet%sInterfacePPAPI()" % interface.GetName()
7806      original_arg = func.MakeOriginalArgString("")
7807      context_arg = "glGetCurrentContextPPAPI()"
7808      if len(original_arg):
7809        arg = context_arg + ", " + original_arg
7810      else:
7811        arg = context_arg
7812      if interface.GetName():
7813        file.Write("  const struct %s* ext = %s;\n" %
7814                   (interface.GetStructName(), interface_str))
7815        file.Write("  if (ext)\n")
7816        file.Write("    %sext->%s(%s);\n" %
7817                   (return_str, func.GetPepperName(), arg))
7818        if return_str:
7819          file.Write("  %s0;\n" % return_str)
7820      else:
7821        file.Write("  %s%s->%s(%s);\n" %
7822                   (return_str, interface_str, func.GetPepperName(), arg))
7823      file.Write("}\n\n")
7824    file.Close()
7825
7826  def WriteMojoGLCallVisitor(self, filename):
7827    """Provides the GL implementation for mojo"""
7828    file = CWriter(filename)
7829    file.Write(_LICENSE)
7830    file.Write(_DO_NOT_EDIT_WARNING)
7831
7832    for func in self.original_functions:
7833      if not func.IsCoreGLFunction():
7834        continue
7835      file.Write("VISIT_GL_CALL(%s, %s, (%s), (%s))\n" %
7836                             (func.name, func.return_type,
7837                              func.MakeTypedOriginalArgString(""),
7838                              func.MakeOriginalArgString("")))
7839
7840    file.Close()
7841
7842def Format(generated_files):
7843  for filename in generated_files:
7844    call(["clang-format", "-i", "-style=chromium", filename])
7845
7846def main(argv):
7847  """This is the main function."""
7848  parser = OptionParser()
7849  parser.add_option(
7850      "--output-dir",
7851      help="base directory for resulting files, under chrome/src. default is "
7852      "empty. Use this if you want the result stored under gen.")
7853  parser.add_option(
7854      "-v", "--verbose", action="store_true",
7855      help="prints more output.")
7856
7857  (options, args) = parser.parse_args(args=argv)
7858
7859  # Add in states and capabilites to GLState
7860  for state_name in sorted(_STATES.keys()):
7861    state = _STATES[state_name]
7862    if 'enum' in state:
7863      _ENUM_LISTS['GLState']['valid'].append(state['enum'])
7864    else:
7865      for item in state['states']:
7866        if 'extension_flag' in item:
7867          continue
7868        _ENUM_LISTS['GLState']['valid'].append(item['enum'])
7869  for capability in _CAPABILITY_FLAGS:
7870    _ENUM_LISTS['GLState']['valid'].append("GL_%s" % capability['name'].upper())
7871
7872  # This script lives under gpu/command_buffer, cd to base directory.
7873  os.chdir(os.path.dirname(__file__) + "/../..")
7874
7875  gen = GLGenerator(options.verbose)
7876  gen.ParseGLH("gpu/command_buffer/cmd_buffer_functions.txt")
7877
7878  # Support generating files under gen/
7879  if options.output_dir != None:
7880    os.chdir(options.output_dir)
7881
7882  gen.WritePepperGLES2Interface("ppapi/c/ppb_opengles2.h", False)
7883  gen.WritePepperGLES2Interface("ppapi/c/dev/ppb_opengles2ext_dev.h", True)
7884  gen.WriteGLES2ToPPAPIBridge("ppapi/lib/gl/gles2/gles2.c")
7885  gen.WritePepperGLES2Implementation(
7886      "ppapi/shared_impl/ppb_opengles2_shared.cc")
7887  os.chdir("gpu/command_buffer")
7888  gen.WriteCommandIds("common/gles2_cmd_ids_autogen.h")
7889  gen.WriteFormat("common/gles2_cmd_format_autogen.h")
7890  gen.WriteFormatTest("common/gles2_cmd_format_test_autogen.h")
7891  gen.WriteGLES2InterfaceHeader("client/gles2_interface_autogen.h")
7892  gen.WriteGLES2InterfaceStub("client/gles2_interface_stub_autogen.h")
7893  gen.WriteGLES2InterfaceStubImpl(
7894      "client/gles2_interface_stub_impl_autogen.h")
7895  gen.WriteGLES2ImplementationHeader("client/gles2_implementation_autogen.h")
7896  gen.WriteGLES2Implementation("client/gles2_implementation_impl_autogen.h")
7897  gen.WriteGLES2ImplementationUnitTests(
7898      "client/gles2_implementation_unittest_autogen.h")
7899  gen.WriteGLES2TraceImplementationHeader(
7900      "client/gles2_trace_implementation_autogen.h")
7901  gen.WriteGLES2TraceImplementation(
7902      "client/gles2_trace_implementation_impl_autogen.h")
7903  gen.WriteGLES2CLibImplementation("client/gles2_c_lib_autogen.h")
7904  gen.WriteCmdHelperHeader("client/gles2_cmd_helper_autogen.h")
7905  gen.WriteServiceImplementation("service/gles2_cmd_decoder_autogen.h")
7906  gen.WriteServiceContextStateHeader("service/context_state_autogen.h")
7907  gen.WriteServiceContextStateImpl("service/context_state_impl_autogen.h")
7908  gen.WriteClientContextStateHeader("client/client_context_state_autogen.h")
7909  gen.WriteClientContextStateImpl(
7910      "client/client_context_state_impl_autogen.h")
7911  gen.WriteServiceUnitTests("service/gles2_cmd_decoder_unittest_%d_autogen.h")
7912  gen.WriteServiceUtilsHeader("service/gles2_cmd_validation_autogen.h")
7913  gen.WriteServiceUtilsImplementation(
7914      "service/gles2_cmd_validation_implementation_autogen.h")
7915  gen.WriteCommonUtilsHeader("common/gles2_cmd_utils_autogen.h")
7916  gen.WriteCommonUtilsImpl("common/gles2_cmd_utils_implementation_autogen.h")
7917  gen.WriteGLES2Header("../GLES2/gl2chromium_autogen.h")
7918  gen.WriteMojoGLCallVisitor(
7919      "../../mojo/public/c/gles2/gles2_call_visitor_autogen.h")
7920
7921  Format([
7922      "common/gles2_cmd_format_autogen.h",
7923      "common/gles2_cmd_format_test_autogen.h",
7924      "common/gles2_cmd_ids_autogen.h",
7925      "common/gles2_cmd_utils_autogen.h",
7926      "common/gles2_cmd_utils_implementation_autogen.h",
7927      "client/client_context_state_autogen.h",
7928      "client/client_context_state_impl_autogen.h",
7929      "client/gles2_cmd_helper_autogen.h",
7930      "client/gles2_c_lib_autogen.h",
7931      "client/gles2_implementation_autogen.h",
7932      "client/gles2_implementation_impl_autogen.h",
7933      "client/gles2_implementation_unittest_autogen.h",
7934      "client/gles2_interface_autogen.h",
7935      "client/gles2_interface_stub_autogen.h",
7936      "client/gles2_interface_stub_impl_autogen.h",
7937      "client/gles2_trace_implementation_autogen.h",
7938      "client/gles2_trace_implementation_impl_autogen.h",
7939      "service/context_state_autogen.h",
7940      "service/context_state_impl_autogen.h",
7941      "service/gles2_cmd_decoder_autogen.h",
7942      "service/gles2_cmd_decoder_unittest_0_autogen.h",
7943      "service/gles2_cmd_decoder_unittest_1_autogen.h",
7944      "service/gles2_cmd_decoder_unittest_2_autogen.h",
7945      "service/gles2_cmd_decoder_unittest_3_autogen.h",
7946      "service/gles2_cmd_validation_autogen.h",
7947      "service/gles2_cmd_validation_implementation_autogen.h"])
7948  os.chdir("../..")
7949  Format([
7950      "gpu/GLES2/gl2chromium_autogen.h",
7951      "mojo/public/c/gles2/gles2_call_visitor_autogen.h",
7952      "ppapi/c/dev/ppb_opengles2ext_dev.h",
7953      "ppapi/c/ppb_opengles2.h",
7954      "ppapi/lib/gl/gles2/gles2.c",
7955      "ppapi/shared_impl/ppb_opengles2_shared.cc"])
7956
7957  if gen.errors > 0:
7958    print "%d errors" % gen.errors
7959    return 1
7960  return 0
7961
7962
7963if __name__ == '__main__':
7964  sys.exit(main(sys.argv[1:]))
7965