• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""code generator for GLES2 command buffers."""
7
8import itertools
9import os
10import os.path
11import sys
12import re
13from optparse import OptionParser
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  'BlitFramebufferCHROMIUM': {
1264    'decoder_func': 'DoBlitFramebufferCHROMIUM',
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  'RenderbufferStorageMultisampleCHROMIUM': {
1905    'cmd_comment':
1906        '// GL_CHROMIUM_framebuffer_multisample\n',
1907    'decoder_func': 'DoRenderbufferStorageMultisampleCHROMIUM',
1908    'gl_test_func': 'glRenderbufferStorageMultisampleCHROMIUM',
1909    'expectation': False,
1910    'unit_test': False,
1911    'extension': True,
1912    'pepper_interface': 'FramebufferMultisample',
1913  },
1914  'RenderbufferStorageMultisampleEXT': {
1915    'cmd_comment':
1916        '// GL_EXT_multisampled_render_to_texture\n',
1917    'decoder_func': 'DoRenderbufferStorageMultisampleEXT',
1918    'gl_test_func': 'glRenderbufferStorageMultisampleEXT',
1919    'expectation': False,
1920    'unit_test': False,
1921    'extension': True,
1922  },
1923  'ReadPixels': {
1924    'cmd_comment':
1925        '// ReadPixels has the result separated from the pixel buffer so that\n'
1926        '// it is easier to specify the result going to some specific place\n'
1927        '// that exactly fits the rectangle of pixels.\n',
1928    'type': 'Custom',
1929    'immediate': False,
1930    'impl_func': False,
1931    'client_test': False,
1932    'cmd_args':
1933        'GLint x, GLint y, GLsizei width, GLsizei height, '
1934        'GLenumReadPixelFormat format, GLenumReadPixelType type, '
1935        'uint32 pixels_shm_id, uint32 pixels_shm_offset, '
1936        'uint32 result_shm_id, uint32 result_shm_offset, '
1937        'GLboolean async',
1938    'result': ['uint32'],
1939    'defer_reads': True,
1940  },
1941  'RegisterSharedIdsCHROMIUM': {
1942    'type': 'Custom',
1943    'decoder_func': 'DoRegisterSharedIdsCHROMIUM',
1944    'impl_func': False,
1945    'expectation': False,
1946    'immediate': False,
1947    'extension': True,
1948    'chromium': True,
1949  },
1950  'ReleaseShaderCompiler': {
1951    'decoder_func': 'DoReleaseShaderCompiler',
1952    'unit_test': False,
1953  },
1954  'ShaderBinary': {
1955    'type': 'Custom',
1956    'client_test': False,
1957  },
1958  'ShaderSource': {
1959    'type': 'Manual',
1960    'immediate': False,
1961    'bucket': True,
1962    'needs_size': True,
1963    'client_test': False,
1964    'cmd_args':
1965        'GLuint shader, const char* data',
1966    'pepper_args':
1967        'GLuint shader, GLsizei count, const char** str, const GLint* length',
1968  },
1969  'StencilMask': {
1970    'type': 'StateSetFrontBack',
1971    'state': 'StencilMask',
1972    'no_gl': True,
1973    'expectation': False,
1974  },
1975  'StencilMaskSeparate': {
1976    'type': 'StateSetFrontBackSeparate',
1977    'state': 'StencilMask',
1978    'no_gl': True,
1979    'expectation': False,
1980  },
1981  'SwapBuffers': {
1982    'impl_func': False,
1983    'decoder_func': 'DoSwapBuffers',
1984    'unit_test': False,
1985    'client_test': False,
1986    'extension': True,
1987  },
1988  'TexImage2D': {
1989    'type': 'Manual',
1990    'immediate': False,
1991    'client_test': False,
1992  },
1993  'TexParameterf': {
1994    'decoder_func': 'DoTexParameterf',
1995    'gl_test_func': 'glTexParameteri',
1996    'valid_args': {
1997      '2': 'GL_NEAREST'
1998    },
1999  },
2000  'TexParameteri': {
2001    'decoder_func': 'DoTexParameteri',
2002    'valid_args': {
2003      '2': 'GL_NEAREST'
2004    },
2005  },
2006  'TexParameterfv': {
2007    'type': 'PUT',
2008    'data_type': 'GLfloat',
2009    'data_value': 'GL_NEAREST',
2010    'count': 1,
2011    'decoder_func': 'DoTexParameterfv',
2012    'gl_test_func': 'glTexParameteri',
2013    'first_element_only': True,
2014  },
2015  'TexParameteriv': {
2016    'type': 'PUT',
2017    'data_type': 'GLint',
2018    'data_value': 'GL_NEAREST',
2019    'count': 1,
2020    'decoder_func': 'DoTexParameteriv',
2021    'gl_test_func': 'glTexParameteri',
2022    'first_element_only': True,
2023  },
2024  'TexSubImage2D': {
2025    'type': 'Manual',
2026    'immediate': False,
2027    'client_test': False,
2028    'cmd_args': 'GLenumTextureTarget target, GLint level, '
2029                'GLint xoffset, GLint yoffset, '
2030                'GLsizei width, GLsizei height, '
2031                'GLenumTextureFormat format, GLenumPixelType type, '
2032                'const void* pixels, GLboolean internal'
2033  },
2034  'Uniform1f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 1},
2035  'Uniform1fv': {
2036    'type': 'PUTn',
2037    'data_type': 'GLfloat',
2038    'count': 1,
2039    'decoder_func': 'DoUniform1fv',
2040  },
2041  'Uniform1i': {'decoder_func': 'DoUniform1i', 'unit_test': False},
2042  'Uniform1iv': {
2043    'type': 'PUTn',
2044    'data_type': 'GLint',
2045    'count': 1,
2046    'decoder_func': 'DoUniform1iv',
2047    'unit_test': False,
2048  },
2049  'Uniform2i': {'type': 'PUTXn', 'data_type': 'GLint', 'count': 2},
2050  'Uniform2f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 2},
2051  'Uniform2fv': {
2052    'type': 'PUTn',
2053    'data_type': 'GLfloat',
2054    'count': 2,
2055    'decoder_func': 'DoUniform2fv',
2056  },
2057  'Uniform2iv': {
2058    'type': 'PUTn',
2059    'data_type': 'GLint',
2060    'count': 2,
2061    'decoder_func': 'DoUniform2iv',
2062  },
2063  'Uniform3i': {'type': 'PUTXn', 'data_type': 'GLint', 'count': 3},
2064  'Uniform3f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 3},
2065  'Uniform3fv': {
2066    'type': 'PUTn',
2067    'data_type': 'GLfloat',
2068    'count': 3,
2069    'decoder_func': 'DoUniform3fv',
2070  },
2071  'Uniform3iv': {
2072    'type': 'PUTn',
2073    'data_type': 'GLint',
2074    'count': 3,
2075    'decoder_func': 'DoUniform3iv',
2076  },
2077  'Uniform4i': {'type': 'PUTXn', 'data_type': 'GLint', 'count': 4},
2078  'Uniform4f': {'type': 'PUTXn', 'data_type': 'GLfloat', 'count': 4},
2079  'Uniform4fv': {
2080    'type': 'PUTn',
2081    'data_type': 'GLfloat',
2082    'count': 4,
2083    'decoder_func': 'DoUniform4fv',
2084  },
2085  'Uniform4iv': {
2086    'type': 'PUTn',
2087    'data_type': 'GLint',
2088    'count': 4,
2089    'decoder_func': 'DoUniform4iv',
2090  },
2091  'UniformMatrix2fv': {
2092    'type': 'PUTn',
2093    'data_type': 'GLfloat',
2094    'count': 4,
2095    'decoder_func': 'DoUniformMatrix2fv',
2096  },
2097  'UniformMatrix3fv': {
2098    'type': 'PUTn',
2099    'data_type': 'GLfloat',
2100    'count': 9,
2101    'decoder_func': 'DoUniformMatrix3fv',
2102  },
2103  'UniformMatrix4fv': {
2104    'type': 'PUTn',
2105    'data_type': 'GLfloat',
2106    'count': 16,
2107    'decoder_func': 'DoUniformMatrix4fv',
2108  },
2109  'UnmapBufferCHROMIUM': {
2110    'gen_cmd': False,
2111    'extension': True,
2112    'chromium': True,
2113    'client_test': False,
2114  },
2115  'UnmapBufferSubDataCHROMIUM': {
2116    'gen_cmd': False,
2117    'extension': True,
2118    'chromium': True,
2119    'client_test': False,
2120    'pepper_interface': 'ChromiumMapSub',
2121  },
2122  'UnmapImageCHROMIUM': {
2123    'gen_cmd': False,
2124    'extension': True,
2125    'chromium': True,
2126    'client_test': False,
2127  },
2128  'UnmapTexSubImage2DCHROMIUM': {
2129    'gen_cmd': False,
2130    'extension': True,
2131    'chromium': True,
2132    'client_test': False,
2133    'pepper_interface': 'ChromiumMapSub',
2134  },
2135  'UseProgram': {
2136    'decoder_func': 'DoUseProgram',
2137    'impl_func': False,
2138    'unit_test': False,
2139  },
2140  'ValidateProgram': {'decoder_func': 'DoValidateProgram'},
2141  'VertexAttrib1f': {'decoder_func': 'DoVertexAttrib1f'},
2142  'VertexAttrib1fv': {
2143    'type': 'PUT',
2144    'data_type': 'GLfloat',
2145    'count': 1,
2146    'decoder_func': 'DoVertexAttrib1fv',
2147  },
2148  'VertexAttrib2f': {'decoder_func': 'DoVertexAttrib2f'},
2149  'VertexAttrib2fv': {
2150    'type': 'PUT',
2151    'data_type': 'GLfloat',
2152    'count': 2,
2153    'decoder_func': 'DoVertexAttrib2fv',
2154  },
2155  'VertexAttrib3f': {'decoder_func': 'DoVertexAttrib3f'},
2156  'VertexAttrib3fv': {
2157    'type': 'PUT',
2158    'data_type': 'GLfloat',
2159    'count': 3,
2160    'decoder_func': 'DoVertexAttrib3fv',
2161  },
2162  'VertexAttrib4f': {'decoder_func': 'DoVertexAttrib4f'},
2163  'VertexAttrib4fv': {
2164    'type': 'PUT',
2165    'data_type': 'GLfloat',
2166    'count': 4,
2167    'decoder_func': 'DoVertexAttrib4fv',
2168  },
2169  'VertexAttribPointer': {
2170      'type': 'Manual',
2171      'cmd_args': 'GLuint indx, GLintVertexAttribSize size, '
2172                  'GLenumVertexAttribType type, GLboolean normalized, '
2173                  'GLsizei stride, GLuint offset',
2174      'client_test': False,
2175  },
2176  'Scissor': {
2177    'type': 'StateSet',
2178    'state': 'Scissor',
2179  },
2180  'Viewport': {
2181    'decoder_func': 'DoViewport',
2182  },
2183  'ResizeCHROMIUM': {
2184      'type': 'Custom',
2185      'impl_func': False,
2186      'unit_test': False,
2187      'extension': True,
2188      'chromium': True,
2189  },
2190  'GetRequestableExtensionsCHROMIUM': {
2191    'type': 'Custom',
2192    'impl_func': False,
2193    'immediate': False,
2194    'cmd_args': 'uint32 bucket_id',
2195    'extension': True,
2196    'chromium': True,
2197  },
2198  'RequestExtensionCHROMIUM': {
2199    'type': 'Custom',
2200    'impl_func': False,
2201    'immediate': False,
2202    'client_test': False,
2203    'cmd_args': 'uint32 bucket_id',
2204    'extension': True,
2205    'chromium': True,
2206  },
2207  'RateLimitOffscreenContextCHROMIUM': {
2208    'gen_cmd': False,
2209    'extension': True,
2210    'chromium': True,
2211    'client_test': False,
2212  },
2213  'CreateStreamTextureCHROMIUM':  {
2214    'type': 'Custom',
2215    'cmd_args': 'GLuint client_id, void* result',
2216    'result': ['GLuint'],
2217    'immediate': False,
2218    'impl_func': False,
2219    'expectation': False,
2220    'extension': True,
2221    'chromium': True,
2222    'client_test': False,
2223   },
2224  'DestroyStreamTextureCHROMIUM':  {
2225    'type': 'Custom',
2226    'impl_func': False,
2227    'expectation': False,
2228    'extension': True,
2229    'chromium': True,
2230   },
2231  'TexImageIOSurface2DCHROMIUM': {
2232    'decoder_func': 'DoTexImageIOSurface2DCHROMIUM',
2233    'unit_test': False,
2234    'extension': True,
2235    'chromium': True,
2236  },
2237  'CopyTextureCHROMIUM': {
2238    'decoder_func': 'DoCopyTextureCHROMIUM',
2239    'unit_test': False,
2240    'extension': True,
2241    'chromium': True,
2242  },
2243  'TexStorage2DEXT': {
2244    'unit_test': False,
2245    'extension': True,
2246    'decoder_func': 'DoTexStorage2DEXT',
2247  },
2248  'DrawArraysInstancedANGLE': {
2249    'type': 'Manual',
2250    'cmd_args': 'GLenumDrawMode mode, GLint first, GLsizei count, '
2251                'GLsizei primcount',
2252    'extension': True,
2253    'unit_test': False,
2254    'pepper_interface': 'InstancedArrays',
2255    'defer_draws': True,
2256  },
2257  'DrawBuffersEXT': {
2258    'type': 'PUTn',
2259    'decoder_func': 'DoDrawBuffersEXT',
2260    'data_type': 'GLenum',
2261    'count': 1,
2262    'client_test': False,
2263    'unit_test': False,
2264    'extension': True,
2265  },
2266  'DrawElementsInstancedANGLE': {
2267    'type': 'Manual',
2268    'cmd_args': 'GLenumDrawMode mode, GLsizei count, '
2269                'GLenumIndexType type, GLuint index_offset, GLsizei primcount',
2270    'extension': True,
2271    'unit_test': False,
2272    'client_test': False,
2273    'pepper_interface': 'InstancedArrays',
2274    'defer_draws': True,
2275  },
2276  'VertexAttribDivisorANGLE': {
2277    'type': 'Manual',
2278    'cmd_args': 'GLuint index, GLuint divisor',
2279    'extension': True,
2280    'unit_test': False,
2281    'pepper_interface': 'InstancedArrays',
2282  },
2283  'GenQueriesEXT': {
2284    'type': 'GENn',
2285    'gl_test_func': 'glGenQueriesARB',
2286    'resource_type': 'Query',
2287    'resource_types': 'Queries',
2288    'unit_test': False,
2289    'pepper_interface': 'Query',
2290  },
2291  'DeleteQueriesEXT': {
2292    'type': 'DELn',
2293    'gl_test_func': 'glDeleteQueriesARB',
2294    'resource_type': 'Query',
2295    'resource_types': 'Queries',
2296    'unit_test': False,
2297    'pepper_interface': 'Query',
2298  },
2299  'IsQueryEXT': {
2300    'gen_cmd': False,
2301    'client_test': False,
2302    'pepper_interface': 'Query',
2303  },
2304  'BeginQueryEXT': {
2305    'type': 'Manual',
2306    'cmd_args': 'GLenumQueryTarget target, GLidQuery id, void* sync_data',
2307    'immediate': False,
2308    'gl_test_func': 'glBeginQuery',
2309    'pepper_interface': 'Query',
2310  },
2311  'EndQueryEXT': {
2312    'type': 'Manual',
2313    'cmd_args': 'GLenumQueryTarget target, GLuint submit_count',
2314    'gl_test_func': 'glEndnQuery',
2315    'client_test': False,
2316    'pepper_interface': 'Query',
2317  },
2318  'GetQueryivEXT': {
2319    'gen_cmd': False,
2320    'client_test': False,
2321    'gl_test_func': 'glGetQueryiv',
2322    'pepper_interface': 'Query',
2323  },
2324  'GetQueryObjectuivEXT': {
2325    'gen_cmd': False,
2326    'client_test': False,
2327    'gl_test_func': 'glGetQueryObjectuiv',
2328    'pepper_interface': 'Query',
2329  },
2330  'BindUniformLocationCHROMIUM': {
2331    'type': 'GLchar',
2332    'extension': True,
2333    'bucket': True,
2334    'needs_size': True,
2335    'gl_test_func': 'DoBindUniformLocationCHROMIUM',
2336    'immediate': False,
2337  },
2338  'InsertEventMarkerEXT': {
2339    'type': 'GLcharN',
2340    'decoder_func': 'DoInsertEventMarkerEXT',
2341    'expectation': False,
2342    'extension': True,
2343  },
2344  'PushGroupMarkerEXT': {
2345    'type': 'GLcharN',
2346    'decoder_func': 'DoPushGroupMarkerEXT',
2347    'expectation': False,
2348    'extension': True,
2349  },
2350  'PopGroupMarkerEXT': {
2351    'decoder_func': 'DoPopGroupMarkerEXT',
2352    'expectation': False,
2353    'extension': True,
2354    'impl_func': False,
2355  },
2356
2357  'GenVertexArraysOES': {
2358    'type': 'GENn',
2359    'extension': True,
2360    'gl_test_func': 'glGenVertexArraysOES',
2361    'resource_type': 'VertexArray',
2362    'resource_types': 'VertexArrays',
2363    'unit_test': False,
2364  },
2365  'BindVertexArrayOES': {
2366    'type': 'Bind',
2367    'extension': True,
2368    'gl_test_func': 'glBindVertexArrayOES',
2369    'decoder_func': 'DoBindVertexArrayOES',
2370    'gen_func': 'GenVertexArraysOES',
2371    'unit_test': False,
2372    'client_test': False,
2373  },
2374  'DeleteVertexArraysOES': {
2375    'type': 'DELn',
2376    'extension': True,
2377    'gl_test_func': 'glDeleteVertexArraysOES',
2378    'resource_type': 'VertexArray',
2379    'resource_types': 'VertexArrays',
2380    'unit_test': False,
2381  },
2382  'IsVertexArrayOES': {
2383    'type': 'Is',
2384    'extension': True,
2385    'gl_test_func': 'glIsVertexArrayOES',
2386    'decoder_func': 'DoIsVertexArrayOES',
2387    'expectation': False,
2388    'unit_test': False,
2389  },
2390  'BindTexImage2DCHROMIUM': {
2391    'decoder_func': 'DoBindTexImage2DCHROMIUM',
2392    'unit_test': False,
2393    'extension': True,
2394    'chromium': True,
2395  },
2396  'ReleaseTexImage2DCHROMIUM': {
2397    'decoder_func': 'DoReleaseTexImage2DCHROMIUM',
2398    'unit_test': False,
2399    'extension': True,
2400    'chromium': True,
2401  },
2402  'ShallowFinishCHROMIUM': {
2403    'impl_func': False,
2404    'gen_cmd': False,
2405    'extension': True,
2406    'chromium': True,
2407    'client_test': False,
2408  },
2409  'ShallowFlushCHROMIUM': {
2410    'impl_func': False,
2411    'gen_cmd': False,
2412    'extension': True,
2413    'chromium': True,
2414    'client_test': False,
2415  },
2416  'TraceBeginCHROMIUM': {
2417    'type': 'Custom',
2418    'impl_func': False,
2419    'immediate': False,
2420    'client_test': False,
2421    'cmd_args': 'GLuint bucket_id',
2422    'extension': True,
2423    'chromium': True,
2424  },
2425  'TraceEndCHROMIUM': {
2426    'impl_func': False,
2427    'immediate': False,
2428    'client_test': False,
2429    'decoder_func': 'DoTraceEndCHROMIUM',
2430    'unit_test': False,
2431    'extension': True,
2432    'chromium': True,
2433  },
2434  'AsyncTexImage2DCHROMIUM': {
2435    'type': 'Manual',
2436    'immediate': False,
2437    'client_test': False,
2438    'extension': True,
2439    'chromium': True,
2440  },
2441  'AsyncTexSubImage2DCHROMIUM': {
2442    'type': 'Manual',
2443    'immediate': False,
2444    'client_test': False,
2445    'extension': True,
2446    'chromium': True,
2447  },
2448  'WaitAsyncTexImage2DCHROMIUM': {
2449    'type': 'Manual',
2450    'immediate': False,
2451    'client_test': False,
2452    'extension': True,
2453    'chromium': True,
2454  },
2455  'DiscardFramebufferEXT': {
2456    'type': 'PUTn',
2457    'count': 1,
2458    'data_type': 'GLenum',
2459    'cmd_args': 'GLenum target, GLsizei count, '
2460        'const GLenum* attachments',
2461    'decoder_func': 'DoDiscardFramebufferEXT',
2462    'unit_test': False,
2463    'client_test': False,
2464    'extension': True,
2465  },
2466  'LoseContextCHROMIUM': {
2467    'type': 'Manual',
2468    'impl_func': True,
2469    'extension': True,
2470    'chromium': True,
2471  },
2472  'InsertSyncPointCHROMIUM': {
2473    'type': 'HandWritten',
2474    'impl_func': False,
2475    'extension': True,
2476    'chromium': True,
2477  },
2478  'WaitSyncPointCHROMIUM': {
2479    'type': 'Custom',
2480    'impl_func': True,
2481    'extension': True,
2482    'chromium': True,
2483  },
2484  'DiscardBackbufferCHROMIUM': {
2485    'type': 'Custom',
2486    'impl_func': True,
2487    'extension': True,
2488    'chromium': True,
2489  },
2490}
2491
2492
2493def Grouper(n, iterable, fillvalue=None):
2494  """Collect data into fixed-length chunks or blocks"""
2495  args = [iter(iterable)] * n
2496  return itertools.izip_longest(fillvalue=fillvalue, *args)
2497
2498
2499def SplitWords(input_string):
2500  """Transforms a input_string into a list of lower-case components.
2501
2502  Args:
2503    input_string: the input string.
2504
2505  Returns:
2506    a list of lower-case words.
2507  """
2508  if input_string.find('_') > -1:
2509    # 'some_TEXT_' -> 'some text'
2510    return input_string.replace('_', ' ').strip().lower().split()
2511  else:
2512    if re.search('[A-Z]', input_string) and re.search('[a-z]', input_string):
2513      # mixed case.
2514      # look for capitalization to cut input_strings
2515      # 'SomeText' -> 'Some Text'
2516      input_string = re.sub('([A-Z])', r' \1', input_string).strip()
2517      # 'Vector3' -> 'Vector 3'
2518      input_string = re.sub('([^0-9])([0-9])', r'\1 \2', input_string)
2519    return input_string.lower().split()
2520
2521
2522def Lower(words):
2523  """Makes a lower-case identifier from words.
2524
2525  Args:
2526    words: a list of lower-case words.
2527
2528  Returns:
2529    the lower-case identifier.
2530  """
2531  return '_'.join(words)
2532
2533
2534def ToUnderscore(input_string):
2535  """converts CamelCase to camel_case."""
2536  words = SplitWords(input_string)
2537  return Lower(words)
2538
2539
2540class CWriter(object):
2541  """Writes to a file formatting it for Google's style guidelines."""
2542
2543  def __init__(self, filename):
2544    self.filename = filename
2545    self.file_num = 0
2546    self.content = []
2547
2548  def SetFileNum(self, num):
2549    """Used to help write number files and tests."""
2550    self.file_num = num
2551
2552  def Write(self, string):
2553    """Writes a string to a file spliting if it's > 80 characters."""
2554    lines = string.splitlines()
2555    num_lines = len(lines)
2556    for ii in range(0, num_lines):
2557      self.__WriteLine(lines[ii], ii < (num_lines - 1) or string[-1] == '\n')
2558
2559  def __FindSplit(self, string):
2560    """Finds a place to split a string."""
2561    splitter = string.find('=')
2562    if splitter >= 1 and not string[splitter + 1] == '=' and splitter < 80:
2563      return splitter
2564    # parts = string.split('(')
2565    parts = re.split("(?<=[^\"])\((?!\")", string)
2566    fptr = re.compile('\*\w*\)')
2567    if len(parts) > 1:
2568      splitter = len(parts[0])
2569      for ii in range(1, len(parts)):
2570        # Don't split on the dot in "if (.condition)".
2571        if (not parts[ii - 1][-3:] == "if " and
2572            # Don't split "(.)" or "(.*fptr)".
2573            (len(parts[ii]) > 0 and
2574                not parts[ii][0] == ")" and not fptr.match(parts[ii]))
2575            and splitter < 80):
2576          return splitter
2577        splitter += len(parts[ii]) + 1
2578    done = False
2579    end = len(string)
2580    last_splitter = -1
2581    while not done:
2582      splitter = string[0:end].rfind(',')
2583      if splitter < 0 or (splitter > 0 and string[splitter - 1] == '"'):
2584        return last_splitter
2585      elif splitter >= 80:
2586        end = splitter
2587      else:
2588        return splitter
2589
2590  def __WriteLine(self, line, ends_with_eol):
2591    """Given a signle line, writes it to a file, splitting if it's > 80 chars"""
2592    if len(line) >= 80:
2593      i = self.__FindSplit(line)
2594      if i > 0:
2595        line1 = line[0:i + 1]
2596        if line1[-1] == ' ':
2597          line1 = line1[:-1]
2598        lineend = ''
2599        if line1[0] == '#':
2600          lineend = ' \\'
2601        nolint = ''
2602        if len(line1) > 80:
2603          nolint = '  // NOLINT'
2604        self.__AddLine(line1 + nolint + lineend + '\n')
2605        match = re.match("( +)", line1)
2606        indent = ""
2607        if match:
2608          indent = match.group(1)
2609        splitter = line[i]
2610        if not splitter == ',':
2611          indent = "    " + indent
2612        self.__WriteLine(indent + line[i + 1:].lstrip(), True)
2613        return
2614    nolint = ''
2615    if len(line) > 80:
2616      nolint = '  // NOLINT'
2617    self.__AddLine(line + nolint)
2618    if ends_with_eol:
2619      self.__AddLine('\n')
2620
2621  def __AddLine(self, line):
2622    self.content.append(line)
2623
2624  def Close(self):
2625    """Close the file."""
2626    content = "".join(self.content)
2627    write_file = True
2628    if os.path.exists(self.filename):
2629      old_file = open(self.filename, "rb");
2630      old_content = old_file.read()
2631      old_file.close();
2632      if content == old_content:
2633        write_file = False
2634    if write_file:
2635      file = open(self.filename, "wb")
2636      file.write(content)
2637      file.close()
2638
2639
2640class CHeaderWriter(CWriter):
2641  """Writes a C Header file."""
2642
2643  _non_alnum_re = re.compile(r'[^a-zA-Z0-9]')
2644
2645  def __init__(self, filename, file_comment = None):
2646    CWriter.__init__(self, filename)
2647
2648    base = os.path.abspath(filename)
2649    while os.path.basename(base) != 'src':
2650      new_base = os.path.dirname(base)
2651      assert new_base != base  # Prevent infinite loop.
2652      base = new_base
2653
2654    hpath = os.path.relpath(filename, base)
2655    self.guard = self._non_alnum_re.sub('_', hpath).upper() + '_'
2656
2657    self.Write(_LICENSE)
2658    self.Write(_DO_NOT_EDIT_WARNING)
2659    if not file_comment == None:
2660      self.Write(file_comment)
2661    self.Write("#ifndef %s\n" % self.guard)
2662    self.Write("#define %s\n\n" % self.guard)
2663
2664  def Close(self):
2665    self.Write("#endif  // %s\n\n" % self.guard)
2666    CWriter.Close(self)
2667
2668class TypeHandler(object):
2669  """This class emits code for a particular type of function."""
2670
2671  _remove_expected_call_re = re.compile(r'  EXPECT_CALL.*?;\n', re.S)
2672
2673  def __init__(self):
2674    pass
2675
2676  def InitFunction(self, func):
2677    """Add or adjust anything type specific for this function."""
2678    if func.GetInfo('needs_size') and not func.name.endswith('Bucket'):
2679      func.AddCmdArg(DataSizeArgument('data_size'))
2680
2681  def AddImmediateFunction(self, generator, func):
2682    """Adds an immediate version of a function."""
2683    # Generate an immediate command if there is only 1 pointer arg.
2684    immediate = func.GetInfo('immediate')  # can be True, False or None
2685    if immediate == True or immediate == None:
2686      if func.num_pointer_args == 1 or immediate:
2687        generator.AddFunction(ImmediateFunction(func))
2688
2689  def AddBucketFunction(self, generator, func):
2690    """Adds a bucket version of a function."""
2691    # Generate an immediate command if there is only 1 pointer arg.
2692    bucket = func.GetInfo('bucket')  # can be True, False or None
2693    if bucket:
2694      generator.AddFunction(BucketFunction(func))
2695
2696  def WriteStruct(self, func, file):
2697    """Writes a structure that matches the arguments to a function."""
2698    comment = func.GetInfo('cmd_comment')
2699    if not comment == None:
2700      file.Write(comment)
2701    file.Write("struct %s {\n" % func.name)
2702    file.Write("  typedef %s ValueType;\n" % func.name)
2703    file.Write("  static const CommandId kCmdId = k%s;\n" % func.name)
2704    func.WriteCmdArgFlag(file)
2705    file.Write("\n")
2706    result = func.GetInfo('result')
2707    if not result == None:
2708      if len(result) == 1:
2709        file.Write("  typedef %s Result;\n\n" % result[0])
2710      else:
2711        file.Write("  struct Result {\n")
2712        for line in result:
2713          file.Write("    %s;\n" % line)
2714        file.Write("  };\n\n")
2715
2716    func.WriteCmdComputeSize(file)
2717    func.WriteCmdSetHeader(file)
2718    func.WriteCmdInit(file)
2719    func.WriteCmdSet(file)
2720
2721    file.Write("  gpu::CommandHeader header;\n")
2722    args = func.GetCmdArgs()
2723    for arg in args:
2724      file.Write("  %s %s;\n" % (arg.cmd_type, arg.name))
2725    file.Write("};\n")
2726    file.Write("\n")
2727
2728    size = len(args) * _SIZE_OF_UINT32 + _SIZE_OF_COMMAND_HEADER
2729    file.Write("COMPILE_ASSERT(sizeof(%s) == %d,\n" % (func.name, size))
2730    file.Write("               Sizeof_%s_is_not_%d);\n" % (func.name, size))
2731    file.Write("COMPILE_ASSERT(offsetof(%s, header) == 0,\n" % func.name)
2732    file.Write("               OffsetOf_%s_header_not_0);\n" % func.name)
2733    offset = _SIZE_OF_COMMAND_HEADER
2734    for arg in args:
2735      file.Write("COMPILE_ASSERT(offsetof(%s, %s) == %d,\n" %
2736                 (func.name, arg.name, offset))
2737      file.Write("               OffsetOf_%s_%s_not_%d);\n" %
2738                 (func.name, arg.name, offset))
2739      offset += _SIZE_OF_UINT32
2740    if not result == None and len(result) > 1:
2741      offset = 0;
2742      for line in result:
2743        parts = line.split()
2744        name = parts[-1]
2745        check = """
2746COMPILE_ASSERT(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d,
2747               OffsetOf_%(cmd_name)s_Result_%(field_name)s_not_%(offset)d);
2748"""
2749        file.Write((check.strip() + "\n") % {
2750              'cmd_name': func.name,
2751              'field_name': name,
2752              'offset': offset,
2753            })
2754        offset += _SIZE_OF_UINT32
2755    file.Write("\n")
2756
2757  def WriteHandlerImplementation(self, func, file):
2758    """Writes the handler implementation for this command."""
2759    file.Write("  %s(%s);\n" %
2760               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
2761
2762  def WriteCmdSizeTest(self, func, file):
2763    """Writes the size test for a command."""
2764    file.Write("  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n")
2765
2766  def WriteFormatTest(self, func, file):
2767    """Writes a format test for a command."""
2768    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
2769    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
2770               (func.name, func.name))
2771    file.Write("  void* next_cmd = cmd.Set(\n")
2772    file.Write("      &cmd")
2773    args = func.GetCmdArgs()
2774    for value, arg in enumerate(args):
2775      file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 11))
2776    file.Write(");\n")
2777    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
2778               func.name)
2779    file.Write("            cmd.header.command);\n")
2780    func.type_handler.WriteCmdSizeTest(func, file)
2781    for value, arg in enumerate(args):
2782      file.Write("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" %
2783                 (arg.type, value + 11, arg.name))
2784    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
2785    file.Write("      next_cmd, sizeof(cmd));\n")
2786    file.Write("}\n")
2787    file.Write("\n")
2788
2789  def WriteImmediateFormatTest(self, func, file):
2790    """Writes a format test for an immediate version of a command."""
2791    pass
2792
2793  def WriteBucketFormatTest(self, func, file):
2794    """Writes a format test for a bucket version of a command."""
2795    pass
2796
2797  def WriteGetDataSizeCode(self, func, file):
2798    """Writes the code to set data_size used in validation"""
2799    pass
2800
2801  def WriteImmediateCmdSizeTest(self, func, file):
2802    """Writes a size test for an immediate version of a command."""
2803    file.Write("  // TODO(gman): Compute correct size.\n")
2804    file.Write("  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n")
2805
2806  def WriteImmediateHandlerImplementation (self, func, file):
2807    """Writes the handler impl for the immediate version of a command."""
2808    file.Write("  %s(%s);\n" %
2809               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
2810
2811  def WriteBucketHandlerImplementation (self, func, file):
2812    """Writes the handler impl for the bucket version of a command."""
2813    file.Write("  %s(%s);\n" %
2814               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
2815
2816  def WriteServiceImplementation(self, func, file):
2817    """Writes the service implementation for a command."""
2818    file.Write(
2819        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
2820    file.Write(
2821        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
2822        func.name)
2823    self.WriteHandlerDeferReadWrite(func, file);
2824    if len(func.GetOriginalArgs()) > 0:
2825      last_arg = func.GetLastOriginalArg()
2826      all_but_last_arg = func.GetOriginalArgs()[:-1]
2827      for arg in all_but_last_arg:
2828        arg.WriteGetCode(file)
2829      self.WriteGetDataSizeCode(func, file)
2830      last_arg.WriteGetCode(file)
2831    func.WriteHandlerValidation(file)
2832    func.WriteHandlerImplementation(file)
2833    file.Write("  return error::kNoError;\n")
2834    file.Write("}\n")
2835    file.Write("\n")
2836
2837  def WriteImmediateServiceImplementation(self, func, file):
2838    """Writes the service implementation for an immediate version of command."""
2839    file.Write(
2840        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
2841    file.Write(
2842        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
2843        func.name)
2844    self.WriteHandlerDeferReadWrite(func, file);
2845    last_arg = func.GetLastOriginalArg()
2846    all_but_last_arg = func.GetOriginalArgs()[:-1]
2847    for arg in all_but_last_arg:
2848      arg.WriteGetCode(file)
2849    self.WriteGetDataSizeCode(func, file)
2850    last_arg.WriteGetCode(file)
2851    func.WriteHandlerValidation(file)
2852    func.WriteHandlerImplementation(file)
2853    file.Write("  return error::kNoError;\n")
2854    file.Write("}\n")
2855    file.Write("\n")
2856
2857  def WriteBucketServiceImplementation(self, func, file):
2858    """Writes the service implementation for a bucket version of command."""
2859    file.Write(
2860        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
2861    file.Write(
2862        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
2863        func.name)
2864    self.WriteHandlerDeferReadWrite(func, file);
2865    last_arg = func.GetLastOriginalArg()
2866    all_but_last_arg = func.GetOriginalArgs()[:-1]
2867    for arg in all_but_last_arg:
2868      arg.WriteGetCode(file)
2869    self.WriteGetDataSizeCode(func, file)
2870    last_arg.WriteGetCode(file)
2871    func.WriteHandlerValidation(file)
2872    func.WriteHandlerImplementation(file)
2873    file.Write("  return error::kNoError;\n")
2874    file.Write("}\n")
2875    file.Write("\n")
2876
2877  def WriteHandlerDeferReadWrite(self, func, file):
2878    """Writes the code to handle deferring reads or writes."""
2879    defer_draws = func.GetInfo('defer_draws')
2880    defer_reads = func.GetInfo('defer_reads')
2881    if defer_draws or defer_reads:
2882      file.Write("  error::Error error;\n")
2883    if defer_draws:
2884      file.Write("  error = WillAccessBoundFramebufferForDraw();\n")
2885      file.Write("  if (error != error::kNoError)\n")
2886      file.Write("    return error;\n")
2887    if defer_reads:
2888      file.Write("  error = WillAccessBoundFramebufferForRead();\n")
2889      file.Write("  if (error != error::kNoError)\n")
2890      file.Write("    return error;\n")
2891
2892  def WriteValidUnitTest(self, func, file, test, extra = {}):
2893    """Writes a valid unit test."""
2894    if func.GetInfo('expectation') == False:
2895      test = self._remove_expected_call_re.sub('', test)
2896    name = func.name
2897    arg_strings = []
2898    for count, arg in enumerate(func.GetOriginalArgs()):
2899      arg_strings.append(arg.GetValidArg(func, count, 0))
2900    gl_arg_strings = []
2901    for count, arg in enumerate(func.GetOriginalArgs()):
2902      gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
2903    gl_func_name = func.GetGLTestFunctionName()
2904    vars = {
2905      'test_name': 'GLES2DecoderTest%d' % file.file_num,
2906      'name':name,
2907      'gl_func_name': gl_func_name,
2908      'args': ", ".join(arg_strings),
2909      'gl_args': ", ".join(gl_arg_strings),
2910    }
2911    vars.update(extra)
2912    old_test = ""
2913    while (old_test != test):
2914      old_test = test
2915      test = test % vars
2916    file.Write(test % vars)
2917
2918  def WriteInvalidUnitTest(self, func, file, test, extra = {}):
2919    """Writes a invalid unit test."""
2920    for arg_index, arg in enumerate(func.GetOriginalArgs()):
2921      num_invalid_values = arg.GetNumInvalidValues(func)
2922      for value_index in range(0, num_invalid_values):
2923        arg_strings = []
2924        parse_result = "kNoError"
2925        gl_error = None
2926        for count, arg in enumerate(func.GetOriginalArgs()):
2927          if count == arg_index:
2928            (arg_string, parse_result, gl_error) = arg.GetInvalidArg(
2929                count, value_index)
2930          else:
2931            arg_string = arg.GetValidArg(func, count, 0)
2932          arg_strings.append(arg_string)
2933        gl_arg_strings = []
2934        for arg in func.GetOriginalArgs():
2935          gl_arg_strings.append("_")
2936        gl_func_name = func.GetGLTestFunctionName()
2937        gl_error_test = ''
2938        if not gl_error == None:
2939          gl_error_test = '\n  EXPECT_EQ(%s, GetGLError());' % gl_error
2940
2941        vars = {
2942          'test_name': 'GLES2DecoderTest%d' % file.file_num ,
2943          'name': func.name,
2944          'arg_index': arg_index,
2945          'value_index': value_index,
2946          'gl_func_name': gl_func_name,
2947          'args': ", ".join(arg_strings),
2948          'all_but_last_args': ", ".join(arg_strings[:-1]),
2949          'gl_args': ", ".join(gl_arg_strings),
2950          'parse_result': parse_result,
2951            'gl_error_test': gl_error_test,
2952        }
2953        vars.update(extra)
2954        file.Write(test % vars)
2955
2956  def WriteServiceUnitTest(self, func, file):
2957    """Writes the service unit test for a command."""
2958    valid_test = """
2959TEST_F(%(test_name)s, %(name)sValidArgs) {
2960  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
2961  SpecializedSetup<cmds::%(name)s, 0>(true);
2962  cmds::%(name)s cmd;
2963  cmd.Init(%(args)s);
2964  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2965  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2966}
2967"""
2968    self.WriteValidUnitTest(func, file, valid_test)
2969
2970    invalid_test = """
2971TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
2972  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
2973  SpecializedSetup<cmds::%(name)s, 0>(false);
2974  cmds::%(name)s cmd;
2975  cmd.Init(%(args)s);
2976  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
2977}
2978"""
2979    self.WriteInvalidUnitTest(func, file, invalid_test)
2980
2981  def WriteImmediateServiceUnitTest(self, func, file):
2982    """Writes the service unit test for an immediate command."""
2983    file.Write("// TODO(gman): %s\n" % func.name)
2984
2985  def WriteImmediateValidationCode(self, func, file):
2986    """Writes the validation code for an immediate version of a command."""
2987    pass
2988
2989  def WriteBucketServiceUnitTest(self, func, file):
2990    """Writes the service unit test for a bucket command."""
2991    file.Write("// TODO(gman): %s\n" % func.name)
2992
2993  def WriteBucketValidationCode(self, func, file):
2994    """Writes the validation code for a bucket version of a command."""
2995    file.Write("// TODO(gman): %s\n" % func.name)
2996
2997  def WriteGLES2ImplementationDeclaration(self, func, file):
2998    """Writes the GLES2 Implemention declaration."""
2999    impl_decl = func.GetInfo('impl_decl')
3000    if impl_decl == None or impl_decl == True:
3001      file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3002                 (func.return_type, func.original_name,
3003                  func.MakeTypedOriginalArgString("")))
3004      file.Write("\n")
3005
3006  def WriteGLES2CLibImplementation(self, func, file):
3007    file.Write("%s GLES2%s(%s) {\n" %
3008               (func.return_type, func.name,
3009                func.MakeTypedOriginalArgString("")))
3010    result_string = "return "
3011    if func.return_type == "void":
3012      result_string = ""
3013    file.Write("  %sgles2::GetGLContext()->%s(%s);\n" %
3014               (result_string, func.original_name,
3015                func.MakeOriginalArgString("")))
3016    file.Write("}\n")
3017
3018  def WriteGLES2Header(self, func, file):
3019    """Writes a re-write macro for GLES"""
3020    file.Write("#define gl%s GLES2_GET_FUN(%s)\n" %(func.name, func.name))
3021
3022  def WriteClientGLCallLog(self, func, file):
3023    """Writes a logging macro for the client side code."""
3024    comma = ""
3025    if len(func.GetOriginalArgs()):
3026      comma = " << "
3027    file.Write(
3028        '  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] gl%s("%s%s << ")");\n' %
3029        (func.original_name, comma, func.MakeLogArgString()))
3030
3031  def WriteClientGLReturnLog(self, func, file):
3032    """Writes the return value logging code."""
3033    if func.return_type != "void":
3034      file.Write('  GPU_CLIENT_LOG("return:" << result)\n')
3035
3036  def WriteGLES2ImplementationHeader(self, func, file):
3037    """Writes the GLES2 Implemention."""
3038    self.WriteGLES2ImplementationDeclaration(func, file)
3039
3040  def WriteGLES2TraceImplementationHeader(self, func, file):
3041    """Writes the GLES2 Trace Implemention header."""
3042    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3043               (func.return_type, func.original_name,
3044                func.MakeTypedOriginalArgString("")))
3045
3046  def WriteGLES2TraceImplementation(self, func, file):
3047    """Writes the GLES2 Trace Implemention."""
3048    file.Write("%s GLES2TraceImplementation::%s(%s) {\n" %
3049               (func.return_type, func.original_name,
3050                func.MakeTypedOriginalArgString("")))
3051    result_string = "return "
3052    if func.return_type == "void":
3053      result_string = ""
3054    file.Write('  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::%s");\n' %
3055               func.name)
3056    file.Write("  %sgl_->%s(%s);\n" %
3057               (result_string, func.name, func.MakeOriginalArgString("")))
3058    file.Write("}\n")
3059    file.Write("\n")
3060
3061  def WriteGLES2Implementation(self, func, file):
3062    """Writes the GLES2 Implemention."""
3063    impl_func = func.GetInfo('impl_func')
3064    impl_decl = func.GetInfo('impl_decl')
3065    gen_cmd = func.GetInfo('gen_cmd')
3066    if (func.can_auto_generate and
3067        (impl_func == None or impl_func == True) and
3068        (impl_decl == None or impl_decl == True) and
3069        (gen_cmd == None or gen_cmd == True)):
3070      file.Write("%s GLES2Implementation::%s(%s) {\n" %
3071                 (func.return_type, func.original_name,
3072                  func.MakeTypedOriginalArgString("")))
3073      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
3074      self.WriteClientGLCallLog(func, file)
3075      func.WriteDestinationInitalizationValidation(file)
3076      for arg in func.GetOriginalArgs():
3077        arg.WriteClientSideValidationCode(file, func)
3078      file.Write("  helper_->%s(%s);\n" %
3079                 (func.name, func.MakeOriginalArgString("")))
3080      file.Write("  CheckGLError();\n")
3081      self.WriteClientGLReturnLog(func, file)
3082      file.Write("}\n")
3083      file.Write("\n")
3084
3085  def WriteGLES2InterfaceHeader(self, func, file):
3086    """Writes the GLES2 Interface."""
3087    file.Write("virtual %s %s(%s) = 0;\n" %
3088               (func.return_type, func.original_name,
3089                func.MakeTypedOriginalArgString("")))
3090
3091  def WriteGLES2InterfaceStub(self, func, file):
3092    """Writes the GLES2 Interface stub declaration."""
3093    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3094               (func.return_type, func.original_name,
3095                func.MakeTypedOriginalArgString("")))
3096
3097  def WriteGLES2InterfaceStubImpl(self, func, file):
3098    """Writes the GLES2 Interface stub declaration."""
3099    args = func.GetOriginalArgs()
3100    arg_string = ", ".join(
3101        ["%s /* %s */" % (arg.type, arg.name) for arg in args])
3102    file.Write("%s GLES2InterfaceStub::%s(%s) {\n" %
3103               (func.return_type, func.original_name, arg_string))
3104    if func.return_type != "void":
3105      file.Write("  return 0;\n")
3106    file.Write("}\n")
3107
3108  def WriteGLES2ImplementationUnitTest(self, func, file):
3109    """Writes the GLES2 Implemention unit test."""
3110    client_test = func.GetInfo('client_test')
3111    if (func.can_auto_generate and
3112        (client_test == None or client_test == True)):
3113      code = """
3114TEST_F(GLES2ImplementationTest, %(name)s) {
3115  struct Cmds {
3116    cmds::%(name)s cmd;
3117  };
3118  Cmds expected;
3119  expected.cmd.Init(%(cmd_args)s);
3120
3121  gl_->%(name)s(%(args)s);
3122  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3123}
3124"""
3125      cmd_arg_strings = []
3126      for count, arg in enumerate(func.GetCmdArgs()):
3127        cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
3128        count += 1
3129      gl_arg_strings = []
3130      for count, arg in enumerate(func.GetOriginalArgs()):
3131        gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
3132      file.Write(code % {
3133            'name': func.name,
3134            'args': ", ".join(gl_arg_strings),
3135            'cmd_args': ", ".join(cmd_arg_strings),
3136          })
3137    else:
3138      if client_test != False:
3139        file.Write("// TODO: Implement unit test for %s\n" % func.name)
3140
3141  def WriteDestinationInitalizationValidation(self, func, file):
3142    """Writes the client side destintion initialization validation."""
3143    for arg in func.GetOriginalArgs():
3144      arg.WriteDestinationInitalizationValidation(file, func)
3145
3146  def WriteTraceEvent(self, func, file):
3147    file.Write('  TRACE_EVENT0("gpu", "GLES2Implementation::%s");\n' %
3148               func.original_name)
3149
3150  def WriteImmediateCmdComputeSize(self, func, file):
3151    """Writes the size computation code for the immediate version of a cmd."""
3152    file.Write("  static uint32 ComputeSize(uint32 size_in_bytes) {\n")
3153    file.Write("    return static_cast<uint32>(\n")
3154    file.Write("        sizeof(ValueType) +  // NOLINT\n")
3155    file.Write("        RoundSizeToMultipleOfEntries(size_in_bytes));\n")
3156    file.Write("  }\n")
3157    file.Write("\n")
3158
3159  def WriteImmediateCmdSetHeader(self, func, file):
3160    """Writes the SetHeader function for the immediate version of a cmd."""
3161    file.Write("  void SetHeader(uint32 size_in_bytes) {\n")
3162    file.Write("    header.SetCmdByTotalSize<ValueType>(size_in_bytes);\n")
3163    file.Write("  }\n")
3164    file.Write("\n")
3165
3166  def WriteImmediateCmdInit(self, func, file):
3167    """Writes the Init function for the immediate version of a command."""
3168    raise NotImplementedError(func.name)
3169
3170  def WriteImmediateCmdSet(self, func, file):
3171    """Writes the Set function for the immediate version of a command."""
3172    raise NotImplementedError(func.name)
3173
3174  def WriteCmdHelper(self, func, file):
3175    """Writes the cmd helper definition for a cmd."""
3176    code = """  void %(name)s(%(typed_args)s) {
3177    gles2::cmds::%(name)s* c = GetCmdSpace<gles2::cmds::%(name)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  def WriteImmediateCmdHelper(self, func, file):
3191    """Writes the cmd helper definition for the immediate version of a cmd."""
3192    code = """  void %(name)s(%(typed_args)s) {
3193    const uint32 s = 0;  // TODO(gman): compute correct size
3194    gles2::cmds::%(name)s* c =
3195        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(s);
3196    if (c) {
3197      c->Init(%(args)s);
3198    }
3199  }
3200
3201"""
3202    file.Write(code % {
3203           "name": func.name,
3204           "typed_args": func.MakeTypedCmdArgString(""),
3205           "args": func.MakeCmdArgString(""),
3206        })
3207
3208
3209class StateSetHandler(TypeHandler):
3210  """Handler for commands that simply set state."""
3211
3212  def __init__(self):
3213    TypeHandler.__init__(self)
3214
3215  def WriteHandlerImplementation(self, func, file):
3216    """Overrriden from TypeHandler."""
3217    state_name = func.GetInfo('state')
3218    state = _STATES[state_name]
3219    states = state['states']
3220    args = func.GetOriginalArgs()
3221    code = []
3222    for ndx,item in enumerate(states):
3223      if 'range_checks' in item:
3224        for range_check in item['range_checks']:
3225          code.append("%s %s" % (args[ndx].name, range_check['check']))
3226    if len(code):
3227      file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3228      file.Write(
3229        '    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,'
3230        ' "%s", "%s out of range");\n' %
3231        (func.name, args[ndx].name))
3232      file.Write("    return error::kNoError;\n")
3233      file.Write("  }\n")
3234    code = []
3235    for ndx,item in enumerate(states):
3236      code.append("state_.%s != %s" % (item['name'], args[ndx].name))
3237    file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3238    for ndx,item in enumerate(states):
3239      file.Write("    state_.%s = %s;\n" % (item['name'], args[ndx].name))
3240    if 'state_flag' in state:
3241      file.Write("    %s = true;\n" % state['state_flag'])
3242    if not func.GetInfo("no_gl"):
3243      file.Write("    %s(%s);\n" %
3244                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3245    file.Write("  }\n")
3246
3247  def WriteServiceUnitTest(self, func, file):
3248    """Overrriden from TypeHandler."""
3249    TypeHandler.WriteServiceUnitTest(self, func, file)
3250    state_name = func.GetInfo('state')
3251    state = _STATES[state_name]
3252    states = state['states']
3253    for ndx,item in enumerate(states):
3254      if 'range_checks' in item:
3255        for check_ndx, range_check in enumerate(item['range_checks']):
3256          valid_test = """
3257TEST_F(%(test_name)s, %(name)sInvalidValue%(ndx)d_%(check_ndx)d) {
3258  SpecializedSetup<cmds::%(name)s, 0>(false);
3259  cmds::%(name)s cmd;
3260  cmd.Init(%(args)s);
3261  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3262  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3263}
3264"""
3265          name = func.name
3266          arg_strings = []
3267          for count, arg in enumerate(func.GetOriginalArgs()):
3268            arg_strings.append(arg.GetValidArg(func, count, 0))
3269          arg_strings[ndx] = range_check['test_value']
3270          vars = {
3271            'test_name': 'GLES2DecoderTest%d' % file.file_num,
3272            'name': name,
3273            'ndx': ndx,
3274            'check_ndx': check_ndx,
3275            'args': ", ".join(arg_strings),
3276          }
3277          file.Write(valid_test % vars)
3278
3279
3280class StateSetRGBAlphaHandler(TypeHandler):
3281  """Handler for commands that simply set state that have rgb/alpha."""
3282
3283  def __init__(self):
3284    TypeHandler.__init__(self)
3285
3286  def WriteHandlerImplementation(self, func, file):
3287    """Overrriden from TypeHandler."""
3288    state_name = func.GetInfo('state')
3289    state = _STATES[state_name]
3290    states = state['states']
3291    args = func.GetOriginalArgs()
3292    num_args = len(args)
3293    code = []
3294    for ndx,item in enumerate(states):
3295      code.append("state_.%s != %s" % (item['name'], args[ndx % num_args].name))
3296    file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3297    for ndx, item in enumerate(states):
3298      file.Write("    state_.%s = %s;\n" %
3299                 (item['name'], args[ndx % num_args].name))
3300    if 'state_flag' in state:
3301      file.Write("    %s = true;\n" % state['state_flag'])
3302    if not func.GetInfo("no_gl"):
3303      file.Write("    %s(%s);\n" %
3304                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3305      file.Write("  }\n")
3306
3307
3308class StateSetFrontBackSeparateHandler(TypeHandler):
3309  """Handler for commands that simply set state that have front/back."""
3310
3311  def __init__(self):
3312    TypeHandler.__init__(self)
3313
3314  def WriteHandlerImplementation(self, func, file):
3315    """Overrriden from TypeHandler."""
3316    state_name = func.GetInfo('state')
3317    state = _STATES[state_name]
3318    states = state['states']
3319    args = func.GetOriginalArgs()
3320    face = args[0].name
3321    num_args = len(args)
3322    file.Write("  bool changed = false;\n")
3323    for group_ndx, group in enumerate(Grouper(num_args - 1, states)):
3324      file.Write("  if (%s == %s || %s == GL_FRONT_AND_BACK) {\n" %
3325                 (face, ('GL_FRONT', 'GL_BACK')[group_ndx], face))
3326      code = []
3327      for ndx, item in enumerate(group):
3328        code.append("state_.%s != %s" % (item['name'], args[ndx + 1].name))
3329      file.Write("    changed |= %s;\n" % " ||\n        ".join(code))
3330      file.Write("  }\n")
3331    file.Write("  if (changed) {\n")
3332    for group_ndx, group in enumerate(Grouper(num_args - 1, states)):
3333      file.Write("    if (%s == %s || %s == GL_FRONT_AND_BACK) {\n" %
3334                 (face, ('GL_FRONT', 'GL_BACK')[group_ndx], face))
3335      for ndx, item in enumerate(group):
3336        file.Write("      state_.%s = %s;\n" %
3337                   (item['name'], args[ndx + 1].name))
3338      file.Write("    }\n")
3339    if 'state_flag' in state:
3340      file.Write("    %s = true;\n" % state['state_flag'])
3341    if not func.GetInfo("no_gl"):
3342      file.Write("    %s(%s);\n" %
3343                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3344    file.Write("  }\n")
3345
3346
3347class StateSetFrontBackHandler(TypeHandler):
3348  """Handler for commands that simply set state that set both front/back."""
3349
3350  def __init__(self):
3351    TypeHandler.__init__(self)
3352
3353  def WriteHandlerImplementation(self, func, file):
3354    """Overrriden from TypeHandler."""
3355    state_name = func.GetInfo('state')
3356    state = _STATES[state_name]
3357    states = state['states']
3358    args = func.GetOriginalArgs()
3359    num_args = len(args)
3360    code = []
3361    for group_ndx, group in enumerate(Grouper(num_args, states)):
3362      for ndx, item in enumerate(group):
3363        code.append("state_.%s != %s" % (item['name'], args[ndx].name))
3364    file.Write("  if (%s) {\n" % " ||\n      ".join(code))
3365    for group_ndx, group in enumerate(Grouper(num_args, states)):
3366      for ndx, item in enumerate(group):
3367        file.Write("    state_.%s = %s;\n" % (item['name'], args[ndx].name))
3368    if 'state_flag' in state:
3369      file.Write("    %s = true;\n" % state['state_flag'])
3370    if not func.GetInfo("no_gl"):
3371      file.Write("    %s(%s);\n" %
3372                 (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3373    file.Write("  }\n")
3374
3375
3376class StateSetNamedParameter(TypeHandler):
3377  """Handler for commands that set a state chosen with an enum parameter."""
3378
3379  def __init__(self):
3380    TypeHandler.__init__(self)
3381
3382  def WriteHandlerImplementation(self, func, file):
3383    """Overridden from TypeHandler."""
3384    state_name = func.GetInfo('state')
3385    state = _STATES[state_name]
3386    states = state['states']
3387    args = func.GetOriginalArgs()
3388    num_args = len(args)
3389    assert num_args == 2
3390    file.Write("  switch (%s) {\n" % args[0].name)
3391    for state in states:
3392      file.Write("    case %s:\n" % state['enum'])
3393      file.Write("      if (state_.%s != %s) {\n" %
3394                 (state['name'], args[1].name))
3395      file.Write("        state_.%s = %s;\n" % (state['name'], args[1].name))
3396      if not func.GetInfo("no_gl"):
3397        file.Write("        %s(%s);\n" %
3398                   (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
3399      file.Write("      }\n")
3400      file.Write("      break;\n")
3401    file.Write("    default:\n")
3402    file.Write("      NOTREACHED();\n")
3403    file.Write("  }\n")
3404
3405
3406class CustomHandler(TypeHandler):
3407  """Handler for commands that are auto-generated but require minor tweaks."""
3408
3409  def __init__(self):
3410    TypeHandler.__init__(self)
3411
3412  def WriteServiceImplementation(self, func, file):
3413    """Overrriden from TypeHandler."""
3414    pass
3415
3416  def WriteImmediateServiceImplementation(self, func, file):
3417    """Overrriden from TypeHandler."""
3418    pass
3419
3420  def WriteBucketServiceImplementation(self, func, file):
3421    """Overrriden from TypeHandler."""
3422    pass
3423
3424  def WriteServiceUnitTest(self, func, file):
3425    """Overrriden from TypeHandler."""
3426    file.Write("// TODO(gman): %s\n\n" % func.name)
3427
3428  def WriteImmediateServiceUnitTest(self, func, file):
3429    """Overrriden from TypeHandler."""
3430    file.Write("// TODO(gman): %s\n\n" % func.name)
3431
3432  def WriteImmediateCmdGetTotalSize(self, func, file):
3433    """Overrriden from TypeHandler."""
3434    file.Write("    uint32 total_size = 0;  // TODO(gman): get correct size.\n")
3435
3436  def WriteImmediateCmdInit(self, func, file):
3437    """Overrriden from TypeHandler."""
3438    file.Write("  void Init(%s) {\n" % func.MakeTypedCmdArgString("_"))
3439    self.WriteImmediateCmdGetTotalSize(func, file)
3440    file.Write("    SetHeader(total_size);\n")
3441    args = func.GetCmdArgs()
3442    for arg in args:
3443      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
3444    file.Write("  }\n")
3445    file.Write("\n")
3446
3447  def WriteImmediateCmdSet(self, func, file):
3448    """Overrriden from TypeHandler."""
3449    copy_args = func.MakeCmdArgString("_", False)
3450    file.Write("  void* Set(void* cmd%s) {\n" %
3451               func.MakeTypedCmdArgString("_", True))
3452    self.WriteImmediateCmdGetTotalSize(func, file)
3453    file.Write("    static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args)
3454    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
3455               "cmd, total_size);\n")
3456    file.Write("  }\n")
3457    file.Write("\n")
3458
3459
3460class TodoHandler(CustomHandler):
3461  """Handle for commands that are not yet implemented."""
3462
3463  def AddImmediateFunction(self, generator, func):
3464    """Overrriden from TypeHandler."""
3465    pass
3466
3467  def WriteImmediateFormatTest(self, func, file):
3468    """Overrriden from TypeHandler."""
3469    pass
3470
3471  def WriteGLES2ImplementationUnitTest(self, func, file):
3472    """Overrriden from TypeHandler."""
3473    pass
3474
3475  def WriteGLES2Implementation(self, func, file):
3476    """Overrriden from TypeHandler."""
3477    file.Write("%s GLES2Implementation::%s(%s) {\n" %
3478               (func.return_type, func.original_name,
3479                func.MakeTypedOriginalArgString("")))
3480    file.Write("  // TODO: for now this is a no-op\n")
3481    file.Write(
3482        "  SetGLError("
3483        "GL_INVALID_OPERATION, \"gl%s\", \"not implemented\");\n" %
3484        func.name)
3485    if func.return_type != "void":
3486      file.Write("  return 0;\n")
3487    file.Write("}\n")
3488    file.Write("\n")
3489
3490  def WriteServiceImplementation(self, func, file):
3491    """Overrriden from TypeHandler."""
3492    file.Write(
3493        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
3494    file.Write(
3495        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
3496        func.name)
3497    file.Write("  // TODO: for now this is a no-op\n")
3498    file.Write(
3499        "  LOCAL_SET_GL_ERROR("
3500        "GL_INVALID_OPERATION, \"gl%s\", \"not implemented\");\n" %
3501        func.name)
3502    file.Write("  return error::kNoError;\n")
3503    file.Write("}\n")
3504    file.Write("\n")
3505
3506
3507class HandWrittenHandler(CustomHandler):
3508  """Handler for comands where everything must be written by hand."""
3509
3510  def InitFunction(self, func):
3511    """Add or adjust anything type specific for this function."""
3512    CustomHandler.InitFunction(self, func)
3513    func.can_auto_generate = False
3514
3515  def WriteStruct(self, func, file):
3516    """Overrriden from TypeHandler."""
3517    pass
3518
3519  def WriteDocs(self, func, file):
3520    """Overrriden from TypeHandler."""
3521    pass
3522
3523  def WriteServiceUnitTest(self, func, file):
3524    """Overrriden from TypeHandler."""
3525    file.Write("// TODO(gman): %s\n\n" % func.name)
3526
3527  def WriteImmediateServiceUnitTest(self, func, file):
3528    """Overrriden from TypeHandler."""
3529    file.Write("// TODO(gman): %s\n\n" % func.name)
3530
3531  def WriteBucketServiceUnitTest(self, func, file):
3532    """Overrriden from TypeHandler."""
3533    file.Write("// TODO(gman): %s\n\n" % func.name)
3534
3535  def WriteServiceImplementation(self, func, file):
3536    """Overrriden from TypeHandler."""
3537    pass
3538
3539  def WriteImmediateServiceImplementation(self, func, file):
3540    """Overrriden from TypeHandler."""
3541    pass
3542
3543  def WriteBucketServiceImplementation(self, func, file):
3544    """Overrriden from TypeHandler."""
3545    pass
3546
3547  def WriteImmediateCmdHelper(self, func, file):
3548    """Overrriden from TypeHandler."""
3549    pass
3550
3551  def WriteBucketCmdHelper(self, func, file):
3552    """Overrriden from TypeHandler."""
3553    pass
3554
3555  def WriteCmdHelper(self, func, file):
3556    """Overrriden from TypeHandler."""
3557    pass
3558
3559  def WriteFormatTest(self, func, file):
3560    """Overrriden from TypeHandler."""
3561    file.Write("// TODO(gman): Write test for %s\n" % func.name)
3562
3563  def WriteImmediateFormatTest(self, func, file):
3564    """Overrriden from TypeHandler."""
3565    file.Write("// TODO(gman): Write test for %s\n" % func.name)
3566
3567  def WriteBucketFormatTest(self, func, file):
3568    """Overrriden from TypeHandler."""
3569    file.Write("// TODO(gman): Write test for %s\n" % func.name)
3570
3571
3572
3573class ManualHandler(CustomHandler):
3574  """Handler for commands who's handlers must be written by hand."""
3575
3576  def __init__(self):
3577    CustomHandler.__init__(self)
3578
3579  def InitFunction(self, func):
3580    """Overrriden from TypeHandler."""
3581    if (func.name == 'CompressedTexImage2DBucket'):
3582      func.cmd_args = func.cmd_args[:-1]
3583      func.AddCmdArg(Argument('bucket_id', 'GLuint'))
3584    else:
3585      CustomHandler.InitFunction(self, func)
3586
3587  def WriteServiceImplementation(self, func, file):
3588    """Overrriden from TypeHandler."""
3589    pass
3590
3591  def WriteBucketServiceImplementation(self, func, file):
3592    """Overrriden from TypeHandler."""
3593    pass
3594
3595  def WriteServiceUnitTest(self, func, file):
3596    """Overrriden from TypeHandler."""
3597    file.Write("// TODO(gman): %s\n\n" % func.name)
3598
3599  def WriteImmediateServiceUnitTest(self, func, file):
3600    """Overrriden from TypeHandler."""
3601    file.Write("// TODO(gman): %s\n\n" % func.name)
3602
3603  def WriteImmediateServiceImplementation(self, func, file):
3604    """Overrriden from TypeHandler."""
3605    pass
3606
3607  def WriteImmediateFormatTest(self, func, file):
3608    """Overrriden from TypeHandler."""
3609    file.Write("// TODO(gman): Implement test for %s\n" % func.name)
3610
3611  def WriteGLES2Implementation(self, func, file):
3612    """Overrriden from TypeHandler."""
3613    if func.GetInfo('impl_func'):
3614      super(ManualHandler, self).WriteGLES2Implementation(func, file)
3615
3616  def WriteGLES2ImplementationHeader(self, func, file):
3617    """Overrriden from TypeHandler."""
3618    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
3619               (func.return_type, func.original_name,
3620                func.MakeTypedOriginalArgString("")))
3621    file.Write("\n")
3622
3623  def WriteImmediateCmdGetTotalSize(self, func, file):
3624    """Overrriden from TypeHandler."""
3625    # TODO(gman): Move this data to _FUNCTION_INFO?
3626    CustomHandler.WriteImmediateCmdGetTotalSize(self, func, file)
3627
3628
3629class DataHandler(TypeHandler):
3630  """Handler for glBufferData, glBufferSubData, glTexImage2D, glTexSubImage2D,
3631     glCompressedTexImage2D, glCompressedTexImageSub2D."""
3632  def __init__(self):
3633    TypeHandler.__init__(self)
3634
3635  def InitFunction(self, func):
3636    """Overrriden from TypeHandler."""
3637    if func.name == 'CompressedTexSubImage2DBucket':
3638      func.cmd_args = func.cmd_args[:-1]
3639      func.AddCmdArg(Argument('bucket_id', 'GLuint'))
3640
3641  def WriteGetDataSizeCode(self, func, file):
3642    """Overrriden from TypeHandler."""
3643    # TODO(gman): Move this data to _FUNCTION_INFO?
3644    name = func.name
3645    if name.endswith("Immediate"):
3646      name = name[0:-9]
3647    if name == 'BufferData' or name == 'BufferSubData':
3648      file.Write("  uint32 data_size = size;\n")
3649    elif (name == 'CompressedTexImage2D' or
3650          name == 'CompressedTexSubImage2D'):
3651      file.Write("  uint32 data_size = imageSize;\n")
3652    elif (name == 'CompressedTexSubImage2DBucket'):
3653      file.Write("  Bucket* bucket = GetBucket(c.bucket_id);\n")
3654      file.Write("  uint32 data_size = bucket->size();\n")
3655      file.Write("  GLsizei imageSize = data_size;\n")
3656    elif name == 'TexImage2D' or name == 'TexSubImage2D':
3657      code = """  uint32 data_size;
3658  if (!GLES2Util::ComputeImageDataSize(
3659      width, height, format, type, unpack_alignment_, &data_size)) {
3660    return error::kOutOfBounds;
3661  }
3662"""
3663      file.Write(code)
3664    else:
3665      file.Write("// uint32 data_size = 0;  // TODO(gman): get correct size!\n")
3666
3667  def WriteImmediateCmdGetTotalSize(self, func, file):
3668    """Overrriden from TypeHandler."""
3669    pass
3670
3671  def WriteImmediateCmdSizeTest(self, func, file):
3672    """Overrriden from TypeHandler."""
3673    file.Write("  EXPECT_EQ(sizeof(cmd), total_size);\n")
3674
3675  def WriteImmediateCmdInit(self, func, file):
3676    """Overrriden from TypeHandler."""
3677    file.Write("  void Init(%s) {\n" % func.MakeTypedCmdArgString("_"))
3678    self.WriteImmediateCmdGetTotalSize(func, file)
3679    file.Write("    SetHeader(total_size);\n")
3680    args = func.GetCmdArgs()
3681    for arg in args:
3682      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
3683    file.Write("  }\n")
3684    file.Write("\n")
3685
3686  def WriteImmediateCmdSet(self, func, file):
3687    """Overrriden from TypeHandler."""
3688    copy_args = func.MakeCmdArgString("_", False)
3689    file.Write("  void* Set(void* cmd%s) {\n" %
3690               func.MakeTypedCmdArgString("_", True))
3691    self.WriteImmediateCmdGetTotalSize(func, file)
3692    file.Write("    static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args)
3693    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
3694               "cmd, total_size);\n")
3695    file.Write("  }\n")
3696    file.Write("\n")
3697
3698  def WriteImmediateFormatTest(self, func, file):
3699    """Overrriden from TypeHandler."""
3700    # TODO(gman): Remove this exception.
3701    file.Write("// TODO(gman): Implement test for %s\n" % func.name)
3702    return
3703
3704  def WriteServiceUnitTest(self, func, file):
3705    """Overrriden from TypeHandler."""
3706    file.Write("// TODO(gman): %s\n\n" % func.name)
3707
3708  def WriteImmediateServiceUnitTest(self, func, file):
3709    """Overrriden from TypeHandler."""
3710    file.Write("// TODO(gman): %s\n\n" % func.name)
3711
3712  def WriteBucketServiceImplementation(self, func, file):
3713    """Overrriden from TypeHandler."""
3714    if not func.name == 'CompressedTexSubImage2DBucket':
3715      TypeHandler.WriteBucketServiceImplemenation(self, func, file)
3716
3717
3718class BindHandler(TypeHandler):
3719  """Handler for glBind___ type functions."""
3720
3721  def __init__(self):
3722    TypeHandler.__init__(self)
3723
3724  def WriteServiceUnitTest(self, func, file):
3725    """Overrriden from TypeHandler."""
3726
3727    if len(func.GetOriginalArgs()) == 1:
3728      valid_test = """
3729TEST_F(%(test_name)s, %(name)sValidArgs) {
3730  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
3731  SpecializedSetup<cmds::%(name)s, 0>(true);
3732  cmds::%(name)s cmd;
3733  cmd.Init(%(args)s);
3734  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3735  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3736}
3737
3738TEST_F(%(test_name)s, %(name)sValidArgsNewId) {
3739  EXPECT_CALL(*gl_, %(gl_func_name)s(kNewServiceId));
3740  EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _))
3741     .WillOnce(SetArgumentPointee<1>(kNewServiceId));
3742  SpecializedSetup<cmds::%(name)s, 0>(true);
3743  cmds::%(name)s cmd;
3744  cmd.Init(kNewClientId);
3745  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3746  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3747  EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
3748}
3749"""
3750      gen_func_names = {
3751      }
3752      self.WriteValidUnitTest(func, file, valid_test, {
3753          'resource_type': func.GetOriginalArgs()[0].resource_type,
3754          'gl_gen_func_name': func.GetInfo("gen_func"),
3755      })
3756    else:
3757      valid_test = """
3758TEST_F(%(test_name)s, %(name)sValidArgs) {
3759  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
3760  SpecializedSetup<cmds::%(name)s, 0>(true);
3761  cmds::%(name)s cmd;
3762  cmd.Init(%(args)s);
3763  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3764  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3765}
3766
3767TEST_F(%(test_name)s, %(name)sValidArgsNewId) {
3768  EXPECT_CALL(*gl_, %(gl_func_name)s(%(first_gl_arg)s, kNewServiceId));
3769  EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _))
3770     .WillOnce(SetArgumentPointee<1>(kNewServiceId));
3771  SpecializedSetup<cmds::%(name)s, 0>(true);
3772  cmds::%(name)s cmd;
3773  cmd.Init(%(first_arg)s, kNewClientId);
3774  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3775  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3776  EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
3777}
3778"""
3779      gen_func_names = {
3780      }
3781      self.WriteValidUnitTest(func, file, valid_test, {
3782          'first_arg': func.GetOriginalArgs()[0].GetValidArg(func, 0, 0),
3783          'first_gl_arg': func.GetOriginalArgs()[0].GetValidGLArg(func, 0, 0),
3784          'resource_type': func.GetOriginalArgs()[1].resource_type,
3785          'gl_gen_func_name': func.GetInfo("gen_func"),
3786      })
3787
3788    invalid_test = """
3789TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
3790  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
3791  SpecializedSetup<cmds::%(name)s, 0>(false);
3792  cmds::%(name)s cmd;
3793  cmd.Init(%(args)s);
3794  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
3795}
3796"""
3797    self.WriteInvalidUnitTest(func, file, invalid_test)
3798
3799  def WriteGLES2Implementation(self, func, file):
3800    """Writes the GLES2 Implemention."""
3801
3802    impl_func = func.GetInfo('impl_func')
3803    impl_decl = func.GetInfo('impl_decl')
3804
3805    if (func.can_auto_generate and
3806          (impl_func == None or impl_func == True) and
3807          (impl_decl == None or impl_decl == True)):
3808
3809      file.Write("%s GLES2Implementation::%s(%s) {\n" %
3810                 (func.return_type, func.original_name,
3811                  func.MakeTypedOriginalArgString("")))
3812      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
3813      func.WriteDestinationInitalizationValidation(file)
3814      self.WriteClientGLCallLog(func, file)
3815      for arg in func.GetOriginalArgs():
3816        arg.WriteClientSideValidationCode(file, func)
3817
3818      code = """  if (Is%(type)sReservedId(%(id)s)) {
3819    SetGLError(GL_INVALID_OPERATION, "%(name)s\", \"%(id)s reserved id");
3820    return;
3821  }
3822  if (Bind%(type)sHelper(%(arg_string)s)) {
3823    helper_->%(name)s(%(arg_string)s);
3824  }
3825  CheckGLError();
3826}
3827
3828"""
3829      name_arg = None
3830      if len(func.GetOriginalArgs()) == 1:
3831        # Bind functions that have no target (like BindVertexArrayOES)
3832        name_arg = func.GetOriginalArgs()[0]
3833      else:
3834        # Bind functions that have both a target and a name (like BindTexture)
3835        name_arg = func.GetOriginalArgs()[1]
3836
3837      file.Write(code % {
3838          'name': func.name,
3839          'arg_string': func.MakeOriginalArgString(""),
3840          'id': name_arg.name,
3841          'type': name_arg.resource_type,
3842          'lc_type': name_arg.resource_type.lower(),
3843        })
3844
3845  def WriteGLES2ImplementationUnitTest(self, func, file):
3846    """Overrriden from TypeHandler."""
3847    client_test = func.GetInfo('client_test')
3848    if client_test == False:
3849      return
3850    code = """
3851TEST_F(GLES2ImplementationTest, %(name)s) {
3852  struct Cmds {
3853    cmds::%(name)s cmd;
3854  };
3855  Cmds expected;
3856  expected.cmd.Init(%(cmd_args)s);
3857
3858  gl_->%(name)s(%(args)s);
3859  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3860  ClearCommands();
3861  gl_->%(name)s(%(args)s);
3862  EXPECT_TRUE(NoCommandsWritten());
3863}
3864"""
3865    cmd_arg_strings = []
3866    for count, arg in enumerate(func.GetCmdArgs()):
3867      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
3868      count += 1
3869    gl_arg_strings = []
3870    for count, arg in enumerate(func.GetOriginalArgs()):
3871      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
3872    file.Write(code % {
3873          'name': func.name,
3874          'args': ", ".join(gl_arg_strings),
3875          'cmd_args': ", ".join(cmd_arg_strings),
3876        })
3877
3878
3879class GENnHandler(TypeHandler):
3880  """Handler for glGen___ type functions."""
3881
3882  def __init__(self):
3883    TypeHandler.__init__(self)
3884
3885  def InitFunction(self, func):
3886    """Overrriden from TypeHandler."""
3887    pass
3888
3889  def WriteGetDataSizeCode(self, func, file):
3890    """Overrriden from TypeHandler."""
3891    code = """  uint32 data_size;
3892  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
3893    return error::kOutOfBounds;
3894  }
3895"""
3896    file.Write(code)
3897
3898  def WriteHandlerImplementation (self, func, file):
3899    """Overrriden from TypeHandler."""
3900    file.Write("  if (!%sHelper(n, %s)) {\n"
3901               "    return error::kInvalidArguments;\n"
3902               "  }\n" %
3903               (func.name, func.GetLastOriginalArg().name))
3904
3905  def WriteImmediateHandlerImplementation(self, func, file):
3906    """Overrriden from TypeHandler."""
3907    file.Write("  if (!%sHelper(n, %s)) {\n"
3908               "    return error::kInvalidArguments;\n"
3909               "  }\n" %
3910               (func.original_name, func.GetLastOriginalArg().name))
3911
3912  def WriteGLES2Implementation(self, func, file):
3913    """Overrriden from TypeHandler."""
3914    log_code = ("""  GPU_CLIENT_LOG_CODE_BLOCK({
3915    for (GLsizei i = 0; i < n; ++i) {
3916      GPU_CLIENT_LOG("  " << i << ": " << %s[i]);
3917    }
3918  });""" % func.GetOriginalArgs()[1].name)
3919    args = {
3920        'log_code': log_code,
3921        'return_type': func.return_type,
3922        'name': func.original_name,
3923        'typed_args': func.MakeTypedOriginalArgString(""),
3924        'args': func.MakeOriginalArgString(""),
3925        'resource_types': func.GetInfo('resource_types'),
3926        'count_name': func.GetOriginalArgs()[0].name,
3927      }
3928    file.Write(
3929        "%(return_type)s GLES2Implementation::%(name)s(%(typed_args)s) {\n" %
3930        args)
3931    func.WriteDestinationInitalizationValidation(file)
3932    self.WriteClientGLCallLog(func, file)
3933    for arg in func.GetOriginalArgs():
3934      arg.WriteClientSideValidationCode(file, func)
3935    code = """  GPU_CLIENT_SINGLE_THREAD_CHECK();
3936  GetIdHandler(id_namespaces::k%(resource_types)s)->
3937      MakeIds(this, 0, %(args)s);
3938  %(name)sHelper(%(args)s);
3939  helper_->%(name)sImmediate(%(args)s);
3940  helper_->CommandBufferHelper::Flush();
3941%(log_code)s
3942  CheckGLError();
3943}
3944
3945"""
3946    file.Write(code % args)
3947
3948  def WriteGLES2ImplementationUnitTest(self, func, file):
3949    """Overrriden from TypeHandler."""
3950    code = """
3951TEST_F(GLES2ImplementationTest, %(name)s) {
3952  GLuint ids[2] = { 0, };
3953  struct Cmds {
3954    cmds::%(name)sImmediate gen;
3955    GLuint data[2];
3956  };
3957  Cmds expected;
3958  expected.gen.Init(arraysize(ids), &ids[0]);
3959  expected.data[0] = k%(types)sStartId;
3960  expected.data[1] = k%(types)sStartId + 1;
3961  gl_->%(name)s(arraysize(ids), &ids[0]);
3962  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3963  EXPECT_EQ(k%(types)sStartId, ids[0]);
3964  EXPECT_EQ(k%(types)sStartId + 1, ids[1]);
3965}
3966"""
3967    file.Write(code % {
3968          'name': func.name,
3969          'types': func.GetInfo('resource_types'),
3970        })
3971
3972  def WriteServiceUnitTest(self, func, file):
3973    """Overrriden from TypeHandler."""
3974    valid_test = """
3975TEST_F(%(test_name)s, %(name)sValidArgs) {
3976  EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
3977      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
3978  GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
3979  SpecializedSetup<cmds::%(name)s, 0>(true);
3980  cmds::%(name)s cmd;
3981  cmd.Init(%(args)s);
3982  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3983  EXPECT_EQ(GL_NO_ERROR, GetGLError());
3984  EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL);
3985}
3986"""
3987    self.WriteValidUnitTest(func, file, valid_test, {
3988        'resource_name': func.GetInfo('resource_type'),
3989      })
3990    invalid_test = """
3991TEST_F(%(test_name)s, %(name)sInvalidArgs) {
3992  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
3993  GetSharedMemoryAs<GLuint*>()[0] = client_%(resource_name)s_id_;
3994  SpecializedSetup<cmds::%(name)s, 0>(false);
3995  cmds::%(name)s cmd;
3996  cmd.Init(%(args)s);
3997  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
3998}
3999"""
4000    self.WriteValidUnitTest(func, file, invalid_test, {
4001          'resource_name': func.GetInfo('resource_type').lower(),
4002        })
4003
4004  def WriteImmediateServiceUnitTest(self, func, file):
4005    """Overrriden from TypeHandler."""
4006    valid_test = """
4007TEST_F(%(test_name)s, %(name)sValidArgs) {
4008  EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
4009      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
4010  cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
4011  GLuint temp = kNewClientId;
4012  SpecializedSetup<cmds::%(name)s, 0>(true);
4013  cmd->Init(1, &temp);
4014  EXPECT_EQ(error::kNoError,
4015            ExecuteImmediateCmd(*cmd, sizeof(temp)));
4016  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4017  EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL);
4018}
4019"""
4020    self.WriteValidUnitTest(func, file, valid_test, {
4021        'resource_name': func.GetInfo('resource_type'),
4022      })
4023    invalid_test = """
4024TEST_F(%(test_name)s, %(name)sInvalidArgs) {
4025  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
4026  cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
4027  SpecializedSetup<cmds::%(name)s, 0>(false);
4028  cmd->Init(1, &client_%(resource_name)s_id_);
4029  EXPECT_EQ(error::kInvalidArguments,
4030            ExecuteImmediateCmd(*cmd, sizeof(&client_%(resource_name)s_id_)));
4031}
4032"""
4033    self.WriteValidUnitTest(func, file, invalid_test, {
4034          'resource_name': func.GetInfo('resource_type').lower(),
4035        })
4036
4037  def WriteImmediateCmdComputeSize(self, func, file):
4038    """Overrriden from TypeHandler."""
4039    file.Write("  static uint32 ComputeDataSize(GLsizei n) {\n")
4040    file.Write(
4041        "    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT\n")
4042    file.Write("  }\n")
4043    file.Write("\n")
4044    file.Write("  static uint32 ComputeSize(GLsizei n) {\n")
4045    file.Write("    return static_cast<uint32>(\n")
4046    file.Write("        sizeof(ValueType) + ComputeDataSize(n));  // NOLINT\n")
4047    file.Write("  }\n")
4048    file.Write("\n")
4049
4050  def WriteImmediateCmdSetHeader(self, func, file):
4051    """Overrriden from TypeHandler."""
4052    file.Write("  void SetHeader(GLsizei n) {\n")
4053    file.Write("    header.SetCmdByTotalSize<ValueType>(ComputeSize(n));\n")
4054    file.Write("  }\n")
4055    file.Write("\n")
4056
4057  def WriteImmediateCmdInit(self, func, file):
4058    """Overrriden from TypeHandler."""
4059    last_arg = func.GetLastOriginalArg()
4060    file.Write("  void Init(%s, %s _%s) {\n" %
4061               (func.MakeTypedCmdArgString("_"),
4062                last_arg.type, last_arg.name))
4063    file.Write("    SetHeader(_n);\n")
4064    args = func.GetCmdArgs()
4065    for arg in args:
4066      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
4067    file.Write("    memcpy(ImmediateDataAddress(this),\n")
4068    file.Write("           _%s, ComputeDataSize(_n));\n" % last_arg.name)
4069    file.Write("  }\n")
4070    file.Write("\n")
4071
4072  def WriteImmediateCmdSet(self, func, file):
4073    """Overrriden from TypeHandler."""
4074    last_arg = func.GetLastOriginalArg()
4075    copy_args = func.MakeCmdArgString("_", False)
4076    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
4077               (func.MakeTypedCmdArgString("_", True),
4078                last_arg.type, last_arg.name))
4079    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
4080               (copy_args, last_arg.name))
4081    file.Write("    const uint32 size = ComputeSize(_n);\n")
4082    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
4083               "cmd, size);\n")
4084    file.Write("  }\n")
4085    file.Write("\n")
4086
4087  def WriteImmediateCmdHelper(self, func, file):
4088    """Overrriden from TypeHandler."""
4089    code = """  void %(name)s(%(typed_args)s) {
4090    const uint32 size = gles2::cmds::%(name)s::ComputeSize(n);
4091    gles2::cmds::%(name)s* c =
4092        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
4093    if (c) {
4094      c->Init(%(args)s);
4095    }
4096  }
4097
4098"""
4099    file.Write(code % {
4100          "name": func.name,
4101          "typed_args": func.MakeTypedOriginalArgString(""),
4102          "args": func.MakeOriginalArgString(""),
4103        })
4104
4105  def WriteImmediateFormatTest(self, func, file):
4106    """Overrriden from TypeHandler."""
4107    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
4108    file.Write("  static GLuint ids[] = { 12, 23, 34, };\n")
4109    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
4110               (func.name, func.name))
4111    file.Write("  void* next_cmd = cmd.Set(\n")
4112    file.Write("      &cmd, static_cast<GLsizei>(arraysize(ids)), ids);\n")
4113    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
4114               func.name)
4115    file.Write("            cmd.header.command);\n")
4116    file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
4117    file.Write("            RoundSizeToMultipleOfEntries(cmd.n * 4u),\n")
4118    file.Write("            cmd.header.size * 4u);\n")
4119    file.Write("  EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);\n");
4120    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
4121    file.Write("      next_cmd, sizeof(cmd) +\n")
4122    file.Write("      RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));\n")
4123    file.Write("  // TODO(gman): Check that ids were inserted;\n")
4124    file.Write("}\n")
4125    file.Write("\n")
4126
4127
4128class CreateHandler(TypeHandler):
4129  """Handler for glCreate___ type functions."""
4130
4131  def __init__(self):
4132    TypeHandler.__init__(self)
4133
4134  def InitFunction(self, func):
4135    """Overrriden from TypeHandler."""
4136    func.AddCmdArg(Argument("client_id", 'uint32'))
4137
4138  def WriteServiceUnitTest(self, func, file):
4139    """Overrriden from TypeHandler."""
4140    valid_test = """
4141TEST_F(%(test_name)s, %(name)sValidArgs) {
4142  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
4143      .WillOnce(Return(kNewServiceId));
4144  SpecializedSetup<cmds::%(name)s, 0>(true);
4145  cmds::%(name)s cmd;
4146  cmd.Init(%(args)s%(comma)skNewClientId);
4147  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4148  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4149  EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
4150}
4151"""
4152    comma = ""
4153    if len(func.GetOriginalArgs()):
4154      comma =", "
4155    self.WriteValidUnitTest(func, file, valid_test, {
4156          'comma': comma,
4157          'resource_type': func.name[6:],
4158        })
4159    invalid_test = """
4160TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4161  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
4162  SpecializedSetup<cmds::%(name)s, 0>(false);
4163  cmds::%(name)s cmd;
4164  cmd.Init(%(args)s%(comma)skNewClientId);
4165  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));%(gl_error_test)s
4166}
4167"""
4168    self.WriteInvalidUnitTest(func, file, invalid_test, {
4169          'comma': comma,
4170        })
4171
4172  def WriteHandlerImplementation (self, func, file):
4173    """Overrriden from TypeHandler."""
4174    file.Write("  uint32 client_id = c.client_id;\n")
4175    file.Write("  if (!%sHelper(%s)) {\n" %
4176               (func.name, func.MakeCmdArgString("")))
4177    file.Write("    return error::kInvalidArguments;\n")
4178    file.Write("  }\n")
4179
4180  def WriteGLES2Implementation(self, func, file):
4181    """Overrriden from TypeHandler."""
4182    file.Write("%s GLES2Implementation::%s(%s) {\n" %
4183               (func.return_type, func.original_name,
4184                func.MakeTypedOriginalArgString("")))
4185    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4186    func.WriteDestinationInitalizationValidation(file)
4187    self.WriteClientGLCallLog(func, file)
4188    for arg in func.GetOriginalArgs():
4189      arg.WriteClientSideValidationCode(file, func)
4190    file.Write("  GLuint client_id;\n")
4191    file.Write(
4192        "  GetIdHandler(id_namespaces::kProgramsAndShaders)->\n")
4193    file.Write("      MakeIds(this, 0, 1, &client_id);\n")
4194    file.Write("  helper_->%s(%s);\n" %
4195               (func.name, func.MakeCmdArgString("")))
4196    file.Write('  GPU_CLIENT_LOG("returned " << client_id);\n')
4197    file.Write("  CheckGLError();\n")
4198    file.Write("  return client_id;\n")
4199    file.Write("}\n")
4200    file.Write("\n")
4201
4202
4203class DeleteHandler(TypeHandler):
4204  """Handler for glDelete___ single resource type functions."""
4205
4206  def __init__(self):
4207    TypeHandler.__init__(self)
4208
4209  def WriteServiceImplementation(self, func, file):
4210    """Overrriden from TypeHandler."""
4211    pass
4212
4213  def WriteGLES2Implementation(self, func, file):
4214    """Overrriden from TypeHandler."""
4215    file.Write("%s GLES2Implementation::%s(%s) {\n" %
4216               (func.return_type, func.original_name,
4217                func.MakeTypedOriginalArgString("")))
4218    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4219    func.WriteDestinationInitalizationValidation(file)
4220    self.WriteClientGLCallLog(func, file)
4221    for arg in func.GetOriginalArgs():
4222      arg.WriteClientSideValidationCode(file, func)
4223    file.Write(
4224        "  GPU_CLIENT_DCHECK(%s != 0);\n" % func.GetOriginalArgs()[-1].name)
4225    file.Write("  %sHelper(%s);\n" %
4226               (func.original_name, func.GetOriginalArgs()[-1].name))
4227    file.Write("  CheckGLError();\n")
4228    file.Write("}\n")
4229    file.Write("\n")
4230
4231
4232class DELnHandler(TypeHandler):
4233  """Handler for glDelete___ type functions."""
4234
4235  def __init__(self):
4236    TypeHandler.__init__(self)
4237
4238  def WriteGetDataSizeCode(self, func, file):
4239    """Overrriden from TypeHandler."""
4240    code = """  uint32 data_size;
4241  if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4242    return error::kOutOfBounds;
4243  }
4244"""
4245    file.Write(code)
4246
4247  def WriteGLES2ImplementationUnitTest(self, func, file):
4248    """Overrriden from TypeHandler."""
4249    code = """
4250TEST_F(GLES2ImplementationTest, %(name)s) {
4251  GLuint ids[2] = { k%(types)sStartId, k%(types)sStartId + 1 };
4252  struct Cmds {
4253    cmds::%(name)sImmediate del;
4254    GLuint data[2];
4255  };
4256  Cmds expected;
4257  expected.del.Init(arraysize(ids), &ids[0]);
4258  expected.data[0] = k%(types)sStartId;
4259  expected.data[1] = k%(types)sStartId + 1;
4260  gl_->%(name)s(arraysize(ids), &ids[0]);
4261  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
4262}
4263"""
4264    file.Write(code % {
4265          'name': func.name,
4266          'types': func.GetInfo('resource_types'),
4267        })
4268
4269  def WriteServiceUnitTest(self, func, file):
4270    """Overrriden from TypeHandler."""
4271    valid_test = """
4272TEST_F(%(test_name)s, %(name)sValidArgs) {
4273  EXPECT_CALL(
4274      *gl_,
4275      %(gl_func_name)s(1, Pointee(kService%(upper_resource_name)sId)))
4276      .Times(1);
4277  GetSharedMemoryAs<GLuint*>()[0] = client_%(resource_name)s_id_;
4278  SpecializedSetup<cmds::%(name)s, 0>(true);
4279  cmds::%(name)s cmd;
4280  cmd.Init(%(args)s);
4281  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4282  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4283  EXPECT_TRUE(
4284      Get%(upper_resource_name)s(client_%(resource_name)s_id_) == NULL);
4285}
4286"""
4287    self.WriteValidUnitTest(func, file, valid_test, {
4288          'resource_name': func.GetInfo('resource_type').lower(),
4289          'upper_resource_name': func.GetInfo('resource_type'),
4290        })
4291    invalid_test = """
4292TEST_F(%(test_name)s, %(name)sInvalidArgs) {
4293  GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
4294  SpecializedSetup<cmds::%(name)s, 0>(false);
4295  cmds::%(name)s cmd;
4296  cmd.Init(%(args)s);
4297  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4298}
4299"""
4300    self.WriteValidUnitTest(func, file, invalid_test)
4301
4302  def WriteImmediateServiceUnitTest(self, func, file):
4303    """Overrriden from TypeHandler."""
4304    valid_test = """
4305TEST_F(%(test_name)s, %(name)sValidArgs) {
4306  EXPECT_CALL(
4307      *gl_,
4308      %(gl_func_name)s(1, Pointee(kService%(upper_resource_name)sId)))
4309      .Times(1);
4310  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4311  SpecializedSetup<cmds::%(name)s, 0>(true);
4312  cmd.Init(1, &client_%(resource_name)s_id_);
4313  EXPECT_EQ(error::kNoError,
4314            ExecuteImmediateCmd(cmd, sizeof(client_%(resource_name)s_id_)));
4315  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4316  EXPECT_TRUE(
4317      Get%(upper_resource_name)s(client_%(resource_name)s_id_) == NULL);
4318}
4319"""
4320    self.WriteValidUnitTest(func, file, valid_test, {
4321          'resource_name': func.GetInfo('resource_type').lower(),
4322          'upper_resource_name': func.GetInfo('resource_type'),
4323        })
4324    invalid_test = """
4325TEST_F(%(test_name)s, %(name)sInvalidArgs) {
4326  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4327  SpecializedSetup<cmds::%(name)s, 0>(false);
4328  GLuint temp = kInvalidClientId;
4329  cmd.Init(1, &temp);
4330  EXPECT_EQ(error::kNoError,
4331            ExecuteImmediateCmd(cmd, sizeof(temp)));
4332}
4333"""
4334    self.WriteValidUnitTest(func, file, invalid_test)
4335
4336  def WriteHandlerImplementation (self, func, file):
4337    """Overrriden from TypeHandler."""
4338    file.Write("  %sHelper(n, %s);\n" %
4339               (func.name, func.GetLastOriginalArg().name))
4340
4341  def WriteImmediateHandlerImplementation (self, func, file):
4342    """Overrriden from TypeHandler."""
4343    file.Write("  %sHelper(n, %s);\n" %
4344               (func.original_name, func.GetLastOriginalArg().name))
4345
4346  def WriteGLES2Implementation(self, func, file):
4347    """Overrriden from TypeHandler."""
4348    impl_decl = func.GetInfo('impl_decl')
4349    if impl_decl == None or impl_decl == True:
4350      args = {
4351          'return_type': func.return_type,
4352          'name': func.original_name,
4353          'typed_args': func.MakeTypedOriginalArgString(""),
4354          'args': func.MakeOriginalArgString(""),
4355          'resource_type': func.GetInfo('resource_type').lower(),
4356          'count_name': func.GetOriginalArgs()[0].name,
4357        }
4358      file.Write(
4359          "%(return_type)s GLES2Implementation::%(name)s(%(typed_args)s) {\n" %
4360          args)
4361      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4362      func.WriteDestinationInitalizationValidation(file)
4363      self.WriteClientGLCallLog(func, file)
4364      file.Write("""  GPU_CLIENT_LOG_CODE_BLOCK({
4365    for (GLsizei i = 0; i < n; ++i) {
4366      GPU_CLIENT_LOG("  " << i << ": " << %s[i]);
4367    }
4368  });
4369""" % func.GetOriginalArgs()[1].name)
4370      file.Write("""  GPU_CLIENT_DCHECK_CODE_BLOCK({
4371    for (GLsizei i = 0; i < n; ++i) {
4372      DCHECK(%s[i] != 0);
4373    }
4374  });
4375""" % func.GetOriginalArgs()[1].name)
4376      for arg in func.GetOriginalArgs():
4377        arg.WriteClientSideValidationCode(file, func)
4378      code = """  %(name)sHelper(%(args)s);
4379  CheckGLError();
4380}
4381
4382"""
4383      file.Write(code % args)
4384
4385  def WriteImmediateCmdComputeSize(self, func, file):
4386    """Overrriden from TypeHandler."""
4387    file.Write("  static uint32 ComputeDataSize(GLsizei n) {\n")
4388    file.Write(
4389        "    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT\n")
4390    file.Write("  }\n")
4391    file.Write("\n")
4392    file.Write("  static uint32 ComputeSize(GLsizei n) {\n")
4393    file.Write("    return static_cast<uint32>(\n")
4394    file.Write("        sizeof(ValueType) + ComputeDataSize(n));  // NOLINT\n")
4395    file.Write("  }\n")
4396    file.Write("\n")
4397
4398  def WriteImmediateCmdSetHeader(self, func, file):
4399    """Overrriden from TypeHandler."""
4400    file.Write("  void SetHeader(GLsizei n) {\n")
4401    file.Write("    header.SetCmdByTotalSize<ValueType>(ComputeSize(n));\n")
4402    file.Write("  }\n")
4403    file.Write("\n")
4404
4405  def WriteImmediateCmdInit(self, func, file):
4406    """Overrriden from TypeHandler."""
4407    last_arg = func.GetLastOriginalArg()
4408    file.Write("  void Init(%s, %s _%s) {\n" %
4409               (func.MakeTypedCmdArgString("_"),
4410                last_arg.type, last_arg.name))
4411    file.Write("    SetHeader(_n);\n")
4412    args = func.GetCmdArgs()
4413    for arg in args:
4414      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
4415    file.Write("    memcpy(ImmediateDataAddress(this),\n")
4416    file.Write("           _%s, ComputeDataSize(_n));\n" % last_arg.name)
4417    file.Write("  }\n")
4418    file.Write("\n")
4419
4420  def WriteImmediateCmdSet(self, func, file):
4421    """Overrriden from TypeHandler."""
4422    last_arg = func.GetLastOriginalArg()
4423    copy_args = func.MakeCmdArgString("_", False)
4424    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
4425               (func.MakeTypedCmdArgString("_", True),
4426                last_arg.type, last_arg.name))
4427    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
4428               (copy_args, last_arg.name))
4429    file.Write("    const uint32 size = ComputeSize(_n);\n")
4430    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
4431               "cmd, size);\n")
4432    file.Write("  }\n")
4433    file.Write("\n")
4434
4435  def WriteImmediateCmdHelper(self, func, file):
4436    """Overrriden from TypeHandler."""
4437    code = """  void %(name)s(%(typed_args)s) {
4438    const uint32 size = gles2::cmds::%(name)s::ComputeSize(n);
4439    gles2::cmds::%(name)s* c =
4440        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
4441    if (c) {
4442      c->Init(%(args)s);
4443    }
4444  }
4445
4446"""
4447    file.Write(code % {
4448          "name": func.name,
4449          "typed_args": func.MakeTypedOriginalArgString(""),
4450          "args": func.MakeOriginalArgString(""),
4451        })
4452
4453  def WriteImmediateFormatTest(self, func, file):
4454    """Overrriden from TypeHandler."""
4455    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
4456    file.Write("  static GLuint ids[] = { 12, 23, 34, };\n")
4457    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
4458               (func.name, func.name))
4459    file.Write("  void* next_cmd = cmd.Set(\n")
4460    file.Write("      &cmd, static_cast<GLsizei>(arraysize(ids)), ids);\n")
4461    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
4462               func.name)
4463    file.Write("            cmd.header.command);\n")
4464    file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
4465    file.Write("            RoundSizeToMultipleOfEntries(cmd.n * 4u),\n")
4466    file.Write("            cmd.header.size * 4u);\n")
4467    file.Write("  EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);\n");
4468    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
4469    file.Write("      next_cmd, sizeof(cmd) +\n")
4470    file.Write("      RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));\n")
4471    file.Write("  // TODO(gman): Check that ids were inserted;\n")
4472    file.Write("}\n")
4473    file.Write("\n")
4474
4475
4476class GETnHandler(TypeHandler):
4477  """Handler for GETn for glGetBooleanv, glGetFloatv, ... type functions."""
4478
4479  def __init__(self):
4480    TypeHandler.__init__(self)
4481
4482  def AddImmediateFunction(self, generator, func):
4483    """Overrriden from TypeHandler."""
4484    pass
4485
4486  def WriteServiceImplementation(self, func, file):
4487    """Overrriden from TypeHandler."""
4488    file.Write(
4489        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
4490    file.Write(
4491        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
4492        func.name)
4493    last_arg = func.GetLastOriginalArg()
4494
4495    all_but_last_args = func.GetOriginalArgs()[:-1]
4496    for arg in all_but_last_args:
4497      arg.WriteGetCode(file)
4498
4499    code = """  typedef cmds::%(func_name)s::Result Result;
4500  GLsizei num_values = 0;
4501  GetNumValuesReturnedForGLGet(pname, &num_values);
4502  Result* result = GetSharedMemoryAs<Result*>(
4503      c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
4504  %(last_arg_type)s params = result ? result->GetData() : NULL;
4505"""
4506    file.Write(code % {
4507        'last_arg_type': last_arg.type,
4508        'func_name': func.name,
4509      })
4510    func.WriteHandlerValidation(file)
4511    code = """  // Check that the client initialized the result.
4512  if (result->size != 0) {
4513    return error::kInvalidArguments;
4514  }
4515"""
4516    shadowed = func.GetInfo('shadowed')
4517    if not shadowed:
4518      file.Write('  LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("%s");\n' % func.name)
4519    file.Write(code)
4520    func.WriteHandlerImplementation(file)
4521    if shadowed:
4522      code = """  result->SetNumResults(num_values);
4523  return error::kNoError;
4524}
4525"""
4526    else:
4527     code = """  GLenum error = glGetError();
4528  if (error == GL_NO_ERROR) {
4529    result->SetNumResults(num_values);
4530  } else {
4531    LOCAL_SET_GL_ERROR(error, "%(func_name)s", "");
4532  }
4533  return error::kNoError;
4534}
4535
4536"""
4537    file.Write(code % {'func_name': func.name})
4538
4539  def WriteGLES2Implementation(self, func, file):
4540    """Overrriden from TypeHandler."""
4541    impl_decl = func.GetInfo('impl_decl')
4542    if impl_decl == None or impl_decl == True:
4543      file.Write("%s GLES2Implementation::%s(%s) {\n" %
4544                 (func.return_type, func.original_name,
4545                  func.MakeTypedOriginalArgString("")))
4546      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4547      func.WriteDestinationInitalizationValidation(file)
4548      self.WriteClientGLCallLog(func, file)
4549      for arg in func.GetOriginalArgs():
4550        arg.WriteClientSideValidationCode(file, func)
4551      all_but_last_args = func.GetOriginalArgs()[:-1]
4552      arg_string = (
4553          ", ".join(["%s" % arg.name for arg in all_but_last_args]))
4554      all_arg_string = (
4555          ", ".join(["%s" % arg.name for arg in func.GetOriginalArgs()]))
4556      self.WriteTraceEvent(func, file)
4557      code = """  if (%(func_name)sHelper(%(all_arg_string)s)) {
4558    return;
4559  }
4560  typedef cmds::%(func_name)s::Result Result;
4561  Result* result = GetResultAs<Result*>();
4562  if (!result) {
4563    return;
4564  }
4565  result->SetNumResults(0);
4566  helper_->%(func_name)s(%(arg_string)s,
4567      GetResultShmId(), GetResultShmOffset());
4568  WaitForCmd();
4569  result->CopyResult(params);
4570  GPU_CLIENT_LOG_CODE_BLOCK({
4571    for (int32 i = 0; i < result->GetNumResults(); ++i) {
4572      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
4573    }
4574  });
4575  CheckGLError();
4576}
4577"""
4578      file.Write(code % {
4579          'func_name': func.name,
4580          'arg_string': arg_string,
4581          'all_arg_string': all_arg_string,
4582        })
4583
4584  def WriteGLES2ImplementationUnitTest(self, func, file):
4585    """Writes the GLES2 Implemention unit test."""
4586    code = """
4587TEST_F(GLES2ImplementationTest, %(name)s) {
4588  struct Cmds {
4589    cmds::%(name)s cmd;
4590  };
4591  typedef cmds::%(name)s::Result Result;
4592  Result::Type result = 0;
4593  Cmds expected;
4594  ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
4595  expected.cmd.Init(%(cmd_args)s, result1.id, result1.offset);
4596  EXPECT_CALL(*command_buffer(), OnFlush())
4597      .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
4598      .RetiresOnSaturation();
4599  gl_->%(name)s(%(args)s, &result);
4600  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
4601  EXPECT_EQ(static_cast<Result::Type>(1), result);
4602}
4603"""
4604    cmd_arg_strings = []
4605    for count, arg in enumerate(func.GetCmdArgs()[0:-2]):
4606      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
4607    cmd_arg_strings[0] = '123'
4608    gl_arg_strings = []
4609    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
4610      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
4611    gl_arg_strings[0] = '123'
4612    file.Write(code % {
4613          'name': func.name,
4614          'args': ", ".join(gl_arg_strings),
4615          'cmd_args': ", ".join(cmd_arg_strings),
4616        })
4617
4618  def WriteServiceUnitTest(self, func, file):
4619    """Overrriden from TypeHandler."""
4620    valid_test = """
4621TEST_F(%(test_name)s, %(name)sValidArgs) {
4622  EXPECT_CALL(*gl_, GetError())
4623      .WillOnce(Return(GL_NO_ERROR))
4624      .WillOnce(Return(GL_NO_ERROR))
4625      .RetiresOnSaturation();
4626  SpecializedSetup<cmds::%(name)s, 0>(true);
4627  typedef cmds::%(name)s::Result Result;
4628  Result* result = static_cast<Result*>(shared_memory_address_);
4629  EXPECT_CALL(*gl_, %(gl_func_name)s(%(local_gl_args)s));
4630  result->size = 0;
4631  cmds::%(name)s cmd;
4632  cmd.Init(%(args)s);
4633  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4634  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
4635                %(valid_pname)s),
4636            result->GetNumResults());
4637  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4638}
4639"""
4640    gl_arg_strings = []
4641    valid_pname = ''
4642    for count, arg in enumerate(func.GetOriginalArgs()[:-1]):
4643      arg_value = arg.GetValidGLArg(func, count, 0)
4644      gl_arg_strings.append(arg_value)
4645      if arg.name == 'pname':
4646        valid_pname = arg_value
4647    if func.GetInfo('gl_test_func') == 'glGetIntegerv':
4648      gl_arg_strings.append("_")
4649    else:
4650      gl_arg_strings.append("result->GetData()")
4651
4652    self.WriteValidUnitTest(func, file, valid_test, {
4653        'local_gl_args': ", ".join(gl_arg_strings),
4654        'valid_pname': valid_pname,
4655      })
4656
4657    invalid_test = """
4658TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4659  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
4660  SpecializedSetup<cmds::%(name)s, 0>(false);
4661  cmds::%(name)s::Result* result =
4662      static_cast<cmds::%(name)s::Result*>(shared_memory_address_);
4663  result->size = 0;
4664  cmds::%(name)s cmd;
4665  cmd.Init(%(args)s);
4666  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));
4667  EXPECT_EQ(0u, result->size);%(gl_error_test)s
4668}
4669"""
4670    self.WriteInvalidUnitTest(func, file, invalid_test)
4671
4672
4673class PUTHandler(TypeHandler):
4674  """Handler for glTexParameter_v, glVertexAttrib_v functions."""
4675
4676  def __init__(self):
4677    TypeHandler.__init__(self)
4678
4679  def WriteServiceUnitTest(self, func, file):
4680    """Writes the service unit test for a command."""
4681    expected_call = "EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));"
4682    if func.GetInfo("first_element_only"):
4683      gl_arg_strings = []
4684      for count, arg in enumerate(func.GetOriginalArgs()):
4685        gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
4686      gl_arg_strings[-1] = "*" + gl_arg_strings[-1]
4687      expected_call = ("EXPECT_CALL(*gl_, %%(gl_func_name)s(%s));" %
4688          ", ".join(gl_arg_strings))
4689    valid_test = """
4690TEST_F(%(test_name)s, %(name)sValidArgs) {
4691  SpecializedSetup<cmds::%(name)s, 0>(true);
4692  cmds::%(name)s cmd;
4693  cmd.Init(%(args)s);
4694  GetSharedMemoryAs<%(data_type)s*>()[0] = %(data_value)s;
4695  %(expected_call)s
4696  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4697  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4698}
4699"""
4700    extra = {
4701      'data_type': func.GetInfo('data_type'),
4702      'data_value': func.GetInfo('data_value') or '0',
4703      'expected_call': expected_call,
4704    }
4705    self.WriteValidUnitTest(func, file, valid_test, extra)
4706
4707    invalid_test = """
4708TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4709  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
4710  SpecializedSetup<cmds::%(name)s, 0>(false);
4711  cmds::%(name)s cmd;
4712  cmd.Init(%(args)s);
4713  GetSharedMemoryAs<%(data_type)s*>()[0] = %(data_value)s;
4714  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
4715}
4716"""
4717    self.WriteInvalidUnitTest(func, file, invalid_test, extra)
4718
4719  def WriteImmediateServiceUnitTest(self, func, file):
4720    """Writes the service unit test for a command."""
4721    valid_test = """
4722TEST_F(%(test_name)s, %(name)sValidArgs) {
4723  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4724  SpecializedSetup<cmds::%(name)s, 0>(true);
4725  %(data_type)s temp[%(data_count)s] = { %(data_value)s, };
4726  cmd.Init(%(gl_args)s, &temp[0]);
4727  EXPECT_CALL(
4728      *gl_,
4729      %(gl_func_name)s(%(gl_args)s, %(data_ref)sreinterpret_cast<
4730          %(data_type)s*>(ImmediateDataAddress(&cmd))));
4731  EXPECT_EQ(error::kNoError,
4732            ExecuteImmediateCmd(cmd, sizeof(temp)));
4733  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4734}
4735"""
4736    gl_arg_strings = []
4737    gl_any_strings = []
4738    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
4739      gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
4740      gl_any_strings.append("_")
4741    extra = {
4742      'data_ref': ("*" if func.GetInfo('first_element_only') else ""),
4743      'data_type': func.GetInfo('data_type'),
4744      'data_count': func.GetInfo('count'),
4745      'data_value': func.GetInfo('data_value') or '0',
4746      'gl_args': ", ".join(gl_arg_strings),
4747      'gl_any_args': ", ".join(gl_any_strings),
4748    }
4749    self.WriteValidUnitTest(func, file, valid_test, extra)
4750
4751    invalid_test = """
4752TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
4753  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4754  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
4755  SpecializedSetup<cmds::%(name)s, 0>(false);
4756  %(data_type)s temp[%(data_count)s] = { %(data_value)s, };
4757  cmd.Init(%(all_but_last_args)s, &temp[0]);
4758  EXPECT_EQ(error::%(parse_result)s,
4759            ExecuteImmediateCmd(cmd, sizeof(temp)));%(gl_error_test)s
4760}
4761"""
4762    self.WriteInvalidUnitTest(func, file, invalid_test, extra)
4763
4764  def WriteGetDataSizeCode(self, func, file):
4765    """Overrriden from TypeHandler."""
4766    code = """  uint32 data_size;
4767  if (!ComputeDataSize(1, sizeof(%s), %d, &data_size)) {
4768    return error::kOutOfBounds;
4769  }
4770"""
4771    file.Write(code % (func.info.data_type, func.info.count))
4772    if func.is_immediate:
4773      file.Write("  if (data_size > immediate_data_size) {\n")
4774      file.Write("    return error::kOutOfBounds;\n")
4775      file.Write("  }\n")
4776
4777  def WriteGLES2Implementation(self, func, file):
4778    """Overrriden from TypeHandler."""
4779    file.Write("%s GLES2Implementation::%s(%s) {\n" %
4780               (func.return_type, func.original_name,
4781                func.MakeTypedOriginalArgString("")))
4782    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
4783    func.WriteDestinationInitalizationValidation(file)
4784    self.WriteClientGLCallLog(func, file)
4785    last_arg_name = func.GetLastOriginalArg().name
4786    values_str = ' << ", " << '.join(
4787        ["%s[%d]" % (last_arg_name, ndx) for ndx in range(0, func.info.count)])
4788    file.Write('  GPU_CLIENT_LOG("values: " << %s);\n' % values_str)
4789    for arg in func.GetOriginalArgs():
4790      arg.WriteClientSideValidationCode(file, func)
4791    file.Write("  helper_->%sImmediate(%s);\n" %
4792               (func.name, func.MakeOriginalArgString("")))
4793    file.Write("  CheckGLError();\n")
4794    file.Write("}\n")
4795    file.Write("\n")
4796
4797  def WriteGLES2ImplementationUnitTest(self, func, file):
4798    """Writes the GLES2 Implemention unit test."""
4799    code = """
4800TEST_F(GLES2ImplementationTest, %(name)s) {
4801  %(type)s data[%(count)d] = {0};
4802  struct Cmds {
4803    cmds::%(name)sImmediate cmd;
4804    %(type)s data[%(count)d];
4805  };
4806
4807  for (int jj = 0; jj < %(count)d; ++jj) {
4808    data[jj] = static_cast<%(type)s>(jj);
4809  }
4810  Cmds expected;
4811  expected.cmd.Init(%(cmd_args)s, &data[0]);
4812  gl_->%(name)s(%(args)s, &data[0]);
4813  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
4814}
4815"""
4816    cmd_arg_strings = []
4817    for count, arg in enumerate(func.GetCmdArgs()[0:-2]):
4818      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
4819    gl_arg_strings = []
4820    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
4821      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
4822    file.Write(code % {
4823          'name': func.name,
4824          'type': func.GetInfo('data_type'),
4825          'count': func.GetInfo('count'),
4826          'args': ", ".join(gl_arg_strings),
4827          'cmd_args': ", ".join(cmd_arg_strings),
4828        })
4829
4830  def WriteImmediateCmdComputeSize(self, func, file):
4831    """Overrriden from TypeHandler."""
4832    file.Write("  static uint32 ComputeDataSize() {\n")
4833    file.Write("    return static_cast<uint32>(\n")
4834    file.Write("        sizeof(%s) * %d);  // NOLINT\n" %
4835               (func.info.data_type, func.info.count))
4836    file.Write("  }\n")
4837    file.Write("\n")
4838    file.Write("  static uint32 ComputeSize() {\n")
4839    file.Write("    return static_cast<uint32>(\n")
4840    file.Write(
4841        "        sizeof(ValueType) + ComputeDataSize());  // NOLINT\n")
4842    file.Write("  }\n")
4843    file.Write("\n")
4844
4845  def WriteImmediateCmdSetHeader(self, func, file):
4846    """Overrriden from TypeHandler."""
4847    file.Write("  void SetHeader() {\n")
4848    file.Write(
4849        "    header.SetCmdByTotalSize<ValueType>(ComputeSize());\n")
4850    file.Write("  }\n")
4851    file.Write("\n")
4852
4853  def WriteImmediateCmdInit(self, func, file):
4854    """Overrriden from TypeHandler."""
4855    last_arg = func.GetLastOriginalArg()
4856    file.Write("  void Init(%s, %s _%s) {\n" %
4857               (func.MakeTypedCmdArgString("_"),
4858                last_arg.type, last_arg.name))
4859    file.Write("    SetHeader();\n")
4860    args = func.GetCmdArgs()
4861    for arg in args:
4862      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
4863    file.Write("    memcpy(ImmediateDataAddress(this),\n")
4864    file.Write("           _%s, ComputeDataSize());\n" % last_arg.name)
4865    file.Write("  }\n")
4866    file.Write("\n")
4867
4868  def WriteImmediateCmdSet(self, func, file):
4869    """Overrriden from TypeHandler."""
4870    last_arg = func.GetLastOriginalArg()
4871    copy_args = func.MakeCmdArgString("_", False)
4872    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
4873               (func.MakeTypedCmdArgString("_", True),
4874                last_arg.type, last_arg.name))
4875    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
4876               (copy_args, last_arg.name))
4877    file.Write("    const uint32 size = ComputeSize();\n")
4878    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
4879               "cmd, size);\n")
4880    file.Write("  }\n")
4881    file.Write("\n")
4882
4883  def WriteImmediateCmdHelper(self, func, file):
4884    """Overrriden from TypeHandler."""
4885    code = """  void %(name)s(%(typed_args)s) {
4886    const uint32 size = gles2::cmds::%(name)s::ComputeSize();
4887    gles2::cmds::%(name)s* c =
4888        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
4889    if (c) {
4890      c->Init(%(args)s);
4891    }
4892  }
4893
4894"""
4895    file.Write(code % {
4896          "name": func.name,
4897          "typed_args": func.MakeTypedOriginalArgString(""),
4898          "args": func.MakeOriginalArgString(""),
4899        })
4900
4901  def WriteImmediateFormatTest(self, func, file):
4902    """Overrriden from TypeHandler."""
4903    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
4904    file.Write("  const int kSomeBaseValueToTestWith = 51;\n")
4905    file.Write("  static %s data[] = {\n" % func.info.data_type)
4906    for v in range(0, func.info.count):
4907      file.Write("    static_cast<%s>(kSomeBaseValueToTestWith + %d),\n" %
4908                 (func.info.data_type, v))
4909    file.Write("  };\n")
4910    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
4911               (func.name, func.name))
4912    file.Write("  void* next_cmd = cmd.Set(\n")
4913    file.Write("      &cmd")
4914    args = func.GetCmdArgs()
4915    for value, arg in enumerate(args):
4916      file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 11))
4917    file.Write(",\n      data);\n")
4918    args = func.GetCmdArgs()
4919    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n"
4920               % func.name)
4921    file.Write("            cmd.header.command);\n")
4922    file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
4923    file.Write("            RoundSizeToMultipleOfEntries(sizeof(data)),\n")
4924    file.Write("            cmd.header.size * 4u);\n")
4925    for value, arg in enumerate(args):
4926      file.Write("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" %
4927                 (arg.type, value + 11, arg.name))
4928    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
4929    file.Write("      next_cmd, sizeof(cmd) +\n")
4930    file.Write("      RoundSizeToMultipleOfEntries(sizeof(data)));\n")
4931    file.Write("  // TODO(gman): Check that data was inserted;\n")
4932    file.Write("}\n")
4933    file.Write("\n")
4934
4935
4936class PUTnHandler(TypeHandler):
4937  """Handler for PUTn 'glUniform__v' type functions."""
4938
4939  def __init__(self):
4940    TypeHandler.__init__(self)
4941
4942  def WriteServiceUnitTest(self, func, file):
4943    """Overridden from TypeHandler."""
4944    TypeHandler.WriteServiceUnitTest(self, func, file)
4945
4946    valid_test = """
4947TEST_F(%(test_name)s, %(name)sValidArgsCountTooLarge) {
4948  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
4949  SpecializedSetup<cmds::%(name)s, 0>(true);
4950  cmds::%(name)s cmd;
4951  cmd.Init(%(args)s);
4952  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4953  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4954}
4955"""
4956    gl_arg_strings = []
4957    arg_strings = []
4958    for count, arg in enumerate(func.GetOriginalArgs()):
4959      # hardcoded to match unit tests.
4960      if count == 0:
4961        # the location of the second element of the 2nd uniform.
4962        # defined in GLES2DecoderBase::SetupShaderForUniform
4963        gl_arg_strings.append("3")
4964        arg_strings.append("ProgramManager::MakeFakeLocation(1, 1)")
4965      elif count == 1:
4966        # the number of elements that gl will be called with.
4967        gl_arg_strings.append("3")
4968        # the number of elements requested in the command.
4969        arg_strings.append("5")
4970      else:
4971        gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
4972        arg_strings.append(arg.GetValidArg(func, count, 0))
4973    extra = {
4974      'gl_args': ", ".join(gl_arg_strings),
4975      'args': ", ".join(arg_strings),
4976    }
4977    self.WriteValidUnitTest(func, file, valid_test, extra)
4978
4979  def WriteImmediateServiceUnitTest(self, func, file):
4980    """Overridden from TypeHandler."""
4981    valid_test = """
4982TEST_F(%(test_name)s, %(name)sValidArgs) {
4983  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
4984  EXPECT_CALL(
4985      *gl_,
4986      %(gl_func_name)s(%(gl_args)s,
4987          reinterpret_cast<%(data_type)s*>(ImmediateDataAddress(&cmd))));
4988  SpecializedSetup<cmds::%(name)s, 0>(true);
4989  %(data_type)s temp[%(data_count)s * 2] = { 0, };
4990  cmd.Init(%(args)s, &temp[0]);
4991  EXPECT_EQ(error::kNoError,
4992            ExecuteImmediateCmd(cmd, sizeof(temp)));
4993  EXPECT_EQ(GL_NO_ERROR, GetGLError());
4994}
4995"""
4996    gl_arg_strings = []
4997    gl_any_strings = []
4998    arg_strings = []
4999    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
5000      gl_arg_strings.append(arg.GetValidGLArg(func, count, 0))
5001      gl_any_strings.append("_")
5002      arg_strings.append(arg.GetValidArg(func, count, 0))
5003    extra = {
5004      'data_type': func.GetInfo('data_type'),
5005      'data_count': func.GetInfo('count'),
5006      'args': ", ".join(arg_strings),
5007      'gl_args': ", ".join(gl_arg_strings),
5008      'gl_any_args': ", ".join(gl_any_strings),
5009    }
5010    self.WriteValidUnitTest(func, file, valid_test, extra)
5011
5012    invalid_test = """
5013TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
5014  cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
5015  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
5016  SpecializedSetup<cmds::%(name)s, 0>(false);
5017  %(data_type)s temp[%(data_count)s * 2] = { 0, };
5018  cmd.Init(%(all_but_last_args)s, &temp[0]);
5019  EXPECT_EQ(error::%(parse_result)s,
5020            ExecuteImmediateCmd(cmd, sizeof(temp)));%(gl_error_test)s
5021}
5022"""
5023    self.WriteInvalidUnitTest(func, file, invalid_test, extra)
5024
5025  def WriteGetDataSizeCode(self, func, file):
5026    """Overrriden from TypeHandler."""
5027    code = """  uint32 data_size;
5028  if (!ComputeDataSize(count, sizeof(%s), %d, &data_size)) {
5029    return error::kOutOfBounds;
5030  }
5031"""
5032    file.Write(code % (func.info.data_type, func.info.count))
5033    if func.is_immediate:
5034      file.Write("  if (data_size > immediate_data_size) {\n")
5035      file.Write("    return error::kOutOfBounds;\n")
5036      file.Write("  }\n")
5037
5038  def WriteGLES2Implementation(self, func, file):
5039    """Overrriden from TypeHandler."""
5040    file.Write("%s GLES2Implementation::%s(%s) {\n" %
5041               (func.return_type, func.original_name,
5042                func.MakeTypedOriginalArgString("")))
5043    file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
5044    func.WriteDestinationInitalizationValidation(file)
5045    self.WriteClientGLCallLog(func, file)
5046    last_arg_name = func.GetLastOriginalArg().name
5047    file.Write("""  GPU_CLIENT_LOG_CODE_BLOCK({
5048    for (GLsizei i = 0; i < count; ++i) {
5049""")
5050    values_str = ' << ", " << '.join(
5051        ["%s[%d + i * %d]" % (
5052            last_arg_name, ndx, func.info.count) for ndx in range(
5053                0, func.info.count)])
5054    file.Write('       GPU_CLIENT_LOG("  " << i << ": " << %s);\n' % values_str)
5055    file.Write("    }\n  });\n")
5056    for arg in func.GetOriginalArgs():
5057      arg.WriteClientSideValidationCode(file, func)
5058    file.Write("  helper_->%sImmediate(%s);\n" %
5059               (func.name, func.MakeOriginalArgString("")))
5060    file.Write("  CheckGLError();\n")
5061    file.Write("}\n")
5062    file.Write("\n")
5063
5064  def WriteGLES2ImplementationUnitTest(self, func, file):
5065    """Writes the GLES2 Implemention unit test."""
5066    code = """
5067TEST_F(GLES2ImplementationTest, %(name)s) {
5068  %(type)s data[%(count_param)d][%(count)d] = {{0}};
5069  struct Cmds {
5070    cmds::%(name)sImmediate cmd;
5071    %(type)s data[%(count_param)d][%(count)d];
5072  };
5073
5074  Cmds expected;
5075  for (int ii = 0; ii < %(count_param)d; ++ii) {
5076    for (int jj = 0; jj < %(count)d; ++jj) {
5077      data[ii][jj] = static_cast<%(type)s>(ii * %(count)d + jj);
5078    }
5079  }
5080  expected.cmd.Init(%(cmd_args)s, &data[0][0]);
5081  gl_->%(name)s(%(args)s, &data[0][0]);
5082  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
5083}
5084"""
5085    cmd_arg_strings = []
5086    for count, arg in enumerate(func.GetCmdArgs()[0:-2]):
5087      cmd_arg_strings.append(arg.GetValidClientSideCmdArg(func, count, 0))
5088    gl_arg_strings = []
5089    count_param = 0
5090    for count, arg in enumerate(func.GetOriginalArgs()[0:-1]):
5091      gl_arg_strings.append(arg.GetValidClientSideArg(func, count, 0))
5092      if arg.name == "count":
5093        count_param = int(arg.GetValidClientSideArg(func, count, 0))
5094    file.Write(code % {
5095          'name': func.name,
5096          'type': func.GetInfo('data_type'),
5097          'count': func.GetInfo('count'),
5098          'args': ", ".join(gl_arg_strings),
5099          'cmd_args': ", ".join(cmd_arg_strings),
5100          'count_param': count_param,
5101        })
5102
5103  def WriteImmediateCmdComputeSize(self, func, file):
5104    """Overrriden from TypeHandler."""
5105    file.Write("  static uint32 ComputeDataSize(GLsizei count) {\n")
5106    file.Write("    return static_cast<uint32>(\n")
5107    file.Write("        sizeof(%s) * %d * count);  // NOLINT\n" %
5108               (func.info.data_type, func.info.count))
5109    file.Write("  }\n")
5110    file.Write("\n")
5111    file.Write("  static uint32 ComputeSize(GLsizei count) {\n")
5112    file.Write("    return static_cast<uint32>(\n")
5113    file.Write(
5114        "        sizeof(ValueType) + ComputeDataSize(count));  // NOLINT\n")
5115    file.Write("  }\n")
5116    file.Write("\n")
5117
5118  def WriteImmediateCmdSetHeader(self, func, file):
5119    """Overrriden from TypeHandler."""
5120    file.Write("  void SetHeader(GLsizei count) {\n")
5121    file.Write(
5122        "    header.SetCmdByTotalSize<ValueType>(ComputeSize(count));\n")
5123    file.Write("  }\n")
5124    file.Write("\n")
5125
5126  def WriteImmediateCmdInit(self, func, file):
5127    """Overrriden from TypeHandler."""
5128    last_arg = func.GetLastOriginalArg()
5129    file.Write("  void Init(%s, %s _%s) {\n" %
5130               (func.MakeTypedCmdArgString("_"),
5131                last_arg.type, last_arg.name))
5132    file.Write("    SetHeader(_count);\n")
5133    args = func.GetCmdArgs()
5134    for arg in args:
5135      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
5136    file.Write("    memcpy(ImmediateDataAddress(this),\n")
5137    file.Write("           _%s, ComputeDataSize(_count));\n" % last_arg.name)
5138    file.Write("  }\n")
5139    file.Write("\n")
5140
5141  def WriteImmediateCmdSet(self, func, file):
5142    """Overrriden from TypeHandler."""
5143    last_arg = func.GetLastOriginalArg()
5144    copy_args = func.MakeCmdArgString("_", False)
5145    file.Write("  void* Set(void* cmd%s, %s _%s) {\n" %
5146               (func.MakeTypedCmdArgString("_", True),
5147                last_arg.type, last_arg.name))
5148    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
5149               (copy_args, last_arg.name))
5150    file.Write("    const uint32 size = ComputeSize(_count);\n")
5151    file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
5152               "cmd, size);\n")
5153    file.Write("  }\n")
5154    file.Write("\n")
5155
5156  def WriteImmediateCmdHelper(self, func, file):
5157    """Overrriden from TypeHandler."""
5158    code = """  void %(name)s(%(typed_args)s) {
5159    const uint32 size = gles2::cmds::%(name)s::ComputeSize(count);
5160    gles2::cmds::%(name)s* c =
5161        GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
5162    if (c) {
5163      c->Init(%(args)s);
5164    }
5165  }
5166
5167"""
5168    file.Write(code % {
5169          "name": func.name,
5170          "typed_args": func.MakeTypedOriginalArgString(""),
5171          "args": func.MakeOriginalArgString(""),
5172        })
5173
5174  def WriteImmediateFormatTest(self, func, file):
5175    """Overrriden from TypeHandler."""
5176    args = func.GetCmdArgs()
5177    count_param = 0
5178    for value, arg in enumerate(args):
5179      if arg.name == "count":
5180        count_param = int(arg.GetValidClientSideArg(func, value, 0))
5181    file.Write("TEST_F(GLES2FormatTest, %s) {\n" % func.name)
5182    file.Write("  const int kSomeBaseValueToTestWith = 51;\n")
5183    file.Write("  static %s data[] = {\n" % func.info.data_type)
5184    for v in range(0, func.info.count * count_param):
5185      file.Write("    static_cast<%s>(kSomeBaseValueToTestWith + %d),\n" %
5186                 (func.info.data_type, v))
5187    file.Write("  };\n")
5188    file.Write("  cmds::%s& cmd = *GetBufferAs<cmds::%s>();\n" %
5189               (func.name, func.name))
5190    file.Write("  const GLsizei kNumElements = %d;\n" % count_param)
5191    file.Write("  const size_t kExpectedCmdSize =\n")
5192    file.Write("      sizeof(cmd) + kNumElements * sizeof(%s) * %d;\n" %
5193               (func.info.data_type, func.info.count))
5194    file.Write("  void* next_cmd = cmd.Set(\n")
5195    file.Write("      &cmd")
5196    for value, arg in enumerate(args):
5197      file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 1))
5198    file.Write(",\n      data);\n")
5199    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
5200               func.name)
5201    file.Write("            cmd.header.command);\n")
5202    file.Write("  EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);\n")
5203    for value, arg in enumerate(args):
5204      file.Write("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" %
5205                 (arg.type, value + 1, arg.name))
5206    file.Write("  CheckBytesWrittenMatchesExpectedSize(\n")
5207    file.Write("      next_cmd, sizeof(cmd) +\n")
5208    file.Write("      RoundSizeToMultipleOfEntries(sizeof(data)));\n")
5209    file.Write("  // TODO(gman): Check that data was inserted;\n")
5210    file.Write("}\n")
5211    file.Write("\n")
5212
5213
5214class PUTXnHandler(TypeHandler):
5215  """Handler for glUniform?f functions."""
5216  def __init__(self):
5217    TypeHandler.__init__(self)
5218
5219  def WriteHandlerImplementation(self, func, file):
5220    """Overrriden from TypeHandler."""
5221    code = """  %(type)s temp[%(count)s] = { %(values)s};
5222  Do%(name)sv(%(location)s, 1, &temp[0]);
5223"""
5224    values = ""
5225    args = func.GetOriginalArgs()
5226    count = int(func.GetInfo('count'))
5227    num_args = len(args)
5228    for ii in range(count):
5229      values += "%s, " % args[len(args) - count + ii].name
5230
5231    file.Write(code % {
5232        'name': func.name,
5233        'count': func.GetInfo('count'),
5234        'type': func.GetInfo('data_type'),
5235        'location': args[0].name,
5236        'args': func.MakeOriginalArgString(""),
5237        'values': values,
5238      })
5239
5240  def WriteServiceUnitTest(self, func, file):
5241    """Overrriden from TypeHandler."""
5242    valid_test = """
5243TEST_F(%(test_name)s, %(name)sValidArgs) {
5244  EXPECT_CALL(*gl_, %(name)sv(%(local_args)s));
5245  SpecializedSetup<cmds::%(name)s, 0>(true);
5246  cmds::%(name)s cmd;
5247  cmd.Init(%(args)s);
5248  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5249  EXPECT_EQ(GL_NO_ERROR, GetGLError());
5250}
5251"""
5252    args = func.GetOriginalArgs()
5253    local_args = "%s, 1, _" % args[0].GetValidGLArg(func, 0, 0)
5254    self.WriteValidUnitTest(func, file, valid_test, {
5255        'name': func.name,
5256        'count': func.GetInfo('count'),
5257        'local_args': local_args,
5258      })
5259
5260    invalid_test = """
5261TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
5262  EXPECT_CALL(*gl_, %(name)sv(_, _, _).Times(0);
5263  SpecializedSetup<cmds::%(name)s, 0>(false);
5264  cmds::%(name)s cmd;
5265  cmd.Init(%(args)s);
5266  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
5267}
5268"""
5269    self.WriteInvalidUnitTest(func, file, invalid_test, {
5270        'name': func.GetInfo('name'),
5271        'count': func.GetInfo('count'),
5272      })
5273
5274
5275class GLcharHandler(CustomHandler):
5276  """Handler for functions that pass a single string ."""
5277
5278  def __init__(self):
5279    CustomHandler.__init__(self)
5280
5281  def WriteImmediateCmdComputeSize(self, func, file):
5282    """Overrriden from TypeHandler."""
5283    file.Write("  static uint32 ComputeSize(uint32 data_size) {\n")
5284    file.Write("    return static_cast<uint32>(\n")
5285    file.Write("        sizeof(ValueType) + data_size);  // NOLINT\n")
5286    file.Write("  }\n")
5287
5288  def WriteImmediateCmdSetHeader(self, func, file):
5289    """Overrriden from TypeHandler."""
5290    code = """
5291  void SetHeader(uint32 data_size) {
5292    header.SetCmdBySize<ValueType>(data_size);
5293  }
5294"""
5295    file.Write(code)
5296
5297  def WriteImmediateCmdInit(self, func, file):
5298    """Overrriden from TypeHandler."""
5299    last_arg = func.GetLastOriginalArg()
5300    args = func.GetCmdArgs()
5301    set_code = []
5302    for arg in args:
5303      set_code.append("    %s = _%s;" % (arg.name, arg.name))
5304    code = """
5305  void Init(%(typed_args)s, uint32 _data_size) {
5306    SetHeader(_data_size);
5307%(set_code)s
5308    memcpy(ImmediateDataAddress(this), _%(last_arg)s, _data_size);
5309  }
5310
5311"""
5312    file.Write(code % {
5313          "typed_args": func.MakeTypedOriginalArgString("_"),
5314          "set_code": "\n".join(set_code),
5315          "last_arg": last_arg.name
5316        })
5317
5318  def WriteImmediateCmdSet(self, func, file):
5319    """Overrriden from TypeHandler."""
5320    last_arg = func.GetLastOriginalArg()
5321    file.Write("  void* Set(void* cmd%s, uint32 _data_size) {\n" %
5322               func.MakeTypedOriginalArgString("_", True))
5323    file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _data_size);\n" %
5324               func.MakeOriginalArgString("_"))
5325    file.Write("    return NextImmediateCmdAddress<ValueType>("
5326               "cmd, _data_size);\n")
5327    file.Write("  }\n")
5328    file.Write("\n")
5329
5330  def WriteImmediateCmdHelper(self, func, file):
5331    """Overrriden from TypeHandler."""
5332    code = """  void %(name)s(%(typed_args)s) {
5333    const uint32 data_size = strlen(name);
5334    gles2::cmds::%(name)s* c =
5335        GetImmediateCmdSpace<gles2::cmds::%(name)s>(data_size);
5336    if (c) {
5337      c->Init(%(args)s, data_size);
5338    }
5339  }
5340
5341"""
5342    file.Write(code % {
5343          "name": func.name,
5344          "typed_args": func.MakeTypedOriginalArgString(""),
5345          "args": func.MakeOriginalArgString(""),
5346        })
5347
5348
5349  def WriteImmediateFormatTest(self, func, file):
5350    """Overrriden from TypeHandler."""
5351    init_code = []
5352    check_code = []
5353    all_but_last_arg = func.GetCmdArgs()[:-1]
5354    for value, arg in enumerate(all_but_last_arg):
5355      init_code.append("      static_cast<%s>(%d)," % (arg.type, value + 11))
5356    for value, arg in enumerate(all_but_last_arg):
5357      check_code.append("  EXPECT_EQ(static_cast<%s>(%d), cmd.%s);" %
5358                        (arg.type, value + 11, arg.name))
5359    code = """
5360TEST_F(GLES2FormatTest, %(func_name)s) {
5361  cmds::%(func_name)s& cmd = *GetBufferAs<cmds::%(func_name)s>();
5362  static const char* const test_str = \"test string\";
5363  void* next_cmd = cmd.Set(
5364      &cmd,
5365%(init_code)s
5366      test_str,
5367      strlen(test_str));
5368  EXPECT_EQ(static_cast<uint32>(cmds::%(func_name)s::kCmdId),
5369            cmd.header.command);
5370  EXPECT_EQ(sizeof(cmd) +
5371            RoundSizeToMultipleOfEntries(strlen(test_str)),
5372            cmd.header.size * 4u);
5373  EXPECT_EQ(static_cast<char*>(next_cmd),
5374            reinterpret_cast<char*>(&cmd) + sizeof(cmd) +
5375                RoundSizeToMultipleOfEntries(strlen(test_str)));
5376%(check_code)s
5377  EXPECT_EQ(static_cast<uint32>(strlen(test_str)), cmd.data_size);
5378  EXPECT_EQ(0, memcmp(test_str, ImmediateDataAddress(&cmd), strlen(test_str)));
5379  CheckBytesWritten(
5380      next_cmd,
5381      sizeof(cmd) + RoundSizeToMultipleOfEntries(strlen(test_str)),
5382      sizeof(cmd) + strlen(test_str));
5383}
5384
5385"""
5386    file.Write(code % {
5387          'func_name': func.name,
5388          'init_code': "\n".join(init_code),
5389          'check_code': "\n".join(check_code),
5390        })
5391
5392
5393class GLcharNHandler(CustomHandler):
5394  """Handler for functions that pass a single string with an optional len."""
5395
5396  def __init__(self):
5397    CustomHandler.__init__(self)
5398
5399  def InitFunction(self, func):
5400    """Overrriden from TypeHandler."""
5401    func.cmd_args = []
5402    func.AddCmdArg(Argument('bucket_id', 'GLuint'))
5403
5404  def AddImmediateFunction(self, generator, func):
5405    """Overrriden from TypeHandler."""
5406    pass
5407
5408  def AddBucketFunction(self, generator, func):
5409    """Overrriden from TypeHandler."""
5410    pass
5411
5412  def WriteServiceImplementation(self, func, file):
5413    """Overrriden from TypeHandler."""
5414    file.Write("""error::Error GLES2DecoderImpl::Handle%(name)s(
5415  uint32 immediate_data_size, const gles2::cmds::%(name)s& c) {
5416  GLuint bucket_id = static_cast<GLuint>(c.%(bucket_id)s);
5417  Bucket* bucket = GetBucket(bucket_id);
5418  if (!bucket || bucket->size() == 0) {
5419    return error::kInvalidArguments;
5420  }
5421  std::string str;
5422  if (!bucket->GetAsString(&str)) {
5423    return error::kInvalidArguments;
5424  }
5425  %(gl_func_name)s(0, str.c_str());
5426  return error::kNoError;
5427}
5428
5429""" % {
5430    'name': func.name,
5431    'gl_func_name': func.GetGLFunctionName(),
5432    'bucket_id': func.cmd_args[0].name,
5433  })
5434
5435
5436class IsHandler(TypeHandler):
5437  """Handler for glIs____ type and glGetError functions."""
5438
5439  def __init__(self):
5440    TypeHandler.__init__(self)
5441
5442  def InitFunction(self, func):
5443    """Overrriden from TypeHandler."""
5444    func.AddCmdArg(Argument("result_shm_id", 'uint32'))
5445    func.AddCmdArg(Argument("result_shm_offset", 'uint32'))
5446    if func.GetInfo('result') == None:
5447      func.AddInfo('result', ['uint32'])
5448
5449  def WriteServiceUnitTest(self, func, file):
5450    """Overrriden from TypeHandler."""
5451    valid_test = """
5452TEST_F(%(test_name)s, %(name)sValidArgs) {
5453  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
5454  SpecializedSetup<cmds::%(name)s, 0>(true);
5455  cmds::%(name)s cmd;
5456  cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);
5457  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5458  EXPECT_EQ(GL_NO_ERROR, GetGLError());
5459}
5460"""
5461    comma = ""
5462    if len(func.GetOriginalArgs()):
5463      comma =", "
5464    self.WriteValidUnitTest(func, file, valid_test, {
5465          'comma': comma,
5466        })
5467
5468    invalid_test = """
5469TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
5470  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
5471  SpecializedSetup<cmds::%(name)s, 0>(false);
5472  cmds::%(name)s cmd;
5473  cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);
5474  EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd));%(gl_error_test)s
5475}
5476"""
5477    self.WriteInvalidUnitTest(func, file, invalid_test, {
5478          'comma': comma,
5479        })
5480
5481    invalid_test = """
5482TEST_F(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
5483  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
5484  SpecializedSetup<cmds::%(name)s, 0>(false);
5485  cmds::%(name)s cmd;
5486  cmd.Init(%(args)s%(comma)skInvalidSharedMemoryId, shared_memory_offset_);
5487  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
5488  cmd.Init(%(args)s%(comma)sshared_memory_id_, kInvalidSharedMemoryOffset);
5489  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
5490}
5491"""
5492    self.WriteValidUnitTest(func, file, invalid_test, {
5493          'comma': comma,
5494        })
5495
5496  def WriteServiceImplementation(self, func, file):
5497    """Overrriden from TypeHandler."""
5498    file.Write(
5499        "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
5500    file.Write(
5501        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
5502        func.name)
5503    args = func.GetOriginalArgs()
5504    for arg in args:
5505      arg.WriteGetCode(file)
5506
5507    code = """  typedef cmds::%(func_name)s::Result Result;
5508  Result* result_dst = GetSharedMemoryAs<Result*>(
5509      c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
5510  if (!result_dst) {
5511    return error::kOutOfBounds;
5512  }
5513"""
5514    file.Write(code % {'func_name': func.name})
5515    func.WriteHandlerValidation(file)
5516    file.Write("  *result_dst = %s(%s);\n" %
5517               (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
5518    file.Write("  return error::kNoError;\n")
5519    file.Write("}\n")
5520    file.Write("\n")
5521
5522  def WriteGLES2Implementation(self, func, file):
5523    """Overrriden from TypeHandler."""
5524    impl_func = func.GetInfo('impl_func')
5525    if impl_func == None or impl_func == True:
5526      error_value = func.GetInfo("error_value") or "GL_FALSE"
5527      file.Write("%s GLES2Implementation::%s(%s) {\n" %
5528                 (func.return_type, func.original_name,
5529                  func.MakeTypedOriginalArgString("")))
5530      file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
5531      self.WriteTraceEvent(func, file)
5532      func.WriteDestinationInitalizationValidation(file)
5533      self.WriteClientGLCallLog(func, file)
5534      file.Write("  typedef cmds::%s::Result Result;\n" % func.name)
5535      file.Write("  Result* result = GetResultAs<Result*>();\n")
5536      file.Write("  if (!result) {\n")
5537      file.Write("    return %s;\n" % error_value)
5538      file.Write("  }\n")
5539      file.Write("  *result = 0;\n")
5540      arg_string = func.MakeOriginalArgString("")
5541      comma = ""
5542      if len(arg_string) > 0:
5543        comma = ", "
5544      file.Write(
5545          "  helper_->%s(%s%sGetResultShmId(), GetResultShmOffset());\n" %
5546                 (func.name, arg_string, comma))
5547      file.Write("  WaitForCmd();\n")
5548      file.Write("  %s result_value = *result;\n" % func.return_type)
5549      file.Write('  GPU_CLIENT_LOG("returned " << result_value);\n')
5550      file.Write("  CheckGLError();\n")
5551      file.Write("  return result_value;\n")
5552      file.Write("}\n")
5553      file.Write("\n")
5554
5555  def WriteGLES2ImplementationUnitTest(self, func, file):
5556    """Overrriden from TypeHandler."""
5557    client_test = func.GetInfo('client_test')
5558    if client_test == None or client_test == True:
5559      code = """
5560TEST_F(GLES2ImplementationTest, %(name)s) {
5561  struct Cmds {
5562    cmds::%(name)s cmd;
5563  };
5564
5565  typedef cmds::%(name)s::Result Result;
5566  Cmds expected;
5567  ExpectedMemoryInfo result1 =
5568      GetExpectedResultMemory(sizeof(cmds::%(name)s::Result));
5569  expected.cmd.Init(1, result1.id, result1.offset);
5570
5571  EXPECT_CALL(*command_buffer(), OnFlush())
5572      .WillOnce(SetMemory(result1.ptr, uint32(1)))
5573      .RetiresOnSaturation();
5574
5575  GLboolean result = gl_->%(name)s(1);
5576  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
5577  EXPECT_TRUE(result);
5578}
5579"""
5580      file.Write(code % {
5581            'name': func.name,
5582          })
5583
5584
5585class STRnHandler(TypeHandler):
5586  """Handler for GetProgramInfoLog, GetShaderInfoLog, GetShaderSource, and
5587  GetTranslatedShaderSourceANGLE."""
5588
5589  def __init__(self):
5590    TypeHandler.__init__(self)
5591
5592  def InitFunction(self, func):
5593    """Overrriden from TypeHandler."""
5594    # remove all but the first cmd args.
5595    cmd_args = func.GetCmdArgs()
5596    func.ClearCmdArgs()
5597    func.AddCmdArg(cmd_args[0])
5598    # add on a bucket id.
5599    func.AddCmdArg(Argument('bucket_id', 'uint32'))
5600
5601  def WriteGLES2Implementation(self, func, file):
5602    """Overrriden from TypeHandler."""
5603    code_1 = """%(return_type)s GLES2Implementation::%(func_name)s(%(args)s) {
5604  GPU_CLIENT_SINGLE_THREAD_CHECK();
5605"""
5606    code_2 = """  GPU_CLIENT_LOG("[" << GetLogPrefix()
5607      << "] gl%(func_name)s" << "("
5608      << %(arg0)s << ", "
5609      << %(arg1)s << ", "
5610      << static_cast<void*>(%(arg2)s) << ", "
5611      << static_cast<void*>(%(arg3)s) << ")");
5612  helper_->SetBucketSize(kResultBucketId, 0);
5613  helper_->%(func_name)s(%(id_name)s, kResultBucketId);
5614  std::string str;
5615  GLsizei max_size = 0;
5616  if (GetBucketAsString(kResultBucketId, &str)) {
5617    if (bufsize > 0) {
5618      max_size =
5619          std::min(static_cast<size_t>(%(bufsize_name)s) - 1, str.size());
5620      memcpy(%(dest_name)s, str.c_str(), max_size);
5621      %(dest_name)s[max_size] = '\\0';
5622      GPU_CLIENT_LOG("------\\n" << %(dest_name)s << "\\n------");
5623    }
5624  }
5625  if (%(length_name)s != NULL) {
5626    *%(length_name)s = max_size;
5627  }
5628  CheckGLError();
5629}
5630"""
5631    args = func.GetOriginalArgs()
5632    str_args = {
5633      'return_type': func.return_type,
5634      'func_name': func.original_name,
5635      'args': func.MakeTypedOriginalArgString(""),
5636      'id_name': args[0].name,
5637      'bufsize_name': args[1].name,
5638      'length_name': args[2].name,
5639      'dest_name': args[3].name,
5640      'arg0': args[0].name,
5641      'arg1': args[1].name,
5642      'arg2': args[2].name,
5643      'arg3': args[3].name,
5644    }
5645    file.Write(code_1 % str_args)
5646    func.WriteDestinationInitalizationValidation(file)
5647    file.Write(code_2 % str_args)
5648
5649  def WriteServiceUnitTest(self, func, file):
5650    """Overrriden from TypeHandler."""
5651    valid_test = """
5652TEST_F(%(test_name)s, %(name)sValidArgs) {
5653  const char* kInfo = "hello";
5654  const uint32 kBucketId = 123;
5655  SpecializedSetup<cmds::%(name)s, 0>(true);
5656%(expect_len_code)s
5657  EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
5658      .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
5659                      SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1)));
5660  cmds::%(name)s cmd;
5661  cmd.Init(%(args)s);
5662  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5663  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
5664  ASSERT_TRUE(bucket != NULL);
5665  EXPECT_EQ(strlen(kInfo) + 1, bucket->size());
5666  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kInfo,
5667                      bucket->size()));
5668  EXPECT_EQ(GL_NO_ERROR, GetGLError());
5669}
5670"""
5671    args = func.GetOriginalArgs()
5672    id_name = args[0].GetValidGLArg(func, 0, 0)
5673    get_len_func = func.GetInfo('get_len_func')
5674    get_len_enum = func.GetInfo('get_len_enum')
5675    sub = {
5676        'id_name': id_name,
5677        'get_len_func': get_len_func,
5678        'get_len_enum': get_len_enum,
5679        'gl_args': '%s, strlen(kInfo) + 1, _, _' %
5680             args[0].GetValidGLArg(func, 0, 0),
5681        'args': '%s, kBucketId' % args[0].GetValidArg(func, 0, 0),
5682        'expect_len_code': '',
5683    }
5684    if get_len_func and get_len_func[0:2] == 'gl':
5685      sub['expect_len_code'] = (
5686        "  EXPECT_CALL(*gl_, %s(%s, %s, _))\n"
5687        "      .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1));") % (
5688            get_len_func[2:], id_name, get_len_enum)
5689    self.WriteValidUnitTest(func, file, valid_test, sub)
5690
5691    invalid_test = """
5692TEST_F(%(test_name)s, %(name)sInvalidArgs) {
5693  const uint32 kBucketId = 123;
5694  EXPECT_CALL(*gl_, %(gl_func_name)s(_, _, _, _))
5695      .Times(0);
5696  cmds::%(name)s cmd;
5697  cmd.Init(kInvalidClientId, kBucketId);
5698  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5699  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5700}
5701"""
5702    self.WriteValidUnitTest(func, file, invalid_test)
5703
5704  def WriteServiceImplementation(self, func, file):
5705    """Overrriden from TypeHandler."""
5706    pass
5707
5708
5709class FunctionInfo(object):
5710  """Holds info about a function."""
5711
5712  def __init__(self, info, type_handler):
5713    for key in info:
5714      setattr(self, key, info[key])
5715    self.type_handler = type_handler
5716    if not 'type' in info:
5717      self.type = ''
5718
5719
5720class Argument(object):
5721  """A class that represents a function argument."""
5722
5723  cmd_type_map_ = {
5724    'GLenum': 'uint32',
5725    'GLint': 'int32',
5726    'GLintptr': 'int32',
5727    'GLsizei': 'int32',
5728    'GLsizeiptr': 'int32',
5729    'GLfloat': 'float',
5730    'GLclampf': 'float',
5731  }
5732  need_validation_ = ['GLsizei*', 'GLboolean*', 'GLenum*', 'GLint*']
5733
5734  def __init__(self, name, type):
5735    self.name = name
5736    self.optional = type.endswith("Optional*")
5737    if self.optional:
5738      type = type[:-9] + "*"
5739    self.type = type
5740
5741    if type in self.cmd_type_map_:
5742      self.cmd_type = self.cmd_type_map_[type]
5743    else:
5744      self.cmd_type = 'uint32'
5745
5746  def IsPointer(self):
5747    """Returns true if argument is a pointer."""
5748    return False
5749
5750  def AddCmdArgs(self, args):
5751    """Adds command arguments for this argument to the given list."""
5752    return args.append(self)
5753
5754  def AddInitArgs(self, args):
5755    """Adds init arguments for this argument to the given list."""
5756    return args.append(self)
5757
5758  def GetValidArg(self, func, offset, index):
5759    """Gets a valid value for this argument."""
5760    valid_arg = func.GetValidArg(offset)
5761    if valid_arg != None:
5762      return valid_arg
5763    return str(offset + 1)
5764
5765  def GetValidClientSideArg(self, func, offset, index):
5766    """Gets a valid value for this argument."""
5767    return str(offset + 1)
5768
5769  def GetValidClientSideCmdArg(self, func, offset, index):
5770    """Gets a valid value for this argument."""
5771    return str(offset + 1)
5772
5773  def GetValidGLArg(self, func, offset, index):
5774    """Gets a valid GL value for this argument."""
5775    valid_arg = func.GetValidArg(offset)
5776    if valid_arg != None:
5777      return valid_arg
5778    return str(offset + 1)
5779
5780  def GetNumInvalidValues(self, func):
5781    """returns the number of invalid values to be tested."""
5782    return 0
5783
5784  def GetInvalidArg(self, offset, index):
5785    """returns an invalid value and expected parse result by index."""
5786    return ("---ERROR0---", "---ERROR2---", None)
5787
5788  def GetLogArg(self):
5789    """Get argument appropriate for LOG macro."""
5790    if self.type == 'GLboolean':
5791      return 'GLES2Util::GetStringBool(%s)' % self.name
5792    if self.type == 'GLenum':
5793      return 'GLES2Util::GetStringEnum(%s)' % self.name
5794    return self.name
5795
5796  def WriteGetCode(self, file):
5797    """Writes the code to get an argument from a command structure."""
5798    file.Write("  %s %s = static_cast<%s>(c.%s);\n" %
5799               (self.type, self.name, self.type, self.name))
5800
5801  def WriteValidationCode(self, file, func):
5802    """Writes the validation code for an argument."""
5803    pass
5804
5805  def WriteClientSideValidationCode(self, file, func):
5806    """Writes the validation code for an argument."""
5807    pass
5808
5809  def WriteDestinationInitalizationValidation(self, file, func):
5810    """Writes the client side destintion initialization validation."""
5811    pass
5812
5813  def WriteDestinationInitalizationValidatationIfNeeded(self, file, func):
5814    """Writes the client side destintion initialization validation if needed."""
5815    parts = self.type.split(" ")
5816    if len(parts) > 1:
5817      return
5818    if parts[0] in self.need_validation_:
5819      file.Write(
5820          "  GPU_CLIENT_VALIDATE_DESTINATION_%sINITALIZATION(%s, %s);\n" %
5821          ("OPTIONAL_" if self.optional else "", self.type[:-1], self.name))
5822
5823
5824  def WriteGetAddress(self, file):
5825    """Writes the code to get the address this argument refers to."""
5826    pass
5827
5828  def GetImmediateVersion(self):
5829    """Gets the immediate version of this argument."""
5830    return self
5831
5832  def GetBucketVersion(self):
5833    """Gets the bucket version of this argument."""
5834    return self
5835
5836
5837class BoolArgument(Argument):
5838  """class for GLboolean"""
5839
5840  def __init__(self, name, type):
5841    Argument.__init__(self, name, 'GLboolean')
5842
5843  def GetValidArg(self, func, offset, index):
5844    """Gets a valid value for this argument."""
5845    return 'true'
5846
5847  def GetValidClientSideArg(self, func, offset, index):
5848    """Gets a valid value for this argument."""
5849    return 'true'
5850
5851  def GetValidClientSideCmdArg(self, func, offset, index):
5852    """Gets a valid value for this argument."""
5853    return 'true'
5854
5855  def GetValidGLArg(self, func, offset, index):
5856    """Gets a valid GL value for this argument."""
5857    return 'true'
5858
5859
5860class UniformLocationArgument(Argument):
5861  """class for uniform locations."""
5862
5863  def __init__(self, name):
5864    Argument.__init__(self, name, "GLint")
5865
5866  def WriteGetCode(self, file):
5867    """Writes the code to get an argument from a command structure."""
5868    code = """  %s %s = static_cast<%s>(c.%s);
5869"""
5870    file.Write(code % (self.type, self.name, self.type, self.name))
5871
5872  def GetValidArg(self, func, offset, index):
5873    """Gets a valid value for this argument."""
5874    return "%d" % (offset + 1)
5875
5876
5877class DataSizeArgument(Argument):
5878  """class for data_size which Bucket commands do not need."""
5879
5880  def __init__(self, name):
5881    Argument.__init__(self, name, "uint32")
5882
5883  def GetBucketVersion(self):
5884    return None
5885
5886
5887class SizeArgument(Argument):
5888  """class for GLsizei and GLsizeiptr."""
5889
5890  def __init__(self, name, type):
5891    Argument.__init__(self, name, type)
5892
5893  def GetNumInvalidValues(self, func):
5894    """overridden from Argument."""
5895    if func.is_immediate:
5896      return 0
5897    return 1
5898
5899  def GetInvalidArg(self, offset, index):
5900    """overridden from Argument."""
5901    return ("-1", "kNoError", "GL_INVALID_VALUE")
5902
5903  def WriteValidationCode(self, file, func):
5904    """overridden from Argument."""
5905    file.Write("  if (%s < 0) {\n" % self.name)
5906    file.Write(
5907        "    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, \"gl%s\", \"%s < 0\");\n" %
5908        (func.original_name, self.name))
5909    file.Write("    return error::kNoError;\n")
5910    file.Write("  }\n")
5911
5912  def WriteClientSideValidationCode(self, file, func):
5913    """overridden from Argument."""
5914    file.Write("  if (%s < 0) {\n" % self.name)
5915    file.Write(
5916        "    SetGLError(GL_INVALID_VALUE, \"gl%s\", \"%s < 0\");\n" %
5917        (func.original_name, self.name))
5918    file.Write("    return;\n")
5919    file.Write("  }\n")
5920
5921
5922class SizeNotNegativeArgument(SizeArgument):
5923  """class for GLsizeiNotNegative. It's NEVER allowed to be negative"""
5924
5925  def __init__(self, name, type, gl_type):
5926    SizeArgument.__init__(self, name, gl_type)
5927
5928  def GetInvalidArg(self, offset, index):
5929    """overridden from SizeArgument."""
5930    return ("-1", "kOutOfBounds", "GL_NO_ERROR")
5931
5932  def WriteValidationCode(self, file, func):
5933    """overridden from SizeArgument."""
5934    pass
5935
5936
5937class EnumBaseArgument(Argument):
5938  """Base class for EnumArgument, IntArgument and ValidatedBoolArgument"""
5939
5940  def __init__(self, name, gl_type, type, gl_error):
5941    Argument.__init__(self, name, gl_type)
5942
5943    self.local_type = type
5944    self.gl_error = gl_error
5945    name = type[len(gl_type):]
5946    self.type_name = name
5947    self.enum_info = _ENUM_LISTS[name]
5948
5949  def WriteValidationCode(self, file, func):
5950    file.Write("  if (!validators_->%s.IsValid(%s)) {\n" %
5951        (ToUnderscore(self.type_name), self.name))
5952    if self.gl_error == "GL_INVALID_ENUM":
5953      file.Write(
5954          "    LOCAL_SET_GL_ERROR_INVALID_ENUM(\"gl%s\", %s, \"%s\");\n" %
5955          (func.original_name, self.name, self.name))
5956    else:
5957      file.Write(
5958          "    LOCAL_SET_GL_ERROR(%s, \"gl%s\", \"%s %s\");\n" %
5959          (self.gl_error, func.original_name, self.name, self.gl_error))
5960    file.Write("    return error::kNoError;\n")
5961    file.Write("  }\n")
5962
5963  def GetValidArg(self, func, offset, index):
5964    valid_arg = func.GetValidArg(offset)
5965    if valid_arg != None:
5966      return valid_arg
5967    if 'valid' in self.enum_info:
5968      valid = self.enum_info['valid']
5969      num_valid = len(valid)
5970      if index >= num_valid:
5971        index = num_valid - 1
5972      return valid[index]
5973    return str(offset + 1)
5974
5975  def GetValidClientSideArg(self, func, offset, index):
5976    """Gets a valid value for this argument."""
5977    return self.GetValidArg(func, offset, index)
5978
5979  def GetValidClientSideCmdArg(self, func, offset, index):
5980    """Gets a valid value for this argument."""
5981    return self.GetValidArg(func, offset, index)
5982
5983  def GetValidGLArg(self, func, offset, index):
5984    """Gets a valid value for this argument."""
5985    return self.GetValidArg(func, offset, index)
5986
5987  def GetNumInvalidValues(self, func):
5988    """returns the number of invalid values to be tested."""
5989    if 'invalid' in self.enum_info:
5990      invalid = self.enum_info['invalid']
5991      return len(invalid)
5992    return 0
5993
5994  def GetInvalidArg(self, offset, index):
5995    """returns an invalid value by index."""
5996    if 'invalid' in self.enum_info:
5997      invalid = self.enum_info['invalid']
5998      num_invalid = len(invalid)
5999      if index >= num_invalid:
6000        index = num_invalid - 1
6001      return (invalid[index], "kNoError", self.gl_error)
6002    return ("---ERROR1---", "kNoError", self.gl_error)
6003
6004
6005class EnumArgument(EnumBaseArgument):
6006  """A class that represents a GLenum argument"""
6007
6008  def __init__(self, name, type):
6009    EnumBaseArgument.__init__(self, name, "GLenum", type, "GL_INVALID_ENUM")
6010
6011  def GetLogArg(self):
6012    """Overridden from Argument."""
6013    return ("GLES2Util::GetString%s(%s)" %
6014            (self.type_name, self.name))
6015
6016
6017class IntArgument(EnumBaseArgument):
6018  """A class for a GLint argument that can only except specific values.
6019
6020  For example glTexImage2D takes a GLint for its internalformat
6021  argument instead of a GLenum.
6022  """
6023
6024  def __init__(self, name, type):
6025    EnumBaseArgument.__init__(self, name, "GLint", type, "GL_INVALID_VALUE")
6026
6027
6028class ValidatedBoolArgument(EnumBaseArgument):
6029  """A class for a GLboolean argument that can only except specific values.
6030
6031  For example glUniformMatrix takes a GLboolean for it's transpose but it
6032  must be false.
6033  """
6034
6035  def __init__(self, name, type):
6036    EnumBaseArgument.__init__(self, name, "GLboolean", type, "GL_INVALID_VALUE")
6037
6038  def GetLogArg(self):
6039    """Overridden from Argument."""
6040    return 'GLES2Util::GetStringBool(%s)' % self.name
6041
6042
6043class ImmediatePointerArgument(Argument):
6044  """A class that represents an immediate argument to a function.
6045
6046  An immediate argument is one where the data follows the command.
6047  """
6048
6049  def __init__(self, name, type):
6050    Argument.__init__(self, name, type)
6051
6052  def AddCmdArgs(self, args):
6053    """Overridden from Argument."""
6054    pass
6055
6056  def WriteGetCode(self, file):
6057    """Overridden from Argument."""
6058    file.Write(
6059      "  %s %s = GetImmediateDataAs<%s>(\n" %
6060      (self.type, self.name, self.type))
6061    file.Write("      c, data_size, immediate_data_size);\n")
6062
6063  def WriteValidationCode(self, file, func):
6064    """Overridden from Argument."""
6065    file.Write("  if (%s == NULL) {\n" % self.name)
6066    file.Write("    return error::kOutOfBounds;\n")
6067    file.Write("  }\n")
6068
6069  def GetImmediateVersion(self):
6070    """Overridden from Argument."""
6071    return None
6072
6073  def WriteDestinationInitalizationValidation(self, file, func):
6074    """Overridden from Argument."""
6075    self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
6076
6077  def GetLogArg(self):
6078    """Overridden from Argument."""
6079    return "static_cast<const void*>(%s)" % self.name
6080
6081
6082class BucketPointerArgument(Argument):
6083  """A class that represents an bucket argument to a function."""
6084
6085  def __init__(self, name, type):
6086    Argument.__init__(self, name, type)
6087
6088  def AddCmdArgs(self, args):
6089    """Overridden from Argument."""
6090    pass
6091
6092  def WriteGetCode(self, file):
6093    """Overridden from Argument."""
6094    file.Write(
6095      "  %s %s = bucket->GetData(0, data_size);\n" %
6096      (self.type, self.name))
6097
6098  def WriteValidationCode(self, file, func):
6099    """Overridden from Argument."""
6100    pass
6101
6102  def GetImmediateVersion(self):
6103    """Overridden from Argument."""
6104    return None
6105
6106  def WriteDestinationInitalizationValidation(self, file, func):
6107    """Overridden from Argument."""
6108    self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
6109
6110  def GetLogArg(self):
6111    """Overridden from Argument."""
6112    return "static_cast<const void*>(%s)" % self.name
6113
6114
6115class PointerArgument(Argument):
6116  """A class that represents a pointer argument to a function."""
6117
6118  def __init__(self, name, type):
6119    Argument.__init__(self, name, type)
6120
6121  def IsPointer(self):
6122    """Returns true if argument is a pointer."""
6123    return True
6124
6125  def GetValidArg(self, func, offset, index):
6126    """Overridden from Argument."""
6127    return "shared_memory_id_, shared_memory_offset_"
6128
6129  def GetValidGLArg(self, func, offset, index):
6130    """Overridden from Argument."""
6131    return "reinterpret_cast<%s>(shared_memory_address_)" % self.type
6132
6133  def GetNumInvalidValues(self, func):
6134    """Overridden from Argument."""
6135    return 2
6136
6137  def GetInvalidArg(self, offset, index):
6138    """Overridden from Argument."""
6139    if index == 0:
6140      return ("kInvalidSharedMemoryId, 0", "kOutOfBounds", None)
6141    else:
6142      return ("shared_memory_id_, kInvalidSharedMemoryOffset",
6143              "kOutOfBounds", None)
6144
6145  def GetLogArg(self):
6146    """Overridden from Argument."""
6147    return "static_cast<const void*>(%s)" % self.name
6148
6149  def AddCmdArgs(self, args):
6150    """Overridden from Argument."""
6151    args.append(Argument("%s_shm_id" % self.name, 'uint32'))
6152    args.append(Argument("%s_shm_offset" % self.name, 'uint32'))
6153
6154  def WriteGetCode(self, file):
6155    """Overridden from Argument."""
6156    file.Write(
6157        "  %s %s = GetSharedMemoryAs<%s>(\n" %
6158        (self.type, self.name, self.type))
6159    file.Write(
6160        "      c.%s_shm_id, c.%s_shm_offset, data_size);\n" %
6161        (self.name, self.name))
6162
6163  def WriteGetAddress(self, file):
6164    """Overridden from Argument."""
6165    file.Write(
6166        "  %s %s = GetSharedMemoryAs<%s>(\n" %
6167        (self.type, self.name, self.type))
6168    file.Write(
6169        "      %s_shm_id, %s_shm_offset, %s_size);\n" %
6170        (self.name, self.name, self.name))
6171
6172  def WriteValidationCode(self, file, func):
6173    """Overridden from Argument."""
6174    file.Write("  if (%s == NULL) {\n" % self.name)
6175    file.Write("    return error::kOutOfBounds;\n")
6176    file.Write("  }\n")
6177
6178  def GetImmediateVersion(self):
6179    """Overridden from Argument."""
6180    return ImmediatePointerArgument(self.name, self.type)
6181
6182  def GetBucketVersion(self):
6183    """Overridden from Argument."""
6184    if self.type == "const char*":
6185      return InputStringBucketArgument(self.name, self.type)
6186    return BucketPointerArgument(self.name, self.type)
6187
6188  def WriteDestinationInitalizationValidation(self, file, func):
6189    """Overridden from Argument."""
6190    self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
6191
6192
6193class InputStringBucketArgument(Argument):
6194  """An string input argument where the string is passed in a bucket."""
6195
6196  def __init__(self, name, type):
6197    Argument.__init__(self, name + "_bucket_id", "uint32")
6198
6199  def WriteGetCode(self, file):
6200    """Overridden from Argument."""
6201    code = """
6202  Bucket* %(name)s_bucket = GetBucket(c.%(name)s);
6203  if (!%(name)s_bucket) {
6204    return error::kInvalidArguments;
6205  }
6206  std::string %(name)s_str;
6207  if (!%(name)s_bucket->GetAsString(&%(name)s_str)) {
6208    return error::kInvalidArguments;
6209  }
6210  const char* %(name)s = %(name)s_str.c_str();
6211"""
6212    file.Write(code % {
6213        'name': self.name,
6214      })
6215
6216  def GetValidArg(self, func, offset, index):
6217    return "kNameBucketId"
6218
6219  def GetValidGLArg(self, func, offset, index):
6220    return "_"
6221
6222
6223class NonImmediatePointerArgument(PointerArgument):
6224  """A pointer argument that stays a pointer even in an immediate cmd."""
6225
6226  def __init__(self, name, type):
6227    PointerArgument.__init__(self, name, type)
6228
6229  def IsPointer(self):
6230    """Returns true if argument is a pointer."""
6231    return False
6232
6233  def GetImmediateVersion(self):
6234    """Overridden from Argument."""
6235    return self
6236
6237
6238class ResourceIdArgument(Argument):
6239  """A class that represents a resource id argument to a function."""
6240
6241  def __init__(self, name, type):
6242    match = re.match("(GLid\w+)", type)
6243    self.resource_type = match.group(1)[4:]
6244    type = type.replace(match.group(1), "GLuint")
6245    Argument.__init__(self, name, type)
6246
6247  def WriteGetCode(self, file):
6248    """Overridden from Argument."""
6249    file.Write("  %s %s = c.%s;\n" % (self.type, self.name, self.name))
6250
6251  def GetValidArg(self, func, offset, index):
6252    return "client_%s_id_" % self.resource_type.lower()
6253
6254  def GetValidGLArg(self, func, offset, index):
6255    return "kService%sId" % self.resource_type
6256
6257
6258class ResourceIdBindArgument(Argument):
6259  """Represents a resource id argument to a bind function."""
6260
6261  def __init__(self, name, type):
6262    match = re.match("(GLidBind\w+)", type)
6263    self.resource_type = match.group(1)[8:]
6264    type = type.replace(match.group(1), "GLuint")
6265    Argument.__init__(self, name, type)
6266
6267  def WriteGetCode(self, file):
6268    """Overridden from Argument."""
6269    code = """  %(type)s %(name)s = c.%(name)s;
6270"""
6271    file.Write(code % {'type': self.type, 'name': self.name})
6272
6273  def GetValidArg(self, func, offset, index):
6274    return "client_%s_id_" % self.resource_type.lower()
6275
6276  def GetValidGLArg(self, func, offset, index):
6277    return "kService%sId" % self.resource_type
6278
6279
6280class ResourceIdZeroArgument(Argument):
6281  """Represents a resource id argument to a function that can be zero."""
6282
6283  def __init__(self, name, type):
6284    match = re.match("(GLidZero\w+)", type)
6285    self.resource_type = match.group(1)[8:]
6286    type = type.replace(match.group(1), "GLuint")
6287    Argument.__init__(self, name, type)
6288
6289  def WriteGetCode(self, file):
6290    """Overridden from Argument."""
6291    file.Write("  %s %s = c.%s;\n" % (self.type, self.name, self.name))
6292
6293  def GetValidArg(self, func, offset, index):
6294    return "client_%s_id_" % self.resource_type.lower()
6295
6296  def GetValidGLArg(self, func, offset, index):
6297    return "kService%sId" % self.resource_type
6298
6299  def GetNumInvalidValues(self, func):
6300    """returns the number of invalid values to be tested."""
6301    return 1
6302
6303  def GetInvalidArg(self, offset, index):
6304    """returns an invalid value by index."""
6305    return ("kInvalidClientId", "kNoError", "GL_INVALID_VALUE")
6306
6307
6308class Function(object):
6309  """A class that represents a function."""
6310
6311  def __init__(self, original_name, name, info, return_type, original_args,
6312               args_for_cmds, cmd_args, init_args, num_pointer_args):
6313    self.name = name
6314    self.original_name = original_name
6315    self.info = info
6316    self.type_handler = info.type_handler
6317    self.return_type = return_type
6318    self.original_args = original_args
6319    self.num_pointer_args = num_pointer_args
6320    self.can_auto_generate = num_pointer_args == 0 and return_type == "void"
6321    self.cmd_args = cmd_args
6322    self.init_args = init_args
6323    self.InitFunction()
6324    self.args_for_cmds = args_for_cmds
6325    self.is_immediate = False
6326
6327  def IsType(self, type_name):
6328    """Returns true if function is a certain type."""
6329    return self.info.type == type_name
6330
6331  def InitFunction(self):
6332    """Calls the init function for the type handler."""
6333    self.type_handler.InitFunction(self)
6334
6335  def GetInfo(self, name):
6336    """Returns a value from the function info for this function."""
6337    if hasattr(self.info, name):
6338      return getattr(self.info, name)
6339    return None
6340
6341  def GetValidArg(self, index):
6342    """Gets a valid arg from the function info if one exists."""
6343    valid_args = self.GetInfo('valid_args')
6344    if valid_args and str(index) in valid_args:
6345      return valid_args[str(index)]
6346    return None
6347
6348  def AddInfo(self, name, value):
6349    """Adds an info."""
6350    setattr(self.info, name, value)
6351
6352  def IsCoreGLFunction(self):
6353    return (not self.GetInfo('extension') and
6354            not self.GetInfo('pepper_interface'))
6355
6356  def InPepperInterface(self, interface):
6357    ext = self.GetInfo('pepper_interface')
6358    if not interface.GetName():
6359      return self.IsCoreGLFunction()
6360    return ext == interface.GetName()
6361
6362  def InAnyPepperExtension(self):
6363    return self.IsCoreGLFunction() or self.GetInfo('pepper_interface')
6364
6365  def GetGLFunctionName(self):
6366    """Gets the function to call to execute GL for this command."""
6367    if self.GetInfo('decoder_func'):
6368      return self.GetInfo('decoder_func')
6369    return "gl%s" % self.original_name
6370
6371  def GetGLTestFunctionName(self):
6372    gl_func_name = self.GetInfo('gl_test_func')
6373    if gl_func_name == None:
6374      gl_func_name = self.GetGLFunctionName()
6375    if gl_func_name.startswith("gl"):
6376      gl_func_name = gl_func_name[2:]
6377    else:
6378      gl_func_name = self.original_name
6379    return gl_func_name
6380
6381  def AddCmdArg(self, arg):
6382    """Adds a cmd argument to this function."""
6383    self.cmd_args.append(arg)
6384
6385  def GetCmdArgs(self):
6386    """Gets the command args for this function."""
6387    return self.cmd_args
6388
6389  def ClearCmdArgs(self):
6390    """Clears the command args for this function."""
6391    self.cmd_args = []
6392
6393  def GetInitArgs(self):
6394    """Gets the init args for this function."""
6395    return self.init_args
6396
6397  def GetOriginalArgs(self):
6398    """Gets the original arguments to this function."""
6399    return self.original_args
6400
6401  def GetLastOriginalArg(self):
6402    """Gets the last original argument to this function."""
6403    return self.original_args[len(self.original_args) - 1]
6404
6405  def __MaybePrependComma(self, arg_string, add_comma):
6406    """Adds a comma if arg_string is not empty and add_comma is true."""
6407    comma = ""
6408    if add_comma and len(arg_string):
6409      comma = ", "
6410    return "%s%s" % (comma, arg_string)
6411
6412  def MakeTypedOriginalArgString(self, prefix, add_comma = False):
6413    """Gets a list of arguments as they are in GL."""
6414    args = self.GetOriginalArgs()
6415    arg_string = ", ".join(
6416        ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
6417    return self.__MaybePrependComma(arg_string, add_comma)
6418
6419  def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "):
6420    """Gets the list of arguments as they are in GL."""
6421    args = self.GetOriginalArgs()
6422    arg_string = separator.join(
6423        ["%s%s" % (prefix, arg.name) for arg in args])
6424    return self.__MaybePrependComma(arg_string, add_comma)
6425
6426  def MakeTypedPepperArgString(self, prefix):
6427    """Gets a list of arguments as they need to be for Pepper."""
6428    if self.GetInfo("pepper_args"):
6429      return self.GetInfo("pepper_args")
6430    else:
6431      return self.MakeTypedOriginalArgString(prefix, False)
6432
6433  def MakeTypedCmdArgString(self, prefix, add_comma = False):
6434    """Gets a typed list of arguments as they need to be for command buffers."""
6435    args = self.GetCmdArgs()
6436    arg_string = ", ".join(
6437        ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
6438    return self.__MaybePrependComma(arg_string, add_comma)
6439
6440  def MakeCmdArgString(self, prefix, add_comma = False):
6441    """Gets the list of arguments as they need to be for command buffers."""
6442    args = self.GetCmdArgs()
6443    arg_string = ", ".join(
6444        ["%s%s" % (prefix, arg.name) for arg in args])
6445    return self.__MaybePrependComma(arg_string, add_comma)
6446
6447  def MakeTypedInitString(self, prefix, add_comma = False):
6448    """Gets a typed list of arguments as they need to be for cmd Init/Set."""
6449    args = self.GetInitArgs()
6450    arg_string = ", ".join(
6451        ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
6452    return self.__MaybePrependComma(arg_string, add_comma)
6453
6454  def MakeInitString(self, prefix, add_comma = False):
6455    """Gets the list of arguments as they need to be for cmd Init/Set."""
6456    args = self.GetInitArgs()
6457    arg_string = ", ".join(
6458        ["%s%s" % (prefix, arg.name) for arg in args])
6459    return self.__MaybePrependComma(arg_string, add_comma)
6460
6461  def MakeLogArgString(self):
6462    """Makes a string of the arguments for the LOG macros"""
6463    args = self.GetOriginalArgs()
6464    return ' << ", " << '.join([arg.GetLogArg() for arg in args])
6465
6466  def WriteCommandDescription(self, file):
6467    """Writes a description of the command."""
6468    file.Write("//! Command that corresponds to gl%s.\n" % self.original_name)
6469
6470  def WriteHandlerValidation(self, file):
6471    """Writes validation code for the function."""
6472    for arg in self.GetOriginalArgs():
6473      arg.WriteValidationCode(file, self)
6474    self.WriteValidationCode(file)
6475
6476  def WriteHandlerImplementation(self, file):
6477    """Writes the handler implementation for this command."""
6478    self.type_handler.WriteHandlerImplementation(self, file)
6479
6480  def WriteValidationCode(self, file):
6481    """Writes the validation code for a command."""
6482    pass
6483
6484  def WriteCmdArgFlag(self, file):
6485    """Writes the cmd kArgFlags constant."""
6486    file.Write("  static const cmd::ArgFlags kArgFlags = cmd::kFixed;\n")
6487
6488  def WriteCmdComputeSize(self, file):
6489    """Writes the ComputeSize function for the command."""
6490    file.Write("  static uint32 ComputeSize() {\n")
6491    file.Write(
6492        "    return static_cast<uint32>(sizeof(ValueType));  // NOLINT\n")
6493    file.Write("  }\n")
6494    file.Write("\n")
6495
6496  def WriteCmdSetHeader(self, file):
6497    """Writes the cmd's SetHeader function."""
6498    file.Write("  void SetHeader() {\n")
6499    file.Write("    header.SetCmd<ValueType>();\n")
6500    file.Write("  }\n")
6501    file.Write("\n")
6502
6503  def WriteCmdInit(self, file):
6504    """Writes the cmd's Init function."""
6505    file.Write("  void Init(%s) {\n" % self.MakeTypedCmdArgString("_"))
6506    file.Write("    SetHeader();\n")
6507    args = self.GetCmdArgs()
6508    for arg in args:
6509      file.Write("    %s = _%s;\n" % (arg.name, arg.name))
6510    file.Write("  }\n")
6511    file.Write("\n")
6512
6513  def WriteCmdSet(self, file):
6514    """Writes the cmd's Set function."""
6515    copy_args = self.MakeCmdArgString("_", False)
6516    file.Write("  void* Set(void* cmd%s) {\n" %
6517               self.MakeTypedCmdArgString("_", True))
6518    file.Write("    static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args)
6519    file.Write("    return NextCmdAddress<ValueType>(cmd);\n")
6520    file.Write("  }\n")
6521    file.Write("\n")
6522
6523  def WriteStruct(self, file):
6524    self.type_handler.WriteStruct(self, file)
6525
6526  def WriteDocs(self, file):
6527    self.type_handler.WriteDocs(self, file)
6528
6529  def WriteCmdHelper(self, file):
6530    """Writes the cmd's helper."""
6531    self.type_handler.WriteCmdHelper(self, file)
6532
6533  def WriteServiceImplementation(self, file):
6534    """Writes the service implementation for a command."""
6535    self.type_handler.WriteServiceImplementation(self, file)
6536
6537  def WriteServiceUnitTest(self, file):
6538    """Writes the service implementation for a command."""
6539    self.type_handler.WriteServiceUnitTest(self, file)
6540
6541  def WriteGLES2CLibImplementation(self, file):
6542    """Writes the GLES2 C Lib Implemention."""
6543    self.type_handler.WriteGLES2CLibImplementation(self, file)
6544
6545  def WriteGLES2InterfaceHeader(self, file):
6546    """Writes the GLES2 Interface declaration."""
6547    self.type_handler.WriteGLES2InterfaceHeader(self, file)
6548
6549  def WriteGLES2InterfaceStub(self, file):
6550    """Writes the GLES2 Interface Stub declaration."""
6551    self.type_handler.WriteGLES2InterfaceStub(self, file)
6552
6553  def WriteGLES2InterfaceStubImpl(self, file):
6554    """Writes the GLES2 Interface Stub declaration."""
6555    self.type_handler.WriteGLES2InterfaceStubImpl(self, file)
6556
6557  def WriteGLES2ImplementationHeader(self, file):
6558    """Writes the GLES2 Implemention declaration."""
6559    self.type_handler.WriteGLES2ImplementationHeader(self, file)
6560
6561  def WriteGLES2Implementation(self, file):
6562    """Writes the GLES2 Implemention definition."""
6563    self.type_handler.WriteGLES2Implementation(self, file)
6564
6565  def WriteGLES2TraceImplementationHeader(self, file):
6566    """Writes the GLES2 Trace Implemention declaration."""
6567    self.type_handler.WriteGLES2TraceImplementationHeader(self, file)
6568
6569  def WriteGLES2TraceImplementation(self, file):
6570    """Writes the GLES2 Trace Implemention definition."""
6571    self.type_handler.WriteGLES2TraceImplementation(self, file)
6572
6573  def WriteGLES2Header(self, file):
6574    """Writes the GLES2 Implemention unit test."""
6575    self.type_handler.WriteGLES2Header(self, file)
6576
6577  def WriteGLES2ImplementationUnitTest(self, file):
6578    """Writes the GLES2 Implemention unit test."""
6579    self.type_handler.WriteGLES2ImplementationUnitTest(self, file)
6580
6581  def WriteDestinationInitalizationValidation(self, file):
6582    """Writes the client side destintion initialization validation."""
6583    self.type_handler.WriteDestinationInitalizationValidation(self, file)
6584
6585  def WriteFormatTest(self, file):
6586    """Writes the cmd's format test."""
6587    self.type_handler.WriteFormatTest(self, file)
6588
6589
6590class PepperInterface(object):
6591  """A class that represents a function."""
6592
6593  def __init__(self, info):
6594    self.name = info["name"]
6595    self.dev = info["dev"]
6596
6597  def GetName(self):
6598    return self.name
6599
6600  def GetInterfaceName(self):
6601    upperint = ""
6602    dev = ""
6603    if self.name:
6604      upperint = "_" + self.name.upper()
6605    if self.dev:
6606      dev = "_DEV"
6607    return "PPB_OPENGLES2%s%s_INTERFACE" % (upperint, dev)
6608
6609  def GetInterfaceString(self):
6610    dev = ""
6611    if self.dev:
6612      dev = "(Dev)"
6613    return "PPB_OpenGLES2%s%s" % (self.name, dev)
6614
6615  def GetStructName(self):
6616    dev = ""
6617    if self.dev:
6618      dev = "_Dev"
6619    return "PPB_OpenGLES2%s%s" % (self.name, dev)
6620
6621
6622class ImmediateFunction(Function):
6623  """A class that represnets an immediate function command."""
6624
6625  def __init__(self, func):
6626    new_args = []
6627    for arg in func.GetOriginalArgs():
6628      new_arg = arg.GetImmediateVersion()
6629      if new_arg:
6630        new_args.append(new_arg)
6631
6632    cmd_args = []
6633    new_args_for_cmds = []
6634    for arg in func.args_for_cmds:
6635      new_arg = arg.GetImmediateVersion()
6636      if new_arg:
6637        new_args_for_cmds.append(new_arg)
6638        new_arg.AddCmdArgs(cmd_args)
6639
6640    new_init_args = []
6641    for arg in new_args_for_cmds:
6642      arg.AddInitArgs(new_init_args)
6643
6644    Function.__init__(
6645        self,
6646        func.original_name,
6647        "%sImmediate" % func.name,
6648        func.info,
6649        func.return_type,
6650        new_args,
6651        new_args_for_cmds,
6652        cmd_args,
6653        new_init_args,
6654        0)
6655    self.is_immediate = True
6656
6657  def WriteCommandDescription(self, file):
6658    """Overridden from Function"""
6659    file.Write("//! Immediate version of command that corresponds to gl%s.\n" %
6660        self.original_name)
6661
6662  def WriteServiceImplementation(self, file):
6663    """Overridden from Function"""
6664    self.type_handler.WriteImmediateServiceImplementation(self, file)
6665
6666  def WriteHandlerImplementation(self, file):
6667    """Overridden from Function"""
6668    self.type_handler.WriteImmediateHandlerImplementation(self, file)
6669
6670  def WriteServiceUnitTest(self, file):
6671    """Writes the service implementation for a command."""
6672    self.type_handler.WriteImmediateServiceUnitTest(self, file)
6673
6674  def WriteValidationCode(self, file):
6675    """Overridden from Function"""
6676    self.type_handler.WriteImmediateValidationCode(self, file)
6677
6678  def WriteCmdArgFlag(self, file):
6679    """Overridden from Function"""
6680    file.Write("  static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;\n")
6681
6682  def WriteCmdComputeSize(self, file):
6683    """Overridden from Function"""
6684    self.type_handler.WriteImmediateCmdComputeSize(self, file)
6685
6686  def WriteCmdSetHeader(self, file):
6687    """Overridden from Function"""
6688    self.type_handler.WriteImmediateCmdSetHeader(self, file)
6689
6690  def WriteCmdInit(self, file):
6691    """Overridden from Function"""
6692    self.type_handler.WriteImmediateCmdInit(self, file)
6693
6694  def WriteCmdSet(self, file):
6695    """Overridden from Function"""
6696    self.type_handler.WriteImmediateCmdSet(self, file)
6697
6698  def WriteCmdHelper(self, file):
6699    """Overridden from Function"""
6700    self.type_handler.WriteImmediateCmdHelper(self, file)
6701
6702  def WriteFormatTest(self, file):
6703    """Overridden from Function"""
6704    self.type_handler.WriteImmediateFormatTest(self, file)
6705
6706
6707class BucketFunction(Function):
6708  """A class that represnets a bucket version of a function command."""
6709
6710  def __init__(self, func):
6711    new_args = []
6712    for arg in func.GetOriginalArgs():
6713      new_arg = arg.GetBucketVersion()
6714      if new_arg:
6715        new_args.append(new_arg)
6716
6717    cmd_args = []
6718    new_args_for_cmds = []
6719    for arg in func.args_for_cmds:
6720      new_arg = arg.GetBucketVersion()
6721      if new_arg:
6722        new_args_for_cmds.append(new_arg)
6723        new_arg.AddCmdArgs(cmd_args)
6724
6725    new_init_args = []
6726    for arg in new_args_for_cmds:
6727      arg.AddInitArgs(new_init_args)
6728
6729    Function.__init__(
6730        self,
6731        func.original_name,
6732        "%sBucket" % func.name,
6733        func.info,
6734        func.return_type,
6735        new_args,
6736        new_args_for_cmds,
6737        cmd_args,
6738        new_init_args,
6739        0)
6740
6741#  def InitFunction(self):
6742#    """Overridden from Function"""
6743#    pass
6744
6745  def WriteCommandDescription(self, file):
6746    """Overridden from Function"""
6747    file.Write("//! Bucket version of command that corresponds to gl%s.\n" %
6748        self.original_name)
6749
6750  def WriteServiceImplementation(self, file):
6751    """Overridden from Function"""
6752    self.type_handler.WriteBucketServiceImplementation(self, file)
6753
6754  def WriteHandlerImplementation(self, file):
6755    """Overridden from Function"""
6756    self.type_handler.WriteBucketHandlerImplementation(self, file)
6757
6758  def WriteServiceUnitTest(self, file):
6759    """Writes the service implementation for a command."""
6760    self.type_handler.WriteBucketServiceUnitTest(self, file)
6761
6762
6763def CreateArg(arg_string):
6764  """Creates an Argument."""
6765  arg_parts = arg_string.split()
6766  if len(arg_parts) == 1 and arg_parts[0] == 'void':
6767    return None
6768  # Is this a pointer argument?
6769  elif arg_string.find('*') >= 0:
6770    if arg_parts[0] == 'NonImmediate':
6771      return NonImmediatePointerArgument(
6772          arg_parts[-1],
6773          " ".join(arg_parts[1:-1]))
6774    else:
6775      return PointerArgument(
6776          arg_parts[-1],
6777          " ".join(arg_parts[0:-1]))
6778  # Is this a resource argument? Must come after pointer check.
6779  elif arg_parts[0].startswith('GLidBind'):
6780    return ResourceIdBindArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6781  elif arg_parts[0].startswith('GLidZero'):
6782    return ResourceIdZeroArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6783  elif arg_parts[0].startswith('GLid'):
6784    return ResourceIdArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6785  elif arg_parts[0].startswith('GLenum') and len(arg_parts[0]) > 6:
6786    return EnumArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6787  elif arg_parts[0].startswith('GLboolean') and len(arg_parts[0]) > 9:
6788    return ValidatedBoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6789  elif arg_parts[0].startswith('GLboolean'):
6790    return BoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6791  elif arg_parts[0].startswith('GLintUniformLocation'):
6792    return UniformLocationArgument(arg_parts[-1])
6793  elif (arg_parts[0].startswith('GLint') and len(arg_parts[0]) > 5 and
6794        not arg_parts[0].startswith('GLintptr')):
6795    return IntArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6796  elif (arg_parts[0].startswith('GLsizeiNotNegative') or
6797        arg_parts[0].startswith('GLintptrNotNegative')):
6798    return SizeNotNegativeArgument(arg_parts[-1],
6799                                   " ".join(arg_parts[0:-1]),
6800                                   arg_parts[0][0:-11])
6801  elif arg_parts[0].startswith('GLsize'):
6802    return SizeArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6803  else:
6804    return Argument(arg_parts[-1], " ".join(arg_parts[0:-1]))
6805
6806
6807class GLGenerator(object):
6808  """A class to generate GL command buffers."""
6809
6810  _function_re = re.compile(r'GL_APICALL(.*?)GL_APIENTRY (.*?) \((.*?)\);')
6811
6812  def __init__(self, verbose):
6813    self.original_functions = []
6814    self.functions = []
6815    self.verbose = verbose
6816    self.errors = 0
6817    self._function_info = {}
6818    self._empty_type_handler = TypeHandler()
6819    self._empty_function_info = FunctionInfo({}, self._empty_type_handler)
6820    self.pepper_interfaces = []
6821    self.interface_info = {}
6822
6823    self._type_handlers = {
6824      'Bind': BindHandler(),
6825      'Create': CreateHandler(),
6826      'Custom': CustomHandler(),
6827      'Data': DataHandler(),
6828      'Delete': DeleteHandler(),
6829      'DELn': DELnHandler(),
6830      'GENn': GENnHandler(),
6831      'GETn': GETnHandler(),
6832      'GLchar': GLcharHandler(),
6833      'GLcharN': GLcharNHandler(),
6834      'HandWritten': HandWrittenHandler(),
6835      'Is': IsHandler(),
6836      'Manual': ManualHandler(),
6837      'PUT': PUTHandler(),
6838      'PUTn': PUTnHandler(),
6839      'PUTXn': PUTXnHandler(),
6840      'StateSet': StateSetHandler(),
6841      'StateSetRGBAlpha': StateSetRGBAlphaHandler(),
6842      'StateSetFrontBack': StateSetFrontBackHandler(),
6843      'StateSetFrontBackSeparate': StateSetFrontBackSeparateHandler(),
6844      'StateSetNamedParameter': StateSetNamedParameter(),
6845      'STRn': STRnHandler(),
6846      'Todo': TodoHandler(),
6847    }
6848
6849    for func_name in _FUNCTION_INFO:
6850      info = _FUNCTION_INFO[func_name]
6851      type = ''
6852      if 'type' in info:
6853        type = info['type']
6854      self._function_info[func_name] = FunctionInfo(info,
6855                                                    self.GetTypeHandler(type))
6856    for interface in _PEPPER_INTERFACES:
6857      interface = PepperInterface(interface)
6858      self.pepper_interfaces.append(interface)
6859      self.interface_info[interface.GetName()] = interface
6860
6861  def AddFunction(self, func):
6862    """Adds a function."""
6863    self.functions.append(func)
6864
6865  def GetTypeHandler(self, name):
6866    """Gets a type info for the given type."""
6867    if len(name):
6868      if name in self._type_handlers:
6869        return self._type_handlers[name]
6870      else:
6871        raise KeyError("no such type handler: %s" % name)
6872    return self._empty_type_handler
6873
6874  def GetFunctionInfo(self, name):
6875    """Gets a type info for the given function name."""
6876    if name in self._function_info:
6877      return self._function_info[name]
6878    return self._empty_function_info
6879
6880  def Log(self, msg):
6881    """Prints something if verbose is true."""
6882    if self.verbose:
6883      print msg
6884
6885  def Error(self, msg):
6886    """Prints an error."""
6887    print "Error: %s" % msg
6888    self.errors += 1
6889
6890  def WriteLicense(self, file):
6891    """Writes the license."""
6892    file.Write(_LICENSE)
6893
6894  def WriteNamespaceOpen(self, file):
6895    """Writes the code for the namespace."""
6896    file.Write("namespace gpu {\n")
6897    file.Write("namespace gles2 {\n")
6898    file.Write("\n")
6899
6900  def WriteNamespaceClose(self, file):
6901    """Writes the code to close the namespace."""
6902    file.Write("}  // namespace gles2\n")
6903    file.Write("}  // namespace gpu\n")
6904    file.Write("\n")
6905
6906  def ParseArgs(self, arg_string):
6907    """Parses a function arg string."""
6908    args = []
6909    num_pointer_args = 0
6910    parts = arg_string.split(',')
6911    is_gl_enum = False
6912    for arg_string in parts:
6913      if arg_string.startswith('GLenum '):
6914        is_gl_enum = True
6915      arg = CreateArg(arg_string)
6916      if arg:
6917        args.append(arg)
6918        if arg.IsPointer():
6919          num_pointer_args += 1
6920    return (args, num_pointer_args, is_gl_enum)
6921
6922  def ParseGLH(self, filename):
6923    """Parses the cmd_buffer_functions.txt file and extracts the functions"""
6924    f = open("gpu/command_buffer/cmd_buffer_functions.txt", "r")
6925    functions = f.read()
6926    f.close()
6927    for line in functions.splitlines():
6928      match = self._function_re.match(line)
6929      if match:
6930        func_name = match.group(2)[2:]
6931        func_info = self.GetFunctionInfo(func_name)
6932        if func_info.type != 'Noop':
6933          return_type = match.group(1).strip()
6934          arg_string = match.group(3)
6935          (args, num_pointer_args, is_gl_enum) = self.ParseArgs(arg_string)
6936          # comment in to find out which functions use bare enums.
6937          # if is_gl_enum:
6938          #   self.Log("%s uses bare GLenum" % func_name)
6939          args_for_cmds = args
6940          if hasattr(func_info, 'cmd_args'):
6941            (args_for_cmds, num_pointer_args, is_gl_enum) = (
6942                self.ParseArgs(getattr(func_info, 'cmd_args')))
6943          cmd_args = []
6944          for arg in args_for_cmds:
6945            arg.AddCmdArgs(cmd_args)
6946          init_args = []
6947          for arg in args_for_cmds:
6948            arg.AddInitArgs(init_args)
6949          return_arg = CreateArg(return_type + " result")
6950          if return_arg:
6951            init_args.append(return_arg)
6952          f = Function(func_name, func_name, func_info, return_type, args,
6953                       args_for_cmds, cmd_args, init_args, num_pointer_args)
6954          self.original_functions.append(f)
6955          gen_cmd = f.GetInfo('gen_cmd')
6956          if gen_cmd == True or gen_cmd == None:
6957            self.AddFunction(f)
6958            f.type_handler.AddImmediateFunction(self, f)
6959            f.type_handler.AddBucketFunction(self, f)
6960
6961    self.Log("Auto Generated Functions    : %d" %
6962             len([f for f in self.functions if f.can_auto_generate or
6963                  (not f.IsType('') and not f.IsType('Custom') and
6964                   not f.IsType('Todo'))]))
6965
6966    funcs = [f for f in self.functions if not f.can_auto_generate and
6967             (f.IsType('') or f.IsType('Custom') or f.IsType('Todo'))]
6968    self.Log("Non Auto Generated Functions: %d" % len(funcs))
6969
6970    for f in funcs:
6971      self.Log("  %-10s %-20s gl%s" % (f.info.type, f.return_type, f.name))
6972
6973  def WriteCommandIds(self, filename):
6974    """Writes the command buffer format"""
6975    file = CHeaderWriter(filename)
6976    file.Write("#define GLES2_COMMAND_LIST(OP) \\\n")
6977    id = 256
6978    for func in self.functions:
6979      file.Write("  %-60s /* %d */ \\\n" %
6980                 ("OP(%s)" % func.name, id))
6981      id += 1
6982    file.Write("\n")
6983
6984    file.Write("enum CommandId {\n")
6985    file.Write("  kStartPoint = cmd::kLastCommonId,  "
6986               "// All GLES2 commands start after this.\n")
6987    file.Write("#define GLES2_CMD_OP(name) k ## name,\n")
6988    file.Write("  GLES2_COMMAND_LIST(GLES2_CMD_OP)\n")
6989    file.Write("#undef GLES2_CMD_OP\n")
6990    file.Write("  kNumCommands\n")
6991    file.Write("};\n")
6992    file.Write("\n")
6993    file.Close()
6994
6995  def WriteFormat(self, filename):
6996    """Writes the command buffer format"""
6997    file = CHeaderWriter(filename)
6998    for func in self.functions:
6999      if True:
7000      #gen_cmd = func.GetInfo('gen_cmd')
7001      #if gen_cmd == True or gen_cmd == None:
7002        func.WriteStruct(file)
7003    file.Write("\n")
7004    file.Close()
7005
7006  def WriteDocs(self, filename):
7007    """Writes the command buffer doc version of the commands"""
7008    file = CWriter(filename)
7009    for func in self.functions:
7010      if True:
7011      #gen_cmd = func.GetInfo('gen_cmd')
7012      #if gen_cmd == True or gen_cmd == None:
7013        func.WriteDocs(file)
7014    file.Write("\n")
7015    file.Close()
7016
7017  def WriteFormatTest(self, filename):
7018    """Writes the command buffer format test."""
7019    file = CHeaderWriter(
7020      filename,
7021      "// This file contains unit tests for gles2 commmands\n"
7022      "// It is included by gles2_cmd_format_test.cc\n"
7023      "\n")
7024
7025    for func in self.functions:
7026      if True:
7027      #gen_cmd = func.GetInfo('gen_cmd')
7028      #if gen_cmd == True or gen_cmd == None:
7029        func.WriteFormatTest(file)
7030
7031    file.Close()
7032
7033  def WriteCmdHelperHeader(self, filename):
7034    """Writes the gles2 command helper."""
7035    file = CHeaderWriter(filename)
7036
7037    for func in self.functions:
7038      if True:
7039      #gen_cmd = func.GetInfo('gen_cmd')
7040      #if gen_cmd == True or gen_cmd == None:
7041        func.WriteCmdHelper(file)
7042
7043    file.Close()
7044
7045  def WriteServiceContextStateHeader(self, filename):
7046    """Writes the service context state header."""
7047    file = CHeaderWriter(
7048        filename,
7049        "// It is included by context_state.h\n")
7050    file.Write("struct EnableFlags {\n")
7051    file.Write("  EnableFlags();\n")
7052    for capability in _CAPABILITY_FLAGS:
7053      file.Write("  bool %s;\n" % capability['name'])
7054    file.Write("};\n\n")
7055
7056    for state_name in sorted(_STATES.keys()):
7057      state = _STATES[state_name]
7058      for item in state['states']:
7059        file.Write("%s %s;\n" % (item['type'], item['name']))
7060    file.Write("\n")
7061
7062    file.Close()
7063
7064  def WriteClientContextStateHeader(self, filename):
7065    """Writes the client context state header."""
7066    file = CHeaderWriter(
7067        filename,
7068        "// It is included by client_context_state.h\n")
7069    file.Write("struct EnableFlags {\n")
7070    file.Write("  EnableFlags();\n")
7071    for capability in _CAPABILITY_FLAGS:
7072      file.Write("  bool %s;\n" % capability['name'])
7073    file.Write("};\n\n")
7074
7075    file.Close()
7076
7077  def WriteContextStateGetters(self, file, class_name):
7078    """Writes the state getters."""
7079    for gl_type in ["GLint", "GLfloat"]:
7080      file.Write("""
7081bool %s::GetStateAs%s(
7082    GLenum pname, %s* params, GLsizei* num_written) const {
7083  switch (pname) {
7084""" % (class_name, gl_type, gl_type))
7085      for state_name in sorted(_STATES.keys()):
7086        state = _STATES[state_name]
7087        if 'enum' in state:
7088          file.Write("    case %s:\n" % state['enum'])
7089          file.Write("      *num_written = %d;\n" % len(state['states']))
7090          file.Write("      if (params) {\n")
7091          for ndx,item in enumerate(state['states']):
7092            file.Write("        params[%d] = static_cast<%s>(%s);\n" %
7093                       (ndx, gl_type, item['name']))
7094          file.Write("      }\n")
7095          file.Write("      return true;\n")
7096        else:
7097          for item in state['states']:
7098            file.Write("    case %s:\n" % item['enum'])
7099            file.Write("      *num_written = 1;\n")
7100            file.Write("      if (params) {\n")
7101            file.Write("        params[0] = static_cast<%s>(%s);\n" %
7102                       (gl_type, item['name']))
7103            file.Write("      }\n")
7104            file.Write("      return true;\n")
7105      for capability in _CAPABILITY_FLAGS:
7106            file.Write("    case GL_%s:\n" % capability['name'].upper())
7107            file.Write("      *num_written = 1;\n")
7108            file.Write("      if (params) {\n")
7109            file.Write(
7110                "        params[0] = static_cast<%s>(enable_flags.%s);\n" %
7111                (gl_type, capability['name']))
7112            file.Write("      }\n")
7113            file.Write("      return true;\n")
7114      file.Write("""    default:
7115      return false;
7116  }
7117}
7118""")
7119
7120  def WriteServiceContextStateImpl(self, filename):
7121    """Writes the context state service implementation."""
7122    file = CHeaderWriter(
7123        filename,
7124        "// It is included by context_state.cc\n")
7125    code = []
7126    for capability in _CAPABILITY_FLAGS:
7127      code.append("%s(%s)" %
7128                  (capability['name'],
7129                   ('false', 'true')['default' in capability]))
7130    file.Write("ContextState::EnableFlags::EnableFlags()\n    : %s {\n}\n" %
7131               ",\n      ".join(code))
7132    file.Write("\n")
7133
7134    file.Write("void ContextState::Initialize() {\n")
7135    for state_name in sorted(_STATES.keys()):
7136      state = _STATES[state_name]
7137      for item in state['states']:
7138        file.Write("  %s = %s;\n" % (item['name'], item['default']))
7139    file.Write("}\n")
7140
7141    file.Write("""
7142void ContextState::InitCapabilities() const {
7143""")
7144    for capability in _CAPABILITY_FLAGS:
7145      file.Write("  EnableDisable(GL_%s, enable_flags.%s);\n" %
7146                 (capability['name'].upper(), capability['name']))
7147    file.Write("""}
7148
7149void ContextState::InitState() const {
7150""")
7151
7152    # We need to sort the keys so the expectations match
7153    for state_name in sorted(_STATES.keys()):
7154      state = _STATES[state_name]
7155      if state['type'] == 'FrontBack':
7156        num_states = len(state['states'])
7157        for ndx, group in enumerate(Grouper(num_states / 2, state['states'])):
7158          args = []
7159          for item in group:
7160            args.append('%s' % item['name'])
7161          file.Write(
7162              "  gl%s(%s, %s);\n" %
7163              (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args)))
7164      elif state['type'] == 'NamedParameter':
7165        for item in state['states']:
7166          if 'extension_flag' in item:
7167            file.Write("  if (feature_info_->feature_flags().%s)\n  " %
7168                       item['extension_flag'])
7169          file.Write("  gl%s(%s, %s);\n" %
7170                     (state['func'], item['enum'], item['name']))
7171      else:
7172        args = []
7173        for item in state['states']:
7174          args.append('%s' % item['name'])
7175        file.Write("  gl%s(%s);\n" % (state['func'], ", ".join(args)))
7176    file.Write("}\n")
7177
7178    file.Write("""bool ContextState::GetEnabled(GLenum cap) const {
7179  switch (cap) {
7180""")
7181    for capability in _CAPABILITY_FLAGS:
7182      file.Write("    case GL_%s:\n" % capability['name'].upper())
7183      file.Write("      return enable_flags.%s;\n" % capability['name'])
7184    file.Write("""    default:
7185      NOTREACHED();
7186      return false;
7187  }
7188}
7189""")
7190
7191    self.WriteContextStateGetters(file, "ContextState")
7192    file.Close()
7193
7194  def WriteClientContextStateImpl(self, filename):
7195    """Writes the context state client side implementation."""
7196    file = CHeaderWriter(
7197        filename,
7198        "// It is included by client_context_state.cc\n")
7199    code = []
7200    for capability in _CAPABILITY_FLAGS:
7201      code.append("%s(%s)" %
7202                  (capability['name'],
7203                   ('false', 'true')['default' in capability]))
7204    file.Write(
7205      "ClientContextState::EnableFlags::EnableFlags()\n    : %s {\n}\n" %
7206      ",\n      ".join(code))
7207    file.Write("\n")
7208
7209    file.Write("""
7210bool ClientContextState::SetCapabilityState(
7211    GLenum cap, bool enabled, bool* changed) {
7212  *changed = false;
7213  switch (cap) {
7214""")
7215    for capability in _CAPABILITY_FLAGS:
7216      file.Write("    case GL_%s:\n" % capability['name'].upper())
7217      file.Write("""      if (enable_flags.%(name)s != enabled) {
7218         *changed = true;
7219         enable_flags.%(name)s = enabled;
7220      }
7221      return true;
7222""" % capability)
7223    file.Write("""    default:
7224      return false;
7225  }
7226}
7227""")
7228    file.Write("""bool ClientContextState::GetEnabled(
7229    GLenum cap, bool* enabled) const {
7230  switch (cap) {
7231""")
7232    for capability in _CAPABILITY_FLAGS:
7233      file.Write("    case GL_%s:\n" % capability['name'].upper())
7234      file.Write("      *enabled = enable_flags.%s;\n" % capability['name'])
7235      file.Write("      return true;\n")
7236    file.Write("""    default:
7237      return false;
7238  }
7239}
7240""")
7241    file.Close()
7242
7243  def WriteServiceImplementation(self, filename):
7244    """Writes the service decorder implementation."""
7245    file = CHeaderWriter(
7246        filename,
7247        "// It is included by gles2_cmd_decoder.cc\n")
7248
7249    for func in self.functions:
7250      if True:
7251      #gen_cmd = func.GetInfo('gen_cmd')
7252      #if gen_cmd == True or gen_cmd == None:
7253        func.WriteServiceImplementation(file)
7254
7255    file.Write("""
7256bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
7257  switch (cap) {
7258""")
7259    for capability in _CAPABILITY_FLAGS:
7260      file.Write("    case GL_%s:\n" % capability['name'].upper())
7261      if 'state_flag' in capability:
7262        file.Write("""      if (state_.enable_flags.%(name)s != enabled) {
7263        state_.enable_flags.%(name)s = enabled;
7264        %(state_flag)s = true;
7265      }
7266      return false;
7267""" % capability)
7268      else:
7269        file.Write("""      state_.enable_flags.%(name)s = enabled;
7270      return true;
7271""" % capability)
7272    file.Write("""    default:
7273      NOTREACHED();
7274      return false;
7275  }
7276}
7277""")
7278    file.Close()
7279
7280  def WriteServiceUnitTests(self, filename):
7281    """Writes the service decorder unit tests."""
7282    num_tests = len(self.functions)
7283    FUNCTIONS_PER_FILE = 98  # hard code this so it doesn't change.
7284    count = 0
7285    for test_num in range(0, num_tests, FUNCTIONS_PER_FILE):
7286      count += 1
7287      name = filename % count
7288      file = CHeaderWriter(
7289          name,
7290          "// It is included by gles2_cmd_decoder_unittest_%d.cc\n" % count)
7291      file.SetFileNum(count)
7292      end = test_num + FUNCTIONS_PER_FILE
7293      if end > num_tests:
7294        end = num_tests
7295      for idx in range(test_num, end):
7296        func = self.functions[idx]
7297        if True:
7298        #gen_cmd = func.GetInfo('gen_cmd')
7299        #if gen_cmd == True or gen_cmd == None:
7300          if func.GetInfo('unit_test') == False:
7301            file.Write("// TODO(gman): %s\n" % func.name)
7302          else:
7303            func.WriteServiceUnitTest(file)
7304
7305      file.Close()
7306    file = CHeaderWriter(
7307        filename % 0,
7308        "// It is included by gles2_cmd_decoder_unittest_base.cc\n")
7309    file.Write(
7310"""void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations() {
7311""")
7312    for capability in _CAPABILITY_FLAGS:
7313      file.Write("  ExpectEnableDisable(GL_%s, %s);\n" %
7314                 (capability['name'].upper(),
7315                  ('false', 'true')['default' in capability]))
7316    file.Write("""}
7317
7318void GLES2DecoderTestBase::SetupInitStateExpectations() {
7319""")
7320
7321    # We need to sort the keys so the expectations match
7322    for state_name in sorted(_STATES.keys()):
7323      state = _STATES[state_name]
7324      if state['type'] == 'FrontBack':
7325        num_states = len(state['states'])
7326        for ndx, group in enumerate(Grouper(num_states / 2, state['states'])):
7327          args = []
7328          for item in group:
7329            if 'expected' in item:
7330              args.append(item['expected'])
7331            else:
7332              args.append(item['default'])
7333          file.Write(
7334              "  EXPECT_CALL(*gl_, %s(%s, %s))\n" %
7335              (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args)))
7336          file.Write("      .Times(1)\n")
7337          file.Write("      .RetiresOnSaturation();\n")
7338      elif state['type'] == 'NamedParameter':
7339        for item in state['states']:
7340          if 'extension_flag' in item:
7341            continue
7342          file.Write(
7343              "  EXPECT_CALL(*gl_, %s(%s, %s))\n" %
7344              (state['func'], item['enum'], item['default']))
7345          file.Write("      .Times(1)\n")
7346          file.Write("      .RetiresOnSaturation();\n")
7347      else:
7348        args = []
7349        for item in state['states']:
7350          if 'expected' in item:
7351            args.append(item['expected'])
7352          else:
7353            args.append(item['default'])
7354        file.Write("  EXPECT_CALL(*gl_, %s(%s))\n" %
7355                   (state['func'], ", ".join(args)))
7356        file.Write("      .Times(1)\n")
7357        file.Write("      .RetiresOnSaturation();\n")
7358    file.Write("""}
7359""")
7360    file.Close()
7361
7362  def WriteGLES2Header(self, filename):
7363    """Writes the GLES2 header."""
7364    file = CHeaderWriter(
7365        filename,
7366        "// This file contains Chromium-specific GLES2 declarations.\n\n")
7367
7368    for func in self.original_functions:
7369      func.WriteGLES2Header(file)
7370
7371    file.Write("\n")
7372    file.Close()
7373
7374  def WriteGLES2CLibImplementation(self, filename):
7375    """Writes the GLES2 c lib implementation."""
7376    file = CHeaderWriter(
7377        filename,
7378        "// These functions emulate GLES2 over command buffers.\n")
7379
7380    for func in self.original_functions:
7381      func.WriteGLES2CLibImplementation(file)
7382
7383    file.Write("""
7384namespace gles2 {
7385
7386extern const NameToFunc g_gles2_function_table[] = {
7387""")
7388    for func in self.original_functions:
7389      file.Write(
7390          '  { "gl%s", reinterpret_cast<GLES2FunctionPointer>(gl%s), },\n' %
7391          (func.name, func.name))
7392    file.Write("""  { NULL, NULL, },
7393};
7394
7395}  // namespace gles2
7396""")
7397    file.Close()
7398
7399  def WriteGLES2InterfaceHeader(self, filename):
7400    """Writes the GLES2 interface header."""
7401    file = CHeaderWriter(
7402        filename,
7403        "// This file is included by gles2_interface.h to declare the\n"
7404        "// GL api functions.\n")
7405    for func in self.original_functions:
7406      func.WriteGLES2InterfaceHeader(file)
7407    file.Close()
7408
7409  def WriteGLES2InterfaceStub(self, filename):
7410    """Writes the GLES2 interface stub header."""
7411    file = CHeaderWriter(
7412        filename,
7413        "// This file is included by gles2_interface_stub.h.\n")
7414    for func in self.original_functions:
7415      func.WriteGLES2InterfaceStub(file)
7416    file.Close()
7417
7418  def WriteGLES2InterfaceStubImpl(self, filename):
7419    """Writes the GLES2 interface header."""
7420    file = CHeaderWriter(
7421        filename,
7422        "// This file is included by gles2_interface_stub.cc.\n")
7423    for func in self.original_functions:
7424      func.WriteGLES2InterfaceStubImpl(file)
7425    file.Close()
7426
7427  def WriteGLES2ImplementationHeader(self, filename):
7428    """Writes the GLES2 Implementation header."""
7429    file = CHeaderWriter(
7430        filename,
7431        "// This file is included by gles2_implementation.h to declare the\n"
7432        "// GL api functions.\n")
7433    for func in self.original_functions:
7434      func.WriteGLES2ImplementationHeader(file)
7435    file.Close()
7436
7437  def WriteGLES2Implementation(self, filename):
7438    """Writes the GLES2 Implementation."""
7439    file = CHeaderWriter(
7440        filename,
7441        "// This file is included by gles2_implementation.cc to define the\n"
7442        "// GL api functions.\n")
7443    for func in self.original_functions:
7444      func.WriteGLES2Implementation(file)
7445    file.Close()
7446
7447  def WriteGLES2TraceImplementationHeader(self, filename):
7448    """Writes the GLES2 Trace Implementation header."""
7449    file = CHeaderWriter(
7450        filename,
7451        "// This file is included by gles2_trace_implementation.h\n")
7452    for func in self.original_functions:
7453      func.WriteGLES2TraceImplementationHeader(file)
7454    file.Close()
7455
7456  def WriteGLES2TraceImplementation(self, filename):
7457    """Writes the GLES2 Trace Implementation."""
7458    file = CHeaderWriter(
7459        filename,
7460        "// This file is included by gles2_trace_implementation.cc\n")
7461    for func in self.original_functions:
7462      func.WriteGLES2TraceImplementation(file)
7463    file.Close()
7464
7465  def WriteGLES2ImplementationUnitTests(self, filename):
7466    """Writes the GLES2 helper header."""
7467    file = CHeaderWriter(
7468        filename,
7469        "// This file is included by gles2_implementation.h to declare the\n"
7470        "// GL api functions.\n")
7471    for func in self.original_functions:
7472      func.WriteGLES2ImplementationUnitTest(file)
7473    file.Close()
7474
7475  def WriteServiceUtilsHeader(self, filename):
7476    """Writes the gles2 auto generated utility header."""
7477    file = CHeaderWriter(filename)
7478    for enum in sorted(_ENUM_LISTS.keys()):
7479      file.Write("ValueValidator<%s> %s;\n" %
7480                 (_ENUM_LISTS[enum]['type'], ToUnderscore(enum)))
7481    file.Write("\n")
7482    file.Close()
7483
7484  def WriteServiceUtilsImplementation(self, filename):
7485    """Writes the gles2 auto generated utility implementation."""
7486    file = CHeaderWriter(filename)
7487    enums = sorted(_ENUM_LISTS.keys())
7488    for enum in enums:
7489      if len(_ENUM_LISTS[enum]['valid']) > 0:
7490        file.Write("static const %s valid_%s_table[] = {\n" %
7491                   (_ENUM_LISTS[enum]['type'], ToUnderscore(enum)))
7492        for value in _ENUM_LISTS[enum]['valid']:
7493          file.Write("  %s,\n" % value)
7494        file.Write("};\n")
7495        file.Write("\n")
7496    file.Write("Validators::Validators()\n")
7497    pre = ': '
7498    post = ','
7499    for count, enum in enumerate(enums):
7500      if count + 1 == len(enums):
7501        post = ' {'
7502      if len(_ENUM_LISTS[enum]['valid']) > 0:
7503        code = """    %(pre)s%(name)s(
7504          valid_%(name)s_table, arraysize(valid_%(name)s_table))%(post)s
7505"""
7506      else:
7507        code = """    %(pre)s%(name)s()%(post)s
7508"""
7509      file.Write(code % {
7510          'name': ToUnderscore(enum),
7511          'pre': pre,
7512          'post': post,
7513        })
7514      pre = '  '
7515    file.Write("}\n\n");
7516    file.Close()
7517
7518  def WriteCommonUtilsHeader(self, filename):
7519    """Writes the gles2 common utility header."""
7520    file = CHeaderWriter(filename)
7521    enums = sorted(_ENUM_LISTS.keys())
7522    for enum in enums:
7523      if _ENUM_LISTS[enum]['type'] == 'GLenum':
7524        file.Write("static std::string GetString%s(uint32 value);\n" % enum)
7525    file.Write("\n")
7526    file.Close()
7527
7528  def WriteCommonUtilsImpl(self, filename):
7529    """Writes the gles2 common utility header."""
7530    enum_re = re.compile(r'\#define\s+(GL_[a-zA-Z0-9_]+)\s+([0-9A-Fa-fx]+)')
7531    dict = {}
7532    for fname in ['../../third_party/khronos/GLES2/gl2.h',
7533                  '../../third_party/khronos/GLES2/gl2ext.h',
7534                  '../../gpu/GLES2/gl2chromium.h',
7535                  '../../gpu/GLES2/gl2extchromium.h']:
7536      lines = open(fname).readlines()
7537      for line in lines:
7538        m = enum_re.match(line)
7539        if m:
7540          name = m.group(1)
7541          value = m.group(2)
7542          if len(value) <= 10 and not value in dict:
7543            dict[value] = name
7544
7545    file = CHeaderWriter(filename)
7546    file.Write("static const GLES2Util::EnumToString "
7547               "enum_to_string_table[] = {\n")
7548    for value in dict:
7549      file.Write('  { %s, "%s", },\n' % (value, dict[value]))
7550    file.Write("""};
7551
7552const GLES2Util::EnumToString* const GLES2Util::enum_to_string_table_ =
7553    enum_to_string_table;
7554const size_t GLES2Util::enum_to_string_table_len_ =
7555    sizeof(enum_to_string_table) / sizeof(enum_to_string_table[0]);
7556
7557""")
7558
7559    enums = sorted(_ENUM_LISTS.keys())
7560    for enum in enums:
7561      if _ENUM_LISTS[enum]['type'] == 'GLenum':
7562        file.Write("std::string GLES2Util::GetString%s(uint32 value) {\n" %
7563                   enum)
7564        if len(_ENUM_LISTS[enum]['valid']) > 0:
7565          file.Write("  static const EnumToString string_table[] = {\n")
7566          for value in _ENUM_LISTS[enum]['valid']:
7567            file.Write('    { %s, "%s" },\n' % (value, value))
7568          file.Write("""  };
7569  return GLES2Util::GetQualifiedEnumString(
7570      string_table, arraysize(string_table), value);
7571}
7572
7573""")
7574        else:
7575          file.Write("""  return GLES2Util::GetQualifiedEnumString(
7576      NULL, 0, value);
7577}
7578
7579""")
7580    file.Close()
7581
7582  def WritePepperGLES2Interface(self, filename, dev):
7583    """Writes the Pepper OpenGLES interface definition."""
7584    file = CHeaderWriter(
7585        filename,
7586        "// OpenGL ES interface.\n",
7587        2)
7588
7589    file.Write("#include \"ppapi/c/pp_resource.h\"\n")
7590    if dev:
7591      file.Write("#include \"ppapi/c/ppb_opengles2.h\"\n\n")
7592    else:
7593      file.Write("\n#ifndef __gl2_h_\n")
7594      for (k, v) in _GL_TYPES.iteritems():
7595        file.Write("typedef %s %s;\n" % (v, k))
7596      file.Write("#endif  // __gl2_h_\n\n")
7597
7598    for interface in self.pepper_interfaces:
7599      if interface.dev != dev:
7600        continue
7601      file.Write("#define %s_1_0 \"%s;1.0\"\n" %
7602                 (interface.GetInterfaceName(), interface.GetInterfaceString()))
7603      file.Write("#define %s %s_1_0\n" %
7604                 (interface.GetInterfaceName(), interface.GetInterfaceName()))
7605
7606      file.Write("\nstruct %s {\n" % interface.GetStructName())
7607      for func in self.original_functions:
7608        if not func.InPepperInterface(interface):
7609          continue
7610
7611        original_arg = func.MakeTypedPepperArgString("")
7612        context_arg = "PP_Resource context"
7613        if len(original_arg):
7614          arg = context_arg + ", " + original_arg
7615        else:
7616          arg = context_arg
7617        file.Write("  %s (*%s)(%s);\n" % (func.return_type, func.name, arg))
7618      file.Write("};\n\n")
7619
7620
7621    file.Close()
7622
7623  def WritePepperGLES2Implementation(self, filename):
7624    """Writes the Pepper OpenGLES interface implementation."""
7625
7626    file = CWriter(filename)
7627    file.Write(_LICENSE)
7628    file.Write(_DO_NOT_EDIT_WARNING)
7629
7630    file.Write("#include \"ppapi/shared_impl/ppb_opengles2_shared.h\"\n\n")
7631    file.Write("#include \"base/logging.h\"\n")
7632    file.Write("#include \"gpu/command_buffer/client/gles2_implementation.h\"\n")
7633    file.Write("#include \"ppapi/shared_impl/ppb_graphics_3d_shared.h\"\n")
7634    file.Write("#include \"ppapi/thunk/enter.h\"\n\n")
7635
7636    file.Write("namespace ppapi {\n\n")
7637    file.Write("namespace {\n\n")
7638
7639    file.Write("typedef thunk::EnterResource<thunk::PPB_Graphics3D_API>"
7640               " Enter3D;\n\n")
7641
7642    file.Write("gpu::gles2::GLES2Implementation* ToGles2Impl(Enter3D*"
7643               " enter) {\n")
7644    file.Write("  DCHECK(enter);\n")
7645    file.Write("  DCHECK(enter->succeeded());\n")
7646    file.Write("  return static_cast<PPB_Graphics3D_Shared*>(enter->object())->"
7647               "gles2_impl();\n");
7648    file.Write("}\n\n");
7649
7650    for func in self.original_functions:
7651      if not func.InAnyPepperExtension():
7652        continue
7653
7654      original_arg = func.MakeTypedPepperArgString("")
7655      context_arg = "PP_Resource context_id"
7656      if len(original_arg):
7657        arg = context_arg + ", " + original_arg
7658      else:
7659        arg = context_arg
7660      file.Write("%s %s(%s) {\n" % (func.return_type, func.name, arg))
7661      file.Write("  Enter3D enter(context_id, true);\n")
7662      file.Write("  if (enter.succeeded()) {\n")
7663
7664      return_str = "" if func.return_type == "void" else "return "
7665      file.Write("    %sToGles2Impl(&enter)->%s(%s);\n" %
7666                 (return_str, func.original_name,
7667                  func.MakeOriginalArgString("")))
7668      file.Write("  }")
7669      if func.return_type == "void":
7670        file.Write("\n")
7671      else:
7672        file.Write(" else {\n")
7673        error_return = "0"
7674        if func.GetInfo("error_return"):
7675          error_return = func.GetInfo("error_return")
7676        elif func.return_type == "GLboolean":
7677          error_return = "GL_FALSE"
7678        elif "*" in func.return_type:
7679          error_return = "NULL"
7680        file.Write("    return %s;\n" % error_return)
7681        file.Write("  }\n")
7682      file.Write("}\n\n")
7683
7684    file.Write("}  // namespace\n")
7685
7686    for interface in self.pepper_interfaces:
7687      file.Write("const %s* PPB_OpenGLES2_Shared::Get%sInterface() {\n" %
7688                 (interface.GetStructName(), interface.GetName()))
7689      file.Write("  static const struct %s "
7690                 "ppb_opengles2 = {\n" % interface.GetStructName())
7691      file.Write("    &")
7692      file.Write(",\n    &".join(
7693        f.name for f in self.original_functions
7694          if f.InPepperInterface(interface)))
7695      file.Write("\n")
7696
7697      file.Write("  };\n")
7698      file.Write("  return &ppb_opengles2;\n")
7699      file.Write("}\n")
7700
7701    file.Write("}  // namespace ppapi\n")
7702    file.Close()
7703
7704  def WriteGLES2ToPPAPIBridge(self, filename):
7705    """Connects GLES2 helper library to PPB_OpenGLES2 interface"""
7706
7707    file = CWriter(filename)
7708    file.Write(_LICENSE)
7709    file.Write(_DO_NOT_EDIT_WARNING)
7710
7711    file.Write("#ifndef GL_GLEXT_PROTOTYPES\n")
7712    file.Write("#define GL_GLEXT_PROTOTYPES\n")
7713    file.Write("#endif\n")
7714    file.Write("#include <GLES2/gl2.h>\n")
7715    file.Write("#include <GLES2/gl2ext.h>\n")
7716    file.Write("#include \"ppapi/lib/gl/gles2/gl2ext_ppapi.h\"\n\n")
7717
7718    for func in self.original_functions:
7719      if not func.InAnyPepperExtension():
7720        continue
7721
7722      interface = self.interface_info[func.GetInfo('pepper_interface') or '']
7723
7724      file.Write("%s GL_APIENTRY gl%s(%s) {\n" %
7725                 (func.return_type, func.name,
7726                  func.MakeTypedOriginalArgString("")))
7727      return_str = "" if func.return_type == "void" else "return "
7728      interface_str = "glGet%sInterfacePPAPI()" % interface.GetName()
7729      original_arg = func.MakeOriginalArgString("")
7730      context_arg = "glGetCurrentContextPPAPI()"
7731      if len(original_arg):
7732        arg = context_arg + ", " + original_arg
7733      else:
7734        arg = context_arg
7735      if interface.GetName():
7736        file.Write("  const struct %s* ext = %s;\n" %
7737                   (interface.GetStructName(), interface_str))
7738        file.Write("  if (ext)\n")
7739        file.Write("    %sext->%s(%s);\n" %
7740                   (return_str, func.name, arg))
7741        if return_str:
7742          file.Write("  %s0;\n" % return_str)
7743      else:
7744        file.Write("  %s%s->%s(%s);\n" %
7745                   (return_str, interface_str, func.name, arg))
7746      file.Write("}\n\n")
7747    file.Close()
7748
7749def main(argv):
7750  """This is the main function."""
7751  parser = OptionParser()
7752  parser.add_option(
7753      "-g", "--generate-implementation-templates", action="store_true",
7754      help="generates files that are generally hand edited..")
7755  parser.add_option(
7756      "--alternate-mode", type="choice",
7757      choices=("ppapi", "chrome_ppapi", "chrome_ppapi_proxy", "nacl_ppapi"),
7758      help="generate files for other projects. \"ppapi\" will generate ppapi "
7759      "bindings. \"chrome_ppapi\" generate chrome implementation for ppapi. "
7760      "\"chrome_ppapi_proxy\" will generate the glue for the chrome IPC ppapi"
7761      "proxy. \"nacl_ppapi\" will generate NaCl implementation for ppapi")
7762  parser.add_option(
7763      "--output-dir",
7764      help="base directory for resulting files, under chrome/src. default is "
7765      "empty. Use this if you want the result stored under gen.")
7766  parser.add_option(
7767      "-v", "--verbose", action="store_true",
7768      help="prints more output.")
7769
7770  (options, args) = parser.parse_args(args=argv)
7771
7772  # Add in states and capabilites to GLState
7773  for state_name in sorted(_STATES.keys()):
7774    state = _STATES[state_name]
7775    if 'enum' in state:
7776      _ENUM_LISTS['GLState']['valid'].append(state['enum'])
7777    else:
7778      for item in state['states']:
7779        if 'extension_flag' in item:
7780          continue
7781        _ENUM_LISTS['GLState']['valid'].append(item['enum'])
7782  for capability in _CAPABILITY_FLAGS:
7783    _ENUM_LISTS['GLState']['valid'].append("GL_%s" % capability['name'].upper())
7784
7785  # This script lives under gpu/command_buffer, cd to base directory.
7786  os.chdir(os.path.dirname(__file__) + "/../..")
7787
7788  gen = GLGenerator(options.verbose)
7789  gen.ParseGLH("common/GLES2/gl2.h")
7790
7791  # Support generating files under gen/
7792  if options.output_dir != None:
7793    os.chdir(options.output_dir)
7794
7795  if options.alternate_mode == "ppapi":
7796    # To trigger this action, do "make ppapi_gles_bindings"
7797    os.chdir("ppapi");
7798    gen.WritePepperGLES2Interface("c/ppb_opengles2.h", False)
7799    gen.WritePepperGLES2Interface("c/dev/ppb_opengles2ext_dev.h", True)
7800    gen.WriteGLES2ToPPAPIBridge("lib/gl/gles2/gles2.c")
7801
7802  elif options.alternate_mode == "chrome_ppapi":
7803    # To trigger this action, do "make ppapi_gles_implementation"
7804    gen.WritePepperGLES2Implementation(
7805        "ppapi/shared_impl/ppb_opengles2_shared.cc")
7806
7807  else:
7808    os.chdir("gpu/command_buffer")
7809    gen.WriteCommandIds("common/gles2_cmd_ids_autogen.h")
7810    gen.WriteFormat("common/gles2_cmd_format_autogen.h")
7811    gen.WriteFormatTest("common/gles2_cmd_format_test_autogen.h")
7812    gen.WriteGLES2InterfaceHeader("client/gles2_interface_autogen.h")
7813    gen.WriteGLES2InterfaceStub("client/gles2_interface_stub_autogen.h")
7814    gen.WriteGLES2InterfaceStubImpl(
7815        "client/gles2_interface_stub_impl_autogen.h")
7816    gen.WriteGLES2ImplementationHeader("client/gles2_implementation_autogen.h")
7817    gen.WriteGLES2Implementation("client/gles2_implementation_impl_autogen.h")
7818    gen.WriteGLES2ImplementationUnitTests(
7819        "client/gles2_implementation_unittest_autogen.h")
7820    gen.WriteGLES2TraceImplementationHeader(
7821        "client/gles2_trace_implementation_autogen.h")
7822    gen.WriteGLES2TraceImplementation(
7823        "client/gles2_trace_implementation_impl_autogen.h")
7824    gen.WriteGLES2CLibImplementation("client/gles2_c_lib_autogen.h")
7825    gen.WriteCmdHelperHeader("client/gles2_cmd_helper_autogen.h")
7826    gen.WriteServiceImplementation("service/gles2_cmd_decoder_autogen.h")
7827    gen.WriteServiceContextStateHeader("service/context_state_autogen.h")
7828    gen.WriteServiceContextStateImpl("service/context_state_impl_autogen.h")
7829    gen.WriteClientContextStateHeader("client/client_context_state_autogen.h")
7830    gen.WriteClientContextStateImpl(
7831        "client/client_context_state_impl_autogen.h")
7832    gen.WriteServiceUnitTests("service/gles2_cmd_decoder_unittest_%d_autogen.h")
7833    gen.WriteServiceUtilsHeader("service/gles2_cmd_validation_autogen.h")
7834    gen.WriteServiceUtilsImplementation(
7835        "service/gles2_cmd_validation_implementation_autogen.h")
7836    gen.WriteCommonUtilsHeader("common/gles2_cmd_utils_autogen.h")
7837    gen.WriteCommonUtilsImpl("common/gles2_cmd_utils_implementation_autogen.h")
7838    gen.WriteGLES2Header("../GLES2/gl2chromium_autogen.h")
7839
7840  if gen.errors > 0:
7841    print "%d errors" % gen.errors
7842    return 1
7843  return 0
7844
7845
7846if __name__ == '__main__':
7847  sys.exit(main(sys.argv[1:]))
7848