• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
20 
21 #include <configstore/Utils.h>
22 #include <utils/String8.h>
23 
24 #include <EGL/egl.h>
25 #include <gui/Surface.h>
26 #include <gui/IConsumerListener.h>
27 #include <gui/IProducerListener.h>
28 #include <gui/IGraphicBufferConsumer.h>
29 #include <gui/BufferQueue.h>
30 
hasEglExtension(EGLDisplay dpy,const char * extensionName)31 bool hasEglExtension(EGLDisplay dpy, const char* extensionName) {
32     const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
33     size_t cropExtLen = strlen(extensionName);
34     size_t extsLen = strlen(exts);
35     bool equal = !strcmp(extensionName, exts);
36     android::String8 extString(extensionName);
37     android::String8 space(" ");
38     bool atStart = !strncmp(extString + space, exts, cropExtLen + 1);
39     bool atEnd = (cropExtLen + 1) < extsLen &&
40             !strcmp(space + extString, exts + extsLen - (cropExtLen + 1));
41     bool inMiddle = strstr(exts, space + extString + space);
42     return equal || atStart || atEnd || inMiddle;
43 }
44 
45 namespace android {
46 
47 #define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE)
48 
49 // retrieve wide-color setting from configstore
50 using namespace android::hardware::configstore;
51 using namespace android::hardware::configstore::V1_0;
52 
53 static bool hasWideColorDisplay =
54         getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
55 
56 class EGLTest : public ::testing::Test {
57 protected:
58     EGLDisplay mEglDisplay;
59 
60 protected:
EGLTest()61     EGLTest() :
62             mEglDisplay(EGL_NO_DISPLAY) {
63     }
64 
SetUp()65     virtual void SetUp() {
66         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
67         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
68         ASSERT_EQ(EGL_SUCCESS, eglGetError());
69 
70         EGLint majorVersion;
71         EGLint minorVersion;
72         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
73         ASSERT_EQ(EGL_SUCCESS, eglGetError());
74         RecordProperty("EglVersionMajor", majorVersion);
75         RecordProperty("EglVersionMajor", minorVersion);
76     }
77 
TearDown()78     virtual void TearDown() {
79         EGLBoolean success = eglTerminate(mEglDisplay);
80         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
81         ASSERT_EQ(EGL_SUCCESS, eglGetError());
82     }
83 };
84 
TEST_F(EGLTest,DISABLED_EGLConfigEightBitFirst)85 TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) {
86 
87     EGLint numConfigs;
88     EGLConfig config;
89     EGLBoolean success;
90     EGLint attrs[] = {
91             EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
92             EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
93             EGL_NONE
94     };
95 
96     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
97     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
98     ASSERT_EQ(EGL_SUCCESS, eglGetError());
99     ASSERT_GE(numConfigs, 1);
100 
101     EGLint components[3];
102 
103     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
104     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
105     ASSERT_EQ(EGL_SUCCESS, eglGetError());
106     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
107     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
108     ASSERT_EQ(EGL_SUCCESS, eglGetError());
109     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
110     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
111     ASSERT_EQ(EGL_SUCCESS, eglGetError());
112 
113     EXPECT_GE(components[0], 8);
114     EXPECT_GE(components[1], 8);
115     EXPECT_GE(components[2], 8);
116 }
117 
TEST_F(EGLTest,EGLTerminateSucceedsWithRemainingObjects)118 TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) {
119     EGLint numConfigs;
120     EGLConfig config;
121     EGLint attrs[] = {
122         EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
123         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
124         EGL_RED_SIZE,           8,
125         EGL_GREEN_SIZE,         8,
126         EGL_BLUE_SIZE,          8,
127         EGL_ALPHA_SIZE,         8,
128         EGL_NONE
129     };
130     EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
131 
132     struct DummyConsumer : public BnConsumerListener {
133         void onFrameAvailable(const BufferItem& /* item */) override {}
134         void onBuffersReleased() override {}
135         void onSidebandStreamChanged() override {}
136     };
137 
138     // Create a EGLSurface
139     sp<IGraphicBufferProducer> producer;
140     sp<IGraphicBufferConsumer> consumer;
141     BufferQueue::createBufferQueue(&producer, &consumer);
142     consumer->consumerConnect(new DummyConsumer, false);
143     sp<Surface> mSTC = new Surface(producer);
144     sp<ANativeWindow> mANW = mSTC;
145 
146     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config,
147                                 mANW.get(), NULL);
148     ASSERT_EQ(EGL_SUCCESS, eglGetError());
149     ASSERT_NE(EGL_NO_SURFACE, eglSurface) ;
150 
151     // do not destroy eglSurface
152     // eglTerminate is called in the tear down and should destroy it for us
153 }
154 
TEST_F(EGLTest,EGLConfigRGBA8888First)155 TEST_F(EGLTest, EGLConfigRGBA8888First) {
156 
157     EGLint numConfigs;
158     EGLConfig config;
159     EGLBoolean success;
160     EGLint attrs[] = {
161             EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
162             EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
163             EGL_RED_SIZE,           8,
164             EGL_GREEN_SIZE,         8,
165             EGL_BLUE_SIZE,          8,
166             EGL_ALPHA_SIZE,         8,
167             EGL_NONE
168     };
169 
170     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
171     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
172     ASSERT_EQ(EGL_SUCCESS, eglGetError());
173     ASSERT_GE(numConfigs, 1);
174 
175     EGLint components[4];
176 
177     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
178     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
179     ASSERT_EQ(EGL_SUCCESS, eglGetError());
180     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
181     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
182     ASSERT_EQ(EGL_SUCCESS, eglGetError());
183     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
184     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
185     ASSERT_EQ(EGL_SUCCESS, eglGetError());
186     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
187     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
188     ASSERT_EQ(EGL_SUCCESS, eglGetError());
189 
190     EXPECT_GE(components[0], 8);
191     EXPECT_GE(components[1], 8);
192     EXPECT_GE(components[2], 8);
193     EXPECT_GE(components[3], 8);
194 }
195 
TEST_F(EGLTest,EGLDisplayP3)196 TEST_F(EGLTest, EGLDisplayP3) {
197     EGLint numConfigs;
198     EGLConfig config;
199     EGLBoolean success;
200 
201     if (!hasWideColorDisplay) {
202         // skip this test if device does not have wide-color display
203         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
204         return;
205     }
206 
207     // Test that display-p3 extensions exist
208     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
209     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
210 
211     // Use 8-bit to keep forcus on Display-P3 aspect
212     EGLint attrs[] = {
213             // clang-format off
214             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
215             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
216             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
217             EGL_RED_SIZE,                 8,
218             EGL_GREEN_SIZE,               8,
219             EGL_BLUE_SIZE,                8,
220             EGL_ALPHA_SIZE,               8,
221             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
222             EGL_NONE,                     EGL_NONE
223             // clang-format on
224     };
225     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
226     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
227     ASSERT_EQ(1, numConfigs);
228 
229     EGLint components[4];
230     EGLint value;
231     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
232 
233     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
234     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
235     ASSERT_EQ(EGL_SUCCESS, eglGetError());
236     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
237     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
238     ASSERT_EQ(EGL_SUCCESS, eglGetError());
239     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
240     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
241     ASSERT_EQ(EGL_SUCCESS, eglGetError());
242     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
243     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
244     ASSERT_EQ(EGL_SUCCESS, eglGetError());
245 
246     EXPECT_EQ(components[0], 8);
247     EXPECT_EQ(components[1], 8);
248     EXPECT_EQ(components[2], 8);
249     EXPECT_EQ(components[3], 8);
250 
251     struct DummyConsumer : public BnConsumerListener {
252         void onFrameAvailable(const BufferItem& /* item */) override {}
253         void onBuffersReleased() override {}
254         void onSidebandStreamChanged() override {}
255     };
256 
257     // Create a EGLSurface
258     sp<IGraphicBufferProducer> producer;
259     sp<IGraphicBufferConsumer> consumer;
260     BufferQueue::createBufferQueue(&producer, &consumer);
261     consumer->consumerConnect(new DummyConsumer, false);
262     sp<Surface> mSTC = new Surface(producer);
263     sp<ANativeWindow> mANW = mSTC;
264     EGLint winAttrs[] = {
265             // clang-format off
266             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
267             EGL_NONE,              EGL_NONE
268             // clang-format on
269     };
270 
271     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
272     ASSERT_EQ(EGL_SUCCESS, eglGetError());
273     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
274 
275     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
276     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
277     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
278 
279     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
280 }
281 
TEST_F(EGLTest,EGLDisplayP31010102)282 TEST_F(EGLTest, EGLDisplayP31010102) {
283     EGLint numConfigs;
284     EGLConfig config;
285     EGLBoolean success;
286 
287     if (!hasWideColorDisplay) {
288         // skip this test if device does not have wide-color display
289         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
290         return;
291     }
292 
293     // Test that display-p3 extensions exist
294     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
295     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
296 
297     // Use 8-bit to keep forcus on Display-P3 aspect
298     EGLint attrs[] = {
299             // clang-format off
300             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
301             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
302             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
303             EGL_RED_SIZE,                 10,
304             EGL_GREEN_SIZE,               10,
305             EGL_BLUE_SIZE,                10,
306             EGL_ALPHA_SIZE,               2,
307             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
308             EGL_NONE,                     EGL_NONE
309             // clang-format on
310     };
311     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
312     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
313     ASSERT_EQ(1, numConfigs);
314 
315     EGLint components[4];
316     EGLint value;
317     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
318 
319     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
320     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
321     ASSERT_EQ(EGL_SUCCESS, eglGetError());
322     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
323     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
324     ASSERT_EQ(EGL_SUCCESS, eglGetError());
325     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
326     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
327     ASSERT_EQ(EGL_SUCCESS, eglGetError());
328     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
329     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
330     ASSERT_EQ(EGL_SUCCESS, eglGetError());
331 
332     EXPECT_EQ(components[0], 10);
333     EXPECT_EQ(components[1], 10);
334     EXPECT_EQ(components[2], 10);
335     EXPECT_EQ(components[3], 2);
336 
337     struct DummyConsumer : public BnConsumerListener {
338         void onFrameAvailable(const BufferItem& /* item */) override {}
339         void onBuffersReleased() override {}
340         void onSidebandStreamChanged() override {}
341     };
342 
343     // Create a EGLSurface
344     sp<IGraphicBufferProducer> producer;
345     sp<IGraphicBufferConsumer> consumer;
346     BufferQueue::createBufferQueue(&producer, &consumer);
347     consumer->consumerConnect(new DummyConsumer, false);
348     sp<Surface> mSTC = new Surface(producer);
349     sp<ANativeWindow> mANW = mSTC;
350     EGLint winAttrs[] = {
351             // clang-format off
352             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
353             EGL_NONE,              EGL_NONE
354             // clang-format on
355     };
356 
357     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
358     ASSERT_EQ(EGL_SUCCESS, eglGetError());
359     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
360 
361     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
362     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
363     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
364 
365     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
366 }
367 
TEST_F(EGLTest,EGLConfigFP16)368 TEST_F(EGLTest, EGLConfigFP16) {
369     EGLint numConfigs;
370     EGLConfig config;
371     EGLBoolean success;
372 
373     if (!hasWideColorDisplay) {
374         // skip this test if device does not have wide-color display
375         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
376         return;
377     }
378 
379     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
380 
381     EGLint attrs[] = {
382             // clang-format off
383             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
384             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
385             EGL_RED_SIZE,                 16,
386             EGL_GREEN_SIZE,               16,
387             EGL_BLUE_SIZE,                16,
388             EGL_ALPHA_SIZE,               16,
389             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
390             EGL_NONE,                     EGL_NONE
391             // clang-format on
392     };
393     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
394     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
395     ASSERT_EQ(1, numConfigs);
396 
397     EGLint components[4];
398 
399     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
400     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
401     ASSERT_EQ(EGL_SUCCESS, eglGetError());
402     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
403     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
404     ASSERT_EQ(EGL_SUCCESS, eglGetError());
405     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
406     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
407     ASSERT_EQ(EGL_SUCCESS, eglGetError());
408     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
409     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
410     ASSERT_EQ(EGL_SUCCESS, eglGetError());
411 
412     EXPECT_GE(components[0], 16);
413     EXPECT_GE(components[1], 16);
414     EXPECT_GE(components[2], 16);
415     EXPECT_GE(components[3], 16);
416 
417     struct DummyConsumer : public BnConsumerListener {
418         void onFrameAvailable(const BufferItem& /* item */) override {}
419         void onBuffersReleased() override {}
420         void onSidebandStreamChanged() override {}
421     };
422 
423     sp<IGraphicBufferProducer> producer;
424     sp<IGraphicBufferConsumer> consumer;
425     BufferQueue::createBufferQueue(&producer, &consumer);
426     consumer->consumerConnect(new DummyConsumer, false);
427     sp<Surface> mSTC = new Surface(producer);
428     sp<ANativeWindow> mANW = mSTC;
429 
430     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
431     ASSERT_EQ(EGL_SUCCESS, eglGetError());
432     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
433 
434     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
435 }
436 
TEST_F(EGLTest,EGLNoConfigContext)437 TEST_F(EGLTest, EGLNoConfigContext) {
438     if (!hasWideColorDisplay) {
439         // skip this test if device does not have wide-color display
440         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
441         return;
442     }
443 
444     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
445 
446     struct DummyConsumer : public BnConsumerListener {
447         void onFrameAvailable(const BufferItem& /* item */) override {}
448         void onBuffersReleased() override {}
449         void onSidebandStreamChanged() override {}
450     };
451 
452     std::vector<EGLint> contextAttributes;
453     contextAttributes.reserve(4);
454     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
455     contextAttributes.push_back(2);
456     contextAttributes.push_back(EGL_NONE);
457     contextAttributes.push_back(EGL_NONE);
458 
459     EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
460                                              contextAttributes.data());
461     EXPECT_NE(EGL_NO_CONTEXT, eglContext);
462     EXPECT_EQ(EGL_SUCCESS, eglGetError());
463 
464     if (eglContext != EGL_NO_CONTEXT) {
465         eglDestroyContext(mEglDisplay, eglContext);
466     }
467 }
468 
469 // Emulate what a native application would do to create a
470 // 10:10:10:2 surface.
TEST_F(EGLTest,EGLConfig1010102)471 TEST_F(EGLTest, EGLConfig1010102) {
472     EGLint numConfigs;
473     EGLConfig config;
474     EGLBoolean success;
475 
476     if (!hasWideColorDisplay) {
477         // skip this test if device does not have wide-color display
478         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
479         return;
480     }
481 
482     EGLint attrs[] = {
483             // clang-format off
484             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
485             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
486             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
487             EGL_RED_SIZE,                 10,
488             EGL_GREEN_SIZE,               10,
489             EGL_BLUE_SIZE,                10,
490             EGL_ALPHA_SIZE,               2,
491             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
492             EGL_NONE,                     EGL_NONE
493             // clang-format on
494     };
495     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
496     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
497     ASSERT_EQ(1, numConfigs);
498 
499     EGLint components[4];
500     EGLint value;
501     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
502 
503     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
504     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
505     ASSERT_EQ(EGL_SUCCESS, eglGetError());
506     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
507     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
508     ASSERT_EQ(EGL_SUCCESS, eglGetError());
509     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
510     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
511     ASSERT_EQ(EGL_SUCCESS, eglGetError());
512     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
513     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
514     ASSERT_EQ(EGL_SUCCESS, eglGetError());
515 
516     EXPECT_EQ(components[0], 10);
517     EXPECT_EQ(components[1], 10);
518     EXPECT_EQ(components[2], 10);
519     EXPECT_EQ(components[3], 2);
520 
521     struct DummyConsumer : public BnConsumerListener {
522         void onFrameAvailable(const BufferItem& /* item */) override {}
523         void onBuffersReleased() override {}
524         void onSidebandStreamChanged() override {}
525     };
526 
527     // Create a EGLSurface
528     sp<IGraphicBufferProducer> producer;
529     sp<IGraphicBufferConsumer> consumer;
530     BufferQueue::createBufferQueue(&producer, &consumer);
531     consumer->consumerConnect(new DummyConsumer, false);
532     sp<Surface> mSTC = new Surface(producer);
533     sp<ANativeWindow> mANW = mSTC;
534 
535     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
536     ASSERT_EQ(EGL_SUCCESS, eglGetError());
537     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
538 
539     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
540 }
541 }
542