//
// Copyright 2017 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.
//
// ExtensionBehavior.cpp: Extension name enumeration and data structures for storing extension
// behavior.

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "compiler/translator/ExtensionBehavior.h"

#include "common/debug.h"

#include <string.h>

// clang-format off
// Extension Name, Min ESSL Version, Max ESSL Version
//
// Note that OES_EGL_image_external and OES_texture_3D are ESSL 100 only extensions, but one app has
// been found that uses them on GLSL 310.  http://issuetracker.google.com/285871779
// Similarly, other applications have been found to use OES_EGL_image_external on GLSL 320. Refer to
// http://issuetracker.google.com/452565020 for details.
//
// Note that OES_texture_storage_multisample_2d_array officially requires ESSL 310
// but ANGLE is able to support it with ESSL 300 in most cases.
#define LIST_EXTENSIONS(OP)                                      \
    OP(ANDROID_extension_pack_es31a,                   310, 320) \
    OP(ANGLE_base_vertex_base_instance_shader_builtin, 300, 320) \
    OP(ANGLE_clip_cull_distance,                       300, 320) \
    OP(ANGLE_multi_draw,                               100, 320) \
    OP(ANGLE_shader_pixel_local_storage,               300, 320) \
    OP(ANGLE_texture_multisample,                      300, 320) \
    OP(APPLE_clip_distance,                            100, 320) \
    OP(ARB_texture_rectangle,                          100, 320) \
    OP(ARM_shader_framebuffer_fetch,                   100, 320) \
    OP(ARM_shader_framebuffer_fetch_depth_stencil,     100, 320) \
    OP(EXT_blend_func_extended,                        100, 320) \
    OP(EXT_clip_cull_distance,                         300, 320) \
    OP(EXT_conservative_depth,                         300, 320) \
    OP(EXT_draw_buffers,                               100, 100) \
    OP(EXT_frag_depth,                                 100, 100) \
    OP(EXT_fragment_shading_rate,                      310, 320) \
    OP(EXT_fragment_shading_rate_primitive,            310, 320) \
    OP(EXT_geometry_shader,                            310, 320) \
    OP(OES_geometry_shader,                            310, 320) \
    OP(OES_shader_io_blocks,                           310, 320) \
    OP(EXT_shader_io_blocks,                           310, 320) \
    OP(EXT_gpu_shader5,                                310, 320) \
    OP(OES_gpu_shader5,                                310, 320) \
    OP(EXT_primitive_bounding_box,                     310, 320) \
    OP(OES_primitive_bounding_box,                     310, 320) \
    OP(EXT_separate_shader_objects,                    100, 320) \
    OP(EXT_shader_framebuffer_fetch,                   100, 320) \
    OP(EXT_shader_framebuffer_fetch_non_coherent,      100, 320) \
    OP(EXT_shader_non_constant_global_initializers,    100, 320) \
    OP(EXT_shader_texture_lod,                         100, 100) \
    OP(EXT_shadow_samplers,                            100, 100) \
    OP(EXT_tessellation_shader,                        310, 320) \
    OP(OES_tessellation_shader,                        310, 320) \
    OP(EXT_texture_buffer,                             310, 320) \
    OP(EXT_texture_cube_map_array,                     310, 320) \
    OP(EXT_texture_query_lod,                          300, 320) \
    OP(EXT_texture_shadow_lod,                         300, 320) \
    OP(EXT_YUV_target,                                 300, 320) \
    OP(KHR_blend_equation_advanced,                    100, 320) \
    OP(NV_EGL_stream_consumer_external,                100, 320) \
    OP(NV_shader_noperspective_interpolation,          300, 320) \
    OP(OES_EGL_image_external,                         100, 320) \
    OP(OES_EGL_image_external_essl3,                   300, 320) \
    OP(OES_sample_variables,                           300, 320) \
    OP(OES_shader_multisample_interpolation,           300, 320) \
    OP(OES_shader_image_atomic,                        310, 320) \
    OP(OES_standard_derivatives,                       100, 100) \
    OP(OES_texture_3D,                                 100, 310) \
    OP(OES_texture_buffer,                             310, 320) \
    OP(OES_texture_cube_map_array,                     310, 320) \
    OP(OES_texture_storage_multisample_2d_array,       300, 320) \
    OP(OVR_multiview,                                  300, 320) \
    OP(OVR_multiview2,                                 300, 320) \
    OP(WEBGL_video_texture,                            100, 320)
// clang-format on

namespace sh
{

#define RETURN_EXTENSION_NAME_CASE(ext, min_version, max_version) \
    case TExtension::ext:                                         \
        return "GL_" #ext;

const char *GetExtensionNameString(TExtension extension)
{
    switch (extension)
    {
        LIST_EXTENSIONS(RETURN_EXTENSION_NAME_CASE)
        default:
            UNREACHABLE();
            return "";
    }
}

#define RETURN_EXTENSION_IF_NAME_MATCHES(ext, min_version, max_version) \
    if (strcmp(extWithoutGLPrefix, #ext) == 0)                          \
    {                                                                   \
        return TExtension::ext;                                         \
    }

TExtension GetExtensionByName(const char *extension)
{
    // If first characters of the extension don't equal "GL_", early out.
    if (strncmp(extension, "GL_", 3) != 0)
    {
        return TExtension::UNDEFINED;
    }
    const char *extWithoutGLPrefix = extension + 3;

    LIST_EXTENSIONS(RETURN_EXTENSION_IF_NAME_MATCHES)

    return TExtension::UNDEFINED;
}

#define RETURN_VERSION_CHECK(ext, min_version, max_version) \
    case TExtension::ext:                                   \
        return (version >= min_version) && (version <= max_version);

bool CheckExtensionVersion(TExtension extension, int version)
{
    switch (extension)
    {
        LIST_EXTENSIONS(RETURN_VERSION_CHECK)
        default:
            UNREACHABLE();
            return false;
    }
}

const char *GetBehaviorString(TBehavior b)
{
    switch (b)
    {
        case EBhRequire:
            return "require";
        case EBhEnable:
            return "enable";
        case EBhWarn:
            return "warn";
        case EBhDisable:
            return "disable";
        default:
            return nullptr;
    }
}

bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension)
{
    ASSERT(extension != TExtension::UNDEFINED);
    auto iter = extBehavior.find(extension);
    return iter != extBehavior.end() &&
           (iter->second == EBhEnable || iter->second == EBhRequire || iter->second == EBhWarn);
}

}  // namespace sh
