Lower correlation threshold in flush-finish tests again am: 6455e6f987 am: 2e18b48b04...
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglThreadCleanUpTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2016 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 EGL thread clean up tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglThreadCleanUpTests.hpp"
25
26 #include "egluUtil.hpp"
27 #include "egluUnique.hpp"
28 #include "egluConfigFilter.hpp"
29
30 #include "eglwLibrary.hpp"
31 #include "eglwEnums.hpp"
32
33 #include "tcuMaybe.hpp"
34 #include "tcuTestLog.hpp"
35
36 #include "deThread.hpp"
37
38 namespace deqp
39 {
40 namespace egl
41 {
42 namespace
43 {
44
45 using namespace eglw;
46 using tcu::TestLog;
47
48 bool isES2Renderable (const eglu::CandidateConfig& c)
49 {
50         return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
51 }
52
53 bool isPBuffer (const eglu::CandidateConfig& c)
54 {
55         return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT;
56 }
57
58 class Thread : public de::Thread
59 {
60 public:
61         Thread (const Library& egl, EGLDisplay display, EGLSurface surface, EGLContext context, EGLConfig config, tcu::Maybe<eglu::Error>& error)
62                 : m_egl         (egl)
63                 , m_display     (display)
64                 , m_surface     (surface)
65                 , m_context     (context)
66                 , m_config      (config)
67                 , m_error       (error)
68         {
69         }
70
71         void testContext (EGLContext context)
72         {
73                 if (m_surface != EGL_NO_SURFACE)
74                 {
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");
78                 }
79                 else
80                 {
81                         const EGLint attribs[] =
82                         {
83                                 EGL_WIDTH, 32,
84                                 EGL_HEIGHT, 32,
85                                 EGL_NONE
86                         };
87                         const eglu::UniqueSurface surface (m_egl, m_display, m_egl.createPbufferSurface(m_display, m_config, attribs));
88
89                         EGLU_CHECK_MSG(m_egl, "eglCreateContext");
90                         m_egl.makeCurrent(m_display, *surface, *surface, context);
91                         EGLU_CHECK_MSG(m_egl, "eglMakeCurrent");
92                 }
93         }
94
95         void run (void)
96         {
97                 try
98                 {
99                         const EGLint    attribList[] =
100                         {
101                                 EGL_CONTEXT_CLIENT_VERSION, 2,
102                                 EGL_NONE
103                         };
104
105                         m_egl.bindAPI(EGL_OPENGL_ES_API);
106
107                         if (m_context == EGL_NO_CONTEXT)
108                         {
109                                 const eglu::UniqueContext context (m_egl, m_display, m_egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList));
110
111                                 testContext(*context);
112                         }
113                         else
114                         {
115                                 testContext(m_context);
116                         }
117
118                 }
119                 catch (const eglu::Error& error)
120                 {
121                         m_error = error;
122                 }
123         }
124
125 private:
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;
132 };
133
134 class ThreadCleanUpTest : public TestCase
135 {
136 public:
137         enum ContextType
138         {
139                 CONTEXTTYPE_SINGLE = 0,
140                 CONTEXTTYPE_MULTI
141         };
142
143         enum SurfaceType
144         {
145                 SURFACETYPE_SINGLE = 0,
146                 SURFACETYPE_MULTI
147         };
148
149         static std::string testCaseName (ContextType contextType, SurfaceType surfaceType)
150         {
151                 std::string name;
152
153                 if (contextType == CONTEXTTYPE_SINGLE)
154                         name += "single_context_";
155                 else
156                         name += "multi_context_";
157
158                 if (surfaceType ==SURFACETYPE_SINGLE)
159                         name += "single_surface";
160                 else
161                         name += "multi_surface";
162
163                 return name;
164         }
165
166
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)
171                 , m_iterCount           (250)
172                 , m_iterNdx                     (0)
173                 , m_display                     (EGL_NO_DISPLAY)
174                 , m_config                      (0)
175                 , m_surface                     (EGL_NO_SURFACE)
176                 , m_context                     (EGL_NO_CONTEXT)
177         {
178         }
179
180         ~ThreadCleanUpTest (void)
181         {
182                 deinit();
183         }
184
185         void init (void)
186         {
187                 const Library&  egl     = m_eglTestCtx.getLibrary();
188
189                 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
190
191                 {
192                         eglu::FilterList filters;
193                         filters << isES2Renderable << isPBuffer;
194                         m_config = eglu::chooseSingleConfig(egl, m_display, filters);
195                 }
196
197                 if (m_contextType == CONTEXTTYPE_SINGLE)
198                 {
199                         const EGLint    attribList[] =
200                         {
201                                 EGL_CONTEXT_CLIENT_VERSION, 2,
202                                 EGL_NONE
203                         };
204
205                         egl.bindAPI(EGL_OPENGL_ES_API);
206
207                         m_context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList);
208                         EGLU_CHECK_MSG(egl, "Failed to create context");
209                 }
210
211                 if (m_surfaceType == SURFACETYPE_SINGLE)
212                 {
213                         const EGLint attribs[] =
214                         {
215                                 EGL_WIDTH, 32,
216                                 EGL_HEIGHT, 32,
217                                 EGL_NONE
218                         };
219
220                         m_surface = egl.createPbufferSurface(m_display, m_config, attribs);
221                         EGLU_CHECK_MSG(egl, "Failed to create surface");
222                 }
223         }
224
225         void deinit (void)
226         {
227                 const Library& egl = m_eglTestCtx.getLibrary();
228
229                 if (m_surface != EGL_NO_SURFACE)
230                 {
231                         egl.destroySurface(m_display, m_surface);
232                         m_surface = EGL_NO_SURFACE;
233                 }
234
235                 if (m_context != EGL_NO_CONTEXT)
236                 {
237                         egl.destroyContext(m_display, m_context);
238                         m_context = EGL_NO_CONTEXT;
239                 }
240
241                 if (m_display != EGL_NO_DISPLAY)
242                 {
243                         egl.terminate(m_display);
244                         m_display = EGL_NO_DISPLAY;
245                 }
246         }
247
248         IterateResult iterate (void)
249         {
250                 if (m_iterNdx < m_iterCount)
251                 {
252                         tcu::Maybe<eglu::Error> error;
253
254                         Thread thread (m_eglTestCtx.getLibrary(), m_display, m_surface, m_context, m_config, error);
255
256                         thread.start();
257                         thread.join();
258
259                         if (error)
260                         {
261                                 m_testCtx.getLog() << TestLog::Message << "Failed. Got error: " << error->getMessage() << TestLog::EndMessage;
262                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error->getMessage());
263                                 return STOP;
264                         }
265
266                         m_iterNdx++;
267                         return CONTINUE;
268                 }
269                 else
270                 {
271                         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
272                         return STOP;
273                 }
274         }
275
276 private:
277         const ContextType       m_contextType;
278         const SurfaceType       m_surfaceType;
279         const size_t            m_iterCount;
280         size_t                          m_iterNdx;
281         EGLDisplay                      m_display;
282         EGLConfig                       m_config;
283         EGLSurface                      m_surface;
284         EGLContext                      m_context;
285 };
286
287 } // anonymous
288
289 TestCaseGroup* createThreadCleanUpTest (EglTestContext& eglTestCtx)
290 {
291         de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "thread_cleanup", "Thread cleanup tests"));
292
293         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_SINGLE,        ThreadCleanUpTest::SURFACETYPE_SINGLE));
294         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_MULTI,         ThreadCleanUpTest::SURFACETYPE_SINGLE));
295
296         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_SINGLE,        ThreadCleanUpTest::SURFACETYPE_MULTI));
297         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_MULTI,         ThreadCleanUpTest::SURFACETYPE_MULTI));
298
299         return group.release();
300 }
301
302 } // egl
303 } // deqp