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