am 028bb2ef: (-s ours) am 2084300a: DO NOT MERGE Treat adb device info parse failures...
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglTestCase.cpp
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 EGL Test Case
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglTestCase.hpp"
25
26 #include "tcuPlatform.hpp"
27
28 #include "egluUtil.hpp"
29 #include "egluGLFunctionLoader.hpp"
30 #include "egluPlatform.hpp"
31
32 #include "gluRenderContext.hpp"
33 #include "glwInitFunctions.hpp"
34
35 #include <set>
36
37 using std::vector;
38 using std::set;
39
40 namespace deqp
41 {
42 namespace egl
43 {
44
45 namespace
46 {
47
48 void split (std::vector<std::string>& dst, const std::string& src)
49 {
50         size_t start = 0;
51         size_t end       = std::string::npos;
52
53         while ((end = src.find(' ', start)) != std::string::npos)
54         {
55                 dst.push_back(src.substr(start, end-start));
56                 start = end+1;
57         }
58
59         if (start < end)
60                 dst.push_back(src.substr(start, end-start));
61 }
62
63 EGLint parseAPI (const std::string& api)
64 {
65         if (api == "OpenGL")
66                 return EGL_OPENGL_API;
67         else if (api == "OpenGL_ES")
68                 return EGL_OPENGL_ES_API;
69         else if (api == "OpenVG")
70                 return EGL_OPENVG_API;
71         else
72         {
73                 tcu::print("Warning: Unknown API '%s'", api.c_str());
74                 return 0;
75         }
76 }
77
78 } // anonymous
79
80 EglTestContext::EglTestContext (tcu::TestContext& testCtx, const eglu::NativeDisplayFactory& displayFactory, const eglu::NativeWindowFactory* windowFactory, const eglu::NativePixmapFactory* pixmapFactory)
81         : m_testCtx                                     (testCtx)
82         , m_displayFactory                      (displayFactory)
83         , m_windowFactory                       (windowFactory)
84         , m_pixmapFactory                       (pixmapFactory)
85         , m_defaultNativeDisplay        (DE_NULL)
86         , m_defaultEGLDisplay           (DE_NULL)
87 {
88         // Temporarily allocate default display for storing config list
89         try
90         {
91                 EGLDisplay      eglDisplay      = EGL_NO_DISPLAY;
92                 EGLint          majorVersion;
93                 EGLint          minorVersion;
94
95                 m_defaultNativeDisplay  = m_displayFactory.createDisplay();
96
97                 eglDisplay = eglu::getDisplay(*m_defaultNativeDisplay);
98                 TCU_CHECK_EGL_CALL(eglInitialize(eglDisplay, &majorVersion, &minorVersion));
99
100                 m_defaultEGLDisplay = new tcu::egl::Display(eglDisplay, majorVersion, minorVersion);
101
102                 // Create config list
103                 {
104                         vector<EGLConfig>       configs;
105                         set<EGLint>                     idSet; // For checking for duplicate config IDs
106
107                         m_defaultEGLDisplay->getConfigs(configs);
108
109                         m_configs.resize(configs.size());
110                         for (int ndx = 0; ndx < (int)configs.size(); ndx++)
111                         {
112                                 m_defaultEGLDisplay->describeConfig(configs[ndx], m_configs[ndx]);
113
114                                 EGLint id = m_configs[ndx].configId;
115                                 if (idSet.find(id) != idSet.end())
116                                         tcu::print("Warning: Duplicate config ID %d\n", id);
117                                 idSet.insert(id);
118                         }
119                 }
120
121                 // Query supported APIs
122                 {
123                         const char*                                     clientAPIs      = eglQueryString(eglDisplay, EGL_CLIENT_APIS);
124                         std::vector<std::string>        apis;
125                         TCU_CHECK(clientAPIs);
126
127                         split(apis, clientAPIs);
128                         for (std::vector<std::string>::const_iterator apiIter = apis.begin(); apiIter != apis.end(); apiIter++)
129                         {
130                                 EGLint parsedAPI = parseAPI(*apiIter);
131                                 if (parsedAPI != 0)
132                                         m_supportedAPIs.insert(parsedAPI);
133                         }
134                 }
135
136                 delete m_defaultEGLDisplay;
137                 m_defaultEGLDisplay = DE_NULL;
138                 delete m_defaultNativeDisplay;
139                 m_defaultNativeDisplay = DE_NULL;
140         }
141         catch (...)
142         {
143                 delete m_defaultEGLDisplay;
144                 m_defaultEGLDisplay = DE_NULL;
145                 delete m_defaultNativeDisplay;
146                 m_defaultNativeDisplay = DE_NULL;
147                 throw;
148         }
149 }
150
151 EglTestContext::~EglTestContext (void)
152 {
153         for (GLLibraryMap::iterator iter = m_glLibraries.begin(); iter != m_glLibraries.end(); ++iter)
154                 delete iter->second;
155
156         delete m_defaultEGLDisplay;
157         delete m_defaultNativeDisplay;
158 }
159
160 void EglTestContext::createDefaultDisplay (void)
161 {
162         EGLDisplay      eglDisplay      = EGL_NO_DISPLAY;
163         EGLint          majorVersion;
164         EGLint          minorVersion;
165
166         DE_ASSERT(!m_defaultEGLDisplay);
167         DE_ASSERT(!m_defaultNativeDisplay);
168
169         try
170         {
171                 m_defaultNativeDisplay  = m_displayFactory.createDisplay();
172
173                 eglDisplay = eglu::getDisplay(*m_defaultNativeDisplay);
174                 TCU_CHECK_EGL_CALL(eglInitialize(eglDisplay, &majorVersion, &minorVersion));
175
176                 m_defaultEGLDisplay = new tcu::egl::Display(eglDisplay, majorVersion, minorVersion);
177         }
178         catch (const std::exception&)
179         {
180                 delete m_defaultEGLDisplay;
181                 m_defaultEGLDisplay = DE_NULL;
182                 delete m_defaultNativeDisplay;
183                 m_defaultNativeDisplay = DE_NULL;
184                 throw;
185         }
186 }
187
188 const eglu::NativeWindowFactory& EglTestContext::getNativeWindowFactory (void) const
189 {
190         if (m_windowFactory)
191                 return *m_windowFactory;
192         else
193                 throw tcu::NotSupportedError("No default native window factory available", "", __FILE__, __LINE__);
194 }
195
196 const eglu::NativePixmapFactory& EglTestContext::getNativePixmapFactory (void) const
197 {
198         if (m_pixmapFactory)
199                 return *m_pixmapFactory;
200         else
201                 throw tcu::NotSupportedError("No default native pixmap factory available", "", __FILE__, __LINE__);
202 }
203
204 void EglTestContext::destroyDefaultDisplay (void)
205 {
206         DE_ASSERT(m_defaultEGLDisplay);
207         DE_ASSERT(m_defaultNativeDisplay);
208
209         delete m_defaultEGLDisplay;
210         m_defaultEGLDisplay = DE_NULL;
211
212         delete m_defaultNativeDisplay;
213         m_defaultNativeDisplay = DE_NULL;
214 }
215
216 eglu::NativeWindow* EglTestContext::createNativeWindow (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height, eglu::WindowParams::Visibility visibility)
217 {
218         if (!m_windowFactory)
219                 throw tcu::NotSupportedError("Windows not supported", "", __FILE__, __LINE__);
220
221         return m_windowFactory->createWindow(m_defaultNativeDisplay, display, config, attribList, eglu::WindowParams(width, height, visibility));
222 }
223
224 eglu::NativeWindow* EglTestContext::createNativeWindow (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height)
225 {
226         return createNativeWindow(display, config, attribList, width, height, eglu::parseWindowVisibility(getTestContext().getCommandLine()));
227 }
228
229 eglu::NativePixmap* EglTestContext::createNativePixmap (EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, int width, int height)
230 {
231         if (!m_pixmapFactory)
232                 throw tcu::NotSupportedError("Pixmaps not supported", "", __FILE__, __LINE__);
233
234         return m_pixmapFactory->createPixmap(m_defaultNativeDisplay, display, config, attribList, width, height);
235 }
236
237 // \todo [2014-10-06 pyry] Quite hacky, expose ApiType internals?
238 static deUint32 makeKey (glu::ApiType apiType)
239 {
240         return (apiType.getMajorVersion() << 8) | (apiType.getMinorVersion() << 4) | apiType.getProfile();
241 }
242
243 const tcu::FunctionLibrary* EglTestContext::getGLLibrary (glu::ApiType apiType) const
244 {
245         tcu::FunctionLibrary*           library = DE_NULL;
246         const deUint32                          key             = makeKey(apiType);
247         GLLibraryMap::iterator          iter    = m_glLibraries.find(key);
248
249         if (iter == m_glLibraries.end())
250         {
251                 library = m_testCtx.getPlatform().getEGLPlatform().createDefaultGLFunctionLibrary(apiType, m_testCtx.getCommandLine());
252                 m_glLibraries.insert(std::make_pair(key, library));
253         }
254         else
255                 library = iter->second;
256
257         return library;
258 }
259
260 deFunctionPtr EglTestContext::getGLFunction (glu::ApiType apiType, const char* name) const
261 {
262         // \todo [2014-03-11 pyry] This requires fall-back to eglGetProcAddress(), right?
263         const tcu::FunctionLibrary* const       library = getGLLibrary(apiType);
264         return library->getFunction(name);
265 }
266
267 void EglTestContext::getGLFunctions (glw::Functions& gl, glu::ApiType apiType, const std::vector<const char*>& extensions) const
268 {
269         const tcu::FunctionLibrary* const       library         = getGLLibrary(apiType);
270         const eglu::GLFunctionLoader            loader          (library);
271
272         // \note There may not be current context, so we can't use initFunctions().
273         glu::initCoreFunctions(&gl, &loader, apiType);
274         glu::initExtensionFunctions(&gl, &loader, apiType, extensions.size(), &extensions.front());
275 }
276
277 TestCaseGroup::TestCaseGroup (EglTestContext& eglTestCtx, const char* name, const char* description)
278         : tcu::TestCaseGroup    (eglTestCtx.getTestContext(), name, description)
279         , m_eglTestCtx                  (eglTestCtx)
280 {
281 }
282
283 TestCaseGroup::~TestCaseGroup (void)
284 {
285 }
286
287 TestCase::TestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
288         : tcu::TestCase         (eglTestCtx.getTestContext(), name, description)
289         , m_eglTestCtx          (eglTestCtx)
290 {
291 }
292
293 TestCase::TestCase (EglTestContext& eglTestCtx, tcu::TestNodeType type,  const char* name, const char* description)
294         : tcu::TestCase         (eglTestCtx.getTestContext(), type, name, description)
295         , m_eglTestCtx          (eglTestCtx)
296 {
297 }
298
299 TestCase::~TestCase (void)
300 {
301 }
302
303 } // egl
304 } // deqp