1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EGLPrintEGLinfoTest.cpp:
7 //   This test prints out the extension strings, configs and their attributes
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include "common/string_utils.h"
13 #include "test_utils/ANGLETest.h"
14 
15 using namespace angle;
16 
17 class EGLPrintEGLinfoTest : public ANGLETest
18 {
19   protected:
EGLPrintEGLinfoTest()20     EGLPrintEGLinfoTest() {}
21 
testSetUp()22     void testSetUp() override
23     {
24         mDisplay = getEGLWindow()->getDisplay();
25         ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
26     }
27 
28     EGLDisplay mDisplay = EGL_NO_DISPLAY;
29 };
30 
31 namespace
32 {
33 // Parse space separated extension string into a vector of strings
ParseExtensions(const char * extensions)34 std::vector<std::string> ParseExtensions(const char *extensions)
35 {
36     std::string extensionsStr(extensions);
37     std::vector<std::string> extensionsVec;
38     SplitStringAlongWhitespace(extensionsStr, &extensionsVec);
39     return extensionsVec;
40 }
41 
42 // Query a EGL attribute
GetAttrib(EGLDisplay display,EGLConfig config,EGLint attrib)43 EGLint GetAttrib(EGLDisplay display, EGLConfig config, EGLint attrib)
44 {
45     EGLint value = 0;
46     EXPECT_EGL_TRUE(eglGetConfigAttrib(display, config, attrib, &value));
47     return value;
48 }
49 
50 // Query a egl string
GetEGLString(EGLDisplay display,EGLint name)51 const char *GetEGLString(EGLDisplay display, EGLint name)
52 {
53     const char *value = "";
54     value             = eglQueryString(display, name);
55     EXPECT_TRUE(value != nullptr);
56     return value;
57 }
58 
59 // Query a GL string
GetGLString(EGLint name)60 const char *GetGLString(EGLint name)
61 {
62     const char *value = "";
63     value             = reinterpret_cast<const char *>(glGetString(name));
64     EXPECT_TRUE(value != nullptr);
65     return value;
66 }
67 
68 }  // namespace
69 
70 // Print the EGL strings and extensions
TEST_P(EGLPrintEGLinfoTest,PrintEGLInfo)71 TEST_P(EGLPrintEGLinfoTest, PrintEGLInfo)
72 {
73     std::cout << "    EGL Information:" << std::endl;
74     std::cout << "\tVendor: " << GetEGLString(mDisplay, EGL_VENDOR) << std::endl;
75     std::cout << "\tVersion: " << GetEGLString(mDisplay, EGL_VENDOR) << std::endl;
76     std::cout << "\tClient APIs: " << GetEGLString(mDisplay, EGL_CLIENT_APIS) << std::endl;
77 
78     std::cout << "\tEGL Client Extensions:" << std::endl;
79     for (auto extension : ParseExtensions(GetEGLString(EGL_NO_DISPLAY, EGL_EXTENSIONS)))
80     {
81         std::cout << "\t\t" << extension << std::endl;
82     }
83 
84     std::cout << "\tEGL Display Extensions:" << std::endl;
85     for (auto extension : ParseExtensions(GetEGLString(mDisplay, EGL_EXTENSIONS)))
86     {
87         std::cout << "\t\t" << extension << std::endl;
88     }
89 
90     std::cout << std::endl;
91 }
92 
93 // Print the GL strings and extensions
TEST_P(EGLPrintEGLinfoTest,PrintGLInfo)94 TEST_P(EGLPrintEGLinfoTest, PrintGLInfo)
95 {
96     std::cout << "    GLES Information:" << std::endl;
97     std::cout << "\tVendor: " << GetGLString(GL_VENDOR) << std::endl;
98     std::cout << "\tVersion: " << GetGLString(GL_VERSION) << std::endl;
99     std::cout << "\tRenderer: " << GetGLString(GL_RENDERER) << std::endl;
100     std::cout << "\tShader: " << GetGLString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
101 
102     std::cout << "\tExtensions:" << std::endl;
103     for (auto extension : ParseExtensions(GetGLString(GL_EXTENSIONS)))
104     {
105         std::cout << "\t\t" << extension << std::endl;
106     }
107 
108     std::cout << std::endl;
109 }
110 
111 #define QUERY_HELPER(enumValue, enumString, stream)                                    \
112     {                                                                                  \
113         GLint result;                                                                  \
114         glGetIntegerv(enumValue, &result);                                             \
115         ASSERT_GL_NO_ERROR();                                                          \
116         stream << enumString + std::string(",") + std::to_string(result) << std::endl; \
117     }
118 
119 #define QUERY_ARRAY_HELPER(enumValue, enumString, size, stream)               \
120     {                                                                         \
121         GLint result[size];                                                   \
122         glGetIntegerv(enumValue, result);                                     \
123         ASSERT_GL_NO_ERROR();                                                 \
124         std::stringstream results;                                            \
125         for (int i = 0; i < size; i++)                                        \
126             results << result[i] << " ";                                      \
127         stream << enumString + std::string(",") + results.str() << std::endl; \
128     }
129 
130 #define QUERY_INDEXED_HELPER(enumValue, enumString, index, stream)                     \
131     {                                                                                  \
132         GLint result;                                                                  \
133         glGetIntegeri_v(enumValue, index, &result);                                    \
134         ASSERT_GL_NO_ERROR();                                                          \
135         stream << enumString + std::string(",") + std::to_string(result) << std::endl; \
136     }
137 
138 #define QUERY_AND_LOG_CAPABILITY(enum, stream) QUERY_HELPER(enum, #enum, stream)
139 
140 #define QUERY_AND_LOG_CAPABILITY_ARRAY(enum, size, stream) \
141     QUERY_ARRAY_HELPER(enum, #enum, size, stream)
142 
143 #define QUERY_AND_LOG_CAPABILITY_INDEXED(enum, index, stream) \
144     QUERY_INDEXED_HELPER(enum, #enum "[" #index "]", index, stream)
145 
LogGles2Capabilities(std::ostream & stream)146 static void LogGles2Capabilities(std::ostream &stream)
147 {
148     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, stream);
149     QUERY_AND_LOG_CAPABILITY(GL_MAX_CUBE_MAP_TEXTURE_SIZE, stream);
150     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_UNIFORM_VECTORS, stream);
151     QUERY_AND_LOG_CAPABILITY(GL_MAX_RENDERBUFFER_SIZE, stream);
152     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_IMAGE_UNITS, stream);
153     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_SIZE, stream);
154     QUERY_AND_LOG_CAPABILITY(GL_MAX_VARYING_VECTORS, stream);
155     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIBS, stream);
156     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, stream);
157     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_UNIFORM_VECTORS, stream);
158     constexpr int kMaxViewPortDimsReturnValuesSize = 2;
159     QUERY_AND_LOG_CAPABILITY_ARRAY(GL_MAX_VIEWPORT_DIMS, kMaxViewPortDimsReturnValuesSize, stream);
160     QUERY_AND_LOG_CAPABILITY(GL_NUM_COMPRESSED_TEXTURE_FORMATS, stream);
161     QUERY_AND_LOG_CAPABILITY(GL_NUM_SHADER_BINARY_FORMATS, stream);
162 }
163 
LogGles3Capabilities(std::ostream & stream)164 static void LogGles3Capabilities(std::ostream &stream)
165 {
166     QUERY_AND_LOG_CAPABILITY(GL_MAX_3D_TEXTURE_SIZE, stream);
167     QUERY_AND_LOG_CAPABILITY(GL_MAX_ARRAY_TEXTURE_LAYERS, stream);
168     QUERY_AND_LOG_CAPABILITY(GL_MAX_COLOR_ATTACHMENTS, stream);
169     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, stream);
170     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_UNIFORM_BLOCKS, stream);
171     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, stream);
172     QUERY_AND_LOG_CAPABILITY(GL_MAX_DRAW_BUFFERS, stream);
173     QUERY_AND_LOG_CAPABILITY(GL_MAX_ELEMENT_INDEX, stream);
174     QUERY_AND_LOG_CAPABILITY(GL_MAX_ELEMENTS_INDICES, stream);
175     QUERY_AND_LOG_CAPABILITY(GL_MAX_ELEMENTS_VERTICES, stream);
176     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_INPUT_COMPONENTS, stream);
177     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, stream);
178     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, stream);
179     QUERY_AND_LOG_CAPABILITY(GL_MAX_PROGRAM_TEXEL_OFFSET, stream);
180     QUERY_AND_LOG_CAPABILITY(GL_MAX_SAMPLES, stream);
181     QUERY_AND_LOG_CAPABILITY(GL_MAX_SERVER_WAIT_TIMEOUT, stream);
182     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_LOD_BIAS, stream);
183     QUERY_AND_LOG_CAPABILITY(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, stream);
184     QUERY_AND_LOG_CAPABILITY(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, stream);
185     QUERY_AND_LOG_CAPABILITY(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, stream);
186     QUERY_AND_LOG_CAPABILITY(GL_MAX_UNIFORM_BLOCK_SIZE, stream);
187     QUERY_AND_LOG_CAPABILITY(GL_MAX_UNIFORM_BUFFER_BINDINGS, stream);
188     QUERY_AND_LOG_CAPABILITY(GL_MAX_VARYING_COMPONENTS, stream);
189     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_OUTPUT_COMPONENTS, stream);
190     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_UNIFORM_BLOCKS, stream);
191     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_UNIFORM_COMPONENTS, stream);
192     QUERY_AND_LOG_CAPABILITY(GL_MIN_PROGRAM_TEXEL_OFFSET, stream);
193     QUERY_AND_LOG_CAPABILITY(GL_NUM_PROGRAM_BINARY_FORMATS, stream);
194     // GLES3 capabilities are a superset of GLES2
195     LogGles2Capabilities(stream);
196 }
197 
LogGles31Capabilities(std::ostream & stream)198 static void LogGles31Capabilities(std::ostream &stream)
199 {
200     QUERY_AND_LOG_CAPABILITY(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, stream);
201     QUERY_AND_LOG_CAPABILITY(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, stream);
202     QUERY_AND_LOG_CAPABILITY(GL_MAX_COLOR_TEXTURE_SAMPLES, stream);
203     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, stream);
204     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_ATOMIC_COUNTERS, stream);
205     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, stream);
206     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_IMAGE_UNIFORMS, stream);
207     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, stream);
208     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, stream);
209     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, stream);
210     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_ATOMIC_COUNTERS, stream);
211     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_IMAGE_UNIFORMS, stream);
212     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, stream);
213     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, stream);
214     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, stream);
215     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_UNIFORM_BLOCKS, stream);
216     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, stream);
217     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, stream);
218     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, stream);
219     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, stream);
220     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, stream);
221     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, stream);
222     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, stream);
223     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, stream);
224     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEPTH_TEXTURE_SAMPLES, stream);
225     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, stream);
226     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, stream);
227     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, stream);
228     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, stream);
229     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_HEIGHT, stream);
230     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_SAMPLES, stream);
231     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_WIDTH, stream);
232     QUERY_AND_LOG_CAPABILITY(GL_MAX_IMAGE_UNITS, stream);
233     QUERY_AND_LOG_CAPABILITY(GL_MAX_INTEGER_SAMPLES, stream);
234     QUERY_AND_LOG_CAPABILITY(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, stream);
235     QUERY_AND_LOG_CAPABILITY(GL_MAX_SAMPLE_MASK_WORDS, stream);
236     QUERY_AND_LOG_CAPABILITY(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, stream);
237     QUERY_AND_LOG_CAPABILITY(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, stream);
238     QUERY_AND_LOG_CAPABILITY(GL_MAX_UNIFORM_LOCATIONS, stream);
239     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, stream);
240     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATOMIC_COUNTERS, stream);
241     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIB_BINDINGS, stream);
242     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, stream);
243     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIB_STRIDE, stream);
244     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_IMAGE_UNIFORMS, stream);
245     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, stream);
246     QUERY_AND_LOG_CAPABILITY(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, stream);
247 
248     // GLES31 capabilities are a superset of GLES3
249     LogGles3Capabilities(stream);
250 }
251 
LogGles32Capabilities(std::ostream & stream)252 static void LogGles32Capabilities(std::ostream &stream)
253 {
254     // Most of these capabilities are not implemented yet.
255     ANGLE_SKIP_TEST_IF(IsVulkan());
256 
257     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, stream);
258     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, stream);
259     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, stream);
260     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEBUG_GROUP_STACK_DEPTH, stream);
261     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEBUG_LOGGED_MESSAGES, stream);
262     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEBUG_MESSAGE_LENGTH, stream);
263     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, stream);
264     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_LAYERS, stream);
265     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, stream);
266     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, stream);
267     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, stream);
268     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_INPUT_COMPONENTS, stream);
269     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, stream);
270     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_OUTPUT_VERTICES, stream);
271     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, stream);
272     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, stream);
273     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, stream);
274     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, stream);
275     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, stream);
276     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, stream);
277     QUERY_AND_LOG_CAPABILITY(GL_MAX_LABEL_LENGTH, stream);
278     QUERY_AND_LOG_CAPABILITY(GL_MAX_PATCH_VERTICES, stream);
279     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS, stream);
280     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, stream);
281     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, stream);
282     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, stream);
283     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, stream);
284     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, stream);
285     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, stream);
286     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, stream);
287     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, stream);
288     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, stream);
289     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS, stream);
290     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, stream);
291     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, stream);
292     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, stream);
293     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, stream);
294     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, stream);
295     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, stream);
296     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, stream);
297     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, stream);
298     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_GEN_LEVEL, stream);
299     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_PATCH_COMPONENTS, stream);
300     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_BUFFER_SIZE, stream);
301     QUERY_AND_LOG_CAPABILITY(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, stream);
302     QUERY_AND_LOG_CAPABILITY(GL_MIN_SAMPLE_SHADING_VALUE, stream);
303 
304     // GLES32 capabilities are a superset of GLES31
305     LogGles31Capabilities(stream);
306 }
307 
308 // Prints GLES Capabilities listed at
309 // https://opengles.gpuinfo.org/listcapabilities.php
310 // in CSV format
TEST_P(EGLPrintEGLinfoTest,PrintGLESCapabilities)311 TEST_P(EGLPrintEGLinfoTest, PrintGLESCapabilities)
312 {
313     std::cout << std::endl << "Capability name, value" << std::endl << std::endl;
314 
315     std::ostream &stream = std::cout;
316 
317     switch (getClientMajorVersion())
318     {
319         case 3:
320             switch (getClientMinorVersion())
321             {
322                 case 2:
323                     LogGles32Capabilities(stream);
324                     break;
325                 case 1:
326                     LogGles31Capabilities(stream);
327                     break;
328                 case 0:
329                     LogGles3Capabilities(stream);
330                     break;
331                 default:
332                     FAIL() << "unknown client minor version.";
333             }
334             break;
335         case 2:
336             LogGles2Capabilities(stream);
337             break;
338         default:
339             FAIL() << "unknown client major version.";
340     }
341 
342     stream << std::endl;
343 }
344 
345 // Print the EGL configs with attributes
TEST_P(EGLPrintEGLinfoTest,PrintConfigInfo)346 TEST_P(EGLPrintEGLinfoTest, PrintConfigInfo)
347 {
348     // Get all the configs
349     EGLint count;
350     EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &count));
351     EXPECT_TRUE(count > 0);
352     std::vector<EGLConfig> configs(count);
353     EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), count, &count));
354     configs.resize(count);
355     // sort configs by increaing ID
356     std::sort(configs.begin(), configs.end(), [this](EGLConfig a, EGLConfig b) -> bool {
357         return GetAttrib(mDisplay, a, EGL_CONFIG_ID) < GetAttrib(mDisplay, b, EGL_CONFIG_ID);
358     });
359 
360     std::cout << "Configs - Count: " << count << std::endl;
361 
362     // For each config, print its attributes
363     for (auto config : configs)
364     {
365         // Config ID
366         std::cout << "    Config: " << GetAttrib(mDisplay, config, EGL_CONFIG_ID) << std::endl;
367 
368         // Color
369         const char *componentType = (GetAttrib(mDisplay, config, EGL_COLOR_COMPONENT_TYPE_EXT) ==
370                                      EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
371                                         ? "Float "
372                                         : "Fixed ";
373         const char *colorBuffType =
374             (GetAttrib(mDisplay, config, EGL_COLOR_BUFFER_TYPE) == EGL_LUMINANCE_BUFFER)
375                 ? "LUMINANCE"
376                 : "RGB";
377         std::cout << "\tColor:" << GetAttrib(mDisplay, config, EGL_BUFFER_SIZE) << "bit "
378                   << componentType << colorBuffType
379                   << " Red:" << GetAttrib(mDisplay, config, EGL_RED_SIZE)
380                   << " Green:" << GetAttrib(mDisplay, config, EGL_GREEN_SIZE)
381                   << " Blue:" << GetAttrib(mDisplay, config, EGL_BLUE_SIZE)
382                   << " Alpha:" << GetAttrib(mDisplay, config, EGL_ALPHA_SIZE)
383                   << " Lum:" << GetAttrib(mDisplay, config, EGL_LUMINANCE_SIZE)
384                   << " AlphaMask:" << GetAttrib(mDisplay, config, EGL_ALPHA_MASK_SIZE) << std::endl;
385 
386         // Texture Binding
387         std::cout << "\tBinding RGB:" << (bool)GetAttrib(mDisplay, config, EGL_BIND_TO_TEXTURE_RGB)
388                   << " RGBA:" << (bool)GetAttrib(mDisplay, config, EGL_BIND_TO_TEXTURE_RGBA)
389                   << " MaxWidth:" << GetAttrib(mDisplay, config, EGL_MAX_PBUFFER_WIDTH)
390                   << " MaxHeight:" << GetAttrib(mDisplay, config, EGL_MAX_PBUFFER_HEIGHT)
391                   << " MaxPixels:" << GetAttrib(mDisplay, config, EGL_MAX_PBUFFER_PIXELS)
392                   << std::endl;
393 
394         // Conformant
395         EGLint caveatAttrib = GetAttrib(mDisplay, config, EGL_CONFIG_CAVEAT);
396         const char *caveat  = nullptr;
397         switch (caveatAttrib)
398         {
399             case EGL_NONE:
400                 caveat = "None.";
401                 break;
402             case EGL_SLOW_CONFIG:
403                 caveat = "Slow.";
404                 break;
405             case EGL_NON_CONFORMANT_CONFIG:
406                 caveat = "Non-Conformant.";
407                 break;
408             default:
409                 caveat = ".";
410         }
411         std::cout << "\tCaveate: " << caveat;
412 
413         EGLint conformant = GetAttrib(mDisplay, config, EGL_CONFORMANT);
414         std::cout << " Conformant: ";
415         if (conformant & EGL_OPENGL_BIT)
416             std::cout << "OpenGL ";
417         if (conformant & EGL_OPENGL_ES_BIT)
418             std::cout << "ES1 ";
419         if (conformant & EGL_OPENGL_ES2_BIT)
420             std::cout << "ES2 ";
421         if (conformant & EGL_OPENGL_ES3_BIT)
422             std::cout << "ES3";
423         std::cout << std::endl;
424 
425         // Ancilary buffers
426         std::cout << "\tAncilary "
427                   << "Depth:" << GetAttrib(mDisplay, config, EGL_DEPTH_SIZE)
428                   << " Stencil:" << GetAttrib(mDisplay, config, EGL_STENCIL_SIZE)
429                   << " SampleBuffs:" << GetAttrib(mDisplay, config, EGL_SAMPLE_BUFFERS)
430                   << " Samples:" << GetAttrib(mDisplay, config, EGL_SAMPLES) << std::endl;
431 
432         // Swap interval
433         std::cout << "\tSwap Interval"
434                   << " Min:" << GetAttrib(mDisplay, config, EGL_MIN_SWAP_INTERVAL)
435                   << " Max:" << GetAttrib(mDisplay, config, EGL_MAX_SWAP_INTERVAL) << std::endl;
436 
437         // Native
438         std::cout << "\tNative Renderable: " << GetAttrib(mDisplay, config, EGL_NATIVE_RENDERABLE)
439                   << ", VisualID: " << GetAttrib(mDisplay, config, EGL_NATIVE_VISUAL_ID)
440                   << ", VisualType: " << GetAttrib(mDisplay, config, EGL_NATIVE_VISUAL_TYPE)
441                   << std::endl;
442 
443         // Surface type
444         EGLint surfaceType = GetAttrib(mDisplay, config, EGL_SURFACE_TYPE);
445         std::cout << "\tSurface Type: ";
446         if (surfaceType & EGL_WINDOW_BIT)
447             std::cout << "WINDOW ";
448         if (surfaceType & EGL_PIXMAP_BIT)
449             std::cout << "PIXMAP ";
450         if (surfaceType & EGL_PBUFFER_BIT)
451             std::cout << "PBUFFER ";
452         if (surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)
453             std::cout << "MULTISAMPLE_RESOLVE_BOX ";
454         if (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
455             std::cout << "SWAP_PRESERVE ";
456         std::cout << std::endl;
457 
458         // Renderable
459         EGLint rendType = GetAttrib(mDisplay, config, EGL_RENDERABLE_TYPE);
460         std::cout << "\tRender: ";
461         if (rendType & EGL_OPENGL_BIT)
462             std::cout << "OpenGL ";
463         if (rendType & EGL_OPENGL_ES_BIT)
464             std::cout << "ES1 ";
465         if (rendType & EGL_OPENGL_ES2_BIT)
466             std::cout << "ES2 ";
467         if (rendType & EGL_OPENGL_ES3_BIT)
468             std::cout << "ES3 ";
469         std::cout << std::endl;
470 
471         // Extensions
472         if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_recordable"))
473         {
474             std::cout << "\tAndroid Recordable: "
475                       << GetAttrib(mDisplay, config, EGL_RECORDABLE_ANDROID) << std::endl;
476         }
477         if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_framebuffer_target"))
478         {
479             std::cout << "\tAndroid framebuffer target: "
480                       << GetAttrib(mDisplay, config, EGL_FRAMEBUFFER_TARGET_ANDROID) << std::endl;
481         }
482 
483         // Separator between configs
484         std::cout << std::endl;
485     }
486 }
487 
488 ANGLE_INSTANTIATE_TEST(EGLPrintEGLinfoTest, ES2_VULKAN(), ES3_VULKAN(), ES32_VULKAN());
489 
490 // This test suite is not instantiated on some OSes.
491 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPrintEGLinfoTest);
492