1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 19 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> 20 21 #include <configstore/Utils.h> 22 #include <utils/String8.h> 23 24 #include <EGL/egl.h> 25 #include <gui/Surface.h> 26 #include <gui/IConsumerListener.h> 27 #include <gui/IProducerListener.h> 28 #include <gui/IGraphicBufferConsumer.h> 29 #include <gui/BufferQueue.h> 30 31 bool hasEglExtension(EGLDisplay dpy, const char* extensionName) { 32 const char* exts = eglQueryString(dpy, EGL_EXTENSIONS); 33 size_t cropExtLen = strlen(extensionName); 34 size_t extsLen = strlen(exts); 35 bool equal = !strcmp(extensionName, exts); 36 android::String8 extString(extensionName); 37 android::String8 space(" "); 38 bool atStart = !strncmp(extString + space, exts, cropExtLen + 1); 39 bool atEnd = (cropExtLen + 1) < extsLen && 40 !strcmp(space + extString, exts + extsLen - (cropExtLen + 1)); 41 bool inMiddle = strstr(exts, space + extString + space); 42 return equal || atStart || atEnd || inMiddle; 43 } 44 45 namespace android { 46 47 #define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE) 48 49 // retrieve wide-color setting from configstore 50 using namespace android::hardware::configstore; 51 using namespace android::hardware::configstore::V1_0; 52 53 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT)) 54 55 static bool hasWideColorDisplay = 56 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false); 57 58 static bool hasHdrDisplay = 59 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false); 60 61 class EGLTest : public ::testing::Test { 62 public: 63 void get8BitConfig(EGLConfig& config); 64 void setSurfaceSmpteMetadata(EGLSurface surface); 65 void checkSurfaceSmpteMetadata(EGLSurface eglSurface); 66 67 protected: 68 EGLDisplay mEglDisplay; 69 70 protected: 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); 90 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 91 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 92 } 93 }; 94 95 TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) { 96 97 EGLint numConfigs; 98 EGLConfig config; 99 EGLBoolean success; 100 EGLint attrs[] = { 101 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 102 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 103 EGL_NONE 104 }; 105 106 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); 107 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 108 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 109 ASSERT_GE(numConfigs, 1); 110 111 EGLint components[3]; 112 113 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); 114 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 115 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 116 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); 117 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 118 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 119 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); 120 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 121 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 122 123 EXPECT_GE(components[0], 8); 124 EXPECT_GE(components[1], 8); 125 EXPECT_GE(components[2], 8); 126 } 127 128 TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { 129 EGLint numConfigs; 130 EGLConfig config; 131 EGLint attrs[] = { 132 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 133 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 134 EGL_RED_SIZE, 8, 135 EGL_GREEN_SIZE, 8, 136 EGL_BLUE_SIZE, 8, 137 EGL_ALPHA_SIZE, 8, 138 EGL_NONE 139 }; 140 EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs)); 141 142 struct DummyConsumer : public BnConsumerListener { 143 void onFrameAvailable(const BufferItem& /* item */) override {} 144 void onBuffersReleased() override {} 145 void onSidebandStreamChanged() override {} 146 }; 147 148 // Create a EGLSurface 149 sp<IGraphicBufferProducer> producer; 150 sp<IGraphicBufferConsumer> consumer; 151 BufferQueue::createBufferQueue(&producer, &consumer); 152 consumer->consumerConnect(new DummyConsumer, false); 153 sp<Surface> mSTC = new Surface(producer); 154 sp<ANativeWindow> mANW = mSTC; 155 156 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, 157 mANW.get(), NULL); 158 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 159 ASSERT_NE(EGL_NO_SURFACE, eglSurface) ; 160 161 // do not destroy eglSurface 162 // eglTerminate is called in the tear down and should destroy it for us 163 } 164 165 TEST_F(EGLTest, EGLConfigRGBA8888First) { 166 167 EGLint numConfigs; 168 EGLConfig config; 169 EGLBoolean success; 170 EGLint attrs[] = { 171 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 172 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 173 EGL_RED_SIZE, 8, 174 EGL_GREEN_SIZE, 8, 175 EGL_BLUE_SIZE, 8, 176 EGL_ALPHA_SIZE, 8, 177 EGL_NONE 178 }; 179 180 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); 181 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 182 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 183 ASSERT_GE(numConfigs, 1); 184 185 EGLint components[4]; 186 187 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); 188 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 189 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 190 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); 191 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 192 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 193 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); 194 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 195 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 196 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]); 197 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 198 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 199 200 EXPECT_GE(components[0], 8); 201 EXPECT_GE(components[1], 8); 202 EXPECT_GE(components[2], 8); 203 EXPECT_GE(components[3], 8); 204 } 205 206 TEST_F(EGLTest, EGLDisplayP3) { 207 EGLint numConfigs; 208 EGLConfig config; 209 EGLBoolean success; 210 211 if (!hasWideColorDisplay) { 212 // skip this test if device does not have wide-color display 213 std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl; 214 return; 215 } 216 217 // Test that display-p3 extensions exist 218 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3")); 219 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear")); 220 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough")); 221 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 293 TEST_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 346 TEST_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 353 std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl; 354 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")); 360 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough")); 361 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 433 void 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 479 void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) { 480 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) { 481 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)); 501 } 502 503 if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) { 504 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)); 508 } 509 } 510 511 void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) { 512 EGLBoolean success; 513 EGLint value; 514 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); 518 ASSERT_EQ(METADATA_SCALE(0.640), value); 519 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value); 520 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 521 ASSERT_EQ(METADATA_SCALE(0.330), value); 522 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value); 523 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 524 ASSERT_EQ(METADATA_SCALE(0.290), value); 525 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value); 526 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 527 ASSERT_EQ(METADATA_SCALE(0.600), value); 528 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value); 529 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 530 ASSERT_EQ(METADATA_SCALE(0.150), value); 531 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value); 532 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 533 ASSERT_EQ(METADATA_SCALE(0.060), value); 534 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value); 535 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 536 ASSERT_EQ(METADATA_SCALE(0.3127), value); 537 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value); 538 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 539 ASSERT_EQ(METADATA_SCALE(0.3290), value); 540 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value); 541 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 542 ASSERT_EQ(METADATA_SCALE(300.0), value); 543 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value); 544 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 545 ASSERT_EQ(METADATA_SCALE(0.7), value); 546 } 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); 551 ASSERT_EQ(METADATA_SCALE(300.0), value); 552 success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value); 553 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 554 ASSERT_EQ(METADATA_SCALE(75.0), value); 555 } 556 } 557 558 TEST_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 592 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 603 ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface)); 604 605 ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface)); 606 607 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface)); 608 } 609 610 TEST_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); 642 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 653 ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface)); 654 655 ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface)); 656 657 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface)); 658 } 659 660 TEST_F(EGLTest, EGLConfigFP16) { 661 EGLint numConfigs; 662 EGLConfig config; 663 EGLBoolean success; 664 665 if (!hasWideColorDisplay) { 666 // skip this test if device does not have wide-color display 667 RecordProperty("hasWideColorDisplay", false); 668 return; 669 } 670 671 ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float")); 672 673 const EGLint attrs[] = { 674 // 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, 682 EGL_NONE, 683 // clang-format on 684 }; 685 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 715 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 729 TEST_F(EGLTest, EGLNoConfigContext) { 730 if (!hasWideColorDisplay) { 731 // skip this test if device does not have wide-color display 732 RecordProperty("hasWideColorDisplay", false); 733 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 761 // Emulate what a native application would do to create a 762 // 10:10:10:2 surface. 763 TEST_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 770 RecordProperty("hasWideColorDisplay", false); 771 return; 772 } 773 774 const EGLint attrs[] = { 775 // 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 819 // 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 } 833 834 TEST_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 865 TEST_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 912 TEST_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 952 TEST_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 } 998 } 999