Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 786ab884 authored by Courtney Goeltzenleuchter's avatar Courtney Goeltzenleuchter
Browse files

Add hdr attributes to setSurfaceAttr

Keep original copies of hdr metadata to return to the user if requested.
Scale integer values prior to sending to system.

Test: --deqp-case=dEQP-EGL.functional.hdr_color.*
Bug: 72491459, 72828483

Change-Id: I86ed35cf96d740ac230cc10acde322acbeffe847
parent ad87a690
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -712,7 +712,8 @@ EGLBoolean setSurfaceMetadata(egl_surface_t* s, NativeWindowType window,
        cta8613 |= s->setCta8613Attribute(attr[0], attr[1]);
    }
    if (smpte2086) {
        int err = native_window_set_buffers_smpte2086_metadata(window, s->getSmpte2086Metadata());
        android_smpte2086_metadata metadata = s->getSmpte2086Metadata();
        int err = native_window_set_buffers_smpte2086_metadata(window, &metadata);
        if (err != 0) {
            ALOGE("error setting native window smpte2086 metadata: %s (%d)",
                  strerror(-err), err);
@@ -721,7 +722,8 @@ EGLBoolean setSurfaceMetadata(egl_surface_t* s, NativeWindowType window,
        }
    }
    if (cta8613) {
        int err = native_window_set_buffers_cta861_3_metadata(window, s->getCta8613Metadata());
        android_cta861_3_metadata metadata = s->getCta8613Metadata();
        int err = native_window_set_buffers_cta861_3_metadata(window, &metadata);
        if (err != 0) {
            ALOGE("error setting native window CTS 861.3 metadata: %s (%d)",
                  strerror(-err), err);
@@ -1578,7 +1580,11 @@ EGLBoolean eglSurfaceAttrib(
        return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
    }

    if (s->cnx->egl.eglSurfaceAttrib) {
    if (s->setSmpte2086Attribute(attribute, value)) {
        return EGL_TRUE;
    } else if (s->setCta8613Attribute(attribute, value)) {
        return EGL_TRUE;
    } else if (s->cnx->egl.eglSurfaceAttrib) {
        return s->cnx->egl.eglSurfaceAttrib(
                dp->disp.dpy, s->surface, attribute, value);
    }
+50 −27
Original line number Diff line number Diff line
@@ -64,8 +64,8 @@ egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWind
        cnx(cnx),
        connected(true),
        colorSpace(colorSpace),
        smpte2086_metadata({}),
        cta861_3_metadata({}) {
        egl_smpte2086_metadata({}),
        egl_cta861_3_metadata({}) {
    if (win) {
        win->incStrong(this);
    }
@@ -90,36 +90,35 @@ void egl_surface_t::disconnect() {

EGLBoolean egl_surface_t::setSmpte2086Attribute(EGLint attribute, EGLint value) {
    switch (attribute) {
            break;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
            smpte2086_metadata.displayPrimaryRed.x = value;
            egl_smpte2086_metadata.displayPrimaryRed.x = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
            smpte2086_metadata.displayPrimaryRed.y = value;
            egl_smpte2086_metadata.displayPrimaryRed.y = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
            smpte2086_metadata.displayPrimaryGreen.x = value;
            egl_smpte2086_metadata.displayPrimaryGreen.x = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
            smpte2086_metadata.displayPrimaryGreen.y = value;
            egl_smpte2086_metadata.displayPrimaryGreen.y = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
            smpte2086_metadata.displayPrimaryBlue.x = value;
            egl_smpte2086_metadata.displayPrimaryBlue.x = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
            smpte2086_metadata.displayPrimaryBlue.y = value;
            egl_smpte2086_metadata.displayPrimaryBlue.y = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_WHITE_POINT_X_EXT:
            smpte2086_metadata.whitePoint.x = value;
            egl_smpte2086_metadata.whitePoint.x = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
            smpte2086_metadata.whitePoint.y = value;
            egl_smpte2086_metadata.whitePoint.y = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
            smpte2086_metadata.maxLuminance = value;
            egl_smpte2086_metadata.maxLuminance = value;
            return EGL_TRUE;
        case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
            smpte2086_metadata.minLuminance = value;
            egl_smpte2086_metadata.minLuminance = value;
            return EGL_TRUE;
    }
    return EGL_FALSE;
@@ -128,15 +127,39 @@ EGLBoolean egl_surface_t::setSmpte2086Attribute(EGLint attribute, EGLint value)
EGLBoolean egl_surface_t::setCta8613Attribute(EGLint attribute, EGLint value) {
    switch (attribute) {
        case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
            cta861_3_metadata.maxContentLightLevel = value;
            egl_cta861_3_metadata.maxContentLightLevel = value;
            return EGL_TRUE;
        case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
            cta861_3_metadata.maxFrameAverageLightLevel = value;
            egl_cta861_3_metadata.maxFrameAverageLightLevel = value;
            return EGL_TRUE;
    }
    return EGL_FALSE;
}

const android_smpte2086_metadata egl_surface_t::getSmpte2086Metadata() {
    android_smpte2086_metadata metadata;
    metadata.displayPrimaryRed.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.x) / EGL_METADATA_SCALING_EXT;
    metadata.displayPrimaryRed.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.y) / EGL_METADATA_SCALING_EXT;
    metadata.displayPrimaryGreen.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.x) / EGL_METADATA_SCALING_EXT;
    metadata.displayPrimaryGreen.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.y) / EGL_METADATA_SCALING_EXT;
    metadata.displayPrimaryBlue.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.x) / EGL_METADATA_SCALING_EXT;
    metadata.displayPrimaryBlue.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.y) / EGL_METADATA_SCALING_EXT;
    metadata.whitePoint.x = static_cast<float>(egl_smpte2086_metadata.whitePoint.x) / EGL_METADATA_SCALING_EXT;
    metadata.whitePoint.y = static_cast<float>(egl_smpte2086_metadata.whitePoint.y) / EGL_METADATA_SCALING_EXT;
    metadata.maxLuminance = static_cast<float>(egl_smpte2086_metadata.maxLuminance) / EGL_METADATA_SCALING_EXT;
    metadata.minLuminance = static_cast<float>(egl_smpte2086_metadata.minLuminance) / EGL_METADATA_SCALING_EXT;

    return metadata;
}

const android_cta861_3_metadata egl_surface_t::getCta8613Metadata() {
    android_cta861_3_metadata metadata;
    metadata.maxContentLightLevel = static_cast<float>(egl_cta861_3_metadata.maxContentLightLevel) / EGL_METADATA_SCALING_EXT;
    metadata.maxFrameAverageLightLevel = static_cast<float>(egl_cta861_3_metadata.maxFrameAverageLightLevel) / EGL_METADATA_SCALING_EXT;
    return metadata;
}


EGLBoolean egl_surface_t::getColorSpaceAttribute(EGLint attribute, EGLint* value) const {
    if (attribute == EGL_GL_COLORSPACE_KHR) {
        *value = colorSpace;
@@ -148,43 +171,43 @@ EGLBoolean egl_surface_t::getColorSpaceAttribute(EGLint attribute, EGLint* value
EGLBoolean egl_surface_t::getSmpte2086Attribute(EGLint attribute, EGLint *value) const {
    switch (attribute) {
        case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryRed.x);
            *value = egl_smpte2086_metadata.displayPrimaryRed.x;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryRed.y);
            *value = egl_smpte2086_metadata.displayPrimaryRed.y;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryGreen.x);
            *value = egl_smpte2086_metadata.displayPrimaryGreen.x;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryGreen.y);
            *value = egl_smpte2086_metadata.displayPrimaryGreen.y;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryBlue.x);
            *value = egl_smpte2086_metadata.displayPrimaryBlue.x;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.displayPrimaryBlue.y);
            *value = egl_smpte2086_metadata.displayPrimaryBlue.y;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_WHITE_POINT_X_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.whitePoint.x);
            *value = egl_smpte2086_metadata.whitePoint.x;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.whitePoint.y);
            *value = egl_smpte2086_metadata.whitePoint.y;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.maxLuminance);
            *value = egl_smpte2086_metadata.maxLuminance;
            return EGL_TRUE;
            break;
        case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
            *value = *reinterpret_cast<const int*>(&smpte2086_metadata.minLuminance);
            *value = egl_smpte2086_metadata.minLuminance;
            return EGL_TRUE;
            break;
    }
@@ -194,11 +217,11 @@ EGLBoolean egl_surface_t::getSmpte2086Attribute(EGLint attribute, EGLint *value)
EGLBoolean egl_surface_t::getCta8613Attribute(EGLint attribute, EGLint *value) const {
    switch (attribute) {
        case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
            *value = *reinterpret_cast<const int*>(&cta861_3_metadata.maxContentLightLevel);
            *value = egl_cta861_3_metadata.maxContentLightLevel;
            return EGL_TRUE;
            break;
        case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
            *value = *reinterpret_cast<const int*>(&cta861_3_metadata.maxFrameAverageLightLevel);
            *value = egl_cta861_3_metadata.maxFrameAverageLightLevel;
            return EGL_TRUE;
            break;
    }
+23 −4
Original line number Diff line number Diff line
@@ -142,8 +142,8 @@ public:
    EGLBoolean getColorSpaceAttribute(EGLint attribute, EGLint* value) const;
    EGLBoolean getSmpte2086Attribute(EGLint attribute, EGLint* value) const;
    EGLBoolean getCta8613Attribute(EGLint attribute, EGLint* value) const;
    const android_smpte2086_metadata* getSmpte2086Metadata() const { return &smpte2086_metadata; }
    const android_cta861_3_metadata* getCta8613Metadata() const { return &cta861_3_metadata; }
    const android_smpte2086_metadata getSmpte2086Metadata();
    const android_cta861_3_metadata getCta8613Metadata();

    // Try to keep the order of these fields and size unchanged. It's not public API, but
    // it's not hard to imagine native games accessing them.
@@ -157,8 +157,27 @@ private:
    bool connected;
    void disconnect();
    EGLint colorSpace;
    android_smpte2086_metadata smpte2086_metadata;
    android_cta861_3_metadata cta861_3_metadata;

    struct egl_xy_color {
        EGLint x;
        EGLint y;
    };

    struct egl_smpte2086_metadata {
        struct egl_xy_color displayPrimaryRed;
        struct egl_xy_color displayPrimaryGreen;
        struct egl_xy_color displayPrimaryBlue;
        struct egl_xy_color whitePoint;
        EGLint maxLuminance;
        EGLint minLuminance;
    };

    struct egl_cta861_3_metadata {
        EGLint maxContentLightLevel;
        EGLint maxFrameAverageLightLevel;
    };
    egl_smpte2086_metadata egl_smpte2086_metadata;
    egl_cta861_3_metadata egl_cta861_3_metadata;
};

class egl_context_t: public egl_object_t {
+26 −56
Original line number Diff line number Diff line
@@ -50,17 +50,14 @@ namespace android {
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;

#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))

static bool hasWideColorDisplay =
        getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);

static bool hasHdrDisplay =
        getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);

union FlexAttribute {
    EGLint uint_value;
    float float_value;
};

class EGLTest : public ::testing::Test {
public:
    void get8BitConfig(EGLConfig& config);
@@ -425,108 +422,81 @@ void EGLTest::get8BitConfig(EGLConfig& config) {
}

void EGLTest::addOptionalWindowMetadata(std::vector<EGLint>& attrs) {
    FlexAttribute data;
    if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
        attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT);
        data.float_value = 0.640;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.640));
        attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT);
        data.float_value = 0.330;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.330));
        attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT);
        data.float_value = 0.290;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.290));
        attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT);
        data.float_value = 0.600;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.600));
        attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT);
        data.float_value = 0.150;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.150));
        attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT);
        data.float_value = 0.060;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.060));
        attrs.push_back(EGL_SMPTE2086_WHITE_POINT_X_EXT);
        data.float_value = 0.3127;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.3127));
        attrs.push_back(EGL_SMPTE2086_WHITE_POINT_Y_EXT);
        data.float_value = 0.3290;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.3290));
        attrs.push_back(EGL_SMPTE2086_MAX_LUMINANCE_EXT);
        data.float_value = 300.0;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(300));
        attrs.push_back(EGL_SMPTE2086_MIN_LUMINANCE_EXT);
        data.float_value = 0.7;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(0.7));
    }

    if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
        attrs.push_back(EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT);
        data.float_value = 300.0;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(300));
        attrs.push_back(EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT);
        data.float_value = 75.0;
        attrs.push_back(data.uint_value);
        attrs.push_back(METADATA_SCALE(75));
    }
}

void EGLTest::checkOptionalWindowMetadata(EGLSurface eglSurface) {
    EGLBoolean success;
    EGLint value;
    FlexAttribute expected;

    if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.640;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.640), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.330;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(0, value);
        ASSERT_EQ(METADATA_SCALE(0.330), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.290;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.290), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.600;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.600), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.150;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.150), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.060;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.060), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.3127;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.3127), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.3290;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.3290), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 300.0;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(300.0), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 0.7;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(0.7), value);
    }

    if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 300.0;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(300.0), value);
        success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
        ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
        expected.float_value = 75.0;
        ASSERT_EQ(expected.uint_value, value);
        ASSERT_EQ(METADATA_SCALE(75.0), value);
    }
}