|  | #!/usr/bin/env python | 
|  | # Copyright 2018 The Chromium Authors. All rights reserved. | 
|  | # 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 os.path | 
|  | import sys | 
|  | from optparse import OptionParser | 
|  |  | 
|  | import build_cmd_buffer_lib | 
|  |  | 
|  | # 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_ISSUED_TIMESTAMP_CHROMIUM', | 
|  | 'GL_COMMANDS_COMPLETED_CHROMIUM', | 
|  | ], | 
|  | 'invalid': [ | 
|  | 'GL_LATENCY_QUERY_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_ARB', | 
|  | 'GL_INNOCENT_CONTEXT_RESET_ARB', | 
|  | 'GL_UNKNOWN_CONTEXT_RESET_ARB', | 
|  | ], | 
|  | }, | 
|  | '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', | 
|  | ], | 
|  | }, | 
|  | 'viz::ResourceFormat': { | 
|  | 'type': 'viz::ResourceFormat', | 
|  | 'valid': [ | 
|  | 'viz::ResourceFormat::RGBA_8888', | 
|  | 'viz::ResourceFormat::RGBA_4444', | 
|  | 'viz::ResourceFormat::BGRA_8888', | 
|  | 'viz::ResourceFormat::ALPHA_8', | 
|  | 'viz::ResourceFormat::LUMINANCE_8', | 
|  | 'viz::ResourceFormat::RGB_565', | 
|  | 'viz::ResourceFormat::BGR_565', | 
|  | 'viz::ResourceFormat::RED_8', | 
|  | 'viz::ResourceFormat::RG_88', | 
|  | 'viz::ResourceFormat::LUMINANCE_F16', | 
|  | 'viz::ResourceFormat::RGBA_F16', | 
|  | 'viz::ResourceFormat::R16_EXT', | 
|  | 'viz::ResourceFormat::RGBX_8888', | 
|  | 'viz::ResourceFormat::BGRX_8888', | 
|  | 'viz::ResourceFormat::RGBA_1010102', | 
|  | 'viz::ResourceFormat::BGRA_1010102', | 
|  | 'viz::ResourceFormat::YVU_420', | 
|  | 'viz::ResourceFormat::YUV_420_BIPLANAR', | 
|  |  | 
|  | ], | 
|  | 'invalid': [ | 
|  | 'viz::ResourceFormat::ETC1', | 
|  | ], | 
|  | }, | 
|  | } | 
|  |  | 
|  | # 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 = { | 
|  | 'CopySubTextureINTERNAL': { | 
|  | 'decoder_func': 'DoCopySubTextureINTERNAL', | 
|  | '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, | 
|  | }, | 
|  | 'ReadbackImagePixelsINTERNAL': { | 
|  | 'decoder_func': 'DoReadbackImagePixelsINTERNAL', | 
|  | 'internal': True, | 
|  | 'type': 'PUT', | 
|  | 'count': 16,  # GL_MAILBOX_SIZE_CHROMIUM | 
|  | 'unit_test': False, | 
|  | 'trace_level': 2, | 
|  | }, | 
|  | 'ConvertYUVMailboxesToRGBINTERNAL': { | 
|  | 'decoder_func': 'DoConvertYUVMailboxesToRGBINTERNAL', | 
|  | 'internal': True, | 
|  | 'type': 'PUT', | 
|  | 'count': 64, #GL_MAILBOX_SIZE_CHROMIUM x4 | 
|  | 'unit_test': False, | 
|  | 'trace_level': 2, | 
|  | }, | 
|  | 'Finish': { | 
|  | 'impl_func': False, | 
|  | 'client_test': False, | 
|  | 'decoder_func': 'DoFinish', | 
|  | 'trace_level': 1, | 
|  | }, | 
|  | 'Flush': { | 
|  | 'impl_func': False, | 
|  | 'decoder_func': 'DoFlush', | 
|  | '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, | 
|  | }, | 
|  | 'QueryCounterEXT' : { | 
|  | 'type': 'Custom', | 
|  | 'impl_func': False, | 
|  | 'cmd_args': 'GLidQuery id, GLenumQueryTarget target, ' | 
|  | 'void* sync_data, GLuint submit_count', | 
|  | 'data_transfer_methods': ['shm'], | 
|  | 'gl_test_func': 'glQueryCounter', | 
|  | }, | 
|  | 'GetQueryObjectuivEXT': { | 
|  | 'type': 'NoCommand', | 
|  | 'gl_test_func': 'glGetQueryObjectuiv', | 
|  | }, | 
|  | 'GetQueryObjectui64vEXT': { | 
|  | 'type': 'NoCommand', | 
|  | 'gl_test_func': 'glGetQueryObjectui64v', | 
|  | }, | 
|  | 'ShallowFlushCHROMIUM': { | 
|  | 'type': 'NoCommand', | 
|  | }, | 
|  | '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', | 
|  | 'extension_flag': 'chromium_raster_transport', | 
|  | }, | 
|  | 'EndRasterCHROMIUM': { | 
|  | 'decoder_func': 'DoEndRasterCHROMIUM', | 
|  | 'impl_func': False, | 
|  | '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, | 
|  | }, | 
|  | 'DeletePaintCacheTextBlobsINTERNAL': { | 
|  | 'type': 'DELn', | 
|  | 'internal': True, | 
|  | 'unit_test': False, | 
|  | }, | 
|  | 'DeletePaintCachePathsINTERNAL': { | 
|  | 'type': 'DELn', | 
|  | 'internal': True, | 
|  | 'unit_test': False, | 
|  | }, | 
|  | '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.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:])) |