• 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 <SurfaceFlingerProperties.h>
20 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
21 
22 #include <configstore/Utils.h>
23 #include <utils/String8.h>
24 
25 #include <EGL/egl.h>
26 #include <gui/Surface.h>
27 #include <gui/IConsumerListener.h>
28 #include <gui/IProducerListener.h>
29 #include <gui/IGraphicBufferConsumer.h>
30 #include <gui/BufferQueue.h>
31 
hasEglExtension(EGLDisplay dpy,const char * extensionName)32 bool hasEglExtension(EGLDisplay dpy, const char* extensionName) {
33     const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
34     size_t cropExtLen = strlen(extensionName);
35     size_t extsLen = strlen(exts);
36     bool equal = !strcmp(extensionName, exts);
37     android::String8 extString(extensionName);
38     android::String8 space(" ");
39     bool atStart = !strncmp(extString + space, exts, cropExtLen + 1);
40     bool atEnd = (cropExtLen + 1) < extsLen &&
41             !strcmp(space + extString, exts + extsLen - (cropExtLen + 1));
42     bool inMiddle = strstr(exts, space + extString + space);
43     return equal || atStart || atEnd || inMiddle;
44 }
45 
46 namespace android {
47 
48 #define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE)
49 
50 // retrieve wide-color setting from configstore
51 using namespace android::hardware::configstore;
52 using namespace android::hardware::configstore::V1_0;
53 
54 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
55 
56 static bool hasWideColorDisplay = android::sysprop::has_wide_color_display(false);
57 
58 static bool hasHdrDisplay = android::sysprop::has_HDR_display(false);
59 
60 class EGLTest : public ::testing::Test {
61 public:
62     void get8BitConfig(EGLConfig& config);
63     void setSurfaceSmpteMetadata(EGLSurface surface);
64     void checkSurfaceSmpteMetadata(EGLSurface eglSurface);
65 
66 protected:
67     EGLDisplay mEglDisplay;
68 
69 protected:
EGLTest()70     EGLTest() :
71             mEglDisplay(EGL_NO_DISPLAY) {
72     }
73 
SetUp()74     virtual void SetUp() {
75         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
76         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
77         ASSERT_EQ(EGL_SUCCESS, eglGetError());
78 
79         EGLint majorVersion;
80         EGLint minorVersion;
81         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
82         ASSERT_EQ(EGL_SUCCESS, eglGetError());
83         RecordProperty("EglVersionMajor", majorVersion);
84         RecordProperty("EglVersionMajor", minorVersion);
85     }
86 
TearDown()87     virtual void TearDown() {
88         EGLBoolean success = eglTerminate(mEglDisplay);
89         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
90         ASSERT_EQ(EGL_SUCCESS, eglGetError());
91     }
92 };
93 
TEST_F(EGLTest,DISABLED_EGLConfigEightBitFirst)94 TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) {
95 
96     EGLint numConfigs;
97     EGLConfig config;
98     EGLBoolean success;
99     EGLint attrs[] = {
100             EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
101             EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
102             EGL_NONE
103     };
104 
105     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
106     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
107     ASSERT_EQ(EGL_SUCCESS, eglGetError());
108     ASSERT_GE(numConfigs, 1);
109 
110     EGLint components[3];
111 
112     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
113     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
114     ASSERT_EQ(EGL_SUCCESS, eglGetError());
115     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
116     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
117     ASSERT_EQ(EGL_SUCCESS, eglGetError());
118     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
119     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
120     ASSERT_EQ(EGL_SUCCESS, eglGetError());
121 
122     EXPECT_GE(components[0], 8);
123     EXPECT_GE(components[1], 8);
124     EXPECT_GE(components[2], 8);
125 }
126 
TEST_F(EGLTest,EGLTerminateSucceedsWithRemainingObjects)127 TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) {
128     EGLint numConfigs;
129     EGLConfig config;
130     EGLint attrs[] = {
131         EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
132         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
133         EGL_RED_SIZE,           8,
134         EGL_GREEN_SIZE,         8,
135         EGL_BLUE_SIZE,          8,
136         EGL_ALPHA_SIZE,         8,
137         EGL_NONE
138     };
139     EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
140 
141     struct MockConsumer : public BnConsumerListener {
142         void onFrameAvailable(const BufferItem& /* item */) override {}
143         void onBuffersReleased() override {}
144         void onSidebandStreamChanged() override {}
145     };
146 
147     // Create a EGLSurface
148     sp<IGraphicBufferProducer> producer;
149     sp<IGraphicBufferConsumer> consumer;
150     BufferQueue::createBufferQueue(&producer, &consumer);
151     consumer->consumerConnect(new MockConsumer, false);
152     sp<Surface> mSTC = new Surface(producer);
153     sp<ANativeWindow> mANW = mSTC;
154 
155     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config,
156                                 mANW.get(), NULL);
157     ASSERT_EQ(EGL_SUCCESS, eglGetError());
158     ASSERT_NE(EGL_NO_SURFACE, eglSurface) ;
159 
160     // do not destroy eglSurface
161     // eglTerminate is called in the tear down and should destroy it for us
162 }
163 
TEST_F(EGLTest,EGLConfigRGBA8888First)164 TEST_F(EGLTest, EGLConfigRGBA8888First) {
165 
166     EGLint numConfigs;
167     EGLConfig config;
168     EGLBoolean success;
169     EGLint attrs[] = {
170             EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
171             EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
172             EGL_RED_SIZE,           8,
173             EGL_GREEN_SIZE,         8,
174             EGL_BLUE_SIZE,          8,
175             EGL_ALPHA_SIZE,         8,
176             EGL_NONE
177     };
178 
179     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
180     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
181     ASSERT_EQ(EGL_SUCCESS, eglGetError());
182     ASSERT_GE(numConfigs, 1);
183 
184     EGLint components[4];
185 
186     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
187     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
188     ASSERT_EQ(EGL_SUCCESS, eglGetError());
189     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
190     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
191     ASSERT_EQ(EGL_SUCCESS, eglGetError());
192     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
193     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
194     ASSERT_EQ(EGL_SUCCESS, eglGetError());
195     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
196     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
197     ASSERT_EQ(EGL_SUCCESS, eglGetError());
198 
199     EXPECT_GE(components[0], 8);
200     EXPECT_GE(components[1], 8);
201     EXPECT_GE(components[2], 8);
202     EXPECT_GE(components[3], 8);
203 }
204 
TEST_F(EGLTest,EGLDisplayP3)205 TEST_F(EGLTest, EGLDisplayP3) {
206     EGLint numConfigs;
207     EGLConfig config;
208     EGLBoolean success;
209 
210     if (!hasWideColorDisplay) {
211         // skip this test if device does not have wide-color display
212         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
213         return;
214     }
215 
216     // Test that display-p3 extensions exist
217     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
218     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
219     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
220 
221     // Use 8-bit to keep forcus on Display-P3 aspect
222     EGLint attrs[] = {
223             // clang-format off
224             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
225             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
226             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
227             EGL_RED_SIZE,                 8,
228             EGL_GREEN_SIZE,               8,
229             EGL_BLUE_SIZE,                8,
230             EGL_ALPHA_SIZE,               8,
231             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
232             EGL_NONE,                     EGL_NONE
233             // clang-format on
234     };
235     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
236     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
237     ASSERT_EQ(1, numConfigs);
238 
239     EGLint components[4];
240     EGLint value;
241     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
242 
243     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
244     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
245     ASSERT_EQ(EGL_SUCCESS, eglGetError());
246     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
247     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
248     ASSERT_EQ(EGL_SUCCESS, eglGetError());
249     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
250     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
251     ASSERT_EQ(EGL_SUCCESS, eglGetError());
252     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
253     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
254     ASSERT_EQ(EGL_SUCCESS, eglGetError());
255 
256     EXPECT_EQ(components[0], 8);
257     EXPECT_EQ(components[1], 8);
258     EXPECT_EQ(components[2], 8);
259     EXPECT_EQ(components[3], 8);
260 
261     struct MockConsumer : public BnConsumerListener {
262         void onFrameAvailable(const BufferItem& /* item */) override {}
263         void onBuffersReleased() override {}
264         void onSidebandStreamChanged() override {}
265     };
266 
267     // Create a EGLSurface
268     sp<IGraphicBufferProducer> producer;
269     sp<IGraphicBufferConsumer> consumer;
270     BufferQueue::createBufferQueue(&producer, &consumer);
271     consumer->consumerConnect(new MockConsumer, false);
272     sp<Surface> mSTC = new Surface(producer);
273     sp<ANativeWindow> mANW = mSTC;
274     EGLint winAttrs[] = {
275             // clang-format off
276             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
277             EGL_NONE,              EGL_NONE
278             // clang-format on
279     };
280 
281     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
282     ASSERT_EQ(EGL_SUCCESS, eglGetError());
283     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
284 
285     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
286     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
287     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
288 
289     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
290 }
291 
TEST_F(EGLTest,EGLDisplayP3Passthrough)292 TEST_F(EGLTest, EGLDisplayP3Passthrough) {
293     EGLConfig config;
294     EGLBoolean success;
295 
296     if (!hasWideColorDisplay) {
297         // skip this test if device does not have wide-color display
298         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
299         return;
300     }
301 
302     // Test that display-p3 extensions exist
303     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
304     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
305     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
306 
307     get8BitConfig(config);
308 
309     struct MockConsumer : public BnConsumerListener {
310         void onFrameAvailable(const BufferItem& /* item */) override {}
311         void onBuffersReleased() override {}
312         void onSidebandStreamChanged() override {}
313     };
314 
315     // Create a EGLSurface
316     sp<IGraphicBufferProducer> producer;
317     sp<IGraphicBufferConsumer> consumer;
318     BufferQueue::createBufferQueue(&producer, &consumer);
319     consumer->consumerConnect(new MockConsumer, false);
320     sp<Surface> mSTC = new Surface(producer);
321     sp<ANativeWindow> mANW = mSTC;
322     EGLint winAttrs[] = {
323             // clang-format off
324             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
325             EGL_NONE,              EGL_NONE
326             // clang-format on
327     };
328 
329     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
330     ASSERT_EQ(EGL_SUCCESS, eglGetError());
331     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
332 
333     android_dataspace dataspace =
334         static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
335     ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
336 
337     EGLint value;
338     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
339     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
340     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT, value);
341 
342     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
343 }
344 
TEST_F(EGLTest,EGLDisplayP31010102)345 TEST_F(EGLTest, EGLDisplayP31010102) {
346     EGLint numConfigs;
347     EGLConfig config;
348     EGLBoolean success;
349 
350     if (!hasWideColorDisplay) {
351         // skip this test if device does not have wide-color display
352         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
353         return;
354     }
355 
356     // Test that display-p3 extensions exist
357     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
358     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
359     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
360 
361     // Use 8-bit to keep forcus on Display-P3 aspect
362     EGLint attrs[] = {
363             // clang-format off
364             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
365             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
366             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
367             EGL_RED_SIZE,                 10,
368             EGL_GREEN_SIZE,               10,
369             EGL_BLUE_SIZE,                10,
370             EGL_ALPHA_SIZE,               2,
371             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
372             EGL_NONE,                     EGL_NONE
373             // clang-format on
374     };
375     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
376     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
377     ASSERT_EQ(1, numConfigs);
378 
379     EGLint components[4];
380     EGLint value;
381     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
382 
383     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
384     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
385     ASSERT_EQ(EGL_SUCCESS, eglGetError());
386     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
387     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
388     ASSERT_EQ(EGL_SUCCESS, eglGetError());
389     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
390     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
391     ASSERT_EQ(EGL_SUCCESS, eglGetError());
392     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
393     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
394     ASSERT_EQ(EGL_SUCCESS, eglGetError());
395 
396     EXPECT_EQ(components[0], 10);
397     EXPECT_EQ(components[1], 10);
398     EXPECT_EQ(components[2], 10);
399     EXPECT_EQ(components[3], 2);
400 
401     struct MockConsumer : public BnConsumerListener {
402         void onFrameAvailable(const BufferItem& /* item */) override {}
403         void onBuffersReleased() override {}
404         void onSidebandStreamChanged() override {}
405     };
406 
407     // Create a EGLSurface
408     sp<IGraphicBufferProducer> producer;
409     sp<IGraphicBufferConsumer> consumer;
410     BufferQueue::createBufferQueue(&producer, &consumer);
411     consumer->consumerConnect(new MockConsumer, false);
412     sp<Surface> mSTC = new Surface(producer);
413     sp<ANativeWindow> mANW = mSTC;
414     EGLint winAttrs[] = {
415             // clang-format off
416             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
417             EGL_NONE,              EGL_NONE
418             // clang-format on
419     };
420 
421     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
422     ASSERT_EQ(EGL_SUCCESS, eglGetError());
423     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
424 
425     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
426     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
427     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
428 
429     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
430 }
431 
get8BitConfig(EGLConfig & config)432 void EGLTest::get8BitConfig(EGLConfig& config) {
433     EGLint numConfigs;
434     EGLBoolean success;
435 
436     // Use 8-bit to keep focus on colorspace aspect
437     const EGLint attrs[] = {
438             // clang-format off
439             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
440             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
441             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
442             EGL_RED_SIZE,                 8,
443             EGL_GREEN_SIZE,               8,
444             EGL_BLUE_SIZE,                8,
445             EGL_ALPHA_SIZE,               8,
446             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
447             EGL_NONE,
448             // clang-format on
449     };
450     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
451     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
452     ASSERT_EQ(1, numConfigs);
453 
454     EGLint components[4];
455     EGLint value;
456     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
457 
458     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
459     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
460     ASSERT_EQ(EGL_SUCCESS, eglGetError());
461     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
462     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
463     ASSERT_EQ(EGL_SUCCESS, eglGetError());
464     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
465     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
466     ASSERT_EQ(EGL_SUCCESS, eglGetError());
467     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
468     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
469     ASSERT_EQ(EGL_SUCCESS, eglGetError());
470 
471     // Verify component sizes on config match what was asked for.
472     EXPECT_EQ(components[0], 8);
473     EXPECT_EQ(components[1], 8);
474     EXPECT_EQ(components[2], 8);
475     EXPECT_EQ(components[3], 8);
476 }
477 
setSurfaceSmpteMetadata(EGLSurface surface)478 void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
479     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
480         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
481                          METADATA_SCALE(0.640));
482         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
483                          METADATA_SCALE(0.330));
484         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
485                          METADATA_SCALE(0.290));
486         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
487                          METADATA_SCALE(0.600));
488         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
489                          METADATA_SCALE(0.150));
490         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
491                          METADATA_SCALE(0.060));
492         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
493                          METADATA_SCALE(0.3127));
494         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
495                          METADATA_SCALE(0.3290));
496         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
497                          METADATA_SCALE(300));
498         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
499                          METADATA_SCALE(0.7));
500     }
501 
502     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
503         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
504                          METADATA_SCALE(300));
505         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
506                          METADATA_SCALE(75));
507     }
508 }
509 
checkSurfaceSmpteMetadata(EGLSurface eglSurface)510 void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
511     EGLBoolean success;
512     EGLint value;
513 
514     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
515         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
516         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
517         ASSERT_EQ(METADATA_SCALE(0.640), value);
518         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
519         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
520         ASSERT_EQ(METADATA_SCALE(0.330), value);
521         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
522         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
523         ASSERT_EQ(METADATA_SCALE(0.290), value);
524         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
525         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
526         ASSERT_EQ(METADATA_SCALE(0.600), value);
527         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
528         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
529         ASSERT_EQ(METADATA_SCALE(0.150), value);
530         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
531         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
532         ASSERT_EQ(METADATA_SCALE(0.060), value);
533         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
534         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
535         ASSERT_EQ(METADATA_SCALE(0.3127), value);
536         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
537         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
538         ASSERT_EQ(METADATA_SCALE(0.3290), value);
539         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
540         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
541         ASSERT_EQ(METADATA_SCALE(300.0), value);
542         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
543         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
544         ASSERT_EQ(METADATA_SCALE(0.7), value);
545     }
546 
547     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
548         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
549         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
550         ASSERT_EQ(METADATA_SCALE(300.0), value);
551         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
552         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
553         ASSERT_EQ(METADATA_SCALE(75.0), value);
554     }
555 }
556 
TEST_F(EGLTest,EGLBT2020Linear)557 TEST_F(EGLTest, EGLBT2020Linear) {
558     EGLConfig config;
559     EGLBoolean success;
560 
561     if (!hasHdrDisplay) {
562         // skip this test if device does not have HDR display
563         RecordProperty("hasHdrDisplay", false);
564         return;
565     }
566 
567     // Test that bt2020 linear extension exists
568     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
569             << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
570 
571     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
572 
573     struct MockConsumer : public BnConsumerListener {
574         void onFrameAvailable(const BufferItem& /* item */) override {}
575         void onBuffersReleased() override {}
576         void onSidebandStreamChanged() override {}
577     };
578 
579     // Create a EGLSurface
580     sp<IGraphicBufferProducer> producer;
581     sp<IGraphicBufferConsumer> consumer;
582     BufferQueue::createBufferQueue(&producer, &consumer);
583     consumer->consumerConnect(new MockConsumer, false);
584     sp<Surface> mSTC = new Surface(producer);
585     sp<ANativeWindow> mANW = mSTC;
586 
587     std::vector<EGLint> winAttrs;
588     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
589     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
590 
591     winAttrs.push_back(EGL_NONE);
592 
593     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
594     ASSERT_EQ(EGL_SUCCESS, eglGetError());
595     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
596 
597     EGLint value;
598     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
599     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
600     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
601 
602     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
603 
604     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
605 
606     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
607 }
608 
TEST_F(EGLTest,EGLBT2020PQ)609 TEST_F(EGLTest, EGLBT2020PQ) {
610     EGLConfig config;
611     EGLBoolean success;
612 
613     if (!hasHdrDisplay) {
614         // skip this test if device does not have HDR display
615         RecordProperty("hasHdrDisplay", false);
616         return;
617     }
618 
619     // Test that bt2020-pq extension exists
620     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
621             << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
622 
623     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
624 
625     struct MockConsumer : public BnConsumerListener {
626         void onFrameAvailable(const BufferItem& /* item */) override {}
627         void onBuffersReleased() override {}
628         void onSidebandStreamChanged() override {}
629     };
630 
631     // Create a EGLSurface
632     sp<IGraphicBufferProducer> producer;
633     sp<IGraphicBufferConsumer> consumer;
634     BufferQueue::createBufferQueue(&producer, &consumer);
635     consumer->consumerConnect(new MockConsumer, false);
636     sp<Surface> mSTC = new Surface(producer);
637     sp<ANativeWindow> mANW = mSTC;
638     std::vector<EGLint> winAttrs;
639     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
640     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
641     winAttrs.push_back(EGL_NONE);
642 
643     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
644     ASSERT_EQ(EGL_SUCCESS, eglGetError());
645     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
646 
647     EGLint value;
648     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
649     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
650     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
651 
652     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
653 
654     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
655 
656     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
657 }
658 
TEST_F(EGLTest,EGLConfigFP16)659 TEST_F(EGLTest, EGLConfigFP16) {
660     EGLint numConfigs;
661     EGLConfig config;
662     EGLBoolean success;
663 
664     if (!hasWideColorDisplay) {
665         // skip this test if device does not have wide-color display
666         RecordProperty("hasWideColorDisplay", false);
667         return;
668     }
669 
670     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
671 
672     const EGLint attrs[] = {
673             // clang-format off
674             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
675             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
676             EGL_RED_SIZE,                 16,
677             EGL_GREEN_SIZE,               16,
678             EGL_BLUE_SIZE,                16,
679             EGL_ALPHA_SIZE,               16,
680             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
681             EGL_NONE,
682             // clang-format on
683     };
684     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
685     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
686     ASSERT_EQ(1, numConfigs);
687 
688     EGLint components[4];
689 
690     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
691     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
692     ASSERT_EQ(EGL_SUCCESS, eglGetError());
693     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
694     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
695     ASSERT_EQ(EGL_SUCCESS, eglGetError());
696     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
697     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
698     ASSERT_EQ(EGL_SUCCESS, eglGetError());
699     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
700     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
701     ASSERT_EQ(EGL_SUCCESS, eglGetError());
702 
703     EXPECT_GE(components[0], 16);
704     EXPECT_GE(components[1], 16);
705     EXPECT_GE(components[2], 16);
706     EXPECT_GE(components[3], 16);
707 
708     struct MockConsumer : public BnConsumerListener {
709         void onFrameAvailable(const BufferItem& /* item */) override {}
710         void onBuffersReleased() override {}
711         void onSidebandStreamChanged() override {}
712     };
713 
714     sp<IGraphicBufferProducer> producer;
715     sp<IGraphicBufferConsumer> consumer;
716     BufferQueue::createBufferQueue(&producer, &consumer);
717     consumer->consumerConnect(new MockConsumer, false);
718     sp<Surface> mSTC = new Surface(producer);
719     sp<ANativeWindow> mANW = mSTC;
720 
721     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
722     ASSERT_EQ(EGL_SUCCESS, eglGetError());
723     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
724 
725     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
726 }
727 
TEST_F(EGLTest,EGLNoConfigContext)728 TEST_F(EGLTest, EGLNoConfigContext) {
729     if (!hasWideColorDisplay) {
730         // skip this test if device does not have wide-color display
731         RecordProperty("hasWideColorDisplay", false);
732         return;
733     }
734 
735     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
736 
737     struct MockConsumer : public BnConsumerListener {
738         void onFrameAvailable(const BufferItem& /* item */) override {}
739         void onBuffersReleased() override {}
740         void onSidebandStreamChanged() override {}
741     };
742 
743     std::vector<EGLint> contextAttributes;
744     contextAttributes.reserve(4);
745     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
746     contextAttributes.push_back(2);
747     contextAttributes.push_back(EGL_NONE);
748     contextAttributes.push_back(EGL_NONE);
749 
750     EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
751                                              contextAttributes.data());
752     EXPECT_NE(EGL_NO_CONTEXT, eglContext);
753     EXPECT_EQ(EGL_SUCCESS, eglGetError());
754 
755     if (eglContext != EGL_NO_CONTEXT) {
756         eglDestroyContext(mEglDisplay, eglContext);
757     }
758 }
759 
760 // Emulate what a native application would do to create a
761 // 10:10:10:2 surface.
TEST_F(EGLTest,EGLConfig1010102)762 TEST_F(EGLTest, EGLConfig1010102) {
763     EGLint numConfigs;
764     EGLConfig config;
765     EGLBoolean success;
766 
767     if (!hasWideColorDisplay) {
768         // skip this test if device does not have wide-color display
769         RecordProperty("hasWideColorDisplay", false);
770         return;
771     }
772 
773     const EGLint attrs[] = {
774             // clang-format off
775             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
776             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
777             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
778             EGL_RED_SIZE,                 10,
779             EGL_GREEN_SIZE,               10,
780             EGL_BLUE_SIZE,                10,
781             EGL_ALPHA_SIZE,               2,
782             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
783             EGL_NONE,                     EGL_NONE
784             // clang-format on
785     };
786     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
787     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
788     ASSERT_EQ(1, numConfigs);
789 
790     EGLint components[4];
791     EGLint value;
792     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
793 
794     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
795     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
796     ASSERT_EQ(EGL_SUCCESS, eglGetError());
797     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
798     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
799     ASSERT_EQ(EGL_SUCCESS, eglGetError());
800     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
801     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
802     ASSERT_EQ(EGL_SUCCESS, eglGetError());
803     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
804     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
805     ASSERT_EQ(EGL_SUCCESS, eglGetError());
806 
807     EXPECT_EQ(components[0], 10);
808     EXPECT_EQ(components[1], 10);
809     EXPECT_EQ(components[2], 10);
810     EXPECT_EQ(components[3], 2);
811 
812     struct MockConsumer : public BnConsumerListener {
813         void onFrameAvailable(const BufferItem& /* item */) override {}
814         void onBuffersReleased() override {}
815         void onSidebandStreamChanged() override {}
816     };
817 
818     // Create a EGLSurface
819     sp<IGraphicBufferProducer> producer;
820     sp<IGraphicBufferConsumer> consumer;
821     BufferQueue::createBufferQueue(&producer, &consumer);
822     consumer->consumerConnect(new MockConsumer, false);
823     sp<Surface> mSTC = new Surface(producer);
824     sp<ANativeWindow> mANW = mSTC;
825 
826     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
827     ASSERT_EQ(EGL_SUCCESS, eglGetError());
828     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
829 
830     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
831 }
832 
TEST_F(EGLTest,EGLInvalidColorspaceAttribute)833 TEST_F(EGLTest, EGLInvalidColorspaceAttribute) {
834     EGLConfig config;
835 
836     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
837 
838     struct MockConsumer : public BnConsumerListener {
839         void onFrameAvailable(const BufferItem& /* item */) override {}
840         void onBuffersReleased() override {}
841         void onSidebandStreamChanged() override {}
842     };
843 
844     // Create a EGLSurface
845     sp<IGraphicBufferProducer> producer;
846     sp<IGraphicBufferConsumer> consumer;
847     BufferQueue::createBufferQueue(&producer, &consumer);
848     consumer->consumerConnect(new MockConsumer, false);
849     sp<Surface> mSTC = new Surface(producer);
850     sp<ANativeWindow> mANW = mSTC;
851 
852     EGLint winAttrs[] = {
853             // clang-format off
854             EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
855             EGL_NONE,
856             // clang-format on
857     };
858 
859     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
860     ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
861     ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
862 }
863 
TEST_F(EGLTest,EGLUnsupportedColorspaceFormatCombo)864 TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) {
865     EGLint numConfigs;
866     EGLConfig config;
867     EGLBoolean success;
868 
869     const EGLint attrs[] = {
870             // clang-format off
871             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
872             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
873             EGL_RED_SIZE,                 16,
874             EGL_GREEN_SIZE,               16,
875             EGL_BLUE_SIZE,                16,
876             EGL_ALPHA_SIZE,               16,
877             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
878             EGL_NONE,
879             // clang-format on
880     };
881     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
882     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
883     ASSERT_EQ(1, numConfigs);
884 
885     struct MockConsumer : public BnConsumerListener {
886         void onFrameAvailable(const BufferItem& /* item */) override {}
887         void onBuffersReleased() override {}
888         void onSidebandStreamChanged() override {}
889     };
890 
891     // Create a EGLSurface
892     sp<IGraphicBufferProducer> producer;
893     sp<IGraphicBufferConsumer> consumer;
894     BufferQueue::createBufferQueue(&producer, &consumer);
895     consumer->consumerConnect(new MockConsumer, false);
896     sp<Surface> mSTC = new Surface(producer);
897     sp<ANativeWindow> mANW = mSTC;
898 
899     const EGLint winAttrs[] = {
900             // clang-format off
901             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
902             EGL_NONE,
903             // clang-format on
904     };
905 
906     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
907     ASSERT_EQ(EGL_BAD_MATCH, eglGetError());
908     ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
909 }
910 
TEST_F(EGLTest,EGLCreateWindowFailAndSucceed)911 TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) {
912     EGLConfig config;
913 
914     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
915 
916     struct MockConsumer : public BnConsumerListener {
917         void onFrameAvailable(const BufferItem& /* item */) override {}
918         void onBuffersReleased() override {}
919         void onSidebandStreamChanged() override {}
920     };
921 
922     // Create a EGLSurface
923     sp<IGraphicBufferProducer> producer;
924     sp<IGraphicBufferConsumer> consumer;
925     BufferQueue::createBufferQueue(&producer, &consumer);
926     consumer->consumerConnect(new MockConsumer, false);
927     sp<Surface> mSTC = new Surface(producer);
928     sp<ANativeWindow> mANW = mSTC;
929 
930     EGLint winAttrs[] = {
931             // clang-format off
932             EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
933             EGL_NONE,
934             // clang-format on
935     };
936 
937     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
938     ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
939     ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
940 
941     // Now recreate surface with a valid colorspace. Ensure proper cleanup is done
942     // in the first failed attempt (e.g. native_window_api_disconnect).
943     winAttrs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
944     eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
945     ASSERT_EQ(EGL_SUCCESS, eglGetError());
946     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
947 
948     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
949 }
950 
TEST_F(EGLTest,EGLCreateWindowTwoColorspaces)951 TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) {
952     EGLConfig config;
953 
954     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
955 
956     struct MockConsumer : public BnConsumerListener {
957         void onFrameAvailable(const BufferItem& /* item */) override {}
958         void onBuffersReleased() override {}
959         void onSidebandStreamChanged() override {}
960     };
961 
962     // Create a EGLSurface
963     sp<IGraphicBufferProducer> producer;
964     sp<IGraphicBufferConsumer> consumer;
965     BufferQueue::createBufferQueue(&producer, &consumer);
966     consumer->consumerConnect(new MockConsumer, false);
967     sp<Surface> mSTC = new Surface(producer);
968     sp<ANativeWindow> mANW = mSTC;
969 
970     const EGLint winAttrs[] = {
971             // clang-format off
972             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
973             EGL_NONE,
974             // clang-format on
975     };
976 
977     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
978     ASSERT_EQ(EGL_SUCCESS, eglGetError());
979     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
980 
981     android_dataspace dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
982     ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
983 
984     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
985 
986     // Now create with default attribute (EGL_GL_COLORSPACE_LINEAR_KHR)
987     eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
988     ASSERT_EQ(EGL_SUCCESS, eglGetError());
989     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
990 
991     dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
992     // Make sure the dataspace has been reset to UNKNOWN
993     ASSERT_NE(dataspace, HAL_DATASPACE_DISPLAY_P3);
994 
995     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
996 }
997 }
998