#!/usr/bin/python
# 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_angle_format_table.py:
#  Code generation for ANGLE format map.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
#

import angle_format
from datetime import date
import json
import math
import pprint
import re
import sys

template_autogen_h = """// 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.
//
// ANGLE format enumeration.

#ifndef LIBANGLE_RENDERER_FORMATID_H_
#define LIBANGLE_RENDERER_FORMATID_H_

#include <cstdint>

namespace angle
{{

enum class FormatID
{{
{angle_format_enum}
}};

constexpr uint32_t kNumANGLEFormats = {num_angle_formats};

}}  // namespace angle

#endif  // LIBANGLE_RENDERER_FORMATID_H_
"""

template_autogen_inl = """// 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.
//
// ANGLE Format table:
//   Queries for typed format information from the ANGLE format enum.

#include "libANGLE/renderer/Format.h"

#include "image_util/copyimage.h"
#include "image_util/generatemip.h"
#include "image_util/loadimage.h"

namespace angle
{{

static constexpr rx::FastCopyFunctionMap::Entry BGRAEntry = {{angle::FormatID::R8G8B8A8_UNORM,
                                                             CopyBGRA8ToRGBA8}};
static constexpr rx::FastCopyFunctionMap BGRACopyFunctions = {{&BGRAEntry, 1}};
static constexpr rx::FastCopyFunctionMap NoCopyFunctions;

const Format gFormatInfoTable[] = {{
    // clang-format off
    {{ FormatID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false, false, gl::VertexAttribType::InvalidEnum }},
{angle_format_info_cases}    // clang-format on
}};

// static
FormatID Format::InternalFormatToID(GLenum internalFormat)
{{
    switch (internalFormat)
    {{
{angle_format_switch}
    }}
}}

const Format *GetFormatInfoTable()
{{
    return gFormatInfoTable;
}}
}}  // namespace angle
"""


def ceil_int(value, mod):
    assert mod > 0 and value > 0, 'integer modulation should be larger than 0'
    return (value + mod - 1) / mod


def is_depth_stencil(angle_format):
    if not 'channels' in angle_format or not angle_format['channels']:
        return False
    return 'd' in angle_format['channels'] or 's' in angle_format['channels']


def get_component_suffix(angle_format):
    if angle_format['componentType'] == 'float':
        return 'F'
    if angle_format['componentType'] == 'int' or angle_format['componentType'] == 'snorm':
        return 'S'
    return ""


def get_channel_struct(angle_format):
    if 'bits' not in angle_format or angle_format['bits'] is None:
        return None
    if 'BLOCK' in angle_format['id']:
        return None
    if 'VERTEX' in angle_format['id']:
        return None

    bits = angle_format['bits']

    if 'channelStruct' in angle_format:
        return angle_format['channelStruct']

    struct_name = ''
    component_suffix = get_component_suffix(angle_format)

    for channel in angle_format['channels']:
        if channel == 'r':
            struct_name += 'R{}'.format(bits['R'])
        if channel == 'g':
            struct_name += 'G{}'.format(bits['G'])
        if channel == 'b':
            struct_name += 'B{}'.format(bits['B'])
        if channel == 'a':
            struct_name += 'A{}'.format(bits['A'])
        if channel == 'l':
            struct_name += 'L{}'.format(bits['L'])
        if channel == 'd':
            struct_name += 'D{}'.format(bits['D']) + component_suffix
        if channel == 's':
            struct_name += 'S{}'.format(bits['S'])
        if channel == 'x':
            struct_name += 'X{}'.format(bits['X'])

    if not is_depth_stencil(angle_format):
        struct_name += component_suffix

    return struct_name


def get_mip_generation_function(angle_format):
    channel_struct = get_channel_struct(angle_format)
    if is_depth_stencil(angle_format) or channel_struct == None \
            or "BLOCK" in angle_format["id"] or "VERTEX" in angle_format["id"]:
        return 'nullptr'
    return 'GenerateMip<' + channel_struct + '>'


def get_color_read_write_component_type(angle_format):
    component_type_map = {
        'uint': 'GLuint',
        'int': 'GLint',
        'unorm': 'GLfloat',
        'snorm': 'GLfloat',
        'float': 'GLfloat'
    }
    return component_type_map[angle_format['componentType']]


def get_color_read_function(angle_format):
    channel_struct = get_channel_struct(angle_format)
    if channel_struct == None:
        return 'nullptr'

    if is_depth_stencil(angle_format):
        return 'ReadDepthStencil<' + channel_struct + '>'

    read_component_type = get_color_read_write_component_type(angle_format)
    return 'ReadColor<' + channel_struct + ', ' + read_component_type + '>'


def get_color_write_function(angle_format):
    channel_struct = get_channel_struct(angle_format)
    if channel_struct == None:
        return 'nullptr'

    if is_depth_stencil(angle_format):
        return 'WriteDepthStencil<' + channel_struct + '>'

    write_component_type = get_color_read_write_component_type(angle_format)
    return 'WriteColor<' + channel_struct + ', ' + write_component_type + '>'


format_entry_template = """    {{ FormatID::{id}, {glInternalFormat}, {fboImplementationInternalFormat}, {mipGenerationFunction}, {fastCopyFunctions}, {colorReadFunction}, {colorWriteFunction}, {namedComponentType}, {R}, {G}, {B}, {A}, {L}, {D}, {S}, {pixelBytes}, {componentAlignmentMask}, {isBlock}, {isFixed}, {isScaled}, {isSRGB}, {vertexAttribType} }},
"""


def get_named_component_type(component_type):
    if component_type == "snorm":
        return "GL_SIGNED_NORMALIZED"
    elif component_type == "unorm":
        return "GL_UNSIGNED_NORMALIZED"
    elif component_type == "float":
        return "GL_FLOAT"
    elif component_type == "uint":
        return "GL_UNSIGNED_INT"
    elif component_type == "int":
        return "GL_INT"
    elif component_type == "none":
        return "GL_NONE"
    else:
        raise ValueError("Unknown component type for " + component_type)


def get_component_alignment_mask(channels, bits):
    if channels == None or bits == None:
        return "std::numeric_limits<GLuint>::max()"
    bitness = bits[channels[0].upper()]
    for channel in channels:
        if channel not in "rgba":
            return "std::numeric_limits<GLuint>::max()"
        # Can happen for RGB10A2 formats.
        if bits[channel.upper()] != bitness:
            return "std::numeric_limits<GLuint>::max()"
    component_bytes = (int(bitness) >> 3)

    if component_bytes == 1:
        return "0"
    elif component_bytes == 2:
        return "1"
    elif component_bytes == 4:
        return "3"
    else:
        # Can happen for 4-bit RGBA.
        return "std::numeric_limits<GLuint>::max()"


def get_vertex_attrib_type(format_id):

    has_u = "_U" in format_id
    has_s = "_S" in format_id
    has_float = "_FLOAT" in format_id
    has_fixed = "_FIXED" in format_id
    has_r8 = "R8" in format_id
    has_r16 = "R16" in format_id
    has_r32 = "R32" in format_id
    has_r10 = "R10" in format_id
    has_vertex = "VERTEX" in format_id

    if has_fixed:
        return "Fixed"

    if has_float:
        return "HalfFloat" if has_r16 else "Float"

    if has_r8:
        return "Byte" if has_s else "UnsignedByte"

    if has_r10:
        if has_vertex:
            return "Int1010102" if has_s else "UnsignedInt1010102"
        else:
            return "Int2101010" if has_s else "UnsignedInt2101010"

    if has_r16:
        return "Short" if has_s else "UnsignedShort"

    if has_r32:
        return "Int" if has_s else "UnsignedInt"

    # Many ANGLE formats don't correspond with vertex formats.
    return "InvalidEnum"


def bool_str(cond):
    return "true" if cond else "false"


def json_to_table_data(format_id, json, angle_to_gl):

    table_data = ""

    parsed = {
        "id": format_id,
        "fastCopyFunctions": "NoCopyFunctions",
    }

    for k, v in json.iteritems():
        parsed[k] = v

    if "glInternalFormat" not in parsed:
        parsed["glInternalFormat"] = angle_to_gl[format_id]

    if "fboImplementationInternalFormat" not in parsed:
        parsed["fboImplementationInternalFormat"] = parsed["glInternalFormat"]

    if "componentType" not in parsed:
        parsed["componentType"] = angle_format.get_component_type(format_id)

    if "channels" not in parsed:
        parsed["channels"] = angle_format.get_channels(format_id)

    if "bits" not in parsed:
        parsed["bits"] = angle_format.get_bits(format_id)

    # Derived values.
    parsed["mipGenerationFunction"] = get_mip_generation_function(parsed)
    parsed["colorReadFunction"] = get_color_read_function(parsed)
    parsed["colorWriteFunction"] = get_color_write_function(parsed)

    for channel in angle_format.kChannels:
        if parsed["bits"] != None and channel in parsed["bits"]:
            parsed[channel] = parsed["bits"][channel]
        else:
            parsed[channel] = "0"

    parsed["namedComponentType"] = get_named_component_type(parsed["componentType"])

    if format_id == "B8G8R8A8_UNORM":
        parsed["fastCopyFunctions"] = "BGRACopyFunctions"

    is_block = format_id.endswith("_BLOCK")

    pixel_bytes = 0
    if is_block:
        assert 'blockPixelBytes' in parsed, \
            'Compressed format %s requires its block size to be specified in angle_format_data.json' % \
                format_id
        pixel_bytes = parsed['blockPixelBytes']
    else:
        sum_of_bits = 0
        for channel in angle_format.kChannels:
            sum_of_bits += int(parsed[channel])
        pixel_bytes = ceil_int(sum_of_bits, 8)
    parsed["pixelBytes"] = pixel_bytes
    parsed["componentAlignmentMask"] = get_component_alignment_mask(parsed["channels"],
                                                                    parsed["bits"])
    parsed["isBlock"] = bool_str(is_block)
    parsed["isFixed"] = bool_str("FIXED" in format_id)
    parsed["isScaled"] = bool_str("SCALED" in format_id)
    parsed["isSRGB"] = bool_str("SRGB" in format_id)

    parsed["vertexAttribType"] = "gl::VertexAttribType::" + get_vertex_attrib_type(format_id)

    return format_entry_template.format(**parsed)


# For convenience of the Vulkan backend, place depth/stencil formats first.  This allows
# depth/stencil format IDs to be placed in only a few bits.
def sorted_ds_first(all_angle):
    ds_sorted = []
    color_sorted = []
    for format_id in sorted(all_angle):
        if format_id == 'NONE':
            continue
        if format_id[0] == 'D' or format_id[0] == 'S':
            ds_sorted.append(format_id)
        else:
            color_sorted.append(format_id)

    return ds_sorted + color_sorted


def parse_angle_format_table(all_angle, json_data, angle_to_gl):
    table_data = ''
    for format_id in sorted_ds_first(all_angle):
        assert (format_id != 'NONE')
        format_info = json_data[format_id] if format_id in json_data else {}
        table_data += json_to_table_data(format_id, format_info, angle_to_gl)

    return table_data


def gen_enum_string(all_angle):
    enum_data = '    NONE'
    for format_id in sorted_ds_first(all_angle):
        assert (format_id != 'NONE')
        enum_data += ',\n    ' + format_id
    return enum_data


case_template = """        case {gl_format}:
            return FormatID::{angle_format};
"""


def gen_map_switch_string(gl_to_angle):
    switch_data = ''
    for gl_format in sorted(gl_to_angle.keys()):
        angle_format = gl_to_angle[gl_format]
        switch_data += case_template.format(gl_format=gl_format, angle_format=angle_format)
    switch_data += "        default:\n"
    switch_data += "            return FormatID::NONE;"
    return switch_data


def main():

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['angle_format.py', 'angle_format_data.json', 'angle_format_map.json']
        outputs = ['Format_table_autogen.cpp', 'FormatID_autogen.h']

        if sys.argv[1] == 'inputs':
            print ','.join(inputs)
        elif sys.argv[1] == 'outputs':
            print ','.join(outputs)
        else:
            print('Invalid script parameters')
            return 1
        return 0

    gl_to_angle = angle_format.load_forward_table('angle_format_map.json')
    angle_to_gl = angle_format.load_inverse_table('angle_format_map.json')
    data_source_name = 'angle_format_data.json'
    json_data = angle_format.load_json(data_source_name)
    all_angle = angle_to_gl.keys()

    angle_format_cases = parse_angle_format_table(all_angle, json_data, angle_to_gl)
    switch_data = gen_map_switch_string(gl_to_angle)
    output_cpp = template_autogen_inl.format(
        script_name=sys.argv[0],
        copyright_year=date.today().year,
        angle_format_info_cases=angle_format_cases,
        angle_format_switch=switch_data,
        data_source_name=data_source_name)
    with open('Format_table_autogen.cpp', 'wt') as out_file:
        out_file.write(output_cpp)
        out_file.close()

    enum_data = gen_enum_string(all_angle)
    num_angle_formats = len(all_angle)
    output_h = template_autogen_h.format(
        script_name=sys.argv[0],
        copyright_year=date.today().year,
        angle_format_enum=enum_data,
        data_source_name=data_source_name,
        num_angle_formats=num_angle_formats)
    with open('FormatID_autogen.h', 'wt') as out_file:
        out_file.write(output_h)
        out_file.close()

    return 0


if __name__ == '__main__':
    sys.exit(main())
