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 
32 namespace deqp
33 {
34 namespace egl
35 {
36 
37 using std::vector;
38 using std::string;
39 using tcu::TestLog;
40 using eglu::ConfigInfo;
41 using namespace eglw;
42 using namespace eglu;
43 
SimpleConfigCase(EglTestContext & eglTestCtx,const char * name,const char * description,const FilterList & filters)44 SimpleConfigCase::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 
~SimpleConfigCase(void)51 SimpleConfigCase::~SimpleConfigCase (void)
52 {
53 }
54 
init(void)55 void 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 
deinit(void)88 void 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 
iterate(void)98 SimpleConfigCase::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 
118 template <int Red, int Green, int Blue, int Alpha>
colorBits(const eglu::CandidateConfig & c)119 static 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 
127 template <int Red, int Green, int Blue, int Alpha>
notColorBits(const eglu::CandidateConfig & c)128 static 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 
hasDepth(const eglu::CandidateConfig & c)136 static bool	hasDepth	(const eglu::CandidateConfig& c)	{ return c.depthSize() > 0;		}
noDepth(const eglu::CandidateConfig & c)137 static bool	noDepth		(const eglu::CandidateConfig& c)	{ return c.depthSize() == 0;	}
hasStencil(const eglu::CandidateConfig & c)138 static bool	hasStencil	(const eglu::CandidateConfig& c)	{ return c.stencilSize() > 0;	}
noStencil(const eglu::CandidateConfig & c)139 static bool	noStencil	(const eglu::CandidateConfig& c)	{ return c.stencilSize() == 0;	}
140 
isConformant(const eglu::CandidateConfig & c)141 static bool isConformant (const eglu::CandidateConfig& c)
142 {
143 	return c.get(EGL_CONFIG_CAVEAT) != EGL_NON_CONFORMANT_CONFIG;
144 }
145 
getDefaultFilterLists(vector<NamedFilterList> & lists,const FilterList & baseFilters)146 void getDefaultFilterLists (vector<NamedFilterList>& lists, const FilterList& baseFilters)
147 {
148 	static const struct
149 	{
150 		const char*			name;
151 		eglu::ConfigFilter	filter;
152 	} s_colorRules[] =
153 	{
154 		{ "rgb565",		colorBits<5, 6, 5, 0> },
155 		{ "rgb888",		colorBits<8, 8, 8, 0> },
156 		{ "rgba4444",	colorBits<4, 4, 4, 4> },
157 		{ "rgba5551",	colorBits<5, 5, 5, 1> },
158 		{ "rgba8888",	colorBits<8, 8, 8, 8> }
159 	};
160 
161 	static const struct
162 	{
163 		const char*			name;
164 		eglu::ConfigFilter	filter;
165 	} s_depthRules[] =
166 	{
167 		{ "no_depth",	noDepth		},
168 		{ "depth",		hasDepth	},
169 	};
170 
171 	static const struct
172 	{
173 		const char*			name;
174 		eglu::ConfigFilter	filter;
175 	} s_stencilRules[] =
176 	{
177 		{ "no_stencil",	noStencil	},
178 		{ "stencil",	hasStencil	},
179 	};
180 
181 	for (int colorRuleNdx = 0; colorRuleNdx < DE_LENGTH_OF_ARRAY(s_colorRules); colorRuleNdx++)
182 	{
183 		for (int depthRuleNdx = 0; depthRuleNdx < DE_LENGTH_OF_ARRAY(s_depthRules); depthRuleNdx++)
184 		{
185 			for (int stencilRuleNdx = 0; stencilRuleNdx < DE_LENGTH_OF_ARRAY(s_stencilRules); stencilRuleNdx++)
186 			{
187 				const string		name		= string(s_colorRules[colorRuleNdx].name) + "_" + s_depthRules[depthRuleNdx].name + "_" + s_stencilRules[stencilRuleNdx].name;
188 				NamedFilterList		filters		(name.c_str(), "");
189 
190 				filters << baseFilters
191 						<< s_colorRules[colorRuleNdx].filter
192 						<< s_depthRules[depthRuleNdx].filter
193 						<< s_stencilRules[stencilRuleNdx].filter
194 						<< isConformant;
195 
196 				lists.push_back(filters);
197 			}
198 		}
199 	}
200 
201 	// Build "other" set - not configs that don't match any of known color rules
202 	{
203 		NamedFilterList		filters		("other", "All other configs");
204 
205 		// \todo [2014-12-18 pyry] Optimize rules
206 		filters << baseFilters
207 				<< notColorBits<5, 6, 5, 0>
208 				<< notColorBits<8, 8, 8, 0>
209 				<< notColorBits<4, 4, 4, 4>
210 				<< notColorBits<5, 5, 5, 1>
211 				<< notColorBits<8, 8, 8, 8>
212 				<< isConformant;
213 
214 		lists.push_back(filters);
215 	}
216 }
217 
218 } // egl
219 } // deqp
220