| #!/usr/bin/env python3 | |
| # Copyright 2018 The Chromium Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """code generator for raster command buffers.""" | |
| import filecmp | |
| import os | |
| import sys | |
| from optparse import OptionParser | |
| import build_cmd_buffer_lib | |
| # Additional space required after "type" here and elsewhere because otherwise | |
| # pylint detects "# type:" as invalid syntax on Python 3.8, see | |
| # https://github.com/PyCQA/pylint/issues/3556. | |
| # Named type info object represents a named type that is used in OpenGL call | |
| # arguments. Each named type defines a set of valid OpenGL call arguments. The | |
| # named types are used in 'raster_cmd_buffer_functions.txt'. | |
| # type : The actual GL type of the named type. | |
| # valid: The list of values that are valid for both the client and the service. | |
| # invalid: Examples of invalid values for the type. At least these values | |
| # should be tested to be invalid. | |
| # is_complete: The list of valid values of type are final and will not be | |
| # modified during runtime. | |
| # validator: If set to False will prevent creation of a ValueValidator. Values | |
| # are still expected to be checked for validity and will be tested. | |
| _NAMED_TYPE_INFO = { | |
| 'GLState': { | |
| 'type': 'GLenum', | |
| 'valid': [ | |
| 'GL_ACTIVE_TEXTURE', | |
| ], | |
| 'invalid': [ | |
| 'GL_FOG_HINT', | |
| ], | |
| }, | |
| 'QueryObjectParameter': { | |
| 'type': 'GLenum', | |
| 'is_complete': True, | |
| 'valid': [ | |
| 'GL_QUERY_RESULT_EXT', | |
| 'GL_QUERY_RESULT_AVAILABLE_EXT', | |
| 'GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT', | |
| ], | |
| }, | |
| 'QueryTarget': { | |
| 'type': 'GLenum', | |
| 'is_complete': True, | |
| 'valid': [ | |
| 'GL_COMMANDS_ISSUED_CHROMIUM', | |
| 'GL_COMMANDS_COMPLETED_CHROMIUM', | |
| ], | |
| }, | |
| 'TextureParameter': { | |
| 'type': 'GLenum', | |
| 'valid': [ | |
| 'GL_TEXTURE_MAG_FILTER', | |
| 'GL_TEXTURE_MIN_FILTER', | |
| 'GL_TEXTURE_WRAP_S', | |
| 'GL_TEXTURE_WRAP_T', | |
| ], | |
| 'invalid': [ | |
| 'GL_GENERATE_MIPMAP', | |
| ], | |
| }, | |
| 'TextureWrapMode': { | |
| 'type': 'GLenum', | |
| 'valid': [ | |
| 'GL_CLAMP_TO_EDGE', | |
| ], | |
| 'invalid': [ | |
| 'GL_REPEAT', | |
| ], | |
| }, | |
| 'TextureMinFilterMode': { | |
| 'type': 'GLenum', | |
| 'valid': [ | |
| 'GL_NEAREST', | |
| ], | |
| 'invalid': [ | |
| 'GL_NEAREST_MIPMAP_NEAREST', | |
| ], | |
| }, | |
| 'TextureMagFilterMode': { | |
| 'type': 'GLenum', | |
| 'valid': [ | |
| 'GL_NEAREST', | |
| ], | |
| 'invalid': [ | |
| 'GL_LINEAR', | |
| ], | |
| }, | |
| 'ResetStatus': { | |
| 'type': 'GLenum', | |
| 'is_complete': True, | |
| 'valid': [ | |
| 'GL_GUILTY_CONTEXT_RESET', | |
| 'GL_INNOCENT_CONTEXT_RESET', | |
| 'GL_UNKNOWN_CONTEXT_RESET', | |
| ], | |
| }, | |
| 'gfx::BufferUsage': { | |
| 'type': 'gfx::BufferUsage', | |
| 'valid': [ | |
| 'gfx::BufferUsage::GPU_READ', | |
| 'gfx::BufferUsage::SCANOUT', | |
| 'gfx::BufferUsage::GPU_READ_CPU_READ_WRITE', | |
| ], | |
| 'invalid': [ | |
| 'gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE', | |
| 'gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE', | |
| ], | |
| }, | |
| 'gpu::raster::MsaaMode': { | |
| 'type': 'gpu::raster::MsaaMode', | |
| 'is_complete': True, | |
| 'valid': [ | |
| 'gpu::raster::MsaaMode::kNoMSAA', | |
| 'gpu::raster::MsaaMode::kMSAA', | |
| 'gpu::raster::MsaaMode::kDMSAA', | |
| ], | |
| }, | |
| } | |
| # A function info object specifies the type and other special data for the | |
| # command that will be generated. A base function info object is generated by | |
| # parsing the "raster_cmd_buffer_functions.txt", one for each function in the | |
| # file. These function info objects can be augmented and their values can be | |
| # overridden by adding an object to the table below. | |
| # | |
| # Must match function names specified in "raster_cmd_buffer_functions.txt". | |
| # | |
| # type : defines which handler will be used to generate code. | |
| # decoder_func: defines which function to call in the decoder to execute the | |
| # corresponding GL command. If not specified the GL command will | |
| # be called directly. | |
| # cmd_args: The arguments to use for the command. This overrides generating | |
| # them based on the GL function arguments. | |
| # data_transfer_methods: Array of methods that are used for transfering the | |
| # pointer data. Possible values: 'immediate', 'shm', 'bucket'. | |
| # The default is 'immediate' if the command has one pointer | |
| # argument, otherwise 'shm'. One command is generated for each | |
| # transfer method. Affects only commands which are not of type | |
| # 'GETn' or 'GLcharN'. | |
| # Note: the command arguments that affect this are the final args, | |
| # taking cmd_args override into consideration. | |
| # impl_func: Whether or not to generate the GLES2Implementation part of this | |
| # command. | |
| # internal: If true, this is an internal command only, not exposed to the | |
| # client. | |
| # count: The number of units per element. For PUTn or PUT types. | |
| # use_count_func: If True the actual data count needs to be computed; the count | |
| # argument specifies the maximum count. | |
| # unit_test: If False no service side unit test will be generated. | |
| # client_test: If False no client side unit test will be generated. | |
| # expectation: If False the unit test will have no expected calls. | |
| # valid_args: A dictionary of argument indices to args to use in unit tests | |
| # when they can not be automatically determined. | |
| # invalid_test: False if no invalid test needed. | |
| # not_shared: For GENn types, True if objects can't be shared between contexts | |
| _FUNCTION_INFO = { | |
| 'CopySharedImageINTERNAL': { | |
| 'decoder_func': 'DoCopySharedImageINTERNAL', | |
| 'internal': True, | |
| 'type': 'PUT', | |
| 'count': 32, # GL_MAILBOX_SIZE_CHROMIUM x2 | |
| 'unit_test': False, | |
| 'trace_level': 2, | |
| }, | |
| 'WritePixelsINTERNAL': { | |
| 'decoder_func': 'DoWritePixelsINTERNAL', | |
| 'internal': True, | |
| 'type': 'PUT', | |
| 'count': 16, # GL_MAILBOX_SIZE_CHROMIUM | |
| 'unit_test': False, | |
| 'trace_level': 2, | |
| }, | |
| 'WritePixelsYUVINTERNAL': { | |
| 'decoder_func': 'DoWritePixelsYUVINTERNAL', | |
| 'internal': True, | |
| 'type': 'PUT', | |
| 'count': 16, # GL_MAILBOX_SIZE_CHROMIUM | |
| 'unit_test': False, | |
| 'trace_level': 2, | |
| }, | |
| 'ReadbackARGBImagePixelsINTERNAL': { | |
| 'decoder_func': 'DoReadbackARGBImagePixelsINTERNAL', | |
| 'internal': True, | |
| 'type': 'PUT', | |
| 'count': 16, # GL_MAILBOX_SIZE_CHROMIUM | |
| 'unit_test': False, | |
| 'result': ['uint32_t'], | |
| 'trace_level': 2, | |
| }, | |
| 'ReadbackYUVImagePixelsINTERNAL': { | |
| 'decoder_func': 'DoReadbackYUVImagePixelsINTERNAL', | |
| 'internal': True, | |
| 'type': 'PUT', | |
| 'count': 16, # GL_MAILBOX_SIZE_CHROMIUM | |
| 'unit_test': False, | |
| 'result': ['uint32_t'], | |
| 'trace_level': 2, | |
| }, | |
| 'Finish': { | |
| 'impl_func': False, | |
| 'client_test': False, | |
| 'decoder_func': 'DoFinish', | |
| 'unit_test': False, | |
| 'trace_level': 1, | |
| }, | |
| 'Flush': { | |
| 'impl_func': False, | |
| 'decoder_func': 'DoFlush', | |
| 'unit_test': False, | |
| 'trace_level': 1, | |
| }, | |
| 'GetError': { | |
| 'type': 'Is', | |
| 'decoder_func': 'GetErrorState()->GetGLError', | |
| 'impl_func': False, | |
| 'result': ['GLenum'], | |
| 'client_test': False, | |
| }, | |
| 'GetGraphicsResetStatusKHR': { | |
| 'type': 'NoCommand', | |
| 'trace_level': 1, | |
| }, | |
| 'GenQueriesEXT': { | |
| 'type': 'GENn', | |
| 'gl_test_func': 'glGenQueriesARB', | |
| 'resource_type': 'Query', | |
| 'resource_types': 'Queries', | |
| 'unit_test': False, | |
| 'not_shared': 'True', | |
| }, | |
| 'DeleteQueriesEXT': { | |
| 'type': 'DELn', | |
| 'gl_test_func': 'glDeleteQueriesARB', | |
| 'resource_type': 'Query', | |
| 'resource_types': 'Queries', | |
| 'unit_test': False, | |
| }, | |
| 'BeginQueryEXT': { | |
| 'type': 'Custom', | |
| 'impl_func': False, | |
| 'cmd_args': 'GLenumQueryTarget target, GLidQuery id, void* sync_data', | |
| 'data_transfer_methods': ['shm'], | |
| 'gl_test_func': 'glBeginQuery', | |
| }, | |
| 'EndQueryEXT': { | |
| 'type': 'Custom', | |
| 'impl_func': False, | |
| 'cmd_args': 'GLenumQueryTarget target, GLuint submit_count', | |
| 'gl_test_func': 'glEndnQuery', | |
| 'client_test': False, | |
| }, | |
| 'GetQueryObjectuivEXT': { | |
| 'type': 'NoCommand', | |
| 'gl_test_func': 'glGetQueryObjectuiv', | |
| }, | |
| 'OrderingBarrierCHROMIUM': { | |
| 'type': 'NoCommand', | |
| }, | |
| 'TraceBeginCHROMIUM': { | |
| 'type': 'Custom', | |
| 'impl_func': False, | |
| 'client_test': False, | |
| 'cmd_args': 'GLuint category_bucket_id, GLuint name_bucket_id', | |
| 'extension': 'CHROMIUM_trace_marker', | |
| }, | |
| 'TraceEndCHROMIUM': { | |
| 'impl_func': False, | |
| 'client_test': False, | |
| 'decoder_func': 'DoTraceEndCHROMIUM', | |
| 'unit_test': False, | |
| 'extension': 'CHROMIUM_trace_marker', | |
| }, | |
| 'SetActiveURLCHROMIUM': { | |
| 'type': 'Custom', | |
| 'impl_func': False, | |
| 'client_test': False, | |
| 'cmd_args': 'GLuint url_bucket_id', | |
| }, | |
| 'LoseContextCHROMIUM': { | |
| 'decoder_func': 'DoLoseContextCHROMIUM', | |
| 'unit_test': False, | |
| 'trace_level': 1, | |
| }, | |
| 'BeginRasterCHROMIUM': { | |
| 'decoder_func': 'DoBeginRasterCHROMIUM', | |
| 'type': 'PUT', | |
| 'count': 16, # GL_MAILBOX_SIZE_CHROMIUM | |
| 'internal': True, | |
| 'impl_func': False, | |
| 'unit_test': False, | |
| }, | |
| 'RasterCHROMIUM': { | |
| 'decoder_func': 'DoRasterCHROMIUM', | |
| 'internal': True, | |
| 'impl_func': True, | |
| 'cmd_args': 'GLuint raster_shm_id, GLuint raster_shm_offset,' | |
| 'GLsizeiptr raster_shm_size, GLuint font_shm_id,' | |
| 'GLuint font_shm_offset, GLsizeiptr font_shm_size', | |
| 'extension': 'CHROMIUM_raster_transport', | |
| 'unit_test': False, | |
| }, | |
| 'EndRasterCHROMIUM': { | |
| 'decoder_func': 'DoEndRasterCHROMIUM', | |
| 'impl_func': False, | |
| 'unit_test': False, | |
| 'client_test': False, | |
| }, | |
| 'FlushTileRasterGraphiteCommandsCHROMIUM': { | |
| 'decoder_func': 'DoFlushTileRasterGraphiteCommandsCHROMIUM', | |
| 'unit_test': False, | |
| 'client_test': False, | |
| }, | |
| 'CreateTransferCacheEntryINTERNAL': { | |
| 'decoder_func': 'DoCreateTransferCacheEntryINTERNAL', | |
| 'cmd_args': 'GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, ' | |
| 'GLuint handle_shm_offset, GLuint data_shm_id, ' | |
| 'GLuint data_shm_offset, GLuint data_size', | |
| 'internal': True, | |
| 'impl_func': True, | |
| 'client_test': False, | |
| 'unit_test': False, | |
| }, | |
| 'DeleteTransferCacheEntryINTERNAL': { | |
| 'decoder_func': 'DoDeleteTransferCacheEntryINTERNAL', | |
| 'cmd_args': 'GLuint entry_type, GLuint entry_id', | |
| 'internal': True, | |
| 'impl_func': True, | |
| 'client_test': False, | |
| 'unit_test': False, | |
| }, | |
| 'DeletePaintCachePathsINTERNAL': { | |
| 'type': 'DELn', | |
| 'internal': True, | |
| 'unit_test': False, | |
| 'data_transfer_methods': ['immediate', 'shm'], | |
| }, | |
| 'DeletePaintCacheEffectsINTERNAL': { | |
| 'type': 'DELn', | |
| 'internal': True, | |
| 'unit_test': False, | |
| 'data_transfer_methods': ['immediate', 'shm'], | |
| }, | |
| 'ClearPaintCacheINTERNAL': { | |
| 'decoder_func': 'DoClearPaintCacheINTERNAL', | |
| 'internal': True, | |
| 'unit_test': False, | |
| }, | |
| 'UnlockTransferCacheEntryINTERNAL': { | |
| 'decoder_func': 'DoUnlockTransferCacheEntryINTERNAL', | |
| 'cmd_args': 'GLuint entry_type, GLuint entry_id', | |
| 'internal': True, | |
| 'impl_func': True, | |
| 'client_test': False, | |
| 'unit_test': False, | |
| }, | |
| } | |
| def main(argv): | |
| """This is the main function.""" | |
| parser = OptionParser() | |
| parser.add_option( | |
| "--output-dir", | |
| help="Output directory for generated files. Defaults to chromium root " | |
| "directory.", | |
| ) | |
| parser.add_option( | |
| "-v", "--verbose", action="store_true", help="Verbose logging output." | |
| ) | |
| parser.add_option( | |
| "-c", | |
| "--check", | |
| action="store_true", | |
| help="Check if output files match generated files in chromium root " | |
| "directory. Use this in PRESUBMIT scripts with --output-dir.", | |
| ) | |
| (options, _) = parser.parse_args(args=argv) | |
| # This script lives under src/gpu/command_buffer. | |
| script_dir = os.path.dirname(os.path.abspath(__file__)) | |
| assert script_dir.endswith( | |
| ( | |
| os.path.normpath("src/gpu/command_buffer"), | |
| os.path.normpath("chromium/gpu/command_buffer"), | |
| ) | |
| ) | |
| # os.path.join doesn't do the right thing with relative paths. | |
| chromium_root_dir = os.path.abspath(script_dir + "/../..") | |
| # Support generating files under gen/ and for PRESUBMIT. | |
| if options.output_dir: | |
| output_dir = options.output_dir | |
| else: | |
| output_dir = chromium_root_dir | |
| os.chdir(output_dir) | |
| build_cmd_buffer_lib.InitializePrefix("Raster") | |
| gen = build_cmd_buffer_lib.GLGenerator( | |
| options.verbose, "2018", _FUNCTION_INFO, _NAMED_TYPE_INFO, chromium_root_dir | |
| ) | |
| gen.ParseGLH("gpu/command_buffer/raster_cmd_buffer_functions.txt") | |
| gen.WriteCommandIds("gpu/command_buffer/common/raster_cmd_ids_autogen.h") | |
| gen.WriteFormat("gpu/command_buffer/common/raster_cmd_format_autogen.h") | |
| gen.WriteFormatTest( | |
| "gpu/command_buffer/common/raster_cmd_format_test_autogen.h" | |
| ) | |
| gen.WriteGLES2InterfaceHeader( | |
| "gpu/command_buffer/client/raster_interface_autogen.h" | |
| ) | |
| gen.WriteGLES2ImplementationHeader( | |
| "gpu/command_buffer/client/raster_implementation_autogen.h" | |
| ) | |
| gen.WriteGLES2Implementation( | |
| "gpu/command_buffer/client/raster_implementation_impl_autogen.h" | |
| ) | |
| gen.WriteGLES2ImplementationUnitTests( | |
| "gpu/command_buffer/client/raster_implementation_unittest_autogen.h" | |
| ) | |
| gen.WriteCmdHelperHeader( | |
| "gpu/command_buffer/client/raster_cmd_helper_autogen.h" | |
| ) | |
| gen.WriteServiceImplementation( | |
| "gpu/command_buffer/service/raster_decoder_autogen.h" | |
| ) | |
| gen.WriteServiceUnitTests( | |
| "gpu/command_buffer/service/raster_decoder_unittest_%d_autogen.h" | |
| ) | |
| gen.WriteServiceUtilsHeader( | |
| "gpu/command_buffer/service/raster_cmd_validation_autogen.h" | |
| ) | |
| gen.WriteServiceUtilsImplementation( | |
| "gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h" | |
| ) | |
| build_cmd_buffer_lib.Format( | |
| gen.generated_cpp_filenames, output_dir, chromium_root_dir | |
| ) | |
| if gen.errors > 0: | |
| print("build_raster_cmd_buffer.py: Failed with %d errors" % gen.errors) | |
| return 1 | |
| check_failed_filenames = [] | |
| if options.check: | |
| for filename in gen.generated_cpp_filenames: | |
| if not filecmp.cmp( | |
| os.path.join(output_dir, filename), | |
| os.path.join(chromium_root_dir, filename), | |
| ): | |
| check_failed_filenames.append(filename) | |
| if len(check_failed_filenames) > 0: | |
| print('Please run gpu/command_buffer/build_raster_cmd_buffer.py') | |
| print('Failed check on autogenerated command buffer files:') | |
| for filename in check_failed_filenames: | |
| print(filename) | |
| return 1 | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(main(sys.argv[1:])) |