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