blob: cca91c3a6f64f47900093cee60bd5a913e75231f [file] [log] [blame]
Mathias Agopian2f739f82011-07-07 14:54:30 -07001/*
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
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060019#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
20
21#include <configstore/Utils.h>
Mathias Agopian2f739f82011-07-07 14:54:30 -070022#include <utils/String8.h>
23
24#include <EGL/egl.h>
Mathias Agopiane3c697f2013-02-14 17:11:02 -080025#include <gui/Surface.h>
Mathias Agopian2b5dd402017-02-07 17:36:19 -080026#include <gui/IConsumerListener.h>
27#include <gui/IProducerListener.h>
28#include <gui/IGraphicBufferConsumer.h>
29#include <gui/BufferQueue.h>
Mathias Agopian2f739f82011-07-07 14:54:30 -070030
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -060031bool hasEglExtension(EGLDisplay dpy, const char* extensionName) {
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060032 const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -060033 size_t cropExtLen = strlen(extensionName);
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060034 size_t extsLen = strlen(exts);
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -060035 bool equal = !strcmp(extensionName, exts);
36 android::String8 extString(extensionName);
37 android::String8 space(" ");
38 bool atStart = !strncmp(extString + space, exts, cropExtLen + 1);
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060039 bool atEnd = (cropExtLen + 1) < extsLen &&
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -060040 !strcmp(space + extString, exts + extsLen - (cropExtLen + 1));
41 bool inMiddle = strstr(exts, space + extString + space);
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060042 return equal || atStart || atEnd || inMiddle;
43}
44
Mathias Agopian2f739f82011-07-07 14:54:30 -070045namespace android {
46
Kalle Raita4cf36372017-01-13 10:18:36 -080047#define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE)
48
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060049// retrieve wide-color setting from configstore
50using namespace android::hardware::configstore;
Jaesoo Lee3b746b32017-05-02 22:19:39 +090051using namespace android::hardware::configstore::V1_0;
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060052
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -080053#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
54
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -060055static bool hasWideColorDisplay =
56 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
57
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -070058static bool hasHdrDisplay =
59 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
60
Mathias Agopian2f739f82011-07-07 14:54:30 -070061class EGLTest : public ::testing::Test {
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -070062public:
63 void get8BitConfig(EGLConfig& config);
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -070064 void setSurfaceSmpteMetadata(EGLSurface surface);
65 void checkSurfaceSmpteMetadata(EGLSurface eglSurface);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -070066
Mathias Agopian2f739f82011-07-07 14:54:30 -070067protected:
68 EGLDisplay mEglDisplay;
69
70protected:
71 EGLTest() :
72 mEglDisplay(EGL_NO_DISPLAY) {
73 }
74
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
88 virtual void TearDown() {
89 EGLBoolean success = eglTerminate(mEglDisplay);
Kalle Raita4cf36372017-01-13 10:18:36 -080090 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -070091 ASSERT_EQ(EGL_SUCCESS, eglGetError());
92 }
93};
94
95TEST_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);
Kalle Raita4cf36372017-01-13 10:18:36 -0800107 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700108 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]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800114 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700115 ASSERT_EQ(EGL_SUCCESS, eglGetError());
116 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800117 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700118 ASSERT_EQ(EGL_SUCCESS, eglGetError());
119 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800120 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700121 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
Daniel Lam1cbcb982012-04-16 22:21:02 -0700128TEST_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
Mathias Agopiana4e19522013-07-31 20:09:53 -0700142 struct DummyConsumer : public BnConsumerListener {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800143 void onFrameAvailable(const BufferItem& /* item */) override {}
144 void onBuffersReleased() override {}
145 void onSidebandStreamChanged() override {}
Mathias Agopian595264f2013-07-16 22:56:09 -0700146 };
147
Daniel Lam1cbcb982012-04-16 22:21:02 -0700148 // Create a EGLSurface
Dan Stoza5603a2f2014-04-07 13:41:37 -0700149 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);
Daniel Lam1cbcb982012-04-16 22:21:02 -0700154 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
Mathias Agopian2f739f82011-07-07 14:54:30 -0700165TEST_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);
Kalle Raita4cf36372017-01-13 10:18:36 -0800181 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700182 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]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800188 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700189 ASSERT_EQ(EGL_SUCCESS, eglGetError());
190 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800191 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700192 ASSERT_EQ(EGL_SUCCESS, eglGetError());
193 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800194 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700195 ASSERT_EQ(EGL_SUCCESS, eglGetError());
196 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800197 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700198 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
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600206TEST_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
Courtney Goeltzenleuchtere4177262017-07-10 16:34:25 -0600213 std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600214 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"));
Peiyong Line0ff3772018-12-08 22:23:20 -0800220 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600221
222 // Use 8-bit to keep forcus on Display-P3 aspect
223 EGLint attrs[] = {
224 // clang-format off
225 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
226 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
227 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
228 EGL_RED_SIZE, 8,
229 EGL_GREEN_SIZE, 8,
230 EGL_BLUE_SIZE, 8,
231 EGL_ALPHA_SIZE, 8,
232 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
233 EGL_NONE, EGL_NONE
234 // clang-format on
235 };
236 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
237 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
238 ASSERT_EQ(1, numConfigs);
239
240 EGLint components[4];
241 EGLint value;
242 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
243
244 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
245 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
246 ASSERT_EQ(EGL_SUCCESS, eglGetError());
247 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
248 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
249 ASSERT_EQ(EGL_SUCCESS, eglGetError());
250 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
251 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
252 ASSERT_EQ(EGL_SUCCESS, eglGetError());
253 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
254 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
255 ASSERT_EQ(EGL_SUCCESS, eglGetError());
256
257 EXPECT_EQ(components[0], 8);
258 EXPECT_EQ(components[1], 8);
259 EXPECT_EQ(components[2], 8);
260 EXPECT_EQ(components[3], 8);
261
262 struct DummyConsumer : public BnConsumerListener {
263 void onFrameAvailable(const BufferItem& /* item */) override {}
264 void onBuffersReleased() override {}
265 void onSidebandStreamChanged() override {}
266 };
267
268 // Create a EGLSurface
269 sp<IGraphicBufferProducer> producer;
270 sp<IGraphicBufferConsumer> consumer;
271 BufferQueue::createBufferQueue(&producer, &consumer);
272 consumer->consumerConnect(new DummyConsumer, false);
273 sp<Surface> mSTC = new Surface(producer);
274 sp<ANativeWindow> mANW = mSTC;
275 EGLint winAttrs[] = {
276 // clang-format off
277 EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
278 EGL_NONE, EGL_NONE
279 // clang-format on
280 };
281
282 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
283 ASSERT_EQ(EGL_SUCCESS, eglGetError());
284 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
285
286 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
287 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
288 ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
289
290 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
291}
292
Peiyong Line0ff3772018-12-08 22:23:20 -0800293TEST_F(EGLTest, EGLDisplayP3Passthrough) {
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 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
307
308 get8BitConfig(config);
309
310 struct DummyConsumer : public BnConsumerListener {
311 void onFrameAvailable(const BufferItem& /* item */) override {}
312 void onBuffersReleased() override {}
313 void onSidebandStreamChanged() override {}
314 };
315
316 // Create a EGLSurface
317 sp<IGraphicBufferProducer> producer;
318 sp<IGraphicBufferConsumer> consumer;
319 BufferQueue::createBufferQueue(&producer, &consumer);
320 consumer->consumerConnect(new DummyConsumer, false);
321 sp<Surface> mSTC = new Surface(producer);
322 sp<ANativeWindow> mANW = mSTC;
323 EGLint winAttrs[] = {
324 // clang-format off
325 EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
326 EGL_NONE, EGL_NONE
327 // clang-format on
328 };
329
330 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
331 ASSERT_EQ(EGL_SUCCESS, eglGetError());
332 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
333
334 android_dataspace dataspace =
335 static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
336 ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
337
338 EGLint value;
339 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
340 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
341 ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT, value);
342
343 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
344}
345
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600346TEST_F(EGLTest, EGLDisplayP31010102) {
347 EGLint numConfigs;
348 EGLConfig config;
349 EGLBoolean success;
350
351 if (!hasWideColorDisplay) {
352 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchtere4177262017-07-10 16:34:25 -0600353 std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600354 return;
355 }
356
357 // Test that display-p3 extensions exist
358 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
359 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
Peiyong Line0ff3772018-12-08 22:23:20 -0800360 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600361
362 // Use 8-bit to keep forcus on Display-P3 aspect
363 EGLint attrs[] = {
364 // clang-format off
365 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
366 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
367 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
368 EGL_RED_SIZE, 10,
369 EGL_GREEN_SIZE, 10,
370 EGL_BLUE_SIZE, 10,
371 EGL_ALPHA_SIZE, 2,
372 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
373 EGL_NONE, EGL_NONE
374 // clang-format on
375 };
376 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
377 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
378 ASSERT_EQ(1, numConfigs);
379
380 EGLint components[4];
381 EGLint value;
382 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
383
384 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
385 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
386 ASSERT_EQ(EGL_SUCCESS, eglGetError());
387 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
388 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
389 ASSERT_EQ(EGL_SUCCESS, eglGetError());
390 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
391 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
392 ASSERT_EQ(EGL_SUCCESS, eglGetError());
393 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
394 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
395 ASSERT_EQ(EGL_SUCCESS, eglGetError());
396
397 EXPECT_EQ(components[0], 10);
398 EXPECT_EQ(components[1], 10);
399 EXPECT_EQ(components[2], 10);
400 EXPECT_EQ(components[3], 2);
401
402 struct DummyConsumer : public BnConsumerListener {
403 void onFrameAvailable(const BufferItem& /* item */) override {}
404 void onBuffersReleased() override {}
405 void onSidebandStreamChanged() override {}
406 };
407
408 // Create a EGLSurface
409 sp<IGraphicBufferProducer> producer;
410 sp<IGraphicBufferConsumer> consumer;
411 BufferQueue::createBufferQueue(&producer, &consumer);
412 consumer->consumerConnect(new DummyConsumer, false);
413 sp<Surface> mSTC = new Surface(producer);
414 sp<ANativeWindow> mANW = mSTC;
415 EGLint winAttrs[] = {
416 // clang-format off
417 EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
418 EGL_NONE, EGL_NONE
419 // clang-format on
420 };
421
422 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
423 ASSERT_EQ(EGL_SUCCESS, eglGetError());
424 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
425
426 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
427 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
428 ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
429
430 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
431}
432
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700433void EGLTest::get8BitConfig(EGLConfig& config) {
434 EGLint numConfigs;
435 EGLBoolean success;
436
437 // Use 8-bit to keep focus on colorspace aspect
438 const EGLint attrs[] = {
439 // clang-format off
440 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
441 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
442 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
443 EGL_RED_SIZE, 8,
444 EGL_GREEN_SIZE, 8,
445 EGL_BLUE_SIZE, 8,
446 EGL_ALPHA_SIZE, 8,
447 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
448 EGL_NONE,
449 // clang-format on
450 };
451 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
452 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
453 ASSERT_EQ(1, numConfigs);
454
455 EGLint components[4];
456 EGLint value;
457 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
458
459 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
460 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
461 ASSERT_EQ(EGL_SUCCESS, eglGetError());
462 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
463 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
464 ASSERT_EQ(EGL_SUCCESS, eglGetError());
465 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
466 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
467 ASSERT_EQ(EGL_SUCCESS, eglGetError());
468 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
469 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
470 ASSERT_EQ(EGL_SUCCESS, eglGetError());
471
472 // Verify component sizes on config match what was asked for.
473 EXPECT_EQ(components[0], 8);
474 EXPECT_EQ(components[1], 8);
475 EXPECT_EQ(components[2], 8);
476 EXPECT_EQ(components[3], 8);
477}
478
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -0700479void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700480 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -0700481 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
482 METADATA_SCALE(0.640));
483 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
484 METADATA_SCALE(0.330));
485 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
486 METADATA_SCALE(0.290));
487 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
488 METADATA_SCALE(0.600));
489 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
490 METADATA_SCALE(0.150));
491 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
492 METADATA_SCALE(0.060));
493 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
494 METADATA_SCALE(0.3127));
495 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
496 METADATA_SCALE(0.3290));
497 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
498 METADATA_SCALE(300));
499 eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
500 METADATA_SCALE(0.7));
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700501 }
502
503 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -0700504 eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
505 METADATA_SCALE(300));
506 eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
507 METADATA_SCALE(75));
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700508 }
509}
510
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -0700511void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700512 EGLBoolean success;
513 EGLint value;
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700514
515 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
516 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
517 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800518 ASSERT_EQ(METADATA_SCALE(0.640), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700519 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
520 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800521 ASSERT_EQ(METADATA_SCALE(0.330), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700522 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
523 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800524 ASSERT_EQ(METADATA_SCALE(0.290), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700525 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
526 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800527 ASSERT_EQ(METADATA_SCALE(0.600), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700528 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
529 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800530 ASSERT_EQ(METADATA_SCALE(0.150), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700531 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
532 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800533 ASSERT_EQ(METADATA_SCALE(0.060), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700534 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
535 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800536 ASSERT_EQ(METADATA_SCALE(0.3127), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700537 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
538 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800539 ASSERT_EQ(METADATA_SCALE(0.3290), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700540 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
541 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800542 ASSERT_EQ(METADATA_SCALE(300.0), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700543 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
544 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800545 ASSERT_EQ(METADATA_SCALE(0.7), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700546 }
547
548 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
549 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
550 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800551 ASSERT_EQ(METADATA_SCALE(300.0), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700552 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
553 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Courtney Goeltzenleuchter786ab882018-01-26 13:37:33 -0800554 ASSERT_EQ(METADATA_SCALE(75.0), value);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700555 }
556}
557
558TEST_F(EGLTest, EGLBT2020Linear) {
559 EGLConfig config;
560 EGLBoolean success;
561
562 if (!hasHdrDisplay) {
563 // skip this test if device does not have HDR display
564 RecordProperty("hasHdrDisplay", false);
565 return;
566 }
567
568 // Test that bt2020 linear extension exists
569 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
570 << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
571
572 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
573
574 struct DummyConsumer : public BnConsumerListener {
575 void onFrameAvailable(const BufferItem& /* item */) override {}
576 void onBuffersReleased() override {}
577 void onSidebandStreamChanged() override {}
578 };
579
580 // Create a EGLSurface
581 sp<IGraphicBufferProducer> producer;
582 sp<IGraphicBufferConsumer> consumer;
583 BufferQueue::createBufferQueue(&producer, &consumer);
584 consumer->consumerConnect(new DummyConsumer, false);
585 sp<Surface> mSTC = new Surface(producer);
586 sp<ANativeWindow> mANW = mSTC;
587
588 std::vector<EGLint> winAttrs;
589 winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
590 winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
591
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700592 winAttrs.push_back(EGL_NONE);
593
594 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
595 ASSERT_EQ(EGL_SUCCESS, eglGetError());
596 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
597
598 EGLint value;
599 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
600 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
601 ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
602
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -0700603 ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
604
605 ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700606
607 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
608}
609
610TEST_F(EGLTest, EGLBT2020PQ) {
611 EGLConfig config;
612 EGLBoolean success;
613
614 if (!hasHdrDisplay) {
615 // skip this test if device does not have HDR display
616 RecordProperty("hasHdrDisplay", false);
617 return;
618 }
619
620 // Test that bt2020-pq extension exists
621 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
622 << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
623
624 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
625
626 struct DummyConsumer : public BnConsumerListener {
627 void onFrameAvailable(const BufferItem& /* item */) override {}
628 void onBuffersReleased() override {}
629 void onSidebandStreamChanged() override {}
630 };
631
632 // Create a EGLSurface
633 sp<IGraphicBufferProducer> producer;
634 sp<IGraphicBufferConsumer> consumer;
635 BufferQueue::createBufferQueue(&producer, &consumer);
636 consumer->consumerConnect(new DummyConsumer, false);
637 sp<Surface> mSTC = new Surface(producer);
638 sp<ANativeWindow> mANW = mSTC;
639 std::vector<EGLint> winAttrs;
640 winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
641 winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700642 winAttrs.push_back(EGL_NONE);
643
644 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
645 ASSERT_EQ(EGL_SUCCESS, eglGetError());
646 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
647
648 EGLint value;
649 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
650 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
651 ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
652
Courtney Goeltzenleuchter936799c2018-03-02 16:47:08 -0700653 ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
654
655 ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700656
657 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
658}
659
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600660TEST_F(EGLTest, EGLConfigFP16) {
661 EGLint numConfigs;
662 EGLConfig config;
663 EGLBoolean success;
Mathias Agopian2f739f82011-07-07 14:54:30 -0700664
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600665 if (!hasWideColorDisplay) {
666 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700667 RecordProperty("hasWideColorDisplay", false);
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600668 return;
669 }
670
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600671 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600672
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700673 const EGLint attrs[] = {
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600674 // clang-format off
675 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
676 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
677 EGL_RED_SIZE, 16,
678 EGL_GREEN_SIZE, 16,
679 EGL_BLUE_SIZE, 16,
680 EGL_ALPHA_SIZE, 16,
681 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700682 EGL_NONE,
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600683 // clang-format on
684 };
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600685 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
686 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
687 ASSERT_EQ(1, numConfigs);
688
689 EGLint components[4];
690
691 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
692 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
693 ASSERT_EQ(EGL_SUCCESS, eglGetError());
694 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
695 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
696 ASSERT_EQ(EGL_SUCCESS, eglGetError());
697 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
698 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
699 ASSERT_EQ(EGL_SUCCESS, eglGetError());
700 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
701 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
702 ASSERT_EQ(EGL_SUCCESS, eglGetError());
703
704 EXPECT_GE(components[0], 16);
705 EXPECT_GE(components[1], 16);
706 EXPECT_GE(components[2], 16);
707 EXPECT_GE(components[3], 16);
708
709 struct DummyConsumer : public BnConsumerListener {
710 void onFrameAvailable(const BufferItem& /* item */) override {}
711 void onBuffersReleased() override {}
712 void onSidebandStreamChanged() override {}
713 };
714
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600715 sp<IGraphicBufferProducer> producer;
716 sp<IGraphicBufferConsumer> consumer;
717 BufferQueue::createBufferQueue(&producer, &consumer);
718 consumer->consumerConnect(new DummyConsumer, false);
719 sp<Surface> mSTC = new Surface(producer);
720 sp<ANativeWindow> mANW = mSTC;
721
722 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
723 ASSERT_EQ(EGL_SUCCESS, eglGetError());
724 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
725
726 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
727}
728
Courtney Goeltzenleuchterd99694b2017-07-10 16:30:42 -0600729TEST_F(EGLTest, EGLNoConfigContext) {
Courtney Goeltzenleuchterf7ed1b42017-04-17 17:27:47 -0600730 if (!hasWideColorDisplay) {
731 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700732 RecordProperty("hasWideColorDisplay", false);
Courtney Goeltzenleuchterf7ed1b42017-04-17 17:27:47 -0600733 return;
734 }
735
736 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
737
738 struct DummyConsumer : public BnConsumerListener {
739 void onFrameAvailable(const BufferItem& /* item */) override {}
740 void onBuffersReleased() override {}
741 void onSidebandStreamChanged() override {}
742 };
743
744 std::vector<EGLint> contextAttributes;
745 contextAttributes.reserve(4);
746 contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
747 contextAttributes.push_back(2);
748 contextAttributes.push_back(EGL_NONE);
749 contextAttributes.push_back(EGL_NONE);
750
751 EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
752 contextAttributes.data());
753 EXPECT_NE(EGL_NO_CONTEXT, eglContext);
754 EXPECT_EQ(EGL_SUCCESS, eglGetError());
755
756 if (eglContext != EGL_NO_CONTEXT) {
757 eglDestroyContext(mEglDisplay, eglContext);
758 }
759}
760
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600761// Emulate what a native application would do to create a
762// 10:10:10:2 surface.
763TEST_F(EGLTest, EGLConfig1010102) {
764 EGLint numConfigs;
765 EGLConfig config;
766 EGLBoolean success;
767
768 if (!hasWideColorDisplay) {
769 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700770 RecordProperty("hasWideColorDisplay", false);
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600771 return;
772 }
773
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700774 const EGLint attrs[] = {
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600775 // clang-format off
776 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
777 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
778 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
779 EGL_RED_SIZE, 10,
780 EGL_GREEN_SIZE, 10,
781 EGL_BLUE_SIZE, 10,
782 EGL_ALPHA_SIZE, 2,
783 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
784 EGL_NONE, EGL_NONE
785 // clang-format on
786 };
787 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
788 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
789 ASSERT_EQ(1, numConfigs);
790
791 EGLint components[4];
792 EGLint value;
793 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
794
795 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
796 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
797 ASSERT_EQ(EGL_SUCCESS, eglGetError());
798 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
799 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
800 ASSERT_EQ(EGL_SUCCESS, eglGetError());
801 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
802 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
803 ASSERT_EQ(EGL_SUCCESS, eglGetError());
804 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
805 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
806 ASSERT_EQ(EGL_SUCCESS, eglGetError());
807
808 EXPECT_EQ(components[0], 10);
809 EXPECT_EQ(components[1], 10);
810 EXPECT_EQ(components[2], 10);
811 EXPECT_EQ(components[3], 2);
812
813 struct DummyConsumer : public BnConsumerListener {
814 void onFrameAvailable(const BufferItem& /* item */) override {}
815 void onBuffersReleased() override {}
816 void onSidebandStreamChanged() override {}
817 };
818
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600819 // Create a EGLSurface
820 sp<IGraphicBufferProducer> producer;
821 sp<IGraphicBufferConsumer> consumer;
822 BufferQueue::createBufferQueue(&producer, &consumer);
823 consumer->consumerConnect(new DummyConsumer, false);
824 sp<Surface> mSTC = new Surface(producer);
825 sp<ANativeWindow> mANW = mSTC;
826
827 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
828 ASSERT_EQ(EGL_SUCCESS, eglGetError());
829 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
830
831 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
832}
Weiwan Liu3ca92972018-09-28 15:44:12 -0700833
834TEST_F(EGLTest, EGLInvalidColorspaceAttribute) {
835 EGLConfig config;
836
837 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
838
839 struct DummyConsumer : public BnConsumerListener {
840 void onFrameAvailable(const BufferItem& /* item */) override {}
841 void onBuffersReleased() override {}
842 void onSidebandStreamChanged() override {}
843 };
844
845 // Create a EGLSurface
846 sp<IGraphicBufferProducer> producer;
847 sp<IGraphicBufferConsumer> consumer;
848 BufferQueue::createBufferQueue(&producer, &consumer);
849 consumer->consumerConnect(new DummyConsumer, false);
850 sp<Surface> mSTC = new Surface(producer);
851 sp<ANativeWindow> mANW = mSTC;
852
853 EGLint winAttrs[] = {
854 // clang-format off
855 EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
856 EGL_NONE,
857 // clang-format on
858 };
859
860 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
861 ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
862 ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
863}
864
865TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) {
866 EGLint numConfigs;
867 EGLConfig config;
868 EGLBoolean success;
869
870 const EGLint attrs[] = {
871 // clang-format off
872 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
873 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
874 EGL_RED_SIZE, 16,
875 EGL_GREEN_SIZE, 16,
876 EGL_BLUE_SIZE, 16,
877 EGL_ALPHA_SIZE, 16,
878 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
879 EGL_NONE,
880 // clang-format on
881 };
882 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
883 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
884 ASSERT_EQ(1, numConfigs);
885
886 struct DummyConsumer : public BnConsumerListener {
887 void onFrameAvailable(const BufferItem& /* item */) override {}
888 void onBuffersReleased() override {}
889 void onSidebandStreamChanged() override {}
890 };
891
892 // Create a EGLSurface
893 sp<IGraphicBufferProducer> producer;
894 sp<IGraphicBufferConsumer> consumer;
895 BufferQueue::createBufferQueue(&producer, &consumer);
896 consumer->consumerConnect(new DummyConsumer, false);
897 sp<Surface> mSTC = new Surface(producer);
898 sp<ANativeWindow> mANW = mSTC;
899
900 const EGLint winAttrs[] = {
901 // clang-format off
902 EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
903 EGL_NONE,
904 // clang-format on
905 };
906
907 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
908 ASSERT_EQ(EGL_BAD_MATCH, eglGetError());
909 ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
910}
911
912TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) {
913 EGLConfig config;
914
915 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
916
917 struct DummyConsumer : public BnConsumerListener {
918 void onFrameAvailable(const BufferItem& /* item */) override {}
919 void onBuffersReleased() override {}
920 void onSidebandStreamChanged() override {}
921 };
922
923 // Create a EGLSurface
924 sp<IGraphicBufferProducer> producer;
925 sp<IGraphicBufferConsumer> consumer;
926 BufferQueue::createBufferQueue(&producer, &consumer);
927 consumer->consumerConnect(new DummyConsumer, false);
928 sp<Surface> mSTC = new Surface(producer);
929 sp<ANativeWindow> mANW = mSTC;
930
931 EGLint winAttrs[] = {
932 // clang-format off
933 EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
934 EGL_NONE,
935 // clang-format on
936 };
937
938 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
939 ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
940 ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
941
942 // Now recreate surface with a valid colorspace. Ensure proper cleanup is done
943 // in the first failed attempt (e.g. native_window_api_disconnect).
944 winAttrs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
945 eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
946 ASSERT_EQ(EGL_SUCCESS, eglGetError());
947 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
948
949 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
950}
951
952TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) {
953 EGLConfig config;
954
955 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
956
957 struct DummyConsumer : public BnConsumerListener {
958 void onFrameAvailable(const BufferItem& /* item */) override {}
959 void onBuffersReleased() override {}
960 void onSidebandStreamChanged() override {}
961 };
962
963 // Create a EGLSurface
964 sp<IGraphicBufferProducer> producer;
965 sp<IGraphicBufferConsumer> consumer;
966 BufferQueue::createBufferQueue(&producer, &consumer);
967 consumer->consumerConnect(new DummyConsumer, false);
968 sp<Surface> mSTC = new Surface(producer);
969 sp<ANativeWindow> mANW = mSTC;
970
971 const EGLint winAttrs[] = {
972 // clang-format off
973 EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
974 EGL_NONE,
975 // clang-format on
976 };
977
978 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
979 ASSERT_EQ(EGL_SUCCESS, eglGetError());
980 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
981
982 android_dataspace dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
983 ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
984
985 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
986
987 // Now create with default attribute (EGL_GL_COLORSPACE_LINEAR_KHR)
988 eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
989 ASSERT_EQ(EGL_SUCCESS, eglGetError());
990 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
991
992 dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
993 // Make sure the dataspace has been reset to UNKNOWN
994 ASSERT_NE(dataspace, HAL_DATASPACE_DISPLAY_P3);
995
996 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
997}
Mathias Agopian2f739f82011-07-07 14:54:30 -0700998}