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

Commit f2fc4e97 authored by Krzysztof Kosiński's avatar Krzysztof Kosiński
Browse files

Refactor color space attribute processing.

getColorSpaceAttribute and stripAttributes have closely related purpose.
Merge them into a single processAttribute function.

This also adjusts which color space attributes are passed to the driver,
based on the EGL extension specifications.

Bug: 78247539
Test: cts-tradefed run singleCommand cts-dev -m CtsDeqpTestCases \
--module-arg CtsDeqpTestCases:include-filter:dEQP-EGL.functional.* \
--skip-preconditions

Change-Id: I79650e0066e54ae92033b280d75f17b4060114bd
parent d893c333
Loading
Loading
Loading
Loading
+158 −228
Original line number Original line Diff line number Diff line
@@ -80,6 +80,7 @@ extern char const * const gBuiltinExtensionString;
extern char const * const gExtensionString;
extern char const * const gExtensionString;


// clang-format off
// clang-format off
// Extensions implemented by the EGL wrapper.
char const * const gBuiltinExtensionString =
char const * const gBuiltinExtensionString =
        "EGL_KHR_get_all_proc_addresses "
        "EGL_KHR_get_all_proc_addresses "
        "EGL_ANDROID_presentation_time "
        "EGL_ANDROID_presentation_time "
@@ -91,6 +92,7 @@ char const * const gBuiltinExtensionString =
        "EGL_EXT_surface_CTA861_3_metadata "
        "EGL_EXT_surface_CTA861_3_metadata "
        ;
        ;


// Whitelist of extensions exposed to applications if implemented in the vendor driver.
char const * const gExtensionString  =
char const * const gExtensionString  =
        "EGL_KHR_image "                        // mandatory
        "EGL_KHR_image "                        // mandatory
        "EGL_KHR_image_base "                   // mandatory
        "EGL_KHR_image_base "                   // mandatory
@@ -451,12 +453,8 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
// surfaces
// surfaces
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


// Turn linear formats into corresponding sRGB formats when colorspace is
// Translates EGL color spaces to Android data spaces.
// EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
static android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace) {
// formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
// the modification isn't possible, the original dataSpace is returned.
static android_dataspace modifyBufferDataspace(android_dataspace dataSpace,
                                               EGLint colorspace) {
    if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
    if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
        return HAL_DATASPACE_SRGB_LINEAR;
        return HAL_DATASPACE_SRGB_LINEAR;
    } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
    } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
@@ -474,158 +472,106 @@ static android_dataspace modifyBufferDataspace(android_dataspace dataSpace,
    } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
    } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
        return HAL_DATASPACE_BT2020_PQ;
        return HAL_DATASPACE_BT2020_PQ;
    }
    }
    return dataSpace;
    return HAL_DATASPACE_UNKNOWN;
}

// stripAttributes is used by eglCreateWindowSurface, eglCreatePbufferSurface
// and eglCreatePixmapSurface to clean up color space related Window parameters
// that a driver does not advertise support for.
// Return true if stripped_attrib_list has stripped contents.

static EGLBoolean stripAttributes(egl_display_ptr dp, const EGLint* attrib_list,
                                  EGLint format,
                                  std::vector<EGLint>& stripped_attrib_list) {
    std::vector<EGLint> allowedColorSpaces;
    bool haveColorSpaceSupport = dp->haveExtension("EGL_KHR_gl_colorspace");
    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        // RGB_888 is never returned by getNativePixelFormat, but is included here for completeness.
        case HAL_PIXEL_FORMAT_RGB_888:
            if (haveColorSpaceSupport) {
                // Spec says:
                //     [fn1] Only OpenGL and OpenGL ES contexts which support sRGB
                //     rendering must respect requests for EGL_GL_COLORSPACE_SRGB_KHR, and
                //     only to sRGB formats supported by the context (normally just SRGB8)
                //     Older versions not supporting sRGB rendering will ignore this
                //     surface attribute.
                //
                // We support sRGB and pixel format is SRGB8, so allow
                // the EGL_GL_COLORSPACE_SRGB_KHR and
                // EGL_GL_COLORSPACE_LINEAR_KHR
                // colorspaces to be specified.

                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
            }
            if (findExtension(dp->disp.queryString.extensions,
                                  "EGL_EXT_gl_colorspace_display_p3_linear")) {
                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
}
}

// Returns a list of color spaces understood by the vendor EGL driver.
static std::vector<EGLint> getDriverColorSpaces(egl_display_ptr dp,
                                                android_pixel_format format) {
    std::vector<EGLint> colorSpaces;
    if (!dp->hasColorSpaceSupport) return colorSpaces;

    // OpenGL drivers only support sRGB encoding with 8-bit formats.
    // RGB_888 is never returned by getNativePixelFormat, but is included for completeness.
    const bool formatSupportsSRGBEncoding =
        format == HAL_PIXEL_FORMAT_RGBA_8888 || format == HAL_PIXEL_FORMAT_RGBX_8888 ||
        format == HAL_PIXEL_FORMAT_RGB_888;
    const bool formatIsFloatingPoint = format == HAL_PIXEL_FORMAT_RGBA_FP16;

    if (formatSupportsSRGBEncoding) {
        // sRGB and linear are always supported when color space support is present.
        colorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
        colorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
        // DCI-P3 uses the sRGB transfer function, so it's only relevant for 8-bit formats.
        if (findExtension(dp->disp.queryString.extensions,
        if (findExtension(dp->disp.queryString.extensions,
                              "EGL_EXT_gl_colorspace_display_p3")) {
                              "EGL_EXT_gl_colorspace_display_p3")) {
                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
            colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
        }
        }
            if (findExtension(dp->disp.queryString.extensions,
                                  "EGL_EXT_gl_colorspace_bt2020_linear")) {
                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
    }
    }

    // According to the spec, scRGB is only supported for floating point formats.
    // For non-linear scRGB, the application is responsible for applying the
    // transfer function.
    if (formatIsFloatingPoint) {
        if (findExtension(dp->disp.queryString.extensions,
        if (findExtension(dp->disp.queryString.extensions,
                                  "EGL_EXT_gl_colorspace_bt2020_pq")) {
                  "EGL_EXT_gl_colorspace_scrgb")) {
                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
            colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_EXT);
        }
        }
        if (findExtension(dp->disp.queryString.extensions,
        if (findExtension(dp->disp.queryString.extensions,
                  "EGL_EXT_gl_colorspace_scrgb_linear")) {
                  "EGL_EXT_gl_colorspace_scrgb_linear")) {
                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
            colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
        }
        }
            break;

        case HAL_PIXEL_FORMAT_RGBA_FP16:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
        case HAL_PIXEL_FORMAT_RGB_565:
            // Future: if driver supports XXXX extension, we can pass down that colorspace
        default:
            break;
    }
    }


    if (!attrib_list) return false;
    // BT2020 can be used with any pixel format. PQ encoding must be applied by the

    // application and does not affect the behavior of OpenGL.
    bool stripped = false;
    if (findExtension(dp->disp.queryString.extensions,
    for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
                          "EGL_EXT_gl_colorspace_bt2020_linear")) {
        switch (attr[0]) {
        colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
            case EGL_GL_COLORSPACE_KHR: {
                    EGLint colorSpace = attr[1];
                    bool found = false;
                    // Verify that color space is allowed
                    for (auto it : allowedColorSpaces) {
                        if (colorSpace == it) {
                            found = true;
                        }
                    }
                    if (found) {
                        // Found supported attribute
                        stripped_attrib_list.push_back(attr[0]);
                        stripped_attrib_list.push_back(attr[1]);
                    } else if (!haveColorSpaceSupport) {
                        // Device does not support colorspace extension
                        // pass on the attribute and let downstream
                        // components validate like normal
                        stripped_attrib_list.push_back(attr[0]);
                        stripped_attrib_list.push_back(attr[1]);
                    } else {
                        // Found supported attribute that driver does not
                        // support, strip it.
                        stripped = true;
    }
    }
    if (findExtension(dp->disp.queryString.extensions,
                          "EGL_EXT_gl_colorspace_bt2020_pq")) {
        colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
    }
    }
                break;

            default:
    // Linear DCI-P3 simply uses different primaries than standard RGB and thus
                stripped_attrib_list.push_back(attr[0]);
    // can be used with any pixel format.
                stripped_attrib_list.push_back(attr[1]);
    if (findExtension(dp->disp.queryString.extensions,
                          "EGL_EXT_gl_colorspace_display_p3_linear")) {
        colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
    }
    return colorSpaces;
}

// Cleans up color space related parameters that the driver does not understand.
// If there is no color space attribute in attrib_list, colorSpace is left
// unmodified.
static EGLBoolean processAttributes(egl_display_ptr dp, NativeWindowType window,
                                    android_pixel_format format, const EGLint* attrib_list,
                                    EGLint* colorSpace,
                                    std::vector<EGLint>* strippedAttribList) {
    for (const EGLint* attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
        bool copyAttribute = true;
        if (attr[0] == EGL_GL_COLORSPACE_KHR) {
            // Fail immediately if the driver doesn't have color space support at all.
            if (!dp->hasColorSpaceSupport) return false;
            *colorSpace = attr[1];

            // Strip the attribute if the driver doesn't understand it.
            copyAttribute = false;
            std::vector<EGLint> driverColorSpaces = getDriverColorSpaces(dp, format);
            for (auto driverColorSpace : driverColorSpaces) {
                if (attr[1] == driverColorSpace) {
                    copyAttribute = true;
                    break;
                    break;
                }
                }
            }
            }

    // Make sure there is at least one attribute
    if (stripped) {
        stripped_attrib_list.push_back(EGL_NONE);
        }
        }
    return stripped;
        if (copyAttribute) {
            strippedAttribList->push_back(attr[0]);
            strippedAttribList->push_back(attr[1]);
        }
        }

static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, NativeWindowType window,
                                         const EGLint* attrib_list, EGLint& colorSpace,
                                         android_dataspace& dataSpace) {
    colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
    dataSpace = HAL_DATASPACE_UNKNOWN;

    if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
        for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
            if (*attr == EGL_GL_COLORSPACE_KHR) {
                colorSpace = attr[1];
                bool found = false;
                bool verify = true;
                // Verify that color space is allowed
                if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
                    colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) {
                    // SRGB and LINEAR are always supported when EGL_KHR_gl_colorspace
                    // is available, so no need to verify.
                    found = true;
                    verify = false;
                } else if (colorSpace == EGL_GL_COLORSPACE_BT2020_LINEAR_EXT &&
                           dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) {
                    found = true;
                } else if (colorSpace == EGL_GL_COLORSPACE_BT2020_PQ_EXT &&
                           dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) {
                    found = true;
                } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_EXT &&
                           dp->haveExtension("EGL_EXT_gl_colorspace_scrgb")) {
                    found = true;
                } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT &&
                           dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) {
                    found = true;
                } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT &&
                           dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) {
                    found = true;
                } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT &&
                           dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) {
                    found = true;
                }
                if (!found) {
                    return false;
    }
    }
                if (verify && window) {
    // Terminate the attribute list.
                    bool wide_color_support = true;
    strippedAttribList->push_back(EGL_NONE);

    // If the passed color space has wide color gamut, check whether the target native window
    // supports wide color.
    const bool colorSpaceIsNarrow =
        *colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
        *colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR;
    if (window && !colorSpaceIsNarrow) {
        bool windowSupportsWideColor = true;
        // Ordinarily we'd put a call to native_window_get_wide_color_support
        // Ordinarily we'd put a call to native_window_get_wide_color_support
        // at the beginning of the function so that we'll have the
        // at the beginning of the function so that we'll have the
        // result when needed elsewhere in the function.
        // result when needed elsewhere in the function.
@@ -635,35 +581,26 @@ static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, NativeWindowType wi
        // if the application has specifically asked for wide-color we avoid
        // if the application has specifically asked for wide-color we avoid
        // the deadlock with SurfaceFlinger since it will not ask for a
        // the deadlock with SurfaceFlinger since it will not ask for a
        // wide-color surface.
        // wide-color surface.
                    int err = native_window_get_wide_color_support(window, &wide_color_support);
        int err = native_window_get_wide_color_support(window, &windowSupportsWideColor);


        if (err) {
        if (err) {
                        ALOGE("getColorSpaceAttribute: invalid window (win=%p) "
            ALOGE("processAttributes: invalid window (win=%p) "
                  "failed (%#x) (already connected to another API?)",
                  "failed (%#x) (already connected to another API?)",
                  window, err);
                  window, err);
            return false;
            return false;
        }
        }
                    if (!wide_color_support) {
        if (!windowSupportsWideColor) {
            // Application has asked for a wide-color colorspace but
            // Application has asked for a wide-color colorspace but
            // wide-color support isn't available on the display the window is on.
            // wide-color support isn't available on the display the window is on.
            return false;
            return false;
        }
        }
    }
    }
                // Only change the dataSpace from default if the application
                // has explicitly set the color space with a EGL_GL_COLORSPACE_KHR attribute.
                dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
            }
        }
    }
    return true;
    return true;
}
}


static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
// Gets the native pixel format corrsponding to the passed EGLConfig.
                                         EGLint& colorSpace, android_dataspace& dataSpace) {
void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
    return getColorSpaceAttribute(dp, NULL, attrib_list, colorSpace, dataSpace);
                          android_pixel_format* format) {
}

void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config, EGLint& format) {
    // Set the native window's buffers format to match what this config requests.
    // Set the native window's buffers format to match what this config requests.
    // Whether to use sRGB gamma is not part of the EGLconfig, but is part
    // Whether to use sRGB gamma is not part of the EGLconfig, but is part
    // of our native format. So if sRGB gamma is requested, we have to
    // of our native format. So if sRGB gamma is requested, we have to
@@ -697,27 +634,27 @@ void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig confi
    // endif
    // endif
    if (a == 0) {
    if (a == 0) {
        if (colorDepth <= 16) {
        if (colorDepth <= 16) {
            format = HAL_PIXEL_FORMAT_RGB_565;
            *format = HAL_PIXEL_FORMAT_RGB_565;
        } else {
        } else {
            if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
            if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
                if (colorDepth > 24) {
                if (colorDepth > 24) {
                    format = HAL_PIXEL_FORMAT_RGBA_1010102;
                    *format = HAL_PIXEL_FORMAT_RGBA_1010102;
                } else {
                } else {
                    format = HAL_PIXEL_FORMAT_RGBX_8888;
                    *format = HAL_PIXEL_FORMAT_RGBX_8888;
                }
                }
            } else {
            } else {
                format = HAL_PIXEL_FORMAT_RGBA_FP16;
                *format = HAL_PIXEL_FORMAT_RGBA_FP16;
            }
            }
        }
        }
    } else {
    } else {
        if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
        if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
            if (colorDepth > 24) {
            if (colorDepth > 24) {
                format = HAL_PIXEL_FORMAT_RGBA_1010102;
                *format = HAL_PIXEL_FORMAT_RGBA_1010102;
            } else {
            } else {
                format = HAL_PIXEL_FORMAT_RGBA_8888;
                *format = HAL_PIXEL_FORMAT_RGBA_8888;
            }
            }
        } else {
        } else {
            format = HAL_PIXEL_FORMAT_RGBA_FP16;
            *format = HAL_PIXEL_FORMAT_RGBA_FP16;
        }
        }
    }
    }
}
}
@@ -758,8 +695,6 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
    egl_connection_t* cnx = NULL;
    egl_connection_t* cnx = NULL;
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    if (dp) {
    if (dp) {
        EGLDisplay iDpy = dp->disp.dpy;

        if (!window) {
        if (!window) {
            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
        }
        }
@@ -778,25 +713,21 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
        }
        }


        EGLint format;
        EGLDisplay iDpy = dp->disp.dpy;
        getNativePixelFormat(iDpy, cnx, config, format);
        android_pixel_format format;
        getNativePixelFormat(iDpy, cnx, config, &format);


        // now select correct colorspace and dataspace based on user's attribute list
        // now select correct colorspace and dataspace based on user's attribute list
        EGLint colorSpace;
        EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
        android_dataspace dataSpace;
        std::vector<EGLint> strippedAttribList;
        if (!getColorSpaceAttribute(dp, window, attrib_list, colorSpace, dataSpace)) {
        if (!processAttributes(dp, window, format, attrib_list, &colorSpace,
                               &strippedAttribList)) {
            ALOGE("error invalid colorspace: %d", colorSpace);
            ALOGE("error invalid colorspace: %d", colorSpace);
            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
        }
        }

        std::vector<EGLint> strippedAttribList;
        if (stripAttributes(dp, attrib_list, format, strippedAttribList)) {
            // Had to modify the attribute list due to use of color space.
            // Use modified list from here on.
        attrib_list = strippedAttribList.data();
        attrib_list = strippedAttribList.data();
        }


        if (format != 0) {
        {
            int err = native_window_set_buffers_format(window, format);
            int err = native_window_set_buffers_format(window, format);
            if (err != 0) {
            if (err != 0) {
                ALOGE("error setting native window pixel format: %s (%d)",
                ALOGE("error setting native window pixel format: %s (%d)",
@@ -806,7 +737,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
            }
            }
        }
        }


        if (dataSpace != 0) {
        android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
        if (dataSpace != HAL_DATASPACE_UNKNOWN) {
            int err = native_window_set_buffers_data_space(window, dataSpace);
            int err = native_window_set_buffers_data_space(window, dataSpace);
            if (err != 0) {
            if (err != 0) {
                ALOGE("error setting native window pixel dataSpace: %s (%d)",
                ALOGE("error setting native window pixel dataSpace: %s (%d)",
@@ -844,14 +776,20 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config,


    egl_connection_t* cnx = NULL;
    egl_connection_t* cnx = NULL;
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    EGLint colorSpace;
    android_dataspace dataSpace;
    if (dp) {
    if (dp) {
        EGLDisplay iDpy = dp->disp.dpy;
        android_pixel_format format;
        getNativePixelFormat(iDpy, cnx, config, &format);

        // now select a corresponding sRGB format if needed
        // now select a corresponding sRGB format if needed
        if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
        EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
        std::vector<EGLint> strippedAttribList;
        if (!processAttributes(dp, nullptr, format, attrib_list, &colorSpace,
                               &strippedAttribList)) {
            ALOGE("error invalid colorspace: %d", colorSpace);
            ALOGE("error invalid colorspace: %d", colorSpace);
            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
        }
        }
        attrib_list = strippedAttribList.data();


        EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
        EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
                dp->disp.dpy, config, pixmap, attrib_list);
                dp->disp.dpy, config, pixmap, attrib_list);
@@ -872,26 +810,18 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    if (dp) {
    if (dp) {
        EGLDisplay iDpy = dp->disp.dpy;
        EGLDisplay iDpy = dp->disp.dpy;
        EGLint format;
        android_pixel_format format;
        getNativePixelFormat(iDpy, cnx, config, format);
        getNativePixelFormat(iDpy, cnx, config, &format);


        // now select correct colorspace and dataspace based on user's attribute list
        // Select correct colorspace based on user's attribute list
        EGLint colorSpace;
        EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
        android_dataspace dataSpace;
        std::vector<EGLint> strippedAttribList;
        if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
        if (!processAttributes(dp, nullptr, format, attrib_list, &colorSpace,
                               &strippedAttribList)) {
            ALOGE("error invalid colorspace: %d", colorSpace);
            ALOGE("error invalid colorspace: %d", colorSpace);
            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
            return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
        }
        }

        // Pbuffers are not displayed so we don't need to store the
        // colorspace. We do need to filter out color spaces the
        // driver doesn't know how to process.
        std::vector<EGLint> strippedAttribList;
        if (stripAttributes(dp, attrib_list, format, strippedAttribList)) {
            // Had to modify the attribute list due to use of color space.
            // Use modified list from here on.
        attrib_list = strippedAttribList.data();
        attrib_list = strippedAttribList.data();
        }


        EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
        EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
                dp->disp.dpy, config, attrib_list);
                dp->disp.dpy, config, attrib_list);
+6 −2
Original line number Original line Diff line number Diff line
@@ -206,12 +206,16 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {


        mExtensionString = gBuiltinExtensionString;
        mExtensionString = gBuiltinExtensionString;


        hasColorSpaceSupport = findExtension(disp.queryString.extensions, "EGL_KHR_gl_colorspace");

        // Note: CDD requires that devices supporting wide color and/or HDR color also support
        // the EGL_KHR_gl_colorspace extension.
        bool wideColorBoardConfig =
        bool wideColorBoardConfig =
                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(
                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(
                        false);
                        false);


        // Add wide-color extensions if device can support wide-color
        // Add wide-color extensions if device can support wide-color
        if (wideColorBoardConfig) {
        if (wideColorBoardConfig && hasColorSpaceSupport) {
            mExtensionString.append(
            mExtensionString.append(
                    "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear "
                    "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear "
                    "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 ");
                    "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 ");
@@ -220,7 +224,7 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
        bool hasHdrBoardConfig =
        bool hasHdrBoardConfig =
                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);


        if (hasHdrBoardConfig) {
        if (hasHdrBoardConfig && hasColorSpaceSupport) {
            // hasHDRBoardConfig indicates the system is capable of supporting HDR content.
            // hasHDRBoardConfig indicates the system is capable of supporting HDR content.
            // Typically that means there is an HDR capable display attached, but could be
            // Typically that means there is an HDR capable display attached, but could be
            // support for attaching an HDR display. In either case, advertise support for
            // support for attaching an HDR display. In either case, advertise support for
+1 −0
Original line number Original line Diff line number Diff line
@@ -113,6 +113,7 @@ public:
    DisplayImpl     disp;
    DisplayImpl     disp;
    bool    finishOnSwap;       // property: debug.egl.finish
    bool    finishOnSwap;       // property: debug.egl.finish
    bool    traceGpuCompletion; // property: debug.egl.traceGpuCompletion
    bool    traceGpuCompletion; // property: debug.egl.traceGpuCompletion
    bool    hasColorSpaceSupport;


private:
private:
    friend class egl_display_ptr;
    friend class egl_display_ptr;