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 
    221     // Use 8-bit to keep forcus on Display-P3 aspect
    222     EGLint attrs[] = {
    223             // clang-format off
    224             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
    225             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
    226             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
    227             EGL_RED_SIZE,                 8,
    228             EGL_GREEN_SIZE,               8,
    229             EGL_BLUE_SIZE,                8,
    230             EGL_ALPHA_SIZE,               8,
    231             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
    232             EGL_NONE,                     EGL_NONE
    233             // clang-format on
    234     };
    235     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
    236     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    237     ASSERT_EQ(1, numConfigs);
    238 
    239     EGLint components[4];
    240     EGLint value;
    241     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
    242 
    243     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
    244     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    245     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    246     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
    247     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    248     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    249     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
    250     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    251     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    252     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
    253     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    254     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    255 
    256     EXPECT_EQ(components[0], 8);
    257     EXPECT_EQ(components[1], 8);
    258     EXPECT_EQ(components[2], 8);
    259     EXPECT_EQ(components[3], 8);
    260 
    261     struct DummyConsumer : public BnConsumerListener {
    262         void onFrameAvailable(const BufferItem& /* item */) override {}
    263         void onBuffersReleased() override {}
    264         void onSidebandStreamChanged() override {}
    265     };
    266 
    267     // Create a EGLSurface
    268     sp<IGraphicBufferProducer> producer;
    269     sp<IGraphicBufferConsumer> consumer;
    270     BufferQueue::createBufferQueue(&producer, &consumer);
    271     consumer->consumerConnect(new DummyConsumer, false);
    272     sp<Surface> mSTC = new Surface(producer);
    273     sp<ANativeWindow> mANW = mSTC;
    274     EGLint winAttrs[] = {
    275             // clang-format off
    276             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
    277             EGL_NONE,              EGL_NONE
    278             // clang-format on
    279     };
    280 
    281     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
    282     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    283     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
    284 
    285     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
    286     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    287     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
    288 
    289     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
    290 }
    291 
    292 TEST_F(EGLTest, EGLDisplayP31010102) {
    293     EGLint numConfigs;
    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 
    307     // Use 8-bit to keep forcus on Display-P3 aspect
    308     EGLint attrs[] = {
    309             // clang-format off
    310             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
    311             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
    312             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
    313             EGL_RED_SIZE,                 10,
    314             EGL_GREEN_SIZE,               10,
    315             EGL_BLUE_SIZE,                10,
    316             EGL_ALPHA_SIZE,               2,
    317             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
    318             EGL_NONE,                     EGL_NONE
    319             // clang-format on
    320     };
    321     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
    322     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    323     ASSERT_EQ(1, numConfigs);
    324 
    325     EGLint components[4];
    326     EGLint value;
    327     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
    328 
    329     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
    330     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    331     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    332     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
    333     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    334     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    335     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
    336     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    337     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    338     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
    339     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    340     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    341 
    342     EXPECT_EQ(components[0], 10);
    343     EXPECT_EQ(components[1], 10);
    344     EXPECT_EQ(components[2], 10);
    345     EXPECT_EQ(components[3], 2);
    346 
    347     struct DummyConsumer : public BnConsumerListener {
    348         void onFrameAvailable(const BufferItem& /* item */) override {}
    349         void onBuffersReleased() override {}
    350         void onSidebandStreamChanged() override {}
    351     };
    352 
    353     // Create a EGLSurface
    354     sp<IGraphicBufferProducer> producer;
    355     sp<IGraphicBufferConsumer> consumer;
    356     BufferQueue::createBufferQueue(&producer, &consumer);
    357     consumer->consumerConnect(new DummyConsumer, false);
    358     sp<Surface> mSTC = new Surface(producer);
    359     sp<ANativeWindow> mANW = mSTC;
    360     EGLint winAttrs[] = {
    361             // clang-format off
    362             EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
    363             EGL_NONE,              EGL_NONE
    364             // clang-format on
    365     };
    366 
    367     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
    368     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    369     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
    370 
    371     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
    372     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    373     ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
    374 
    375     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
    376 }
    377 
    378 void EGLTest::get8BitConfig(EGLConfig& config) {
    379     EGLint numConfigs;
    380     EGLBoolean success;
    381 
    382     // Use 8-bit to keep focus on colorspace aspect
    383     const EGLint attrs[] = {
    384             // clang-format off
    385             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
    386             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
    387             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
    388             EGL_RED_SIZE,                 8,
    389             EGL_GREEN_SIZE,               8,
    390             EGL_BLUE_SIZE,                8,
    391             EGL_ALPHA_SIZE,               8,
    392             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
    393             EGL_NONE,
    394             // clang-format on
    395     };
    396     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
    397     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    398     ASSERT_EQ(1, numConfigs);
    399 
    400     EGLint components[4];
    401     EGLint value;
    402     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
    403 
    404     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
    405     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    406     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    407     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
    408     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    409     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    410     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
    411     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    412     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    413     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
    414     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    415     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    416 
    417     // Verify component sizes on config match what was asked for.
    418     EXPECT_EQ(components[0], 8);
    419     EXPECT_EQ(components[1], 8);
    420     EXPECT_EQ(components[2], 8);
    421     EXPECT_EQ(components[3], 8);
    422 }
    423 
    424 void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
    425     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
    426         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
    427                          METADATA_SCALE(0.640));
    428         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
    429                          METADATA_SCALE(0.330));
    430         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
    431                          METADATA_SCALE(0.290));
    432         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
    433                          METADATA_SCALE(0.600));
    434         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
    435                          METADATA_SCALE(0.150));
    436         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
    437                          METADATA_SCALE(0.060));
    438         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
    439                          METADATA_SCALE(0.3127));
    440         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
    441                          METADATA_SCALE(0.3290));
    442         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
    443                          METADATA_SCALE(300));
    444         eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
    445                          METADATA_SCALE(0.7));
    446     }
    447 
    448     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
    449         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
    450                          METADATA_SCALE(300));
    451         eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
    452                          METADATA_SCALE(75));
    453     }
    454 }
    455 
    456 void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
    457     EGLBoolean success;
    458     EGLint value;
    459 
    460     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
    461         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
    462         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    463         ASSERT_EQ(METADATA_SCALE(0.640), value);
    464         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
    465         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    466         ASSERT_EQ(METADATA_SCALE(0.330), value);
    467         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
    468         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    469         ASSERT_EQ(METADATA_SCALE(0.290), value);
    470         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
    471         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    472         ASSERT_EQ(METADATA_SCALE(0.600), value);
    473         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
    474         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    475         ASSERT_EQ(METADATA_SCALE(0.150), value);
    476         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
    477         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    478         ASSERT_EQ(METADATA_SCALE(0.060), value);
    479         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
    480         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    481         ASSERT_EQ(METADATA_SCALE(0.3127), value);
    482         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
    483         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    484         ASSERT_EQ(METADATA_SCALE(0.3290), value);
    485         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
    486         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    487         ASSERT_EQ(METADATA_SCALE(300.0), value);
    488         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
    489         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    490         ASSERT_EQ(METADATA_SCALE(0.7), value);
    491     }
    492 
    493     if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
    494         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
    495         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    496         ASSERT_EQ(METADATA_SCALE(300.0), value);
    497         success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
    498         ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    499         ASSERT_EQ(METADATA_SCALE(75.0), value);
    500     }
    501 }
    502 
    503 TEST_F(EGLTest, EGLBT2020Linear) {
    504     EGLConfig config;
    505     EGLBoolean success;
    506 
    507     if (!hasHdrDisplay) {
    508         // skip this test if device does not have HDR display
    509         RecordProperty("hasHdrDisplay", false);
    510         return;
    511     }
    512 
    513     // Test that bt2020 linear extension exists
    514     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
    515             << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
    516 
    517     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
    518 
    519     struct DummyConsumer : public BnConsumerListener {
    520         void onFrameAvailable(const BufferItem& /* item */) override {}
    521         void onBuffersReleased() override {}
    522         void onSidebandStreamChanged() override {}
    523     };
    524 
    525     // Create a EGLSurface
    526     sp<IGraphicBufferProducer> producer;
    527     sp<IGraphicBufferConsumer> consumer;
    528     BufferQueue::createBufferQueue(&producer, &consumer);
    529     consumer->consumerConnect(new DummyConsumer, false);
    530     sp<Surface> mSTC = new Surface(producer);
    531     sp<ANativeWindow> mANW = mSTC;
    532 
    533     std::vector<EGLint> winAttrs;
    534     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
    535     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
    536 
    537     winAttrs.push_back(EGL_NONE);
    538 
    539     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
    540     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    541     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
    542 
    543     EGLint value;
    544     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
    545     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    546     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
    547 
    548     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
    549 
    550     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
    551 
    552     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
    553 }
    554 
    555 TEST_F(EGLTest, EGLBT2020PQ) {
    556     EGLConfig config;
    557     EGLBoolean success;
    558 
    559     if (!hasHdrDisplay) {
    560         // skip this test if device does not have HDR display
    561         RecordProperty("hasHdrDisplay", false);
    562         return;
    563     }
    564 
    565     // Test that bt2020-pq extension exists
    566     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
    567             << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
    568 
    569     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
    570 
    571     struct DummyConsumer : public BnConsumerListener {
    572         void onFrameAvailable(const BufferItem& /* item */) override {}
    573         void onBuffersReleased() override {}
    574         void onSidebandStreamChanged() override {}
    575     };
    576 
    577     // Create a EGLSurface
    578     sp<IGraphicBufferProducer> producer;
    579     sp<IGraphicBufferConsumer> consumer;
    580     BufferQueue::createBufferQueue(&producer, &consumer);
    581     consumer->consumerConnect(new DummyConsumer, false);
    582     sp<Surface> mSTC = new Surface(producer);
    583     sp<ANativeWindow> mANW = mSTC;
    584     std::vector<EGLint> winAttrs;
    585     winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
    586     winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
    587     winAttrs.push_back(EGL_NONE);
    588 
    589     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
    590     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    591     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
    592 
    593     EGLint value;
    594     success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
    595     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    596     ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
    597 
    598     ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
    599 
    600     ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
    601 
    602     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
    603 }
    604 
    605 TEST_F(EGLTest, EGLConfigFP16) {
    606     EGLint numConfigs;
    607     EGLConfig config;
    608     EGLBoolean success;
    609 
    610     if (!hasWideColorDisplay) {
    611         // skip this test if device does not have wide-color display
    612         RecordProperty("hasWideColorDisplay", false);
    613         return;
    614     }
    615 
    616     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
    617 
    618     const EGLint attrs[] = {
    619             // clang-format off
    620             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
    621             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
    622             EGL_RED_SIZE,                 16,
    623             EGL_GREEN_SIZE,               16,
    624             EGL_BLUE_SIZE,                16,
    625             EGL_ALPHA_SIZE,               16,
    626             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
    627             EGL_NONE,
    628             // clang-format on
    629     };
    630     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
    631     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    632     ASSERT_EQ(1, numConfigs);
    633 
    634     EGLint components[4];
    635 
    636     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
    637     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    638     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    639     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
    640     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    641     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    642     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
    643     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    644     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    645     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
    646     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    647     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    648 
    649     EXPECT_GE(components[0], 16);
    650     EXPECT_GE(components[1], 16);
    651     EXPECT_GE(components[2], 16);
    652     EXPECT_GE(components[3], 16);
    653 
    654     struct DummyConsumer : public BnConsumerListener {
    655         void onFrameAvailable(const BufferItem& /* item */) override {}
    656         void onBuffersReleased() override {}
    657         void onSidebandStreamChanged() override {}
    658     };
    659 
    660     sp<IGraphicBufferProducer> producer;
    661     sp<IGraphicBufferConsumer> consumer;
    662     BufferQueue::createBufferQueue(&producer, &consumer);
    663     consumer->consumerConnect(new DummyConsumer, false);
    664     sp<Surface> mSTC = new Surface(producer);
    665     sp<ANativeWindow> mANW = mSTC;
    666 
    667     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
    668     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    669     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
    670 
    671     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
    672 }
    673 
    674 TEST_F(EGLTest, EGLNoConfigContext) {
    675     if (!hasWideColorDisplay) {
    676         // skip this test if device does not have wide-color display
    677         RecordProperty("hasWideColorDisplay", false);
    678         return;
    679     }
    680 
    681     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
    682 
    683     struct DummyConsumer : public BnConsumerListener {
    684         void onFrameAvailable(const BufferItem& /* item */) override {}
    685         void onBuffersReleased() override {}
    686         void onSidebandStreamChanged() override {}
    687     };
    688 
    689     std::vector<EGLint> contextAttributes;
    690     contextAttributes.reserve(4);
    691     contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
    692     contextAttributes.push_back(2);
    693     contextAttributes.push_back(EGL_NONE);
    694     contextAttributes.push_back(EGL_NONE);
    695 
    696     EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
    697                                              contextAttributes.data());
    698     EXPECT_NE(EGL_NO_CONTEXT, eglContext);
    699     EXPECT_EQ(EGL_SUCCESS, eglGetError());
    700 
    701     if (eglContext != EGL_NO_CONTEXT) {
    702         eglDestroyContext(mEglDisplay, eglContext);
    703     }
    704 }
    705 
    706 // Emulate what a native application would do to create a
    707 // 10:10:10:2 surface.
    708 TEST_F(EGLTest, EGLConfig1010102) {
    709     EGLint numConfigs;
    710     EGLConfig config;
    711     EGLBoolean success;
    712 
    713     if (!hasWideColorDisplay) {
    714         // skip this test if device does not have wide-color display
    715         RecordProperty("hasWideColorDisplay", false);
    716         return;
    717     }
    718 
    719     const EGLint attrs[] = {
    720             // clang-format off
    721             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT,
    722             EGL_RENDERABLE_TYPE,          EGL_OPENGL_ES2_BIT,
    723             EGL_SURFACE_TYPE,             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
    724             EGL_RED_SIZE,                 10,
    725             EGL_GREEN_SIZE,               10,
    726             EGL_BLUE_SIZE,                10,
    727             EGL_ALPHA_SIZE,               2,
    728             EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
    729             EGL_NONE,                     EGL_NONE
    730             // clang-format on
    731     };
    732     success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
    733     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    734     ASSERT_EQ(1, numConfigs);
    735 
    736     EGLint components[4];
    737     EGLint value;
    738     eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
    739 
    740     success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
    741     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    742     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    743     success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
    744     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    745     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    746     success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
    747     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    748     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    749     success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
    750     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
    751     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    752 
    753     EXPECT_EQ(components[0], 10);
    754     EXPECT_EQ(components[1], 10);
    755     EXPECT_EQ(components[2], 10);
    756     EXPECT_EQ(components[3], 2);
    757 
    758     struct DummyConsumer : public BnConsumerListener {
    759         void onFrameAvailable(const BufferItem& /* item */) override {}
    760         void onBuffersReleased() override {}
    761         void onSidebandStreamChanged() override {}
    762     };
    763 
    764     // Create a EGLSurface
    765     sp<IGraphicBufferProducer> producer;
    766     sp<IGraphicBufferConsumer> consumer;
    767     BufferQueue::createBufferQueue(&producer, &consumer);
    768     consumer->consumerConnect(new DummyConsumer, false);
    769     sp<Surface> mSTC = new Surface(producer);
    770     sp<ANativeWindow> mANW = mSTC;
    771 
    772     EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
    773     ASSERT_EQ(EGL_SUCCESS, eglGetError());
    774     ASSERT_NE(EGL_NO_SURFACE, eglSurface);
    775 
    776     EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
    777 }
    778 }
    779