Index: ui/gl/generate_bindings.py |
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py |
index af1bdc84b563876082359726f9b16c82c8f2e5a5..7a339b62ec22b1f385b5ccebe0e2880ff68b539b 100755 |
--- a/ui/gl/generate_bindings.py |
+++ b/ui/gl/generate_bindings.py |
@@ -9,7 +9,16 @@ import optparse |
import os |
import collections |
import re |
+import platform |
import sys |
+from subprocess import call |
+ |
+HEADER_PATHS = [ |
+ '../../third_party/khronos', |
+ '../../third_party/mesa/src/include', |
+ '.', |
+ '../../gpu', |
+] |
"""In case there are multiple versions of the same function, one that's listed |
first takes priority if its conditions are met. If the function is an extension |
@@ -149,7 +158,7 @@ GL_FUNCTIONS = [ |
'glCheckFramebufferStatus'], |
'arguments': 'GLenum target', |
'logging_code': """ |
- GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringEnum(result)); |
+ GL_SERVICE_LOG("GL_RESULT: " << GLEnums::GetStringEnum(result)); |
""", }, |
{ 'return_type': 'void', |
'names': ['glClear'], |
@@ -521,7 +530,7 @@ GL_FUNCTIONS = [ |
'names': ['glGetError'], |
'arguments': 'void', |
'logging_code': """ |
- GL_SERVICE_LOG("GL_RESULT: " << GLES2Util::GetStringError(result)); |
+ GL_SERVICE_LOG("GL_RESULT: " << GLEnums::GetStringError(result)); |
""", }, |
{ 'return_type': 'void', |
'names': ['glGetFenceivNV'], |
@@ -1688,17 +1697,35 @@ FUNCTION_SETS = [ |
[GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []], |
] |
+GLES2_HEADERS_WITH_ENUMS = [ |
+ 'GLES2/gl2.h', |
+ 'GLES2/gl2ext.h', |
+ 'GLES2/gl2chromium.h', |
+ 'GLES2/gl2extchromium.h', |
+ 'GLES3/gl3.h', |
+] |
-def GenerateHeader(file, functions, set_name, used_extensions): |
- """Generates gl_bindings_autogen_x.h""" |
+SELF_LOCATION = os.path.dirname(os.path.abspath(__file__)) |
- # Write file header. |
- file.write( |
-"""// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+LICENSE_AND_HEADER = """\ |
+// Copyright 2014 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. |
+// |
+// This file is auto-generated from |
+// ui/gl/generate_bindings.py |
+// It's formatted by clang-format using chromium coding style: |
+// clang-format -i -style=chromium filename |
+// DO NOT EDIT! |
-// This file is automatically generated. |
+""" |
+ |
+def GenerateHeader(file, functions, set_name, used_extensions): |
+ """Generates gl_bindings_autogen_x.h""" |
+ |
+ # Write file header. |
+ file.write(LICENSE_AND_HEADER + |
+""" |
#ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ |
#define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ |
@@ -1763,14 +1790,7 @@ def GenerateAPIHeader(file, functions, set_name): |
"""Generates gl_bindings_api_autogen_x.h""" |
# Write file header. |
- file.write( |
-"""// Copyright (c) 2012 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. |
- |
-// This file is automatically generated. |
- |
-""" % {'name': set_name.upper()}) |
+ file.write(LICENSE_AND_HEADER) |
# Write API declaration. |
for func in functions: |
@@ -1784,14 +1804,7 @@ def GenerateMockHeader(file, functions, set_name): |
"""Generates gl_mock_autogen_x.h""" |
# Write file header. |
- file.write( |
-"""// Copyright (c) 2012 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. |
- |
-// This file is automatically generated. |
- |
-""" % {'name': set_name.upper()}) |
+ file.write(LICENSE_AND_HEADER) |
# Write API declaration. |
for func in functions: |
@@ -1810,27 +1823,27 @@ def GenerateMockHeader(file, functions, set_name): |
def GenerateSource(file, functions, set_name, used_extensions): |
"""Generates gl_bindings_autogen_x.cc""" |
- # Write file header. |
- file.write( |
-"""// Copyright (c) 2011 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. |
+ set_header_name = "ui/gl/gl_" + set_name.lower() + "_api_implementation.h" |
+ include_list = [ 'base/debug/trace_event.h', |
+ 'ui/gl/gl_enums.h', |
+ 'ui/gl/gl_bindings.h', |
+ 'ui/gl/gl_context.h', |
+ 'ui/gl/gl_implementation.h', |
+ 'ui/gl/gl_version_info.h', |
+ set_header_name ] |
+ includes_string = "\n".join(["#include \"{0}\"".format(h) |
+ for h in sorted(include_list)]) |
-// This file is automatically generated. |
+ # Write file header. |
+ file.write(LICENSE_AND_HEADER + |
+""" |
#include <string> |
-#include "base/debug/trace_event.h" |
-#include "gpu/command_buffer/common/gles2_cmd_utils.h" |
-#include "ui/gl/gl_bindings.h" |
-#include "ui/gl/gl_context.h" |
-#include "ui/gl/gl_implementation.h" |
-#include "ui/gl/gl_version_info.h" |
-#include "ui/gl/gl_%s_api_implementation.h" |
-using gpu::gles2::GLES2Util; |
+%s |
namespace gfx { |
-""" % set_name.lower()) |
+""" % includes_string) |
file.write('\n') |
file.write('static bool g_debugBindingsInitialized;\n') |
@@ -1945,12 +1958,13 @@ namespace gfx { |
# http://crbug.com/325668 |
if cond != '' and not last_version: |
if not first_version: |
- file.write(' if (!fn.%sFn && (%s))\n ' % (known_as, cond)) |
+ file.write(' if (!fn.%sFn && (%s)) {\n ' % (known_as, cond)) |
else: |
- file.write(' if (%s)\n ' % cond) |
+ file.write(' if (%s) {\n ' % cond) |
elif not first_version: |
- file.write(' if (!fn.%sFn)\n ' % known_as) |
+ file.write(' if (!fn.%sFn) {\n ' % known_as) |
WriteFuncBinding(file, known_as, version['name']) |
+ file.write('}\n') |
i += 1 |
first_version = False |
@@ -2002,10 +2016,10 @@ namespace gfx { |
log_argument_names = re.sub( |
r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names) |
log_argument_names = re.sub( |
- r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)', |
+ r'GLenum_([a-zA-Z0-9_]+)', r'GLEnums::GetStringEnum(\1)', |
log_argument_names) |
log_argument_names = re.sub( |
- r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)', |
+ r'GLboolean_([a-zA-Z0-9_]+)', r'GLEnums::GetStringBool(\1)', |
log_argument_names) |
log_argument_names = log_argument_names.replace(',', ' << ", " <<') |
if argument_names == 'void' or argument_names == '': |
@@ -2151,14 +2165,7 @@ def GetUniquelyNamedFunctions(functions): |
def GenerateMockBindingsHeader(file, functions): |
"""Headers for functions that invoke MockGLInterface members""" |
- file.write( |
-"""// Copyright (c) 2014 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. |
- |
-// This file is automatically generated. |
- |
-""") |
+ file.write(LICENSE_AND_HEADER) |
uniquely_named_functions = GetUniquelyNamedFunctions(functions) |
for key in sorted(uniquely_named_functions.iterkeys()): |
@@ -2171,12 +2178,8 @@ def GenerateMockBindingsSource(file, functions): |
"""Generates functions that invoke MockGLInterface members and a |
GetGLProcAddress function that returns addresses to those functions.""" |
- file.write( |
-"""// Copyright (c) 2011 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. |
- |
-// This file is automatically generated. |
+ file.write(LICENSE_AND_HEADER + |
+""" |
#include <string.h> |
@@ -2238,6 +2241,39 @@ void MakeFunctionUnique(const char *func_name) { |
file.write('\n') |
file.write('} // namespace gfx\n') |
+def GenerateEnumUtils(out_file, input_filenames): |
+ enum_re = re.compile(r'\#define\s+(GL_[a-zA-Z0-9_]+)\s+([0-9A-Fa-fx]+)') |
+ dict = {} |
+ for fname in input_filenames: |
+ lines = open(fname).readlines() |
+ for line in lines: |
+ m = enum_re.match(line) |
+ if m: |
+ name = m.group(1) |
+ value = m.group(2) |
+ if len(value) <= 10: |
+ if not value in dict: |
+ dict[value] = name |
+ # check our own _CHROMIUM macro conflicts with khronos GL headers. |
+ elif dict[value] != name and (name.endswith('_CHROMIUM') or |
+ dict[value].endswith('_CHROMIUM')): |
+ raise RunTimeError("code collision: %s and %s have the same code %s" |
+ % (dict[value], name, value)) |
+ |
+ out_file.write(LICENSE_AND_HEADER) |
+ out_file.write("static const GLEnums::EnumToString " |
+ "enum_to_string_table[] = {\n") |
+ for value in dict: |
+ out_file.write(' { %s, "%s", },\n' % (value, dict[value])) |
+ out_file.write("""}; |
+ |
+const GLEnums::EnumToString* const GLEnums::enum_to_string_table_ = |
+ enum_to_string_table; |
+const size_t GLEnums::enum_to_string_table_len_ = |
+ sizeof(enum_to_string_table) / sizeof(enum_to_string_table[0]); |
+ |
+""") |
+ |
def ParseExtensionFunctionsFromHeader(header_file): |
"""Parse a C extension header file and return a map from extension names to |
@@ -2358,12 +2394,10 @@ def FillExtensionsFromHeaders(functions, extension_headers, extra_extensions): |
def ResolveHeader(header, header_paths): |
- paths = header_paths.split(':') |
- |
- for path in paths: |
+ for path in header_paths: |
result = os.path.join(path, header) |
if not os.path.isabs(path): |
- result = os.path.relpath(os.path.join(os.getcwd(), result), os.getcwd()) |
+ result = os.path.abspath(os.path.join(SELF_LOCATION, result)) |
if os.path.exists(result): |
# Always use forward slashes as path separators. Otherwise backslashes |
# may be incorrectly interpreted as escape characters. |
@@ -2377,7 +2411,6 @@ def main(argv): |
parser = optparse.OptionParser() |
parser.add_option('--inputs', action='store_true') |
- parser.add_option('--header-paths') |
parser.add_option('--verify-order', action='store_true') |
options, args = parser.parse_args(argv) |
@@ -2385,13 +2418,19 @@ def main(argv): |
if options.inputs: |
for [_, _, headers, _] in FUNCTION_SETS: |
for header in headers: |
- print ResolveHeader(header, options.header_paths) |
+ print ResolveHeader(header, HEADER_PATHS) |
return 0 |
- directory = '.' |
+ directory = SELF_LOCATION |
if len(args) >= 1: |
directory = args[0] |
+ def ClangFormat(filename): |
+ formatter = "clang-format" |
+ if platform.system() == "Windows": |
+ formatter += ".bat" |
+ call([formatter, "-i", "-style=chromium", filename]) |
+ |
for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS: |
# Function names can be specified in two ways (list of unique names or list |
# of versions with different binding conditions). Fill in the data to the |
@@ -2417,7 +2456,7 @@ def main(argv): |
if options.verify_order: |
continue |
- extension_headers = [ResolveHeader(h, options.header_paths) |
+ extension_headers = [ResolveHeader(h, HEADER_PATHS) |
for h in extension_headers] |
used_extensions = FillExtensionsFromHeaders( |
functions, extension_headers, extensions) |
@@ -2426,33 +2465,48 @@ def main(argv): |
os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb') |
GenerateHeader(header_file, functions, set_name, used_extensions) |
header_file.close() |
+ ClangFormat(header_file.name) |
header_file = open( |
os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name), |
'wb') |
GenerateAPIHeader(header_file, functions, set_name) |
header_file.close() |
+ ClangFormat(header_file.name) |
source_file = open( |
os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') |
GenerateSource(source_file, functions, set_name, used_extensions) |
source_file.close() |
+ ClangFormat(source_file.name) |
if not options.verify_order: |
header_file = open( |
os.path.join(directory, 'gl_mock_autogen_gl.h'), 'wb') |
GenerateMockHeader(header_file, GL_FUNCTIONS, 'gl') |
header_file.close() |
+ ClangFormat(header_file.name) |
header_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.h'), |
'wb') |
GenerateMockBindingsHeader(header_file, GL_FUNCTIONS) |
header_file.close() |
+ ClangFormat(header_file.name) |
source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'), |
'wb') |
GenerateMockBindingsSource(source_file, GL_FUNCTIONS) |
source_file.close() |
+ ClangFormat(source_file.name) |
+ |
+ enum_header_filenames = [ResolveHeader(h, HEADER_PATHS) |
+ for h in GLES2_HEADERS_WITH_ENUMS] |
+ header_file = open(os.path.join(directory, |
+ 'gl_enums_implementation_autogen.h'), |
+ 'wb') |
+ GenerateEnumUtils(header_file, enum_header_filenames) |
+ header_file.close() |
+ ClangFormat(header_file.name) |
return 0 |