blob: 8bb74a2b29b14c4b5f6837fa0621a770ca8b5a42 [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
53static bool hasWideColorDisplay =
54 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
55
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -070056static bool hasHdrDisplay =
57 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
58
59union FlexAttribute {
60 EGLint uint_value;
61 float float_value;
62};
63
Mathias Agopian2f739f82011-07-07 14:54:30 -070064class EGLTest : public ::testing::Test {
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -070065public:
66 void get8BitConfig(EGLConfig& config);
67 void addOptionalWindowMetadata(std::vector<EGLint>& attrs);
68 void checkOptionalWindowMetadata(EGLSurface eglSurface);
69
Mathias Agopian2f739f82011-07-07 14:54:30 -070070protected:
71 EGLDisplay mEglDisplay;
72
73protected:
74 EGLTest() :
75 mEglDisplay(EGL_NO_DISPLAY) {
76 }
77
78 virtual void SetUp() {
79 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
80 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
81 ASSERT_EQ(EGL_SUCCESS, eglGetError());
82
83 EGLint majorVersion;
84 EGLint minorVersion;
85 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
86 ASSERT_EQ(EGL_SUCCESS, eglGetError());
87 RecordProperty("EglVersionMajor", majorVersion);
88 RecordProperty("EglVersionMajor", minorVersion);
89 }
90
91 virtual void TearDown() {
92 EGLBoolean success = eglTerminate(mEglDisplay);
Kalle Raita4cf36372017-01-13 10:18:36 -080093 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -070094 ASSERT_EQ(EGL_SUCCESS, eglGetError());
95 }
96};
97
98TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) {
99
100 EGLint numConfigs;
101 EGLConfig config;
102 EGLBoolean success;
103 EGLint attrs[] = {
104 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
105 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
106 EGL_NONE
107 };
108
109 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
Kalle Raita4cf36372017-01-13 10:18:36 -0800110 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700111 ASSERT_EQ(EGL_SUCCESS, eglGetError());
112 ASSERT_GE(numConfigs, 1);
113
114 EGLint components[3];
115
116 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
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_GREEN_SIZE, &components[1]);
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 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800123 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700124 ASSERT_EQ(EGL_SUCCESS, eglGetError());
125
126 EXPECT_GE(components[0], 8);
127 EXPECT_GE(components[1], 8);
128 EXPECT_GE(components[2], 8);
129}
130
Daniel Lam1cbcb982012-04-16 22:21:02 -0700131TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) {
132 EGLint numConfigs;
133 EGLConfig config;
134 EGLint attrs[] = {
135 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
136 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
137 EGL_RED_SIZE, 8,
138 EGL_GREEN_SIZE, 8,
139 EGL_BLUE_SIZE, 8,
140 EGL_ALPHA_SIZE, 8,
141 EGL_NONE
142 };
143 EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
144
Mathias Agopiana4e19522013-07-31 20:09:53 -0700145 struct DummyConsumer : public BnConsumerListener {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800146 void onFrameAvailable(const BufferItem& /* item */) override {}
147 void onBuffersReleased() override {}
148 void onSidebandStreamChanged() override {}
Mathias Agopian595264f2013-07-16 22:56:09 -0700149 };
150
Daniel Lam1cbcb982012-04-16 22:21:02 -0700151 // Create a EGLSurface
Dan Stoza5603a2f2014-04-07 13:41:37 -0700152 sp<IGraphicBufferProducer> producer;
153 sp<IGraphicBufferConsumer> consumer;
154 BufferQueue::createBufferQueue(&producer, &consumer);
155 consumer->consumerConnect(new DummyConsumer, false);
156 sp<Surface> mSTC = new Surface(producer);
Daniel Lam1cbcb982012-04-16 22:21:02 -0700157 sp<ANativeWindow> mANW = mSTC;
158
159 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config,
160 mANW.get(), NULL);
161 ASSERT_EQ(EGL_SUCCESS, eglGetError());
162 ASSERT_NE(EGL_NO_SURFACE, eglSurface) ;
163
164 // do not destroy eglSurface
165 // eglTerminate is called in the tear down and should destroy it for us
166}
167
Mathias Agopian2f739f82011-07-07 14:54:30 -0700168TEST_F(EGLTest, EGLConfigRGBA8888First) {
169
170 EGLint numConfigs;
171 EGLConfig config;
172 EGLBoolean success;
173 EGLint attrs[] = {
174 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
175 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
176 EGL_RED_SIZE, 8,
177 EGL_GREEN_SIZE, 8,
178 EGL_BLUE_SIZE, 8,
179 EGL_ALPHA_SIZE, 8,
180 EGL_NONE
181 };
182
183 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
Kalle Raita4cf36372017-01-13 10:18:36 -0800184 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700185 ASSERT_EQ(EGL_SUCCESS, eglGetError());
186 ASSERT_GE(numConfigs, 1);
187
188 EGLint components[4];
189
190 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
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_GREEN_SIZE, &components[1]);
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_BLUE_SIZE, &components[2]);
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 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
Kalle Raita4cf36372017-01-13 10:18:36 -0800200 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
Mathias Agopian2f739f82011-07-07 14:54:30 -0700201 ASSERT_EQ(EGL_SUCCESS, eglGetError());
202
203 EXPECT_GE(components[0], 8);
204 EXPECT_GE(components[1], 8);
205 EXPECT_GE(components[2], 8);
206 EXPECT_GE(components[3], 8);
207}
208
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600209TEST_F(EGLTest, EGLDisplayP3) {
210 EGLint numConfigs;
211 EGLConfig config;
212 EGLBoolean success;
213
214 if (!hasWideColorDisplay) {
215 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchtere4177262017-07-10 16:34:25 -0600216 std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600217 return;
218 }
219
220 // Test that display-p3 extensions exist
221 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
222 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
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 DummyConsumer : public BnConsumerListener {
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 DummyConsumer, 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
295TEST_F(EGLTest, EGLDisplayP31010102) {
296 EGLint numConfigs;
297 EGLConfig config;
298 EGLBoolean success;
299
300 if (!hasWideColorDisplay) {
301 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchtere4177262017-07-10 16:34:25 -0600302 std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
Courtney Goeltzenleuchter2c325e22017-04-25 14:40:42 -0600303 return;
304 }
305
306 // Test that display-p3 extensions exist
307 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
308 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
309
310 // Use 8-bit to keep forcus on Display-P3 aspect
311 EGLint attrs[] = {
312 // clang-format off
313 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
314 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
315 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
316 EGL_RED_SIZE, 10,
317 EGL_GREEN_SIZE, 10,
318 EGL_BLUE_SIZE, 10,
319 EGL_ALPHA_SIZE, 2,
320 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
321 EGL_NONE, EGL_NONE
322 // clang-format on
323 };
324 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
325 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
326 ASSERT_EQ(1, numConfigs);
327
328 EGLint components[4];
329 EGLint value;
330 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
331
332 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
333 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
334 ASSERT_EQ(EGL_SUCCESS, eglGetError());
335 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
336 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
337 ASSERT_EQ(EGL_SUCCESS, eglGetError());
338 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
339 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
340 ASSERT_EQ(EGL_SUCCESS, eglGetError());
341 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
342 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
343 ASSERT_EQ(EGL_SUCCESS, eglGetError());
344
345 EXPECT_EQ(components[0], 10);
346 EXPECT_EQ(components[1], 10);
347 EXPECT_EQ(components[2], 10);
348 EXPECT_EQ(components[3], 2);
349
350 struct DummyConsumer : public BnConsumerListener {
351 void onFrameAvailable(const BufferItem& /* item */) override {}
352 void onBuffersReleased() override {}
353 void onSidebandStreamChanged() override {}
354 };
355
356 // Create a EGLSurface
357 sp<IGraphicBufferProducer> producer;
358 sp<IGraphicBufferConsumer> consumer;
359 BufferQueue::createBufferQueue(&producer, &consumer);
360 consumer->consumerConnect(new DummyConsumer, false);
361 sp<Surface> mSTC = new Surface(producer);
362 sp<ANativeWindow> mANW = mSTC;
363 EGLint winAttrs[] = {
364 // clang-format off
365 EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
366 EGL_NONE, EGL_NONE
367 // clang-format on
368 };
369
370 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
371 ASSERT_EQ(EGL_SUCCESS, eglGetError());
372 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
373
374 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
375 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
376 ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
377
378 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
379}
380
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700381void EGLTest::get8BitConfig(EGLConfig& config) {
382 EGLint numConfigs;
383 EGLBoolean success;
384
385 // Use 8-bit to keep focus on colorspace aspect
386 const EGLint attrs[] = {
387 // clang-format off
388 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
389 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
390 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
391 EGL_RED_SIZE, 8,
392 EGL_GREEN_SIZE, 8,
393 EGL_BLUE_SIZE, 8,
394 EGL_ALPHA_SIZE, 8,
395 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
396 EGL_NONE,
397 // clang-format on
398 };
399 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
400 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
401 ASSERT_EQ(1, numConfigs);
402
403 EGLint components[4];
404 EGLint value;
405 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
406
407 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
408 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
409 ASSERT_EQ(EGL_SUCCESS, eglGetError());
410 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
411 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
412 ASSERT_EQ(EGL_SUCCESS, eglGetError());
413 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
414 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
415 ASSERT_EQ(EGL_SUCCESS, eglGetError());
416 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
417 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
418 ASSERT_EQ(EGL_SUCCESS, eglGetError());
419
420 // Verify component sizes on config match what was asked for.
421 EXPECT_EQ(components[0], 8);
422 EXPECT_EQ(components[1], 8);
423 EXPECT_EQ(components[2], 8);
424 EXPECT_EQ(components[3], 8);
425}
426
427void EGLTest::addOptionalWindowMetadata(std::vector<EGLint>& attrs) {
428 FlexAttribute data;
429 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
430 attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT);
431 data.float_value = 0.640;
432 attrs.push_back(data.uint_value);
433 attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT);
434 data.float_value = 0.330;
435 attrs.push_back(data.uint_value);
436 attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT);
437 data.float_value = 0.290;
438 attrs.push_back(data.uint_value);
439 attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT);
440 data.float_value = 0.600;
441 attrs.push_back(data.uint_value);
442 attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT);
443 data.float_value = 0.150;
444 attrs.push_back(data.uint_value);
445 attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT);
446 data.float_value = 0.060;
447 attrs.push_back(data.uint_value);
448 attrs.push_back(EGL_SMPTE2086_WHITE_POINT_X_EXT);
449 data.float_value = 0.3127;
450 attrs.push_back(data.uint_value);
451 attrs.push_back(EGL_SMPTE2086_WHITE_POINT_Y_EXT);
452 data.float_value = 0.3290;
453 attrs.push_back(data.uint_value);
454 attrs.push_back(EGL_SMPTE2086_MAX_LUMINANCE_EXT);
455 data.float_value = 300.0;
456 attrs.push_back(data.uint_value);
457 attrs.push_back(EGL_SMPTE2086_MIN_LUMINANCE_EXT);
458 data.float_value = 0.7;
459 attrs.push_back(data.uint_value);
460 }
461
462 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
463 attrs.push_back(EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT);
464 data.float_value = 300.0;
465 attrs.push_back(data.uint_value);
466 attrs.push_back(EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT);
467 data.float_value = 75.0;
468 attrs.push_back(data.uint_value);
469 }
470}
471
472void EGLTest::checkOptionalWindowMetadata(EGLSurface eglSurface) {
473 EGLBoolean success;
474 EGLint value;
475 FlexAttribute expected;
476
477 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
478 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
479 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
480 expected.float_value = 0.640;
481 ASSERT_EQ(expected.uint_value, value);
482 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
483 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
484 expected.float_value = 0.330;
485 ASSERT_EQ(expected.uint_value, value);
486 ASSERT_EQ(0, value);
487 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
488 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
489 expected.float_value = 0.290;
490 ASSERT_EQ(expected.uint_value, value);
491 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
492 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
493 expected.float_value = 0.600;
494 ASSERT_EQ(expected.uint_value, value);
495 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
496 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
497 expected.float_value = 0.150;
498 ASSERT_EQ(expected.uint_value, value);
499 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
500 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
501 expected.float_value = 0.060;
502 ASSERT_EQ(expected.uint_value, value);
503 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
504 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
505 expected.float_value = 0.3127;
506 ASSERT_EQ(expected.uint_value, value);
507 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
508 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
509 expected.float_value = 0.3290;
510 ASSERT_EQ(expected.uint_value, value);
511 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
512 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
513 expected.float_value = 300.0;
514 ASSERT_EQ(expected.uint_value, value);
515 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
516 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
517 expected.float_value = 0.7;
518 ASSERT_EQ(expected.uint_value, value);
519 }
520
521 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
522 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
523 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
524 expected.float_value = 300.0;
525 ASSERT_EQ(expected.uint_value, value);
526 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
527 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
528 expected.float_value = 75.0;
529 ASSERT_EQ(expected.uint_value, value);
530 }
531}
532
533TEST_F(EGLTest, EGLBT2020Linear) {
534 EGLConfig config;
535 EGLBoolean success;
536
537 if (!hasHdrDisplay) {
538 // skip this test if device does not have HDR display
539 RecordProperty("hasHdrDisplay", false);
540 return;
541 }
542
543 // Test that bt2020 linear extension exists
544 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
545 << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
546
547 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
548
549 struct DummyConsumer : public BnConsumerListener {
550 void onFrameAvailable(const BufferItem& /* item */) override {}
551 void onBuffersReleased() override {}
552 void onSidebandStreamChanged() override {}
553 };
554
555 // Create a EGLSurface
556 sp<IGraphicBufferProducer> producer;
557 sp<IGraphicBufferConsumer> consumer;
558 BufferQueue::createBufferQueue(&producer, &consumer);
559 consumer->consumerConnect(new DummyConsumer, false);
560 sp<Surface> mSTC = new Surface(producer);
561 sp<ANativeWindow> mANW = mSTC;
562
563 std::vector<EGLint> winAttrs;
564 winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
565 winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
566
567 ASSERT_NO_FATAL_FAILURE(addOptionalWindowMetadata(winAttrs));
568
569 winAttrs.push_back(EGL_NONE);
570
571 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
572 ASSERT_EQ(EGL_SUCCESS, eglGetError());
573 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
574
575 EGLint value;
576 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
577 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
578 ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
579
580 ASSERT_NO_FATAL_FAILURE(checkOptionalWindowMetadata(eglSurface));
581
582 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
583}
584
585TEST_F(EGLTest, EGLBT2020PQ) {
586 EGLConfig config;
587 EGLBoolean success;
588
589 if (!hasHdrDisplay) {
590 // skip this test if device does not have HDR display
591 RecordProperty("hasHdrDisplay", false);
592 return;
593 }
594
595 // Test that bt2020-pq extension exists
596 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
597 << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
598
599 ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
600
601 struct DummyConsumer : public BnConsumerListener {
602 void onFrameAvailable(const BufferItem& /* item */) override {}
603 void onBuffersReleased() override {}
604 void onSidebandStreamChanged() override {}
605 };
606
607 // Create a EGLSurface
608 sp<IGraphicBufferProducer> producer;
609 sp<IGraphicBufferConsumer> consumer;
610 BufferQueue::createBufferQueue(&producer, &consumer);
611 consumer->consumerConnect(new DummyConsumer, false);
612 sp<Surface> mSTC = new Surface(producer);
613 sp<ANativeWindow> mANW = mSTC;
614 std::vector<EGLint> winAttrs;
615 winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
616 winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
617
618 ASSERT_NO_FATAL_FAILURE(addOptionalWindowMetadata(winAttrs));
619
620 winAttrs.push_back(EGL_NONE);
621
622 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
623 ASSERT_EQ(EGL_SUCCESS, eglGetError());
624 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
625
626 EGLint value;
627 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
628 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
629 ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
630
631 ASSERT_NO_FATAL_FAILURE(checkOptionalWindowMetadata(eglSurface));
632
633 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
634}
635
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600636TEST_F(EGLTest, EGLConfigFP16) {
637 EGLint numConfigs;
638 EGLConfig config;
639 EGLBoolean success;
Mathias Agopian2f739f82011-07-07 14:54:30 -0700640
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600641 if (!hasWideColorDisplay) {
642 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700643 RecordProperty("hasWideColorDisplay", false);
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600644 return;
645 }
646
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600647 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600648
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700649 const EGLint attrs[] = {
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600650 // clang-format off
651 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
652 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
653 EGL_RED_SIZE, 16,
654 EGL_GREEN_SIZE, 16,
655 EGL_BLUE_SIZE, 16,
656 EGL_ALPHA_SIZE, 16,
657 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700658 EGL_NONE,
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600659 // clang-format on
660 };
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600661 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
662 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
663 ASSERT_EQ(1, numConfigs);
664
665 EGLint components[4];
666
667 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
668 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
669 ASSERT_EQ(EGL_SUCCESS, eglGetError());
670 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
671 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
672 ASSERT_EQ(EGL_SUCCESS, eglGetError());
673 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
674 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
675 ASSERT_EQ(EGL_SUCCESS, eglGetError());
676 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
677 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
678 ASSERT_EQ(EGL_SUCCESS, eglGetError());
679
680 EXPECT_GE(components[0], 16);
681 EXPECT_GE(components[1], 16);
682 EXPECT_GE(components[2], 16);
683 EXPECT_GE(components[3], 16);
684
685 struct DummyConsumer : public BnConsumerListener {
686 void onFrameAvailable(const BufferItem& /* item */) override {}
687 void onBuffersReleased() override {}
688 void onSidebandStreamChanged() override {}
689 };
690
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600691 sp<IGraphicBufferProducer> producer;
692 sp<IGraphicBufferConsumer> consumer;
693 BufferQueue::createBufferQueue(&producer, &consumer);
694 consumer->consumerConnect(new DummyConsumer, false);
695 sp<Surface> mSTC = new Surface(producer);
696 sp<ANativeWindow> mANW = mSTC;
697
698 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
699 ASSERT_EQ(EGL_SUCCESS, eglGetError());
700 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
701
702 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
703}
704
Courtney Goeltzenleuchterd99694b2017-07-10 16:30:42 -0600705TEST_F(EGLTest, EGLNoConfigContext) {
Courtney Goeltzenleuchterf7ed1b42017-04-17 17:27:47 -0600706 if (!hasWideColorDisplay) {
707 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700708 RecordProperty("hasWideColorDisplay", false);
Courtney Goeltzenleuchterf7ed1b42017-04-17 17:27:47 -0600709 return;
710 }
711
712 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
713
714 struct DummyConsumer : public BnConsumerListener {
715 void onFrameAvailable(const BufferItem& /* item */) override {}
716 void onBuffersReleased() override {}
717 void onSidebandStreamChanged() override {}
718 };
719
720 std::vector<EGLint> contextAttributes;
721 contextAttributes.reserve(4);
722 contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
723 contextAttributes.push_back(2);
724 contextAttributes.push_back(EGL_NONE);
725 contextAttributes.push_back(EGL_NONE);
726
727 EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
728 contextAttributes.data());
729 EXPECT_NE(EGL_NO_CONTEXT, eglContext);
730 EXPECT_EQ(EGL_SUCCESS, eglGetError());
731
732 if (eglContext != EGL_NO_CONTEXT) {
733 eglDestroyContext(mEglDisplay, eglContext);
734 }
735}
736
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600737// Emulate what a native application would do to create a
738// 10:10:10:2 surface.
739TEST_F(EGLTest, EGLConfig1010102) {
740 EGLint numConfigs;
741 EGLConfig config;
742 EGLBoolean success;
743
744 if (!hasWideColorDisplay) {
745 // skip this test if device does not have wide-color display
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700746 RecordProperty("hasWideColorDisplay", false);
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600747 return;
748 }
749
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700750 const EGLint attrs[] = {
Courtney Goeltzenleuchterd118ea92017-04-17 17:33:52 -0600751 // clang-format off
752 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
753 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
754 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
755 EGL_RED_SIZE, 10,
756 EGL_GREEN_SIZE, 10,
757 EGL_BLUE_SIZE, 10,
758 EGL_ALPHA_SIZE, 2,
759 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
760 EGL_NONE, EGL_NONE
761 // clang-format on
762 };
763 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
764 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
765 ASSERT_EQ(1, numConfigs);
766
767 EGLint components[4];
768 EGLint value;
769 eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
770
771 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
772 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
773 ASSERT_EQ(EGL_SUCCESS, eglGetError());
774 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
775 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
776 ASSERT_EQ(EGL_SUCCESS, eglGetError());
777 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
778 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
779 ASSERT_EQ(EGL_SUCCESS, eglGetError());
780 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
781 ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
782 ASSERT_EQ(EGL_SUCCESS, eglGetError());
783
784 EXPECT_EQ(components[0], 10);
785 EXPECT_EQ(components[1], 10);
786 EXPECT_EQ(components[2], 10);
787 EXPECT_EQ(components[3], 2);
788
789 struct DummyConsumer : public BnConsumerListener {
790 void onFrameAvailable(const BufferItem& /* item */) override {}
791 void onBuffersReleased() override {}
792 void onSidebandStreamChanged() override {}
793 };
794
Courtney Goeltzenleuchterf29f2872017-03-28 17:29:52 -0600795 // Create a EGLSurface
796 sp<IGraphicBufferProducer> producer;
797 sp<IGraphicBufferConsumer> consumer;
798 BufferQueue::createBufferQueue(&producer, &consumer);
799 consumer->consumerConnect(new DummyConsumer, false);
800 sp<Surface> mSTC = new Surface(producer);
801 sp<ANativeWindow> mANW = mSTC;
802
803 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
804 ASSERT_EQ(EGL_SUCCESS, eglGetError());
805 ASSERT_NE(EGL_NO_SURFACE, eglSurface);
806
807 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
808}
Mathias Agopian2f739f82011-07-07 14:54:30 -0700809}