//
// Copyright 2002 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.
//

// Config.cpp: Implements the egl::Config class, describing the format, type
// and size for an egl::Surface. Implements EGLConfig and related functionality.
// [EGL 1.5] section 3.4 page 19.

#include "libANGLE/Config.h"
#include "libANGLE/AttributeMap.h"

#include <algorithm>
#include <vector>

#include <EGL/eglext.h>
#include "angle_gl.h"

#include "common/debug.h"

namespace egl
{

Config::Config()
    : renderTargetFormat(GL_NONE),
      depthStencilFormat(GL_NONE),
      bufferSize(0),
      redSize(0),
      greenSize(0),
      blueSize(0),
      luminanceSize(0),
      alphaSize(0),
      alphaMaskSize(0),
      bindToTextureRGB(EGL_FALSE),
      bindToTextureRGBA(EGL_FALSE),
      bindToTextureTarget(EGL_TEXTURE_2D),
      colorBufferType(EGL_RGB_BUFFER),
      configCaveat(EGL_NONE),
      configID(0),
      conformant(0),
      depthSize(0),
      level(0),
      matchNativePixmap(EGL_FALSE),
      maxPBufferWidth(0),
      maxPBufferHeight(0),
      maxPBufferPixels(0),
      maxSwapInterval(0),
      minSwapInterval(0),
      nativeRenderable(EGL_FALSE),
      nativeVisualID(0),
      nativeVisualType(0),
      renderableType(0),
      sampleBuffers(0),
      samples(0),
      stencilSize(0),
      surfaceType(0),
      transparentType(EGL_NONE),
      transparentRedValue(0),
      transparentGreenValue(0),
      transparentBlueValue(0),
      optimalOrientation(0),
      colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
      recordable(EGL_FALSE),
      framebufferTarget(EGL_FALSE),  // TODO: http://anglebug.com/42262839
      yInverted(EGL_FALSE)
{}

Config::~Config() {}

Config::Config(const Config &other) = default;

Config &Config::operator=(const Config &other) = default;

ConfigSet::ConfigSet() = default;

ConfigSet::ConfigSet(const ConfigSet &other) = default;

ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default;

ConfigSet::~ConfigSet() = default;

EGLint ConfigSet::add(const Config &config)
{
    // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
    EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;

    Config copyConfig(config);
    copyConfig.configID = id;
    mConfigs.insert(std::make_pair(id, copyConfig));

    return id;
}

const Config &ConfigSet::get(EGLint id) const
{
    ASSERT(mConfigs.find(id) != mConfigs.end());
    return mConfigs.find(id)->second;
}

void ConfigSet::clear()
{
    mConfigs.clear();
}

size_t ConfigSet::size() const
{
    return mConfigs.size();
}

bool ConfigSet::contains(const Config *config) const
{
    for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
    {
        const Config &item = i->second;
        if (config == &item)
        {
            return true;
        }
    }

    return false;
}

// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5]
// section 3.4.1.2 page 28.
class ConfigSorter
{
  public:
    explicit ConfigSorter(const AttributeMap &attributeMap)
        : mWantRed(false),
          mWantGreen(false),
          mWantBlue(false),
          mWantAlpha(false),
          mWantLuminance(false)
    {
        scanForWantedComponents(attributeMap);
    }

    bool operator()(const Config *x, const Config *y) const { return (*this)(*x, *y); }

    bool operator()(const Config &x, const Config &y) const
    {
#define SORT(attribute)                       \
    do                                        \
    {                                         \
        if (x.attribute != y.attribute)       \
            return x.attribute < y.attribute; \
    } while (0)

        static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG,
                      "Unexpected EGL enum value.");
        SORT(configCaveat);

        static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
                      "Unexpected order of EGL enums.");
        SORT(colorComponentType);

        static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
        SORT(colorBufferType);

        // By larger total number of color bits, only considering those that are requested to be >
        // 0.
        EGLint xComponentsSize = wantedComponentsSize(x);
        EGLint yComponentsSize = wantedComponentsSize(y);
        if (xComponentsSize != yComponentsSize)
        {
            return xComponentsSize > yComponentsSize;
        }

        SORT(bufferSize);
        SORT(sampleBuffers);
        SORT(samples);
        SORT(depthSize);
        SORT(stencilSize);
        SORT(alphaMaskSize);
        SORT(nativeVisualType);
        SORT(configID);

#undef SORT

        return false;
    }

  private:
    static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component)
    {
        // [EGL 1.5] section 3.4.1.2 page 30
        // Sorting rule #3: by larger total number of color bits, not considering
        // components that are 0 or don't-care.
        EGLAttrib value = attributeMap.get(component, 0);
        return value != 0 && value != EGL_DONT_CARE;
    }

    void scanForWantedComponents(const AttributeMap &attributeMap)
    {
        mWantRed       = wantsComponent(attributeMap, EGL_RED_SIZE);
        mWantGreen     = wantsComponent(attributeMap, EGL_GREEN_SIZE);
        mWantBlue      = wantsComponent(attributeMap, EGL_BLUE_SIZE);
        mWantAlpha     = wantsComponent(attributeMap, EGL_ALPHA_SIZE);
        mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE);
    }

    EGLint wantedComponentsSize(const Config &config) const
    {
        EGLint total = 0;

        if (mWantRed)
            total += config.redSize;
        if (mWantGreen)
            total += config.greenSize;
        if (mWantBlue)
            total += config.blueSize;
        if (mWantAlpha)
            total += config.alphaSize;
        if (mWantLuminance)
            total += config.luminanceSize;

        return total;
    }

    bool mWantRed;
    bool mWantGreen;
    bool mWantBlue;
    bool mWantAlpha;
    bool mWantLuminance;
};

std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap) const
{
    std::vector<const Config *> result;

    // If EGL_CONFIG_ID is included, all other attributes should be ignored.
    if (attributeMap.contains(EGL_CONFIG_ID))
    {
        result.push_back(&ConfigSet::get(attributeMap.getAsInt(EGL_CONFIG_ID)));
        return result;
    }

    result.reserve(mConfigs.size());

    for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
    {
        const Config &config = configIter->second;
        bool match           = true;

        for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
        {
            EGLAttrib attributeKey   = attribIter->first;
            EGLAttrib attributeValue = attribIter->second;

            if (attributeValue == EGL_DONT_CARE)
            {
                continue;
            }

            switch (attributeKey)
            {
                case EGL_BUFFER_SIZE:
                    match = config.bufferSize >= attributeValue;
                    break;
                case EGL_ALPHA_SIZE:
                    match = config.alphaSize >= attributeValue;
                    break;
                case EGL_BLUE_SIZE:
                    match = config.blueSize >= attributeValue;
                    break;
                case EGL_GREEN_SIZE:
                    match = config.greenSize >= attributeValue;
                    break;
                case EGL_RED_SIZE:
                    match = config.redSize >= attributeValue;
                    break;
                case EGL_DEPTH_SIZE:
                    match = config.depthSize >= attributeValue;
                    break;
                case EGL_STENCIL_SIZE:
                    match = config.stencilSize >= attributeValue;
                    break;
                case EGL_CONFIG_CAVEAT:
                    match = config.configCaveat == static_cast<EGLenum>(attributeValue);
                    break;
                case EGL_LEVEL:
                    match = config.level == attributeValue;
                    break;
                case EGL_NATIVE_RENDERABLE:
                    match = config.nativeRenderable == static_cast<EGLBoolean>(attributeValue);
                    break;
                case EGL_NATIVE_VISUAL_TYPE:
                    match = config.nativeVisualType == attributeValue;
                    break;
                case EGL_SAMPLES:
                    match = config.samples >= attributeValue;
                    break;
                case EGL_SAMPLE_BUFFERS:
                    match = config.sampleBuffers >= attributeValue;
                    break;
                case EGL_SURFACE_TYPE:
                    match = (config.surfaceType & attributeValue) == attributeValue;
                    break;
                case EGL_TRANSPARENT_TYPE:
                    match = config.transparentType == static_cast<EGLenum>(attributeValue);
                    break;
                case EGL_TRANSPARENT_BLUE_VALUE:
                    if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
                    {
                        match = config.transparentBlueValue == attributeValue;
                    }
                    break;
                case EGL_TRANSPARENT_GREEN_VALUE:
                    if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
                    {
                        match = config.transparentGreenValue == attributeValue;
                    }
                    break;
                case EGL_TRANSPARENT_RED_VALUE:
                    if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
                    {
                        match = config.transparentRedValue == attributeValue;
                    }
                    break;
                case EGL_BIND_TO_TEXTURE_RGB:
                    match = config.bindToTextureRGB == static_cast<EGLBoolean>(attributeValue);
                    break;
                case EGL_BIND_TO_TEXTURE_RGBA:
                    match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue);
                    break;
                case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
                    match = config.bindToTextureTarget == static_cast<EGLenum>(attributeValue);
                    break;
                case EGL_MIN_SWAP_INTERVAL:
                    match = config.minSwapInterval == attributeValue;
                    break;
                case EGL_MAX_SWAP_INTERVAL:
                    match = config.maxSwapInterval == attributeValue;
                    break;
                case EGL_LUMINANCE_SIZE:
                    match = config.luminanceSize >= attributeValue;
                    break;
                case EGL_ALPHA_MASK_SIZE:
                    match = config.alphaMaskSize >= attributeValue;
                    break;
                case EGL_COLOR_BUFFER_TYPE:
                    match = config.colorBufferType == static_cast<EGLenum>(attributeValue);
                    break;
                case EGL_RENDERABLE_TYPE:
                    match = (config.renderableType & attributeValue) == attributeValue;
                    break;
                case EGL_MATCH_NATIVE_PIXMAP:
                    match = false;
                    UNIMPLEMENTED();
                    break;
                case EGL_CONFORMANT:
                    match = (config.conformant & attributeValue) == attributeValue;
                    break;
                case EGL_MAX_PBUFFER_WIDTH:
                    match = config.maxPBufferWidth >= attributeValue;
                    break;
                case EGL_MAX_PBUFFER_HEIGHT:
                    match = config.maxPBufferHeight >= attributeValue;
                    break;
                case EGL_MAX_PBUFFER_PIXELS:
                    match = config.maxPBufferPixels >= attributeValue;
                    break;
                case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
                    match = config.optimalOrientation == attributeValue;
                    break;
                case EGL_COLOR_COMPONENT_TYPE_EXT:
                    match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
                    break;
                case EGL_RECORDABLE_ANDROID:
                    match = config.recordable == static_cast<EGLBoolean>(attributeValue);
                    break;
                case EGL_FRAMEBUFFER_TARGET_ANDROID:
                    match = config.framebufferTarget == static_cast<EGLBoolean>(attributeValue);
                    break;
                case EGL_Y_INVERTED_NOK:
                    match = config.yInverted == static_cast<EGLBoolean>(attributeValue);
                    break;
                case EGL_MATCH_FORMAT_KHR:
                    if (attributeValue == EGL_NONE)
                    {
                        match = (config.surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == 0;
                    }
                    else
                    {
                        match = config.matchFormat == attributeValue;
                    }
                    break;
                default:
                    UNREACHABLE();
            }

            if (!match)
            {
                break;
            }
        }

        if (match)
        {
            result.push_back(&config);
        }
    }

    // Sort the result
    std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));

    return result;
}

ConfigSet::ConfigMap::iterator ConfigSet::begin()
{
    return mConfigs.begin();
}

ConfigSet::ConfigMap::iterator ConfigSet::end()
{
    return mConfigs.end();
}
}  // namespace egl
