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
31 #include "teglSimpleConfigCase.hpp"
32 #include "tcuTestContext.hpp"
33 #include "tcuCommandLine.hpp"
34 #include "tcuTestLog.hpp"
35
36 #include "deSTLUtil.hpp"
37 #include "deUniquePtr.hpp"
38
39 #include <memory>
40
41 #if !defined(EGL_EXT_platform_base)
42 # define EGL_EXT_platform_base 1
43 typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
44 typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
45 typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
46 #endif // EGL_EXT_platform_base
47
48 using std::vector;
49 using tcu::TestLog;
50
51 namespace deqp
52 {
53 namespace egl
54 {
55 namespace
56 {
57
checkEGLPlatformSupport(const char * platformExt)58 void checkEGLPlatformSupport (const char* platformExt)
59 {
60 std::vector<std::string> extensions = eglu::getPlatformExtensions();
61
62 if (!de::contains(extensions.begin(), extensions.end(), platformExt))
63 throw tcu::NotSupportedError((std::string("Platform extension '") + platformExt + "' not supported").c_str(), "", __FILE__, __LINE__);
64 }
65
createWindowSurface(EGLDisplay display,EGLConfig config,eglu::NativeDisplay & nativeDisplay,eglu::NativeWindow & window,bool useLegacyCreate)66 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, bool useLegacyCreate)
67 {
68 EGLSurface surface = EGL_NO_SURFACE;
69
70 if (useLegacyCreate)
71 {
72 surface = eglCreateWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
73 TCU_CHECK_EGL_MSG("eglCreateWindowSurface() failed");
74 }
75 else
76 {
77 checkEGLPlatformSupport(nativeDisplay.getPlatformExtensionName());
78
79 PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
80 TCU_CHECK_EGL_MSG("eglGetProcAddress() failed");
81
82 surface = createPlatformWindowSurfaceEXT(display, config, window.getPlatformNative(), DE_NULL);
83 TCU_CHECK_EGL_MSG("eglCreatePlatformWindowSurfaceEXT() failed");
84 }
85
86 return surface;
87 }
88
createPixmapSurface(EGLDisplay display,EGLConfig config,eglu::NativeDisplay & nativeDisplay,eglu::NativePixmap & pixmap,bool useLegacyCreate)89 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, bool useLegacyCreate)
90 {
91 EGLSurface surface = EGL_NO_SURFACE;
92
93 if (useLegacyCreate)
94 {
95 surface = eglCreatePixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
96 TCU_CHECK_EGL_MSG("eglCreatePixmapSurface() failed");
97 }
98 else
99 {
100 checkEGLPlatformSupport(nativeDisplay.getPlatformExtensionName());
101
102 PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC createPlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformPixmapSurfaceEXT");
103 TCU_CHECK_EGL_MSG("eglGetProcAddress() failed");
104
105 surface = createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformNative(), DE_NULL);
106 TCU_CHECK_EGL_MSG("eglCreatePlatformPixmapSurfaceEXT() failed");
107 }
108
109 return surface;
110 }
111
112 class CreateWindowSurfaceCase : public SimpleConfigCase
113 {
114 public:
CreateWindowSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,bool useLegacyCreate,const vector<EGLint> & configIds)115 CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool useLegacyCreate, const vector<EGLint>& configIds)
116 : SimpleConfigCase (eglTestCtx, name, description, configIds)
117 , m_useLegacyCreate (useLegacyCreate)
118 {
119 }
120
executeForConfig(tcu::egl::Display & display,EGLConfig config)121 void executeForConfig (tcu::egl::Display& display, EGLConfig config)
122 {
123 TestLog& log = m_testCtx.getLog();
124 EGLint id = display.getConfigAttrib(config, EGL_CONFIG_ID);
125
126 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
127
128 if (m_useLegacyCreate)
129 {
130 if ((m_eglTestCtx.getNativeWindowFactory().getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
131 throw tcu::NotSupportedError("Native window doesn't support legacy eglCreateWindowSurface()", "", __FILE__, __LINE__);
132 }
133 else
134 {
135 if ((m_eglTestCtx.getNativeWindowFactory().getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
136 throw tcu::NotSupportedError("Native window doesn't support eglCreatePlatformWindowSurfaceEXT()", "", __FILE__, __LINE__);
137 }
138
139 log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
140 TCU_CHECK_EGL();
141
142 {
143 const int width = 64;
144 const int height = 64;
145 de::UniquePtr<eglu::NativeWindow> window (m_eglTestCtx.createNativeWindow(display.getEGLDisplay(), config, DE_NULL, width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
146 tcu::egl::WindowSurface surface (display, createWindowSurface(display.getEGLDisplay(), config, m_eglTestCtx.getNativeDisplay(), *window, m_useLegacyCreate));
147
148 EGLint windowWidth = 0;
149 EGLint windowHeight = 0;
150
151 TCU_CHECK_EGL_CALL(eglQuerySurface(display.getEGLDisplay(), surface.getEGLSurface(), EGL_WIDTH, &windowWidth));
152 TCU_CHECK_EGL_CALL(eglQuerySurface(display.getEGLDisplay(), surface.getEGLSurface(), EGL_HEIGHT, &windowHeight));
153
154 if (windowWidth <= 0 || windowHeight <= 0)
155 {
156 log << TestLog::Message << " Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
157 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
158 }
159 else
160 log << TestLog::Message << " Pass" << TestLog::EndMessage;
161 }
162 }
163
164 private:
165 bool m_useLegacyCreate;
166 };
167
168 class CreatePixmapSurfaceCase : public SimpleConfigCase
169 {
170 public:
CreatePixmapSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,bool useLegacyCreate,const vector<EGLint> & configIds)171 CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool useLegacyCreate, const vector<EGLint>& configIds)
172 : SimpleConfigCase(eglTestCtx, name, description, configIds)
173 , m_useLegacyCreate (useLegacyCreate)
174 {
175 }
176
executeForConfig(tcu::egl::Display & display,EGLConfig config)177 void executeForConfig (tcu::egl::Display& display, EGLConfig config)
178 {
179 TestLog& log = m_testCtx.getLog();
180 EGLint id = display.getConfigAttrib(config, EGL_CONFIG_ID);
181
182 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
183
184 if (m_useLegacyCreate)
185 {
186 if ((m_eglTestCtx.getNativePixmapFactory().getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
187 throw tcu::NotSupportedError("Native pixmap doesn't support legacy eglCreatePixmapSurface()", "", __FILE__, __LINE__);
188 }
189 else
190 {
191 if ((m_eglTestCtx.getNativePixmapFactory().getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
192 throw tcu::NotSupportedError("Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()", "", __FILE__, __LINE__);
193 }
194
195 log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
196 TCU_CHECK_EGL();
197
198 {
199 const int width = 64;
200 const int height = 64;
201 de::UniquePtr<eglu::NativePixmap> pixmap (m_eglTestCtx.createNativePixmap(display.getEGLDisplay(), config, DE_NULL, width, height));
202 tcu::egl::PixmapSurface surface (display, createPixmapSurface(display.getEGLDisplay(), config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_useLegacyCreate));
203 EGLint pixmapWidth = 0;
204 EGLint pixmapHeight = 0;
205
206 TCU_CHECK_EGL_CALL(eglQuerySurface(display.getEGLDisplay(), surface.getEGLSurface(), EGL_WIDTH, &pixmapWidth));
207 TCU_CHECK_EGL_CALL(eglQuerySurface(display.getEGLDisplay(), surface.getEGLSurface(), EGL_HEIGHT, &pixmapHeight));
208
209 if (pixmapWidth <= 0 || pixmapHeight <= 0)
210 {
211 log << TestLog::Message << " Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
212 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
213 }
214 else
215 log << TestLog::Message << " Pass" << TestLog::EndMessage;
216 }
217 }
218
219 private:
220 bool m_useLegacyCreate;
221 };
222
223 class CreatePbufferSurfaceCase : public SimpleConfigCase
224 {
225 public:
CreatePbufferSurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,const vector<EGLint> & configIds)226 CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const vector<EGLint>& configIds)
227 : SimpleConfigCase(eglTestCtx, name, description, configIds)
228 {
229 }
230
executeForConfig(tcu::egl::Display & display,EGLConfig config)231 void executeForConfig (tcu::egl::Display& display, EGLConfig config)
232 {
233 TestLog& log = m_testCtx.getLog();
234 EGLint id = display.getConfigAttrib(config, EGL_CONFIG_ID);
235 int width = 64;
236 int height = 64;
237
238 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
239
240 log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
241 TCU_CHECK_EGL();
242
243 // Clamp to maximums reported by implementation
244 width = deMin32(width, display.getConfigAttrib(config, EGL_MAX_PBUFFER_WIDTH));
245 height = deMin32(height, display.getConfigAttrib(config, EGL_MAX_PBUFFER_HEIGHT));
246
247 if (width == 0 || height == 0)
248 {
249 log << TestLog::Message << " Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
250 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
251 return;
252 }
253
254 // \todo [2011-03-23 pyry] Texture-backed variants!
255
256 EGLint attribs[] =
257 {
258 EGL_WIDTH, width,
259 EGL_HEIGHT, height,
260 EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE,
261 EGL_NONE
262 };
263
264 EGLSurface surface = eglCreatePbufferSurface(display.getEGLDisplay(), config, attribs);
265 TCU_CHECK_EGL_MSG("Failed to create pbuffer");
266 TCU_CHECK(surface != EGL_NO_SURFACE);
267 eglDestroySurface(display.getEGLDisplay(), surface);
268
269 log << TestLog::Message << " Pass" << TestLog::EndMessage;
270 }
271 };
272
273 } // anonymous
274
CreateSurfaceTests(EglTestContext & eglTestCtx)275 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
276 : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
277 {
278 }
279
~CreateSurfaceTests(void)280 CreateSurfaceTests::~CreateSurfaceTests (void)
281 {
282 }
283
init(void)284 void CreateSurfaceTests::init (void)
285 {
286 // Window surfaces
287 {
288 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
289 addChild(windowGroup);
290
291 eglu::FilterList filters;
292 filters << (eglu::ConfigSurfaceType() & EGL_WINDOW_BIT);
293
294 vector<NamedConfigIdSet> configIdSets;
295 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters);
296
297 for (vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++)
298 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), true, i->getConfigIds()));
299 }
300
301 // Pixmap surfaces
302 {
303 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
304 addChild(pixmapGroup);
305
306 eglu::FilterList filters;
307 filters << (eglu::ConfigSurfaceType() & EGL_PIXMAP_BIT);
308
309 vector<NamedConfigIdSet> configIdSets;
310 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters);
311
312 for (vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++)
313 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), true, i->getConfigIds()));
314 }
315
316 // Pbuffer surfaces
317 {
318 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
319 addChild(pbufferGroup);
320
321 eglu::FilterList filters;
322 filters << (eglu::ConfigSurfaceType() & EGL_PBUFFER_BIT);
323
324 vector<NamedConfigIdSet> configIdSets;
325 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters);
326
327 for (vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++)
328 pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds()));
329 }
330
331 // Window surfaces with new platform extension
332 {
333 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with platform extension");
334 addChild(windowGroup);
335
336 eglu::FilterList filters;
337 filters << (eglu::ConfigSurfaceType() & EGL_WINDOW_BIT);
338
339 vector<NamedConfigIdSet> configIdSets;
340 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters);
341
342 for (vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++)
343 windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), false, i->getConfigIds()));
344 }
345
346 // Pixmap surfaces with new platform extension
347 {
348 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with platform extension");
349 addChild(pixmapGroup);
350
351 eglu::FilterList filters;
352 filters << (eglu::ConfigSurfaceType() & EGL_PIXMAP_BIT);
353
354 vector<NamedConfigIdSet> configIdSets;
355 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters);
356
357 for (vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++)
358 pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), false, i->getConfigIds()));
359 }
360 }
361
362 } // egl
363 } // deqp
364