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