// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// 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 "Config.h"

#include "common/debug.h"

#include <EGL/eglext.h>
#ifdef __ANDROID__
#include <system/graphics.h>
#endif

#include <string.h>
#include <algorithm>
#include <vector>

using namespace std;

namespace egl
{
Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
	: mDisplayFormat(displayFormat), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
{
	mBindToTextureRGB = EGL_FALSE;
	mBindToTextureRGBA = EGL_FALSE;

	// Initialize to a high value to lower the preference of formats for which there's no native support
	mNativeVisualID = 0x7FFFFFFF;

	switch(renderTargetFormat)
	{
	case sw::FORMAT_A1R5G5B5:
		mRedSize = 5;
		mGreenSize = 5;
		mBlueSize = 5;
		mAlphaSize = 1;
		break;
	case sw::FORMAT_A2R10G10B10:
		mRedSize = 10;
		mGreenSize = 10;
		mBlueSize = 10;
		mAlphaSize = 2;
		break;
	case sw::FORMAT_A8R8G8B8:
		mRedSize = 8;
		mGreenSize = 8;
		mBlueSize = 8;
		mAlphaSize = 8;
		mBindToTextureRGBA = EGL_TRUE;
		#ifdef __ANDROID__
			mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
		#else
			mNativeVisualID = 2;   // Arbitrary; prefer over ABGR
		#endif
		break;
	case sw::FORMAT_A8B8G8R8:
		mRedSize = 8;
		mGreenSize = 8;
		mBlueSize = 8;
		mAlphaSize = 8;
		mBindToTextureRGBA = EGL_TRUE;
		#ifdef __ANDROID__
			mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
		#endif
		break;
	case sw::FORMAT_R5G6B5:
		mRedSize = 5;
		mGreenSize = 6;
		mBlueSize = 5;
		mAlphaSize = 0;
		#ifdef __ANDROID__
			mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
		#endif
		break;
	case sw::FORMAT_X8R8G8B8:
		mRedSize = 8;
		mGreenSize = 8;
		mBlueSize = 8;
		mAlphaSize = 0;
		mBindToTextureRGB = EGL_TRUE;
		#ifdef __ANDROID__
			mNativeVisualID = 0x1FF;   // HAL_PIXEL_FORMAT_BGRX_8888
		#else
			mNativeVisualID = 1;   // Arbitrary; prefer over XBGR
		#endif
		break;
	case sw::FORMAT_X8B8G8R8:
		mRedSize = 8;
		mGreenSize = 8;
		mBlueSize = 8;
		mAlphaSize = 0;
		mBindToTextureRGB = EGL_TRUE;
		#ifdef __ANDROID__
			mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
		#endif
		break;
	default:
		UNREACHABLE(renderTargetFormat);
	}

	mLuminanceSize = 0;
	mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
	mAlphaMaskSize = 0;
	mColorBufferType = EGL_RGB_BUFFER;
	mConfigCaveat = EGL_NONE;
	mConfigID = 0;
	mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
		| EGL_OPENGL_ES3_BIT
#endif
		;

	switch(depthStencilFormat)
	{
	case sw::FORMAT_NULL:
		mDepthSize = 0;
		mStencilSize = 0;
		break;
//	case sw::FORMAT_D16_LOCKABLE:
//		mDepthSize = 16;
//		mStencilSize = 0;
//		break;
	case sw::FORMAT_D32:
		mDepthSize = 32;
		mStencilSize = 0;
		break;
//	case sw::FORMAT_D15S1:
//		mDepthSize = 15;
//		mStencilSize = 1;
//		break;
	case sw::FORMAT_D24S8:
		mDepthSize = 24;
		mStencilSize = 8;
		break;
	case sw::FORMAT_D24X8:
		mDepthSize = 24;
		mStencilSize = 0;
		break;
//	case sw::FORMAT_D24X4S4:
//		mDepthSize = 24;
//		mStencilSize = 4;
//		break;
	case sw::FORMAT_D16:
		mDepthSize = 16;
		mStencilSize = 0;
		break;
//	case sw::FORMAT_D32F_LOCKABLE:
//		mDepthSize = 32;
//		mStencilSize = 0;
//		break;
//	case sw::FORMAT_D24FS8:
//		mDepthSize = 24;
//		mStencilSize = 8;
//		break;
	default:
		UNREACHABLE(depthStencilFormat);
	}

	mLevel = 0;
	mMatchNativePixmap = EGL_NONE;
	mMaxPBufferWidth = 4096;
	mMaxPBufferHeight = 4096;
	mMaxPBufferPixels = mMaxPBufferWidth * mMaxPBufferHeight;
	mMaxSwapInterval = maxInterval;
	mMinSwapInterval = minInterval;
	mNativeRenderable = EGL_FALSE;
	mNativeVisualType = 0;
	mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT
#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
		| EGL_OPENGL_ES3_BIT
#endif
		;
	mSampleBuffers = (multiSample > 0) ? 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;

	mRecordableAndroid = EGL_TRUE;
	mFramebufferTargetAndroid = (displayFormat == renderTargetFormat) ? EGL_TRUE : EGL_FALSE;
}

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

// This ordering determines the config ID
bool CompareConfig::operator()(const Config &x, const Config &y) const
{
	#define SORT_SMALLER(attribute)                \
		if(x.attribute != y.attribute)             \
		{                                          \
			return x.attribute < y.attribute;      \
		}

	static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
	SORT_SMALLER(mConfigCaveat);

	static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
	SORT_SMALLER(mColorBufferType);

	SORT_SMALLER(mRedSize);
	SORT_SMALLER(mGreenSize);
	SORT_SMALLER(mBlueSize);
	SORT_SMALLER(mAlphaSize);

	SORT_SMALLER(mBufferSize);
	SORT_SMALLER(mSampleBuffers);
	SORT_SMALLER(mSamples);
	SORT_SMALLER(mDepthSize);
	SORT_SMALLER(mStencilSize);
	SORT_SMALLER(mAlphaMaskSize);
	SORT_SMALLER(mNativeVisualType);
	SORT_SMALLER(mNativeVisualID);

	#undef SORT_SMALLER

	// Strict ordering requires sorting all non-equal fields above
	assert(memcmp(&x, &y, sizeof(Config)) == 0);

	return false;
}

// Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
class SortConfig
{
public:
	explicit SortConfig(const EGLint *attribList);

	bool operator()(const Config *x, const Config *y) const;

private:
	EGLint wantedComponentsSize(const Config *config) const;

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

SortConfig::SortConfig(const EGLint *attribList)
	: mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
{
	// [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
{
	#define SORT_SMALLER(attribute)                \
		if(x->attribute != y->attribute)           \
		{                                          \
			return x->attribute < y->attribute;    \
		}

	static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "");
	SORT_SMALLER(mConfigCaveat);

	static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "");
	SORT_SMALLER(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_SMALLER(mBufferSize);
	SORT_SMALLER(mSampleBuffers);
	SORT_SMALLER(mSamples);
	SORT_SMALLER(mDepthSize);
	SORT_SMALLER(mStencilSize);
	SORT_SMALLER(mAlphaMaskSize);
	SORT_SMALLER(mNativeVisualType);
	SORT_SMALLER(mConfigID);

	#undef SORT_SMALLER

	return false;
}

ConfigSet::ConfigSet()
{
}

void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
{
	Config config(displayFormat, 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)
		{
			if(attribute[1] != EGL_DONT_CARE)
			{
				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 == (EGLenum)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 == (EGLBoolean)attribute[1];         break;
				case EGL_NATIVE_VISUAL_ID:           match = config->mNativeVisualID == 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 == (EGLenum)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 == (EGLBoolean)attribute[1];         break;
				case EGL_BIND_TO_TEXTURE_RGBA:       match = config->mBindToTextureRGBA == (EGLBoolean)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 == (EGLenum)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;
				case EGL_MAX_PBUFFER_WIDTH:          match = config->mMaxPBufferWidth >= attribute[1];                      break;
				case EGL_MAX_PBUFFER_HEIGHT:         match = config->mMaxPBufferHeight >= attribute[1];                     break;
				case EGL_MAX_PBUFFER_PIXELS:         match = config->mMaxPBufferPixels >= attribute[1];                     break;
				case EGL_RECORDABLE_ANDROID:         match = config->mRecordableAndroid == (EGLBoolean)attribute[1];        break;
				case EGL_FRAMEBUFFER_TARGET_ANDROID: match = config->mFramebufferTargetAndroid == (EGLBoolean)attribute[1]; break;
				default:
					*numConfig = 0;
					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 = static_cast<EGLint>(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 nullptr;
}
}
