1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
5 * Copyright 2016 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 EGL thread clean up tests
22 *//*--------------------------------------------------------------------*/
24 #include "teglThreadCleanUpTests.hpp"
26 #include "egluUtil.hpp"
27 #include "egluUnique.hpp"
28 #include "egluConfigFilter.hpp"
30 #include "eglwLibrary.hpp"
31 #include "eglwEnums.hpp"
33 #include "tcuMaybe.hpp"
34 #include "tcuTestLog.hpp"
36 #include "deThread.hpp"
48 bool isES2Renderable (const eglu::CandidateConfig& c)
50 return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
53 bool isPBuffer (const eglu::CandidateConfig& c)
55 return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT;
58 class Thread : public de::Thread
61 Thread (const Library& egl, EGLDisplay display, EGLSurface surface, EGLContext context, EGLConfig config, tcu::Maybe<eglu::Error>& error)
71 void testContext (EGLContext context)
73 if (m_surface != EGL_NO_SURFACE)
75 EGLU_CHECK_MSG(m_egl, "eglCreateContext");
76 m_egl.makeCurrent(m_display, m_surface, m_surface, context);
77 EGLU_CHECK_MSG(m_egl, "eglMakeCurrent");
81 const EGLint attribs[] =
87 const eglu::UniqueSurface surface (m_egl, m_display, m_egl.createPbufferSurface(m_display, m_config, attribs));
89 EGLU_CHECK_MSG(m_egl, "eglCreateContext");
90 m_egl.makeCurrent(m_display, *surface, *surface, context);
91 EGLU_CHECK_MSG(m_egl, "eglMakeCurrent");
99 const EGLint attribList[] =
101 EGL_CONTEXT_CLIENT_VERSION, 2,
105 m_egl.bindAPI(EGL_OPENGL_ES_API);
107 if (m_context == EGL_NO_CONTEXT)
109 const eglu::UniqueContext context (m_egl, m_display, m_egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList));
111 testContext(*context);
115 testContext(m_context);
119 catch (const eglu::Error& error)
126 const Library& m_egl;
127 const EGLDisplay m_display;
128 const EGLSurface m_surface;
129 const EGLContext m_context;
130 const EGLConfig m_config;
131 tcu::Maybe<eglu::Error>& m_error;
134 class ThreadCleanUpTest : public TestCase
139 CONTEXTTYPE_SINGLE = 0,
145 SURFACETYPE_SINGLE = 0,
149 static std::string testCaseName (ContextType contextType, SurfaceType surfaceType)
153 if (contextType == CONTEXTTYPE_SINGLE)
154 name += "single_context_";
156 name += "multi_context_";
158 if (surfaceType ==SURFACETYPE_SINGLE)
159 name += "single_surface";
161 name += "multi_surface";
167 ThreadCleanUpTest (EglTestContext& eglTestCtx, ContextType contextType, SurfaceType surfaceType)
168 : TestCase (eglTestCtx, testCaseName(contextType, surfaceType).c_str(), "Simple thread context clean up test")
169 , m_contextType (contextType)
170 , m_surfaceType (surfaceType)
173 , m_display (EGL_NO_DISPLAY)
175 , m_surface (EGL_NO_SURFACE)
176 , m_context (EGL_NO_CONTEXT)
180 ~ThreadCleanUpTest (void)
187 const Library& egl = m_eglTestCtx.getLibrary();
189 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
192 eglu::FilterList filters;
193 filters << isES2Renderable << isPBuffer;
194 m_config = eglu::chooseSingleConfig(egl, m_display, filters);
197 if (m_contextType == CONTEXTTYPE_SINGLE)
199 const EGLint attribList[] =
201 EGL_CONTEXT_CLIENT_VERSION, 2,
205 egl.bindAPI(EGL_OPENGL_ES_API);
207 m_context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList);
208 EGLU_CHECK_MSG(egl, "Failed to create context");
211 if (m_surfaceType == SURFACETYPE_SINGLE)
213 const EGLint attribs[] =
220 m_surface = egl.createPbufferSurface(m_display, m_config, attribs);
221 EGLU_CHECK_MSG(egl, "Failed to create surface");
227 const Library& egl = m_eglTestCtx.getLibrary();
229 if (m_surface != EGL_NO_SURFACE)
231 egl.destroySurface(m_display, m_surface);
232 m_surface = EGL_NO_SURFACE;
235 if (m_context != EGL_NO_CONTEXT)
237 egl.destroyContext(m_display, m_context);
238 m_context = EGL_NO_CONTEXT;
241 if (m_display != EGL_NO_DISPLAY)
243 egl.terminate(m_display);
244 m_display = EGL_NO_DISPLAY;
248 IterateResult iterate (void)
250 if (m_iterNdx < m_iterCount)
252 tcu::Maybe<eglu::Error> error;
254 Thread thread (m_eglTestCtx.getLibrary(), m_display, m_surface, m_context, m_config, error);
261 m_testCtx.getLog() << TestLog::Message << "Failed. Got error: " << error->getMessage() << TestLog::EndMessage;
262 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error->getMessage());
271 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
277 const ContextType m_contextType;
278 const SurfaceType m_surfaceType;
279 const size_t m_iterCount;
281 EGLDisplay m_display;
283 EGLSurface m_surface;
284 EGLContext m_context;
289 TestCaseGroup* createThreadCleanUpTest (EglTestContext& eglTestCtx)
291 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "thread_cleanup", "Thread cleanup tests"));
293 group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_SINGLE, ThreadCleanUpTest::SURFACETYPE_SINGLE));
294 group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_MULTI, ThreadCleanUpTest::SURFACETYPE_SINGLE));
296 group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_SINGLE, ThreadCleanUpTest::SURFACETYPE_MULTI));
297 group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_MULTI, ThreadCleanUpTest::SURFACETYPE_MULTI));
299 return group.release();