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