• 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     // This test has been failing since:
347     // libEGL: When driver doesn't understand P3, map sRGB-encoded P3 to sRGB
348     // https://android-review.git.corp.google.com/c/platform/frameworks/native/+/793504
349     GTEST_SKIP() << "Skipping broken test. See b/120714942 and b/117104367";
350 
351     EGLint numConfigs;
352     EGLConfig config;
353     EGLBoolean success;
354 
355     if (!hasWideColorDisplay) {
356         // skip this test if device does not have wide-color display
357         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
358         return;
359     }
360 
361     // Test that display-p3 extensions exist
362     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
363     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
364     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
365 
366     // Use 8-bit to keep forcus on Display-P3 aspect
367     EGLint attrs[] = {
368             // clang-format off
369             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
370             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
371             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
372             EGL_RED_SIZE,                 10,
373             EGL_GREEN_SIZE,               10,
374             EGL_BLUE_SIZE,                10,
375             EGL_ALPHA_SIZE,               2,
376             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
377             EGL_NONE,                     EGL_NONE
378             // clang-format on
379     };
380     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
381     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
382     ASSERT_EQ(1, numConfigs);
383 
384     EGLint components[4];
385     EGLint value;
386     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
387 
388     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
389     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
390     ASSERT_EQ(EGL_SUCCESS, eglGetError());
391     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
392     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
393     ASSERT_EQ(EGL_SUCCESS, eglGetError());
394     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
395     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
396     ASSERT_EQ(EGL_SUCCESS, eglGetError());
397     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
398     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
399     ASSERT_EQ(EGL_SUCCESS, eglGetError());
400 
401     EXPECT_EQ(components[0], 10);
402     EXPECT_EQ(components[1], 10);
403     EXPECT_EQ(components[2], 10);
404     EXPECT_EQ(components[3], 2);
405 
406     struct MockConsumer : public BnConsumerListener {
407         void onFrameAvailable(const BufferItem& /* item */) override {}
408         void onBuffersReleased() override {}
409         void onSidebandStreamChanged() override {}
410     };
411 
412     // Create a EGLSurface
413     sp<IGraphicBufferProducer> producer;
414     sp<IGraphicBufferConsumer> consumer;
415     BufferQueue::createBufferQueue(&producer, &consumer);
416     consumer->consumerConnect(new MockConsumer, false);
417     sp<Surface> mSTC = new Surface(producer);
418     sp<ANativeWindow> mANW = mSTC;
419     EGLint winAttrs[] = {
420             // clang-format off
421             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
422             EGL_NONE,              EGL_NONE
423             // clang-format on
424     };
425 
426     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
427     ASSERT_EQ(EGL_SUCCESS, eglGetError());
428     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
429 
430     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
431     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
432     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
433 
434     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
435 }
436 
get8BitConfig(EGLConfig & config)437 void EGLTest::get8BitConfig(EGLConfig& config) {
438     EGLint numConfigs;
439     EGLBoolean success;
440 
441     // Use 8-bit to keep focus on colorspace aspect
442     const EGLint attrs[] = {
443             // clang-format off
444             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
445             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
446             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
447             EGL_RED_SIZE,                 8,
448             EGL_GREEN_SIZE,               8,
449             EGL_BLUE_SIZE,                8,
450             EGL_ALPHA_SIZE,               8,
451             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
452             EGL_NONE,
453             // clang-format on
454     };
455     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
456     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
457     ASSERT_EQ(1, numConfigs);
458 
459     EGLint components[4];
460     EGLint value;
461     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
462 
463     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
464     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
465     ASSERT_EQ(EGL_SUCCESS, eglGetError());
466     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
467     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
468     ASSERT_EQ(EGL_SUCCESS, eglGetError());
469     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
470     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
471     ASSERT_EQ(EGL_SUCCESS, eglGetError());
472     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
473     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
474     ASSERT_EQ(EGL_SUCCESS, eglGetError());
475 
476     // Verify component sizes on config match what was asked for.
477     EXPECT_EQ(components[0], 8);
478     EXPECT_EQ(components[1], 8);
479     EXPECT_EQ(components[2], 8);
480     EXPECT_EQ(components[3], 8);
481 }
482 
setSurfaceSmpteMetadata(EGLSurface surface)483 void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
484     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
485         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
486                          METADATA_SCALE(0.640));
487         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
488                          METADATA_SCALE(0.330));
489         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
490                          METADATA_SCALE(0.290));
491         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
492                          METADATA_SCALE(0.600));
493         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
494                          METADATA_SCALE(0.150));
495         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
496                          METADATA_SCALE(0.060));
497         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
498                          METADATA_SCALE(0.3127));
499         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
500                          METADATA_SCALE(0.3290));
501         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
502                          METADATA_SCALE(300));
503         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
504                          METADATA_SCALE(0.7));
505     }
506 
507     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
508         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
509                          METADATA_SCALE(300));
510         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
511                          METADATA_SCALE(75));
512     }
513 }
514 
checkSurfaceSmpteMetadata(EGLSurface eglSurface)515 void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
516     EGLBoolean success;
517     EGLint value;
518 
519     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
520         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
521         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
522         ASSERT_EQ(METADATA_SCALE(0.640), value);
523         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
524         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
525         ASSERT_EQ(METADATA_SCALE(0.330), value);
526         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
527         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
528         ASSERT_EQ(METADATA_SCALE(0.290), value);
529         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
530         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
531         ASSERT_EQ(METADATA_SCALE(0.600), value);
532         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
533         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
534         ASSERT_EQ(METADATA_SCALE(0.150), value);
535         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
536         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
537         ASSERT_EQ(METADATA_SCALE(0.060), value);
538         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
539         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
540         ASSERT_EQ(METADATA_SCALE(0.3127), value);
541         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
542         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
543         ASSERT_EQ(METADATA_SCALE(0.3290), value);
544         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
545         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
546         ASSERT_EQ(METADATA_SCALE(300.0), value);
547         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
548         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
549         ASSERT_EQ(METADATA_SCALE(0.7), value);
550     }
551 
552     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
553         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
554         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
555         ASSERT_EQ(METADATA_SCALE(300.0), value);
556         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
557         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
558         ASSERT_EQ(METADATA_SCALE(75.0), value);
559     }
560 }
561 
TEST_F(EGLTest,EGLBT2020Linear)562 TEST_F(EGLTest, EGLBT2020Linear) {
563     EGLConfig config;
564     EGLBoolean success;
565 
566     if (!hasHdrDisplay) {
567         // skip this test if device does not have HDR display
568         RecordProperty("hasHdrDisplay", false);
569         return;
570     }
571 
572     // Test that bt2020 linear extension exists
573     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
574             << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
575 
576     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
577 
578     struct MockConsumer : public BnConsumerListener {
579         void onFrameAvailable(const BufferItem& /* item */) override {}
580         void onBuffersReleased() override {}
581         void onSidebandStreamChanged() override {}
582     };
583 
584     // Create a EGLSurface
585     sp<IGraphicBufferProducer> producer;
586     sp<IGraphicBufferConsumer> consumer;
587     BufferQueue::createBufferQueue(&producer, &consumer);
588     consumer->consumerConnect(new MockConsumer, false);
589     sp<Surface> mSTC = new Surface(producer);
590     sp<ANativeWindow> mANW = mSTC;
591 
592     std::vector<EGLint> winAttrs;
593     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
594     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
595 
596     winAttrs.push_back(EGL_NONE);
597 
598     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
599     ASSERT_EQ(EGL_SUCCESS, eglGetError());
600     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
601 
602     EGLint value;
603     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
604     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
605     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
606 
607     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
608 
609     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
610 
611     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
612 }
613 
TEST_F(EGLTest,EGLBT2020PQ)614 TEST_F(EGLTest, EGLBT2020PQ) {
615     EGLConfig config;
616     EGLBoolean success;
617 
618     if (!hasHdrDisplay) {
619         // skip this test if device does not have HDR display
620         RecordProperty("hasHdrDisplay", false);
621         return;
622     }
623 
624     // Test that bt2020-pq extension exists
625     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
626             << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
627 
628     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
629 
630     struct MockConsumer : public BnConsumerListener {
631         void onFrameAvailable(const BufferItem& /* item */) override {}
632         void onBuffersReleased() override {}
633         void onSidebandStreamChanged() override {}
634     };
635 
636     // Create a EGLSurface
637     sp<IGraphicBufferProducer> producer;
638     sp<IGraphicBufferConsumer> consumer;
639     BufferQueue::createBufferQueue(&producer, &consumer);
640     consumer->consumerConnect(new MockConsumer, false);
641     sp<Surface> mSTC = new Surface(producer);
642     sp<ANativeWindow> mANW = mSTC;
643     std::vector<EGLint> winAttrs;
644     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
645     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
646     winAttrs.push_back(EGL_NONE);
647 
648     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
649     ASSERT_EQ(EGL_SUCCESS, eglGetError());
650     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
651 
652     EGLint value;
653     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
654     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
655     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
656 
657     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
658 
659     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
660 
661     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
662 }
663 
TEST_F(EGLTest,EGLConfigFP16)664 TEST_F(EGLTest, EGLConfigFP16) {
665     EGLint numConfigs;
666     EGLConfig config;
667     EGLBoolean success;
668 
669     if (!hasWideColorDisplay) {
670         // skip this test if device does not have wide-color display
671         RecordProperty("hasWideColorDisplay", false);
672         return;
673     }
674 
675     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
676 
677     const EGLint attrs[] = {
678             // clang-format off
679             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
680             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
681             EGL_RED_SIZE,                 16,
682             EGL_GREEN_SIZE,               16,
683             EGL_BLUE_SIZE,                16,
684             EGL_ALPHA_SIZE,               16,
685             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
686             EGL_NONE,
687             // clang-format on
688     };
689     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
690     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
691     ASSERT_EQ(1, numConfigs);
692 
693     EGLint components[4];
694 
695     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
696     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
697     ASSERT_EQ(EGL_SUCCESS, eglGetError());
698     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
699     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
700     ASSERT_EQ(EGL_SUCCESS, eglGetError());
701     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
702     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
703     ASSERT_EQ(EGL_SUCCESS, eglGetError());
704     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
705     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
706     ASSERT_EQ(EGL_SUCCESS, eglGetError());
707 
708     EXPECT_GE(components[0], 16);
709     EXPECT_GE(components[1], 16);
710     EXPECT_GE(components[2], 16);
711     EXPECT_GE(components[3], 16);
712 
713     struct MockConsumer : public BnConsumerListener {
714         void onFrameAvailable(const BufferItem& /* item */) override {}
715         void onBuffersReleased() override {}
716         void onSidebandStreamChanged() override {}
717     };
718 
719     sp<IGraphicBufferProducer> producer;
720     sp<IGraphicBufferConsumer> consumer;
721     BufferQueue::createBufferQueue(&producer, &consumer);
722     consumer->consumerConnect(new MockConsumer, false);
723     sp<Surface> mSTC = new Surface(producer);
724     sp<ANativeWindow> mANW = mSTC;
725 
726     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
727     ASSERT_EQ(EGL_SUCCESS, eglGetError());
728     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
729 
730     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
731 }
732 
TEST_F(EGLTest,EGLNoConfigContext)733 TEST_F(EGLTest, EGLNoConfigContext) {
734     if (!hasWideColorDisplay) {
735         // skip this test if device does not have wide-color display
736         RecordProperty("hasWideColorDisplay", false);
737         return;
738     }
739 
740     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
741 
742     struct MockConsumer : public BnConsumerListener {
743         void onFrameAvailable(const BufferItem& /* item */) override {}
744         void onBuffersReleased() override {}
745         void onSidebandStreamChanged() override {}
746     };
747 
748     std::vector<EGLint> contextAttributes;
749     contextAttributes.reserve(4);
750     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
751     contextAttributes.push_back(2);
752     contextAttributes.push_back(EGL_NONE);
753     contextAttributes.push_back(EGL_NONE);
754 
755     EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
756                                              contextAttributes.data());
757     EXPECT_NE(EGL_NO_CONTEXT, eglContext);
758     EXPECT_EQ(EGL_SUCCESS, eglGetError());
759 
760     if (eglContext != EGL_NO_CONTEXT) {
761         eglDestroyContext(mEglDisplay, eglContext);
762     }
763 }
764 
765 // Emulate what a native application would do to create a
766 // 10:10:10:2 surface.
TEST_F(EGLTest,EGLConfig1010102)767 TEST_F(EGLTest, EGLConfig1010102) {
768     EGLint numConfigs;
769     EGLConfig config;
770     EGLBoolean success;
771 
772     if (!hasWideColorDisplay) {
773         // skip this test if device does not have wide-color display
774         RecordProperty("hasWideColorDisplay", false);
775         return;
776     }
777 
778     const EGLint attrs[] = {
779             // clang-format off
780             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
781             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
782             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
783             EGL_RED_SIZE,                 10,
784             EGL_GREEN_SIZE,               10,
785             EGL_BLUE_SIZE,                10,
786             EGL_ALPHA_SIZE,               2,
787             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
788             EGL_NONE,                     EGL_NONE
789             // clang-format on
790     };
791     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
792     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
793     ASSERT_EQ(1, numConfigs);
794 
795     EGLint components[4];
796     EGLint value;
797     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
798 
799     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
800     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
801     ASSERT_EQ(EGL_SUCCESS, eglGetError());
802     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
803     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
804     ASSERT_EQ(EGL_SUCCESS, eglGetError());
805     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
806     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
807     ASSERT_EQ(EGL_SUCCESS, eglGetError());
808     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
809     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
810     ASSERT_EQ(EGL_SUCCESS, eglGetError());
811 
812     EXPECT_EQ(components[0], 10);
813     EXPECT_EQ(components[1], 10);
814     EXPECT_EQ(components[2], 10);
815     EXPECT_EQ(components[3], 2);
816 
817     struct MockConsumer : public BnConsumerListener {
818         void onFrameAvailable(const BufferItem& /* item */) override {}
819         void onBuffersReleased() override {}
820         void onSidebandStreamChanged() override {}
821     };
822 
823     // Create a EGLSurface
824     sp<IGraphicBufferProducer> producer;
825     sp<IGraphicBufferConsumer> consumer;
826     BufferQueue::createBufferQueue(&producer, &consumer);
827     consumer->consumerConnect(new MockConsumer, false);
828     sp<Surface> mSTC = new Surface(producer);
829     sp<ANativeWindow> mANW = mSTC;
830 
831     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
832     ASSERT_EQ(EGL_SUCCESS, eglGetError());
833     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
834 
835     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
836 }
837 
TEST_F(EGLTest,EGLInvalidColorspaceAttribute)838 TEST_F(EGLTest, EGLInvalidColorspaceAttribute) {
839     EGLConfig config;
840 
841     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
842 
843     struct MockConsumer : public BnConsumerListener {
844         void onFrameAvailable(const BufferItem& /* item */) override {}
845         void onBuffersReleased() override {}
846         void onSidebandStreamChanged() override {}
847     };
848 
849     // Create a EGLSurface
850     sp<IGraphicBufferProducer> producer;
851     sp<IGraphicBufferConsumer> consumer;
852     BufferQueue::createBufferQueue(&producer, &consumer);
853     consumer->consumerConnect(new MockConsumer, false);
854     sp<Surface> mSTC = new Surface(producer);
855     sp<ANativeWindow> mANW = mSTC;
856 
857     EGLint winAttrs[] = {
858             // clang-format off
859             EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
860             EGL_NONE,
861             // clang-format on
862     };
863 
864     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
865     ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
866     ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
867 }
868 
TEST_F(EGLTest,EGLUnsupportedColorspaceFormatCombo)869 TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) {
870     EGLint numConfigs;
871     EGLConfig config;
872     EGLBoolean success;
873 
874     if (!hasWideColorDisplay) {
875         // skip this test if device does not have wide-color display
876         RecordProperty("hasWideColorDisplay", false);
877         return;
878     }
879 
880     const EGLint attrs[] = {
881             // clang-format off
882             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
883             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
884             EGL_RED_SIZE,                 16,
885             EGL_GREEN_SIZE,               16,
886             EGL_BLUE_SIZE,                16,
887             EGL_ALPHA_SIZE,               16,
888             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
889             EGL_NONE,
890             // clang-format on
891     };
892     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
893     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
894     ASSERT_EQ(1, numConfigs);
895 
896     struct MockConsumer : public BnConsumerListener {
897         void onFrameAvailable(const BufferItem& /* item */) override {}
898         void onBuffersReleased() override {}
899         void onSidebandStreamChanged() override {}
900     };
901 
902     // Create a EGLSurface
903     sp<IGraphicBufferProducer> producer;
904     sp<IGraphicBufferConsumer> consumer;
905     BufferQueue::createBufferQueue(&producer, &consumer);
906     consumer->consumerConnect(new MockConsumer, false);
907     sp<Surface> mSTC = new Surface(producer);
908     sp<ANativeWindow> mANW = mSTC;
909 
910     const EGLint winAttrs[] = {
911             // clang-format off
912             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
913             EGL_NONE,
914             // clang-format on
915     };
916 
917     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
918     ASSERT_EQ(EGL_BAD_MATCH, eglGetError());
919     ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
920 }
921 
TEST_F(EGLTest,EGLCreateWindowFailAndSucceed)922 TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) {
923     EGLConfig config;
924 
925     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
926 
927     struct MockConsumer : public BnConsumerListener {
928         void onFrameAvailable(const BufferItem& /* item */) override {}
929         void onBuffersReleased() override {}
930         void onSidebandStreamChanged() override {}
931     };
932 
933     // Create a EGLSurface
934     sp<IGraphicBufferProducer> producer;
935     sp<IGraphicBufferConsumer> consumer;
936     BufferQueue::createBufferQueue(&producer, &consumer);
937     consumer->consumerConnect(new MockConsumer, false);
938     sp<Surface> mSTC = new Surface(producer);
939     sp<ANativeWindow> mANW = mSTC;
940 
941     EGLint winAttrs[] = {
942             // clang-format off
943             EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
944             EGL_NONE,
945             // clang-format on
946     };
947 
948     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
949     ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
950     ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
951 
952     // Now recreate surface with a valid colorspace. Ensure proper cleanup is done
953     // in the first failed attempt (e.g. native_window_api_disconnect).
954     winAttrs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
955     eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
956     ASSERT_EQ(EGL_SUCCESS, eglGetError());
957     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
958 
959     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
960 }
961 
TEST_F(EGLTest,EGLCreateWindowTwoColorspaces)962 TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) {
963     EGLConfig config;
964 
965     if (!hasWideColorDisplay) {
966         // skip this test if device does not have wide-color display
967         RecordProperty("hasWideColorDisplay", false);
968         return;
969     }
970 
971     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
972 
973     struct MockConsumer : public BnConsumerListener {
974         void onFrameAvailable(const BufferItem& /* item */) override {}
975         void onBuffersReleased() override {}
976         void onSidebandStreamChanged() override {}
977     };
978 
979     // Create a EGLSurface
980     sp<IGraphicBufferProducer> producer;
981     sp<IGraphicBufferConsumer> consumer;
982     BufferQueue::createBufferQueue(&producer, &consumer);
983     consumer->consumerConnect(new MockConsumer, false);
984     sp<Surface> mSTC = new Surface(producer);
985     sp<ANativeWindow> mANW = mSTC;
986 
987     const EGLint winAttrs[] = {
988             // clang-format off
989             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
990             EGL_NONE,
991             // clang-format on
992     };
993 
994     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
995     ASSERT_EQ(EGL_SUCCESS, eglGetError());
996     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
997 
998     android_dataspace dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
999     ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
1000 
1001     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
1002 
1003     // Now create with default attribute (EGL_GL_COLORSPACE_LINEAR_KHR)
1004     eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
1005     ASSERT_EQ(EGL_SUCCESS, eglGetError());
1006     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
1007 
1008     dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
1009     // Make sure the dataspace has been reset to UNKNOWN
1010     ASSERT_NE(dataspace, HAL_DATASPACE_DISPLAY_P3);
1011 
1012     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
1013 }
1014 }
1015