Loading opengl/libs/EGL/eglApi.cpp +141 −51 Original line number Diff line number Diff line Loading @@ -473,6 +473,59 @@ static android_dataspace modifyBufferDataspace( android_dataspace dataSpace, return dataSpace; } // Return true if we stripped any EGL_GL_COLORSPACE_KHR attributes. static EGLBoolean stripColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, EGLint format, std::vector<EGLint>& stripped_attrib_list) { std::vector<EGLint> allowedColorSpaces; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGB_565: // driver okay with linear & sRGB for 8888, but can't handle // Display-P3 or other spaces. allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR); allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR); break; case HAL_PIXEL_FORMAT_RGBA_FP16: case HAL_PIXEL_FORMAT_RGBA_1010102: default: // driver does not want to see colorspace attributes for 1010102 or fp16. // Future: if driver supports XXXX extension, we can pass down that colorspace break; } bool stripped = false; if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) { if (attr[0] == 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) { stripped = true; } else { stripped_attrib_list.push_back(attr[0]); stripped_attrib_list.push_back(attr[1]); } } else { stripped_attrib_list.push_back(attr[0]); stripped_attrib_list.push_back(attr[1]); } } } if (stripped) { stripped_attrib_list.push_back(EGL_NONE); stripped_attrib_list.push_back(EGL_NONE); } return stripped; } static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, EGLint& colorSpace, android_dataspace& dataSpace) { colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR; Loading Loading @@ -514,35 +567,7 @@ static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attri return true; } EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { clearError(); egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { EGLDisplay iDpy = dp->disp.dpy; if (!window) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int value = 0; window->query(window, NATIVE_WINDOW_IS_VALID, &value); if (!value) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); if (result < 0) { ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " "failed (%#x) (already connected to another API?)", window, result); return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); } 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. // 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 Loading @@ -550,21 +575,30 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, // format. EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT; cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType); EGLint format; EGLint colorSpace; android_dataspace dataSpace; EGLint a = 0; EGLint r, g, b; r = g = b = 0; cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE, &r); cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g); cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE, &b); cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a); EGLint colorDepth = r + g + b; // Today, the driver only understands sRGB and linear on 888X // formats. Strip other colorspaces from the attribute list and // only use them to set the dataspace via // native_window_set_buffers_dataspace // if pixel format is RGBX 8888 // TBD: Can test for future extensions that indicate that driver // handles requested color space and we can let it through. // allow SRGB and LINEAR. All others need to be stripped. // else if 565, 4444 // TBD: Can we assume these are supported if 8888 is? // else if FP16 or 1010102 // strip colorspace from attribs. // endif if (a == 0) { if (colorDepth <= 16) { format = HAL_PIXEL_FORMAT_RGB_565; Loading @@ -590,13 +624,55 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, format = HAL_PIXEL_FORMAT_RGBA_FP16; } } } // now select a corresponding sRGB format if needed EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { clearError(); egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { EGLDisplay iDpy = dp->disp.dpy; if (!window) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int value = 0; window->query(window, NATIVE_WINDOW_IS_VALID, &value); if (!value) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); if (result < 0) { ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " "failed (%#x) (already connected to another API?)", window, result); return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); } EGLint format; getNativePixelFormat(iDpy, cnx, config, format); // now select correct colorspace and dataspace based on user's attribute list EGLint colorSpace; android_dataspace dataSpace; if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } std::vector<EGLint> strippedAttribList; if (stripColorSpaceAttribute(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(); } if (format != 0) { int err = native_window_set_buffers_format(window, format); if (err != 0) { Loading Loading @@ -671,15 +747,29 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { EGLDisplay iDpy = dp->disp.dpy; EGLint format; getNativePixelFormat(iDpy, cnx, config, format); // now select correct colorspace and dataspace based on user's attribute list EGLint colorSpace; android_dataspace dataSpace; if (dp) { // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); 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 (stripColorSpaceAttribute(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(); } EGLSurface surface = cnx->egl.eglCreatePbufferSurface( dp->disp.dpy, config, attrib_list); if (surface != EGL_NO_SURFACE) { Loading Loading
opengl/libs/EGL/eglApi.cpp +141 −51 Original line number Diff line number Diff line Loading @@ -473,6 +473,59 @@ static android_dataspace modifyBufferDataspace( android_dataspace dataSpace, return dataSpace; } // Return true if we stripped any EGL_GL_COLORSPACE_KHR attributes. static EGLBoolean stripColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, EGLint format, std::vector<EGLint>& stripped_attrib_list) { std::vector<EGLint> allowedColorSpaces; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGB_565: // driver okay with linear & sRGB for 8888, but can't handle // Display-P3 or other spaces. allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR); allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR); break; case HAL_PIXEL_FORMAT_RGBA_FP16: case HAL_PIXEL_FORMAT_RGBA_1010102: default: // driver does not want to see colorspace attributes for 1010102 or fp16. // Future: if driver supports XXXX extension, we can pass down that colorspace break; } bool stripped = false; if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) { if (attr[0] == 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) { stripped = true; } else { stripped_attrib_list.push_back(attr[0]); stripped_attrib_list.push_back(attr[1]); } } else { stripped_attrib_list.push_back(attr[0]); stripped_attrib_list.push_back(attr[1]); } } } if (stripped) { stripped_attrib_list.push_back(EGL_NONE); stripped_attrib_list.push_back(EGL_NONE); } return stripped; } static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, EGLint& colorSpace, android_dataspace& dataSpace) { colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR; Loading Loading @@ -514,35 +567,7 @@ static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attri return true; } EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { clearError(); egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { EGLDisplay iDpy = dp->disp.dpy; if (!window) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int value = 0; window->query(window, NATIVE_WINDOW_IS_VALID, &value); if (!value) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); if (result < 0) { ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " "failed (%#x) (already connected to another API?)", window, result); return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); } 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. // 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 Loading @@ -550,21 +575,30 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, // format. EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT; cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType); EGLint format; EGLint colorSpace; android_dataspace dataSpace; EGLint a = 0; EGLint r, g, b; r = g = b = 0; cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE, &r); cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g); cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE, &b); cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b); cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a); EGLint colorDepth = r + g + b; // Today, the driver only understands sRGB and linear on 888X // formats. Strip other colorspaces from the attribute list and // only use them to set the dataspace via // native_window_set_buffers_dataspace // if pixel format is RGBX 8888 // TBD: Can test for future extensions that indicate that driver // handles requested color space and we can let it through. // allow SRGB and LINEAR. All others need to be stripped. // else if 565, 4444 // TBD: Can we assume these are supported if 8888 is? // else if FP16 or 1010102 // strip colorspace from attribs. // endif if (a == 0) { if (colorDepth <= 16) { format = HAL_PIXEL_FORMAT_RGB_565; Loading @@ -590,13 +624,55 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, format = HAL_PIXEL_FORMAT_RGBA_FP16; } } } // now select a corresponding sRGB format if needed EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { clearError(); egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { EGLDisplay iDpy = dp->disp.dpy; if (!window) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int value = 0; window->query(window, NATIVE_WINDOW_IS_VALID, &value); if (!value) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); if (result < 0) { ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " "failed (%#x) (already connected to another API?)", window, result); return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); } EGLint format; getNativePixelFormat(iDpy, cnx, config, format); // now select correct colorspace and dataspace based on user's attribute list EGLint colorSpace; android_dataspace dataSpace; if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } std::vector<EGLint> strippedAttribList; if (stripColorSpaceAttribute(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(); } if (format != 0) { int err = native_window_set_buffers_format(window, format); if (err != 0) { Loading Loading @@ -671,15 +747,29 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { EGLDisplay iDpy = dp->disp.dpy; EGLint format; getNativePixelFormat(iDpy, cnx, config, format); // now select correct colorspace and dataspace based on user's attribute list EGLint colorSpace; android_dataspace dataSpace; if (dp) { // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); 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 (stripColorSpaceAttribute(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(); } EGLSurface surface = cnx->egl.eglCreatePbufferSurface( dp->disp.dpy, config, attrib_list); if (surface != EGL_NO_SURFACE) { Loading