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