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