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