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 checkEGL15Support(egl, display);
137 surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL);
138 EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed");
145 class CreateWindowSurfaceCase : public SimpleConfigCase
148 CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
149 : SimpleConfigCase (eglTestCtx, name, description, filters)
150 , m_createType (createType)
154 void executeForConfig (EGLDisplay display, EGLConfig config)
156 const Library& egl = m_eglTestCtx.getLibrary();
157 TestLog& log = m_testCtx.getLog();
158 EGLint id = eglu::getConfigID(egl, display, config);
159 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
161 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
163 switch (m_createType)
167 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
168 TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
173 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
174 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
179 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
180 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()");
185 log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
186 EGLU_CHECK_MSG(egl, "init");
189 const int width = 64;
190 const int height = 64;
191 de::UniquePtr<eglu::NativeWindow> window (windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
192 eglu::UniqueSurface surface (egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_createType));
194 EGLint windowWidth = 0;
195 EGLint windowHeight = 0;
197 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &windowWidth));
198 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &windowHeight));
200 if (windowWidth <= 0 || windowHeight <= 0)
202 log << TestLog::Message << " Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
203 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
206 log << TestLog::Message << " Pass" << TestLog::EndMessage;
211 ApiType m_createType;
214 class CreatePixmapSurfaceCase : public SimpleConfigCase
217 CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
218 : SimpleConfigCase(eglTestCtx, name, description, filters)
219 , m_createType (createType)
223 void executeForConfig (EGLDisplay display, EGLConfig config)
225 const Library& egl = m_eglTestCtx.getLibrary();
226 TestLog& log = m_testCtx.getLog();
227 EGLint id = eglu::getConfigID(egl, display, config);
228 const eglu::NativePixmapFactory& pixmapFactory = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
230 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
232 switch (m_createType)
236 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
237 TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
242 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
243 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
248 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
249 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()");
254 log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
255 EGLU_CHECK_MSG(egl, "init");
258 const int width = 64;
259 const int height = 64;
260 de::UniquePtr<eglu::NativePixmap> pixmap (pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
261 eglu::UniqueSurface surface (egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_createType));
262 EGLint pixmapWidth = 0;
263 EGLint pixmapHeight = 0;
265 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH, &pixmapWidth));
266 EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT, &pixmapHeight));
268 if (pixmapWidth <= 0 || pixmapHeight <= 0)
270 log << TestLog::Message << " Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
271 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
274 log << TestLog::Message << " Pass" << TestLog::EndMessage;
279 ApiType m_createType;
282 class CreatePbufferSurfaceCase : public SimpleConfigCase
285 CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
286 : SimpleConfigCase(eglTestCtx, name, description, filters)
290 void executeForConfig (EGLDisplay display, EGLConfig config)
292 const Library& egl = m_eglTestCtx.getLibrary();
293 TestLog& log = m_testCtx.getLog();
294 EGLint id = eglu::getConfigID(egl, display, config);
298 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
300 log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
301 EGLU_CHECK_MSG(egl, "init");
303 // Clamp to maximums reported by implementation
304 width = deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
305 height = deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
307 if (width == 0 || height == 0)
309 log << TestLog::Message << " Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
310 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
314 // \todo [2011-03-23 pyry] Texture-backed variants!
316 const EGLint attribs[] =
320 EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE,
324 EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
325 EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
326 TCU_CHECK(surface != EGL_NO_SURFACE);
327 egl.destroySurface(display, surface);
329 log << TestLog::Message << " Pass" << TestLog::EndMessage;
335 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
336 : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
340 CreateSurfaceTests::~CreateSurfaceTests (void)
344 template <deUint32 Type>
345 static bool surfaceType (const eglu::CandidateConfig& c)
347 return (c.surfaceType() & Type) == Type;
350 void CreateSurfaceTests::init (void)
354 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
355 addChild(windowGroup);
357 eglu::FilterList baseFilters;
358 baseFilters << surfaceType<EGL_WINDOW_BIT>;
360 vector<NamedFilterList> filterLists;
361 getDefaultFilterLists(filterLists, baseFilters);
363 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
364 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
369 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
370 addChild(pixmapGroup);
372 eglu::FilterList baseFilters;
373 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
375 vector<NamedFilterList> filterLists;
376 getDefaultFilterLists(filterLists, baseFilters);
378 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
379 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
384 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
385 addChild(pbufferGroup);
387 eglu::FilterList baseFilters;
388 baseFilters << surfaceType<EGL_PBUFFER_BIT>;
390 vector<NamedFilterList> filterLists;
391 getDefaultFilterLists(filterLists, baseFilters);
393 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
394 pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
397 // Window surfaces with new platform extension
399 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension");
400 addChild(windowGroup);
402 eglu::FilterList baseFilters;
403 baseFilters << surfaceType<EGL_WINDOW_BIT>;
405 vector<NamedFilterList> filterLists;
406 getDefaultFilterLists(filterLists, baseFilters);
408 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
409 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
412 // Pixmap surfaces with new platform extension
414 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension");
415 addChild(pixmapGroup);
417 eglu::FilterList baseFilters;
418 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
420 vector<NamedFilterList> filterLists;
421 getDefaultFilterLists(filterLists, baseFilters);
423 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
424 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
427 // Window surfaces with EGL 1.5 CreateWindowSurface
429 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5");
430 addChild(windowGroup);
432 eglu::FilterList baseFilters;
433 baseFilters << surfaceType<EGL_WINDOW_BIT>;
435 vector<NamedFilterList> filterLists;
436 getDefaultFilterLists(filterLists, baseFilters);
438 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
439 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
442 // Pixmap surfaces with EGL 1.5 CreateWindowSurface
444 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5");
445 addChild(pixmapGroup);
447 eglu::FilterList baseFilters;
448 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
450 vector<NamedFilterList> filterLists;
451 getDefaultFilterLists(filterLists, baseFilters);
453 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
454 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));