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                 m_egl.releaseThread();
125         }
126
127 private:
128         const Library&                          m_egl;
129         const EGLDisplay                        m_display;
130         const EGLSurface                        m_surface;
131         const EGLContext                        m_context;
132         const EGLConfig                         m_config;
133         tcu::Maybe<eglu::Error>&        m_error;
134 };
135
136 class ThreadCleanUpTest : public TestCase
137 {
138 public:
139         enum ContextType
140         {
141                 CONTEXTTYPE_SINGLE = 0,
142                 CONTEXTTYPE_MULTI
143         };
144
145         enum SurfaceType
146         {
147                 SURFACETYPE_SINGLE = 0,
148                 SURFACETYPE_MULTI
149         };
150
151         static std::string testCaseName (ContextType contextType, SurfaceType surfaceType)
152         {
153                 std::string name;
154
155                 if (contextType == CONTEXTTYPE_SINGLE)
156                         name += "single_context_";
157                 else
158                         name += "multi_context_";
159
160                 if (surfaceType ==SURFACETYPE_SINGLE)
161                         name += "single_surface";
162                 else
163                         name += "multi_surface";
164
165                 return name;
166         }
167
168
169         ThreadCleanUpTest (EglTestContext& eglTestCtx, ContextType contextType, SurfaceType surfaceType)
170                 : TestCase                      (eglTestCtx, testCaseName(contextType, surfaceType).c_str(), "Simple thread context clean up test")
171                 , m_contextType         (contextType)
172                 , m_surfaceType         (surfaceType)
173                 , m_iterCount           (250)
174                 , m_iterNdx                     (0)
175                 , m_display                     (EGL_NO_DISPLAY)
176                 , m_config                      (0)
177                 , m_surface                     (EGL_NO_SURFACE)
178                 , m_context                     (EGL_NO_CONTEXT)
179         {
180         }
181
182         ~ThreadCleanUpTest (void)
183         {
184                 deinit();
185         }
186
187         void init (void)
188         {
189                 const Library&  egl     = m_eglTestCtx.getLibrary();
190
191                 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
192
193                 {
194                         eglu::FilterList filters;
195                         filters << isES2Renderable << isPBuffer;
196                         m_config = eglu::chooseSingleConfig(egl, m_display, filters);
197                 }
198
199                 if (m_contextType == CONTEXTTYPE_SINGLE)
200                 {
201                         const EGLint    attribList[] =
202                         {
203                                 EGL_CONTEXT_CLIENT_VERSION, 2,
204                                 EGL_NONE
205                         };
206
207                         egl.bindAPI(EGL_OPENGL_ES_API);
208
209                         m_context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList);
210                         EGLU_CHECK_MSG(egl, "Failed to create context");
211                 }
212
213                 if (m_surfaceType == SURFACETYPE_SINGLE)
214                 {
215                         const EGLint attribs[] =
216                         {
217                                 EGL_WIDTH, 32,
218                                 EGL_HEIGHT, 32,
219                                 EGL_NONE
220                         };
221
222                         m_surface = egl.createPbufferSurface(m_display, m_config, attribs);
223                         EGLU_CHECK_MSG(egl, "Failed to create surface");
224                 }
225         }
226
227         void deinit (void)
228         {
229                 const Library& egl = m_eglTestCtx.getLibrary();
230
231                 if (m_surface != EGL_NO_SURFACE)
232                 {
233                         egl.destroySurface(m_display, m_surface);
234                         m_surface = EGL_NO_SURFACE;
235                 }
236
237                 if (m_context != EGL_NO_CONTEXT)
238                 {
239                         egl.destroyContext(m_display, m_context);
240                         m_context = EGL_NO_CONTEXT;
241                 }
242
243                 if (m_display != EGL_NO_DISPLAY)
244                 {
245                         egl.terminate(m_display);
246                         m_display = EGL_NO_DISPLAY;
247                 }
248         }
249
250         IterateResult iterate (void)
251         {
252                 if (m_iterNdx < m_iterCount)
253                 {
254                         tcu::Maybe<eglu::Error> error;
255
256                         Thread thread (m_eglTestCtx.getLibrary(), m_display, m_surface, m_context, m_config, error);
257
258                         thread.start();
259                         thread.join();
260
261                         if (error)
262                         {
263                                 m_testCtx.getLog() << TestLog::Message << "Failed. Got error: " << error->getMessage() << TestLog::EndMessage;
264                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error->getMessage());
265                                 return STOP;
266                         }
267
268                         m_iterNdx++;
269                         return CONTINUE;
270                 }
271                 else
272                 {
273                         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
274                         return STOP;
275                 }
276         }
277
278 private:
279         const ContextType       m_contextType;
280         const SurfaceType       m_surfaceType;
281         const size_t            m_iterCount;
282         size_t                          m_iterNdx;
283         EGLDisplay                      m_display;
284         EGLConfig                       m_config;
285         EGLSurface                      m_surface;
286         EGLContext                      m_context;
287 };
288
289 } // anonymous
290
291 TestCaseGroup* createThreadCleanUpTest (EglTestContext& eglTestCtx)
292 {
293         de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "thread_cleanup", "Thread cleanup tests"));
294
295         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_SINGLE,        ThreadCleanUpTest::SURFACETYPE_SINGLE));
296         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_MULTI,         ThreadCleanUpTest::SURFACETYPE_SINGLE));
297
298         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_SINGLE,        ThreadCleanUpTest::SURFACETYPE_MULTI));
299         group->addChild(new ThreadCleanUpTest(eglTestCtx, ThreadCleanUpTest::CONTEXTTYPE_MULTI,         ThreadCleanUpTest::SURFACETYPE_MULTI));
300
301         return group.release();
302 }
303
304 } // egl
305 } // deqp