• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
20 
21 #include <configstore/Utils.h>
22 #include <utils/String8.h>
23 
24 #include <EGL/egl.h>
25 #include <gui/Surface.h>
26 #include <gui/IConsumerListener.h>
27 #include <gui/IProducerListener.h>
28 #include <gui/IGraphicBufferConsumer.h>
29 #include <gui/BufferQueue.h>
30 
hasEglExtension(EGLDisplay dpy,const char * extensionName)31 bool hasEglExtension(EGLDisplay dpy, const char* extensionName) {
32     const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
33     size_t cropExtLen = strlen(extensionName);
34     size_t extsLen = strlen(exts);
35     bool equal = !strcmp(extensionName, exts);
36     android::String8 extString(extensionName);
37     android::String8 space(" ");
38     bool atStart = !strncmp(extString + space, exts, cropExtLen + 1);
39     bool atEnd = (cropExtLen + 1) < extsLen &&
40             !strcmp(space + extString, exts + extsLen - (cropExtLen + 1));
41     bool inMiddle = strstr(exts, space + extString + space);
42     return equal || atStart || atEnd || inMiddle;
43 }
44 
45 namespace android {
46 
47 #define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE)
48 
49 // retrieve wide-color setting from configstore
50 using namespace android::hardware::configstore;
51 using namespace android::hardware::configstore::V1_0;
52 
53 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
54 
55 static bool hasWideColorDisplay =
56         getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
57 
58 static bool hasHdrDisplay =
59         getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
60 
61 class EGLTest : public ::testing::Test {
62 public:
63     void get8BitConfig(EGLConfig& config);
64     void setSurfaceSmpteMetadata(EGLSurface surface);
65     void checkSurfaceSmpteMetadata(EGLSurface eglSurface);
66 
67 protected:
68     EGLDisplay mEglDisplay;
69 
70 protected:
EGLTest()71     EGLTest() :
72             mEglDisplay(EGL_NO_DISPLAY) {
73     }
74 
SetUp()75     virtual void SetUp() {
76         mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
77         ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
78         ASSERT_EQ(EGL_SUCCESS, eglGetError());
79 
80         EGLint majorVersion;
81         EGLint minorVersion;
82         EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
83         ASSERT_EQ(EGL_SUCCESS, eglGetError());
84         RecordProperty("EglVersionMajor", majorVersion);
85         RecordProperty("EglVersionMajor", minorVersion);
86     }
87 
TearDown()88     virtual void TearDown() {
89         EGLBoolean success = eglTerminate(mEglDisplay);
90         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
91         ASSERT_EQ(EGL_SUCCESS, eglGetError());
92     }
93 };
94 
TEST_F(EGLTest,DISABLED_EGLConfigEightBitFirst)95 TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) {
96 
97     EGLint numConfigs;
98     EGLConfig config;
99     EGLBoolean success;
100     EGLint attrs[] = {
101             EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
102             EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
103             EGL_NONE
104     };
105 
106     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
107     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
108     ASSERT_EQ(EGL_SUCCESS, eglGetError());
109     ASSERT_GE(numConfigs, 1);
110 
111     EGLint components[3];
112 
113     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
114     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
115     ASSERT_EQ(EGL_SUCCESS, eglGetError());
116     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
117     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
118     ASSERT_EQ(EGL_SUCCESS, eglGetError());
119     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
120     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
121     ASSERT_EQ(EGL_SUCCESS, eglGetError());
122 
123     EXPECT_GE(components[0], 8);
124     EXPECT_GE(components[1], 8);
125     EXPECT_GE(components[2], 8);
126 }
127 
TEST_F(EGLTest,EGLTerminateSucceedsWithRemainingObjects)128 TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) {
129     EGLint numConfigs;
130     EGLConfig config;
131     EGLint attrs[] = {
132         EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
133         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
134         EGL_RED_SIZE,           8,
135         EGL_GREEN_SIZE,         8,
136         EGL_BLUE_SIZE,          8,
137         EGL_ALPHA_SIZE,         8,
138         EGL_NONE
139     };
140     EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
141 
142     struct DummyConsumer : public BnConsumerListener {
143         void onFrameAvailable(const BufferItem& /* item */) override {}
144         void onBuffersReleased() override {}
145         void onSidebandStreamChanged() override {}
146     };
147 
148     // Create a EGLSurface
149     sp<IGraphicBufferProducer> producer;
150     sp<IGraphicBufferConsumer> consumer;
151     BufferQueue::createBufferQueue(&producer, &consumer);
152     consumer->consumerConnect(new DummyConsumer, false);
153     sp<Surface> mSTC = new Surface(producer);
154     sp<ANativeWindow> mANW = mSTC;
155 
156     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config,
157                                 mANW.get(), NULL);
158     ASSERT_EQ(EGL_SUCCESS, eglGetError());
159     ASSERT_NE(EGL_NO_SURFACE, eglSurface) ;
160 
161     // do not destroy eglSurface
162     // eglTerminate is called in the tear down and should destroy it for us
163 }
164 
TEST_F(EGLTest,EGLConfigRGBA8888First)165 TEST_F(EGLTest, EGLConfigRGBA8888First) {
166 
167     EGLint numConfigs;
168     EGLConfig config;
169     EGLBoolean success;
170     EGLint attrs[] = {
171             EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
172             EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
173             EGL_RED_SIZE,           8,
174             EGL_GREEN_SIZE,         8,
175             EGL_BLUE_SIZE,          8,
176             EGL_ALPHA_SIZE,         8,
177             EGL_NONE
178     };
179 
180     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
181     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
182     ASSERT_EQ(EGL_SUCCESS, eglGetError());
183     ASSERT_GE(numConfigs, 1);
184 
185     EGLint components[4];
186 
187     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
188     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
189     ASSERT_EQ(EGL_SUCCESS, eglGetError());
190     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
191     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
192     ASSERT_EQ(EGL_SUCCESS, eglGetError());
193     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
194     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
195     ASSERT_EQ(EGL_SUCCESS, eglGetError());
196     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
197     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
198     ASSERT_EQ(EGL_SUCCESS, eglGetError());
199 
200     EXPECT_GE(components[0], 8);
201     EXPECT_GE(components[1], 8);
202     EXPECT_GE(components[2], 8);
203     EXPECT_GE(components[3], 8);
204 }
205 
TEST_F(EGLTest,EGLDisplayP3)206 TEST_F(EGLTest, EGLDisplayP3) {
207     EGLint numConfigs;
208     EGLConfig config;
209     EGLBoolean success;
210 
211     if (!hasWideColorDisplay) {
212         // skip this test if device does not have wide-color display
213         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
214         return;
215     }
216 
217     // Test that display-p3 extensions exist
218     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
219     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
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 DummyConsumer : 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 DummyConsumer, 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,EGLDisplayP31010102)292 TEST_F(EGLTest, EGLDisplayP31010102) {
293     EGLint numConfigs;
294     EGLConfig config;
295     EGLBoolean success;
296 
297     if (!hasWideColorDisplay) {
298         // skip this test if device does not have wide-color display
299         std::cerr << "[          ] Device does not support wide-color, test skipped" << std::endl;
300         return;
301     }
302 
303     // Test that display-p3 extensions exist
304     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
305     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
306 
307     // Use 8-bit to keep forcus on Display-P3 aspect
308     EGLint attrs[] = {
309             // clang-format off
310             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
311             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
312             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
313             EGL_RED_SIZE,                 10,
314             EGL_GREEN_SIZE,               10,
315             EGL_BLUE_SIZE,                10,
316             EGL_ALPHA_SIZE,               2,
317             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
318             EGL_NONE,                     EGL_NONE
319             // clang-format on
320     };
321     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
322     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
323     ASSERT_EQ(1, numConfigs);
324 
325     EGLint components[4];
326     EGLint value;
327     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
328 
329     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
330     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
331     ASSERT_EQ(EGL_SUCCESS, eglGetError());
332     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
333     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
334     ASSERT_EQ(EGL_SUCCESS, eglGetError());
335     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
336     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
337     ASSERT_EQ(EGL_SUCCESS, eglGetError());
338     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
339     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
340     ASSERT_EQ(EGL_SUCCESS, eglGetError());
341 
342     EXPECT_EQ(components[0], 10);
343     EXPECT_EQ(components[1], 10);
344     EXPECT_EQ(components[2], 10);
345     EXPECT_EQ(components[3], 2);
346 
347     struct DummyConsumer : public BnConsumerListener {
348         void onFrameAvailable(const BufferItem& /* item */) override {}
349         void onBuffersReleased() override {}
350         void onSidebandStreamChanged() override {}
351     };
352 
353     // Create a EGLSurface
354     sp<IGraphicBufferProducer> producer;
355     sp<IGraphicBufferConsumer> consumer;
356     BufferQueue::createBufferQueue(&producer, &consumer);
357     consumer->consumerConnect(new DummyConsumer, false);
358     sp<Surface> mSTC = new Surface(producer);
359     sp<ANativeWindow> mANW = mSTC;
360     EGLint winAttrs[] = {
361             // clang-format off
362             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
363             EGL_NONE,              EGL_NONE
364             // clang-format on
365     };
366 
367     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
368     ASSERT_EQ(EGL_SUCCESS, eglGetError());
369     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
370 
371     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
372     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
373     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
374 
375     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
376 }
377 
get8BitConfig(EGLConfig & config)378 void EGLTest::get8BitConfig(EGLConfig& config) {
379     EGLint numConfigs;
380     EGLBoolean success;
381 
382     // Use 8-bit to keep focus on colorspace aspect
383     const EGLint attrs[] = {
384             // clang-format off
385             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
386             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
387             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
388             EGL_RED_SIZE,                 8,
389             EGL_GREEN_SIZE,               8,
390             EGL_BLUE_SIZE,                8,
391             EGL_ALPHA_SIZE,               8,
392             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
393             EGL_NONE,
394             // clang-format on
395     };
396     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
397     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
398     ASSERT_EQ(1, numConfigs);
399 
400     EGLint components[4];
401     EGLint value;
402     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
403 
404     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
405     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
406     ASSERT_EQ(EGL_SUCCESS, eglGetError());
407     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
408     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
409     ASSERT_EQ(EGL_SUCCESS, eglGetError());
410     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
411     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
412     ASSERT_EQ(EGL_SUCCESS, eglGetError());
413     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
414     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
415     ASSERT_EQ(EGL_SUCCESS, eglGetError());
416 
417     // Verify component sizes on config match what was asked for.
418     EXPECT_EQ(components[0], 8);
419     EXPECT_EQ(components[1], 8);
420     EXPECT_EQ(components[2], 8);
421     EXPECT_EQ(components[3], 8);
422 }
423 
setSurfaceSmpteMetadata(EGLSurface surface)424 void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
425     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
426         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
427                          METADATA_SCALE(0.640));
428         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
429                          METADATA_SCALE(0.330));
430         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
431                          METADATA_SCALE(0.290));
432         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
433                          METADATA_SCALE(0.600));
434         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
435                          METADATA_SCALE(0.150));
436         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
437                          METADATA_SCALE(0.060));
438         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
439                          METADATA_SCALE(0.3127));
440         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
441                          METADATA_SCALE(0.3290));
442         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
443                          METADATA_SCALE(300));
444         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
445                          METADATA_SCALE(0.7));
446     }
447 
448     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
449         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
450                          METADATA_SCALE(300));
451         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
452                          METADATA_SCALE(75));
453     }
454 }
455 
checkSurfaceSmpteMetadata(EGLSurface eglSurface)456 void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
457     EGLBoolean success;
458     EGLint value;
459 
460     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
461         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
462         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
463         ASSERT_EQ(METADATA_SCALE(0.640), value);
464         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
465         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
466         ASSERT_EQ(METADATA_SCALE(0.330), value);
467         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
468         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
469         ASSERT_EQ(METADATA_SCALE(0.290), value);
470         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
471         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
472         ASSERT_EQ(METADATA_SCALE(0.600), value);
473         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
474         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
475         ASSERT_EQ(METADATA_SCALE(0.150), value);
476         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
477         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
478         ASSERT_EQ(METADATA_SCALE(0.060), value);
479         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
480         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
481         ASSERT_EQ(METADATA_SCALE(0.3127), value);
482         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
483         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
484         ASSERT_EQ(METADATA_SCALE(0.3290), value);
485         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
486         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
487         ASSERT_EQ(METADATA_SCALE(300.0), value);
488         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
489         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
490         ASSERT_EQ(METADATA_SCALE(0.7), value);
491     }
492 
493     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
494         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
495         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
496         ASSERT_EQ(METADATA_SCALE(300.0), value);
497         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
498         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
499         ASSERT_EQ(METADATA_SCALE(75.0), value);
500     }
501 }
502 
TEST_F(EGLTest,EGLBT2020Linear)503 TEST_F(EGLTest, EGLBT2020Linear) {
504     EGLConfig config;
505     EGLBoolean success;
506 
507     if (!hasHdrDisplay) {
508         // skip this test if device does not have HDR display
509         RecordProperty("hasHdrDisplay", false);
510         return;
511     }
512 
513     // Test that bt2020 linear extension exists
514     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
515             << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
516 
517     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
518 
519     struct DummyConsumer : public BnConsumerListener {
520         void onFrameAvailable(const BufferItem& /* item */) override {}
521         void onBuffersReleased() override {}
522         void onSidebandStreamChanged() override {}
523     };
524 
525     // Create a EGLSurface
526     sp<IGraphicBufferProducer> producer;
527     sp<IGraphicBufferConsumer> consumer;
528     BufferQueue::createBufferQueue(&producer, &consumer);
529     consumer->consumerConnect(new DummyConsumer, false);
530     sp<Surface> mSTC = new Surface(producer);
531     sp<ANativeWindow> mANW = mSTC;
532 
533     std::vector<EGLint> winAttrs;
534     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
535     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
536 
537     winAttrs.push_back(EGL_NONE);
538 
539     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
540     ASSERT_EQ(EGL_SUCCESS, eglGetError());
541     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
542 
543     EGLint value;
544     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
545     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
546     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
547 
548     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
549 
550     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
551 
552     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
553 }
554 
TEST_F(EGLTest,EGLBT2020PQ)555 TEST_F(EGLTest, EGLBT2020PQ) {
556     EGLConfig config;
557     EGLBoolean success;
558 
559     if (!hasHdrDisplay) {
560         // skip this test if device does not have HDR display
561         RecordProperty("hasHdrDisplay", false);
562         return;
563     }
564 
565     // Test that bt2020-pq extension exists
566     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
567             << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
568 
569     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
570 
571     struct DummyConsumer : public BnConsumerListener {
572         void onFrameAvailable(const BufferItem& /* item */) override {}
573         void onBuffersReleased() override {}
574         void onSidebandStreamChanged() override {}
575     };
576 
577     // Create a EGLSurface
578     sp<IGraphicBufferProducer> producer;
579     sp<IGraphicBufferConsumer> consumer;
580     BufferQueue::createBufferQueue(&producer, &consumer);
581     consumer->consumerConnect(new DummyConsumer, false);
582     sp<Surface> mSTC = new Surface(producer);
583     sp<ANativeWindow> mANW = mSTC;
584     std::vector<EGLint> winAttrs;
585     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
586     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
587     winAttrs.push_back(EGL_NONE);
588 
589     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
590     ASSERT_EQ(EGL_SUCCESS, eglGetError());
591     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
592 
593     EGLint value;
594     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
595     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
596     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
597 
598     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
599 
600     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
601 
602     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
603 }
604 
TEST_F(EGLTest,EGLConfigFP16)605 TEST_F(EGLTest, EGLConfigFP16) {
606     EGLint numConfigs;
607     EGLConfig config;
608     EGLBoolean success;
609 
610     if (!hasWideColorDisplay) {
611         // skip this test if device does not have wide-color display
612         RecordProperty("hasWideColorDisplay", false);
613         return;
614     }
615 
616     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
617 
618     const EGLint attrs[] = {
619             // clang-format off
620             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
621             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
622             EGL_RED_SIZE,                 16,
623             EGL_GREEN_SIZE,               16,
624             EGL_BLUE_SIZE,                16,
625             EGL_ALPHA_SIZE,               16,
626             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
627             EGL_NONE,
628             // clang-format on
629     };
630     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
631     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
632     ASSERT_EQ(1, numConfigs);
633 
634     EGLint components[4];
635 
636     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
637     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
638     ASSERT_EQ(EGL_SUCCESS, eglGetError());
639     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
640     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
641     ASSERT_EQ(EGL_SUCCESS, eglGetError());
642     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
643     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
644     ASSERT_EQ(EGL_SUCCESS, eglGetError());
645     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
646     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
647     ASSERT_EQ(EGL_SUCCESS, eglGetError());
648 
649     EXPECT_GE(components[0], 16);
650     EXPECT_GE(components[1], 16);
651     EXPECT_GE(components[2], 16);
652     EXPECT_GE(components[3], 16);
653 
654     struct DummyConsumer : public BnConsumerListener {
655         void onFrameAvailable(const BufferItem& /* item */) override {}
656         void onBuffersReleased() override {}
657         void onSidebandStreamChanged() override {}
658     };
659 
660     sp<IGraphicBufferProducer> producer;
661     sp<IGraphicBufferConsumer> consumer;
662     BufferQueue::createBufferQueue(&producer, &consumer);
663     consumer->consumerConnect(new DummyConsumer, false);
664     sp<Surface> mSTC = new Surface(producer);
665     sp<ANativeWindow> mANW = mSTC;
666 
667     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
668     ASSERT_EQ(EGL_SUCCESS, eglGetError());
669     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
670 
671     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
672 }
673 
TEST_F(EGLTest,EGLNoConfigContext)674 TEST_F(EGLTest, EGLNoConfigContext) {
675     if (!hasWideColorDisplay) {
676         // skip this test if device does not have wide-color display
677         RecordProperty("hasWideColorDisplay", false);
678         return;
679     }
680 
681     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
682 
683     struct DummyConsumer : public BnConsumerListener {
684         void onFrameAvailable(const BufferItem& /* item */) override {}
685         void onBuffersReleased() override {}
686         void onSidebandStreamChanged() override {}
687     };
688 
689     std::vector<EGLint> contextAttributes;
690     contextAttributes.reserve(4);
691     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
692     contextAttributes.push_back(2);
693     contextAttributes.push_back(EGL_NONE);
694     contextAttributes.push_back(EGL_NONE);
695 
696     EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
697                                              contextAttributes.data());
698     EXPECT_NE(EGL_NO_CONTEXT, eglContext);
699     EXPECT_EQ(EGL_SUCCESS, eglGetError());
700 
701     if (eglContext != EGL_NO_CONTEXT) {
702         eglDestroyContext(mEglDisplay, eglContext);
703     }
704 }
705 
706 // Emulate what a native application would do to create a
707 // 10:10:10:2 surface.
TEST_F(EGLTest,EGLConfig1010102)708 TEST_F(EGLTest, EGLConfig1010102) {
709     EGLint numConfigs;
710     EGLConfig config;
711     EGLBoolean success;
712 
713     if (!hasWideColorDisplay) {
714         // skip this test if device does not have wide-color display
715         RecordProperty("hasWideColorDisplay", false);
716         return;
717     }
718 
719     const EGLint attrs[] = {
720             // clang-format off
721             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
722             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
723             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
724             EGL_RED_SIZE,                 10,
725             EGL_GREEN_SIZE,               10,
726             EGL_BLUE_SIZE,                10,
727             EGL_ALPHA_SIZE,               2,
728             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
729             EGL_NONE,                     EGL_NONE
730             // clang-format on
731     };
732     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
733     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
734     ASSERT_EQ(1, numConfigs);
735 
736     EGLint components[4];
737     EGLint value;
738     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
739 
740     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
741     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
742     ASSERT_EQ(EGL_SUCCESS, eglGetError());
743     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
744     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
745     ASSERT_EQ(EGL_SUCCESS, eglGetError());
746     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
747     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
748     ASSERT_EQ(EGL_SUCCESS, eglGetError());
749     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
750     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
751     ASSERT_EQ(EGL_SUCCESS, eglGetError());
752 
753     EXPECT_EQ(components[0], 10);
754     EXPECT_EQ(components[1], 10);
755     EXPECT_EQ(components[2], 10);
756     EXPECT_EQ(components[3], 2);
757 
758     struct DummyConsumer : public BnConsumerListener {
759         void onFrameAvailable(const BufferItem& /* item */) override {}
760         void onBuffersReleased() override {}
761         void onSidebandStreamChanged() override {}
762     };
763 
764     // Create a EGLSurface
765     sp<IGraphicBufferProducer> producer;
766     sp<IGraphicBufferConsumer> consumer;
767     BufferQueue::createBufferQueue(&producer, &consumer);
768     consumer->consumerConnect(new DummyConsumer, false);
769     sp<Surface> mSTC = new Surface(producer);
770     sp<ANativeWindow> mANW = mSTC;
771 
772     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
773     ASSERT_EQ(EGL_SUCCESS, eglGetError());
774     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
775 
776     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
777 }
778 }
779