1/*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Simple Context construction test.
22 *//*--------------------------------------------------------------------*/
23
24#include "teglSimpleConfigCase.hpp"
25#include "tcuTestLog.hpp"
26#include "tcuFormatUtil.hpp"
27#include "egluUtil.hpp"
28#include "eglwLibrary.hpp"
29#include "eglwEnums.hpp"
30#include "deStringUtil.hpp"
31
32namespace deqp
33{
34namespace egl
35{
36
37using std::vector;
38using std::string;
39using tcu::TestLog;
40using eglu::ConfigInfo;
41using namespace eglw;
42using namespace eglu;
43
44SimpleConfigCase::SimpleConfigCase (EglTestContext& eglTestCtx, const char* name, const char* description, const FilterList& filters)
45	: TestCase	(eglTestCtx, name, description)
46	, m_filters	(filters)
47	, m_display	(EGL_NO_DISPLAY)
48{
49}
50
51SimpleConfigCase::~SimpleConfigCase (void)
52{
53}
54
55void SimpleConfigCase::init (void)
56{
57	const Library&		egl		= m_eglTestCtx.getLibrary();
58
59	DE_ASSERT(m_display == EGL_NO_DISPLAY && m_configs.empty());
60
61	m_display	= getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
62	m_configs	= chooseConfigs(egl, m_display, m_filters);
63
64	// Log matching configs.
65	{
66		vector<EGLint> configIds(m_configs.size());
67
68		for (size_t ndx = 0; ndx < m_configs.size(); ndx++)
69			configIds[ndx] = getConfigID(egl, m_display, m_configs[ndx]);
70
71		m_testCtx.getLog() << TestLog::Message << "Compatible configs: " << tcu::formatArray(configIds.begin(), configIds.end()) << TestLog::EndMessage;
72	}
73
74	if (m_configs.empty())
75	{
76		egl.terminate(m_display);
77		m_display = EGL_NO_DISPLAY;
78		TCU_THROW(NotSupportedError, "No compatible configs found");
79	}
80
81	// Init config iter
82	m_configIter = m_configs.begin();
83
84	// Init test case result to Pass
85	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
86}
87
88void SimpleConfigCase::deinit (void)
89{
90	if (m_display != EGL_NO_DISPLAY)
91	{
92		m_eglTestCtx.getLibrary().terminate(m_display);
93		m_display = EGL_NO_DISPLAY;
94	}
95	m_configs.clear();
96}
97
98SimpleConfigCase::IterateResult SimpleConfigCase::iterate (void)
99{
100	DE_ASSERT(m_configIter != m_configs.end());
101
102	EGLConfig	config	= *m_configIter++;
103
104	try
105	{
106		executeForConfig(m_display, config);
107	}
108	catch (const tcu::TestError& e)
109	{
110		m_testCtx.getLog() << e;
111		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
112	}
113	// \note Other errors are handled by framework (resource / internal errors).
114
115	return (m_configIter != m_configs.end()) ? CONTINUE : STOP;
116}
117
118template <int Red, int Green, int Blue, int Alpha>
119static bool colorBits (const eglu::CandidateConfig& c)
120{
121	return c.redSize()		== Red		&&
122		   c.greenSize()	== Green	&&
123		   c.blueSize()		== Blue		&&
124		   c.alphaSize()	== Alpha;
125}
126
127template <int Red, int Green, int Blue, int Alpha>
128static bool notColorBits (const eglu::CandidateConfig& c)
129{
130	return c.redSize()		!= Red		||
131		   c.greenSize()	!= Green	||
132		   c.blueSize()		!= Blue		||
133		   c.alphaSize()	!= Alpha;
134}
135
136static bool	hasDepth	(const eglu::CandidateConfig& c)	{ return c.depthSize() > 0;		}
137static bool	noDepth		(const eglu::CandidateConfig& c)	{ return c.depthSize() == 0;	}
138static bool	hasStencil	(const eglu::CandidateConfig& c)	{ return c.stencilSize() > 0;	}
139static bool	noStencil	(const eglu::CandidateConfig& c)	{ return c.stencilSize() == 0;	}
140
141static bool isConformant (const eglu::CandidateConfig& c)
142{
143	return c.get(EGL_CONFIG_CAVEAT) != EGL_NON_CONFORMANT_CONFIG;
144}
145
146static bool notFloat (const eglu::CandidateConfig& c)
147{
148	return c.colorComponentType() != EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
149}
150
151void getDefaultFilterLists (vector<NamedFilterList>& lists, const FilterList& baseFilters)
152{
153	static const struct
154	{
155		const char*			name;
156		eglu::ConfigFilter	filter;
157	} s_colorRules[] =
158	{
159		{ "rgb565",		colorBits<5, 6, 5, 0> },
160		{ "rgb888",		colorBits<8, 8, 8, 0> },
161		{ "rgba4444",	colorBits<4, 4, 4, 4> },
162		{ "rgba5551",	colorBits<5, 5, 5, 1> },
163		{ "rgba8888",	colorBits<8, 8, 8, 8> }
164	};
165
166	static const struct
167	{
168		const char*			name;
169		eglu::ConfigFilter	filter;
170	} s_depthRules[] =
171	{
172		{ "no_depth",	noDepth		},
173		{ "depth",		hasDepth	},
174	};
175
176	static const struct
177	{
178		const char*			name;
179		eglu::ConfigFilter	filter;
180	} s_stencilRules[] =
181	{
182		{ "no_stencil",	noStencil	},
183		{ "stencil",	hasStencil	},
184	};
185
186	for (int colorRuleNdx = 0; colorRuleNdx < DE_LENGTH_OF_ARRAY(s_colorRules); colorRuleNdx++)
187	{
188		for (int depthRuleNdx = 0; depthRuleNdx < DE_LENGTH_OF_ARRAY(s_depthRules); depthRuleNdx++)
189		{
190			for (int stencilRuleNdx = 0; stencilRuleNdx < DE_LENGTH_OF_ARRAY(s_stencilRules); stencilRuleNdx++)
191			{
192				const string		name		= string(s_colorRules[colorRuleNdx].name) + "_" + s_depthRules[depthRuleNdx].name + "_" + s_stencilRules[stencilRuleNdx].name;
193				NamedFilterList		filters		(name.c_str(), "");
194
195				filters << baseFilters
196						<< s_colorRules[colorRuleNdx].filter
197						<< s_depthRules[depthRuleNdx].filter
198						<< s_stencilRules[stencilRuleNdx].filter
199						<< isConformant;
200
201				lists.push_back(filters);
202			}
203		}
204	}
205
206	// Build "other" set - not configs that don't match any of known color rules
207	{
208		NamedFilterList		filters		("other", "All other configs");
209
210		// \todo [2014-12-18 pyry] Optimize rules
211		filters << baseFilters
212				<< notColorBits<5, 6, 5, 0>
213				<< notColorBits<8, 8, 8, 0>
214				<< notColorBits<4, 4, 4, 4>
215				<< notColorBits<5, 5, 5, 1>
216				<< notColorBits<8, 8, 8, 8>
217				<< isConformant
218				<< notFloat;
219
220		lists.push_back(filters);
221	}
222}
223
224} // egl
225} // deqp
226