Support HDR in skiagl

Fixes: 276807477
Bug: 276385232
Test: setprop debug.hwui.renderer skiagl && silkfx
Change-Id: I173ca5ee3a28b274ffd33f11d67fbee73ce1ff20
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6b2c995..504c0de 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -236,7 +236,6 @@
 
     if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) {
         setBufferCount(mNativeSurface->getNativeWindow());
-
     }
 
     mFrameNumber = 0;
@@ -301,10 +300,6 @@
 
 float CanvasContext::setColorMode(ColorMode mode) {
     if (mode != mColorMode) {
-        const bool isHdr = mode == ColorMode::Hdr || mode == ColorMode::Hdr10;
-        if (isHdr && !mRenderPipeline->supportsExtendedRangeHdr()) {
-            mode = ColorMode::WideColorGamut;
-        }
         mColorMode = mode;
         mRenderPipeline->setSurfaceColorProperties(mode);
         setupPipelineSurface();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 4fb114b..94f35fd 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -423,6 +423,7 @@
     EGLint attribs[] = {EGL_NONE, EGL_NONE, EGL_NONE};
 
     EGLConfig config = mEglConfig;
+    bool overrideWindowDataSpaceForHdr = false;
     if (colorMode == ColorMode::A8) {
         // A8 doesn't use a color space
         if (!mEglConfigA8) {
@@ -450,12 +451,13 @@
                 case ColorMode::Default:
                     attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
                     break;
-                // Extended Range HDR requires being able to manipulate the dataspace in ways
-                // we cannot easily do while going through EGLSurface. Given this requires
-                // composer3 support, just treat HDR as equivalent to wide color gamut if
-                // the GLES path is still being hit
+                // We don't have an EGL colorspace for extended range P3 that's used for HDR
+                // So override it after configuring the EGL context
                 case ColorMode::Hdr:
                 case ColorMode::Hdr10:
+                    overrideWindowDataSpaceForHdr = true;
+                    attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
+                    break;
                 case ColorMode::WideColorGamut: {
                     skcms_Matrix3x3 colorGamut;
                     LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
@@ -491,6 +493,16 @@
                             (void*)window, eglErrorString());
     }
 
+    if (overrideWindowDataSpaceForHdr) {
+        // This relies on knowing that EGL will not re-set the dataspace after the call to
+        // eglCreateWindowSurface. Since the handling of the colorspace extension is largely
+        // implemented in libEGL in the platform, we can safely assume this is the case
+        int32_t err = ANativeWindow_setBuffersDataSpace(
+                window,
+                static_cast<android_dataspace>(STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_EXTENDED));
+        LOG_ALWAYS_FATAL_IF(err, "Failed to ANativeWindow_setBuffersDataSpace %d", err);
+    }
+
     return surface;
 }
 
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index c68fcdf..68d0944 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -95,7 +95,6 @@
     virtual void setPictureCapturedCallback(
             const std::function<void(sk_sp<SkPicture>&&)>& callback) = 0;
 
-    virtual bool supportsExtendedRangeHdr() const { return false; }
     virtual void setTargetSdrHdrRatio(float ratio) = 0;
 
     virtual ~IRenderPipeline() {}