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 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 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 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 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: 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 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: 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 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: 284 CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters) 285 : SimpleConfigCase(eglTestCtx, name, description, filters) 286 { 287 } 288 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 334 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx) 335 : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests") 336 { 337 } 338 339 CreateSurfaceTests::~CreateSurfaceTests (void) 340 { 341 } 342 343 template <deUint32 Type> 344 static bool surfaceType (const eglu::CandidateConfig& c) 345 { 346 return (c.surfaceType() & Type) == Type; 347 } 348 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