//
// Copyright (c) 2002-2010 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.4] section 3.4 page 15.

#include "libEGL/Config.h"

#include <algorithm>
#include <vector>

#include "common/debug.h"

using namespace std;

namespace egl
{
Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample)
    : mDisplayMode(displayMode), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
{
    set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample);
}

void Config::setDefaults()
{
    mBufferSize = 0;
    mRedSize = 0;
    mGreenSize = 0;
    mBlueSize = 0;
    mLuminanceSize = 0;
    mAlphaSize = 0;
    mAlphaMaskSize = 0;
    mBindToTextureRGB = EGL_DONT_CARE;
    mBindToTextureRGBA = EGL_DONT_CARE;
    mColorBufferType = EGL_RGB_BUFFER;
    mConfigCaveat = EGL_DONT_CARE;
    mConfigID = EGL_DONT_CARE;
    mConformant = 0;
    mDepthSize = 0;
    mLevel = 0;
    mMatchNativePixmap = EGL_NONE;
    mMaxPBufferWidth = 0;
    mMaxPBufferHeight = 0;
    mMaxPBufferPixels = 0;
    mMaxSwapInterval = EGL_DONT_CARE;
    mMinSwapInterval = EGL_DONT_CARE;
    mNativeRenderable = EGL_DONT_CARE;
    mNativeVisualID = 0;
    mNativeVisualType = EGL_DONT_CARE;
    mRenderableType = EGL_OPENGL_ES_BIT;
    mSampleBuffers = 0;
    mSamples = 0;
    mStencilSize = 0;
    mSurfaceType = EGL_WINDOW_BIT;
    mTransparentType = EGL_NONE;
    mTransparentRedValue = EGL_DONT_CARE;
    mTransparentGreenValue = EGL_DONT_CARE;
    mTransparentBlueValue = EGL_DONT_CARE;
}

void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample)
{
    switch (renderTargetFormat)
    {
      case D3DFMT_A1R5G5B5:
        mBufferSize = 16;
        mRedSize = 5;
        mGreenSize = 5;
        mBlueSize = 5;
        mAlphaSize = 1;
        break;
      case D3DFMT_A2R10G10B10:
        mBufferSize = 32;
        mRedSize = 10;
        mGreenSize = 10;
        mBlueSize = 10;
        mAlphaSize = 2;
        break;
      case D3DFMT_A8R8G8B8:
        mBufferSize = 32;
        mRedSize = 8;
        mGreenSize = 8;
        mBlueSize = 8;
        mAlphaSize = 8;
        break;
      case D3DFMT_R5G6B5:
        mBufferSize = 16;
        mRedSize = 5;
        mGreenSize = 6;
        mBlueSize = 5;
        mAlphaSize = 0;
        break;
      case D3DFMT_X8R8G8B8:
        mBufferSize = 32;
        mRedSize = 8;
        mGreenSize = 8;
        mBlueSize = 8;
        mAlphaSize = 0;
        break;
      default:
        UNREACHABLE();   // Other formats should not be valid
    }

    mLuminanceSize = 0;
    mAlphaMaskSize = 0;
    mBindToTextureRGB = EGL_FALSE;
    mBindToTextureRGBA = EGL_FALSE;
    mColorBufferType = EGL_RGB_BUFFER;
    mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG;
    mConfigID = 0;
    mConformant = EGL_OPENGL_ES2_BIT;

    switch (depthStencilFormat)
    {
//    case D3DFMT_D16_LOCKABLE:
//      mDepthSize = 16;
//      mStencilSize = 0;
//      break;
      case D3DFMT_D32:
        mDepthSize = 32;
        mStencilSize = 0;
        break;
      case D3DFMT_D15S1:
        mDepthSize = 15;
        mStencilSize = 1;
        break;
      case D3DFMT_D24S8:
        mDepthSize = 24;
        mStencilSize = 8;
        break;
      case D3DFMT_D24X8:
        mDepthSize = 24;
        mStencilSize = 0;
        break;
      case D3DFMT_D24X4S4:
        mDepthSize = 24;
        mStencilSize = 4;
        break;
      case D3DFMT_D16:
        mDepthSize = 16;
        mStencilSize = 0;
        break;
//    case D3DFMT_D32F_LOCKABLE:
//      mDepthSize = 32;
//      mStencilSize = 0;
//      break;
//    case D3DFMT_D24FS8:
//      mDepthSize = 24;
//      mStencilSize = 8;
//      break;
      default:
        UNREACHABLE();
    }

    mLevel = 0;
    mMatchNativePixmap = EGL_NONE;
    mMaxPBufferWidth = 0;
    mMaxPBufferHeight = 0;
    mMaxPBufferPixels = 0;
    mMaxSwapInterval = maxInterval;
    mMinSwapInterval = minInterval;
    mNativeRenderable = EGL_FALSE;
    mNativeVisualID = 0;
    mNativeVisualType = 0;
    mRenderableType = EGL_OPENGL_ES2_BIT;
    mSampleBuffers = multiSample ? 1 : 0;
    mSamples = multiSample;
    mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
    mTransparentType = EGL_NONE;
    mTransparentRedValue = 0;
    mTransparentGreenValue = 0;
    mTransparentBlueValue = 0;
}

EGLConfig Config::getHandle() const
{
    return (EGLConfig)(size_t)mConfigID;
}

SortConfig::SortConfig(const EGLint *attribList)
    : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
{
    scanForWantedComponents(attribList);
}

void SortConfig::scanForWantedComponents(const EGLint *attribList)
{
    // [EGL] section 3.4.1 page 24
    // Sorting rule #3: by larger total number of color bits, not considering
    // components that are 0 or don't-care.
    for (const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
    {
        if (attr[1] != 0 && attr[1] != EGL_DONT_CARE)
        {
            switch (attr[0])
            {
              case EGL_RED_SIZE:       mWantRed = true; break;
              case EGL_GREEN_SIZE:     mWantGreen = true; break;
              case EGL_BLUE_SIZE:      mWantBlue = true; break;
              case EGL_ALPHA_SIZE:     mWantAlpha = true; break;
              case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
            }
        }
    }
}

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

    if (mWantRed)       total += config.mRedSize;
    if (mWantGreen)     total += config.mGreenSize;
    if (mWantBlue)      total += config.mBlueSize;
    if (mWantAlpha)     total += config.mAlphaSize;
    if (mWantLuminance) total += config.mLuminanceSize;

    return total;
}

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

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

    META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
    SORT(mConfigCaveat);

    META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
    SORT(mColorBufferType);

    // 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(mBufferSize);
    SORT(mSampleBuffers);
    SORT(mSamples);
    SORT(mDepthSize);
    SORT(mStencilSize);
    SORT(mAlphaMaskSize);
    SORT(mNativeVisualType);
    SORT(mConfigID);

    #undef SORT

    return false;
}

// We'd like to use SortConfig to also eliminate duplicate configs.
// This works as long as we never have two configs with different per-RGB-component layouts,
// but the same total.
// 5551 and 565 are different because R+G+B is different.
// 5551 and 555 are different because bufferSize is different.
const EGLint ConfigSet::mSortAttribs[] =
{
    EGL_RED_SIZE, 1,
    EGL_GREEN_SIZE, 1,
    EGL_BLUE_SIZE, 1,
    EGL_LUMINANCE_SIZE, 1,
    // BUT NOT ALPHA
    EGL_NONE
};

ConfigSet::ConfigSet()
    : mSet(SortConfig(mSortAttribs))
{
}

void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample)
{
    Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);

    mSet.insert(config);
}

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

bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
{
    vector<const Config*> passed;
    passed.reserve(mSet.size());

    for (Iterator config = mSet.begin(); config != mSet.end(); config++)
    {
        bool match = true;
        const EGLint *attribute = attribList;

        while (attribute[0] != EGL_NONE)
        {
            switch (attribute[0])
            {
              case EGL_BUFFER_SIZE:               match = config->mBufferSize >= attribute[1];                      break;
              case EGL_ALPHA_SIZE:                match = config->mAlphaSize >= attribute[1];                       break;
              case EGL_BLUE_SIZE:                 match = config->mBlueSize >= attribute[1];                        break;
              case EGL_GREEN_SIZE:                match = config->mGreenSize >= attribute[1];                       break;
              case EGL_RED_SIZE:                  match = config->mRedSize >= attribute[1];                         break;
              case EGL_DEPTH_SIZE:                match = config->mDepthSize >= attribute[1];                       break;
              case EGL_STENCIL_SIZE:              match = config->mStencilSize >= attribute[1];                     break;
              case EGL_CONFIG_CAVEAT:             match = config->mConfigCaveat == attribute[1];                    break;
              case EGL_CONFIG_ID:                 match = config->mConfigID == attribute[1];                        break;
              case EGL_LEVEL:                     match = config->mLevel >= attribute[1];                           break;
              case EGL_NATIVE_RENDERABLE:         match = config->mNativeRenderable == attribute[1];                break;
              case EGL_NATIVE_VISUAL_TYPE:        match = config->mNativeVisualType == attribute[1];                break;
              case EGL_SAMPLES:                   match = config->mSamples >= attribute[1];                         break;
              case EGL_SAMPLE_BUFFERS:            match = config->mSampleBuffers >= attribute[1];                   break;
              case EGL_SURFACE_TYPE:              match = (config->mSurfaceType & attribute[1]) == attribute[1];    break;
              case EGL_TRANSPARENT_TYPE:          match = config->mTransparentType == attribute[1];                 break;
              case EGL_TRANSPARENT_BLUE_VALUE:    match = config->mTransparentBlueValue == attribute[1];            break;
              case EGL_TRANSPARENT_GREEN_VALUE:   match = config->mTransparentGreenValue == attribute[1];           break;
              case EGL_TRANSPARENT_RED_VALUE:     match = config->mTransparentRedValue == attribute[1];             break;
              case EGL_BIND_TO_TEXTURE_RGB:       match = config->mBindToTextureRGB == attribute[1];                break;
              case EGL_BIND_TO_TEXTURE_RGBA:      match = config->mBindToTextureRGBA == attribute[1];               break;
              case EGL_MIN_SWAP_INTERVAL:         match = config->mMinSwapInterval == attribute[1];                 break;
              case EGL_MAX_SWAP_INTERVAL:         match = config->mMaxSwapInterval == attribute[1];                 break;
              case EGL_LUMINANCE_SIZE:            match = config->mLuminanceSize >= attribute[1];                   break;
              case EGL_ALPHA_MASK_SIZE:           match = config->mAlphaMaskSize >= attribute[1];                   break;
              case EGL_COLOR_BUFFER_TYPE:         match = config->mColorBufferType == attribute[1];                 break;
              case EGL_RENDERABLE_TYPE:           match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
              case EGL_MATCH_NATIVE_PIXMAP:       match = false; UNIMPLEMENTED();                                   break;
              case EGL_CONFORMANT:                match = (config->mConformant & attribute[1]) == attribute[1];     break;
              default:
                return false;
            }

            if (!match)
            {
                break;
            }

            attribute += 2;
        }

        if (match)
        {
            passed.push_back(&*config);
        }
    }

    if (configs)
    {
        sort(passed.begin(), passed.end(), SortConfig(attribList));

        EGLint index;
        for (index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
        {
            configs[index] = passed[index]->getHandle();
        }

        *numConfig = index;
    }
    else
    {
        *numConfig = passed.size();
    }

    return true;
}

const egl::Config *ConfigSet::get(EGLConfig configHandle)
{
    for (Iterator config = mSet.begin(); config != mSet.end(); config++)
    {
        if (config->getHandle() == configHandle)
        {
            return &(*config);
        }
    }

    return NULL;
}
}
