1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
5 * Copyright 2014 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 Simple surface construction test.
22 *//*--------------------------------------------------------------------*/
24 #include "teglCreateSurfaceTests.hpp"
26 #include "egluNativeDisplay.hpp"
27 #include "egluNativeWindow.hpp"
28 #include "egluNativePixmap.hpp"
29 #include "egluUtil.hpp"
30 #include "egluUnique.hpp"
32 #include "eglwLibrary.hpp"
33 #include "eglwEnums.hpp"
35 #include "teglSimpleConfigCase.hpp"
36 #include "tcuTestContext.hpp"
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
40 #include "deStringUtil.hpp"
41 #include "deSTLUtil.hpp"
42 #include "deUniquePtr.hpp"
58 #define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor))
67 void checkEGLPlatformSupport (const Library& egl)
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__);
74 void checkEGL15Support (const Library& egl, EGLDisplay display)
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__);
87 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, ApiType createType)
89 const Library& egl = nativeDisplay.getLibrary();
90 EGLSurface surface = EGL_NO_SURFACE;
96 surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
97 EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
102 checkEGLPlatformSupport(egl);
103 void *nativeWindow = window.getPlatformExtension();
104 surface = egl.createPlatformWindowSurfaceEXT(display, config, nativeWindow, DE_NULL);
105 EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
110 checkEGL15Support(egl, display);
111 surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), DE_NULL);
112 EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface() failed");
119 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, ApiType createType)
121 const Library& egl = nativeDisplay.getLibrary();
122 EGLSurface surface = EGL_NO_SURFACE;
127 surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
128 EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
131 checkEGLPlatformSupport(egl);
132 surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), DE_NULL);
133 EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
136 surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL);
137 EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed");
144 class CreateWindowSurfaceCase : public SimpleConfigCase
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)
153 void executeForConfig (EGLDisplay display, EGLConfig config)
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());
160 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
162 switch (m_createType)
166 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
167 TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
172 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
173 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
178 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
179 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()");
184 log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
185 EGLU_CHECK_MSG(egl, "init");
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));
193 EGLint windowWidth = 0;
194 EGLint windowHeight = 0;
196 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &windowWidth));
197 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &windowHeight));
199 if (windowWidth <= 0 || windowHeight <= 0)
201 log << TestLog::Message << " Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
202 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
205 log << TestLog::Message << " Pass" << TestLog::EndMessage;
210 ApiType m_createType;
213 class CreatePixmapSurfaceCase : public SimpleConfigCase
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)
222 void executeForConfig (EGLDisplay display, EGLConfig config)
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());
229 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
231 switch (m_createType)
235 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
236 TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
241 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
242 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
247 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
248 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()");
253 log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
254 EGLU_CHECK_MSG(egl, "init");
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;
264 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &pixmapWidth));
265 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &pixmapHeight));
267 if (pixmapWidth <= 0 || pixmapHeight <= 0)
269 log << TestLog::Message << " Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
270 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
273 log << TestLog::Message << " Pass" << TestLog::EndMessage;
278 ApiType m_createType;
281 class CreatePbufferSurfaceCase : public SimpleConfigCase
284 CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
285 : SimpleConfigCase(eglTestCtx, name, description, filters)
289 void executeForConfig (EGLDisplay display, EGLConfig config)
291 const Library& egl = m_eglTestCtx.getLibrary();
292 TestLog& log = m_testCtx.getLog();
293 EGLint id = eglu::getConfigID(egl, display, config);
297 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
299 log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
300 EGLU_CHECK_MSG(egl, "init");
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));
306 if (width == 0 || height == 0)
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");
313 // \todo [2011-03-23 pyry] Texture-backed variants!
315 const EGLint attribs[] =
319 EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE,
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);
328 log << TestLog::Message << " Pass" << TestLog::EndMessage;
334 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
335 : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
339 CreateSurfaceTests::~CreateSurfaceTests (void)
343 template <deUint32 Type>
344 static bool surfaceType (const eglu::CandidateConfig& c)
346 return (c.surfaceType() & Type) == Type;
349 void CreateSurfaceTests::init (void)
353 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
354 addChild(windowGroup);
356 eglu::FilterList baseFilters;
357 baseFilters << surfaceType<EGL_WINDOW_BIT>;
359 vector<NamedFilterList> filterLists;
360 getDefaultFilterLists(filterLists, baseFilters);
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));
368 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
369 addChild(pixmapGroup);
371 eglu::FilterList baseFilters;
372 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
374 vector<NamedFilterList> filterLists;
375 getDefaultFilterLists(filterLists, baseFilters);
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));
383 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
384 addChild(pbufferGroup);
386 eglu::FilterList baseFilters;
387 baseFilters << surfaceType<EGL_PBUFFER_BIT>;
389 vector<NamedFilterList> filterLists;
390 getDefaultFilterLists(filterLists, baseFilters);
392 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
393 pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
396 // Window surfaces with new platform extension
398 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension");
399 addChild(windowGroup);
401 eglu::FilterList baseFilters;
402 baseFilters << surfaceType<EGL_WINDOW_BIT>;
404 vector<NamedFilterList> filterLists;
405 getDefaultFilterLists(filterLists, baseFilters);
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));
411 // Pixmap surfaces with new platform extension
413 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension");
414 addChild(pixmapGroup);
416 eglu::FilterList baseFilters;
417 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
419 vector<NamedFilterList> filterLists;
420 getDefaultFilterLists(filterLists, baseFilters);
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));
426 // Window surfaces with EGL 1.5 CreateWindowSurface
428 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5");
429 addChild(windowGroup);
431 eglu::FilterList baseFilters;
432 baseFilters << surfaceType<EGL_WINDOW_BIT>;
434 vector<NamedFilterList> filterLists;
435 getDefaultFilterLists(filterLists, baseFilters);
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));
441 // Pixmap surfaces with EGL 1.5 CreateWindowSurface
443 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5");
444 addChild(pixmapGroup);
446 eglu::FilterList baseFilters;
447 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
449 vector<NamedFilterList> filterLists;
450 getDefaultFilterLists(filterLists, baseFilters);
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));