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 Simple surface construction test.
22 *//*--------------------------------------------------------------------*/
23
24 #include "teglCreateSurfaceTests.hpp"
25
26 #include "egluNativeDisplay.hpp"
27 #include "egluNativeWindow.hpp"
28 #include "egluNativePixmap.hpp"
29 #include "egluUtil.hpp"
30 #include "egluUnique.hpp"
31
32 #include "eglwLibrary.hpp"
33 #include "eglwEnums.hpp"
34
35 #include "teglSimpleConfigCase.hpp"
36 #include "tcuTestContext.hpp"
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39
40 #include "deStringUtil.hpp"
41 #include "deSTLUtil.hpp"
42 #include "deUniquePtr.hpp"
43
44 #include <memory>
45
46 namespace deqp
47 {
48 namespace egl
49 {
50
51 using std::vector;
52 using tcu::TestLog;
53 using namespace eglw;
54
55 namespace
56 {
57
58 #define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor))
59
60 enum ApiType
61 {
62 LEGACY,
63 EXTENSION,
64 EGL15
65 };
66
checkEGLPlatformSupport(const Library & egl)67 void checkEGLPlatformSupport (const Library& egl)
68 {
69 const vector<std::string> extensions = eglu::getClientExtensions(egl);
70 if (!de::contains(extensions.begin(), extensions.end(), "EGL_EXT_platform_base"))
71 throw tcu::NotSupportedError("Platform extension 'EGL_EXT_platform_base' not supported", "", __FILE__, __LINE__);
72 }
73
checkEGL15Support(const Library & egl,EGLDisplay display)74 void checkEGL15Support (const Library& egl, EGLDisplay display)
75 {
76 // The EGL_VERSION string is laid out as follows:
77 // major_version.minor_version space vendor_specific_info
78 // Split version from vendor_specific_info
79 std::vector<std::string> tokens = de::splitString(egl.queryString(display, EGL_VERSION), ' ');
80 // split version into major & minor
81 std::vector<std::string> values = de::splitString(tokens[0], '.');
82 EGLint eglVersion = EGL_MAKE_VERSION(atoi(values[0].c_str()), atoi(values[1].c_str()));
83 if (eglVersion < EGL_MAKE_VERSION(1, 5))
84 throw tcu::NotSupportedError("EGL 1.5 not supported", "", __FILE__, __LINE__);
85 }
86
createWindowSurface(EGLDisplay display,EGLConfig config,eglu::NativeDisplay & nativeDisplay,eglu::NativeWindow & window,ApiType createType)87 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, ApiType createType)
88 {
89 const Library& egl = nativeDisplay.getLibrary();
90 EGLSurface surface = EGL_NO_SURFACE;
91
92 switch (createType)
93 {
94 case LEGACY:
95 {
96 surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
97 EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
98 }
99 break;
100 case EXTENSION:
101 {
102 checkEGLPlatformSupport(egl);
103 void *nativeWindow = window.getPlatformExtension();
104 surface = egl.createPlatformWindowSurfaceEXT(display, config, nativeWindow, DE_NULL);
105 EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
106 }
107 break;
108 case EGL15:
109 {
110 checkEGL15Support(egl, display);
111 surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), DE_NULL);
112 EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface() failed");
113 }
114 }
115
116 return surface;
117 }
118
createPixmapSurface(EGLDisplay display,EGLConfig config,eglu::NativeDisplay & nativeDisplay,eglu::NativePixmap & pixmap,ApiType createType)119 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, ApiType createType)
120 {
121 const Library& egl = nativeDisplay.getLibrary();
122 EGLSurface surface = EGL_NO_SURFACE;
123
124 switch (createType)
125 {
126 case LEGACY:
127 surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
128 EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
129 break;
130 case EXTENSION:
131 checkEGLPlatformSupport(egl);
132 surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), DE_NULL);
133 EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
134 break;
135 case EGL15:
136 surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL);
137 EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed");
138 break;
139 }
140
141 return surface;
142 }
143
144 class CreateWindowSurfaceCase : public SimpleConfigCase
145 {
146 public:
CreateWindowSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,ApiType createType,const eglu::FilterList & filters)147 CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
148 : SimpleConfigCase (eglTestCtx, name, description, filters)
149 , m_createType (createType)
150 {
151 }
152
executeForConfig(EGLDisplay display,EGLConfig config)153 void executeForConfig (EGLDisplay display, EGLConfig config)
154 {
155 const Library& egl = m_eglTestCtx.getLibrary();
156 TestLog& log = m_testCtx.getLog();
157 EGLint id = eglu::getConfigID(egl, display, config);
158 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
159
160 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
161
162 switch (m_createType)
163 {
164 case LEGACY:
165 {
166 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
167 TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
168 }
169 break;
170 case EXTENSION:
171 {
172 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
173 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
174 }
175 break;
176 case EGL15:
177 {
178 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
179 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()");
180 }
181 break;
182 }
183
184 log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
185 EGLU_CHECK_MSG(egl, "init");
186
187 {
188 const int width = 64;
189 const int height = 64;
190 de::UniquePtr<eglu::NativeWindow> window (windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
191 eglu::UniqueSurface surface (egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_createType));
192
193 EGLint windowWidth = 0;
194 EGLint windowHeight = 0;
195
196 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &windowWidth));
197 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &windowHeight));
198
199 if (windowWidth <= 0 || windowHeight <= 0)
200 {
201 log << TestLog::Message << " Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
202 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
203 }
204 else
205 log << TestLog::Message << " Pass" << TestLog::EndMessage;
206 }
207 }
208
209 private:
210 ApiType m_createType;
211 };
212
213 class CreatePixmapSurfaceCase : public SimpleConfigCase
214 {
215 public:
CreatePixmapSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,ApiType createType,const eglu::FilterList & filters)216 CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
217 : SimpleConfigCase(eglTestCtx, name, description, filters)
218 , m_createType (createType)
219 {
220 }
221
executeForConfig(EGLDisplay display,EGLConfig config)222 void executeForConfig (EGLDisplay display, EGLConfig config)
223 {
224 const Library& egl = m_eglTestCtx.getLibrary();
225 TestLog& log = m_testCtx.getLog();
226 EGLint id = eglu::getConfigID(egl, display, config);
227 const eglu::NativePixmapFactory& pixmapFactory = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
228
229 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
230
231 switch (m_createType)
232 {
233 case LEGACY:
234 {
235 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
236 TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
237 }
238 break;
239 case EXTENSION:
240 {
241 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
242 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
243 }
244 break;
245 case EGL15:
246 {
247 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
248 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()");
249 }
250 break;
251 };
252
253 log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
254 EGLU_CHECK_MSG(egl, "init");
255
256 {
257 const int width = 64;
258 const int height = 64;
259 de::UniquePtr<eglu::NativePixmap> pixmap (pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
260 eglu::UniqueSurface surface (egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_createType));
261 EGLint pixmapWidth = 0;
262 EGLint pixmapHeight = 0;
263
264 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &pixmapWidth));
265 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &pixmapHeight));
266
267 if (pixmapWidth <= 0 || pixmapHeight <= 0)
268 {
269 log << TestLog::Message << " Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
270 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
271 }
272 else
273 log << TestLog::Message << " Pass" << TestLog::EndMessage;
274 }
275 }
276
277 private:
278 ApiType m_createType;
279 };
280
281 class CreatePbufferSurfaceCase : public SimpleConfigCase
282 {
283 public:
CreatePbufferSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)284 CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
285 : SimpleConfigCase(eglTestCtx, name, description, filters)
286 {
287 }
288
executeForConfig(EGLDisplay display,EGLConfig config)289 void executeForConfig (EGLDisplay display, EGLConfig config)
290 {
291 const Library& egl = m_eglTestCtx.getLibrary();
292 TestLog& log = m_testCtx.getLog();
293 EGLint id = eglu::getConfigID(egl, display, config);
294 int width = 64;
295 int height = 64;
296
297 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
298
299 log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
300 EGLU_CHECK_MSG(egl, "init");
301
302 // Clamp to maximums reported by implementation
303 width = deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
304 height = deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
305
306 if (width == 0 || height == 0)
307 {
308 log << TestLog::Message << " Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
309 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
310 return;
311 }
312
313 // \todo [2011-03-23 pyry] Texture-backed variants!
314
315 const EGLint attribs[] =
316 {
317 EGL_WIDTH, width,
318 EGL_HEIGHT, height,
319 EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE,
320 EGL_NONE
321 };
322
323 EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
324 EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
325 TCU_CHECK(surface != EGL_NO_SURFACE);
326 egl.destroySurface(display, surface);
327
328 log << TestLog::Message << " Pass" << TestLog::EndMessage;
329 }
330 };
331
332 } // anonymous
333
CreateSurfaceTests(EglTestContext & eglTestCtx)334 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
335 : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
336 {
337 }
338
~CreateSurfaceTests(void)339 CreateSurfaceTests::~CreateSurfaceTests (void)
340 {
341 }
342
343 template <deUint32 Type>
surfaceType(const eglu::CandidateConfig & c)344 static bool surfaceType (const eglu::CandidateConfig& c)
345 {
346 return (c.surfaceType() & Type) == Type;
347 }
348
init(void)349 void CreateSurfaceTests::init (void)
350 {
351 // Window surfaces
352 {
353 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
354 addChild(windowGroup);
355
356 eglu::FilterList baseFilters;
357 baseFilters << surfaceType<EGL_WINDOW_BIT>;
358
359 vector<NamedFilterList> filterLists;
360 getDefaultFilterLists(filterLists, baseFilters);
361
362 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
363 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
364 }
365
366 // Pixmap surfaces
367 {
368 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
369 addChild(pixmapGroup);
370
371 eglu::FilterList baseFilters;
372 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
373
374 vector<NamedFilterList> filterLists;
375 getDefaultFilterLists(filterLists, baseFilters);
376
377 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
378 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
379 }
380
381 // Pbuffer surfaces
382 {
383 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
384 addChild(pbufferGroup);
385
386 eglu::FilterList baseFilters;
387 baseFilters << surfaceType<EGL_PBUFFER_BIT>;
388
389 vector<NamedFilterList> filterLists;
390 getDefaultFilterLists(filterLists, baseFilters);
391
392 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
393 pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
394 }
395
396 // Window surfaces with new platform extension
397 {
398 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension");
399 addChild(windowGroup);
400
401 eglu::FilterList baseFilters;
402 baseFilters << surfaceType<EGL_WINDOW_BIT>;
403
404 vector<NamedFilterList> filterLists;
405 getDefaultFilterLists(filterLists, baseFilters);
406
407 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
408 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
409 }
410
411 // Pixmap surfaces with new platform extension
412 {
413 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension");
414 addChild(pixmapGroup);
415
416 eglu::FilterList baseFilters;
417 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
418
419 vector<NamedFilterList> filterLists;
420 getDefaultFilterLists(filterLists, baseFilters);
421
422 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
423 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
424 }
425 //
426 // Window surfaces with EGL 1.5 CreateWindowSurface
427 {
428 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5");
429 addChild(windowGroup);
430
431 eglu::FilterList baseFilters;
432 baseFilters << surfaceType<EGL_WINDOW_BIT>;
433
434 vector<NamedFilterList> filterLists;
435 getDefaultFilterLists(filterLists, baseFilters);
436
437 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
438 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
439 }
440
441 // Pixmap surfaces with EGL 1.5 CreateWindowSurface
442 {
443 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5");
444 addChild(pixmapGroup);
445
446 eglu::FilterList baseFilters;
447 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
448
449 vector<NamedFilterList> filterLists;
450 getDefaultFilterLists(filterLists, baseFilters);
451
452 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
453 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
454 }
455 }
456
457 } // egl
458 } // deqp
459