blob: c9cb95d12328be418cdf25f24a69d9c2b872d7b4 [file] [log] [blame]
# Copyright 2016 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_packed_gl_enums.py:
# Code generation for the packed GL enums.
import datetime, json, os, sys
from collections import namedtuple
Enum = namedtuple('Enum', ['name', 'values', 'max_value'])
EnumValue = namedtuple('EnumValue', ['name', 'gl_name', 'value'])
kJsonFileName = "packed_gl_enums.json"
def load_enums(path):
with open(path) as map_file:
enums_dict = json.loads(map_file.read())
enums = []
for (enum_name, values_dict) in enums_dict.iteritems():
values = []
i = 0
for (value_name, value_gl_name) in sorted(values_dict.iteritems()):
values.append(EnumValue(value_name, value_gl_name, i))
i += 1
assert(i < 255) # This makes sure enums fit in the uint8_t
enums.append(Enum(enum_name, values, i))
enums.sort(key=lambda enum: enum.name)
return enums
header_template = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PackedGLEnums_autogen.h:
// Declares ANGLE-specific enums classes for GLEnum and functions operating
// on them.
#ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
#define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
#include <cstdint>
namespace gl
{{
template<typename Enum>
Enum FromGLenum(GLenum from);
{content}
}} // namespace gl
#endif // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_
"""
enum_declaration_template = """
enum class {enum_name} : uint8_t
{{
{value_declarations}
InvalidEnum = {max_value},
EnumCount = {max_value},
}};
template<>
{enum_name} FromGLenum<{enum_name}>(GLenum from);
GLenum ToGLenum({enum_name} from);
"""
def write_header(enums, path):
content = ['']
for enum in enums:
value_declarations = []
for value in enum.values:
value_declarations.append(' ' + value.name + ' = ' + str(value.value) + ',')
content.append(enum_declaration_template.format(
enum_name = enum.name,
max_value = str(enum.max_value),
value_declarations = '\n'.join(value_declarations)
))
header = header_template.format(
content = ''.join(content),
copyright_year = datetime.date.today().year,
data_source_name = kJsonFileName,
script_name = sys.argv[0]
)
with (open(path, 'wt')) as f:
f.write(header)
cpp_template = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PackedGLEnums_autogen.cpp:
// Implements ANGLE-specific enums classes for GLEnum and functions operating
// on them.
#include "common/debug.h"
#include "libANGLE/PackedGLEnums_autogen.h"
namespace gl
{{
{content}
}} // namespace gl
"""
enum_implementation_template = """
template<>
{enum_name} FromGLenum<{enum_name}>(GLenum from)
{{
switch(from)
{{
{from_glenum_cases}
default: return {enum_name}::InvalidEnum;
}}
}}
GLenum ToGLenum({enum_name} from)
{{
switch(from)
{{
{to_glenum_cases}
default: UNREACHABLE(); return GL_NONE;
}}
}}
"""
def write_cpp(enums, path):
content = ['']
for enum in enums:
from_glenum_cases = []
to_glenum_cases = []
for value in enum.values:
qualified_name = enum.name + '::' + value.name
from_glenum_cases.append(' case ' + value.gl_name + ': return ' + qualified_name + ';')
to_glenum_cases.append(' case ' + qualified_name + ': return ' + value.gl_name + ';')
content.append(enum_implementation_template.format(
enum_name = enum.name,
from_glenum_cases = '\n'.join(from_glenum_cases),
max_value = str(enum.max_value),
to_glenum_cases = '\n'.join(to_glenum_cases)
))
cpp = cpp_template.format(
content = ''.join(content),
copyright_year = datetime.date.today().year,
data_source_name = kJsonFileName,
script_name = sys.argv[0]
)
with (open(path, 'wt')) as f:
f.write(cpp)
if __name__ == '__main__':
path_prefix = os.path.dirname(os.path.realpath(__file__)) + os.path.sep
enums = load_enums(path_prefix + kJsonFileName)
write_header(enums, path_prefix + 'PackedGLEnums_autogen.h')
write_cpp(enums, path_prefix + 'PackedGLEnums_autogen.cpp')