/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL Module
 * ---------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Choose config tests.
 *//*--------------------------------------------------------------------*/

#include "teglChooseConfigTests.hpp"
#include "teglChooseConfigReference.hpp"
#include "tcuTestLog.hpp"
#include "egluStrUtil.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"

#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>

using std::set;
using std::vector;
using std::pair;
using std::string;
using tcu::TestLog;

namespace deqp
{
namespace egl
{

using eglu::ConfigInfo;

namespace
{

string configListToString (const tcu::egl::Display& display, const vector<EGLConfig>& configs)
{
	string str = "";
	for (vector<EGLConfig>::const_iterator cfgIter = configs.begin(); cfgIter != configs.end(); cfgIter++)
	{
		EGLConfig	config		= *cfgIter;
		EGLint		configId	= display.getConfigAttrib(config, EGL_CONFIG_ID);

		if (str.length() != 0)
			str += " ";

		str += de::toString(configId);
	}
	return str;
}

void logConfigAttrib (TestLog& log, EGLenum attrib, EGLint value)
{
	const std::string	attribStr	= eglu::getConfigAttribName(attrib);

	if (value == EGL_DONT_CARE)
	{
		log << TestLog::Message << "  " << attribStr << ": EGL_DONT_CARE" << TestLog::EndMessage;
		return;
	}

	log << TestLog::Message << "  " << attribStr << ": " << eglu::getConfigAttribValueStr(attrib, value) << TestLog::EndMessage;
}

} // anonymous

class ChooseConfigCase : public TestCase
{
public:
	ChooseConfigCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool checkOrder, const EGLint* attributes)
		: TestCase		(eglTestCtx, name, description)
		, m_checkOrder	(checkOrder)
	{
		// Parse attributes
		while (attributes[0] != EGL_NONE)
		{
			m_attributes.push_back(std::make_pair((EGLenum)attributes[0], (EGLint)attributes[1]));
			attributes += 2;
		}
	}

	ChooseConfigCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool checkOrder, const std::vector<std::pair<EGLenum, EGLint> >& attributes)
		: TestCase		(eglTestCtx, name, description)
		, m_checkOrder	(checkOrder)
		, m_attributes	(attributes)
	{
	}

	IterateResult iterate (void)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

		executeTest(m_attributes, m_checkOrder);
		return STOP;
	}
protected:
	ChooseConfigCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool checkOrder)
		: TestCase		(eglTestCtx, name, description)
		, m_checkOrder	(checkOrder)
	{
	}

	void executeTest (const std::vector<std::pair<EGLenum, EGLint> >& attributes, bool checkOrder)
	{
		TestLog&					log		= m_testCtx.getLog();
		const tcu::egl::Display&	display	= m_eglTestCtx.getDisplay();

		// Build attributes for EGL
		vector<EGLint> attribList;
		for (vector<pair<EGLenum, EGLint> >::const_iterator i = attributes.begin(); i != attributes.end(); i++)
		{
			attribList.push_back(i->first);
			attribList.push_back(i->second);
		}
		attribList.push_back(EGL_NONE);

		// Print attribList to log
		log << TestLog::Message << "Attributes:" << TestLog::EndMessage;
		for (vector<pair<EGLenum, EGLint> >::const_iterator i = attributes.begin(); i != attributes.end(); i++)
			logConfigAttrib(log, i->first, i->second);

		std::vector<EGLConfig>	resultConfigs;
		std::vector<EGLConfig>	referenceConfigs;

		// Query from EGL implementation
		{
			EGLint numConfigs = 0;
			TCU_CHECK_EGL_CALL(eglChooseConfig(display.getEGLDisplay(), &attribList[0], DE_NULL, 0, &numConfigs));
			resultConfigs.resize(numConfigs);

			if (numConfigs > 0)
				TCU_CHECK_EGL_CALL(eglChooseConfig(display.getEGLDisplay(), &attribList[0], &resultConfigs[0], (EGLint)resultConfigs.size(), &numConfigs));
		}

		// Build reference
		chooseConfigReference(display, referenceConfigs, attributes);

		log << TestLog::Message << "Expected:\n  " << configListToString(display, referenceConfigs) << TestLog::EndMessage;
		log << TestLog::Message << "Got:\n  " << configListToString(display, resultConfigs) << TestLog::EndMessage;

		bool isSetMatch		= (set<EGLConfig>(resultConfigs.begin(), resultConfigs.end()) == set<EGLConfig>(referenceConfigs.begin(), referenceConfigs.end()));
		bool isExactMatch	= (resultConfigs == referenceConfigs);
		bool isMatch		= isSetMatch && (checkOrder ? isExactMatch : true);

		if (isMatch)
			log << TestLog::Message << "Pass" << TestLog::EndMessage;
		else if (!isSetMatch)
			log << TestLog::Message << "Fail, configs don't match" << TestLog::EndMessage;
		else if (!isExactMatch)
			log << TestLog::Message << "Fail, got correct configs but in invalid order" << TestLog::EndMessage;

		if (!isMatch)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	void fillDontCare (std::vector<std::pair<EGLenum, EGLint> >& attributes)
	{
		static const EGLenum dontCareAttributes[] =
		{
			EGL_TRANSPARENT_TYPE,
			EGL_COLOR_BUFFER_TYPE,
			EGL_RENDERABLE_TYPE,
			EGL_SURFACE_TYPE
		};

		// Fill appropriate unused attributes with EGL_DONT_CARE
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(dontCareAttributes); ndx++)
		{
			bool found = false;
			for (size_t findNdx = 0; findNdx < attributes.size(); findNdx++)
				if (attributes[findNdx].first == dontCareAttributes[ndx]) found = true;

			if (!found) attributes.push_back(std::make_pair(dontCareAttributes[ndx], EGL_DONT_CARE));
		}
	}

	bool							m_checkOrder;
	vector<pair<EGLenum, EGLint> >	m_attributes;
};

class ChooseConfigSimpleCase : public ChooseConfigCase
{
protected:
	EGLint getValue (EGLenum name)
	{
		static const struct
		{
			EGLenum		name;
			EGLint		value;
		} attributes[] = {
			{ EGL_BUFFER_SIZE,				0					},
			{ EGL_RED_SIZE,					0					},
			{ EGL_GREEN_SIZE,				0					},
			{ EGL_BLUE_SIZE,				0					},
			{ EGL_LUMINANCE_SIZE,			0					},
			{ EGL_ALPHA_SIZE,				0					},
			{ EGL_ALPHA_MASK_SIZE,			0					},
			{ EGL_BIND_TO_TEXTURE_RGB,		EGL_DONT_CARE		},
			{ EGL_BIND_TO_TEXTURE_RGBA,		EGL_DONT_CARE		},
			{ EGL_COLOR_BUFFER_TYPE,		EGL_DONT_CARE		},
			{ EGL_CONFIG_CAVEAT,			EGL_DONT_CARE		},
			//{ EGL_CONFIG_ID,				EGL_DONT_CARE		},
			{ EGL_DEPTH_SIZE,				0					},
			{ EGL_LEVEL,					0					},
			{ EGL_MAX_SWAP_INTERVAL,		EGL_DONT_CARE		},
			{ EGL_MIN_SWAP_INTERVAL,		EGL_DONT_CARE		},
			{ EGL_NATIVE_RENDERABLE,		EGL_DONT_CARE		},
			{ EGL_NATIVE_VISUAL_TYPE,		EGL_DONT_CARE		},
			{ EGL_SAMPLE_BUFFERS,			0					},
			{ EGL_SAMPLES,					0					},
			{ EGL_STENCIL_SIZE,				0					},
			{ EGL_TRANSPARENT_TYPE,			EGL_TRANSPARENT_RGB	},
			{ EGL_TRANSPARENT_RED_VALUE,	0					},
			{ EGL_TRANSPARENT_GREEN_VALUE,	0					},
			{ EGL_TRANSPARENT_BLUE_VALUE,	0					},
			{ EGL_CONFORMANT,				EGL_OPENGL_ES_BIT	},
			{ EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES_BIT	},
			{ EGL_SURFACE_TYPE,				EGL_WINDOW_BIT		}
			//{ EGL_CONFORMANT,				EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT	},
			//{ EGL_RENDERABLE_TYPE,			EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT	},
			//{ EGL_SURFACE_TYPE,				EGL_WINDOW_BIT
			//								| EGL_PIXMAP_BIT
			//								| EGL_PBUFFER_BIT
			//								| EGL_MULTISAMPLE_RESOLVE_BOX_BIT
			//								| EGL_VG_ALPHA_FORMAT_PRE_BIT
			//								| EGL_SWAP_BEHAVIOR_PRESERVED_BIT
			//								| EGL_VG_COLORSPACE_LINEAR_BIT
			//								}
		};

		if (name == EGL_CONFIG_ID)
		{
			de::Random rnd(0);
			return m_eglTestCtx.getConfigs()[rnd.getInt(0, (int)(m_eglTestCtx.getConfigs().size()-1))].configId;
		}
		else
		{
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(attributes); ndx++)
			{
				if (attributes[ndx].name == name) return attributes[ndx].value;
			}
		}

		DE_ASSERT(DE_FALSE);
		return EGL_NONE;
	}
public:
	ChooseConfigSimpleCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLenum attribute, bool checkOrder)
		: ChooseConfigCase(eglTestCtx, name, description, checkOrder)
		, m_attribute(attribute)
	{
	}

	void init (void)
	{
	}

	TestCase::IterateResult iterate (void)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

		std::vector<std::pair<EGLenum, EGLint> > attributes;
		attributes.push_back(std::pair<EGLenum, EGLint>(m_attribute, getValue(m_attribute)));

		fillDontCare(attributes);
		executeTest(attributes, m_checkOrder);

		return STOP;
	}
private:
	EGLenum	m_attribute;
};

class ChooseConfigRandomCase : public ChooseConfigCase
{
public:
	ChooseConfigRandomCase (EglTestContext& eglTestCtx, const char* name, const char* description, const set<EGLenum>& attribSet)
		: ChooseConfigCase	(eglTestCtx, name, description, true)
		, m_attribSet		(attribSet)
		, m_numIters		(10)
		, m_iterNdx			(0)
	{
	}

	void init (void)
	{
		m_iterNdx = 0;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}

	TestCase::IterateResult iterate (void)
	{
		m_testCtx.getLog() << TestLog::Message << "Iteration :" << m_iterNdx << TestLog::EndMessage;
		m_iterNdx += 1;

		// Build random list of attributes
		de::Random									rnd(m_iterNdx);
		const int									numAttribs	= rnd.getInt(0, (int)m_attribSet.size()*2);

		std::vector<std::pair<EGLenum, EGLint> >	attributes	= genRandomAttributes(m_attribSet, numAttribs, rnd);

		fillDontCare(attributes);
		executeTest(attributes, m_checkOrder);

		return m_iterNdx < m_numIters ? CONTINUE : STOP;
	}

	template <int MinVal, int MaxVal> static EGLint getInt (de::Random& rnd)
	{
		return rnd.getInt(MinVal, MaxVal);
	}

	static EGLint getBool (de::Random& rnd)
	{
		return rnd.getBool() ? EGL_TRUE : EGL_FALSE;
	}

	static EGLint getBufferType (de::Random& rnd)
	{
		static const EGLint types[] = { EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER };
		return rnd.choose<EGLint>(types, types+DE_LENGTH_OF_ARRAY(types));
	}

	static EGLint getConfigCaveat (de::Random& rnd)
	{
		static const EGLint caveats[] = { EGL_SLOW_CONFIG, EGL_NON_CONFORMANT_CONFIG };
		return rnd.choose<EGLint>(caveats, caveats+DE_LENGTH_OF_ARRAY(caveats));
	}

	static EGLint getApiBits (de::Random& rnd)
	{
		EGLint api = 0;
		api |= rnd.getBool() ? EGL_OPENGL_BIT		: 0;
		api |= rnd.getBool() ? EGL_OPENGL_ES_BIT	: 0;
		api |= rnd.getBool() ? EGL_OPENGL_ES2_BIT	: 0;
		api |= rnd.getBool() ? EGL_OPENVG_BIT		: 0;
		return api;
	}

	static EGLint getSurfaceType (de::Random& rnd)
	{
		EGLint bits = 0;
		bits |= rnd.getBool() ? EGL_WINDOW_BIT	: 0;
		bits |= rnd.getBool() ? EGL_PIXMAP_BIT	: 0;
		bits |= rnd.getBool() ? EGL_PBUFFER_BIT	: 0;
		return bits;
	}

	struct AttribSpec
	{
		EGLenum			attribute;
		EGLint			(*getValue)(de::Random& rnd);
	};

	std::vector<std::pair<EGLenum, EGLint> > genRandomAttributes (const std::set<EGLenum>& attribSet, int numAttribs, de::Random& rnd)
	{
		static const struct AttribSpec attributes[] =
		{
			{ EGL_BUFFER_SIZE,				ChooseConfigRandomCase::getInt<0, 32>,		},
			{ EGL_RED_SIZE,					ChooseConfigRandomCase::getInt<0, 8>,		},
			{ EGL_GREEN_SIZE,				ChooseConfigRandomCase::getInt<0, 8>,		},
			{ EGL_BLUE_SIZE,				ChooseConfigRandomCase::getInt<0, 8>,		},
			{ EGL_LUMINANCE_SIZE,			ChooseConfigRandomCase::getInt<0, 1>,		},
			{ EGL_ALPHA_SIZE,				ChooseConfigRandomCase::getInt<0, 8>,		},
			{ EGL_ALPHA_MASK_SIZE,			ChooseConfigRandomCase::getInt<0, 1>,		},
			{ EGL_BIND_TO_TEXTURE_RGB,		ChooseConfigRandomCase::getBool,			},
			{ EGL_BIND_TO_TEXTURE_RGBA,		ChooseConfigRandomCase::getBool,			},
			{ EGL_COLOR_BUFFER_TYPE,		ChooseConfigRandomCase::getBufferType,		},
			{ EGL_CONFIG_CAVEAT,			ChooseConfigRandomCase::getConfigCaveat,	},
//			{ EGL_CONFIG_ID,				0/*special*/,		},
			{ EGL_CONFORMANT,				ChooseConfigRandomCase::getApiBits,			},
			{ EGL_DEPTH_SIZE,				ChooseConfigRandomCase::getInt<0, 32>,		},
			{ EGL_LEVEL,					ChooseConfigRandomCase::getInt<0, 1>,		},
//			{ EGL_MATCH_NATIVE_PIXMAP,		EGL_NONE,			},
			{ EGL_MAX_SWAP_INTERVAL,		ChooseConfigRandomCase::getInt<0, 2>,		},
			{ EGL_MIN_SWAP_INTERVAL,		ChooseConfigRandomCase::getInt<0, 1>,		},
			{ EGL_NATIVE_RENDERABLE,		ChooseConfigRandomCase::getBool,			},
//			{ EGL_NATIVE_VISUAL_TYPE,		EGL_DONT_CARE,		},
			{ EGL_RENDERABLE_TYPE,			ChooseConfigRandomCase::getApiBits,			},
			{ EGL_SAMPLE_BUFFERS,			ChooseConfigRandomCase::getInt<0, 1>,		},
			{ EGL_SAMPLES,					ChooseConfigRandomCase::getInt<0, 1>,		},
			{ EGL_STENCIL_SIZE,				ChooseConfigRandomCase::getInt<0, 1>,		},
			{ EGL_SURFACE_TYPE,				ChooseConfigRandomCase::getSurfaceType,		},
//			{ EGL_TRANSPARENT_TYPE,			EGL_TRANSPARENT_RGB,},
//			{ EGL_TRANSPARENT_RED_VALUE,	ChooseConfigRandomCase::getInt<0, 255>,		},
//			{ EGL_TRANSPARENT_GREEN_VALUE,	ChooseConfigRandomCase::getInt<0, 255>,		},
//			{ EGL_TRANSPARENT_BLUE_VALUE,	ChooseConfigRandomCase::getInt<0, 255>,		}
		};

		std::vector<std::pair<EGLenum, EGLint> > out;

		// Build list to select from
		std::vector<AttribSpec> candidates;
		for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(attributes); ndx++)
		{
			if (attribSet.find(attributes[ndx].attribute) != attribSet.end())
				candidates.push_back(attributes[ndx]);
		}

		for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
		{
			AttribSpec spec = rnd.choose<AttribSpec>(candidates.begin(), candidates.end());
			out.push_back(std::make_pair(spec.attribute, spec.getValue(rnd)));
		}

		return out;
	}
private:
	std::set<EGLenum>	m_attribSet;
	int					m_numIters;
	int					m_iterNdx;
};

ChooseConfigTests::ChooseConfigTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "choose_config", "eglChooseConfig() tests")
{
}

ChooseConfigTests::~ChooseConfigTests (void)
{
}

namespace
{

template <typename T, size_t N>
std::set<T> toSet (const T (&arr)[N])
{
	std::set<T> set;
	for (size_t i = 0; i < N; i++)
		set.insert(arr[i]);
	return set;
}

} // anonymous

void ChooseConfigTests::init (void)
{
	// Single attributes
	{
		static const struct
		{
			EGLenum			attribute;
			const char*		testName;
		} attributes[] =
		{
			{ EGL_BUFFER_SIZE,				"buffer_size"				},
			{ EGL_RED_SIZE,					"red_size"					},
			{ EGL_GREEN_SIZE,				"green_size"				},
			{ EGL_BLUE_SIZE,				"blue_size"					},
			{ EGL_LUMINANCE_SIZE,			"luminance_size"			},
			{ EGL_ALPHA_SIZE,				"alpha_size"				},
			{ EGL_ALPHA_MASK_SIZE,			"alpha_mask_size"			},
			{ EGL_BIND_TO_TEXTURE_RGB,		"bind_to_texture_rgb"		},
			{ EGL_BIND_TO_TEXTURE_RGBA,		"bind_to_texture_rgba"		},
			{ EGL_COLOR_BUFFER_TYPE,		"color_buffer_type"			},
			{ EGL_CONFIG_CAVEAT,			"config_caveat"				},
			{ EGL_CONFIG_ID,				"config_id"					},
			{ EGL_CONFORMANT,				"conformant"				},
			{ EGL_DEPTH_SIZE,				"depth_size"				},
			{ EGL_LEVEL,					"level"						},
			{ EGL_MAX_SWAP_INTERVAL,		"max_swap_interval"			},
			{ EGL_MIN_SWAP_INTERVAL,		"min_swap_interval"			},
			{ EGL_NATIVE_RENDERABLE,		"native_renderable"			},
			{ EGL_NATIVE_VISUAL_TYPE,		"native_visual_type"		},
			{ EGL_RENDERABLE_TYPE,			"renderable_type"			},
			{ EGL_SAMPLE_BUFFERS,			"sample_buffers"			},
			{ EGL_SAMPLES,					"samples"					},
			{ EGL_STENCIL_SIZE,				"stencil_size"				},
			{ EGL_SURFACE_TYPE,				"surface_type"				},
			{ EGL_TRANSPARENT_TYPE,			"transparent_type"			},
			{ EGL_TRANSPARENT_RED_VALUE,	"transparent_red_value"		},
			{ EGL_TRANSPARENT_GREEN_VALUE,	"transparent_green_value"	},
			{ EGL_TRANSPARENT_BLUE_VALUE,	"transparent_blue_value"	}
		};

		tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "simple", "Simple tests");
		addChild(simpleGroup);

		tcu::TestCaseGroup* selectionGroup = new tcu::TestCaseGroup(m_testCtx, "selection_only", "Selection tests, order ignored");
		simpleGroup->addChild(selectionGroup);

		tcu::TestCaseGroup* sortGroup = new tcu::TestCaseGroup(m_testCtx, "selection_and_sort", "Selection and ordering tests");
		simpleGroup->addChild(sortGroup);

		for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(attributes); ndx++)
		{
			selectionGroup->addChild(new ChooseConfigSimpleCase(m_eglTestCtx, attributes[ndx].testName, "Simple config selection case", attributes[ndx].attribute, false));
			sortGroup->addChild(new ChooseConfigSimpleCase(m_eglTestCtx, attributes[ndx].testName, "Simple config selection and sort case", attributes[ndx].attribute, true));
		}
	}

	// Random
	{
		tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random eglChooseConfig() usage");
		addChild(randomGroup);

		static const EGLenum rgbaSizes[] =
		{
			EGL_RED_SIZE,
			EGL_GREEN_SIZE,
			EGL_BLUE_SIZE,
			EGL_ALPHA_SIZE
		};
		randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "color_sizes", "Random color size rules", toSet(rgbaSizes)));

		static const EGLenum colorDepthStencilSizes[] =
		{
			EGL_RED_SIZE,
			EGL_GREEN_SIZE,
			EGL_BLUE_SIZE,
			EGL_ALPHA_SIZE,
			EGL_DEPTH_SIZE,
			EGL_STENCIL_SIZE
		};
		randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "color_depth_stencil_sizes", "Random color, depth and stencil size rules", toSet(colorDepthStencilSizes)));

		static const EGLenum bufferSizes[] =
		{
			EGL_BUFFER_SIZE,
			EGL_LUMINANCE_SIZE,
			EGL_ALPHA_MASK_SIZE,
			EGL_DEPTH_SIZE,
			EGL_STENCIL_SIZE
		};
		randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "buffer_sizes", "Various buffer size rules", toSet(bufferSizes)));

		static const EGLenum surfaceType[] =
		{
			EGL_NATIVE_RENDERABLE,
			EGL_SURFACE_TYPE
		};
		randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "surface_type", "Surface type rules", toSet(surfaceType)));

		static const EGLenum sampleBuffers[] =
		{
			EGL_SAMPLE_BUFFERS,
			EGL_SAMPLES
		};
		randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "sample_buffers", "Sample buffer rules", toSet(sampleBuffers)));

		// \note Not every attribute is supported at the moment
		static const EGLenum allAttribs[] =
		{
			EGL_BUFFER_SIZE,
			EGL_RED_SIZE,
			EGL_GREEN_SIZE,
			EGL_BLUE_SIZE,
			EGL_ALPHA_SIZE,
			EGL_ALPHA_MASK_SIZE,
			EGL_BIND_TO_TEXTURE_RGB,
			EGL_BIND_TO_TEXTURE_RGBA,
			EGL_COLOR_BUFFER_TYPE,
			EGL_CONFIG_CAVEAT,
			EGL_CONFIG_ID,
			EGL_CONFORMANT,
			EGL_DEPTH_SIZE,
			EGL_LEVEL,
//			EGL_MATCH_NATIVE_PIXMAP,
			EGL_MAX_SWAP_INTERVAL,
			EGL_MIN_SWAP_INTERVAL,
			EGL_NATIVE_RENDERABLE,
			EGL_NATIVE_VISUAL_TYPE,
			EGL_RENDERABLE_TYPE,
			EGL_SAMPLE_BUFFERS,
			EGL_SAMPLES,
			EGL_STENCIL_SIZE,
			EGL_SURFACE_TYPE,
			EGL_TRANSPARENT_TYPE,
//			EGL_TRANSPARENT_RED_VALUE,
//			EGL_TRANSPARENT_GREEN_VALUE,
//			EGL_TRANSPARENT_BLUE_VALUE
		};
		randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "all", "All attributes", toSet(allAttribs)));
	}
}

} // egl
} // deqp
