From 1b71702e7e7d6648d7ff23e595bf429a405031ba Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Fri, 7 Jul 2017 14:55:40 -0600 Subject: Check wide-color support before adding extensions Don't want applications seeing the wide-color EGL extensions if the device or display cannot support wide-color. Bug: 63170158 Test: adb shell /data/nativetest/test-opengl-gl2_basic/test-opengl-gl2_basic Verify that EGL_EXT_gl_colorspace_scrgb, EGL_EXT_gl_colorspace_scrgb_linear, EGL_EXT_gl_colorspace_display_p3_linear and EGL_EXT_gl_colorspace_display_p3 are not present on devices that do not support wide-color, e.g. Nexus 6P Change-Id: I46a26a67f2d6da9c5aad50d884ef02a62ccb6945 (cherry picked from commit e5d6f994158d554c692afae0f547d89c75abde71) --- opengl/libs/Android.bp | 9 +++++++- opengl/libs/EGL/eglApi.cpp | 46 ++++++++++++++++++++++++++++++++++------- opengl/libs/EGL/egl_display.cpp | 18 ++++++++++++++++ 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp index a3446368de..b4cc2113e9 100644 --- a/opengl/libs/Android.bp +++ b/opengl/libs/Android.bp @@ -127,7 +127,14 @@ cc_library_shared { "EGL/Loader.cpp", "EGL/BlobCache.cpp", ], - shared_libs: ["libvndksupport"], + shared_libs: [ + "libvndksupport", + "android.hardware.configstore@1.0", + "android.hardware.configstore-utils", + "libhidlbase", + "libhidltransport", + "libutils", + ], static_libs: ["libEGL_getProcAddress"], ldflags: ["-Wl,--exclude-libs=ALL"], export_include_dirs: ["EGL/include"], diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 2fa36faf53..0214b0eb56 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -87,10 +87,6 @@ char const * const gBuiltinExtensionString = "EGL_ANDROID_get_native_client_buffer " "EGL_ANDROID_front_buffer_auto_refresh " "EGL_ANDROID_get_frame_timestamps " - "EGL_EXT_gl_colorspace_scrgb " - "EGL_EXT_gl_colorspace_scrgb_linear " - "EGL_EXT_gl_colorspace_display_p3_linear " - "EGL_EXT_gl_colorspace_display_p3 " ; char const * const gExtensionString = @@ -529,19 +525,25 @@ static EGLBoolean stripColorSpaceAttribute(egl_display_ptr dp, const EGLint* att return stripped; } -static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, - EGLint& colorSpace, android_dataspace& dataSpace) { +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_EXT_gl_colorspace_bt2020_linear && dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) { found = true; @@ -564,6 +566,31 @@ static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attri if (!found) { return false; } + if (verify && window) { + bool wide_color_support = true; + // 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 + // result when needed elsewhere in the function. + // However, because eglCreateWindowSurface is called by SurfaceFlinger and + // SurfaceFlinger is required to answer the call below we would + // end up in a deadlock situation. By moving the call to only happen + // if the application has specifically asked for wide-color we avoid + // the deadlock with SurfaceFlinger since it will not ask for a + // wide-color surface. + int err = native_window_get_wide_color_support(window, &wide_color_support); + + if (err) { + ALOGE("getColorSpaceAttribute: invalid window (win=%p) " + "failed (%#x) (already connected to another API?)", + window, err); + return false; + } + if (!wide_color_support) { + // Application has asked for a wide-color colorspace but + // wide-color support isn't available on the display the window is on. + 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); @@ -573,6 +600,11 @@ static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attri return true; } +static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, + EGLint& colorSpace, android_dataspace& dataSpace) { + return getColorSpaceAttribute(dp, NULL, attrib_list, colorSpace, dataSpace); +} + 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 @@ -667,7 +699,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, // now select correct colorspace and dataspace based on user's attribute list EGLint colorSpace; android_dataspace dataSpace; - if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { + if (!getColorSpaceAttribute(dp, window, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index b696920023..4e5833ab12 100644 --- a/opengl/libs/EGL/egl_display.cpp +++ b/opengl/libs/EGL/egl_display.cpp @@ -30,6 +30,12 @@ #include "Loader.h" #include +#include +#include + +using namespace android::hardware::configstore; +using namespace android::hardware::configstore::V1_0; + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- @@ -192,6 +198,18 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) { mClientApiString = sClientApiString; mExtensionString = gBuiltinExtensionString; + + bool wideColorBoardConfig = + getBool( + false); + + // Add wide-color extensions if device can support wide-color + if (wideColorBoardConfig) { + mExtensionString.append( + "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear " + "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 "); + } + char const* start = gExtensionString; do { // length of the extension name -- cgit v1.2.3-59-g8ed1b From 3329c085ef2747b7ab16011da3f0264301fdd922 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Sun, 9 Jul 2017 12:50:57 -0600 Subject: Add VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT. Bug: 63077212 Test: CTS basicExtensionTest Change-Id: I9c9b5de99249a6fdd49df1995971c14915f6a7c8 (cherry picked from commit edc88e78a30ca412a0a085a21f1fc1be7be5081f) --- vulkan/api/vulkan.api | 1 + vulkan/include/vulkan/vulkan.h | 3 ++- vulkan/libvulkan/swapchain.cpp | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api index 3efc13163e..11161c6bf6 100644 --- a/vulkan/api/vulkan.api +++ b/vulkan/api/vulkan.api @@ -1255,6 +1255,7 @@ enum VkColorSpaceKHR { VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, + VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, } @extension("VK_EXT_debug_report") // 12 diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h index ee3091348c..f0209d6de1 100644 --- a/vulkan/include/vulkan/vulkan.h +++ b/vulkan/include/vulkan/vulkan.h @@ -3355,6 +3355,7 @@ typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, + VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1), @@ -5829,7 +5830,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT( #endif #define VK_EXT_swapchain_colorspace 1 -#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 2 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 3 #define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 651438d6c8..069fb36fd0 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -640,6 +640,8 @@ VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, const VkSurfaceFormatKHR kWideColorFormats[] = { {VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT}, + {VK_FORMAT_R16G16B16A16_SFLOAT, + VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT}, {VK_FORMAT_A2R10G10B10_UNORM_PACK32, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}, }; -- cgit v1.2.3-59-g8ed1b From 281e8113d0ce20c702e847caf971663021eb65e3 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Thu, 13 Jul 2017 17:54:01 -0600 Subject: Communicate composition buffer dataspace to HWC Test: adb shell dumpsys SurfaceFlinger look for dataspace info in DisplayDevice section Bug: 63146977 Change-Id: If427171994fbc91faacf5bad9cc736ddfbd35ec3 (cherry picked from commit 79d272442ce13418c3ea81c95d7fea0159b4b481) --- services/surfaceflinger/DisplayDevice.cpp | 5 +++++ services/surfaceflinger/DisplayDevice.h | 1 + .../surfaceflinger/DisplayHardware/FramebufferSurface.cpp | 14 +++++++------- services/surfaceflinger/SurfaceFlinger.cpp | 3 +++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index a0abf12f9a..fc60002334 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -442,6 +442,11 @@ void DisplayDevice::setActiveColorMode(android_color_mode_t mode) { android_color_mode_t DisplayDevice::getActiveColorMode() const { return mActiveColorMode; } + +void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { + ANativeWindow* const window = mNativeWindow.get(); + native_window_set_buffers_data_space(window, dataspace); +} #endif // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index e2852a7c69..578f81b690 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -189,6 +189,7 @@ public: #ifdef USE_HWC2 android_color_mode_t getActiveColorMode() const; void setActiveColorMode(android_color_mode_t mode); + void setCompositionDataSpace(android_dataspace dataspace); #endif /* ------------------------------------------------------------------------ diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index 5b869e12c7..68d7a18d3a 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -106,12 +106,6 @@ status_t FramebufferSurface::advanceFrame() { if (result != NO_ERROR) { ALOGE("error latching next FramebufferSurface buffer: %s (%d)", strerror(-result), result); - return result; - } - result = mHwc.setClientTarget(mDisplayType, slot, - acquireFence, buf, dataspace); - if (result != NO_ERROR) { - ALOGE("error posting framebuffer: %d", result); } return result; #else @@ -182,7 +176,13 @@ status_t FramebufferSurface::nextBuffer(sp& outBuffer, sp& #else outBuffer = mCurrentBuffer; #endif - return NO_ERROR; + status_t result = + mHwc.setClientTarget(mDisplayType, outSlot, outFence, outBuffer, outDataspace); + if (result != NO_ERROR) { + ALOGE("error posting framebuffer: %d", result); + } + + return result; } #ifndef USE_HWC2 diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 63f260a958..0ae5209884 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -383,6 +383,7 @@ void SurfaceFlinger::bootFinished() #ifdef USE_HWC2 sp hw(getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY])); if (hw->getWideColorSupport()) { + hw->setCompositionDataSpace(HAL_DATASPACE_V0_SRGB); setActiveColorModeInternal(hw, HAL_COLOR_MODE_SRGB); } #endif @@ -1222,6 +1223,7 @@ void SurfaceFlinger::createDefaultDisplayDevice() { hasWideColorModes && hasWideColorDisplay); mDisplays.add(token, hw); setActiveColorModeInternal(hw, HAL_COLOR_MODE_NATIVE); + hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN); } void SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) { @@ -1871,6 +1873,7 @@ void SurfaceFlinger::setUpHWComposer() { // To achieve this we suppress color mode changes until after the boot animation if (mBootFinished) { setActiveColorModeInternal(displayDevice, newColorMode); + displayDevice->setCompositionDataSpace(newDataSpace); } } } -- cgit v1.2.3-59-g8ed1b