Home | History | Annotate | Download | only in EGLTest
      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