Wire-up colorMode="hdr"

Fow now it uses a fixed white point of 150nits
TBD if this is disabled or adjusted

Test: Demo app
Change-Id: Iac13597b3d7633fdef3feaf7ec1da0c27c87904c
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index c701353..2a8aa8c 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -76,6 +76,7 @@
     bool glColorSpace = false;
     bool scRGB = false;
     bool displayP3 = false;
+    bool hdr = false;
     bool contextPriority = false;
     bool surfacelessContext = false;
     bool nativeFenceSync = false;
@@ -86,7 +87,8 @@
 EglManager::EglManager()
         : mEglDisplay(EGL_NO_DISPLAY)
         , mEglConfig(nullptr)
-        , mEglConfigWideGamut(nullptr)
+        , mEglConfigF16(nullptr)
+        , mEglConfig1010102(nullptr)
         , mEglContext(EGL_NO_CONTEXT)
         , mPBufferSurface(EGL_NO_SURFACE)
         , mCurrentSurface(EGL_NO_SURFACE)
@@ -143,8 +145,7 @@
     } else {
         LOG_ALWAYS_FATAL("Unsupported wide color space.");
     }
-    mHasWideColorGamutSupport = EglExtensions.glColorSpace && hasWideColorSpaceExtension &&
-                                mEglConfigWideGamut != EGL_NO_CONFIG_KHR;
+    mHasWideColorGamutSupport = EglExtensions.glColorSpace && hasWideColorSpaceExtension;
 }
 
 EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavior swapBehavior) {
@@ -177,6 +178,35 @@
     return config;
 }
 
+EGLConfig EglManager::load1010102Config(EGLDisplay display, SwapBehavior swapBehavior) {
+    EGLint eglSwapBehavior =
+            (swapBehavior == SwapBehavior::Preserved) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
+    // If we reached this point, we have a valid swap behavior
+    EGLint attribs[] = {EGL_RENDERABLE_TYPE,
+                        EGL_OPENGL_ES2_BIT,
+                        EGL_RED_SIZE,
+                        10,
+                        EGL_GREEN_SIZE,
+                        10,
+                        EGL_BLUE_SIZE,
+                        10,
+                        EGL_ALPHA_SIZE,
+                        2,
+                        EGL_DEPTH_SIZE,
+                        0,
+                        EGL_STENCIL_SIZE,
+                        STENCIL_BUFFER_SIZE,
+                        EGL_SURFACE_TYPE,
+                        EGL_WINDOW_BIT | eglSwapBehavior,
+                        EGL_NONE};
+    EGLConfig config = EGL_NO_CONFIG_KHR;
+    EGLint numConfigs = 1;
+    if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
+        return EGL_NO_CONFIG_KHR;
+    }
+    return config;
+}
+
 EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavior) {
     EGLint eglSwapBehavior =
             (swapBehavior == SwapBehavior::Preserved) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
@@ -230,6 +260,7 @@
     EglExtensions.pixelFormatFloat = extensions.has("EGL_EXT_pixel_format_float");
     EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
     EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough");
+    EglExtensions.hdr = extensions.has("EGL_EXT_gl_colorspace_bt2020_pq");
     EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
     EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
     EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync");
@@ -260,18 +291,20 @@
             LOG_ALWAYS_FATAL("Failed to choose config, error = %s", eglErrorString());
         }
     }
-    SkColorType wideColorType = DeviceInfo::get()->getWideColorType();
 
     // When we reach this point, we have a valid swap behavior
-    if (wideColorType == SkColorType::kRGBA_F16_SkColorType && EglExtensions.pixelFormatFloat) {
-        mEglConfigWideGamut = loadFP16Config(mEglDisplay, mSwapBehavior);
-        if (mEglConfigWideGamut == EGL_NO_CONFIG_KHR) {
+    if (EglExtensions.pixelFormatFloat) {
+        mEglConfigF16 = loadFP16Config(mEglDisplay, mSwapBehavior);
+        if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
             ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
                   eglErrorString());
             EglExtensions.pixelFormatFloat = false;
         }
-    } else if (wideColorType == SkColorType::kN32_SkColorType) {
-        mEglConfigWideGamut = load8BitsConfig(mEglDisplay, mSwapBehavior);
+    }
+    mEglConfig1010102 = load1010102Config(mEglDisplay, mSwapBehavior);
+    if (mEglConfig1010102 == EGL_NO_CONFIG_KHR) {
+        ALOGW("Failed to initialize 101010-2 format, error = %s",
+              eglErrorString());
     }
 }
 
@@ -311,8 +344,9 @@
                                                      sk_sp<SkColorSpace> colorSpace) {
     LOG_ALWAYS_FATAL_IF(!hasEglContext(), "Not initialized");
 
-    bool wideColorGamut = colorMode == ColorMode::WideColorGamut && mHasWideColorGamutSupport &&
-                          EglExtensions.noConfigContext;
+    if (!mHasWideColorGamutSupport || !EglExtensions.noConfigContext) {
+        colorMode = ColorMode::Default;
+    }
 
     // The color space we want to use depends on whether linear blending is turned
     // on and whether the app has requested wide color gamut rendering. When wide
@@ -338,26 +372,47 @@
     // list is considered empty if the first entry is EGL_NONE
     EGLint attribs[] = {EGL_NONE, EGL_NONE, EGL_NONE};
 
+    EGLConfig config = mEglConfig;
+    if (DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType) {
+        if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
+            colorMode = ColorMode::Default;
+        } else {
+            config = mEglConfigF16;
+        }
+    }
     if (EglExtensions.glColorSpace) {
         attribs[0] = EGL_GL_COLORSPACE_KHR;
-        if (wideColorGamut) {
-            skcms_Matrix3x3 colorGamut;
-            LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
-                                "Could not get gamut matrix from color space");
-            if (memcmp(&colorGamut, &SkNamedGamut::kDisplayP3, sizeof(colorGamut)) == 0) {
-                attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
-            } else if (memcmp(&colorGamut, &SkNamedGamut::kSRGB, sizeof(colorGamut)) == 0) {
-                attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
-            } else {
-                LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
+        switch (colorMode) {
+            case ColorMode::Default:
+                attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+                break;
+            case ColorMode::WideColorGamut: {
+                skcms_Matrix3x3 colorGamut;
+                LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
+                                    "Could not get gamut matrix from color space");
+                if (memcmp(&colorGamut, &SkNamedGamut::kDisplayP3, sizeof(colorGamut)) == 0) {
+                    attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
+                } else if (memcmp(&colorGamut, &SkNamedGamut::kSRGB, sizeof(colorGamut)) == 0) {
+                    attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
+                } else if (memcmp(&colorGamut, &SkNamedGamut::kRec2020, sizeof(colorGamut)) == 0) {
+                    attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+                } else {
+                    LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
+                }
+                break;
             }
-        } else {
-            attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+            case ColorMode::Hdr:
+                config = mEglConfigF16;
+                attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+                break;
+            case ColorMode::Hdr10:
+                config = mEglConfig1010102;
+                attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+                break;
         }
     }
 
-    EGLSurface surface = eglCreateWindowSurface(
-            mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
+    EGLSurface surface = eglCreateWindowSurface(mEglDisplay, config, window, attribs);
     if (surface == EGL_NO_SURFACE) {
         return Error<EGLint>{eglGetError()};
     }