1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Config query tests.
22 *//*--------------------------------------------------------------------*/
24 #include "teglQueryContextTests.hpp"
25 #include "teglRenderCase.hpp"
26 #include "teglRenderCase.hpp"
27 #include "egluCallLogWrapper.hpp"
28 #include "egluStrUtil.hpp"
29 #include "tcuCommandLine.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTestContext.hpp"
33 #include "egluUtil.hpp"
34 #include "egluNativeDisplay.hpp"
35 #include "egluNativeWindow.hpp"
36 #include "egluNativePixmap.hpp"
38 #include "eglwLibrary.hpp"
39 #include "eglwEnums.hpp"
41 #include "deUniquePtr.hpp"
42 #include "deSTLUtil.hpp"
52 using eglu::ConfigInfo;
56 static EGLint getClientTypeFromAPIBit (EGLint apiBit)
60 case EGL_OPENGL_BIT: return EGL_OPENGL_API;
61 case EGL_OPENGL_ES_BIT: return EGL_OPENGL_ES_API;
62 case EGL_OPENGL_ES2_BIT: return EGL_OPENGL_ES_API;
63 case EGL_OPENGL_ES3_BIT: return EGL_OPENGL_ES_API;
64 case EGL_OPENVG_BIT: return EGL_OPENVG_API;
71 static EGLint getMinClientMajorVersion (EGLint apiBit)
75 case EGL_OPENGL_BIT: return 1;
76 case EGL_OPENGL_ES_BIT: return 1;
77 case EGL_OPENGL_ES2_BIT: return 2;
78 case EGL_OPENGL_ES3_BIT: return 3;
79 case EGL_OPENVG_BIT: return 1;
86 class GetCurrentContextCase : public SingleContextRenderCase, private eglu::CallLogWrapper
89 GetCurrentContextCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
90 : SingleContextRenderCase (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
91 , eglu::CallLogWrapper (eglTestCtx.getLibrary(), m_testCtx.getLog())
95 void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
97 const Library& egl = m_eglTestCtx.getLibrary();
98 TestLog& log = m_testCtx.getLog();
106 const EGLContext gotContext = eglGetCurrentContext();
107 EGLU_CHECK_MSG(egl, "eglGetCurrentContext");
109 if (gotContext == context)
111 log << TestLog::Message << " Pass" << TestLog::EndMessage;
113 else if (gotContext == EGL_NO_CONTEXT)
115 log << TestLog::Message << " Fail, got EGL_NO_CONTEXT" << TestLog::EndMessage;
116 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected EGL_NO_CONTEXT");
118 else if (gotContext != context)
120 log << TestLog::Message << " Fail, call returned the wrong context. Expected: " << tcu::toHex(context) << ", got: " << tcu::toHex(gotContext) << TestLog::EndMessage;
121 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid context");
124 enableLogging(false);
128 class GetCurrentSurfaceCase : public SingleContextRenderCase, private eglu::CallLogWrapper
131 GetCurrentSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
132 : SingleContextRenderCase (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
133 , eglu::CallLogWrapper (eglTestCtx.getLibrary(), m_testCtx.getLog())
137 void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
139 const Library& egl = m_eglTestCtx.getLibrary();
140 TestLog& log = m_testCtx.getLog();
148 const EGLContext gotReadSurface = eglGetCurrentSurface(EGL_READ);
149 EGLU_CHECK_MSG(egl, "eglGetCurrentSurface(EGL_READ)");
151 const EGLContext gotDrawSurface = eglGetCurrentSurface(EGL_DRAW);
152 EGLU_CHECK_MSG(egl, "eglGetCurrentSurface(EGL_DRAW)");
154 if (gotReadSurface == surface && gotDrawSurface == surface)
156 log << TestLog::Message << " Pass" << TestLog::EndMessage;
160 log << TestLog::Message << " Fail, read surface: " << tcu::toHex(gotReadSurface)
161 << ", draw surface: " << tcu::toHex(gotDrawSurface)
162 << ", expected: " << tcu::toHex(surface) << TestLog::EndMessage;
163 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface");
166 enableLogging(false);
170 class GetCurrentDisplayCase : public SingleContextRenderCase, private eglu::CallLogWrapper
173 GetCurrentDisplayCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
174 : SingleContextRenderCase (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
175 , eglu::CallLogWrapper (eglTestCtx.getLibrary(), m_testCtx.getLog())
179 void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
181 const Library& egl = m_eglTestCtx.getLibrary();
182 TestLog& log = m_testCtx.getLog();
184 DE_UNREF(surface && context);
189 const EGLDisplay gotDisplay = eglGetCurrentDisplay();
190 EGLU_CHECK_MSG(egl, "eglGetCurrentDisplay");
192 if (gotDisplay == display)
194 log << TestLog::Message << " Pass" << TestLog::EndMessage;
196 else if (gotDisplay == EGL_NO_DISPLAY)
198 log << TestLog::Message << " Fail, got EGL_NO_DISPLAY" << TestLog::EndMessage;
199 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected EGL_NO_DISPLAY");
201 else if (gotDisplay != display)
203 log << TestLog::Message << " Fail, call returned the wrong display. Expected: " << tcu::toHex(display) << ", got: " << tcu::toHex(gotDisplay) << TestLog::EndMessage;
204 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid display");
207 enableLogging(false);
211 class QueryContextCase : public SingleContextRenderCase, private eglu::CallLogWrapper
214 QueryContextCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
215 : SingleContextRenderCase (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
216 , eglu::CallLogWrapper (eglTestCtx.getLibrary(), m_testCtx.getLog())
220 EGLint getContextAttrib (EGLDisplay display, EGLContext context, EGLint attrib)
222 const Library& egl = m_eglTestCtx.getLibrary();
224 EGLU_CHECK_CALL(egl, queryContext(display, context, attrib, &value));
229 void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
231 const Library& egl = m_eglTestCtx.getLibrary();
232 TestLog& log = m_testCtx.getLog();
233 const eglu::Version version = eglu::getVersion(egl, display);
240 const EGLint configID = getContextAttrib(display, context, EGL_CONFIG_ID);
241 const EGLint surfaceConfigID = eglu::getConfigAttribInt(egl, display, config.config, EGL_CONFIG_ID);
243 if (configID != surfaceConfigID)
245 log << TestLog::Message << " Fail, config ID doesn't match the one used to create the context." << TestLog::EndMessage;
246 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid config ID");
251 if (version >= eglu::Version(1, 2))
253 const EGLint clientType = getContextAttrib(display, context, EGL_CONTEXT_CLIENT_TYPE);
255 if (clientType != getClientTypeFromAPIBit(config.apiBits))
257 log << TestLog::Message << " Fail, client API type doesn't match." << TestLog::EndMessage;
258 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid client API type");
262 // Client API version
263 if (version >= eglu::Version(1, 3))
265 const EGLint clientVersion = getContextAttrib(display, context, EGL_CONTEXT_CLIENT_VERSION);
267 // \todo [2014-10-21 mika] Query actual supported api version from client api to make this check stricter.
268 if (clientVersion < getMinClientMajorVersion(config.apiBits))
270 log << TestLog::Message << " Fail, client API version doesn't match." << TestLog::EndMessage;
271 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid client API version");
276 if (version >= eglu::Version(1, 2))
278 const EGLint renderBuffer = getContextAttrib(display, context, EGL_RENDER_BUFFER);
280 if (config.surfaceTypeBit == EGL_PIXMAP_BIT && renderBuffer != EGL_SINGLE_BUFFER)
282 log << TestLog::Message << " Fail, render buffer should be EGL_SINGLE_BUFFER for a pixmap surface." << TestLog::EndMessage;
283 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
285 else if (config.surfaceTypeBit == EGL_PBUFFER_BIT && renderBuffer != EGL_BACK_BUFFER)
287 log << TestLog::Message << " Fail, render buffer should be EGL_BACK_BUFFER for a pbuffer surface." << TestLog::EndMessage;
288 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
290 else if (config.surfaceTypeBit == EGL_WINDOW_BIT && renderBuffer != EGL_SINGLE_BUFFER && renderBuffer != EGL_BACK_BUFFER)
292 log << TestLog::Message << " Fail, render buffer should be either EGL_SINGLE_BUFFER or EGL_BACK_BUFFER for a window surface." << TestLog::EndMessage;
293 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
297 enableLogging(false);
299 log << TestLog::Message << " Pass" << TestLog::EndMessage;
303 class QueryAPICase : public TestCase, private eglu::CallLogWrapper
306 QueryAPICase (EglTestContext& eglTestCtx, const char* name, const char* description)
307 : TestCase (eglTestCtx, name, description)
308 , CallLogWrapper(eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
314 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
317 IterateResult iterate (void)
319 const Library& egl = m_eglTestCtx.getLibrary();
320 EGLDisplay display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
321 tcu::TestLog& log = m_testCtx.getLog();
322 const EGLenum apis[] = { EGL_OPENGL_API, EGL_OPENGL_ES_API, EGL_OPENVG_API };
323 const vector<EGLenum> supportedAPIs = eglu::getClientAPIs(egl, display);
328 const EGLenum api = eglQueryAPI();
330 if (api != EGL_OPENGL_ES_API && (de::contains(supportedAPIs.begin(), supportedAPIs.end(), EGL_OPENGL_ES_API)))
332 log << TestLog::Message << " Fail, initial value should be EGL_OPENGL_ES_API if OpenGL ES is supported." << TestLog::EndMessage;
333 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default value");
335 else if (api != EGL_NONE && !(de::contains(supportedAPIs.begin(), supportedAPIs.end(), EGL_OPENGL_ES_API)))
337 log << TestLog::Message << " Fail, initial value should be EGL_NONE if OpenGL ES is not supported." << TestLog::EndMessage;
338 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default value");
342 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(apis); ndx++)
344 const EGLenum api = apis[ndx];
346 log << TestLog::Message << TestLog::EndMessage;
348 if (de::contains(supportedAPIs.begin(), supportedAPIs.end(), api))
352 if (api != egl.queryAPI())
354 log << TestLog::Message << " Fail, return value does not match previously bound API." << TestLog::EndMessage;
355 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid return value");
360 log << TestLog::Message << eglu::getAPIStr(api) << " not supported." << TestLog::EndMessage;
364 enableLogging(false);
365 eglTerminate(display);
370 QueryContextTests::QueryContextTests (EglTestContext& eglTestCtx)
371 : TestCaseGroup(eglTestCtx, "query_context", "Rendering context query tests")
375 QueryContextTests::~QueryContextTests (void)
379 template<class QueryContextClass>
380 void createQueryContextGroups (EglTestContext& eglTestCtx, tcu::TestCaseGroup* group)
382 std::vector<RenderFilterList> filterLists;
384 getDefaultRenderFilterLists(filterLists, eglu::FilterList());
386 for (std::vector<RenderFilterList>::const_iterator listIter = filterLists.begin(); listIter != filterLists.end(); listIter++)
387 group->addChild(new QueryContextClass(eglTestCtx, listIter->getName(), "", *listIter, listIter->getSurfaceTypeMask()));
390 void QueryContextTests::init (void)
393 tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "simple", "Simple API tests");
394 addChild(simpleGroup);
396 simpleGroup->addChild(new QueryAPICase(m_eglTestCtx, "query_api", "eglQueryAPI() test"));
399 // eglGetCurrentContext
401 tcu::TestCaseGroup* getCurrentContextGroup = new tcu::TestCaseGroup(m_testCtx, "get_current_context", "eglGetCurrentContext() tests");
402 addChild(getCurrentContextGroup);
404 createQueryContextGroups<GetCurrentContextCase>(m_eglTestCtx, getCurrentContextGroup);
407 // eglGetCurrentSurface
409 tcu::TestCaseGroup* getCurrentSurfaceGroup = new tcu::TestCaseGroup(m_testCtx, "get_current_surface", "eglGetCurrentSurface() tests");
410 addChild(getCurrentSurfaceGroup);
412 createQueryContextGroups<GetCurrentSurfaceCase>(m_eglTestCtx, getCurrentSurfaceGroup);
415 // eglGetCurrentDisplay
417 tcu::TestCaseGroup* getCurrentDisplayGroup = new tcu::TestCaseGroup(m_testCtx, "get_current_display", "eglGetCurrentDisplay() tests");
418 addChild(getCurrentDisplayGroup);
420 createQueryContextGroups<GetCurrentDisplayCase>(m_eglTestCtx, getCurrentDisplayGroup);
425 tcu::TestCaseGroup* queryContextGroup = new tcu::TestCaseGroup(m_testCtx, "query_context", "eglQueryContext() tests");
426 addChild(queryContextGroup);
428 createQueryContextGroups<QueryContextCase>(m_eglTestCtx, queryContextGroup);